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