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