1 /**
2  * @copyright
3  *
4  *   Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions are met:
8  *
9  *   * Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *   * Redistributions in binary form must reproduce the above copyright notice,
12  *     this list of conditions and the following disclaimer in the documentation
13  *     and/or other materials provided with the distribution.
14  *   * Neither the name of The Linux Foundation nor the names of its
15  *     contributors may be used to endorse or promote products derived from
16  *     this software without specific prior written permission.
17  *
18  *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
19  *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
20  *   FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED.
21  *   IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
22  *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  *   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25  *   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  *   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
28  *   DAMAGE.
29  *
30  * @file
31  *
32  *   omx_swvdec.h
33  *
34  * @brief
35  *
36  *   OMX software video decoder component header.
37  */
38 
39 #ifndef _OMX_SWVDEC_H_
40 #define _OMX_SWVDEC_H_
41 
42 //#undef NDEBUG // uncomment to enable assertions
43 
44 #include <pthread.h>
45 #include <semaphore.h>
46 
47 #include <linux/msm_ion.h>
48 #if TARGET_ION_ABI_VERSION >= 2
49 #include <ion/ion.h>
50 #include <linux/dma-buf.h>
51 #endif
52 
53 
54 #include "qc_omx_component.h"
55 
56 #include "omx_swvdec_utils.h"
57 
58 #include "swvdec_types.h"
59 
60 using namespace android;
61 
62 /// OMX SwVdec version date
63 #define OMX_SWVDEC_VERSION_DATE "2017-10-06T11:32:51+0530"
64 
65 #define OMX_SPEC_VERSION 0x00000101 ///< OMX specification version
66 
67 #define OMX_SWVDEC_NUM_INSTANCES 1 ///< number of OMX SwVdec instances
68 
69 #define OMX_SWVDEC_IP_BUFFER_COUNT_MIN 5 ///< OMX SwVdec minimum ip buffer count
70 
71 #define OMX_SWVDEC_MAX_FRAMES_PER_ETB 2 ///< maximum number of frames per ETB
72 
73 /// frame dimensions structure
74 typedef struct {
75     unsigned int width;  ///< frame width
76     unsigned int height; ///< frame height
77 } FRAME_DIMENSIONS;
78 
79 /// frame attributes structure
80 typedef struct {
81     unsigned int stride;    ///< frame stride
82     unsigned int scanlines; ///< frame scanlines
83     unsigned int size;      ///< frame size
84 } FRAME_ATTRIBUTES;
85 
86 /// asynchronous thread structure
87 typedef struct {
88     sem_t     sem_thread_created; ///< thread created semaphore
89     sem_t     sem_event;          ///< event semaphore
90     pthread_t handle;             ///< thread handle
91     bool      created;            ///< thread created?
92     bool      exit;               ///< thread exit variable
93 } ASYNC_THREAD;
94 
95 /// @cond
96 
97 struct vdec_ion {
98     int dev_fd;
99     struct ion_allocation_data alloc_data;
100     int data_fd;
101 };
102 
103 struct vdec_bufferpayload {
104 	void *bufferaddr;
105 	size_t buffer_len;
106 	int pmem_fd;
107 	size_t offset;
108 	size_t mmaped_size;
109 };
110 
111 typedef struct {
112     OMX_BUFFERHEADERTYPE      buffer_header;
113     struct vdec_ion           ion_info;
114     struct vdec_bufferpayload buffer_payload;
115     SWVDEC_BUFFER             buffer_swvdec;
116     bool                      buffer_populated;
117     unsigned int              split_count;
118 } OMX_SWVDEC_BUFFER_INFO;
119 
120 /// @endcond
121 
122 /// port structure
123 typedef struct {
124     OMX_PARAM_PORTDEFINITIONTYPE def;                 ///< definition
125     OMX_BOOL                     enabled;             ///< enabled?
126     OMX_BOOL                     populated;           ///< populated?
127     OMX_BOOL                     unpopulated;         ///< unpopulated?
128     OMX_BOOL                     flush_inprogress;    ///< flush inprogress?
129     unsigned int                 num_pending_buffers; ///< # of pending buffers
130 } OMX_SWVDEC_PORT;
131 
132 /// meta_buffer information structure
133 typedef struct {
134     int fd;        ///< file descriptor
135     int ref_count; ///< reference count
136 } OMX_SWVDEC_META_BUFFER_INFO;
137 
138 #define DEFAULT_FRAME_WIDTH  1920 ///< default frame width
139 #define DEFAULT_FRAME_HEIGHT 1080 ///< default frame height
140 
141 #define MAX(x, y) (((x) > (y)) ? (x) : (y)) ///< maximum
142 #define MIN(x, y) (((x) < (y)) ? (x) : (y)) ///< minimum
143 #define ALIGN(x, y) (((x) + ((y) - 1)) & (~((y) - 1)))
144                                   ///< align 'x' to next highest multiple of 'y'
145 
146 /// macro to print 'command type' string
147 #define OMX_COMMANDTYPE_STRING(x)                                 \
148     ((x == OMX_CommandStateSet) ? "OMX_CommandStateSet" :         \
149      ((x == OMX_CommandFlush) ? "OMX_CommandFlush" :              \
150       ((x == OMX_CommandPortDisable) ? "OMX_CommandPortDisable" : \
151        ((x == OMX_CommandPortEnable) ? "OMX_CommandPortEnable" :  \
152         "unknown"))))
153 
154 /// macro to print 'state type' string
155 #define OMX_STATETYPE_STRING(x)                                            \
156     ((x == OMX_StateInvalid) ? "OMX_StateInvalid" :                        \
157      ((x == OMX_StateLoaded) ? "OMX_StateLoaded" :                         \
158       ((x == OMX_StateIdle) ? "OMX_StateIdle" :                            \
159        ((x == OMX_StateExecuting) ? "OMX_StateExecuting" :                 \
160         ((x == OMX_StatePause) ? "OMX_StatePause" :                        \
161          ((x == OMX_StateWaitForResources) ? "OMX_StateWaitForResources" : \
162           "unknown"))))))
163 
164 enum {
165     OMX_CORE_PORT_INDEX_IP = 0, ///<  input port index
166     OMX_CORE_PORT_INDEX_OP = 1  ///< output port index
167 };
168 
169 extern "C" {
170     OMX_API void *get_omx_component_factory_fn(void);
171 };
172 
173 /// OMX SwVdec component class; derived from QC OMX component base class
174 class omx_swvdec : public qc_omx_component
175 {
176 public:
177 
178     omx_swvdec();
179 
180     virtual ~omx_swvdec();
181 
182     // derived class versions of base class pure virtual functions
183 
184     OMX_ERRORTYPE component_init(OMX_STRING cmp_name);
185     OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE cmp_handle);
186     OMX_ERRORTYPE get_component_version(OMX_HANDLETYPE   cmp_handle,
187                                         OMX_STRING       cmp_name,
188                                         OMX_VERSIONTYPE *p_cmp_version,
189                                         OMX_VERSIONTYPE *p_spec_version,
190                                         OMX_UUIDTYPE    *p_cmp_UUID);
191     OMX_ERRORTYPE send_command(OMX_HANDLETYPE  cmp_handle,
192                                OMX_COMMANDTYPE cmd,
193                                OMX_U32         param,
194                                OMX_PTR         p_cmd_data);
195     OMX_ERRORTYPE get_parameter(OMX_HANDLETYPE cmp_handle,
196                                 OMX_INDEXTYPE  param_index,
197                                 OMX_PTR        p_param_data);
198     OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE cmp_handle,
199                                 OMX_INDEXTYPE  param_index,
200                                 OMX_PTR        p_param_data);
201     OMX_ERRORTYPE get_config(OMX_HANDLETYPE cmp_handle,
202                              OMX_INDEXTYPE  config_index,
203                              OMX_PTR        p_config_data);
204     OMX_ERRORTYPE set_config(OMX_HANDLETYPE cmp_handle,
205                              OMX_INDEXTYPE  config_index,
206                              OMX_PTR        p_config_data);
207     OMX_ERRORTYPE get_extension_index(OMX_HANDLETYPE cmp_handle,
208                                       OMX_STRING     param_name,
209                                       OMX_INDEXTYPE *p_index_type);
210     OMX_ERRORTYPE get_state(OMX_HANDLETYPE cmp_handle,
211                             OMX_STATETYPE *p_state);
212     OMX_ERRORTYPE component_tunnel_request(OMX_HANDLETYPE       cmp_handle,
213                                            OMX_U32              port,
214                                            OMX_HANDLETYPE       peer_component,
215                                            OMX_U32              peer_port,
216                                            OMX_TUNNELSETUPTYPE *p_tunnel_setup);
217     OMX_ERRORTYPE use_buffer(OMX_HANDLETYPE         cmp_handle,
218                              OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
219                              OMX_U32                port,
220                              OMX_PTR                p_app_data,
221                              OMX_U32                bytes,
222                              OMX_U8                *p_buffer);
223     OMX_ERRORTYPE allocate_buffer(OMX_HANDLETYPE         cmp_handle,
224                                   OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
225                                   OMX_U32                port,
226                                   OMX_PTR                p_app_data,
227                                   OMX_U32                bytes);
228     OMX_ERRORTYPE free_buffer(OMX_HANDLETYPE        cmp_handle,
229                               OMX_U32               port,
230                               OMX_BUFFERHEADERTYPE *p_buffer);
231     OMX_ERRORTYPE empty_this_buffer(OMX_HANDLETYPE        cmp_handle,
232                                     OMX_BUFFERHEADERTYPE *p_buffer_hdr);
233     OMX_ERRORTYPE fill_this_buffer(OMX_HANDLETYPE        cmp_handle,
234                                    OMX_BUFFERHEADERTYPE *p_buffer_hdr);
235     OMX_ERRORTYPE set_callbacks(OMX_HANDLETYPE    cmp_handle,
236                                 OMX_CALLBACKTYPE *p_callbacks,
237                                 OMX_PTR           p_app_data);
238     OMX_ERRORTYPE use_EGL_image(OMX_HANDLETYPE         cmp_handle,
239                                 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
240                                 OMX_U32                port,
241                                 OMX_PTR                p_app_data,
242                                 void                  *egl_image);
243     OMX_ERRORTYPE component_role_enum(OMX_HANDLETYPE cmp_handle,
244                                       OMX_U8        *p_role,
245                                       OMX_U32        index);
246 
247     // SwVdec callback functions
248 
249     static SWVDEC_STATUS swvdec_empty_buffer_done_callback(
250         SWVDEC_HANDLE  swvdec_handle,
251         SWVDEC_BUFFER *p_buffer_ip,
252         void          *p_client_handle);
253     static SWVDEC_STATUS swvdec_fill_buffer_done_callback(
254         SWVDEC_HANDLE  swvdec_handle,
255         SWVDEC_BUFFER *p_buffer_op,
256         void          *p_client_handle);
257     static SWVDEC_STATUS swvdec_event_handler_callback(
258         SWVDEC_HANDLE swvdec_handle,
259         SWVDEC_EVENT  event,
260         void         *p_data,
261         void         *p_client_handle);
262 
263 private:
264 
265     OMX_STATETYPE m_state; ///< component state
266 
267     unsigned int m_status_flags; ///< status flags
268 
269     char m_cmp_name[OMX_MAX_STRINGNAME_SIZE];  ///< component name
270     char m_role_name[OMX_MAX_STRINGNAME_SIZE]; ///< component role name
271 
272     SWVDEC_CODEC  m_swvdec_codec;   ///< SwVdec codec type
273     SWVDEC_HANDLE m_swvdec_handle;  ///< SwVdec handle
274     bool          m_swvdec_created; ///< SwVdec created?
275 
276     OMX_VIDEO_CODINGTYPE m_omx_video_codingtype; ///< OMX video coding type
277     OMX_COLOR_FORMATTYPE m_omx_color_formattype; ///< OMX color format type
278 
279     FRAME_DIMENSIONS m_frame_dimensions; ///< frame dimensions
280     FRAME_ATTRIBUTES m_frame_attributes; ///< frame attributes
281 
282     FRAME_DIMENSIONS m_frame_dimensions_max;
283                                  ///< max frame dimensions for adaptive playback
284 
285     ASYNC_THREAD m_async_thread; ///< asynchronous thread
286 
287     omx_swvdec_queue m_queue_command; ///< command queue
288     omx_swvdec_queue m_queue_port_ip; ///<  input port queue for ETBs & EBDs
289     omx_swvdec_queue m_queue_port_op; ///< output port queue for FTBs & FBDs
290 
291     OMX_SWVDEC_PORT m_port_ip; ///<  input port
292     OMX_SWVDEC_PORT m_port_op; ///< output port
293 
294     OMX_CALLBACKTYPE m_callback; ///< IL client callback structure
295     OMX_PTR          m_app_data; ///< IL client app data pointer
296 
297     OMX_PRIORITYMGMTTYPE m_prio_mgmt; ///< priority management
298 
299     bool m_sync_frame_decoding_mode; ///< sync frame decoding mode enabled?
300     bool m_android_native_buffers;   ///< android native buffers enabled?
301 
302     bool m_meta_buffer_mode_disabled; ///< meta buffer mode disabled?
303     bool m_meta_buffer_mode;          ///< meta buffer mode enabled?
304     bool m_adaptive_playback_mode;    ///< adaptive playback mode enabled?
305     bool m_arbitrary_bytes_mode;      ///< arbitrary bytes mode enabled?
306 
307     bool m_port_reconfig_inprogress; ///< port reconfiguration in progress?
308 
309     bool m_dimensions_update_inprogress; ///< dimensions update in progress?
310 
311     sem_t m_sem_cmd; ///< semaphore for command processing
312 
313     OMX_SWVDEC_BUFFER_INFO *m_buffer_array_ip; ///<  input buffer info array
314     OMX_SWVDEC_BUFFER_INFO *m_buffer_array_op; ///< output buffer info array
315 
316     OMX_SWVDEC_META_BUFFER_INFO *m_meta_buffer_array; ///< metabuffer info array
317     pthread_mutex_t              m_meta_buffer_array_mutex;
318                                             ///< mutex for metabuffer info array
319 
320     std::priority_queue <OMX_TICKS,
321                          std::vector<OMX_TICKS>,
322                          std::greater<OMX_TICKS> > m_queue_timestamp;
323                                                    ///< timestamp priority queue
324 
325     omx_swvdec_diag m_diag; ///< diagnostics class variable
326 
327     OMX_ERRORTYPE set_frame_dimensions(unsigned int width,
328                                        unsigned int height);
329     OMX_ERRORTYPE set_frame_attributes(OMX_COLOR_FORMATTYPE color_format);
330     OMX_ERRORTYPE set_adaptive_playback(unsigned int max_width,
331                                         unsigned int max_height);
332 
333     OMX_ERRORTYPE get_video_port_format(
334         OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format);
335     OMX_ERRORTYPE set_video_port_format(
336         OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format);
337 
338     OMX_ERRORTYPE get_port_definition(OMX_PARAM_PORTDEFINITIONTYPE *p_port_def);
339     OMX_ERRORTYPE set_port_definition(OMX_PARAM_PORTDEFINITIONTYPE *p_port_def);
340 
341     OMX_ERRORTYPE get_supported_profilelevel(
342         OMX_VIDEO_PARAM_PROFILELEVELTYPE *p_profilelevel);
343 
344     OMX_ERRORTYPE describe_color_format(DescribeColorFormatParams *p_params);
345 
346     OMX_ERRORTYPE set_port_definition_qcom(
347         OMX_QCOM_PARAM_PORTDEFINITIONTYPE *p_port_def);
348 
349     // functions to set SwVdec properties with OMX component properties
350 
351     OMX_ERRORTYPE set_frame_dimensions_swvdec();
352     OMX_ERRORTYPE set_frame_attributes_swvdec();
353     OMX_ERRORTYPE set_adaptive_playback_swvdec();
354     OMX_ERRORTYPE set_thumbnail_mode_swvdec();
355 
356     // functions to get SwVdec properties and set OMX component properties
357 
358     OMX_ERRORTYPE get_frame_dimensions_swvdec();
359     OMX_ERRORTYPE get_frame_attributes_swvdec();
360     OMX_ERRORTYPE get_buffer_requirements_swvdec(unsigned int port_index);
361 
362     // buffer allocation & de-allocation functions
363     OMX_ERRORTYPE buffer_allocate_ip(OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
364                                      OMX_PTR                p_app_data,
365                                      OMX_U32                size);
366     OMX_ERRORTYPE buffer_allocate_op(OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
367                                      OMX_PTR                p_app_data,
368                                      OMX_U32                size);
369     OMX_ERRORTYPE buffer_allocate_ip_info_array();
370     OMX_ERRORTYPE buffer_allocate_op_info_array();
371     OMX_ERRORTYPE buffer_use_op(OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
372                                 OMX_PTR                p_app_data,
373                                 OMX_U32                size,
374                                 OMX_U8                *p_buffer);
375     OMX_ERRORTYPE buffer_deallocate_ip(OMX_BUFFERHEADERTYPE *p_buffer_hdr);
376     OMX_ERRORTYPE buffer_deallocate_op(OMX_BUFFERHEADERTYPE *p_buffer_hdr);
377     void          buffer_deallocate_ip_info_array();
378     void          buffer_deallocate_op_info_array();
379 
380     OMX_ERRORTYPE meta_buffer_array_allocate();
381     void          meta_buffer_array_deallocate();
382     void          meta_buffer_ref_add(unsigned int index, int fd);
383     void          meta_buffer_ref_remove(unsigned int index);
384 
385     OMX_BOOL port_ip_populated();
386     OMX_BOOL port_op_populated();
387 
388     OMX_ERRORTYPE flush(unsigned int port_index);
389 
390     int  ion_memory_alloc_map(struct vdec_ion *p_ion_info, OMX_U32 size, OMX_U32 alignment);
391     void ion_memory_free(struct vdec_ion *p_ion_buf_info);
392     void ion_flush_op(unsigned int index);
393     unsigned char *ion_map(int fd, int len);
394     OMX_ERRORTYPE ion_unmap(int fd, void *bufaddr, int len);
395 
396     // component callback functions
397 
398     void swvdec_empty_buffer_done(SWVDEC_BUFFER *p_buffer_ip);
399     void swvdec_fill_buffer_done(SWVDEC_BUFFER *p_buffer_op);
400     void swvdec_event_handler(SWVDEC_EVENT event, void *p_data);
401 
402     OMX_ERRORTYPE retval_swvdec2omx(SWVDEC_STATUS retval_swvdec);
403 
404     // status bits for pending events
405     enum {
406         PENDING_STATE_LOADED_TO_IDLE,    ///< loaded to idle state
407         PENDING_STATE_EXECUTING_TO_IDLE, ///< executing to idle state
408         PENDING_STATE_IDLE_TO_LOADED,    ///< idle to loaded state
409         PENDING_PORT_ENABLE_IP,          ///< enablement of ip port
410         PENDING_PORT_ENABLE_OP,          ///< enablement of op port
411         PENDING_PORT_DISABLE_IP,         ///< disablement of ip port
412         PENDING_PORT_DISABLE_OP,         ///< disablement of op port
413         PENDING_PORT_FLUSH_IP,           ///< flush of ip port
414         PENDING_PORT_FLUSH_OP            ///< flush of op port
415     };
416 
417     // events raised internally
418     enum {
419         OMX_SWVDEC_EVENT_CMD,               ///< command event
420         OMX_SWVDEC_EVENT_CMD_ACK,           ///< command acknowledgement
421         OMX_SWVDEC_EVENT_ERROR,             ///< error event
422         OMX_SWVDEC_EVENT_ETB,               ///< ETB event
423         OMX_SWVDEC_EVENT_EBD,               ///< EBD event
424         OMX_SWVDEC_EVENT_FTB,               ///< FTB event
425         OMX_SWVDEC_EVENT_FBD,               ///< FBD event
426         OMX_SWVDEC_EVENT_EOS,               ///< EOS event
427         OMX_SWVDEC_EVENT_FLUSH_PORT_IP,     ///< flush ip port event
428         OMX_SWVDEC_EVENT_FLUSH_PORT_OP,     ///< flush op port event
429         OMX_SWVDEC_EVENT_PORT_RECONFIG,     ///< port reconfig event
430         OMX_SWVDEC_EVENT_DIMENSIONS_UPDATED ///< dimensions updated event
431     };
432 
433     OMX_ERRORTYPE async_thread_create();
434     void          async_thread_destroy();
435 
436     static void   async_thread(void *p_cmp);
437 
438     void          async_post_event(unsigned long event_id,
439                                    unsigned long event_param1,
440                                    unsigned long event_param2);
441 
442     static void   async_process_event(void *p_cmp);
443 
444     OMX_ERRORTYPE async_process_event_cmd(OMX_COMMANDTYPE cmd, OMX_U32 param);
445     OMX_ERRORTYPE async_process_event_cmd_ack(OMX_COMMANDTYPE cmd,
446                                               OMX_U32         param);
447     OMX_ERRORTYPE async_process_event_error(OMX_ERRORTYPE error_code);
448     OMX_ERRORTYPE async_process_event_cmd_state_set(bool         *p_cmd_ack,
449                                                     OMX_STATETYPE state_new);
450     OMX_ERRORTYPE async_process_event_cmd_flush(unsigned int port_index);
451     OMX_ERRORTYPE async_process_event_cmd_port_disable(
452         bool         *p_cmd_ack,
453         unsigned int  port_index);
454     OMX_ERRORTYPE async_process_event_cmd_port_enable(bool        *p_cmd_ack,
455                                                       unsigned int port_index);
456     OMX_ERRORTYPE async_process_event_etb(OMX_BUFFERHEADERTYPE *p_buffer_hdr,
457                                           unsigned int          index);
458     OMX_ERRORTYPE async_process_event_ftb(OMX_BUFFERHEADERTYPE *p_buffer_hdr,
459                                           unsigned int          index);
460     OMX_ERRORTYPE async_process_event_ebd(OMX_BUFFERHEADERTYPE *p_buffer_hdr,
461                                           unsigned int          index);
462     OMX_ERRORTYPE async_process_event_fbd(OMX_BUFFERHEADERTYPE *p_buffer_hdr,
463                                           unsigned int          index);
464     OMX_ERRORTYPE async_process_event_eos();
465     OMX_ERRORTYPE async_process_event_flush_port_ip();
466     OMX_ERRORTYPE async_process_event_flush_port_op();
467     OMX_ERRORTYPE async_process_event_port_reconfig();
468     OMX_ERRORTYPE async_process_event_dimensions_updated();
469 };
470 
471 #endif // #ifndef _OMX_SWVDEC_H_
472