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.cpp
33 *
34 * @brief
35 *
36 * OMX software video decoder component source.
37 */
38
39 #include <assert.h>
40 #include <fcntl.h>
41 #include <sys/mman.h>
42
43 #include <cutils/properties.h>
44
45 #include <media/hardware/HardwareAPI.h>
46 #include <gralloc_priv.h>
47
48 #include "OMX_QCOMExtns.h"
49
50 #include "omx_swvdec.h"
51
52 #include "swvdec_api.h"
53
54 static unsigned int split_buffer_mpeg4(unsigned int *offset_array,
55 OMX_BUFFERHEADERTYPE *p_buffer_hdr);
56
57 /**
58 * ----------------
59 * PUBLIC FUNCTIONS
60 * ----------------
61 */
62
63 /**
64 * @brief Create & return component class instance.
65 *
66 * @retval Pointer to new component class instance.
67 */
get_omx_component_factory_fn(void)68 void *get_omx_component_factory_fn(void)
69 {
70 return new omx_swvdec;
71 }
72
73 /**
74 * @brief Component constructor.
75 */
omx_swvdec()76 omx_swvdec::omx_swvdec():
77 m_state(OMX_StateInvalid),
78 m_status_flags(0),
79 m_swvdec_codec(SWVDEC_CODEC_INVALID),
80 m_swvdec_handle(NULL),
81 m_swvdec_created(false),
82 m_omx_video_codingtype(OMX_VIDEO_CodingUnused),
83 m_omx_color_formattype(OMX_COLOR_FormatUnused),
84 m_sync_frame_decoding_mode(false),
85 m_android_native_buffers(false),
86 m_meta_buffer_mode_disabled(false),
87 m_meta_buffer_mode(false),
88 m_adaptive_playback_mode(false),
89 m_arbitrary_bytes_mode(false),
90 m_port_reconfig_inprogress(false),
91 m_dimensions_update_inprogress(false),
92 m_buffer_array_ip(NULL),
93 m_buffer_array_op(NULL),
94 m_meta_buffer_array(NULL)
95 {
96 // memset all member variables that are composite structures
97 memset(&m_cmp, 0, sizeof(m_cmp)); // part of base class
98 memset(&m_cmp_name[0], 0, sizeof(m_cmp_name));
99 memset(&m_role_name[0], 0, sizeof(m_role_name));
100 memset(&m_frame_dimensions, 0, sizeof(m_frame_dimensions));
101 memset(&m_frame_attributes, 0, sizeof(m_frame_attributes));
102 memset(&m_frame_dimensions_max, 0, sizeof(m_frame_dimensions_max));
103 memset(&m_async_thread, 0, sizeof(m_async_thread));
104 memset(&m_port_ip, 0, sizeof(m_port_ip));
105 memset(&m_port_op, 0, sizeof(m_port_op));
106 memset(&m_callback, 0, sizeof(m_callback));
107 memset(&m_app_data, 0, sizeof(m_app_data));
108 memset(&m_prio_mgmt, 0, sizeof(m_prio_mgmt));
109 memset(&m_sem_cmd, 0, sizeof(m_sem_cmd));
110 memset(&m_meta_buffer_array_mutex, 0, sizeof(m_meta_buffer_array_mutex));
111
112 // null-terminate component name & role name strings
113 m_cmp_name[0] = '\0';
114 m_role_name[0] = '\0';
115
116 // ports are enabled & unpopulated by default
117 m_port_ip.enabled = OMX_TRUE;
118 m_port_op.enabled = OMX_TRUE;
119 m_port_ip.unpopulated = OMX_TRUE;
120 m_port_op.unpopulated = OMX_TRUE;
121 }
122
123 /**
124 * @brief Component destructor.
125 */
~omx_swvdec()126 omx_swvdec::~omx_swvdec()
127 {
128 }
129
130 /**
131 * @brief Initialize component.
132 *
133 * @param[in] cmp_name: Component name string.
134 *
135 * @retval OMX_ERRORTYPE
136 */
component_init(OMX_STRING cmp_name)137 OMX_ERRORTYPE omx_swvdec::component_init(OMX_STRING cmp_name)
138 {
139 OMX_ERRORTYPE retval = OMX_ErrorNone;
140
141 OMX_SWVDEC_LOG_API("'%s', version date: %s",
142 cmp_name,
143 OMX_SWVDEC_VERSION_DATE);
144
145 omx_swvdec_log_init();
146
147 {
148 char property_value[PROPERTY_VALUE_MAX] = {0};
149
150 if (property_get("vendor.vidc.dec.meta_buffer.disable",
151 property_value,
152 NULL))
153 {
154 m_meta_buffer_mode_disabled = (bool) atoi(property_value);
155
156 OMX_SWVDEC_LOG_LOW("vendor.vidc.dec.meta_buffer.disable: %d",
157 m_meta_buffer_mode_disabled ? 1 : 0);
158 }
159 }
160
161 if (m_state != OMX_StateInvalid)
162 {
163 OMX_SWVDEC_LOG_ERROR("disallowed in state %s",
164 OMX_STATETYPE_STRING(m_state));
165
166 retval = OMX_ErrorIncorrectStateOperation;
167 goto component_init_exit;
168 }
169
170 if (!strncmp(cmp_name,
171 "OMX.qti.video.decoder.mpeg4sw",
172 OMX_MAX_STRINGNAME_SIZE))
173 {
174 OMX_SWVDEC_LOG_LOW("'video_decoder.mpeg4'");
175
176 strlcpy(m_cmp_name, cmp_name, OMX_MAX_STRINGNAME_SIZE);
177 strlcpy(m_role_name, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE);
178
179 m_swvdec_codec = SWVDEC_CODEC_MPEG4;
180 m_omx_video_codingtype = OMX_VIDEO_CodingMPEG4;
181 }
182 else if (!strncmp(cmp_name,
183 "OMX.qti.video.decoder.h263sw",
184 OMX_MAX_STRINGNAME_SIZE))
185 {
186 OMX_SWVDEC_LOG_LOW("video_decoder.h263");
187
188 strlcpy(m_cmp_name, cmp_name, OMX_MAX_STRINGNAME_SIZE);
189 strlcpy(m_role_name, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE);
190
191 m_swvdec_codec = SWVDEC_CODEC_H263;
192 m_omx_video_codingtype = OMX_VIDEO_CodingH263;
193 }
194 else if (((!strncmp(cmp_name,
195 "OMX.qti.video.decoder.divxsw",
196 OMX_MAX_STRINGNAME_SIZE))) ||
197 ((!strncmp(cmp_name,
198 "OMX.qti.video.decoder.divx4sw",
199 OMX_MAX_STRINGNAME_SIZE))))
200 {
201 OMX_SWVDEC_LOG_LOW("video_decoder.divx");
202
203 strlcpy(m_cmp_name, cmp_name, OMX_MAX_STRINGNAME_SIZE);
204 strlcpy(m_role_name, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE);
205
206 m_swvdec_codec = SWVDEC_CODEC_MPEG4;
207 m_omx_video_codingtype = ((OMX_VIDEO_CODINGTYPE) QOMX_VIDEO_CodingDivx);
208 }
209 else if (((!strncmp(cmp_name,
210 "OMX.qti.video.decoder.vc1sw",
211 OMX_MAX_STRINGNAME_SIZE)))||
212 ((!strncmp(cmp_name,
213 "OMX.qti.video.decoder.wmvsw",
214 OMX_MAX_STRINGNAME_SIZE))))
215 {
216 OMX_SWVDEC_LOG_LOW("video_decoder.vc1");
217
218 strlcpy(m_cmp_name, cmp_name, OMX_MAX_STRINGNAME_SIZE);
219 strlcpy(m_role_name, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE);
220
221 m_swvdec_codec = SWVDEC_CODEC_VC1;
222 m_omx_video_codingtype = OMX_VIDEO_CodingWMV;
223 }
224 else
225 {
226 OMX_SWVDEC_LOG_ERROR("'%s': invalid component name", cmp_name);
227
228 retval = OMX_ErrorInvalidComponentName;
229 goto component_init_exit;
230 }
231
232 {
233 SWVDEC_CALLBACK callback;
234
235 SWVDEC_STATUS retval_swvdec;
236
237 callback.pfn_empty_buffer_done = swvdec_empty_buffer_done_callback;
238 callback.pfn_fill_buffer_done = swvdec_fill_buffer_done_callback;
239 callback.pfn_event_notification = swvdec_event_handler_callback;
240 callback.p_client = this;
241
242 if ((retval_swvdec = swvdec_init(&m_swvdec_handle,
243 m_swvdec_codec,
244 &callback)) !=
245 SWVDEC_STATUS_SUCCESS)
246 {
247 retval = retval_swvdec2omx(retval_swvdec);
248 goto component_init_exit;
249 }
250
251 m_swvdec_created = true;
252
253 if ((retval = set_frame_dimensions(DEFAULT_FRAME_WIDTH,
254 DEFAULT_FRAME_HEIGHT)) !=
255 OMX_ErrorNone)
256 {
257 goto component_init_exit;
258 }
259
260 m_omx_color_formattype =
261 ((OMX_COLOR_FORMATTYPE)
262 OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m);
263
264 if ((retval = set_frame_attributes(m_omx_color_formattype)) !=
265 OMX_ErrorNone)
266 {
267 goto component_init_exit;
268 }
269 }
270
271 if ((retval = get_buffer_requirements_swvdec(OMX_CORE_PORT_INDEX_IP)) !=
272 OMX_ErrorNone)
273 {
274 goto component_init_exit;
275 }
276
277 if ((retval = get_buffer_requirements_swvdec(OMX_CORE_PORT_INDEX_OP)) !=
278 OMX_ErrorNone)
279 {
280 goto component_init_exit;
281 }
282
283 if ((retval = async_thread_create()) != OMX_ErrorNone)
284 {
285 goto component_init_exit;
286 }
287
288 if (sem_init(&m_sem_cmd, 0, 0))
289 {
290 OMX_SWVDEC_LOG_ERROR("failed to create command processing semaphore");
291
292 retval = OMX_ErrorInsufficientResources;
293 goto component_init_exit;
294 }
295
296 if (pthread_mutex_init(&m_meta_buffer_array_mutex, NULL))
297 {
298 OMX_SWVDEC_LOG_ERROR("failed to create meta buffer info array mutex");
299
300 retval = OMX_ErrorInsufficientResources;
301 goto component_init_exit;
302 }
303
304 OMX_SWVDEC_LOG_HIGH("OMX_StateInvalid -> OMX_StateLoaded");
305
306 m_state = OMX_StateLoaded;
307
308 component_init_exit:
309 return retval;
310 }
311
312 /**
313 * @brief De-initialize component.
314 *
315 * @param[in] cmp_handle: Component handle.
316 *
317 * @retval OMX_ERRORTYPE
318 */
component_deinit(OMX_HANDLETYPE cmp_handle)319 OMX_ERRORTYPE omx_swvdec::component_deinit(OMX_HANDLETYPE cmp_handle)
320 {
321 OMX_SWVDEC_LOG_API("");
322
323 if (cmp_handle == NULL)
324 {
325 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
326 }
327
328 pthread_mutex_destroy(&m_meta_buffer_array_mutex);
329
330 sem_destroy(&m_sem_cmd);
331
332 async_thread_destroy();
333
334 if (m_swvdec_created)
335 {
336 swvdec_deinit(m_swvdec_handle);
337
338 m_swvdec_handle = NULL;
339 }
340
341 OMX_SWVDEC_LOG_HIGH("all done, goodbye!");
342
343 return OMX_ErrorNone;
344 }
345
346 /**
347 * @brief Get component version.
348 *
349 * @param[in] cmp_handle: Component handle.
350 * @param[in] cmp_name: Component name string.
351 * @param[in,out] p_cmp_version: Pointer to component version variable.
352 * @param[in,out] p_spec_version: Pointer to OMX spec version variable.
353 * @param[in,out] p_cmp_UUID: Pointer to component UUID variable.
354 *
355 * @retval OMX_ERRORTYPE
356 */
get_component_version(OMX_HANDLETYPE cmp_handle,OMX_STRING cmp_name,OMX_VERSIONTYPE * p_cmp_version,OMX_VERSIONTYPE * p_spec_version,OMX_UUIDTYPE * p_cmp_UUID)357 OMX_ERRORTYPE omx_swvdec::get_component_version(OMX_HANDLETYPE cmp_handle,
358 OMX_STRING cmp_name,
359 OMX_VERSIONTYPE *p_cmp_version,
360 OMX_VERSIONTYPE *p_spec_version,
361 OMX_UUIDTYPE *p_cmp_UUID)
362 {
363 OMX_ERRORTYPE retval = OMX_ErrorNone;
364
365 (void) p_cmp_UUID;
366
367 OMX_SWVDEC_LOG_API("");
368
369 if (m_state == OMX_StateInvalid)
370 {
371 OMX_SWVDEC_LOG_ERROR("in invalid state");
372
373 retval = OMX_ErrorInvalidState;
374 }
375 else if (cmp_handle == NULL)
376 {
377 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
378
379 retval = OMX_ErrorInvalidComponent;
380 }
381 else if (strncmp(cmp_name, m_cmp_name, sizeof(m_cmp_name)))
382 {
383 OMX_SWVDEC_LOG_ERROR("'%s': invalid component name", cmp_name);
384
385 retval = OMX_ErrorInvalidComponentName;
386 }
387 else if (p_cmp_version == NULL)
388 {
389 OMX_SWVDEC_LOG_ERROR("p_cmp_version = NULL");
390
391 retval = OMX_ErrorBadParameter;
392 }
393 else if (p_spec_version == NULL)
394 {
395 OMX_SWVDEC_LOG_ERROR("p_spec_version = NULL");
396
397 retval = OMX_ErrorBadParameter;
398 }
399 else
400 {
401 p_spec_version->nVersion = OMX_SPEC_VERSION;
402 }
403
404 return retval;
405 }
406
407 /**
408 * @brief Send command to component.
409 *
410 * @param[in] cmp_handle: Component handle.
411 * @param[in] cmd: Command.
412 * @param[in] param: Command parameter.
413 * @param[in] p_cmd_data: Pointer to command data.
414 *
415 * @retval OMX_ERRORTYPE
416 */
send_command(OMX_HANDLETYPE cmp_handle,OMX_COMMANDTYPE cmd,OMX_U32 param,OMX_PTR p_cmd_data)417 OMX_ERRORTYPE omx_swvdec::send_command(OMX_HANDLETYPE cmp_handle,
418 OMX_COMMANDTYPE cmd,
419 OMX_U32 param,
420 OMX_PTR p_cmd_data)
421 {
422 OMX_ERRORTYPE retval = OMX_ErrorNone;
423
424 (void) p_cmd_data; // prevent warning for unused function argument
425
426 if (m_state == OMX_StateInvalid)
427 {
428 OMX_SWVDEC_LOG_ERROR("in invalid state");
429
430 retval = OMX_ErrorInvalidState;
431 goto send_command_exit;
432 }
433 else if (cmp_handle == NULL)
434 {
435 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
436
437 retval = OMX_ErrorInvalidComponent;
438 goto send_command_exit;
439 }
440
441 switch (cmd)
442 {
443
444 case OMX_CommandStateSet:
445 {
446 OMX_SWVDEC_LOG_API("%s, %s",
447 OMX_COMMANDTYPE_STRING(cmd),
448 OMX_STATETYPE_STRING((OMX_STATETYPE) param));
449 break;
450 }
451
452 case OMX_CommandFlush:
453 case OMX_CommandPortDisable:
454 case OMX_CommandPortEnable:
455 {
456 OMX_SWVDEC_LOG_API("%s, port index %d",
457 OMX_COMMANDTYPE_STRING(cmd),
458 param);
459
460 if ((param != OMX_CORE_PORT_INDEX_IP) &&
461 (param != OMX_CORE_PORT_INDEX_OP) &&
462 (param != OMX_ALL))
463 {
464 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", param);
465
466 retval = OMX_ErrorBadPortIndex;
467 }
468
469 break;
470 }
471
472 default:
473 {
474 OMX_SWVDEC_LOG_API("cmd %d, param %d", cmd, param);
475
476 OMX_SWVDEC_LOG_ERROR("cmd '%d' invalid", cmd);
477
478 retval = OMX_ErrorBadParameter;
479 break;
480 }
481
482 } // switch (cmd)
483
484 if (retval == OMX_ErrorNone)
485 {
486 if (cmp_handle == NULL)
487 {
488 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
489
490 retval = OMX_ErrorInvalidComponent;
491 }
492 else if (m_state == OMX_StateInvalid)
493 {
494 OMX_SWVDEC_LOG_ERROR("in invalid state");
495
496 retval = OMX_ErrorInvalidState;
497 }
498 }
499
500 if (retval != OMX_ErrorNone)
501 {
502 async_post_event(OMX_SWVDEC_EVENT_ERROR, retval, 0);
503 }
504 else
505 {
506 async_post_event(OMX_SWVDEC_EVENT_CMD, cmd, param);
507
508 sem_wait(&m_sem_cmd);
509 }
510
511 send_command_exit:
512 return retval;
513 }
514
515 /**
516 * @brief Get a parameter from component.
517 *
518 * @param[in] cmp_handle: Component handle.
519 * @param[in] param_index: Parameter index.
520 * @param[in,out] p_param_data: Pointer to parameter data.
521 *
522 * @retval OMX_ERRORTYPE
523 */
get_parameter(OMX_HANDLETYPE cmp_handle,OMX_INDEXTYPE param_index,OMX_PTR p_param_data)524 OMX_ERRORTYPE omx_swvdec::get_parameter(OMX_HANDLETYPE cmp_handle,
525 OMX_INDEXTYPE param_index,
526 OMX_PTR p_param_data)
527 {
528 OMX_ERRORTYPE retval = OMX_ErrorNone;
529
530 if (m_state == OMX_StateInvalid)
531 {
532 OMX_SWVDEC_LOG_ERROR("in invalid state");
533
534 retval = OMX_ErrorInvalidState;
535 }
536 else if (cmp_handle == NULL)
537 {
538 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
539
540 retval = OMX_ErrorInvalidComponent;
541 }
542 else if (p_param_data == NULL)
543 {
544 OMX_SWVDEC_LOG_ERROR("p_param_data = NULL");
545
546 retval = OMX_ErrorBadParameter;
547 }
548
549 if (retval != OMX_ErrorNone)
550 {
551 goto get_parameter_exit;
552 }
553
554 switch (param_index)
555 {
556
557 case OMX_IndexParamAudioInit:
558 {
559 OMX_PORT_PARAM_TYPE *p_port_param =
560 (OMX_PORT_PARAM_TYPE *) p_param_data;
561
562 p_port_param->nPorts = 0;
563 p_port_param->nStartPortNumber = 0;
564
565 OMX_SWVDEC_LOG_API("OMX_IndexParamAudioInit: "
566 "%d port(s), start port index %d",
567 p_port_param->nPorts,
568 p_port_param->nStartPortNumber);
569 break;
570 }
571
572 case OMX_IndexParamImageInit:
573 {
574 OMX_PORT_PARAM_TYPE *p_port_param =
575 (OMX_PORT_PARAM_TYPE *) p_param_data;
576
577 p_port_param->nPorts = 0;
578 p_port_param->nStartPortNumber = 0;
579
580 OMX_SWVDEC_LOG_API("OMX_IndexParamImageInit: "
581 "%d port(s), start port index %d",
582 p_port_param->nPorts,
583 p_port_param->nStartPortNumber);
584 break;
585 }
586
587 case OMX_IndexParamVideoInit:
588 {
589 OMX_PORT_PARAM_TYPE *p_port_param =
590 (OMX_PORT_PARAM_TYPE *) p_param_data;
591
592 p_port_param->nPorts = 2;
593 p_port_param->nStartPortNumber = 0;
594
595 OMX_SWVDEC_LOG_API("OMX_IndexParamVideoInit: "
596 "%d port(s), start port index %d",
597 p_port_param->nPorts,
598 p_port_param->nStartPortNumber);
599 break;
600 }
601
602 case OMX_IndexParamOtherInit:
603 {
604 OMX_PORT_PARAM_TYPE *p_port_param =
605 (OMX_PORT_PARAM_TYPE *) p_param_data;
606
607 p_port_param->nPorts = 0;
608 p_port_param->nStartPortNumber = 0;
609
610 OMX_SWVDEC_LOG_API("OMX_IndexParamOtherInit: "
611 "%d port(s), start port index %d",
612 p_port_param->nPorts,
613 p_port_param->nStartPortNumber);
614 break;
615 }
616
617 case OMX_IndexConfigPriorityMgmt:
618 {
619 OMX_PRIORITYMGMTTYPE *p_prio_mgmt =
620 (OMX_PRIORITYMGMTTYPE *) p_param_data;
621
622 OMX_SWVDEC_LOG_API("OMX_IndexConfigPriorityMgmt");
623
624 memcpy(p_prio_mgmt, &m_prio_mgmt, sizeof(OMX_PRIORITYMGMTTYPE));
625 break;
626 }
627
628 case OMX_IndexParamStandardComponentRole:
629 {
630 OMX_PARAM_COMPONENTROLETYPE *p_cmp_role =
631 (OMX_PARAM_COMPONENTROLETYPE *) p_param_data;
632
633 strlcpy((char *) p_cmp_role->cRole,
634 m_role_name,
635 OMX_MAX_STRINGNAME_SIZE);
636
637 OMX_SWVDEC_LOG_API("OMX_IndexParamStandardComponentRole: %s",
638 p_cmp_role->cRole);
639 break;
640 }
641
642 case OMX_IndexParamPortDefinition:
643 {
644 OMX_PARAM_PORTDEFINITIONTYPE *p_port_def =
645 (OMX_PARAM_PORTDEFINITIONTYPE *) p_param_data;
646
647 OMX_SWVDEC_LOG_API("OMX_IndexParamPortDefinition, port index %d",
648 p_port_def->nPortIndex);
649
650 retval = get_port_definition(p_port_def);
651 break;
652 }
653
654 case OMX_IndexParamCompBufferSupplier:
655 {
656 OMX_PARAM_BUFFERSUPPLIERTYPE *p_buffer_supplier =
657 (OMX_PARAM_BUFFERSUPPLIERTYPE *) p_param_data;
658
659 OMX_SWVDEC_LOG_API("OMX_IndexParamCompBufferSupplier, port index %d",
660 p_buffer_supplier->nPortIndex);
661
662 if ((p_buffer_supplier->nPortIndex == OMX_CORE_PORT_INDEX_IP) ||
663 (p_buffer_supplier->nPortIndex == OMX_CORE_PORT_INDEX_OP))
664 {
665 p_buffer_supplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
666 }
667 else
668 {
669 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
670 p_buffer_supplier->nPortIndex);
671
672 retval = OMX_ErrorBadPortIndex;
673 }
674
675 break;
676 }
677
678 case OMX_IndexParamVideoPortFormat:
679 {
680 OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format =
681 (OMX_VIDEO_PARAM_PORTFORMATTYPE *) p_param_data;
682
683 OMX_SWVDEC_LOG_API("OMX_IndexParamVideoPortFormat, "
684 "port index %d, index %d",
685 p_port_format->nPortIndex,
686 p_port_format->nIndex);
687
688 retval = get_video_port_format(p_port_format);
689 break;
690 }
691
692 case OMX_IndexParamVideoMpeg2:
693 {
694 OMX_SWVDEC_LOG_ERROR("OMX_IndexParamVideoMpeg2: unsupported");
695
696 retval = OMX_ErrorUnsupportedIndex;
697 break;
698 }
699
700 case OMX_IndexParamVideoMpeg4:
701 {
702 OMX_SWVDEC_LOG_API("OMX_IndexParamVideoMpeg4: unsupported");
703
704 retval = OMX_ErrorUnsupportedIndex;
705 break;
706 }
707
708 case OMX_IndexParamVideoAvc:
709 {
710 OMX_SWVDEC_LOG_API("OMX_IndexParamVideoAvc: unsupported");
711
712 retval = OMX_ErrorUnsupportedIndex;
713 break;
714 }
715
716 case OMX_IndexParamVideoH263:
717 {
718 OMX_SWVDEC_LOG_API("OMX_IndexParamVideoH263: unsupported");
719
720 retval = OMX_ErrorUnsupportedIndex;
721 break;
722 }
723
724 case OMX_IndexParamVideoProfileLevelQuerySupported:
725 {
726 OMX_VIDEO_PARAM_PROFILELEVELTYPE *p_profilelevel =
727 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) p_param_data;
728
729 OMX_SWVDEC_LOG_API("OMX_IndexParamVideoProfileLevelQuerySupported, "
730 "port index %d, profile index %d",
731 p_profilelevel->nPortIndex,
732 p_profilelevel->nProfileIndex);
733
734 retval = get_supported_profilelevel(p_profilelevel);
735 break;
736 }
737
738 default:
739 {
740 /**
741 * Vendor-specific extension indices checked here since they are not
742 * part of the OMX_INDEXTYPE enumerated type.
743 */
744
745 switch ((OMX_QCOM_EXTN_INDEXTYPE) param_index)
746 {
747
748 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
749 {
750 GetAndroidNativeBufferUsageParams *p_buffer_usage =
751 (GetAndroidNativeBufferUsageParams *) p_param_data;
752
753 OMX_SWVDEC_LOG_API(
754 "OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage, "
755 "port index %d", p_buffer_usage->nPortIndex);
756
757 if (p_buffer_usage->nPortIndex == OMX_CORE_PORT_INDEX_OP)
758 {
759 p_buffer_usage->nUsage = (static_cast<uint32_t>(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
760 GRALLOC_USAGE_SW_READ_OFTEN |
761 GRALLOC_USAGE_SW_WRITE_OFTEN));
762 }
763 else
764 {
765 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
766 p_buffer_usage->nPortIndex);
767
768 retval = OMX_ErrorBadPortIndex;
769 }
770 break;
771 }
772
773 case OMX_QcomIndexFlexibleYUVDescription:
774 {
775 OMX_SWVDEC_LOG_API("OMX_QcomIndexFlexibleYUVDescription");
776
777 retval = describe_color_format((DescribeColorFormatParams *)
778 p_param_data);
779 break;
780 }
781
782 default:
783 {
784 OMX_SWVDEC_LOG_ERROR("param index '0x%08x' invalid",
785 (OMX_QCOM_EXTN_INDEXTYPE) param_index);
786
787 retval = OMX_ErrorBadParameter;
788 break;
789 }
790
791 } // switch ((OMX_QCOM_EXTN_INDEXTYPE) param_index)
792
793 } // default case
794
795 } // switch (param_index)
796
797 get_parameter_exit:
798 return retval;
799 }
800
801 /**
802 * @brief Set a parameter to component.
803 *
804 * @param[in] cmp_handle: Component handle.
805 * @param[in] param_index: Parameter index.
806 * @param[in] p_param_data: Pointer to parameter data.
807 *
808 * @retval OMX_ERRORTYPE
809 */
set_parameter(OMX_HANDLETYPE cmp_handle,OMX_INDEXTYPE param_index,OMX_PTR p_param_data)810 OMX_ERRORTYPE omx_swvdec::set_parameter(OMX_HANDLETYPE cmp_handle,
811 OMX_INDEXTYPE param_index,
812 OMX_PTR p_param_data)
813 {
814 OMX_ERRORTYPE retval = OMX_ErrorNone;
815
816 if (m_state == OMX_StateInvalid)
817 {
818 OMX_SWVDEC_LOG_ERROR("in invalid state");
819
820 retval = OMX_ErrorInvalidState;
821 }
822 else if (cmp_handle == NULL)
823 {
824 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
825
826 retval = OMX_ErrorInvalidComponent;
827 }
828 else if (p_param_data == NULL)
829 {
830 OMX_SWVDEC_LOG_ERROR("p_param_data = NULL");
831
832 retval = OMX_ErrorBadParameter;
833 }
834 else if ((m_state != OMX_StateLoaded) &&
835 (m_port_reconfig_inprogress == false))
836 {
837 OMX_SWVDEC_LOG_ERROR("disallowed in state %s",
838 OMX_STATETYPE_STRING(m_state));
839
840 retval = OMX_ErrorIncorrectStateOperation;
841 }
842
843 if (retval != OMX_ErrorNone)
844 {
845 goto set_parameter_exit;
846 }
847
848 switch (param_index)
849 {
850
851 case OMX_IndexParamPriorityMgmt:
852 {
853 OMX_PRIORITYMGMTTYPE *p_prio_mgmt =
854 (OMX_PRIORITYMGMTTYPE *) p_param_data;
855
856 OMX_SWVDEC_LOG_API("OMX_IndexConfigPriorityMgmt: "
857 "group ID %d, group priority %d",
858 p_prio_mgmt->nGroupID,
859 p_prio_mgmt->nGroupPriority);
860
861 if (m_state != OMX_StateLoaded)
862 {
863 OMX_SWVDEC_LOG_ERROR("'%d' state invalid; "
864 "should be in loaded state",
865 m_state);
866
867 retval = OMX_ErrorIncorrectStateOperation;
868 }
869 else
870 {
871 memcpy(&m_prio_mgmt, p_prio_mgmt, sizeof(OMX_PRIORITYMGMTTYPE));
872 }
873
874 break;
875 }
876
877 case OMX_IndexParamStandardComponentRole:
878 {
879 OMX_PARAM_COMPONENTROLETYPE *p_cmp_role =
880 (OMX_PARAM_COMPONENTROLETYPE *) p_param_data;
881
882 OMX_SWVDEC_LOG_API("OMX_IndexParamStandardComponentRole '%s'",
883 p_cmp_role->cRole);
884
885 if (m_state != OMX_StateLoaded)
886 {
887 OMX_SWVDEC_LOG_ERROR("'%d' state invalid; "
888 "should be in loaded state",
889 m_state);
890
891 retval = OMX_ErrorIncorrectStateOperation;
892 }
893 else
894 {
895 if (strncmp((char *) p_cmp_role->cRole,
896 m_role_name,
897 OMX_MAX_STRINGNAME_SIZE))
898 {
899 OMX_SWVDEC_LOG_ERROR("'%s': invalid component role name",
900 p_cmp_role->cRole);
901
902 retval = OMX_ErrorBadParameter;
903 }
904 }
905
906 break;
907 }
908
909 case OMX_IndexParamPortDefinition:
910 {
911 OMX_PARAM_PORTDEFINITIONTYPE *p_port_def =
912 (OMX_PARAM_PORTDEFINITIONTYPE *) p_param_data;
913
914 OMX_SWVDEC_LOG_API("OMX_IndexParamPortDefinition, port index %d",
915 p_port_def->nPortIndex);
916
917 if ((m_state != OMX_StateLoaded) &&
918 (((p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP) &&
919 (m_port_ip.enabled == OMX_TRUE) &&
920 (m_port_ip.populated == OMX_TRUE)) ||
921 ((p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP) &&
922 (m_port_op.enabled == OMX_TRUE) &&
923 (m_port_op.populated == OMX_TRUE))))
924 {
925 OMX_SWVDEC_LOG_ERROR("OMX_IndexParamPortDefinition "
926 "disallowed in state %s "
927 "while port index %d is enabled & populated",
928 OMX_STATETYPE_STRING(m_state),
929 p_port_def->nPortIndex);
930
931 retval = OMX_ErrorIncorrectStateOperation;
932 }
933 else
934 {
935 retval = set_port_definition(p_port_def);
936 }
937
938 break;
939 }
940
941 case OMX_IndexParamCompBufferSupplier:
942 {
943 OMX_PARAM_BUFFERSUPPLIERTYPE *p_buffer_supplier =
944 (OMX_PARAM_BUFFERSUPPLIERTYPE *) p_param_data;
945
946 OMX_SWVDEC_LOG_API("OMX_IndexParamCompBufferSupplier: "
947 "port index %d, buffer supplier %d",
948 p_buffer_supplier->nPortIndex,
949 (int) p_buffer_supplier->eBufferSupplier);
950
951 if ((p_buffer_supplier->nPortIndex != OMX_CORE_PORT_INDEX_IP) &&
952 (p_buffer_supplier->nPortIndex != OMX_CORE_PORT_INDEX_OP))
953 {
954 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
955 p_buffer_supplier->nPortIndex);
956
957 retval = OMX_ErrorBadPortIndex;
958 }
959
960 break;
961 }
962
963 case OMX_IndexParamVideoPortFormat:
964 {
965 OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format =
966 (OMX_VIDEO_PARAM_PORTFORMATTYPE *) p_param_data;
967
968 OMX_SWVDEC_LOG_API("OMX_IndexParamVideoPortFormat, port index %d",
969 p_port_format->nPortIndex);
970
971 if ((m_state != OMX_StateLoaded) &&
972 (((p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_IP) &&
973 (m_port_ip.enabled == OMX_TRUE) &&
974 (m_port_ip.populated == OMX_TRUE)) ||
975 ((p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_OP) &&
976 (m_port_op.enabled == OMX_TRUE) &&
977 (m_port_op.populated == OMX_TRUE))))
978 {
979 OMX_SWVDEC_LOG_ERROR("OMX_IndexParamVideoPortFormat "
980 "disallowed in state %s "
981 "while port index %d is enabled & populated",
982 OMX_STATETYPE_STRING(m_state),
983 p_port_format->nPortIndex);
984
985 retval = OMX_ErrorIncorrectStateOperation;
986 }
987 else
988 {
989 retval = set_video_port_format(p_port_format);
990 }
991
992 break;
993 }
994
995 case OMX_IndexParamVideoMpeg2:
996 {
997 OMX_SWVDEC_LOG_ERROR("OMX_IndexParamVideoMpeg2 unsupported");
998
999 retval = OMX_ErrorUnsupportedIndex;
1000 break;
1001 }
1002
1003 case OMX_IndexParamVideoMpeg4:
1004 {
1005 OMX_SWVDEC_LOG_API("OMX_IndexParamVideoMpeg4 unsupported");
1006
1007 retval = OMX_ErrorUnsupportedIndex;
1008 break;
1009 }
1010
1011 case OMX_IndexParamVideoAvc:
1012 {
1013 OMX_SWVDEC_LOG_API("OMX_IndexParamVideoAvc unsupported");
1014
1015 retval = OMX_ErrorUnsupportedIndex;
1016 break;
1017 }
1018
1019 case OMX_IndexParamVideoH263:
1020 {
1021 OMX_SWVDEC_LOG_API("OMX_IndexParamVideoH263 unsupported");
1022
1023 retval = OMX_ErrorUnsupportedIndex;
1024 break;
1025 }
1026
1027 default:
1028 {
1029 /**
1030 * Vendor-specific extension indices checked here since they are not
1031 * part of the OMX_INDEXTYPE enumerated type.
1032 */
1033
1034 switch ((OMX_QCOM_EXTN_INDEXTYPE) param_index)
1035 {
1036
1037 case OMX_QcomIndexPortDefn:
1038 {
1039 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *p_port_def =
1040 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) p_param_data;
1041
1042 OMX_SWVDEC_LOG_API("OMX_QcomIndexPortDefn, port index %d",
1043 p_port_def->nPortIndex);
1044
1045 if ((m_state != OMX_StateLoaded) &&
1046 (((p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP) &&
1047 (m_port_ip.enabled == OMX_TRUE) &&
1048 (m_port_ip.populated == OMX_TRUE)) ||
1049 ((p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP) &&
1050 (m_port_op.enabled == OMX_TRUE) &&
1051 (m_port_op.populated == OMX_TRUE))))
1052 {
1053 OMX_SWVDEC_LOG_ERROR("OMX_QcomIndexPortDefn "
1054 "disallowed in state %s "
1055 "while port index %d "
1056 "is enabled & populated",
1057 OMX_STATETYPE_STRING(m_state),
1058 p_port_def->nPortIndex);
1059
1060 retval = OMX_ErrorIncorrectStateOperation;
1061 }
1062 else
1063 {
1064 retval = set_port_definition_qcom(p_port_def);
1065 }
1066
1067 break;
1068 }
1069
1070 case OMX_QcomIndexParamVideoDivx:
1071 {
1072 OMX_SWVDEC_LOG_API("OMX_QcomIndexParamVideoDivx");
1073
1074 break;
1075 }
1076
1077 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
1078 {
1079 OMX_SWVDEC_LOG_API("OMX_QcomIndexParamVideoSyncFrameDecodingMode");
1080
1081 m_sync_frame_decoding_mode = true;
1082
1083 retval = set_thumbnail_mode_swvdec();
1084 break;
1085 }
1086
1087 case OMX_QcomIndexParamVideoDecoderPictureOrder:
1088 {
1089 QOMX_VIDEO_DECODER_PICTURE_ORDER *p_picture_order =
1090 (QOMX_VIDEO_DECODER_PICTURE_ORDER *) p_param_data;
1091
1092 switch (p_picture_order->eOutputPictureOrder)
1093 {
1094
1095 case QOMX_VIDEO_DISPLAY_ORDER:
1096 {
1097 OMX_SWVDEC_LOG_API(
1098 "OMX_QcomIndexParamVideoDecoderPictureOrder, "
1099 "QOMX_VIDEO_DISPLAY_ORDER");
1100
1101 break;
1102 }
1103
1104 case QOMX_VIDEO_DECODE_ORDER:
1105 {
1106 OMX_SWVDEC_LOG_API(
1107 "OMX_QcomIndexParamVideoDecoderPictureOrder, "
1108 "QOMX_VIDEO_DECODE_ORDER");
1109
1110 OMX_SWVDEC_LOG_ERROR(
1111 "OMX_QcomIndexParamVideoDecoderPictureOrder, "
1112 "QOMX_VIDEO_DECODE_ORDER; unsupported");
1113
1114 retval = OMX_ErrorUnsupportedSetting;
1115 break;
1116 }
1117
1118 default:
1119 {
1120 OMX_SWVDEC_LOG_ERROR(
1121 "OMX_QcomIndexParamVideoDecoderPictureOrder, %d; invalid",
1122 p_picture_order->eOutputPictureOrder);
1123
1124 retval = OMX_ErrorBadParameter;
1125 break;
1126 }
1127
1128 }
1129
1130 break;
1131 }
1132
1133 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
1134 {
1135 OMX_SWVDEC_LOG_API(
1136 "OMX_GoogleAndroidIndexEnableAndroidNativeBuffers, %s",
1137 (((EnableAndroidNativeBuffersParams *) p_param_data)->enable ?
1138 "enable" :
1139 "disable"));
1140
1141 m_android_native_buffers =
1142 (bool) (((EnableAndroidNativeBuffersParams *)
1143 p_param_data)->enable);
1144
1145 break;
1146 }
1147
1148 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
1149 {
1150 OMX_SWVDEC_LOG_ERROR("OMX_GoogleAndroidIndexUseAndroidNativeBuffer "
1151 "unsupported");
1152
1153 retval = OMX_ErrorUnsupportedIndex;
1154 break;
1155 }
1156
1157 case OMX_QcomIndexParamEnableTimeStampReorder:
1158 {
1159 OMX_SWVDEC_LOG_API(
1160 "OMX_QcomIndexParamEnableTimeStampReorder, %s",
1161 (((QOMX_INDEXTIMESTAMPREORDER *) p_param_data)->bEnable ?
1162 "enable" :
1163 "disable"));
1164
1165 break;
1166 }
1167
1168 case OMX_QcomIndexParamVideoMetaBufferMode:
1169 {
1170 StoreMetaDataInBuffersParams *p_meta_data =
1171 (StoreMetaDataInBuffersParams *) p_param_data;
1172
1173 OMX_SWVDEC_LOG_API("OMX_QcomIndexParamVideoMetaBufferMode, "
1174 "port index %d, %s",
1175 p_meta_data->nPortIndex,
1176 (p_meta_data->bStoreMetaData ?
1177 "enable" :
1178 "disable"));
1179 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
1180 {
1181 OMX_SWVDEC_LOG_HIGH("meta buffer mode is not supprted for vc1");
1182 return OMX_ErrorUnsupportedSetting;
1183 }
1184 if (p_meta_data->nPortIndex == OMX_CORE_PORT_INDEX_OP)
1185 {
1186 if (p_meta_data->bStoreMetaData && m_meta_buffer_mode_disabled)
1187 {
1188 OMX_SWVDEC_LOG_ERROR("meta buffer mode disabled "
1189 "via ADB setprop: "
1190 "'omx_swvdec.meta_buffer.disable'");
1191
1192 retval = OMX_ErrorBadParameter;
1193 }
1194 else
1195 {
1196 m_meta_buffer_mode = (bool) p_meta_data->bStoreMetaData;
1197 }
1198 }
1199 else
1200 {
1201 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
1202 p_meta_data->nPortIndex);
1203
1204 retval = OMX_ErrorBadPortIndex;
1205 }
1206
1207 break;
1208 }
1209
1210 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
1211 {
1212 PrepareForAdaptivePlaybackParams *p_adaptive_playback_params =
1213 (PrepareForAdaptivePlaybackParams *) p_param_data;
1214
1215 OMX_SWVDEC_LOG_API("OMX_QcomIndexParamVideoAdaptivePlaybackMode, "
1216 "port index %d, %s, max dimensions: %d x %d",
1217 p_adaptive_playback_params->nPortIndex,
1218 (p_adaptive_playback_params->bEnable ?
1219 "enable" :
1220 "disable"),
1221 p_adaptive_playback_params->nMaxFrameWidth,
1222 p_adaptive_playback_params->nMaxFrameHeight);
1223
1224 if (p_adaptive_playback_params->nPortIndex ==
1225 OMX_CORE_PORT_INDEX_OP)
1226 {
1227 if (p_adaptive_playback_params->bEnable)
1228 {
1229 m_adaptive_playback_mode = true;
1230
1231 retval =
1232 set_adaptive_playback(
1233 p_adaptive_playback_params->nMaxFrameWidth,
1234 p_adaptive_playback_params->nMaxFrameHeight);
1235 }
1236 }
1237 else
1238 {
1239 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
1240 p_adaptive_playback_params->nPortIndex);
1241
1242 retval = OMX_ErrorBadPortIndex;
1243 }
1244
1245 break;
1246 }
1247
1248 default:
1249 {
1250 OMX_SWVDEC_LOG_ERROR("param index '0x%08x' invalid",
1251 (OMX_QCOM_EXTN_INDEXTYPE) param_index);
1252
1253 retval = OMX_ErrorBadParameter;
1254 break;
1255 }
1256
1257 } // switch ((OMX_QCOM_EXTN_INDEXTYPE) param_index)
1258
1259 break;
1260 } // default case
1261
1262 } // switch (param_index)
1263
1264 set_parameter_exit:
1265 return retval;
1266 }
1267
1268 /**
1269 * @brief Get a configuration from component.
1270 *
1271 * @param[in] cmp_handle: Component handle.
1272 * @param[in] config_index: Configuration index.
1273 * @param[in] p_config_data: Pointer to configuration data.
1274 *
1275 * @retval OMX_ERRORTYPE
1276 */
get_config(OMX_HANDLETYPE cmp_handle,OMX_INDEXTYPE config_index,OMX_PTR p_config_data)1277 OMX_ERRORTYPE omx_swvdec::get_config(OMX_HANDLETYPE cmp_handle,
1278 OMX_INDEXTYPE config_index,
1279 OMX_PTR p_config_data)
1280 {
1281 OMX_ERRORTYPE retval = OMX_ErrorNone;
1282
1283 if (m_state == OMX_StateInvalid)
1284 {
1285 OMX_SWVDEC_LOG_ERROR("in invalid state");
1286
1287 retval = OMX_ErrorInvalidState;
1288 }
1289 else if (cmp_handle == NULL)
1290 {
1291 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
1292
1293 retval = OMX_ErrorInvalidComponent;
1294 }
1295 else if (p_config_data == NULL)
1296 {
1297 OMX_SWVDEC_LOG_ERROR("p_config_data = NULL");
1298
1299 retval = OMX_ErrorBadParameter;
1300 }
1301
1302 if (retval != OMX_ErrorNone)
1303 {
1304 goto get_config_exit;
1305 }
1306
1307 switch (config_index)
1308 {
1309
1310 case OMX_IndexConfigCommonOutputCrop:
1311 {
1312 OMX_CONFIG_RECTTYPE *p_recttype = (OMX_CONFIG_RECTTYPE *) p_config_data;
1313
1314 OMX_SWVDEC_LOG_API("OMX_IndexConfigCommonOutputCrop, port index %d",
1315 p_recttype->nPortIndex);
1316
1317 if (p_recttype->nPortIndex == OMX_CORE_PORT_INDEX_OP)
1318 {
1319 if (m_dimensions_update_inprogress)
1320 {
1321 retval = get_frame_dimensions_swvdec();
1322
1323 m_dimensions_update_inprogress = false;
1324 }
1325
1326 if (retval == OMX_ErrorNone)
1327 {
1328 p_recttype->nLeft = 0;
1329 p_recttype->nTop = 0;
1330 p_recttype->nWidth = m_frame_dimensions.width;
1331 p_recttype->nHeight = m_frame_dimensions.height;
1332 }
1333 }
1334 else
1335 {
1336 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
1337 p_recttype->nPortIndex);
1338
1339 retval = OMX_ErrorBadPortIndex;
1340 }
1341
1342 break;
1343 }
1344
1345 default:
1346 {
1347 switch ((OMX_QCOM_EXTN_INDEXTYPE) config_index)
1348 {
1349
1350 case OMX_QcomIndexConfigInterlaced:
1351 {
1352 OMX_QCOM_CONFIG_INTERLACETYPE *p_config_interlacetype =
1353 (OMX_QCOM_CONFIG_INTERLACETYPE *) p_config_data;
1354
1355 OMX_SWVDEC_LOG_API("OMX_QcomIndexConfigInterlaced, "
1356 "port index %d, index %d",
1357 p_config_interlacetype->nPortIndex,
1358 p_config_interlacetype->nIndex);
1359
1360 if (p_config_interlacetype->nPortIndex == OMX_CORE_PORT_INDEX_OP)
1361 {
1362 if (p_config_interlacetype->nIndex == 0)
1363 {
1364 p_config_interlacetype->eInterlaceType =
1365 OMX_QCOM_InterlaceFrameProgressive;
1366 }
1367 else if (p_config_interlacetype->nIndex == 1)
1368 {
1369 p_config_interlacetype->eInterlaceType =
1370 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
1371 }
1372 else if (p_config_interlacetype->nIndex == 2)
1373 {
1374 p_config_interlacetype->eInterlaceType =
1375 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
1376 }
1377 else
1378 {
1379 OMX_SWVDEC_LOG_ERROR("index '%d' unsupported; "
1380 "no more interlaced types",
1381 p_config_interlacetype->nIndex);
1382
1383 retval = OMX_ErrorNoMore;
1384 }
1385 }
1386 else
1387 {
1388 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
1389 p_config_interlacetype->nPortIndex);
1390
1391 retval = OMX_ErrorBadPortIndex;
1392 }
1393
1394 break;
1395 }
1396
1397 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
1398 {
1399 QOMX_VIDEO_QUERY_DECODER_INSTANCES *p_decoder_instances =
1400 (QOMX_VIDEO_QUERY_DECODER_INSTANCES *) p_config_data;
1401
1402 OMX_SWVDEC_LOG_API("OMX_QcomIndexQueryNumberOfVideoDecInstance");
1403
1404 p_decoder_instances->nNumOfInstances = OMX_SWVDEC_NUM_INSTANCES;
1405 break;
1406 }
1407
1408 case OMX_QcomIndexConfigVideoFramePackingArrangement:
1409 {
1410 OMX_SWVDEC_LOG_API(
1411 "OMX_QcomIndexConfigVideoFramePackingArrangement");
1412
1413 OMX_SWVDEC_LOG_ERROR(
1414 "OMX_QcomIndexConfigVideoFramePackingArrangement unsupported");
1415
1416 retval = OMX_ErrorUnsupportedIndex;
1417 break;
1418 }
1419
1420 default:
1421 {
1422 OMX_SWVDEC_LOG_ERROR("config index '0x%08x' invalid", config_index);
1423
1424 retval = OMX_ErrorBadParameter;
1425 break;
1426 }
1427
1428 } // switch ((OMX_QCOM_EXTN_INDEXTYPE) config_index)
1429
1430 break;
1431 }
1432
1433 } // switch (config_index)
1434
1435 get_config_exit:
1436 return retval;
1437 }
1438
1439 /**
1440 * @brief Set a configuration to component.
1441 *
1442 * @retval OMX_ERRORTYPE
1443 */
set_config(OMX_HANDLETYPE cmp_handle,OMX_INDEXTYPE config_index,OMX_PTR p_config_data)1444 OMX_ERRORTYPE omx_swvdec::set_config(OMX_HANDLETYPE cmp_handle,
1445 OMX_INDEXTYPE config_index,
1446 OMX_PTR p_config_data)
1447 {
1448 (void) cmp_handle;
1449 (void) p_config_data;
1450
1451 OMX_SWVDEC_LOG_API("config index 0x%08x", config_index);
1452
1453 OMX_SWVDEC_LOG_ERROR("not implemented");
1454
1455 return OMX_ErrorNotImplemented;
1456 }
1457
1458 /**
1459 * @brief Translate a vendor-specific extension string to a standard index type.
1460 *
1461 * @param[in] cmp_handle: Component handle.
1462 * @param[in] param_name: Parameter name (extension string).
1463 * @param[in,out] p_index_type: Pointer to extension string's index type.
1464 *
1465 * @retval OMX_ERRORTYPE
1466 */
get_extension_index(OMX_HANDLETYPE cmp_handle,OMX_STRING param_name,OMX_INDEXTYPE * p_index_type)1467 OMX_ERRORTYPE omx_swvdec::get_extension_index(OMX_HANDLETYPE cmp_handle,
1468 OMX_STRING param_name,
1469 OMX_INDEXTYPE *p_index_type)
1470 {
1471 OMX_ERRORTYPE retval = OMX_ErrorNone;
1472
1473 if (m_state == OMX_StateInvalid)
1474 {
1475 OMX_SWVDEC_LOG_ERROR("in invalid state");
1476
1477 retval = OMX_ErrorInvalidState;
1478 }
1479 else if (cmp_handle == NULL)
1480 {
1481 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
1482
1483 retval = OMX_ErrorInvalidComponent;
1484 }
1485 else if (p_index_type == NULL)
1486 {
1487 OMX_SWVDEC_LOG_ERROR("p_index_type = NULL");
1488
1489 retval = OMX_ErrorBadParameter;
1490 }
1491
1492 if (retval != OMX_ErrorNone)
1493 {
1494 goto get_extension_index_exit;
1495 }
1496
1497 OMX_SWVDEC_LOG_API("'%s'", param_name);
1498
1499 if (!strncmp(param_name,
1500 "OMX.QCOM.index.param.video.SyncFrameDecodingMode",
1501 OMX_MAX_STRINGNAME_SIZE))
1502 {
1503 *p_index_type =
1504 (OMX_INDEXTYPE) OMX_QcomIndexParamVideoSyncFrameDecodingMode;
1505 }
1506 else if (!strncmp(param_name,
1507 "OMX.QCOM.index.param.IndexExtraData",
1508 OMX_MAX_STRINGNAME_SIZE))
1509 {
1510 *p_index_type = (OMX_INDEXTYPE) OMX_QcomIndexParamIndexExtraDataType;
1511 }
1512 else if (!strncmp(param_name,
1513 "OMX.google.android.index.enableAndroidNativeBuffers",
1514 OMX_MAX_STRINGNAME_SIZE))
1515 {
1516 *p_index_type =
1517 (OMX_INDEXTYPE) OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
1518 }
1519 else if (!strncmp(param_name,
1520 "OMX.google.android.index.useAndroidNativeBuffer2",
1521 OMX_MAX_STRINGNAME_SIZE))
1522 {
1523 *p_index_type =
1524 (OMX_INDEXTYPE) OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
1525 }
1526 else if (!strncmp(param_name,
1527 "OMX.google.android.index.useAndroidNativeBuffer",
1528 OMX_MAX_STRINGNAME_SIZE))
1529 {
1530 *p_index_type =
1531 (OMX_INDEXTYPE) OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
1532 }
1533 else if (!strncmp(param_name,
1534 "OMX.google.android.index.getAndroidNativeBufferUsage",
1535 OMX_MAX_STRINGNAME_SIZE))
1536 {
1537 *p_index_type =
1538 (OMX_INDEXTYPE) OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
1539 }
1540 else if (!strncmp(param_name,
1541 "OMX.google.android.index.storeMetaDataInBuffers",
1542 OMX_MAX_STRINGNAME_SIZE))
1543 {
1544 *p_index_type = (OMX_INDEXTYPE) OMX_QcomIndexParamVideoMetaBufferMode;
1545 }
1546 else if (!strncmp(param_name,
1547 "OMX.google.android.index.describeColorFormat",
1548 OMX_MAX_STRINGNAME_SIZE))
1549 {
1550 *p_index_type = (OMX_INDEXTYPE) OMX_QcomIndexFlexibleYUVDescription;
1551 }
1552 else if (!strncmp(param_name,
1553 "OMX.google.android.index.prepareForAdaptivePlayback",
1554 OMX_MAX_STRINGNAME_SIZE))
1555 {
1556 *p_index_type =
1557 (OMX_INDEXTYPE) OMX_QcomIndexParamVideoAdaptivePlaybackMode;
1558 }
1559 else
1560 {
1561 OMX_SWVDEC_LOG_ERROR("'%s': not implemented", param_name);
1562
1563 retval = OMX_ErrorNotImplemented;
1564 }
1565
1566 get_extension_index_exit:
1567 return retval;
1568 }
1569
1570 /**
1571 * @brief Get component state.
1572 *
1573 * @param[in] cmp_handle: Component handle.
1574 * @param[in,out] p_state: Pointer to state variable.
1575 *
1576 * @retval OMX_ERRORTYPE
1577 */
get_state(OMX_HANDLETYPE cmp_handle,OMX_STATETYPE * p_state)1578 OMX_ERRORTYPE omx_swvdec::get_state(OMX_HANDLETYPE cmp_handle,
1579 OMX_STATETYPE *p_state)
1580 {
1581 OMX_ERRORTYPE retval = OMX_ErrorNone;
1582
1583 if (cmp_handle == NULL)
1584 {
1585 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
1586
1587 retval = OMX_ErrorInvalidComponent;
1588 }
1589 else
1590 {
1591 OMX_SWVDEC_LOG_API("%s", OMX_STATETYPE_STRING(m_state));
1592
1593 *p_state = m_state;
1594 }
1595
1596 return retval;
1597 }
1598
1599 /**
1600 * @brief Component tunnel request.
1601 *
1602 * @retval OMX_ErrorNotImplemented
1603 */
component_tunnel_request(OMX_HANDLETYPE cmp_handle,OMX_U32 port,OMX_HANDLETYPE peer_component,OMX_U32 peer_port,OMX_TUNNELSETUPTYPE * p_tunnel_setup)1604 OMX_ERRORTYPE omx_swvdec::component_tunnel_request(
1605 OMX_HANDLETYPE cmp_handle,
1606 OMX_U32 port,
1607 OMX_HANDLETYPE peer_component,
1608 OMX_U32 peer_port,
1609 OMX_TUNNELSETUPTYPE *p_tunnel_setup)
1610 {
1611 (void) cmp_handle;
1612 (void) port;
1613 (void) peer_component;
1614 (void) peer_port;
1615 (void) p_tunnel_setup;
1616
1617 OMX_SWVDEC_LOG_API("");
1618
1619 OMX_SWVDEC_LOG_ERROR("not implemented");
1620
1621 return OMX_ErrorNotImplemented;
1622 }
1623
1624 /**
1625 * @brief Use buffer.
1626 *
1627 * @param[in] cmp_handle: Component handle.
1628 * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
1629 * structure.
1630 * @param[in] port: Port index.
1631 * @param[in] p_app_data: Pointer to IL client app data.
1632 * @param[in] bytes: Size of buffer to be allocated in bytes.
1633 * @param[in] p_buffer: Pointer to buffer to be used.
1634 *
1635 * @retval OMX_ERRORTYPE
1636 */
use_buffer(OMX_HANDLETYPE cmp_handle,OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_U32 port,OMX_PTR p_app_data,OMX_U32 bytes,OMX_U8 * p_buffer)1637 OMX_ERRORTYPE omx_swvdec::use_buffer(OMX_HANDLETYPE cmp_handle,
1638 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
1639 OMX_U32 port,
1640 OMX_PTR p_app_data,
1641 OMX_U32 bytes,
1642 OMX_U8 *p_buffer)
1643 {
1644 OMX_ERRORTYPE retval = OMX_ErrorNone;
1645
1646 if (m_state == OMX_StateInvalid)
1647 {
1648 OMX_SWVDEC_LOG_ERROR("in invalid state");
1649
1650 retval = OMX_ErrorInvalidState;
1651 }
1652 else if (cmp_handle == NULL)
1653 {
1654 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
1655
1656 retval = OMX_ErrorInvalidComponent;
1657 }
1658 else if (pp_buffer_hdr == NULL)
1659 {
1660 OMX_SWVDEC_LOG_ERROR("pp_buffer_hdr = NULL");
1661
1662 retval = OMX_ErrorBadParameter;
1663 }
1664 else
1665 {
1666 OMX_SWVDEC_LOG_API("port index %d, %p", port, p_buffer);
1667
1668 if (port == OMX_CORE_PORT_INDEX_OP)
1669 {
1670 retval = buffer_use_op(pp_buffer_hdr, p_app_data, bytes, p_buffer);
1671
1672 if (retval == OMX_ErrorNone)
1673 {
1674 SWVDEC_STATUS retval_swvdec;
1675
1676 if ((m_status_flags & (1 << PENDING_STATE_LOADED_TO_IDLE)) &&
1677 (m_port_ip.populated == OMX_TRUE) &&
1678 (m_port_op.populated == OMX_TRUE))
1679 {
1680 if ((retval_swvdec = swvdec_start(m_swvdec_handle)) !=
1681 SWVDEC_STATUS_SUCCESS)
1682 {
1683 OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
1684
1685 retval = retval_swvdec2omx(retval_swvdec);
1686 goto use_buffer_exit;
1687 }
1688
1689 m_status_flags &= ~(1 << PENDING_STATE_LOADED_TO_IDLE);
1690
1691 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
1692 OMX_CommandStateSet,
1693 OMX_StateIdle);
1694 }
1695
1696 if ((m_status_flags & (1 << PENDING_PORT_ENABLE_OP)) &&
1697 (m_port_op.populated == OMX_TRUE))
1698 {
1699 if (m_port_reconfig_inprogress)
1700 {
1701 if ((retval_swvdec = swvdec_start(m_swvdec_handle)) !=
1702 SWVDEC_STATUS_SUCCESS)
1703 {
1704 OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
1705
1706 retval = retval_swvdec2omx(retval_swvdec);
1707 }
1708 }
1709
1710 m_status_flags &= ~(1 << PENDING_PORT_ENABLE_OP);
1711
1712 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
1713 OMX_CommandPortEnable,
1714 OMX_CORE_PORT_INDEX_OP);
1715 }
1716 }
1717 }
1718 else
1719 {
1720 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", port);
1721
1722 retval = OMX_ErrorBadPortIndex;
1723 }
1724 }
1725
1726 use_buffer_exit:
1727 return retval;
1728 }
1729
1730 /**
1731 * @brief Allocate new buffer & associated header.
1732 *
1733 * @param[in] cmp_handle: Component handle.
1734 * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
1735 * structure.
1736 * @param[in] port: Port index.
1737 * @param[in] p_app_data: Pointer to IL client app data.
1738 * @param[in] bytes: Size of buffer to be allocated in bytes.
1739 *
1740 * @retval OMX_ERRORTYPE
1741 */
allocate_buffer(OMX_HANDLETYPE cmp_handle,OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_U32 port,OMX_PTR p_app_data,OMX_U32 bytes)1742 OMX_ERRORTYPE omx_swvdec::allocate_buffer(OMX_HANDLETYPE cmp_handle,
1743 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
1744 OMX_U32 port,
1745 OMX_PTR p_app_data,
1746 OMX_U32 bytes)
1747 {
1748 OMX_ERRORTYPE retval = OMX_ErrorNone;
1749
1750 if (m_state == OMX_StateInvalid)
1751 {
1752 OMX_SWVDEC_LOG_ERROR("in invalid state");
1753
1754 retval = OMX_ErrorInvalidState;
1755 }
1756 else if (cmp_handle == NULL)
1757 {
1758 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
1759
1760 retval = OMX_ErrorInvalidComponent;
1761 }
1762 else if (pp_buffer_hdr == NULL)
1763 {
1764 OMX_SWVDEC_LOG_ERROR("pp_buffer_hdr = NULL");
1765
1766 retval = OMX_ErrorBadParameter;
1767 }
1768 else
1769 {
1770 OMX_SWVDEC_LOG_API("port index %d, %d bytes", port, bytes);
1771
1772 if (port == OMX_CORE_PORT_INDEX_IP)
1773 {
1774 retval = buffer_allocate_ip(pp_buffer_hdr,
1775 p_app_data,
1776 bytes);
1777 }
1778 else if (port == OMX_CORE_PORT_INDEX_OP)
1779 {
1780 if (m_meta_buffer_mode == true)
1781 {
1782 OMX_SWVDEC_LOG_ERROR("'meta buffer mode' enabled");
1783
1784 retval = OMX_ErrorBadParameter;
1785 }
1786 else if (m_android_native_buffers == true)
1787 {
1788 OMX_SWVDEC_LOG_ERROR("'android native buffers' enabled");
1789
1790 retval = OMX_ErrorBadParameter;
1791 }
1792 else
1793 {
1794 retval = buffer_allocate_op(pp_buffer_hdr,
1795 p_app_data,
1796 bytes);
1797 }
1798 }
1799 else
1800 {
1801 OMX_SWVDEC_LOG_ERROR("port index %d invalid", port);
1802
1803 retval = OMX_ErrorBadPortIndex;
1804 }
1805
1806 if (retval == OMX_ErrorNone)
1807 {
1808 SWVDEC_STATUS retval_swvdec;
1809
1810 if ((m_status_flags & (1 << PENDING_STATE_LOADED_TO_IDLE)) &&
1811 (m_port_ip.populated == OMX_TRUE) &&
1812 (m_port_op.populated == OMX_TRUE))
1813 {
1814 if ((retval_swvdec = swvdec_start(m_swvdec_handle)) !=
1815 SWVDEC_STATUS_SUCCESS)
1816 {
1817 OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
1818
1819 retval = retval_swvdec2omx(retval_swvdec);
1820 goto allocate_buffer_exit;
1821 }
1822
1823 m_status_flags &= ~(1 << PENDING_STATE_LOADED_TO_IDLE);
1824
1825 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
1826 OMX_CommandStateSet,
1827 OMX_StateIdle);
1828 }
1829
1830 if ((m_status_flags & (1 << PENDING_PORT_ENABLE_IP)) &&
1831 (m_port_ip.populated == OMX_TRUE))
1832 {
1833 m_status_flags &= ~(1 << PENDING_PORT_ENABLE_IP);
1834
1835 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
1836 OMX_CommandPortEnable,
1837 OMX_CORE_PORT_INDEX_IP);
1838 }
1839
1840 if ((m_status_flags & (1 << PENDING_PORT_ENABLE_OP)) &&
1841 (m_port_op.populated == OMX_TRUE))
1842 {
1843 if (m_port_reconfig_inprogress)
1844 {
1845 if ((retval_swvdec = swvdec_start(m_swvdec_handle)) !=
1846 SWVDEC_STATUS_SUCCESS)
1847 {
1848 OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
1849
1850 retval = retval_swvdec2omx(retval_swvdec);
1851 }
1852 }
1853
1854 m_status_flags &= ~(1 << PENDING_PORT_ENABLE_OP);
1855
1856 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
1857 OMX_CommandPortEnable,
1858 OMX_CORE_PORT_INDEX_OP);
1859 }
1860 }
1861 }
1862
1863 allocate_buffer_exit:
1864 return retval;
1865 }
1866
1867 /**
1868 * @brief Release buffer & associated header.
1869 *
1870 * @param[in] cmp_handle: Component handle.
1871 * @param[in] port: Port index.
1872 * @param[in] p_buffer_hdr: Pointer to buffer's buffer header.
1873 *
1874 * @retval OMX_ERRORTYPE
1875 */
free_buffer(OMX_HANDLETYPE cmp_handle,OMX_U32 port,OMX_BUFFERHEADERTYPE * p_buffer_hdr)1876 OMX_ERRORTYPE omx_swvdec::free_buffer(OMX_HANDLETYPE cmp_handle,
1877 OMX_U32 port,
1878 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
1879 {
1880 OMX_ERRORTYPE retval = OMX_ErrorNone;
1881
1882 if (cmp_handle == NULL)
1883 {
1884 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
1885
1886 retval = OMX_ErrorInvalidComponent;
1887 }
1888 else if (p_buffer_hdr == NULL)
1889 {
1890 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
1891
1892 retval = OMX_ErrorBadParameter;
1893 }
1894 else if ((port != OMX_CORE_PORT_INDEX_IP) &&
1895 (port != OMX_CORE_PORT_INDEX_OP))
1896 {
1897 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", port);
1898
1899 retval = OMX_ErrorBadPortIndex;
1900 }
1901 else if (m_state != OMX_StateIdle)
1902 {
1903 if (m_state != OMX_StateExecuting)
1904 {
1905 OMX_SWVDEC_LOG_ERROR("disallowed in state %s",
1906 OMX_STATETYPE_STRING(m_state));
1907
1908 retval = OMX_ErrorIncorrectStateOperation;
1909 }
1910 else
1911 {
1912 if (((port == OMX_CORE_PORT_INDEX_IP) && m_port_ip.enabled) ||
1913 ((port == OMX_CORE_PORT_INDEX_OP) && m_port_op.enabled))
1914 {
1915 OMX_SWVDEC_LOG_ERROR("port index %d not disabled", port);
1916
1917 retval = OMX_ErrorBadPortIndex;
1918 }
1919 }
1920 }
1921
1922 if (retval == OMX_ErrorNone)
1923 {
1924 OMX_SWVDEC_LOG_API("port index %d, %p", port, p_buffer_hdr);
1925
1926 if (port == OMX_CORE_PORT_INDEX_IP)
1927 {
1928 retval = buffer_deallocate_ip(p_buffer_hdr);
1929 }
1930 else
1931 {
1932 retval = buffer_deallocate_op(p_buffer_hdr);
1933 }
1934 }
1935
1936 if ((retval == OMX_ErrorNone) &&
1937 (m_status_flags & (1 << PENDING_STATE_IDLE_TO_LOADED)))
1938 {
1939 if ((m_port_ip.unpopulated == OMX_TRUE) &&
1940 (m_port_op.unpopulated == OMX_TRUE))
1941 {
1942 SWVDEC_STATUS retval_swvdec;
1943
1944 if ((retval_swvdec = swvdec_stop(m_swvdec_handle)) ==
1945 SWVDEC_STATUS_SUCCESS)
1946 {
1947 m_status_flags &= ~(1 << PENDING_STATE_IDLE_TO_LOADED);
1948
1949 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
1950 OMX_CommandStateSet,
1951 OMX_StateLoaded);
1952 }
1953 else
1954 {
1955 OMX_SWVDEC_LOG_ERROR("failed to stop SwVdec");
1956
1957 retval = retval_swvdec2omx(retval_swvdec);
1958 }
1959 }
1960 }
1961
1962 if ((retval == OMX_ErrorNone) &&
1963 (m_status_flags & (1 << PENDING_PORT_DISABLE_IP)) &&
1964 m_port_ip.unpopulated)
1965 {
1966 m_status_flags &= ~(1 << PENDING_PORT_DISABLE_IP);
1967
1968 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
1969 OMX_CommandPortDisable,
1970 OMX_CORE_PORT_INDEX_IP);
1971 }
1972
1973 if ((retval == OMX_ErrorNone) &&
1974 (m_status_flags & (1 << PENDING_PORT_DISABLE_OP)) &&
1975 m_port_op.unpopulated)
1976 {
1977 if (m_port_reconfig_inprogress)
1978 {
1979 SWVDEC_STATUS retval_swvdec;
1980
1981 if ((retval_swvdec = swvdec_stop(m_swvdec_handle)) !=
1982 SWVDEC_STATUS_SUCCESS)
1983 {
1984 OMX_SWVDEC_LOG_ERROR("failed to stop SwVdec");
1985
1986 retval = retval_swvdec2omx(retval_swvdec);
1987 }
1988 }
1989
1990 m_status_flags &= ~(1 << PENDING_PORT_DISABLE_OP);
1991
1992 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
1993 OMX_CommandPortDisable,
1994 OMX_CORE_PORT_INDEX_OP);
1995 }
1996
1997 return retval;
1998 }
1999
2000 /**
2001 * @brief Send a buffer to component's input port to be emptied.
2002 *
2003 * @param[in] cmp_handle: Component handle.
2004 * @param[in] p_buffer_hdr: Pointer to buffer's buffer header.
2005 *
2006 * @retval OMX_ERRORTYPE
2007 */
empty_this_buffer(OMX_HANDLETYPE cmp_handle,OMX_BUFFERHEADERTYPE * p_buffer_hdr)2008 OMX_ERRORTYPE omx_swvdec::empty_this_buffer(OMX_HANDLETYPE cmp_handle,
2009 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
2010 {
2011 OMX_ERRORTYPE retval = OMX_ErrorNone;
2012
2013 unsigned int ii;
2014
2015 if (m_state == OMX_StateInvalid)
2016 {
2017 OMX_SWVDEC_LOG_ERROR("in invalid state");
2018
2019 retval = OMX_ErrorInvalidState;
2020 }
2021 else if (cmp_handle == NULL)
2022 {
2023 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
2024
2025 retval = OMX_ErrorInvalidComponent;
2026 }
2027 else if (p_buffer_hdr == NULL)
2028 {
2029 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
2030
2031 retval = OMX_ErrorBadParameter;
2032 }
2033 else if (p_buffer_hdr->pBuffer == NULL)
2034 {
2035 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr->pBuffer = NULL");
2036
2037 retval = OMX_ErrorBadParameter;
2038 }
2039 else if (p_buffer_hdr->pInputPortPrivate == NULL)
2040 {
2041 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr->pInputPortPrivate = NULL");
2042
2043 retval = OMX_ErrorBadParameter;
2044 }
2045 else if (m_port_ip.enabled == OMX_FALSE)
2046 {
2047 OMX_SWVDEC_LOG_ERROR("ip port disabled");
2048
2049 retval = OMX_ErrorIncorrectStateOperation;
2050 }
2051 else if (p_buffer_hdr->nInputPortIndex != OMX_CORE_PORT_INDEX_IP)
2052 {
2053 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
2054 p_buffer_hdr->nInputPortIndex);
2055
2056 retval = OMX_ErrorBadPortIndex;
2057 }
2058
2059 if (retval != OMX_ErrorNone)
2060 {
2061 goto empty_this_buffer_exit;
2062 }
2063
2064 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
2065 {
2066 if (p_buffer_hdr == &(m_buffer_array_ip[ii].buffer_header))
2067 {
2068 OMX_SWVDEC_LOG_LOW("ip buffer %p has index %d",
2069 p_buffer_hdr->pBuffer,
2070 ii);
2071 break;
2072 }
2073 }
2074
2075 if (ii == m_port_ip.def.nBufferCountActual)
2076 {
2077 OMX_SWVDEC_LOG_ERROR("ip buffer %p not found",
2078 p_buffer_hdr->pBuffer);
2079
2080 retval = OMX_ErrorBadParameter;
2081 goto empty_this_buffer_exit;
2082 }
2083
2084 OMX_SWVDEC_LOG_API("%p: buffer %p, flags 0x%08x, filled length %d, "
2085 "timestamp %lld",
2086 p_buffer_hdr,
2087 p_buffer_hdr->pBuffer,
2088 p_buffer_hdr->nFlags,
2089 p_buffer_hdr->nFilledLen,
2090 p_buffer_hdr->nTimeStamp);
2091
2092 async_post_event(OMX_SWVDEC_EVENT_ETB,
2093 (unsigned long) p_buffer_hdr,
2094 (unsigned long) ii);
2095
2096 empty_this_buffer_exit:
2097 return retval;
2098 }
2099
2100 /**
2101 * @brief Send a buffer to component's output port to be filled.
2102 *
2103 * @param[in] cmp_handle: Component handle.
2104 * @param[in] p_buffer_hdr: Pointer to buffer's buffer header.
2105 *
2106 * @retval OMX_ERRORTYPE
2107 */
fill_this_buffer(OMX_HANDLETYPE cmp_handle,OMX_BUFFERHEADERTYPE * p_buffer_hdr)2108 OMX_ERRORTYPE omx_swvdec::fill_this_buffer(OMX_HANDLETYPE cmp_handle,
2109 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
2110 {
2111 OMX_ERRORTYPE retval = OMX_ErrorNone;
2112
2113 unsigned int ii;
2114
2115 SWVDEC_BUFFER *p_buffer_swvdec;
2116
2117 if (m_state == OMX_StateInvalid)
2118 {
2119 OMX_SWVDEC_LOG_ERROR("in invalid state");
2120
2121 retval = OMX_ErrorInvalidState;
2122 }
2123 else if (cmp_handle == NULL)
2124 {
2125 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
2126
2127 retval = OMX_ErrorInvalidComponent;
2128 }
2129 else if (p_buffer_hdr == NULL)
2130 {
2131 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
2132
2133 retval = OMX_ErrorBadParameter;
2134 }
2135 else if (p_buffer_hdr->pBuffer == NULL)
2136 {
2137 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr->pBuffer = NULL");
2138
2139 retval = OMX_ErrorBadParameter;
2140 }
2141 else if (p_buffer_hdr->pOutputPortPrivate == NULL)
2142 {
2143 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr->pOutputPortPrivate = NULL");
2144
2145 retval = OMX_ErrorBadParameter;
2146 }
2147 else if (m_port_op.enabled == OMX_FALSE)
2148 {
2149 OMX_SWVDEC_LOG_ERROR("op port disabled");
2150
2151 retval = OMX_ErrorIncorrectStateOperation;
2152 }
2153 else if (p_buffer_hdr->nOutputPortIndex != OMX_CORE_PORT_INDEX_OP)
2154 {
2155 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
2156 p_buffer_hdr->nOutputPortIndex);
2157
2158 retval = OMX_ErrorBadPortIndex;
2159 }
2160
2161 if (retval != OMX_ErrorNone)
2162 {
2163 goto fill_this_buffer_exit;
2164 }
2165
2166 OMX_SWVDEC_LOG_API("%p", p_buffer_hdr);
2167
2168 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
2169 {
2170 if (p_buffer_hdr == &(m_buffer_array_op[ii].buffer_header))
2171 {
2172 OMX_SWVDEC_LOG_LOW("op buffer %p has index %d",
2173 p_buffer_hdr->pBuffer,
2174 ii);
2175 break;
2176 }
2177 }
2178
2179 if (ii == m_port_op.def.nBufferCountActual)
2180 {
2181 OMX_SWVDEC_LOG_ERROR("op buffer %p not found",
2182 p_buffer_hdr->pBuffer);
2183
2184 retval = OMX_ErrorBadParameter;
2185 goto fill_this_buffer_exit;
2186 }
2187
2188 p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
2189
2190 if (m_meta_buffer_mode)
2191 {
2192 struct VideoDecoderOutputMetaData *p_meta_data;
2193
2194 private_handle_t *p_private_handle;
2195
2196 struct vdec_bufferpayload *p_buffer_payload;
2197
2198 p_meta_data =
2199 (struct VideoDecoderOutputMetaData *) p_buffer_hdr->pBuffer;
2200
2201 p_private_handle = (private_handle_t *) (p_meta_data->pHandle);
2202
2203 p_buffer_payload = &m_buffer_array_op[ii].buffer_payload;
2204
2205 if (p_private_handle == NULL)
2206 {
2207 OMX_SWVDEC_LOG_ERROR(
2208 "p_buffer_hdr->pBuffer->pHandle = NULL");
2209
2210 retval = OMX_ErrorBadParameter;
2211 goto fill_this_buffer_exit;
2212 }
2213
2214 pthread_mutex_lock(&m_meta_buffer_array_mutex);
2215
2216 if (m_meta_buffer_array[ii].ref_count == 0)
2217 {
2218 unsigned char *bufferaddr;
2219
2220 bufferaddr = (unsigned char *) mmap(NULL,
2221 m_port_op.def.nBufferSize,
2222 PROT_READ | PROT_WRITE,
2223 MAP_SHARED,
2224 p_private_handle->fd,
2225 0);
2226
2227 if (bufferaddr == MAP_FAILED)
2228 {
2229 OMX_SWVDEC_LOG_ERROR("mmap() failed for "
2230 "fd %d of size %d",
2231 p_private_handle->fd,
2232 m_port_op.def.nBufferSize);
2233
2234 pthread_mutex_unlock(&m_meta_buffer_array_mutex);
2235
2236 retval = OMX_ErrorInsufficientResources;
2237 goto fill_this_buffer_exit;
2238 }
2239
2240 p_buffer_payload->bufferaddr = bufferaddr;
2241 p_buffer_payload->pmem_fd = p_private_handle->fd;
2242 p_buffer_payload->buffer_len = m_port_op.def.nBufferSize;
2243 p_buffer_payload->mmaped_size = m_port_op.def.nBufferSize;
2244
2245 p_buffer_swvdec->p_buffer = bufferaddr;
2246 p_buffer_swvdec->size = m_port_op.def.nBufferSize;
2247 p_buffer_swvdec->p_client_data = (void *) ((unsigned long) ii);
2248 }
2249
2250 meta_buffer_ref_add(ii, p_buffer_payload->pmem_fd);
2251
2252 pthread_mutex_unlock(&m_meta_buffer_array_mutex);
2253 }
2254
2255 OMX_SWVDEC_LOG_LOW("%p: buffer %p",
2256 p_buffer_hdr,
2257 p_buffer_swvdec->p_buffer);
2258
2259 async_post_event(OMX_SWVDEC_EVENT_FTB,
2260 (unsigned long) p_buffer_hdr,
2261 (unsigned long) ii);
2262
2263 fill_this_buffer_exit:
2264 return retval;
2265 }
2266
2267 /**
2268 * @brief Set component's callback structure.
2269 *
2270 * @param[in] cmp_handle: Component handle.
2271 * @param[in] p_callbacks: Pointer to callback structure.
2272 * @param[in] p_app_data: Pointer to IL client app data.
2273 *
2274 * @retval OMX_ERRORTYPE
2275 */
set_callbacks(OMX_HANDLETYPE cmp_handle,OMX_CALLBACKTYPE * p_callbacks,OMX_PTR p_app_data)2276 OMX_ERRORTYPE omx_swvdec::set_callbacks(OMX_HANDLETYPE cmp_handle,
2277 OMX_CALLBACKTYPE *p_callbacks,
2278 OMX_PTR p_app_data)
2279 {
2280 OMX_ERRORTYPE retval = OMX_ErrorNone;
2281
2282 OMX_SWVDEC_LOG_API("");
2283
2284 if (m_state == OMX_StateInvalid)
2285 {
2286 OMX_SWVDEC_LOG_ERROR("in invalid state");
2287
2288 retval = OMX_ErrorInvalidState;
2289 }
2290 else if (cmp_handle == NULL)
2291 {
2292 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
2293
2294 retval = OMX_ErrorInvalidComponent;
2295 }
2296 else if (p_callbacks->EventHandler == NULL)
2297 {
2298 OMX_SWVDEC_LOG_ERROR("p_callbacks->EventHandler = NULL");
2299
2300 retval = OMX_ErrorBadParameter;
2301 }
2302 else if (p_callbacks->EmptyBufferDone == NULL)
2303 {
2304 OMX_SWVDEC_LOG_ERROR("p_callbacks->EmptyBufferDone = NULL");
2305
2306 retval = OMX_ErrorBadParameter;
2307 }
2308 else if (p_callbacks->FillBufferDone == NULL)
2309 {
2310 OMX_SWVDEC_LOG_ERROR("p_callbacks->FillBufferDone = NULL");
2311
2312 retval = OMX_ErrorBadParameter;
2313 }
2314 else
2315 {
2316 m_callback = *p_callbacks;
2317 m_app_data = p_app_data;
2318 }
2319
2320 return retval;
2321 }
2322
2323 /**
2324 * @brief Use EGL image.
2325 *
2326 * @retval OMX_ErrorNotImplemented
2327 */
use_EGL_image(OMX_HANDLETYPE cmp_handle,OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_U32 port,OMX_PTR p_app_data,void * egl_image)2328 OMX_ERRORTYPE omx_swvdec::use_EGL_image(OMX_HANDLETYPE cmp_handle,
2329 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
2330 OMX_U32 port,
2331 OMX_PTR p_app_data,
2332 void *egl_image)
2333 {
2334 (void) cmp_handle;
2335 (void) pp_buffer_hdr;
2336 (void) port;
2337 (void) p_app_data;
2338 (void) egl_image;
2339
2340 OMX_SWVDEC_LOG_API("");
2341
2342 OMX_SWVDEC_LOG_ERROR("not implemented");
2343
2344 return OMX_ErrorNotImplemented;
2345 }
2346
2347 /**
2348 * @brief Enumerate component role.
2349 *
2350 * @param[in] cmp_handle: Component handle.
2351 * @param[in,out] p_role: Pointer to component role string.
2352 * @param[in] index: Role index being queried.
2353 *
2354 * @retval OMX_ERRORTYPE
2355 */
component_role_enum(OMX_HANDLETYPE cmp_handle,OMX_U8 * p_role,OMX_U32 index)2356 OMX_ERRORTYPE omx_swvdec::component_role_enum(OMX_HANDLETYPE cmp_handle,
2357 OMX_U8 *p_role,
2358 OMX_U32 index)
2359 {
2360 OMX_ERRORTYPE retval = OMX_ErrorNone;
2361
2362 if (m_state == OMX_StateInvalid)
2363 {
2364 OMX_SWVDEC_LOG_ERROR("in invalid state");
2365
2366 retval = OMX_ErrorInvalidState;
2367 }
2368 else if (cmp_handle == NULL)
2369 {
2370 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
2371
2372 retval = OMX_ErrorInvalidComponent;
2373 }
2374 else if (index > 0)
2375 {
2376 OMX_SWVDEC_LOG_HIGH("index '%d' unsupported; no more roles", index);
2377
2378 retval = OMX_ErrorNoMore;
2379 }
2380 else
2381 {
2382 memcpy(p_role, m_role_name, OMX_MAX_STRINGNAME_SIZE);
2383
2384 OMX_SWVDEC_LOG_API("index '%d': '%s'", index, p_role);
2385 }
2386
2387 return retval;
2388 }
2389
2390 /**
2391 * -------------------------
2392 * SwVdec callback functions
2393 * -------------------------
2394 */
2395
2396 /**
2397 * @brief SwVdec empty buffer done callback.
2398 *
2399 * @param[in] swvdec_handle: SwVdec handle.
2400 * @param[in] p_buffer_ip: Pointer to input buffer structure.
2401 * @param[in] p_client_handle: Pointer to SwVdec's client handle.
2402 *
2403 * @retval SWVDEC_STATUS_SUCCESS
2404 * @retval SWVDEC_STATUS_NULL_POINTER
2405 * @retval SWVDEC_STATUS_INVALID_PARAMETERS
2406 */
swvdec_empty_buffer_done_callback(SWVDEC_HANDLE swvdec_handle,SWVDEC_BUFFER * p_buffer_ip,void * p_client_handle)2407 SWVDEC_STATUS omx_swvdec::swvdec_empty_buffer_done_callback(
2408 SWVDEC_HANDLE swvdec_handle,
2409 SWVDEC_BUFFER *p_buffer_ip,
2410 void *p_client_handle)
2411 {
2412 SWVDEC_STATUS retval = SWVDEC_STATUS_SUCCESS;
2413
2414 if (p_buffer_ip == NULL)
2415 {
2416 OMX_SWVDEC_LOG_ERROR("p_buffer_ip = NULL");
2417
2418 retval = SWVDEC_STATUS_NULL_POINTER;
2419 }
2420 else if (p_client_handle == NULL)
2421 {
2422 OMX_SWVDEC_LOG_ERROR("p_client_handle = NULL");
2423
2424 retval = SWVDEC_STATUS_NULL_POINTER;
2425 }
2426 else
2427 {
2428 omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_client_handle;
2429
2430 if (swvdec_handle != p_omx_swvdec->m_swvdec_handle)
2431 {
2432 OMX_SWVDEC_LOG_ERROR("invalid SwVdec handle");
2433
2434 retval = SWVDEC_STATUS_INVALID_PARAMETERS;
2435 }
2436 else
2437 {
2438 p_omx_swvdec->swvdec_empty_buffer_done(p_buffer_ip);
2439 }
2440 }
2441
2442 return retval;
2443 }
2444
2445 /**
2446 * @brief SwVdec fill buffer done callback.
2447 *
2448 * @param[in] swvdec_handle: SwVdec handle.
2449 * @param[in] p_buffer_op: Pointer to output buffer structure.
2450 * @param[in] p_client_handle: Pointer to SwVdec's client handle.
2451 *
2452 * @retval SWVDEC_STATUS_SUCCESS
2453 * @retval SWVDEC_STATUS_NULL_POINTER
2454 * @retval SWVDEC_STATUS_INVALID_PARAMETERS
2455 */
swvdec_fill_buffer_done_callback(SWVDEC_HANDLE swvdec_handle,SWVDEC_BUFFER * p_buffer_op,void * p_client_handle)2456 SWVDEC_STATUS omx_swvdec::swvdec_fill_buffer_done_callback(
2457 SWVDEC_HANDLE swvdec_handle,
2458 SWVDEC_BUFFER *p_buffer_op,
2459 void *p_client_handle)
2460 {
2461 SWVDEC_STATUS retval = SWVDEC_STATUS_SUCCESS;
2462
2463 if (p_buffer_op == NULL)
2464 {
2465 OMX_SWVDEC_LOG_ERROR("p_buffer_op = NULL");
2466
2467 retval = SWVDEC_STATUS_NULL_POINTER;
2468 }
2469 else if (p_client_handle == NULL)
2470 {
2471 OMX_SWVDEC_LOG_ERROR("p_client_handle = NULL");
2472
2473 retval = SWVDEC_STATUS_NULL_POINTER;
2474 }
2475 else
2476 {
2477 omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_client_handle;
2478
2479 if (swvdec_handle != p_omx_swvdec->m_swvdec_handle)
2480 {
2481 OMX_SWVDEC_LOG_ERROR("invalid SwVdec handle");
2482
2483 retval = SWVDEC_STATUS_INVALID_PARAMETERS;
2484 }
2485 else
2486 {
2487 p_omx_swvdec->swvdec_fill_buffer_done(p_buffer_op);
2488 }
2489 }
2490
2491 return retval;
2492 }
2493
2494 /**
2495 * @brief SwVdec event handler callback.
2496 *
2497 * @param[in] swvdec_handle: SwVdec handle.
2498 * @param[in] event: Event.
2499 * @param[in] p_data: Pointer to event-specific data.
2500 * @param[in] p_client_handle: Pointer to SwVdec's client handle.
2501 *
2502 * @retval SWVDEC_STATUS_SUCCESS
2503 * @retval SWVDEC_STATUS_NULL_POINTER
2504 * @retval SWVDEC_STATUS_INVALID_PARAMETERS
2505 */
swvdec_event_handler_callback(SWVDEC_HANDLE swvdec_handle,SWVDEC_EVENT event,void * p_data,void * p_client_handle)2506 SWVDEC_STATUS omx_swvdec::swvdec_event_handler_callback(
2507 SWVDEC_HANDLE swvdec_handle,
2508 SWVDEC_EVENT event,
2509 void *p_data,
2510 void *p_client_handle)
2511 {
2512 SWVDEC_STATUS retval = SWVDEC_STATUS_SUCCESS;
2513
2514 if ((event == SWVDEC_EVENT_RELEASE_REFERENCE) && (p_data == NULL))
2515 {
2516 OMX_SWVDEC_LOG_ERROR("p_data = NULL");
2517
2518 retval = SWVDEC_STATUS_NULL_POINTER;
2519 }
2520 else if (p_client_handle == NULL)
2521 {
2522 OMX_SWVDEC_LOG_ERROR("p_client_handle = NULL");
2523
2524 retval = SWVDEC_STATUS_NULL_POINTER;
2525 }
2526 else
2527 {
2528 omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_client_handle;
2529
2530 if (swvdec_handle != p_omx_swvdec->m_swvdec_handle)
2531 {
2532 OMX_SWVDEC_LOG_ERROR("invalid SwVdec handle");
2533
2534 retval = SWVDEC_STATUS_INVALID_PARAMETERS;
2535 }
2536 else
2537 {
2538 p_omx_swvdec->swvdec_event_handler(event, p_data);
2539 }
2540 }
2541
2542 return retval;
2543 }
2544
2545 /**
2546 * -----------------
2547 * PRIVATE FUNCTIONS
2548 * -----------------
2549 */
2550
2551 /**
2552 * @brief Set frame dimensions for OMX component & SwVdec core.
2553 *
2554 * @param[in] width: Frame width.
2555 * @param[in] height: Frame height.
2556 *
2557 * @retval OMX_ERRORTYPE
2558 */
set_frame_dimensions(unsigned int width,unsigned int height)2559 OMX_ERRORTYPE omx_swvdec::set_frame_dimensions(unsigned int width,
2560 unsigned int height)
2561 {
2562 OMX_ERRORTYPE retval;
2563
2564 m_frame_dimensions.width = width;
2565 m_frame_dimensions.height = height;
2566
2567 OMX_SWVDEC_LOG_HIGH("%d x %d",
2568 m_frame_dimensions.width,
2569 m_frame_dimensions.height);
2570
2571 retval = set_frame_dimensions_swvdec();
2572
2573 return retval;
2574 }
2575
2576 /**
2577 * @brief Set frame attributes for OMX component & SwVdec core, based on
2578 * frame dimensions & color format.
2579 *
2580 * @param[in] color_format: Color format.
2581 *
2582 * @retval OMX_ERRORTYPE
2583 */
set_frame_attributes(OMX_COLOR_FORMATTYPE color_format)2584 OMX_ERRORTYPE omx_swvdec::set_frame_attributes(
2585 OMX_COLOR_FORMATTYPE color_format)
2586 {
2587 OMX_ERRORTYPE retval = OMX_ErrorNone;
2588
2589 unsigned int width = m_frame_dimensions.width;
2590 unsigned int height = m_frame_dimensions.height;
2591
2592 unsigned int scanlines_uv;
2593
2594 unsigned int plane_size_y;
2595 unsigned int plane_size_uv;
2596
2597 switch (color_format)
2598 {
2599
2600 case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m:
2601 {
2602 /**
2603 * alignment factors:
2604 *
2605 * - stride: 128
2606 * - scanlines_y: 32
2607 * - scanlines_uv: 16
2608 * - size: 4096
2609 */
2610
2611 m_frame_attributes.stride = ALIGN(width, 128);
2612 m_frame_attributes.scanlines = ALIGN(height, 32);
2613
2614 scanlines_uv = ALIGN(height / 2, 16);
2615
2616 plane_size_y = (m_frame_attributes.stride *
2617 m_frame_attributes.scanlines);
2618
2619 plane_size_uv = m_frame_attributes.stride * scanlines_uv;
2620
2621 m_frame_attributes.size = ALIGN(plane_size_y + plane_size_uv, 4096);
2622
2623 OMX_SWVDEC_LOG_HIGH("'OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m': "
2624 "stride %d, scanlines %d, size %d",
2625 m_frame_attributes.stride,
2626 m_frame_attributes.scanlines,
2627 m_frame_attributes.size);
2628
2629 break;
2630 }
2631
2632 case OMX_COLOR_FormatYUV420SemiPlanar:
2633 {
2634 /**
2635 * alignment factors:
2636 *
2637 * - stride: 16
2638 * - scanlines_y: 16
2639 * - scanlines_uv: 16
2640 * - size: 4096
2641 */
2642
2643 m_frame_attributes.stride = ALIGN(width, 16);
2644 m_frame_attributes.scanlines = ALIGN(height, 16);
2645
2646 scanlines_uv = ALIGN(height / 2, 16);
2647
2648 plane_size_y = (m_frame_attributes.stride *
2649 m_frame_attributes.scanlines);
2650
2651 plane_size_uv = m_frame_attributes.stride * scanlines_uv;
2652
2653 m_frame_attributes.size = ALIGN(plane_size_y + plane_size_uv, 4096);
2654
2655 OMX_SWVDEC_LOG_HIGH("'OMX_COLOR_FormatYUV420SemiPlanar': "
2656 "stride %d, scanlines %d, size %d",
2657 m_frame_attributes.stride,
2658 m_frame_attributes.scanlines,
2659 m_frame_attributes.size);
2660
2661 break;
2662 }
2663
2664 default:
2665 {
2666 OMX_SWVDEC_LOG_ERROR("'0x%08x' color format invalid or unsupported",
2667 color_format);
2668
2669 retval = OMX_ErrorBadParameter;
2670 break;
2671 }
2672
2673 } // switch (color_format)
2674
2675 if (retval == OMX_ErrorNone)
2676 {
2677 m_omx_color_formattype = color_format;
2678
2679 retval = set_frame_attributes_swvdec();
2680 }
2681
2682 return retval;
2683 }
2684
2685 /**
2686 * @brief Set maximum adaptive playback frame dimensions for OMX component &
2687 * SwVdec core.
2688 *
2689 * @param[in] width: Max adaptive playback frame width.
2690 * @param[in] height: Max adaptive playback frame height.
2691 *
2692 * @retval OMX_ERRORTYPE
2693 */
set_adaptive_playback(unsigned int max_width,unsigned int max_height)2694 OMX_ERRORTYPE omx_swvdec::set_adaptive_playback(unsigned int max_width,
2695 unsigned int max_height)
2696 {
2697 OMX_ERRORTYPE retval;
2698
2699 m_frame_dimensions_max.width = max_width;
2700 m_frame_dimensions_max.height = max_height;
2701
2702 OMX_SWVDEC_LOG_HIGH("%d x %d",
2703 m_frame_dimensions_max.width,
2704 m_frame_dimensions_max.height);
2705
2706 retval = set_adaptive_playback_swvdec();
2707
2708 if (retval == OMX_ErrorNone)
2709 {
2710 retval = set_frame_dimensions(max_width, max_height);
2711 }
2712
2713 if (retval == OMX_ErrorNone)
2714 {
2715 retval = set_frame_attributes(m_omx_color_formattype);
2716 }
2717
2718 return retval;
2719 }
2720
2721 /**
2722 * @brief Get video port format for input or output port.
2723 *
2724 * @param[in,out] p_port_format: Pointer to video port format type.
2725 *
2726 * @retval OMX_ERRORTYPE
2727 */
get_video_port_format(OMX_VIDEO_PARAM_PORTFORMATTYPE * p_port_format)2728 OMX_ERRORTYPE omx_swvdec::get_video_port_format(
2729 OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format)
2730 {
2731 OMX_ERRORTYPE retval = OMX_ErrorNone;
2732
2733 if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_IP)
2734 {
2735 if (p_port_format->nIndex == 0)
2736 {
2737 p_port_format->eColorFormat = OMX_COLOR_FormatUnused;
2738
2739 p_port_format->eCompressionFormat = m_omx_video_codingtype;
2740
2741 OMX_SWVDEC_LOG_HIGH("color format 0x%08x, "
2742 "compression format 0x%08x",
2743 p_port_format->eColorFormat,
2744 p_port_format->eCompressionFormat);
2745 }
2746 else
2747 {
2748 OMX_SWVDEC_LOG_HIGH("index '%d' unsupported; "
2749 "no more compression formats",
2750 p_port_format->nIndex);
2751
2752 retval = OMX_ErrorNoMore;
2753 }
2754 }
2755 else if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_OP)
2756 {
2757 if (p_port_format->nIndex == 0)
2758 {
2759 p_port_format->eColorFormat =
2760 OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m;
2761
2762 p_port_format->eCompressionFormat = OMX_VIDEO_CodingUnused;
2763
2764 OMX_SWVDEC_LOG_HIGH("color format 0x%08x, "
2765 "compression format 0x%08x",
2766 p_port_format->eColorFormat,
2767 p_port_format->eCompressionFormat);
2768 }
2769 else if (p_port_format->nIndex == 1)
2770 {
2771 p_port_format->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2772
2773 p_port_format->eCompressionFormat = OMX_VIDEO_CodingUnused;
2774
2775 OMX_SWVDEC_LOG_HIGH("color format 0x%08x, "
2776 "compression format 0x%08x",
2777 p_port_format->eColorFormat,
2778 p_port_format->eCompressionFormat);
2779 }
2780 else
2781 {
2782 OMX_SWVDEC_LOG_HIGH("index '%d' unsupported; no more color formats",
2783 p_port_format->nIndex);
2784
2785 retval = OMX_ErrorNoMore;
2786 }
2787 }
2788 else
2789 {
2790 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
2791 p_port_format->nPortIndex);
2792
2793 retval = OMX_ErrorBadPortIndex;
2794 }
2795
2796 return retval;
2797 }
2798
2799 /**
2800 * @brief Set video port format for input or output port.
2801 *
2802 * @param[in] p_port_format: Pointer to video port format type.
2803 *
2804 * @retval OMX_ERRORTYPE
2805 */
set_video_port_format(OMX_VIDEO_PARAM_PORTFORMATTYPE * p_port_format)2806 OMX_ERRORTYPE omx_swvdec::set_video_port_format(
2807 OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format)
2808 {
2809 OMX_ERRORTYPE retval = OMX_ErrorNone;
2810
2811 if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_IP)
2812 {
2813 OMX_SWVDEC_LOG_HIGH("OMX_IndexParamVideoPortFormat, port index 0; "
2814 "doing nothing");
2815 }
2816 else if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_OP)
2817 {
2818 retval = set_frame_attributes(p_port_format->eColorFormat);
2819 }
2820 else
2821 {
2822 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
2823 p_port_format->nPortIndex);
2824
2825 retval = OMX_ErrorBadPortIndex;
2826 }
2827
2828 return retval;
2829 }
2830
2831 /**
2832 * @brief Get port definition for input or output port.
2833 *
2834 * @param[in,out] p_port_def: Pointer to port definition type.
2835 *
2836 * @retval OMX_ERRORTYPE
2837 */
get_port_definition(OMX_PARAM_PORTDEFINITIONTYPE * p_port_def)2838 OMX_ERRORTYPE omx_swvdec::get_port_definition(
2839 OMX_PARAM_PORTDEFINITIONTYPE *p_port_def)
2840 {
2841 OMX_ERRORTYPE retval = OMX_ErrorNone;
2842
2843 p_port_def->eDomain = OMX_PortDomainVideo;
2844
2845 if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP)
2846 {
2847 if ((retval = get_buffer_requirements_swvdec(OMX_CORE_PORT_INDEX_IP)) !=
2848 OMX_ErrorNone)
2849 {
2850 goto get_port_definition_exit;
2851 }
2852
2853 p_port_def->eDir = OMX_DirInput;
2854 p_port_def->nBufferCountActual = m_port_ip.def.nBufferCountActual;
2855 p_port_def->nBufferCountMin = m_port_ip.def.nBufferCountMin;
2856 p_port_def->nBufferSize = m_port_ip.def.nBufferSize;
2857 p_port_def->bEnabled = m_port_ip.enabled;
2858 p_port_def->bPopulated = m_port_ip.populated;
2859
2860 // VTS uses input port dimensions to set OP dimensions
2861 if ((retval = get_frame_dimensions_swvdec()) != OMX_ErrorNone)
2862 {
2863 goto get_port_definition_exit;
2864 }
2865
2866 p_port_def->format.video.nFrameWidth = m_frame_dimensions.width;
2867 p_port_def->format.video.nFrameHeight = m_frame_dimensions.height;
2868
2869 OMX_SWVDEC_LOG_HIGH("port index %d: "
2870 "count actual %d, count min %d, size %d, %d x %d",
2871 p_port_def->nPortIndex,
2872 p_port_def->nBufferCountActual,
2873 p_port_def->nBufferCountMin,
2874 p_port_def->nBufferSize,
2875 p_port_def->format.video.nFrameWidth,
2876 p_port_def->format.video.nFrameHeight);
2877
2878 p_port_def->format.video.eColorFormat = OMX_COLOR_FormatUnused;
2879 p_port_def->format.video.eCompressionFormat = m_omx_video_codingtype;
2880 }
2881 else if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP)
2882 {
2883 if ((retval = get_frame_dimensions_swvdec()) != OMX_ErrorNone)
2884 {
2885 goto get_port_definition_exit;
2886 }
2887
2888 p_port_def->format.video.nFrameWidth = m_frame_dimensions.width;
2889 p_port_def->format.video.nFrameHeight = m_frame_dimensions.height;
2890
2891 if (m_port_reconfig_inprogress)
2892 {
2893 if ((retval = set_frame_attributes(m_omx_color_formattype)) !=
2894 OMX_ErrorNone)
2895 {
2896 goto get_port_definition_exit;
2897 }
2898 }
2899
2900 if ((retval = get_frame_attributes_swvdec()) != OMX_ErrorNone)
2901 {
2902 goto get_port_definition_exit;
2903 }
2904
2905 p_port_def->format.video.nStride = m_frame_attributes.stride;
2906 p_port_def->format.video.nSliceHeight = m_frame_attributes.scanlines;
2907
2908 OMX_SWVDEC_LOG_HIGH("port index %d: "
2909 "%d x %d, stride %d, sliceheight %d",
2910 p_port_def->nPortIndex,
2911 p_port_def->format.video.nFrameWidth,
2912 p_port_def->format.video.nFrameHeight,
2913 p_port_def->format.video.nStride,
2914 p_port_def->format.video.nSliceHeight);
2915
2916 /**
2917 * Query to SwVdec core for buffer requirements is not allowed in
2918 * executing state since it will overwrite the component's buffer
2919 * requirements updated via the most recent set_parameter().
2920 *
2921 * Buffer requirements communicated to component via set_parameter() are
2922 * not propagated to SwVdec core.
2923 *
2924 * The only execption is if port reconfiguration is in progress, in
2925 * which case the query to SwVdec core is required since buffer
2926 * requirements can change based on new dimensions.
2927 */
2928 if ((m_state != OMX_StateExecuting) || m_port_reconfig_inprogress)
2929 {
2930 if ((retval =
2931 get_buffer_requirements_swvdec(OMX_CORE_PORT_INDEX_OP)) !=
2932 OMX_ErrorNone)
2933 {
2934 goto get_port_definition_exit;
2935 }
2936 }
2937
2938 p_port_def->eDir = OMX_DirOutput;
2939 p_port_def->nBufferCountActual = m_port_op.def.nBufferCountActual;
2940 p_port_def->nBufferCountMin = m_port_op.def.nBufferCountMin;
2941 p_port_def->nBufferSize = m_port_op.def.nBufferSize;
2942 p_port_def->bEnabled = m_port_op.enabled;
2943 p_port_def->bPopulated = m_port_op.populated;
2944
2945 OMX_SWVDEC_LOG_HIGH("port index %d: "
2946 "count actual %d, count min %d, size %d",
2947 p_port_def->nPortIndex,
2948 p_port_def->nBufferCountActual,
2949 p_port_def->nBufferCountMin,
2950 p_port_def->nBufferSize);
2951
2952 p_port_def->format.video.eColorFormat = m_omx_color_formattype;
2953 p_port_def->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2954
2955 if (m_omx_color_formattype ==
2956 OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m)
2957 {
2958 OMX_SWVDEC_LOG_HIGH(
2959 "port index %d: color format '0x%08x': "
2960 "OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m",
2961 p_port_def->nPortIndex,
2962 p_port_def->format.video.eColorFormat);
2963 }
2964 else if (m_omx_color_formattype == OMX_COLOR_FormatYUV420SemiPlanar)
2965 {
2966 OMX_SWVDEC_LOG_HIGH("port index %d: color format '0x%08x': "
2967 "OMX_COLOR_FormatYUV420SemiPlanar",
2968 p_port_def->nPortIndex,
2969 p_port_def->format.video.eColorFormat);
2970 }
2971 else
2972 {
2973 assert(0);
2974 retval = OMX_ErrorUndefined;
2975 }
2976 }
2977 else
2978 {
2979 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", p_port_def->nPortIndex);
2980
2981 retval = OMX_ErrorBadPortIndex;
2982 }
2983
2984 get_port_definition_exit:
2985 return retval;
2986 }
2987
2988 /**
2989 * @brief Set port definition for input or output port.
2990 *
2991 * @param[in] p_port_def: Pointer to port definition type.
2992 *
2993 * @retval OMX_ERRORTYPE
2994 */
set_port_definition(OMX_PARAM_PORTDEFINITIONTYPE * p_port_def)2995 OMX_ERRORTYPE omx_swvdec::set_port_definition(
2996 OMX_PARAM_PORTDEFINITIONTYPE *p_port_def)
2997 {
2998 OMX_ERRORTYPE retval = OMX_ErrorNone;
2999
3000 OMX_SWVDEC_LOG_HIGH("port index %d: "
3001 "count actual %d, count min %d, size %d",
3002 p_port_def->nPortIndex,
3003 p_port_def->nBufferCountActual,
3004 p_port_def->nBufferCountMin,
3005 p_port_def->nBufferSize);
3006
3007 if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP)
3008 {
3009 m_port_ip.def.nBufferCountActual = p_port_def->nBufferCountActual;
3010 m_port_ip.def.nBufferCountMin = p_port_def->nBufferCountMin;
3011 m_port_ip.def.nBufferSize = p_port_def->nBufferSize;
3012 }
3013 else if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP)
3014 {
3015 /**
3016 * OMX component's output port nBufferSize is not updated based on what
3017 * IL client sends; instead it is updated based on the possibly updated
3018 * frame attributes.
3019 *
3020 * This is because set_parameter() for output port definition only has
3021 * updates to buffer counts or frame dimensions.
3022 */
3023
3024 m_port_op.def.nBufferCountActual = p_port_def->nBufferCountActual;
3025 m_port_op.def.nBufferCountMin = p_port_def->nBufferCountMin;
3026
3027 OMX_SWVDEC_LOG_HIGH("port index %d: %d x %d",
3028 p_port_def->nPortIndex,
3029 p_port_def->format.video.nFrameWidth,
3030 p_port_def->format.video.nFrameHeight);
3031
3032 /**
3033 * Update frame dimensions & attributes if:
3034 *
3035 * 1. not in adaptive playback mode
3036 * OR
3037 * 2. new frame dimensions greater than adaptive playback mode's
3038 * max frame dimensions
3039 */
3040
3041 if ((m_adaptive_playback_mode == false) ||
3042 (p_port_def->format.video.nFrameWidth >
3043 m_frame_dimensions_max.width) ||
3044 (p_port_def->format.video.nFrameHeight >
3045 m_frame_dimensions_max.height))
3046 {
3047 OMX_SWVDEC_LOG_HIGH("updating frame dimensions & attributes");
3048
3049 if ((retval =
3050 set_frame_dimensions(p_port_def->format.video.nFrameWidth,
3051 p_port_def->format.video.nFrameHeight)) !=
3052 OMX_ErrorNone)
3053 {
3054 goto set_port_definition_exit;
3055 }
3056
3057 if ((retval = set_frame_attributes(m_omx_color_formattype)) !=
3058 OMX_ErrorNone)
3059 {
3060 goto set_port_definition_exit;
3061 }
3062
3063 // nBufferSize updated based on (possibly new) frame attributes
3064
3065 m_port_op.def.nBufferSize = m_frame_attributes.size;
3066 }
3067 else
3068 {
3069 OMX_SWVDEC_LOG_HIGH("not updating frame dimensions & attributes");
3070 }
3071 }
3072 else
3073 {
3074 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", p_port_def->nPortIndex);
3075
3076 retval = OMX_ErrorBadPortIndex;
3077 }
3078
3079 set_port_definition_exit:
3080 return retval;
3081 }
3082
3083 /**
3084 * @brief Get supported profile & level.
3085 *
3086 * The supported profiles & levels are not queried from SwVdec core, but
3087 * hard-coded. This should ideally be replaced with a query to SwVdec core.
3088 *
3089 * @param[in,out] p_profilelevel: Pointer to video profile & level type.
3090 *
3091 * @retval OMX_ERRORTYPE
3092 */
get_supported_profilelevel(OMX_VIDEO_PARAM_PROFILELEVELTYPE * p_profilelevel)3093 OMX_ERRORTYPE omx_swvdec::get_supported_profilelevel(
3094 OMX_VIDEO_PARAM_PROFILELEVELTYPE *p_profilelevel)
3095 {
3096 OMX_ERRORTYPE retval = OMX_ErrorNone;
3097
3098 if (p_profilelevel == NULL)
3099 {
3100 OMX_SWVDEC_LOG_ERROR("p_profilelevel = NULL");
3101
3102 retval = OMX_ErrorBadParameter;
3103 goto get_supported_profilelevel_exit;
3104 }
3105
3106 if (p_profilelevel->nPortIndex != OMX_CORE_PORT_INDEX_IP)
3107 {
3108 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
3109 p_profilelevel->nPortIndex);
3110
3111 retval = OMX_ErrorBadPortIndex;
3112 goto get_supported_profilelevel_exit;
3113 }
3114
3115 if (m_omx_video_codingtype == OMX_VIDEO_CodingH263)
3116 {
3117 if (p_profilelevel->nProfileIndex == 0)
3118 {
3119 p_profilelevel->eProfile = OMX_VIDEO_H263ProfileBaseline;
3120 p_profilelevel->eLevel = OMX_VIDEO_H263Level70;
3121
3122 OMX_SWVDEC_LOG_HIGH("H.263 baseline profile, level 70");
3123 }
3124 else
3125 {
3126 OMX_SWVDEC_LOG_HIGH("profile index '%d' unsupported; "
3127 "no more profiles",
3128 p_profilelevel->nProfileIndex);
3129
3130 retval = OMX_ErrorNoMore;
3131 }
3132 }
3133 else if ((m_omx_video_codingtype == OMX_VIDEO_CodingMPEG4) ||
3134 (m_omx_video_codingtype ==
3135 ((OMX_VIDEO_CODINGTYPE) QOMX_VIDEO_CodingDivx)))
3136 {
3137 if (p_profilelevel->nProfileIndex == 0)
3138 {
3139 p_profilelevel->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
3140 p_profilelevel->eLevel = OMX_VIDEO_MPEG4Level6;
3141
3142 OMX_SWVDEC_LOG_HIGH("MPEG-4 simple profile, level 6");
3143 }
3144 else if (p_profilelevel->nProfileIndex == 1)
3145 {
3146 p_profilelevel->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
3147 p_profilelevel->eLevel = OMX_VIDEO_MPEG4Level5;
3148
3149 OMX_SWVDEC_LOG_HIGH("MPEG-4 advanced simple profile, level 5");
3150 }
3151 else
3152 {
3153 OMX_SWVDEC_LOG_HIGH("profile index '%d' unsupported; "
3154 "no more profiles",
3155 p_profilelevel->nProfileIndex);
3156
3157 retval = OMX_ErrorNoMore;
3158 }
3159 }
3160 else
3161 {
3162 assert(0);
3163 retval = OMX_ErrorUndefined;
3164 }
3165
3166 get_supported_profilelevel_exit:
3167 return retval;
3168 }
3169
3170 /**
3171 * @brief Describe color format.
3172 *
3173 * @param[in,out] p_params: Pointer to 'DescribeColorFormatParams' structure.
3174 *
3175 * @retval OMX_ERRORTYPE
3176 */
describe_color_format(DescribeColorFormatParams * p_params)3177 OMX_ERRORTYPE omx_swvdec::describe_color_format(
3178 DescribeColorFormatParams *p_params)
3179 {
3180 OMX_ERRORTYPE retval = OMX_ErrorNone;
3181
3182 if (p_params == NULL)
3183 {
3184 OMX_SWVDEC_LOG_ERROR("p_params = NULL");
3185
3186 retval = OMX_ErrorBadParameter;
3187 }
3188 else
3189 {
3190 MediaImage *p_img = &p_params->sMediaImage;
3191
3192 switch (p_params->eColorFormat)
3193 {
3194
3195 case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m:
3196 {
3197 size_t stride, scanlines;
3198
3199 p_img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
3200 p_img->mNumPlanes = 3;
3201
3202 p_img->mWidth = p_params->nFrameWidth;
3203 p_img->mHeight = p_params->nFrameHeight;
3204
3205 /**
3206 * alignment factors:
3207 *
3208 * - stride: 128
3209 * - scanlines: 32
3210 */
3211 stride = ALIGN(p_img->mWidth, 128);
3212 scanlines = ALIGN(p_img->mHeight, 32);
3213
3214 p_img->mBitDepth = 8;
3215
3216 // plane 0 (Y)
3217 p_img->mPlane[MediaImage::Y].mOffset = 0;
3218 p_img->mPlane[MediaImage::Y].mColInc = 1;
3219 p_img->mPlane[MediaImage::Y].mRowInc = stride;
3220 p_img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
3221 p_img->mPlane[MediaImage::Y].mVertSubsampling = 1;
3222
3223 // plane 1 (U)
3224 p_img->mPlane[MediaImage::U].mOffset = stride * scanlines;
3225 p_img->mPlane[MediaImage::U].mColInc = 2;
3226 p_img->mPlane[MediaImage::U].mRowInc = stride;
3227 p_img->mPlane[MediaImage::U].mHorizSubsampling = 2;
3228 p_img->mPlane[MediaImage::U].mVertSubsampling = 2;
3229
3230 // plane 2 (V)
3231 p_img->mPlane[MediaImage::V].mOffset = stride * scanlines + 1;
3232 p_img->mPlane[MediaImage::V].mColInc = 2;
3233 p_img->mPlane[MediaImage::V].mRowInc = stride;
3234 p_img->mPlane[MediaImage::V].mHorizSubsampling = 2;
3235 p_img->mPlane[MediaImage::V].mVertSubsampling = 2;
3236
3237 break;
3238 }
3239
3240 case OMX_COLOR_FormatYUV420SemiPlanar:
3241 {
3242 // do nothing; standard OMX color formats should not be described
3243 retval = OMX_ErrorUnsupportedSetting;
3244 break;
3245 }
3246
3247 default:
3248 {
3249 OMX_SWVDEC_LOG_ERROR("color format '0x%08x' invalid/unsupported",
3250 p_params->eColorFormat);
3251
3252 p_img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3253
3254 retval = OMX_ErrorBadParameter;
3255 break;
3256 }
3257
3258 } // switch (p_params->eColorFormat)
3259 }
3260
3261 return retval;
3262 }
3263
3264 /**
3265 * @brief Set QTI vendor-specific port definition for input or output port.
3266 *
3267 * @param[in] p_port_def: Pointer to QTI vendor-specific port definition type.
3268 *
3269 * @retval OMX_ERRORTYPE
3270 */
set_port_definition_qcom(OMX_QCOM_PARAM_PORTDEFINITIONTYPE * p_port_def)3271 OMX_ERRORTYPE omx_swvdec::set_port_definition_qcom(
3272 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *p_port_def)
3273 {
3274 OMX_ERRORTYPE retval = OMX_ErrorNone;
3275
3276 if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP)
3277 {
3278 switch (p_port_def->nFramePackingFormat)
3279 {
3280
3281 case OMX_QCOM_FramePacking_Arbitrary:
3282 {
3283 OMX_SWVDEC_LOG_HIGH("OMX_QCOM_FramePacking_Arbitrary");
3284
3285 m_arbitrary_bytes_mode = true;
3286
3287 break;
3288 }
3289
3290 case OMX_QCOM_FramePacking_OnlyOneCompleteFrame:
3291 {
3292 OMX_SWVDEC_LOG_HIGH(
3293 "OMX_QCOM_FramePacking_OnlyOneCompleteFrame");
3294
3295 break;
3296 }
3297
3298 default:
3299 {
3300 OMX_SWVDEC_LOG_ERROR(
3301 "frame packing format '%d' unsupported",
3302 p_port_def->nFramePackingFormat);
3303
3304 retval = OMX_ErrorUnsupportedSetting;
3305 break;
3306 }
3307
3308 }
3309 }
3310 else if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP)
3311 {
3312 OMX_SWVDEC_LOG_HIGH("nMemRegion %d, nCacheAttr %d",
3313 p_port_def->nMemRegion,
3314 p_port_def->nCacheAttr);
3315 }
3316 else
3317 {
3318 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
3319 p_port_def->nPortIndex);
3320
3321 retval = OMX_ErrorBadPortIndex;
3322 }
3323
3324 return retval;
3325 }
3326
3327 /**
3328 * @brief Set SwVdec frame dimensions based on OMX component frame dimensions.
3329 *
3330 * @retval OMX_ERRORTYPE
3331 */
set_frame_dimensions_swvdec()3332 OMX_ERRORTYPE omx_swvdec::set_frame_dimensions_swvdec()
3333 {
3334 OMX_ERRORTYPE retval = OMX_ErrorNone;
3335
3336 SWVDEC_PROPERTY property;
3337
3338 SWVDEC_STATUS retval_swvdec;
3339
3340 property.id = SWVDEC_PROPERTY_ID_FRAME_DIMENSIONS;
3341
3342 property.info.frame_dimensions.width = m_frame_dimensions.width;
3343 property.info.frame_dimensions.height = m_frame_dimensions.height;
3344
3345 if ((retval_swvdec = swvdec_setproperty(m_swvdec_handle, &property)) !=
3346 SWVDEC_STATUS_SUCCESS)
3347 {
3348 retval = retval_swvdec2omx(retval_swvdec);
3349 }
3350
3351 return retval;
3352 }
3353
3354 /**
3355 * @brief Set SwVdec frame attributes based on OMX component frame attributes.
3356 *
3357 * @retval OMX_ERRORTYPE
3358 */
set_frame_attributes_swvdec()3359 OMX_ERRORTYPE omx_swvdec::set_frame_attributes_swvdec()
3360 {
3361 OMX_ERRORTYPE retval = OMX_ErrorNone;
3362
3363 SWVDEC_FRAME_ATTRIBUTES *p_frame_attributes;
3364
3365 SWVDEC_PROPERTY property;
3366
3367 SWVDEC_STATUS retval_swvdec;
3368
3369 p_frame_attributes = &property.info.frame_attributes;
3370
3371 property.id = SWVDEC_PROPERTY_ID_FRAME_ATTRIBUTES;
3372
3373 if(m_omx_color_formattype == OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m)
3374 p_frame_attributes->color_format = SWVDEC_COLOR_FORMAT_SEMIPLANAR_NV12_32;
3375 else
3376 p_frame_attributes->color_format = SWVDEC_COLOR_FORMAT_SEMIPLANAR_NV12;
3377
3378 p_frame_attributes->stride = m_frame_attributes.stride;
3379 p_frame_attributes->scanlines = m_frame_attributes.scanlines;
3380 p_frame_attributes->size = m_frame_attributes.size;
3381
3382 if ((retval_swvdec = swvdec_setproperty(m_swvdec_handle, &property)) !=
3383 SWVDEC_STATUS_SUCCESS)
3384 {
3385 retval = retval_swvdec2omx(retval_swvdec);
3386 }
3387
3388 return retval;
3389 }
3390
3391 /**
3392 * @brief Set maximum adaptive playback frame dimensions for SwVdec core.
3393 */
set_adaptive_playback_swvdec()3394 OMX_ERRORTYPE omx_swvdec::set_adaptive_playback_swvdec()
3395 {
3396 OMX_ERRORTYPE retval = OMX_ErrorNone;
3397
3398 SWVDEC_PROPERTY property;
3399
3400 SWVDEC_STATUS retval_swvdec;
3401
3402 property.id = SWVDEC_PROPERTY_ID_ADAPTIVE_PLAYBACK;
3403
3404 property.info.frame_dimensions.width = m_frame_dimensions_max.width;
3405 property.info.frame_dimensions.height = m_frame_dimensions_max.height;
3406
3407 if ((retval_swvdec = swvdec_setproperty(m_swvdec_handle, &property)) !=
3408 SWVDEC_STATUS_SUCCESS)
3409 {
3410 retval = retval_swvdec2omx(retval_swvdec);
3411 }
3412
3413 return retval;
3414 }
3415
3416 /**
3417 * @brief Set thumbnail mode for SwVdec core.
3418 */
set_thumbnail_mode_swvdec()3419 OMX_ERRORTYPE omx_swvdec::set_thumbnail_mode_swvdec()
3420 {
3421 OMX_ERRORTYPE retval = OMX_ErrorNone;
3422
3423 SWVDEC_PROPERTY property;
3424
3425 SWVDEC_STATUS retval_swvdec;
3426
3427 property.id = SWVDEC_PROPERTY_ID_THUMBNAIL_MODE;
3428
3429 if ((retval_swvdec = swvdec_setproperty(m_swvdec_handle, &property)) !=
3430 SWVDEC_STATUS_SUCCESS)
3431 {
3432 retval = retval_swvdec2omx(retval_swvdec);
3433 }
3434
3435 return retval;
3436 }
3437
3438 /**
3439 * @brief Get SwVdec frame dimensions and set OMX component frame dimensions.
3440 *
3441 * @retval OMX_ERRORTYPE
3442 */
get_frame_dimensions_swvdec()3443 OMX_ERRORTYPE omx_swvdec::get_frame_dimensions_swvdec()
3444 {
3445 OMX_ERRORTYPE retval = OMX_ErrorNone;
3446
3447 SWVDEC_PROPERTY property;
3448
3449 SWVDEC_STATUS retval_swvdec;
3450
3451 property.id = SWVDEC_PROPERTY_ID_FRAME_DIMENSIONS;
3452
3453 if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
3454 SWVDEC_STATUS_SUCCESS)
3455 {
3456 retval = retval_swvdec2omx(retval_swvdec);
3457 }
3458 else
3459 {
3460 m_frame_dimensions.width = property.info.frame_dimensions.width;
3461 m_frame_dimensions.height = property.info.frame_dimensions.height;
3462 }
3463
3464 return retval;
3465 }
3466
3467 /**
3468 * @brief Get SwVdec frame attributes and set OMX component frame attributes.
3469 *
3470 * @retval OMX_ERRORTYPE
3471 */
get_frame_attributes_swvdec()3472 OMX_ERRORTYPE omx_swvdec::get_frame_attributes_swvdec()
3473 {
3474 OMX_ERRORTYPE retval = OMX_ErrorNone;
3475
3476 SWVDEC_PROPERTY property;
3477
3478 SWVDEC_STATUS retval_swvdec;
3479
3480 property.id = SWVDEC_PROPERTY_ID_FRAME_ATTRIBUTES;
3481
3482 if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
3483 SWVDEC_STATUS_SUCCESS)
3484 {
3485 retval = retval_swvdec2omx(retval_swvdec);
3486 }
3487 else
3488 {
3489 m_frame_attributes.stride = property.info.frame_attributes.stride;
3490 m_frame_attributes.scanlines = property.info.frame_attributes.scanlines;
3491 m_frame_attributes.size = property.info.frame_attributes.size;
3492 }
3493
3494 return retval;
3495 }
3496
3497 /**
3498 * @brief Get SwVdec buffer requirements; set input or output port definitions.
3499 *
3500 * @param[in] port_index: Port index.
3501 *
3502 * @retval OMX_ERRORTYPE
3503 */
get_buffer_requirements_swvdec(unsigned int port_index)3504 OMX_ERRORTYPE omx_swvdec::get_buffer_requirements_swvdec(
3505 unsigned int port_index)
3506 {
3507 OMX_ERRORTYPE retval = OMX_ErrorNone;
3508
3509 SWVDEC_PROPERTY property;
3510
3511 SWVDEC_STATUS retval_swvdec;
3512
3513 SWVDEC_BUFFER_REQ *p_buffer_req;
3514
3515 if (port_index == OMX_CORE_PORT_INDEX_IP)
3516 {
3517 property.id = SWVDEC_PROPERTY_ID_BUFFER_REQ_IP;
3518
3519 p_buffer_req = &property.info.buffer_req_ip;
3520
3521 if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
3522 SWVDEC_STATUS_SUCCESS)
3523 {
3524 retval = retval_swvdec2omx(retval_swvdec);
3525 goto get_buffer_requirements_swvdec_exit;
3526 }
3527
3528 m_port_ip.def.nBufferSize = p_buffer_req->size;
3529 m_port_ip.def.nBufferCountMin = p_buffer_req->mincount;
3530 m_port_ip.def.nBufferCountActual = MAX(p_buffer_req->mincount,
3531 OMX_SWVDEC_IP_BUFFER_COUNT_MIN);
3532 m_port_ip.def.nBufferAlignment = p_buffer_req->alignment;
3533
3534 OMX_SWVDEC_LOG_HIGH("ip port: %d bytes x %d, %d-byte aligned",
3535 m_port_ip.def.nBufferSize,
3536 m_port_ip.def.nBufferCountActual,
3537 m_port_ip.def.nBufferAlignment);
3538 }
3539 else if (port_index == OMX_CORE_PORT_INDEX_OP)
3540 {
3541 property.id = SWVDEC_PROPERTY_ID_BUFFER_REQ_OP;
3542
3543 p_buffer_req = &property.info.buffer_req_op;
3544
3545 if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
3546 SWVDEC_STATUS_SUCCESS)
3547 {
3548 retval = retval_swvdec2omx(retval_swvdec);
3549 goto get_buffer_requirements_swvdec_exit;
3550 }
3551
3552 if (m_sync_frame_decoding_mode)
3553 {
3554 p_buffer_req->mincount = 1;
3555 }
3556
3557 m_port_op.def.nBufferSize = p_buffer_req->size;
3558 m_port_op.def.nBufferCountMin = p_buffer_req->mincount;
3559 m_port_op.def.nBufferCountActual = MAX(p_buffer_req->mincount,
3560 m_port_op.def.nBufferCountActual);
3561 m_port_op.def.nBufferAlignment = p_buffer_req->alignment;
3562
3563 OMX_SWVDEC_LOG_HIGH("op port: %d bytes x %d, %d-byte aligned",
3564 m_port_op.def.nBufferSize,
3565 m_port_op.def.nBufferCountActual,
3566 m_port_op.def.nBufferAlignment);
3567 }
3568 else
3569 {
3570 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", port_index);
3571
3572 retval = OMX_ErrorBadPortIndex;
3573 }
3574
3575 get_buffer_requirements_swvdec_exit:
3576 return retval;
3577 }
3578
3579 /**
3580 * @brief Allocate input buffer, and input buffer info array if ncessary.
3581 *
3582 * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
3583 * structure.
3584 * @param[in] p_app_data: Pointer to IL client app data.
3585 * @param[in] size: Size of buffer to be allocated in bytes.
3586 *
3587 * @retval OMX_ERRORTYPE
3588 */
buffer_allocate_ip(OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_PTR p_app_data,OMX_U32 size)3589 OMX_ERRORTYPE omx_swvdec::buffer_allocate_ip(
3590 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
3591 OMX_PTR p_app_data,
3592 OMX_U32 size)
3593 {
3594 OMX_ERRORTYPE retval = OMX_ErrorNone;
3595
3596 unsigned int ii;
3597
3598 if (size != m_port_ip.def.nBufferSize)
3599 {
3600 OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
3601 "configured size (%d bytes)",
3602 size,
3603 m_port_ip.def.nBufferSize);
3604
3605 retval = OMX_ErrorBadParameter;
3606 goto buffer_allocate_ip_exit;
3607 }
3608
3609 if (m_buffer_array_ip == NULL)
3610 {
3611 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3612 m_port_ip.def.nBufferCountActual,
3613 (m_port_ip.def.nBufferCountActual > 1) ? "s" : "");
3614
3615 if ((retval = buffer_allocate_ip_info_array()) != OMX_ErrorNone)
3616 {
3617 goto buffer_allocate_ip_exit;
3618 }
3619 }
3620
3621 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
3622 {
3623 if (m_buffer_array_ip[ii].buffer_populated == false)
3624 {
3625 OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
3626 break;
3627 }
3628 }
3629
3630 if (ii < m_port_ip.def.nBufferCountActual)
3631 {
3632 int pmem_fd = -1;
3633
3634 unsigned char *bufferaddr;
3635
3636 OMX_SWVDEC_LOG_HIGH("ip buffer %d: %d bytes being allocated",
3637 ii,
3638 size);
3639
3640 m_buffer_array_ip[ii].ion_info.ion_fd_device =
3641 ion_memory_alloc_map(&m_buffer_array_ip[ii].ion_info.ion_alloc_data,
3642 &m_buffer_array_ip[ii].ion_info.ion_fd_data,
3643 size,
3644 m_port_ip.def.nBufferAlignment);
3645
3646 if (m_buffer_array_ip[ii].ion_info.ion_fd_device < 0)
3647 {
3648 retval = OMX_ErrorInsufficientResources;
3649 goto buffer_allocate_ip_exit;
3650 }
3651
3652 pmem_fd = m_buffer_array_ip[ii].ion_info.ion_fd_data.fd;
3653
3654 bufferaddr = (unsigned char *) mmap(NULL,
3655 size,
3656 PROT_READ | PROT_WRITE,
3657 MAP_SHARED,
3658 pmem_fd,
3659 0);
3660
3661 if (bufferaddr == MAP_FAILED)
3662 {
3663 OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d",
3664 pmem_fd,
3665 size);
3666
3667 close(pmem_fd);
3668 ion_memory_free(&m_buffer_array_ip[ii].ion_info);
3669
3670 retval = OMX_ErrorInsufficientResources;
3671 goto buffer_allocate_ip_exit;
3672 }
3673
3674 *pp_buffer_hdr = &m_buffer_array_ip[ii].buffer_header;
3675
3676 m_buffer_array_ip[ii].buffer_payload.bufferaddr = bufferaddr;
3677 m_buffer_array_ip[ii].buffer_payload.pmem_fd = pmem_fd;
3678 m_buffer_array_ip[ii].buffer_payload.buffer_len = size;
3679 m_buffer_array_ip[ii].buffer_payload.mmaped_size = size;
3680 m_buffer_array_ip[ii].buffer_payload.offset = 0;
3681
3682 m_buffer_array_ip[ii].buffer_swvdec.p_buffer = bufferaddr;
3683 m_buffer_array_ip[ii].buffer_swvdec.size = size;
3684 m_buffer_array_ip[ii].buffer_swvdec.p_client_data =
3685 (void *) ((unsigned long) ii);
3686
3687 m_buffer_array_ip[ii].buffer_populated = true;
3688
3689 OMX_SWVDEC_LOG_HIGH("ip buffer %d: %p, fd = %d %d bytes",
3690 ii,
3691 bufferaddr,
3692 pmem_fd,
3693 size);
3694
3695 (*pp_buffer_hdr)->pBuffer = (OMX_U8 *) bufferaddr;
3696 (*pp_buffer_hdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3697 (*pp_buffer_hdr)->nVersion.nVersion = OMX_SPEC_VERSION;
3698 (*pp_buffer_hdr)->nAllocLen = size;
3699 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
3700 (*pp_buffer_hdr)->nInputPortIndex = OMX_CORE_PORT_INDEX_IP;
3701 (*pp_buffer_hdr)->pInputPortPrivate =
3702 (void *) &(m_buffer_array_ip[ii].buffer_payload);
3703
3704 m_port_ip.populated = port_ip_populated();
3705 m_port_ip.unpopulated = OMX_FALSE;
3706 }
3707 else
3708 {
3709 OMX_SWVDEC_LOG_ERROR("all %d ip buffers allocated",
3710 m_port_ip.def.nBufferCountActual);
3711
3712 retval = OMX_ErrorInsufficientResources;
3713 }
3714
3715 buffer_allocate_ip_exit:
3716 return retval;
3717 }
3718
3719 /**
3720 * @brief Allocate output buffer, and output buffer info array if necessary.
3721 *
3722 * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
3723 * structure.
3724 * @param[in] p_app_data: Pointer to IL client app data.
3725 * @param[in] size: Size of buffer to be allocated in bytes.
3726 *
3727 * @retval OMX_ERRORTYPE
3728 */
buffer_allocate_op(OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_PTR p_app_data,OMX_U32 size)3729 OMX_ERRORTYPE omx_swvdec::buffer_allocate_op(
3730 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
3731 OMX_PTR p_app_data,
3732 OMX_U32 size)
3733 {
3734 OMX_ERRORTYPE retval = OMX_ErrorNone;
3735 SWVDEC_STATUS retval_swvdec;
3736 unsigned int ii;
3737
3738 if (size != m_port_op.def.nBufferSize)
3739 {
3740 OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
3741 "configured size (%d bytes)",
3742 size,
3743 m_port_op.def.nBufferSize);
3744
3745 retval = OMX_ErrorBadParameter;
3746 goto buffer_allocate_op_exit;
3747 }
3748
3749 if (m_buffer_array_op == NULL)
3750 {
3751 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3752 m_port_op.def.nBufferCountActual,
3753 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
3754
3755 if ((retval = buffer_allocate_op_info_array()) != OMX_ErrorNone)
3756 {
3757 goto buffer_allocate_op_exit;
3758 }
3759 }
3760
3761 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
3762 {
3763 if (m_buffer_array_op[ii].buffer_populated == false)
3764 {
3765 OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
3766 break;
3767 }
3768 }
3769
3770 if (ii < m_port_op.def.nBufferCountActual)
3771 {
3772 int pmem_fd = -1;
3773
3774 unsigned char *bufferaddr;
3775
3776 OMX_SWVDEC_LOG_HIGH("op buffer %d: %d bytes being allocated",
3777 ii,
3778 size);
3779
3780 m_buffer_array_op[ii].ion_info.ion_fd_device =
3781 ion_memory_alloc_map(&m_buffer_array_op[ii].ion_info.ion_alloc_data,
3782 &m_buffer_array_op[ii].ion_info.ion_fd_data,
3783 size,
3784 m_port_op.def.nBufferAlignment);
3785
3786 if (m_buffer_array_op[ii].ion_info.ion_fd_device < 0)
3787 {
3788 retval = OMX_ErrorInsufficientResources;
3789 goto buffer_allocate_op_exit;
3790 }
3791
3792 pmem_fd = m_buffer_array_op[ii].ion_info.ion_fd_data.fd;
3793
3794 bufferaddr = (unsigned char *) mmap(NULL,
3795 size,
3796 PROT_READ | PROT_WRITE,
3797 MAP_SHARED,
3798 pmem_fd,
3799 0);
3800
3801 if (bufferaddr == MAP_FAILED)
3802 {
3803 OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d",
3804 pmem_fd,
3805 size);
3806
3807 close(pmem_fd);
3808 ion_memory_free(&m_buffer_array_op[ii].ion_info);
3809
3810 retval = OMX_ErrorInsufficientResources;
3811 goto buffer_allocate_op_exit;
3812 }
3813
3814 *pp_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
3815
3816 m_buffer_array_op[ii].buffer_payload.bufferaddr = bufferaddr;
3817 m_buffer_array_op[ii].buffer_payload.pmem_fd = pmem_fd;
3818 m_buffer_array_op[ii].buffer_payload.buffer_len = size;
3819 m_buffer_array_op[ii].buffer_payload.mmaped_size = size;
3820 m_buffer_array_op[ii].buffer_payload.offset = 0;
3821
3822 m_buffer_array_op[ii].buffer_swvdec.p_buffer = bufferaddr;
3823 m_buffer_array_op[ii].buffer_swvdec.size = size;
3824 m_buffer_array_op[ii].buffer_swvdec.p_client_data =
3825 (void *) ((unsigned long) ii);
3826
3827 m_buffer_array_op[ii].buffer_populated = true;
3828
3829 m_buffer_array_op[ii].buffer_swvdec.fd = pmem_fd ;
3830
3831 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
3832 {
3833 OMX_SWVDEC_LOG_LOW("map op buffer");
3834
3835 if((retval_swvdec = swvdec_map(m_swvdec_handle,&m_buffer_array_op[ii].buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
3836 {
3837 OMX_SWVDEC_LOG_ERROR("swvdec_map failed for op buffer %d: %p",ii,bufferaddr);
3838 retval = retval_swvdec2omx(retval_swvdec);;
3839 goto buffer_allocate_op_exit;
3840 }
3841 }
3842 OMX_SWVDEC_LOG_HIGH("op buffer %d: %p, fd = %d %d bytes",
3843 ii,
3844 bufferaddr,
3845 pmem_fd,
3846 size);
3847
3848 (*pp_buffer_hdr)->pBuffer = (OMX_U8 *) bufferaddr;
3849 (*pp_buffer_hdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3850 (*pp_buffer_hdr)->nVersion.nVersion = OMX_SPEC_VERSION;
3851 (*pp_buffer_hdr)->nAllocLen = size;
3852 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
3853 (*pp_buffer_hdr)->nOutputPortIndex = OMX_CORE_PORT_INDEX_OP;
3854 (*pp_buffer_hdr)->pOutputPortPrivate =
3855 (void *) &(m_buffer_array_op[ii].buffer_payload);
3856
3857 m_port_op.populated = port_op_populated();
3858 m_port_op.unpopulated = OMX_FALSE;
3859 }
3860 else
3861 {
3862 OMX_SWVDEC_LOG_ERROR("all %d op buffers allocated",
3863 m_port_op.def.nBufferCountActual);
3864
3865 retval = OMX_ErrorInsufficientResources;
3866 }
3867
3868 buffer_allocate_op_exit:
3869 return retval;
3870 }
3871
3872 /**
3873 * @brief Allocate input buffer info array.
3874 */
buffer_allocate_ip_info_array()3875 OMX_ERRORTYPE omx_swvdec::buffer_allocate_ip_info_array()
3876 {
3877 OMX_ERRORTYPE retval = OMX_ErrorNone;
3878
3879 unsigned int ii;
3880
3881 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
3882
3883 if (m_buffer_array_ip != NULL)
3884 {
3885 OMX_SWVDEC_LOG_ERROR("buffer info array already allocated");
3886
3887 retval = OMX_ErrorInsufficientResources;
3888 goto buffer_allocate_ip_info_array_exit;
3889 }
3890
3891 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3892 m_port_ip.def.nBufferCountActual,
3893 (m_port_ip.def.nBufferCountActual > 1) ? "s" : "");
3894
3895 m_buffer_array_ip =
3896 (OMX_SWVDEC_BUFFER_INFO *) calloc(sizeof(OMX_SWVDEC_BUFFER_INFO),
3897 m_port_ip.def.nBufferCountActual);
3898
3899 if (m_buffer_array_ip == NULL)
3900 {
3901 OMX_SWVDEC_LOG_ERROR("failed to allocate buffer info array; "
3902 "%d element%s, %zu bytes requested",
3903 m_port_ip.def.nBufferCountActual,
3904 (m_port_ip.def.nBufferCountActual > 1) ? "s" : "",
3905 sizeof(OMX_SWVDEC_BUFFER_INFO) *
3906 m_port_ip.def.nBufferCountActual);
3907
3908 retval = OMX_ErrorInsufficientResources;
3909 goto buffer_allocate_ip_info_array_exit;
3910 }
3911
3912 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
3913 {
3914 p_buffer_hdr = &m_buffer_array_ip[ii].buffer_header;
3915
3916 // reset file descriptors
3917
3918 m_buffer_array_ip[ii].buffer_payload.pmem_fd = -1;
3919 m_buffer_array_ip[ii].ion_info.ion_fd_device = -1;
3920
3921 m_buffer_array_ip[ii].buffer_swvdec.p_client_data =
3922 (void *) ((unsigned long) ii);
3923
3924 p_buffer_hdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3925 p_buffer_hdr->nVersion.nVersion = OMX_SPEC_VERSION;
3926 p_buffer_hdr->nInputPortIndex = OMX_CORE_PORT_INDEX_IP;
3927 p_buffer_hdr->pInputPortPrivate =
3928 (void *) &(m_buffer_array_ip[ii].buffer_payload);
3929 }
3930
3931 buffer_allocate_ip_info_array_exit:
3932 return retval;
3933 }
3934
3935 /**
3936 * @brief Allocate output buffer info array.
3937 */
buffer_allocate_op_info_array()3938 OMX_ERRORTYPE omx_swvdec::buffer_allocate_op_info_array()
3939 {
3940 OMX_ERRORTYPE retval = OMX_ErrorNone;
3941
3942 unsigned int ii;
3943
3944 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
3945
3946 if (m_buffer_array_op != NULL)
3947 {
3948 OMX_SWVDEC_LOG_ERROR("buffer info array already allocated");
3949
3950 retval = OMX_ErrorInsufficientResources;
3951 goto buffer_allocate_op_info_array_exit;
3952 }
3953
3954 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3955 m_port_op.def.nBufferCountActual,
3956 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
3957
3958 m_buffer_array_op =
3959 (OMX_SWVDEC_BUFFER_INFO *) calloc(sizeof(OMX_SWVDEC_BUFFER_INFO),
3960 m_port_op.def.nBufferCountActual);
3961
3962 if (m_buffer_array_op == NULL)
3963 {
3964 OMX_SWVDEC_LOG_ERROR("failed to allocate buffer info array; "
3965 "%d element%s, %zu bytes requested",
3966 m_port_op.def.nBufferCountActual,
3967 (m_port_op.def.nBufferCountActual > 1) ? "s" : "",
3968 sizeof(OMX_SWVDEC_BUFFER_INFO) *
3969 m_port_op.def.nBufferCountActual);
3970
3971 retval = OMX_ErrorInsufficientResources;
3972 goto buffer_allocate_op_info_array_exit;
3973 }
3974
3975 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
3976 {
3977 p_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
3978
3979 // reset file descriptors
3980
3981 m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
3982 m_buffer_array_op[ii].ion_info.ion_fd_device = -1;
3983
3984 m_buffer_array_op[ii].buffer_swvdec.p_client_data =
3985 (void *) ((unsigned long) ii);
3986
3987 p_buffer_hdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3988 p_buffer_hdr->nVersion.nVersion = OMX_SPEC_VERSION;
3989 p_buffer_hdr->nOutputPortIndex = OMX_CORE_PORT_INDEX_OP;
3990 p_buffer_hdr->pOutputPortPrivate =
3991 (void *) &(m_buffer_array_op[ii].buffer_payload);
3992 }
3993
3994 buffer_allocate_op_info_array_exit:
3995 return retval;
3996 }
3997
3998 /**
3999 * @brief Use buffer allocated by IL client; allocate output buffer info array
4000 * if necessary.
4001 *
4002 * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
4003 * structure.
4004 * @param[in] p_app_data: Pointer to IL client app data.
4005 * @param[in] size: Size of buffer to be allocated in bytes.
4006 * @param[in] p_buffer: Pointer to buffer to be used.
4007 *
4008 * @retval OMX_ERRORTYPE
4009 */
buffer_use_op(OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_PTR p_app_data,OMX_U32 size,OMX_U8 * p_buffer)4010 OMX_ERRORTYPE omx_swvdec::buffer_use_op(
4011 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
4012 OMX_PTR p_app_data,
4013 OMX_U32 size,
4014 OMX_U8 *p_buffer)
4015 {
4016 OMX_ERRORTYPE retval = OMX_ErrorNone;
4017 SWVDEC_STATUS retval_swvdec;
4018 unsigned int ii;
4019
4020 (void) size;
4021
4022 if (m_buffer_array_op == NULL)
4023 {
4024 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
4025 m_port_op.def.nBufferCountActual,
4026 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
4027
4028 if ((retval = buffer_allocate_op_info_array()) != OMX_ErrorNone)
4029 {
4030 goto buffer_use_op_exit;
4031 }
4032 }
4033
4034 if (m_meta_buffer_mode && (m_meta_buffer_array == NULL))
4035 {
4036 OMX_SWVDEC_LOG_HIGH("allocating meta buffer info array, %d element%s",
4037 m_port_op.def.nBufferCountActual,
4038 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
4039
4040 if ((retval = meta_buffer_array_allocate()) != OMX_ErrorNone)
4041 {
4042 goto buffer_use_op_exit;
4043 }
4044 }
4045
4046 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4047 {
4048 if (m_buffer_array_op[ii].buffer_populated == false)
4049 {
4050 OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
4051 break;
4052 }
4053 }
4054
4055 if (ii < m_port_op.def.nBufferCountActual)
4056 {
4057 struct vdec_bufferpayload *p_buffer_payload;
4058
4059 SWVDEC_BUFFER *p_buffer_swvdec;
4060
4061 *pp_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
4062 p_buffer_payload = &m_buffer_array_op[ii].buffer_payload;
4063 p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
4064
4065 if (m_meta_buffer_mode)
4066 {
4067 p_buffer_swvdec->size = m_port_op.def.nBufferSize;
4068 p_buffer_swvdec->p_client_data = (void *) ((unsigned long) ii);
4069
4070 m_buffer_array_op[ii].buffer_populated = true;
4071
4072 (*pp_buffer_hdr)->pBuffer = p_buffer;
4073 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
4074 (*pp_buffer_hdr)->nAllocLen =
4075 sizeof(struct VideoDecoderOutputMetaData);
4076
4077 OMX_SWVDEC_LOG_HIGH("op buffer %d: %p (meta buffer)",
4078 ii,
4079 *pp_buffer_hdr);
4080
4081 m_port_op.populated = port_op_populated();
4082 m_port_op.unpopulated = OMX_FALSE;
4083 }
4084 else if (m_android_native_buffers)
4085 {
4086 private_handle_t *p_handle;
4087
4088 OMX_U8 *p_buffer_mapped;
4089
4090 p_handle = (private_handle_t *) p_buffer;
4091
4092 if (((OMX_U32) p_handle->size) < m_port_op.def.nBufferSize)
4093 {
4094 OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
4095 "configured size (%d bytes)",
4096 p_handle->size,
4097 m_port_op.def.nBufferSize);
4098
4099 retval = OMX_ErrorBadParameter;
4100 goto buffer_use_op_exit;
4101 }
4102
4103 m_port_op.def.nBufferSize = p_handle->size;
4104
4105 p_buffer_mapped = (OMX_U8 *) mmap(NULL,
4106 p_handle->size,
4107 PROT_READ | PROT_WRITE,
4108 MAP_SHARED,
4109 p_handle->fd,
4110 0);
4111
4112 if (p_buffer_mapped == MAP_FAILED)
4113 {
4114 OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d",
4115 p_handle->fd,
4116 p_handle->size);
4117
4118 retval = OMX_ErrorInsufficientResources;
4119 goto buffer_use_op_exit;
4120 }
4121
4122 p_buffer_payload->bufferaddr = p_buffer_mapped;
4123 p_buffer_payload->pmem_fd = p_handle->fd;
4124 p_buffer_payload->buffer_len = p_handle->size;
4125 p_buffer_payload->mmaped_size = p_handle->size;
4126 p_buffer_payload->offset = 0;
4127
4128 p_buffer_swvdec->p_buffer = p_buffer_mapped;
4129 p_buffer_swvdec->size = m_port_op.def.nBufferSize;
4130 p_buffer_swvdec->p_client_data = (void *) ((unsigned long) ii);
4131 p_buffer_swvdec->fd = p_buffer_payload->pmem_fd ;
4132
4133 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
4134 {
4135 OMX_SWVDEC_LOG_LOW("map op buffer");
4136
4137 if((retval_swvdec = swvdec_map(m_swvdec_handle,p_buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
4138 {
4139 OMX_SWVDEC_LOG_ERROR("swvdec_map failed for op buffer %d: %p",ii,p_buffer_mapped);
4140 retval = retval_swvdec2omx(retval_swvdec);;
4141 goto buffer_use_op_exit;
4142 }
4143 }
4144 m_buffer_array_op[ii].buffer_populated = true;
4145
4146 (*pp_buffer_hdr)->pBuffer = (m_android_native_buffers ?
4147 ((OMX_U8 *) p_handle) :
4148 p_buffer_mapped);
4149 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
4150 (*pp_buffer_hdr)->nAllocLen = m_port_op.def.nBufferSize;
4151
4152 m_buffer_array_op[ii].ion_info.ion_fd_data.fd = p_handle->fd;
4153
4154 OMX_SWVDEC_LOG_HIGH("op buffer %d: %p",
4155 ii,
4156 *pp_buffer_hdr);
4157
4158 m_port_op.populated = port_op_populated();
4159 m_port_op.unpopulated = OMX_FALSE;
4160 }
4161 else
4162 {
4163 OMX_SWVDEC_LOG_ERROR("neither 'meta buffer mode' nor "
4164 "'android native buffers' enabled");
4165
4166 retval = OMX_ErrorBadParameter;
4167 }
4168 }
4169 else
4170 {
4171 OMX_SWVDEC_LOG_ERROR("all %d op buffers populated",
4172 m_port_op.def.nBufferCountActual);
4173
4174 retval = OMX_ErrorInsufficientResources;
4175 }
4176
4177 buffer_use_op_exit:
4178 return retval;
4179 }
4180
4181 /**
4182 * @brief De-allocate input buffer.
4183 *
4184 * @param[in] p_buffer_hdr: Pointer to buffer header structure.
4185 *
4186 * @retval OMX_ERRORTYPE
4187 */
buffer_deallocate_ip(OMX_BUFFERHEADERTYPE * p_buffer_hdr)4188 OMX_ERRORTYPE omx_swvdec::buffer_deallocate_ip(
4189 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
4190 {
4191 OMX_ERRORTYPE retval = OMX_ErrorNone;
4192
4193 unsigned int ii;
4194
4195 if (p_buffer_hdr == NULL)
4196 {
4197 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
4198
4199 retval = OMX_ErrorBadParameter;
4200 goto buffer_deallocate_ip_exit;
4201 }
4202 else if (m_buffer_array_ip == NULL)
4203 {
4204 OMX_SWVDEC_LOG_ERROR("ip buffer array not allocated");
4205
4206 retval = OMX_ErrorBadParameter;
4207 goto buffer_deallocate_ip_exit;
4208 }
4209
4210 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
4211 {
4212 if (p_buffer_hdr == &(m_buffer_array_ip[ii].buffer_header))
4213 {
4214 OMX_SWVDEC_LOG_LOW("%p has index %d",
4215 p_buffer_hdr->pBuffer,
4216 ii);
4217 break;
4218 }
4219 }
4220
4221 if (ii < m_port_ip.def.nBufferCountActual)
4222 {
4223 if (m_buffer_array_ip[ii].buffer_payload.pmem_fd > 0)
4224 {
4225 m_buffer_array_ip[ii].buffer_populated = false;
4226
4227 m_port_ip.populated = OMX_FALSE;
4228
4229 munmap(m_buffer_array_ip[ii].buffer_payload.bufferaddr,
4230 m_buffer_array_ip[ii].buffer_payload.mmaped_size);
4231
4232 close(m_buffer_array_ip[ii].buffer_payload.pmem_fd);
4233 m_buffer_array_ip[ii].buffer_payload.pmem_fd = -1;
4234
4235 ion_memory_free(&m_buffer_array_ip[ii].ion_info);
4236
4237 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
4238 {
4239 if (m_buffer_array_ip[ii].buffer_populated)
4240 {
4241 break;
4242 }
4243 }
4244
4245 if (ii == m_port_ip.def.nBufferCountActual)
4246 {
4247 buffer_deallocate_ip_info_array();
4248
4249 m_port_ip.unpopulated = OMX_TRUE;
4250 }
4251 }
4252 else
4253 {
4254 OMX_SWVDEC_LOG_ERROR("%p: pmem_fd %d",
4255 p_buffer_hdr->pBuffer,
4256 m_buffer_array_ip[ii].buffer_payload.pmem_fd);
4257 }
4258 }
4259 else
4260 {
4261 OMX_SWVDEC_LOG_ERROR("%p not found", p_buffer_hdr->pBuffer);
4262
4263 retval = OMX_ErrorBadParameter;
4264 }
4265
4266 buffer_deallocate_ip_exit:
4267 return retval;
4268 }
4269
4270 /**
4271 * @brief De-allocate output buffer.
4272 *
4273 * @param[in] p_buffer_hdr: Pointer to buffer header structure.
4274 *
4275 * @retval OMX_ERRORTYPE
4276 */
buffer_deallocate_op(OMX_BUFFERHEADERTYPE * p_buffer_hdr)4277 OMX_ERRORTYPE omx_swvdec::buffer_deallocate_op(
4278 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
4279 {
4280 OMX_ERRORTYPE retval = OMX_ErrorNone;
4281 SWVDEC_STATUS retval_swvdec;
4282 unsigned int ii;
4283
4284 if (p_buffer_hdr == NULL)
4285 {
4286 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
4287
4288 retval = OMX_ErrorBadParameter;
4289 goto buffer_deallocate_op_exit;
4290 }
4291 else if (m_buffer_array_op == NULL)
4292 {
4293 OMX_SWVDEC_LOG_ERROR("op buffer array not allocated");
4294
4295 retval = OMX_ErrorBadParameter;
4296 goto buffer_deallocate_op_exit;
4297 }
4298
4299 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4300 {
4301 if (p_buffer_hdr == &(m_buffer_array_op[ii].buffer_header))
4302 {
4303 OMX_SWVDEC_LOG_LOW("%p has index %d",
4304 p_buffer_hdr->pBuffer,
4305 ii);
4306 break;
4307 }
4308 }
4309
4310 if (ii < m_port_op.def.nBufferCountActual)
4311 {
4312 if (m_meta_buffer_mode)
4313 {
4314 // do nothing; munmap() & FD reset done in FBD or RR
4315 }
4316 else if (m_android_native_buffers)
4317 {
4318
4319 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
4320 {
4321 SWVDEC_BUFFER *p_buffer_swvdec;
4322 p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
4323 OMX_SWVDEC_LOG_LOW("map op buffer");
4324
4325 if((retval_swvdec = swvdec_unmap(m_swvdec_handle,p_buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
4326 {
4327 OMX_SWVDEC_LOG_ERROR("swvdec_unmap failed for op buffer %d: %p",ii,p_buffer_swvdec->p_buffer);
4328 retval = retval_swvdec2omx(retval_swvdec);;
4329 goto buffer_deallocate_op_exit;
4330 }
4331 }
4332 munmap(m_buffer_array_op[ii].buffer_payload.bufferaddr,
4333 m_buffer_array_op[ii].buffer_payload.mmaped_size);
4334
4335 m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
4336 }
4337 else
4338 {
4339 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
4340 {
4341 SWVDEC_BUFFER *p_buffer_swvdec;
4342 p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
4343 OMX_SWVDEC_LOG_LOW("map op buffer");
4344
4345 if((retval_swvdec = swvdec_unmap(m_swvdec_handle,p_buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
4346 {
4347 OMX_SWVDEC_LOG_ERROR("swvdec_unmap failed for op buffer %d: %p",ii,p_buffer_swvdec->p_buffer);
4348 retval = retval_swvdec2omx(retval_swvdec);;
4349 goto buffer_deallocate_op_exit;
4350 }
4351 }
4352 munmap(m_buffer_array_op[ii].buffer_payload.bufferaddr,
4353 m_buffer_array_op[ii].buffer_payload.mmaped_size);
4354
4355 close(m_buffer_array_op[ii].buffer_payload.pmem_fd);
4356
4357 m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
4358
4359 ion_memory_free(&m_buffer_array_op[ii].ion_info);
4360 }
4361
4362 m_buffer_array_op[ii].buffer_populated = false;
4363
4364 m_port_op.populated = OMX_FALSE;
4365
4366 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4367 {
4368 if (m_buffer_array_op[ii].buffer_populated)
4369 {
4370 break;
4371 }
4372 }
4373
4374 if (ii == m_port_op.def.nBufferCountActual)
4375 {
4376 buffer_deallocate_op_info_array();
4377
4378 m_port_op.unpopulated = OMX_TRUE;
4379
4380 if (m_meta_buffer_mode)
4381 {
4382 meta_buffer_array_deallocate();
4383 }
4384 }
4385 }
4386 else
4387 {
4388 OMX_SWVDEC_LOG_ERROR("%p not found", p_buffer_hdr->pBuffer);
4389
4390 retval = OMX_ErrorBadParameter;
4391 }
4392
4393 buffer_deallocate_op_exit:
4394 return retval;
4395 }
4396
4397 /**
4398 * @brief De-allocate input buffer info array.
4399 */
buffer_deallocate_ip_info_array()4400 void omx_swvdec::buffer_deallocate_ip_info_array()
4401 {
4402 assert(m_buffer_array_ip != NULL);
4403
4404 free(m_buffer_array_ip);
4405
4406 m_buffer_array_ip = NULL;
4407 }
4408
4409 /**
4410 * @brief De-allocate output buffer info array.
4411 */
buffer_deallocate_op_info_array()4412 void omx_swvdec::buffer_deallocate_op_info_array()
4413 {
4414 assert(m_buffer_array_op != NULL);
4415
4416 free(m_buffer_array_op);
4417
4418 m_buffer_array_op = NULL;
4419 }
4420
4421 /**
4422 * @brief Allocate meta buffer info array.
4423 *
4424 * @retval OMX_ERRORTYPE
4425 */
meta_buffer_array_allocate()4426 OMX_ERRORTYPE omx_swvdec::meta_buffer_array_allocate()
4427 {
4428 OMX_ERRORTYPE retval = OMX_ErrorNone;
4429
4430 m_meta_buffer_array = ((OMX_SWVDEC_META_BUFFER_INFO *)
4431 calloc(sizeof(OMX_SWVDEC_META_BUFFER_INFO),
4432 m_port_op.def.nBufferCountActual));
4433
4434 if (m_meta_buffer_array == NULL)
4435 {
4436 OMX_SWVDEC_LOG_ERROR("failed to allocate meta_buffer info array; "
4437 "%d element%s, %zu bytes requested",
4438 m_port_op.def.nBufferCountActual,
4439 (m_port_op.def.nBufferCountActual > 1) ? "s" : "",
4440 sizeof(OMX_SWVDEC_META_BUFFER_INFO) *
4441 m_port_op.def.nBufferCountActual);
4442
4443 retval = OMX_ErrorInsufficientResources;
4444 }
4445 else
4446 {
4447 unsigned int ii;
4448
4449 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4450 {
4451 m_meta_buffer_array[ii].fd = -1;
4452 }
4453 }
4454
4455 return retval;
4456 }
4457
4458 /**
4459 * @brief De-allocate meta buffer info array.
4460 */
meta_buffer_array_deallocate()4461 void omx_swvdec::meta_buffer_array_deallocate()
4462 {
4463 assert(m_meta_buffer_array != NULL);
4464
4465 free(m_meta_buffer_array);
4466
4467 m_meta_buffer_array = NULL;
4468 }
4469
4470 /**
4471 * @brief Add meta buffer reference.
4472 *
4473 * @param[in] index: Buffer index.
4474 * @param[in] fd: File descriptor.
4475 */
meta_buffer_ref_add(unsigned int index,int fd)4476 void omx_swvdec::meta_buffer_ref_add(unsigned int index, int fd)
4477 {
4478 if (m_meta_buffer_array[index].ref_count == 0)
4479 {
4480 m_meta_buffer_array[index].fd = fd;
4481 }
4482
4483 m_meta_buffer_array[index].ref_count++;
4484 }
4485
4486 /**
4487 * @brief Remove meta buffer reference.
4488 *
4489 * @param[in] index: Buffer index.
4490 */
meta_buffer_ref_remove(unsigned int index)4491 void omx_swvdec::meta_buffer_ref_remove(unsigned int index)
4492 {
4493 pthread_mutex_lock(&m_meta_buffer_array_mutex);
4494
4495 m_meta_buffer_array[index].ref_count--;
4496
4497 if (m_meta_buffer_array[index].ref_count == 0)
4498 {
4499 m_meta_buffer_array[index].fd = -1;
4500
4501 munmap(m_buffer_array_op[index].buffer_payload.bufferaddr,
4502 m_buffer_array_op[index].buffer_payload.mmaped_size);
4503
4504 m_buffer_array_op[index].buffer_payload.bufferaddr = NULL;
4505 m_buffer_array_op[index].buffer_payload.offset = 0;
4506 m_buffer_array_op[index].buffer_payload.mmaped_size = 0;
4507
4508 m_buffer_array_op[index].buffer_swvdec.p_buffer = NULL;
4509 m_buffer_array_op[index].buffer_swvdec.size = 0;
4510 }
4511
4512 pthread_mutex_unlock(&m_meta_buffer_array_mutex);
4513 }
4514
4515 /**
4516 * @brief Split MPEG-4 bitstream buffer into multiple frames (if they exist).
4517 *
4518 * @param[in,out] offset_array: Array of offsets to frame headers.
4519 * @param[in] p_buffer_hdr: Pointer to buffer header.
4520 *
4521 * @retval Number of frames in buffer.
4522 */
split_buffer_mpeg4(unsigned int * offset_array,OMX_BUFFERHEADERTYPE * p_buffer_hdr)4523 unsigned int split_buffer_mpeg4(unsigned int *offset_array,
4524 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
4525 {
4526 unsigned char *p_buffer = p_buffer_hdr->pBuffer;
4527
4528 unsigned int byte_count = 0;
4529
4530 unsigned int num_frame_headers = 0;
4531
4532 unsigned int next_4bytes;
4533
4534 while ((byte_count < p_buffer_hdr->nFilledLen) &&
4535 (num_frame_headers < OMX_SWVDEC_MAX_FRAMES_PER_ETB))
4536 {
4537 next_4bytes = *((unsigned int *) p_buffer);
4538
4539 next_4bytes = __builtin_bswap32(next_4bytes);
4540
4541 if (next_4bytes == 0x000001B6)
4542 {
4543 OMX_SWVDEC_LOG_HIGH("%p, buffer %p: "
4544 "frame header at %d bytes offset",
4545 p_buffer_hdr,
4546 p_buffer_hdr->pBuffer,
4547 byte_count);
4548
4549 offset_array[num_frame_headers] = byte_count;
4550
4551 num_frame_headers++;
4552
4553 p_buffer += 4;
4554 byte_count += 4;
4555 }
4556 else
4557 {
4558 p_buffer++;
4559 byte_count++;
4560 }
4561 }
4562
4563 return num_frame_headers;
4564 }
4565
4566 /**
4567 * @brief Check if ip port is populated, i.e., if all ip buffers are populated.
4568 *
4569 * @retval true
4570 * @retval false
4571 */
port_ip_populated()4572 OMX_BOOL omx_swvdec::port_ip_populated()
4573 {
4574 OMX_BOOL retval = OMX_FALSE;
4575
4576 if (m_buffer_array_ip != NULL)
4577 {
4578 unsigned int ii;
4579
4580 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
4581 {
4582 if (m_buffer_array_ip[ii].buffer_populated == false)
4583 {
4584 break;
4585 }
4586 }
4587
4588 if (ii == m_port_ip.def.nBufferCountActual)
4589 {
4590 retval = OMX_TRUE;
4591 }
4592 }
4593
4594 return retval;
4595 }
4596
4597 /**
4598 * @brief Check if op port is populated, i.e., if all op buffers are populated.
4599 *
4600 * @retval true
4601 * @retval false
4602 */
port_op_populated()4603 OMX_BOOL omx_swvdec::port_op_populated()
4604 {
4605 OMX_BOOL retval = OMX_FALSE;
4606
4607 if (m_buffer_array_op != NULL)
4608 {
4609 unsigned int ii;
4610
4611 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4612 {
4613 if (m_buffer_array_op[ii].buffer_populated == false)
4614 {
4615 break;
4616 }
4617 }
4618
4619 if (ii == m_port_op.def.nBufferCountActual)
4620 {
4621 retval = OMX_TRUE;
4622 }
4623 }
4624
4625 return retval;
4626 }
4627
4628 /**
4629 * @brief Flush input, output, or both input & output ports.
4630 *
4631 * @param[in] port_index: Index of port to flush.
4632 *
4633 * @retval OMX_ERRORTYPE
4634 */
flush(unsigned int port_index)4635 OMX_ERRORTYPE omx_swvdec::flush(unsigned int port_index)
4636 {
4637 OMX_ERRORTYPE retval = OMX_ErrorNone;
4638
4639 if (((port_index == OMX_CORE_PORT_INDEX_IP) &&
4640 m_port_ip.flush_inprogress) ||
4641 ((port_index == OMX_CORE_PORT_INDEX_OP) &&
4642 m_port_op.flush_inprogress) ||
4643 ((port_index == OMX_ALL) &&
4644 m_port_ip.flush_inprogress &&
4645 m_port_op.flush_inprogress))
4646 {
4647 OMX_SWVDEC_LOG_HIGH("flush port index %d already in progress",
4648 port_index);
4649 }
4650 else
4651 {
4652 SWVDEC_FLUSH_TYPE swvdec_flush_type;
4653
4654 SWVDEC_STATUS retval_swvdec;
4655
4656 if (port_index == OMX_CORE_PORT_INDEX_IP)
4657 {
4658 m_port_ip.flush_inprogress = OMX_TRUE;
4659
4660 //for VTS test case IP flush , trigger flush all
4661 // for IP flush, similar behavior is for hwcodecs
4662 m_port_ip.flush_inprogress = OMX_TRUE;
4663 m_port_op.flush_inprogress = OMX_TRUE;
4664
4665 swvdec_flush_type = SWVDEC_FLUSH_TYPE_ALL;
4666
4667 if ((retval_swvdec = swvdec_flush(m_swvdec_handle,
4668 swvdec_flush_type)) !=
4669 SWVDEC_STATUS_SUCCESS)
4670 {
4671 retval = retval_swvdec2omx(retval_swvdec);
4672 }
4673 }
4674 else if (port_index == OMX_CORE_PORT_INDEX_OP)
4675 {
4676 m_port_op.flush_inprogress = OMX_TRUE;
4677
4678 swvdec_flush_type = (m_port_ip.flush_inprogress ?
4679 SWVDEC_FLUSH_TYPE_ALL :
4680 SWVDEC_FLUSH_TYPE_OP);
4681
4682 if ((retval_swvdec = swvdec_flush(m_swvdec_handle,
4683 swvdec_flush_type)) !=
4684 SWVDEC_STATUS_SUCCESS)
4685 {
4686 retval = retval_swvdec2omx(retval_swvdec);
4687 }
4688 }
4689 else if (port_index == OMX_ALL)
4690 {
4691 m_port_ip.flush_inprogress = OMX_TRUE;
4692 m_port_op.flush_inprogress = OMX_TRUE;
4693
4694 swvdec_flush_type = SWVDEC_FLUSH_TYPE_ALL;
4695
4696 if ((retval_swvdec = swvdec_flush(m_swvdec_handle,
4697 swvdec_flush_type)) !=
4698 SWVDEC_STATUS_SUCCESS)
4699 {
4700 retval = retval_swvdec2omx(retval_swvdec);
4701 }
4702 }
4703 else
4704 {
4705 assert(0);
4706 }
4707 }
4708
4709 return retval;
4710 }
4711
4712 /**
4713 * @brief Allocate & map ION memory.
4714 */
ion_memory_alloc_map(struct ion_allocation_data * p_alloc_data,struct ion_fd_data * p_fd_data,OMX_U32 size,OMX_U32 alignment)4715 int omx_swvdec::ion_memory_alloc_map(struct ion_allocation_data *p_alloc_data,
4716 struct ion_fd_data *p_fd_data,
4717 OMX_U32 size,
4718 OMX_U32 alignment)
4719 {
4720 int fd = -EINVAL;
4721 int rc = -EINVAL;
4722
4723 if ((p_alloc_data == NULL) || (p_fd_data == NULL) || (size == 0))
4724 {
4725 OMX_SWVDEC_LOG_ERROR("invalid arguments");
4726 goto ion_memory_alloc_map_exit;
4727 }
4728
4729 if ((fd = open("/dev/ion", O_RDONLY)) < 0)
4730 {
4731 OMX_SWVDEC_LOG_ERROR("failed to open ion device; fd = %d", fd);
4732 goto ion_memory_alloc_map_exit;
4733 }
4734
4735 p_alloc_data->len = size;
4736 p_alloc_data->align = (alignment < 4096) ? 4096 : alignment;
4737 p_alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
4738 p_alloc_data->flags = 0;
4739
4740 OMX_SWVDEC_LOG_LOW("heap_id_mask 0x%08x, len %zu, align %zu",
4741 p_alloc_data->heap_id_mask,
4742 p_alloc_data->len,
4743 p_alloc_data->align);
4744
4745 rc = ioctl(fd, ION_IOC_ALLOC, p_alloc_data);
4746
4747 if (rc || (p_alloc_data->handle == 0))
4748 {
4749 OMX_SWVDEC_LOG_ERROR("ioctl() for allocation failed");
4750
4751 close(fd);
4752 fd = -ENOMEM;
4753
4754 goto ion_memory_alloc_map_exit;
4755 }
4756
4757 p_fd_data->handle = p_alloc_data->handle;
4758
4759 if (ioctl(fd, ION_IOC_MAP, p_fd_data))
4760 {
4761 struct vdec_ion ion_buf_info;
4762
4763 OMX_SWVDEC_LOG_ERROR("ioctl() for mapping failed");
4764
4765 ion_buf_info.ion_alloc_data = *p_alloc_data;
4766 ion_buf_info.ion_fd_device = fd;
4767 ion_buf_info.ion_fd_data = *p_fd_data;
4768
4769 ion_memory_free(&ion_buf_info);
4770
4771 p_fd_data->fd = -1;
4772
4773 close(fd);
4774 fd = -ENOMEM;
4775
4776 goto ion_memory_alloc_map_exit;
4777 }
4778
4779 ion_memory_alloc_map_exit:
4780 return fd;
4781 }
4782
4783 /**
4784 * @brief Free ION memory.
4785 */
ion_memory_free(struct vdec_ion * p_ion_buf_info)4786 void omx_swvdec::ion_memory_free(struct vdec_ion *p_ion_buf_info)
4787 {
4788 if (p_ion_buf_info == NULL)
4789 {
4790 OMX_SWVDEC_LOG_ERROR("p_ion_buf_info = NULL");
4791 goto ion_memory_free_exit;
4792 }
4793
4794 if (ioctl(p_ion_buf_info->ion_fd_device,
4795 ION_IOC_FREE,
4796 &p_ion_buf_info->ion_alloc_data.handle))
4797 {
4798 OMX_SWVDEC_LOG_ERROR("ioctl() for freeing failed");
4799 }
4800
4801 close(p_ion_buf_info->ion_fd_device);
4802
4803 p_ion_buf_info->ion_fd_device = -1;
4804 p_ion_buf_info->ion_alloc_data.handle = 0;
4805 p_ion_buf_info->ion_fd_data.fd = -1;
4806
4807 ion_memory_free_exit:
4808 return;
4809 }
4810
4811 /**
4812 * @brief Flush cached ION output buffer.
4813 *
4814 * @param[in] index: Index of buffer in output buffer info array.
4815 */
ion_flush_op(unsigned int index)4816 void omx_swvdec::ion_flush_op(unsigned int index)
4817 {
4818 if (index < m_port_op.def.nBufferCountActual)
4819 {
4820 int fd = -EINVAL;
4821 int rc = -EINVAL;
4822
4823 struct vdec_bufferpayload *p_buffer_payload =
4824 &m_buffer_array_op[index].buffer_payload;
4825
4826 struct ion_fd_data fd_data;
4827 struct ion_flush_data flush_data;
4828 struct ion_custom_data custom_data;
4829
4830 memset(&fd_data, 0, sizeof(fd_data));
4831 memset(&flush_data, 0, sizeof(flush_data));
4832 memset(&custom_data, 0, sizeof(custom_data));
4833
4834 if ((fd = open("/dev/ion", O_RDONLY)) < 0)
4835 {
4836 OMX_SWVDEC_LOG_ERROR("failed to open /dev/ion, error %s",
4837 strerror(errno));
4838
4839 goto ion_flush_op_exit;
4840 }
4841
4842 fd_data.fd = p_buffer_payload->pmem_fd;
4843
4844 rc = ioctl(fd, ION_IOC_IMPORT, &fd_data);
4845
4846 if (rc)
4847 {
4848 OMX_SWVDEC_LOG_ERROR("ioctl() for import failed; fd %d",
4849 fd_data.fd);
4850
4851 close(fd);
4852 goto ion_flush_op_exit;
4853 }
4854
4855 flush_data.handle = fd_data.handle;
4856
4857 flush_data.fd = p_buffer_payload->pmem_fd;
4858 flush_data.vaddr = p_buffer_payload->bufferaddr;
4859 flush_data.length = p_buffer_payload->buffer_len;
4860
4861 custom_data.cmd = ION_IOC_CLEAN_CACHES;
4862 custom_data.arg = (unsigned long) &flush_data;
4863
4864 OMX_SWVDEC_LOG_LOW("handle %d, fd %d, vaddr %p, length %d",
4865 flush_data.handle,
4866 flush_data.fd,
4867 flush_data.vaddr,
4868 flush_data.length);
4869
4870 rc = ioctl(fd, ION_IOC_CUSTOM, &custom_data);
4871
4872 if (rc < 0)
4873 {
4874 OMX_SWVDEC_LOG_ERROR("ioctl() for clean cache failed");
4875 }
4876
4877 close(fd);
4878 }
4879 else
4880 {
4881 OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
4882 }
4883
4884 ion_flush_op_exit:
4885 return;
4886 }
4887
4888
4889 /**
4890 * ----------------------------
4891 * component callback functions
4892 * ----------------------------
4893 */
4894
4895 /**
4896 * @brief Empty buffer done callback.
4897 *
4898 * @param[in] p_buffer_ip: Pointer to input buffer structure.
4899 */
swvdec_empty_buffer_done(SWVDEC_BUFFER * p_buffer_ip)4900 void omx_swvdec::swvdec_empty_buffer_done(SWVDEC_BUFFER *p_buffer_ip)
4901 {
4902 unsigned long index = (unsigned long) p_buffer_ip->p_client_data;
4903
4904 m_buffer_array_ip[index].buffer_header.nFilledLen =
4905 p_buffer_ip->filled_length;
4906
4907 async_post_event(OMX_SWVDEC_EVENT_EBD,
4908 (unsigned long) &m_buffer_array_ip[index].buffer_header,
4909 index);
4910 }
4911
4912 /**
4913 * @brief Fill buffer done callback.
4914 *
4915 * @param[in] p_buffer_op: Pointer to output buffer structure.
4916 */
swvdec_fill_buffer_done(SWVDEC_BUFFER * p_buffer_op)4917 void omx_swvdec::swvdec_fill_buffer_done(SWVDEC_BUFFER *p_buffer_op)
4918 {
4919 unsigned long index = (unsigned long) p_buffer_op->p_client_data;
4920
4921 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
4922
4923 if (index < ((unsigned long) m_port_op.def.nBufferCountActual))
4924 {
4925 p_buffer_hdr = &m_buffer_array_op[index].buffer_header;
4926
4927 p_buffer_hdr->nFlags = p_buffer_op->flags;
4928 p_buffer_hdr->nTimeStamp = p_buffer_op->timestamp;
4929 p_buffer_hdr->nFilledLen = ((m_meta_buffer_mode &&
4930 p_buffer_op->filled_length) ?
4931 p_buffer_hdr->nAllocLen :
4932 p_buffer_op->filled_length);
4933 }
4934
4935 async_post_event(OMX_SWVDEC_EVENT_FBD,
4936 (unsigned long) &m_buffer_array_op[index].buffer_header,
4937 index);
4938 }
4939
4940 /**
4941 * @brief Event handler callback.
4942 *
4943 * @param[in] event: Event.
4944 * @param[in] p_data: Pointer to event-specific data.
4945 */
swvdec_event_handler(SWVDEC_EVENT event,void * p_data)4946 void omx_swvdec::swvdec_event_handler(SWVDEC_EVENT event, void *p_data)
4947 {
4948 switch (event)
4949 {
4950
4951 case SWVDEC_EVENT_FLUSH_ALL_DONE:
4952 {
4953 async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_IP, 0, 0);
4954 async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_OP, 0, 0);
4955
4956 break;
4957 }
4958
4959 case SWVDEC_EVENT_FLUSH_OP_DONE:
4960 {
4961 async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_OP, 0, 0);
4962
4963 break;
4964 }
4965
4966 case SWVDEC_EVENT_RELEASE_REFERENCE:
4967 {
4968 SWVDEC_BUFFER *p_buffer_op = (SWVDEC_BUFFER *) p_data;
4969
4970 unsigned long index = (unsigned long) p_buffer_op->p_client_data;
4971
4972 OMX_SWVDEC_LOG_LOW("release reference: %p", p_buffer_op->p_buffer);
4973
4974 assert(index < ((unsigned long) m_port_op.def.nBufferCountActual));
4975
4976 if (m_meta_buffer_mode)
4977 {
4978 meta_buffer_ref_remove(index);
4979 }
4980
4981 break;
4982 }
4983
4984 case SWVDEC_EVENT_RECONFIG_REQUIRED:
4985 {
4986 async_post_event(OMX_SWVDEC_EVENT_PORT_RECONFIG, 0, 0);
4987
4988 break;
4989 }
4990
4991 case SWVDEC_EVENT_DIMENSIONS_UPDATED:
4992 {
4993 async_post_event(OMX_SWVDEC_EVENT_DIMENSIONS_UPDATED, 0, 0);
4994
4995 break;
4996 }
4997
4998 case SWVDEC_EVENT_FATAL_ERROR:
4999 default:
5000 {
5001 async_post_event(OMX_SWVDEC_EVENT_ERROR, OMX_ErrorHardware, 0);
5002
5003 break;
5004 }
5005
5006 }
5007 }
5008
5009 /**
5010 * @brief Translate SwVdec status return value to OMX error type return value.
5011 *
5012 * @param[in] retval_swvdec: SwVdec status return value.
5013 *
5014 * @retval OMX_ERRORTYPE
5015 */
retval_swvdec2omx(SWVDEC_STATUS retval_swvdec)5016 OMX_ERRORTYPE omx_swvdec::retval_swvdec2omx(SWVDEC_STATUS retval_swvdec)
5017 {
5018 OMX_ERRORTYPE retval_omx;
5019
5020 switch (retval_swvdec) {
5021 case SWVDEC_STATUS_SUCCESS:
5022 retval_omx = OMX_ErrorNone;
5023 break;
5024
5025 case SWVDEC_STATUS_FAILURE:
5026 retval_omx = OMX_ErrorUndefined;
5027 break;
5028
5029 case SWVDEC_STATUS_NULL_POINTER:
5030 case SWVDEC_STATUS_INVALID_PARAMETERS:
5031 retval_omx = OMX_ErrorBadParameter;
5032 break;
5033
5034 case SWVDEC_STATUS_INVALID_STATE:
5035 retval_omx = OMX_ErrorInvalidState;
5036 break;
5037
5038 case SWVDEC_STATUS_INSUFFICIENT_RESOURCES:
5039 retval_omx = OMX_ErrorInsufficientResources;
5040 break;
5041
5042 case SWVDEC_STATUS_UNSUPPORTED:
5043 retval_omx = OMX_ErrorUnsupportedSetting;
5044 break;
5045
5046 case SWVDEC_STATUS_NOT_IMPLEMENTED:
5047 retval_omx = OMX_ErrorNotImplemented;
5048 break;
5049
5050 default:
5051 retval_omx = OMX_ErrorUndefined;
5052 break;
5053 }
5054
5055 return retval_omx;
5056 }
5057
5058 /**
5059 * @brief Create asynchronous thread.
5060 *
5061 * @retval OMX_ERRORTYPE
5062 */
async_thread_create()5063 OMX_ERRORTYPE omx_swvdec::async_thread_create()
5064 {
5065 OMX_ERRORTYPE retval = OMX_ErrorNone;
5066
5067 pthread_attr_t thread_attributes;
5068
5069 if (sem_init(&m_async_thread.sem_thread_created, 0, 0))
5070 {
5071 OMX_SWVDEC_LOG_ERROR("failed to create async thread created semaphore");
5072
5073 retval = OMX_ErrorInsufficientResources;
5074 }
5075 else if (sem_init(&m_async_thread.sem_event, 0, 0))
5076 {
5077 OMX_SWVDEC_LOG_ERROR("failed to create async thread event semaphore");
5078
5079 retval = OMX_ErrorInsufficientResources;
5080 }
5081 else if (pthread_attr_init(&thread_attributes))
5082 {
5083 OMX_SWVDEC_LOG_ERROR("failed to create thread attributes object");
5084
5085 retval = OMX_ErrorInsufficientResources;
5086 }
5087 else if (pthread_attr_setdetachstate(&thread_attributes,
5088 PTHREAD_CREATE_JOINABLE))
5089 {
5090 OMX_SWVDEC_LOG_ERROR("failed to set detach state attribute");
5091
5092 retval = OMX_ErrorInsufficientResources;
5093
5094 pthread_attr_destroy(&thread_attributes);
5095 }
5096 else
5097 {
5098 m_async_thread.created = false;
5099 m_async_thread.exit = false;
5100
5101 if (pthread_create(&m_async_thread.handle,
5102 &thread_attributes,
5103 (void *(*)(void *)) async_thread,
5104 this))
5105 {
5106 OMX_SWVDEC_LOG_ERROR("failed to create async thread");
5107
5108 retval = OMX_ErrorInsufficientResources;
5109
5110 pthread_attr_destroy(&thread_attributes);
5111 }
5112 else
5113 {
5114 if (pthread_setname_np(m_async_thread.handle, "swvdec_async"))
5115 {
5116 // don't return error
5117 OMX_SWVDEC_LOG_ERROR("failed to set async thread name");
5118 }
5119
5120 sem_wait(&m_async_thread.sem_thread_created);
5121
5122 m_async_thread.created = true;
5123 }
5124 }
5125
5126 return retval;
5127 }
5128
5129 /**
5130 * @brief Destroy asynchronous thread.
5131 */
async_thread_destroy()5132 void omx_swvdec::async_thread_destroy()
5133 {
5134 if (m_async_thread.created)
5135 {
5136 m_async_thread.exit = true;
5137
5138 sem_post(&m_async_thread.sem_event);
5139
5140 pthread_join(m_async_thread.handle, NULL);
5141
5142 m_async_thread.created = false;
5143 }
5144
5145 m_async_thread.exit = false;
5146
5147 sem_destroy(&m_async_thread.sem_event);
5148 sem_destroy(&m_async_thread.sem_thread_created);
5149 }
5150
5151 /**
5152 * @brief Post event to appropriate queue.
5153 *
5154 * @param[in] event_id: Event ID.
5155 * @param[in] event_param1: Event parameter 1.
5156 * @param[in] event_param2: Event parameter 2.
5157 */
async_post_event(unsigned long event_id,unsigned long event_param1,unsigned long event_param2)5158 void omx_swvdec::async_post_event(unsigned long event_id,
5159 unsigned long event_param1,
5160 unsigned long event_param2)
5161 {
5162 OMX_SWVDEC_EVENT_INFO event_info;
5163
5164 event_info.event_id = event_id;
5165 event_info.event_param1 = event_param1;
5166 event_info.event_param2 = event_param2;
5167
5168 switch (event_id)
5169 {
5170
5171 case OMX_SWVDEC_EVENT_ETB:
5172 case OMX_SWVDEC_EVENT_EBD:
5173 {
5174 m_queue_port_ip.push(&event_info);
5175 break;
5176 }
5177
5178 case OMX_SWVDEC_EVENT_FTB:
5179 case OMX_SWVDEC_EVENT_FBD:
5180 {
5181 m_queue_port_op.push(&event_info);
5182 break;
5183 }
5184
5185 default:
5186 {
5187 m_queue_command.push(&event_info);
5188 break;
5189 }
5190
5191 }
5192
5193 sem_post(&m_async_thread.sem_event);
5194 }
5195
5196 /**
5197 * @brief Asynchronous thread.
5198 *
5199 * @param[in] p_cmp: Pointer to OMX SwVdec component class.
5200 */
async_thread(void * p_cmp)5201 void omx_swvdec::async_thread(void *p_cmp)
5202 {
5203 if (p_cmp == NULL)
5204 {
5205 OMX_SWVDEC_LOG_ERROR("p_cmp = NULL");
5206 }
5207 else
5208 {
5209 omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_cmp;
5210
5211 ASYNC_THREAD *p_async_thread = &p_omx_swvdec->m_async_thread;
5212
5213 OMX_SWVDEC_LOG_HIGH("created");
5214
5215 sem_post(&p_async_thread->sem_thread_created);
5216
5217 while (p_async_thread->exit == false)
5218 {
5219 sem_wait(&p_async_thread->sem_event);
5220
5221 if (p_async_thread->exit == true)
5222 {
5223 break;
5224 }
5225
5226 p_omx_swvdec->async_process_event(p_cmp);
5227 }
5228 }
5229
5230 OMX_SWVDEC_LOG_HIGH("exiting");
5231 }
5232
5233 /**
5234 * @brief Process event.
5235 *
5236 * @param[in] p_cmp: Pointer to OMX SwVdec component class.
5237 */
async_process_event(void * p_cmp)5238 void omx_swvdec::async_process_event(void *p_cmp)
5239 {
5240 omx_swvdec *p_omx_swvdec;
5241
5242 OMX_SWVDEC_EVENT_INFO event_info;
5243
5244 OMX_ERRORTYPE retval = OMX_ErrorNone;
5245
5246 if (p_cmp == NULL)
5247 {
5248 OMX_SWVDEC_LOG_ERROR("p_cmp = NULL");
5249
5250 goto async_process_event_exit;
5251 }
5252
5253 p_omx_swvdec = (omx_swvdec *) p_cmp;
5254
5255 // NOTE: queues popped in order of priority; do not change!
5256
5257 if ((p_omx_swvdec->m_queue_command.pop(&event_info) == false) &&
5258 (p_omx_swvdec->m_queue_port_op.pop(&event_info) == false) &&
5259 (p_omx_swvdec->m_queue_port_ip.pop(&event_info) == false))
5260 {
5261 OMX_SWVDEC_LOG_LOW("no event popped");
5262
5263 goto async_process_event_exit;
5264 }
5265
5266 switch (event_info.event_id)
5267 {
5268
5269 case OMX_SWVDEC_EVENT_CMD:
5270 {
5271 OMX_COMMANDTYPE cmd = (OMX_COMMANDTYPE) event_info.event_param1;
5272 OMX_U32 param = (OMX_U32) event_info.event_param2;
5273
5274 retval = p_omx_swvdec->async_process_event_cmd(cmd, param);
5275 break;
5276 }
5277
5278 case OMX_SWVDEC_EVENT_CMD_ACK:
5279 {
5280 OMX_COMMANDTYPE cmd = (OMX_COMMANDTYPE) event_info.event_param1;
5281 OMX_U32 param = (OMX_U32) event_info.event_param2;
5282
5283 retval = p_omx_swvdec->async_process_event_cmd_ack(cmd, param);
5284 break;
5285 }
5286
5287 case OMX_SWVDEC_EVENT_ERROR:
5288 {
5289 OMX_ERRORTYPE error_code = (OMX_ERRORTYPE) event_info.event_param1;
5290
5291 retval = p_omx_swvdec->async_process_event_error(error_code);
5292 break;
5293 }
5294
5295 case OMX_SWVDEC_EVENT_ETB:
5296 {
5297 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5298 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5299
5300 unsigned int index = event_info.event_param2;
5301
5302 retval = p_omx_swvdec->async_process_event_etb(p_buffer_hdr, index);
5303 break;
5304 }
5305
5306 case OMX_SWVDEC_EVENT_FTB:
5307 {
5308 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5309 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5310
5311 unsigned int index = event_info.event_param2;
5312
5313 retval = p_omx_swvdec->async_process_event_ftb(p_buffer_hdr, index);
5314 break;
5315 }
5316
5317 case OMX_SWVDEC_EVENT_EBD:
5318 {
5319 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5320 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5321
5322 unsigned int index = event_info.event_param2;
5323
5324 retval = p_omx_swvdec->async_process_event_ebd(p_buffer_hdr, index);
5325 break;
5326 }
5327
5328 case OMX_SWVDEC_EVENT_FBD:
5329 {
5330 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5331 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5332
5333 unsigned int index = event_info.event_param2;
5334
5335 retval = p_omx_swvdec->async_process_event_fbd(p_buffer_hdr, index);
5336 break;
5337 }
5338
5339 case OMX_SWVDEC_EVENT_EOS:
5340 {
5341 retval = p_omx_swvdec->async_process_event_eos();
5342 break;
5343 }
5344
5345 case OMX_SWVDEC_EVENT_FLUSH_PORT_IP:
5346 {
5347 retval = p_omx_swvdec->async_process_event_flush_port_ip();
5348 break;
5349 }
5350
5351 case OMX_SWVDEC_EVENT_FLUSH_PORT_OP:
5352 {
5353 retval = p_omx_swvdec->async_process_event_flush_port_op();
5354 break;
5355 }
5356
5357 case OMX_SWVDEC_EVENT_PORT_RECONFIG:
5358 {
5359 retval = p_omx_swvdec->async_process_event_port_reconfig();
5360 break;
5361 }
5362
5363 case OMX_SWVDEC_EVENT_DIMENSIONS_UPDATED:
5364 {
5365 retval = p_omx_swvdec->async_process_event_dimensions_updated();
5366 break;
5367 }
5368
5369 default:
5370 {
5371 assert(0);
5372
5373 retval = OMX_ErrorUndefined;
5374 break;
5375 }
5376
5377 }
5378
5379 if (retval != OMX_ErrorNone)
5380 {
5381 p_omx_swvdec->async_post_event(OMX_SWVDEC_EVENT_ERROR, retval, 0);
5382 }
5383
5384 async_process_event_exit:
5385 return;
5386 }
5387
5388 /**
5389 * @brief Process command event.
5390 *
5391 * @param[in] cmd: Command.
5392 * @param[in] param: Command parameter.
5393 *
5394 * @retval OMX_ERRORTYPE
5395 */
async_process_event_cmd(OMX_COMMANDTYPE cmd,OMX_U32 param)5396 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd(OMX_COMMANDTYPE cmd,
5397 OMX_U32 param)
5398 {
5399 OMX_ERRORTYPE retval = OMX_ErrorNone;
5400
5401 bool cmd_ack = false;
5402
5403 switch (cmd)
5404 {
5405
5406 case OMX_CommandStateSet:
5407 {
5408 retval = async_process_event_cmd_state_set(&cmd_ack,
5409 (OMX_STATETYPE) param);
5410 break;
5411 }
5412
5413 case OMX_CommandFlush:
5414 {
5415 retval = async_process_event_cmd_flush((unsigned int) param);
5416 break;
5417 }
5418
5419 case OMX_CommandPortDisable:
5420 {
5421 retval = async_process_event_cmd_port_disable(&cmd_ack,
5422 (unsigned int) param);
5423 break;
5424 }
5425
5426 case OMX_CommandPortEnable:
5427 {
5428 retval = async_process_event_cmd_port_enable(&cmd_ack,
5429 (unsigned int) param);
5430 break;
5431 }
5432
5433 default:
5434 {
5435 OMX_SWVDEC_LOG_ERROR("cmd '%d' invalid", (int) cmd);
5436
5437 retval = OMX_ErrorBadParameter;
5438 break;
5439 }
5440
5441 } // switch (cmd)
5442
5443 if (retval != OMX_ErrorNone)
5444 {
5445 async_post_event(OMX_SWVDEC_EVENT_ERROR, retval, 0);
5446 }
5447 else if (cmd_ack)
5448 {
5449 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK, cmd, param);
5450 }
5451
5452 sem_post(&m_sem_cmd);
5453
5454 return retval;
5455 }
5456
5457 /**
5458 * @brief Process command acknowledgement event.
5459 *
5460 * @param[in] cmd: Command.
5461 * @param[in] param: Command parameter.
5462 *
5463 * @retval OMX_ERRORTYPE
5464 */
async_process_event_cmd_ack(OMX_COMMANDTYPE cmd,OMX_U32 param)5465 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_ack(OMX_COMMANDTYPE cmd,
5466 OMX_U32 param)
5467 {
5468 OMX_ERRORTYPE retval = OMX_ErrorNone;
5469
5470 switch (cmd)
5471 {
5472
5473 case OMX_CommandStateSet:
5474 {
5475 OMX_SWVDEC_LOG_HIGH("%s -> %s",
5476 OMX_STATETYPE_STRING(m_state),
5477 OMX_STATETYPE_STRING((OMX_STATETYPE) param));
5478
5479 m_state = (OMX_STATETYPE) param;
5480
5481 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventCmdComplete, "
5482 "OMX_CommandStateSet, %s",
5483 OMX_STATETYPE_STRING(m_state));
5484
5485 m_callback.EventHandler(&m_cmp,
5486 m_app_data,
5487 OMX_EventCmdComplete,
5488 OMX_CommandStateSet,
5489 (OMX_U32) m_state,
5490 NULL);
5491 break;
5492 }
5493
5494 case OMX_CommandFlush:
5495 case OMX_CommandPortEnable:
5496 case OMX_CommandPortDisable:
5497 {
5498 if ((cmd == OMX_CommandPortEnable) && m_port_reconfig_inprogress)
5499 {
5500 m_port_reconfig_inprogress = false;
5501 }
5502
5503 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventCmdComplete, "
5504 "%s, port index %d",
5505 OMX_COMMANDTYPE_STRING(cmd),
5506 param);
5507
5508 m_callback.EventHandler(&m_cmp,
5509 m_app_data,
5510 OMX_EventCmdComplete,
5511 cmd,
5512 param,
5513 NULL);
5514 break;
5515 }
5516
5517 default:
5518 {
5519 OMX_SWVDEC_LOG_ERROR("cmd '%d' invalid", (int) cmd);
5520
5521 retval = OMX_ErrorBadParameter;
5522 break;
5523 }
5524
5525 } // switch (cmd)
5526
5527 return retval;
5528 }
5529
5530 /**
5531 * @brief Process error event.
5532 *
5533 * @param[in] error_code: Error code.
5534 *
5535 * @retval OMX_ErrorNone
5536 */
async_process_event_error(OMX_ERRORTYPE error_code)5537 OMX_ERRORTYPE omx_swvdec::async_process_event_error(OMX_ERRORTYPE error_code)
5538 {
5539 if (error_code == OMX_ErrorInvalidState)
5540 {
5541 OMX_SWVDEC_LOG_HIGH("%s -> OMX_StateInvalid",
5542 OMX_STATETYPE_STRING(m_state));
5543
5544 m_state = OMX_StateInvalid;
5545 }
5546
5547 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventError, 0x%08x",
5548 error_code);
5549
5550 m_callback.EventHandler(&m_cmp,
5551 m_app_data,
5552 OMX_EventError,
5553 (OMX_U32) error_code,
5554 0,
5555 NULL);
5556
5557 return OMX_ErrorNone;
5558 }
5559
5560 /**
5561 * @brief Process OMX_CommandStateSet.
5562 *
5563 * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
5564 * @param[in] state_new: New state to which transition is requested.
5565 *
5566 * @retval OMX_ERRORTYPE
5567 */
async_process_event_cmd_state_set(bool * p_cmd_ack,OMX_STATETYPE state_new)5568 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_state_set(
5569 bool *p_cmd_ack,
5570 OMX_STATETYPE state_new)
5571 {
5572 OMX_ERRORTYPE retval = OMX_ErrorNone;
5573
5574 SWVDEC_STATUS retval_swvdec;
5575
5576 OMX_SWVDEC_LOG_HIGH("'%s-to-%s' requested",
5577 OMX_STATETYPE_STRING(m_state),
5578 OMX_STATETYPE_STRING(state_new));
5579
5580 /**
5581 * Only the following state transitions are allowed via CommandStateSet:
5582 *
5583 * LOADED -> IDLE -> EXECUTING
5584 * LOADED <- IDLE <- EXECUTING
5585 */
5586
5587 if (m_state == OMX_StateInvalid)
5588 {
5589 OMX_SWVDEC_LOG_ERROR("in state %s", OMX_STATETYPE_STRING(m_state));
5590
5591 retval = OMX_ErrorInvalidState;
5592 }
5593 else if (state_new == OMX_StateInvalid)
5594 {
5595 OMX_SWVDEC_LOG_ERROR("requested transition to state %s",
5596 OMX_STATETYPE_STRING(state_new));
5597
5598 retval = OMX_ErrorInvalidState;
5599 }
5600 else if ((m_state == OMX_StateLoaded) &&
5601 (state_new == OMX_StateIdle))
5602 {
5603 if ((m_port_ip.populated == OMX_TRUE) &&
5604 (m_port_op.populated == OMX_TRUE))
5605 {
5606 if ((retval_swvdec = swvdec_start(m_swvdec_handle)) ==
5607 SWVDEC_STATUS_SUCCESS)
5608 {
5609 *p_cmd_ack = true;
5610 }
5611 else
5612 {
5613 OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
5614
5615 retval = retval_swvdec2omx(retval_swvdec);
5616 }
5617 }
5618 else
5619 {
5620 m_status_flags |= (1 << PENDING_STATE_LOADED_TO_IDLE);
5621
5622 OMX_SWVDEC_LOG_LOW("'loaded-to-idle' pending");
5623 }
5624 }
5625 else if ((m_state == OMX_StateIdle) &&
5626 (state_new == OMX_StateExecuting))
5627 {
5628 *p_cmd_ack = true;
5629 }
5630 else if ((m_state == OMX_StateExecuting) &&
5631 (state_new == OMX_StateIdle))
5632 {
5633 m_status_flags |= (1 << PENDING_STATE_EXECUTING_TO_IDLE);
5634
5635 OMX_SWVDEC_LOG_LOW("'executing-to-idle' pending");
5636
5637 retval = flush(OMX_ALL);
5638 }
5639 else if ((m_state == OMX_StateIdle) &&
5640 (state_new == OMX_StateLoaded))
5641 {
5642 if ((m_port_ip.unpopulated == OMX_TRUE) &&
5643 (m_port_op.unpopulated == OMX_TRUE))
5644 {
5645 if ((retval_swvdec = swvdec_stop(m_swvdec_handle)) ==
5646 SWVDEC_STATUS_SUCCESS)
5647 {
5648 *p_cmd_ack = true;
5649 }
5650 else
5651 {
5652 OMX_SWVDEC_LOG_ERROR("failed to stop SwVdec");
5653
5654 retval = retval_swvdec2omx(retval_swvdec);
5655 }
5656 }
5657 else
5658 {
5659 m_status_flags |= (1 << PENDING_STATE_IDLE_TO_LOADED);
5660
5661 OMX_SWVDEC_LOG_LOW("'idle-to-loaded' pending");
5662 }
5663 }
5664 else
5665 {
5666 OMX_SWVDEC_LOG_ERROR("state transition '%s -> %s' illegal",
5667 OMX_STATETYPE_STRING(m_state),
5668 OMX_STATETYPE_STRING(state_new));
5669
5670 retval = ((state_new == m_state) ?
5671 OMX_ErrorSameState :
5672 OMX_ErrorIncorrectStateTransition);
5673 }
5674
5675 return retval;
5676 }
5677
5678 /**
5679 * @brief Process OMX_CommandFlush.
5680 *
5681 * @param[in] port_index: Index of port to flush.
5682 *
5683 * @retval OMX_ERRORTYPE
5684 */
async_process_event_cmd_flush(unsigned int port_index)5685 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_flush(unsigned int port_index)
5686 {
5687 OMX_ERRORTYPE retval = OMX_ErrorNone;
5688
5689 OMX_SWVDEC_LOG_HIGH("flush port index %d requested", port_index);
5690
5691 if (port_index == OMX_CORE_PORT_INDEX_IP)
5692 {
5693 m_status_flags |= (1 << PENDING_PORT_FLUSH_IP);
5694
5695 OMX_SWVDEC_LOG_LOW("ip port flush pending");
5696 }
5697 else if (port_index == OMX_CORE_PORT_INDEX_OP)
5698 {
5699 m_status_flags |= (1 << PENDING_PORT_FLUSH_OP);
5700
5701 OMX_SWVDEC_LOG_LOW("op port flush pending");
5702 }
5703 else if (port_index == OMX_ALL)
5704 {
5705 m_status_flags |= (1 << PENDING_PORT_FLUSH_IP);
5706 m_status_flags |= (1 << PENDING_PORT_FLUSH_OP);
5707
5708 OMX_SWVDEC_LOG_LOW("ip & op ports flush pending");
5709 }
5710
5711 retval = flush(port_index);
5712
5713 return retval;
5714 }
5715
5716 /**
5717 * @brief Process OMX_CommandPortDisable.
5718 *
5719 * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
5720 * @param[in] port_index: Index of port to disable.
5721 *
5722 * @retval OMX_ERRORTYPE
5723 */
async_process_event_cmd_port_disable(bool * p_cmd_ack,unsigned int port_index)5724 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_port_disable(
5725 bool *p_cmd_ack,
5726 unsigned int port_index)
5727 {
5728 OMX_ERRORTYPE retval = OMX_ErrorNone;
5729
5730 OMX_SWVDEC_LOG_HIGH("disable port index %d requested", port_index);
5731
5732 if (port_index == OMX_CORE_PORT_INDEX_IP)
5733 {
5734 if (m_port_ip.enabled == OMX_FALSE)
5735 {
5736 OMX_SWVDEC_LOG_ERROR("ip port already disabled");
5737
5738 retval = OMX_ErrorBadPortIndex;
5739 }
5740 else
5741 {
5742 m_port_ip.enabled = OMX_FALSE;
5743
5744 if (m_port_ip.unpopulated)
5745 {
5746 *p_cmd_ack = true;
5747 }
5748 else
5749 {
5750 m_status_flags |= (1 << PENDING_PORT_DISABLE_IP);
5751
5752 OMX_SWVDEC_LOG_LOW("ip port disable pending");
5753
5754 if (m_port_ip.num_pending_buffers)
5755 {
5756 retval = flush(port_index);
5757 }
5758 }
5759 }
5760 }
5761 else if (port_index == OMX_CORE_PORT_INDEX_OP)
5762 {
5763 if (m_port_op.enabled == OMX_FALSE)
5764 {
5765 OMX_SWVDEC_LOG_ERROR("op port already disabled");
5766
5767 retval = OMX_ErrorBadPortIndex;
5768 }
5769 else
5770 {
5771 m_port_op.enabled = OMX_FALSE;
5772
5773 if (m_port_op.unpopulated)
5774 {
5775 *p_cmd_ack = true;
5776 }
5777 else
5778 {
5779 m_status_flags |= (1 << PENDING_PORT_DISABLE_OP);
5780
5781 OMX_SWVDEC_LOG_LOW("op port disable pending");
5782
5783 if (m_port_op.num_pending_buffers)
5784 {
5785 retval = flush(port_index);
5786 }
5787 }
5788 }
5789 }
5790 else if (port_index == OMX_ALL)
5791 {
5792 if (m_port_ip.enabled == OMX_FALSE)
5793 {
5794 OMX_SWVDEC_LOG_ERROR("ip port already disabled");
5795
5796 retval = OMX_ErrorBadPortIndex;
5797 }
5798 else if (m_port_op.enabled == OMX_FALSE)
5799 {
5800 OMX_SWVDEC_LOG_ERROR("op port already disabled");
5801
5802 retval = OMX_ErrorBadPortIndex;
5803 }
5804 else
5805 {
5806 if (m_port_ip.unpopulated && m_port_op.unpopulated)
5807 {
5808 *p_cmd_ack = true;
5809 }
5810 else
5811 {
5812 m_port_ip.enabled = OMX_FALSE;
5813 m_port_op.enabled = OMX_FALSE;
5814
5815 if (m_port_ip.unpopulated == OMX_FALSE)
5816 {
5817 m_status_flags |= (1 << PENDING_PORT_DISABLE_IP);
5818
5819 OMX_SWVDEC_LOG_LOW("ip port disable pending");
5820
5821 if (m_port_ip.num_pending_buffers)
5822 {
5823 retval = flush(port_index);
5824 }
5825 }
5826
5827 if ((retval == OMX_ErrorNone) &&
5828 (m_port_op.unpopulated == OMX_FALSE))
5829 {
5830 m_status_flags |= (1 << PENDING_PORT_DISABLE_OP);
5831
5832 OMX_SWVDEC_LOG_LOW("op port disable pending");
5833
5834 if (m_port_op.num_pending_buffers)
5835 {
5836 retval = flush(port_index);
5837 }
5838 }
5839 }
5840 }
5841 }
5842 else
5843 {
5844 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
5845 port_index);
5846
5847 retval = OMX_ErrorBadPortIndex;
5848 }
5849
5850 return retval;
5851 }
5852
5853 /**
5854 * @brief Process OMX_CommandPortEnable.
5855 *
5856 * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
5857 * @param[in] port_index: Index of port to enable.
5858 *
5859 * @retval OMX_ERRORTYPE
5860 */
async_process_event_cmd_port_enable(bool * p_cmd_ack,unsigned int port_index)5861 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_port_enable(
5862 bool *p_cmd_ack,
5863 unsigned int port_index)
5864 {
5865 OMX_ERRORTYPE retval = OMX_ErrorNone;
5866
5867 OMX_SWVDEC_LOG_HIGH("enable port index %d requested", port_index);
5868
5869 if (port_index == OMX_CORE_PORT_INDEX_IP)
5870 {
5871 if (m_port_ip.enabled)
5872 {
5873 OMX_SWVDEC_LOG_ERROR("ip port already enabled");
5874
5875 retval = OMX_ErrorBadPortIndex;
5876 }
5877 else
5878 {
5879 m_port_ip.enabled = OMX_TRUE;
5880
5881 if (m_port_ip.populated)
5882 {
5883 *p_cmd_ack = true;
5884 }
5885 else
5886 {
5887 m_status_flags |= (1 << PENDING_PORT_ENABLE_IP);
5888
5889 OMX_SWVDEC_LOG_LOW("ip port enable pending");
5890 }
5891 }
5892 }
5893 else if (port_index == OMX_CORE_PORT_INDEX_OP)
5894 {
5895 if (m_port_op.enabled)
5896 {
5897 OMX_SWVDEC_LOG_ERROR("op port already enabled");
5898
5899 retval = OMX_ErrorBadPortIndex;
5900 }
5901 else
5902 {
5903 m_port_op.enabled = OMX_TRUE;
5904
5905 if (m_port_op.populated)
5906 {
5907 *p_cmd_ack = true;
5908 }
5909 else
5910 {
5911 m_status_flags |= (1 << PENDING_PORT_ENABLE_OP);
5912
5913 OMX_SWVDEC_LOG_LOW("op port enable pending");
5914 }
5915 }
5916 }
5917 else if (port_index == OMX_ALL)
5918 {
5919 if (m_port_ip.enabled)
5920 {
5921 OMX_SWVDEC_LOG_ERROR("ip port already enabled");
5922
5923 retval = OMX_ErrorBadPortIndex;
5924 }
5925 else if (m_port_op.enabled)
5926 {
5927 OMX_SWVDEC_LOG_ERROR("op port already enabled");
5928
5929 retval = OMX_ErrorBadPortIndex;
5930 }
5931 else
5932 {
5933 m_port_ip.enabled = OMX_TRUE;
5934 m_port_op.enabled = OMX_TRUE;
5935
5936 if (m_port_ip.populated && m_port_op.populated)
5937 {
5938 *p_cmd_ack = true;
5939 }
5940 else if (m_port_ip.populated == false)
5941 {
5942 m_status_flags |= (1 << PENDING_PORT_ENABLE_IP);
5943
5944 OMX_SWVDEC_LOG_LOW("ip port enable pending");
5945 }
5946 else if (m_port_op.populated == false)
5947 {
5948 m_status_flags |= (1 << PENDING_PORT_ENABLE_OP);
5949
5950 OMX_SWVDEC_LOG_LOW("op port enable pending");
5951 }
5952 }
5953 }
5954 else
5955 {
5956 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
5957 port_index);
5958
5959 retval = OMX_ErrorBadPortIndex;
5960 }
5961
5962 return retval;
5963 }
5964
5965 /**
5966 * @brief Process ETB event.
5967 *
5968 * @param[in] p_buffer_hdr: Pointer to buffer header.
5969 * @param[in] index: Index of buffer in input buffer info array.
5970 *
5971 * @retval OMX_ERRORTYPE
5972 */
async_process_event_etb(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)5973 OMX_ERRORTYPE omx_swvdec::async_process_event_etb(
5974 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
5975 unsigned int index)
5976 {
5977 OMX_ERRORTYPE retval = OMX_ErrorNone;
5978
5979 m_port_ip.num_pending_buffers++;
5980
5981 if ((p_buffer_hdr->nFilledLen == 0) &&
5982 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5983 {
5984 OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p,"
5985 "zero length & no EOS flag",
5986 p_buffer_hdr,
5987 p_buffer_hdr->pBuffer);
5988
5989 async_post_event(OMX_SWVDEC_EVENT_EBD,
5990 (unsigned long) p_buffer_hdr,
5991 (unsigned long) index);
5992 }
5993 else if (m_port_ip.flush_inprogress)
5994 {
5995 OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p; "
5996 "ip port flush in progress",
5997 p_buffer_hdr,
5998 p_buffer_hdr->pBuffer);
5999
6000 async_post_event(OMX_SWVDEC_EVENT_EBD,
6001 (unsigned long) p_buffer_hdr,
6002 (unsigned long) index);
6003 }
6004 else
6005 {
6006 SWVDEC_STATUS retval_swvdec;
6007
6008 SWVDEC_BUFFER *p_buffer_swvdec =
6009 &(m_buffer_array_ip[index].buffer_swvdec);
6010
6011 if (p_buffer_hdr->nFilledLen &&
6012 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == 0))
6013 {
6014 m_queue_timestamp.push(p_buffer_hdr->nTimeStamp);
6015 }
6016
6017 assert(p_buffer_swvdec->p_buffer == p_buffer_hdr->pBuffer);
6018 //sending the fd info
6019 p_buffer_swvdec->fd = m_buffer_array_ip[index].buffer_payload.pmem_fd;
6020 if (m_arbitrary_bytes_mode &&
6021 p_buffer_hdr->nFilledLen &&
6022 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == 0))
6023 {
6024 unsigned int offset_array[OMX_SWVDEC_MAX_FRAMES_PER_ETB] = {0};
6025
6026 unsigned int num_frame_headers = 1;
6027
6028 if ((m_omx_video_codingtype ==
6029 ((OMX_VIDEO_CODINGTYPE) QOMX_VIDEO_CodingDivx)) ||
6030 (m_omx_video_codingtype == OMX_VIDEO_CodingMPEG4))
6031 {
6032 num_frame_headers = split_buffer_mpeg4(offset_array,
6033 p_buffer_hdr);
6034 }
6035 else
6036 {
6037 assert(0);
6038 }
6039
6040 if(num_frame_headers > 1)
6041 {
6042 m_buffer_array_ip[index].split_count = num_frame_headers - 1;
6043
6044 for (unsigned int ii = 0; ii < num_frame_headers; ii++)
6045 {
6046 p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
6047 p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
6048
6049 if (ii == 0)
6050 {
6051 p_buffer_swvdec->offset = 0;
6052 p_buffer_swvdec->filled_length = (offset_array[ii + 1] ?
6053 offset_array[ii + 1] :
6054 p_buffer_hdr->nFilledLen);
6055 }
6056 else
6057 {
6058 p_buffer_swvdec->offset = offset_array[ii];
6059 p_buffer_swvdec->filled_length =
6060 p_buffer_hdr->nFilledLen - offset_array[ii];
6061 }
6062
6063 m_diag.dump_ip(p_buffer_swvdec->p_buffer +
6064 p_buffer_swvdec->offset,
6065 p_buffer_swvdec->filled_length);
6066
6067 retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
6068 p_buffer_swvdec);
6069
6070 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6071 {
6072 retval = retval_swvdec2omx(retval_swvdec);
6073 break;
6074 }
6075 }
6076 }
6077 else
6078 {
6079 OMX_SWVDEC_LOG_HIGH("No frame detected for Buffer %p, with TS %lld",
6080 p_buffer_hdr->pBuffer, p_buffer_hdr->nTimeStamp );
6081
6082 p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
6083 p_buffer_swvdec->offset = 0;
6084 p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
6085 p_buffer_swvdec->filled_length = p_buffer_hdr->nFilledLen;
6086
6087 m_diag.dump_ip(p_buffer_swvdec->p_buffer + p_buffer_swvdec->offset,
6088 p_buffer_swvdec->filled_length);
6089
6090 retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
6091 p_buffer_swvdec);
6092
6093 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6094 {
6095 retval = retval_swvdec2omx(retval_swvdec);
6096 }
6097 }
6098 }
6099 else
6100 {
6101 p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
6102 p_buffer_swvdec->offset = 0;
6103 p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
6104 p_buffer_swvdec->filled_length = p_buffer_hdr->nFilledLen;
6105
6106 m_diag.dump_ip(p_buffer_swvdec->p_buffer + p_buffer_swvdec->offset,
6107 p_buffer_swvdec->filled_length);
6108
6109 retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
6110 p_buffer_swvdec);
6111
6112 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6113 {
6114 retval = retval_swvdec2omx(retval_swvdec);
6115 }
6116 }
6117 }
6118 return retval;
6119 }
6120
6121 /**
6122 * @brief Process FTB event.
6123 *
6124 * @param[in] p_buffer_hdr: Pointer to buffer header.
6125 * @param[in] index: Index of buffer in output buffer info array.
6126 *
6127 * @retval OMX_ERRORTYPE
6128 */
async_process_event_ftb(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)6129 OMX_ERRORTYPE omx_swvdec::async_process_event_ftb(
6130 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
6131 unsigned int index)
6132 {
6133 OMX_ERRORTYPE retval = OMX_ErrorNone;
6134
6135 m_port_op.num_pending_buffers++;
6136
6137 if (m_port_op.flush_inprogress)
6138 {
6139 OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p; "
6140 "op port flush in progress",
6141 p_buffer_hdr,
6142 m_buffer_array_op[index].buffer_swvdec.p_buffer);
6143
6144 async_post_event(OMX_SWVDEC_EVENT_FBD,
6145 (unsigned long) p_buffer_hdr,
6146 (unsigned long) index);
6147 }
6148 else
6149 {
6150 SWVDEC_STATUS retval_swvdec;
6151
6152 SWVDEC_BUFFER *p_buffer_swvdec =
6153 &(m_buffer_array_op[index].buffer_swvdec);
6154 p_buffer_swvdec->fd = m_buffer_array_op[index].buffer_payload.pmem_fd;
6155 retval_swvdec = swvdec_fillthisbuffer(m_swvdec_handle, p_buffer_swvdec);
6156
6157 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6158 {
6159 retval = retval_swvdec2omx(retval_swvdec);
6160 }
6161 }
6162
6163 return retval;
6164 }
6165
6166 /**
6167 * @brief Process EBD event.
6168 *
6169 * @param[in] p_buffer_hdr: Pointer to buffer header.
6170 * @param[in] index: Index of buffer in output buffer info array.
6171 *
6172 * @retval OMX_ERRORTYPE
6173 */
async_process_event_ebd(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)6174 OMX_ERRORTYPE omx_swvdec::async_process_event_ebd(
6175 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
6176 unsigned int index)
6177 {
6178 OMX_ERRORTYPE retval = OMX_ErrorNone;
6179
6180 if (index < m_port_ip.def.nBufferCountActual)
6181 {
6182 if (m_arbitrary_bytes_mode && m_buffer_array_ip[index].split_count)
6183 {
6184 m_buffer_array_ip[index].split_count--;
6185 }
6186 else
6187 {
6188 m_port_ip.num_pending_buffers--;
6189
6190 OMX_SWVDEC_LOG_CALLBACK(
6191 "EmptyBufferDone(): %p, buffer %p",
6192 p_buffer_hdr,
6193 m_buffer_array_ip[index].buffer_swvdec.p_buffer);
6194
6195 m_callback.EmptyBufferDone(&m_cmp, m_app_data, p_buffer_hdr);
6196 }
6197 }
6198 else
6199 {
6200 OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
6201
6202 retval = OMX_ErrorBadParameter;
6203 }
6204
6205 return retval;
6206 }
6207
6208 /**
6209 * @brief Process FBD event.
6210 *
6211 * @param[in] p_buffer_hdr: Pointer to buffer header.
6212 * @param[in] index: Index of buffer in output buffer info array.
6213 *
6214 * @retval OMX_ERRORTYPE
6215 */
async_process_event_fbd(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)6216 OMX_ERRORTYPE omx_swvdec::async_process_event_fbd(
6217 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
6218 unsigned int index)
6219 {
6220 OMX_ERRORTYPE retval = OMX_ErrorNone;
6221
6222 static long long timestamp_prev = 0;
6223
6224 if (index < m_port_op.def.nBufferCountActual)
6225 {
6226 OMX_U8 *p_buffer;
6227
6228 p_buffer = m_buffer_array_op[index].buffer_swvdec.p_buffer;
6229
6230 m_port_op.num_pending_buffers--;
6231
6232 if (m_port_op.flush_inprogress)
6233 {
6234 p_buffer_hdr->nFilledLen = 0;
6235 p_buffer_hdr->nTimeStamp = 0;
6236 p_buffer_hdr->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6237 }
6238
6239 if (p_buffer_hdr->nFilledLen)
6240 {
6241 if (m_sync_frame_decoding_mode)
6242 {
6243 OMX_SWVDEC_LOG_LOW("sync frame decoding mode; "
6244 "setting timestamp to zero");
6245
6246 p_buffer_hdr->nTimeStamp = 0;
6247 }
6248 else
6249 {
6250 if (m_queue_timestamp.empty())
6251 {
6252 OMX_SWVDEC_LOG_ERROR("timestamp queue empty; "
6253 "re-using previous timestamp %lld",
6254 timestamp_prev);
6255
6256 p_buffer_hdr->nTimeStamp = timestamp_prev;
6257 }
6258 else
6259 {
6260 p_buffer_hdr->nTimeStamp = m_queue_timestamp.top();
6261
6262 m_queue_timestamp.pop();
6263
6264 timestamp_prev = p_buffer_hdr->nTimeStamp;
6265 }
6266 }
6267
6268 ion_flush_op(index);
6269
6270 if (m_meta_buffer_mode)
6271 {
6272 pthread_mutex_lock(&m_meta_buffer_array_mutex);
6273 }
6274
6275 m_diag.dump_op(p_buffer,
6276 m_frame_dimensions.width,
6277 m_frame_dimensions.height,
6278 m_frame_attributes.stride,
6279 m_frame_attributes.scanlines);
6280
6281 if (m_meta_buffer_mode)
6282 {
6283 pthread_mutex_unlock(&m_meta_buffer_array_mutex);
6284 }
6285 }
6286 else
6287 {
6288 OMX_SWVDEC_LOG_LOW("filled length zero; "
6289 "setting timestamp to zero");
6290
6291 p_buffer_hdr->nTimeStamp = 0;
6292 }
6293
6294 if (p_buffer_hdr->nFlags & OMX_BUFFERFLAG_EOS)
6295 {
6296 async_post_event(OMX_SWVDEC_EVENT_EOS, 0, 0);
6297
6298 OMX_SWVDEC_LOG_LOW("flushing %zu elements in timestamp queue",
6299 m_queue_timestamp.size());
6300
6301 while (m_queue_timestamp.empty() == false)
6302 {
6303 m_queue_timestamp.pop();
6304 }
6305 }
6306
6307 if (m_meta_buffer_mode &&
6308 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_READONLY)) == 0)
6309 {
6310 meta_buffer_ref_remove(index);
6311 }
6312
6313 OMX_SWVDEC_LOG_CALLBACK(
6314 "FillBufferDone(): %p, buffer %p, "
6315 "flags 0x%08x, filled length %d, timestamp %lld",
6316 p_buffer_hdr,
6317 p_buffer,
6318 p_buffer_hdr->nFlags,
6319 p_buffer_hdr->nFilledLen,
6320 p_buffer_hdr->nTimeStamp);
6321
6322 m_callback.FillBufferDone(&m_cmp, m_app_data, p_buffer_hdr);
6323 }
6324 else
6325 {
6326 OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
6327
6328 retval = OMX_ErrorBadParameter;
6329 }
6330
6331 return retval;
6332 }
6333
6334 /**
6335 * @brief Process EOS event.
6336 *
6337 * @retval OMX_ErrorNone
6338 */
async_process_event_eos()6339 OMX_ERRORTYPE omx_swvdec::async_process_event_eos()
6340 {
6341 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
6342 "OMX_EventBufferFlag, port index %d, EOS",
6343 OMX_CORE_PORT_INDEX_OP);
6344
6345 m_callback.EventHandler(&m_cmp,
6346 m_app_data,
6347 OMX_EventBufferFlag,
6348 OMX_CORE_PORT_INDEX_OP,
6349 OMX_BUFFERFLAG_EOS,
6350 NULL);
6351
6352 return OMX_ErrorNone;
6353 }
6354
6355 /**
6356 * @brief Process input port flush event.
6357 *
6358 * @retval OMX_ERRORTYPE
6359 */
async_process_event_flush_port_ip()6360 OMX_ERRORTYPE omx_swvdec::async_process_event_flush_port_ip()
6361 {
6362 OMX_ERRORTYPE retval = OMX_ErrorNone;
6363
6364 OMX_SWVDEC_EVENT_INFO event_info;
6365
6366 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
6367
6368 unsigned int index;
6369
6370 while (m_queue_port_ip.pop(&event_info))
6371 {
6372 switch (event_info.event_id)
6373 {
6374
6375 case OMX_SWVDEC_EVENT_ETB:
6376 {
6377 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6378
6379 index = event_info.event_param2;
6380
6381 // compensate decrement in async_process_event_ebd()
6382 m_port_ip.num_pending_buffers++;
6383
6384 retval = async_process_event_ebd(p_buffer_hdr, index);
6385 break;
6386 }
6387
6388 case OMX_SWVDEC_EVENT_EBD:
6389 {
6390 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6391
6392 index = event_info.event_param2;
6393
6394 retval = async_process_event_ebd(p_buffer_hdr, index);
6395 break;
6396 }
6397
6398 default:
6399 {
6400 assert(0);
6401 break;
6402 }
6403
6404 }
6405 }
6406
6407 assert(m_port_ip.num_pending_buffers == 0);
6408
6409 if ((retval == OMX_ErrorNone) &&
6410 (m_status_flags & (1 << PENDING_PORT_FLUSH_IP)))
6411 {
6412 m_status_flags &= ~(1 << PENDING_PORT_FLUSH_IP);
6413
6414 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
6415 OMX_CommandFlush,
6416 OMX_CORE_PORT_INDEX_IP);
6417 }
6418
6419 m_port_ip.flush_inprogress = OMX_FALSE;
6420
6421 return retval;
6422 }
6423
6424 /**
6425 * @brief Process output port flush event.
6426 *
6427 * @retval OMX_ERRORTYPE
6428 */
async_process_event_flush_port_op()6429 OMX_ERRORTYPE omx_swvdec::async_process_event_flush_port_op()
6430 {
6431 OMX_ERRORTYPE retval = OMX_ErrorNone;
6432
6433 OMX_SWVDEC_EVENT_INFO event_info;
6434
6435 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
6436
6437 unsigned int index;
6438
6439 while (m_queue_port_op.pop(&event_info))
6440 {
6441 switch (event_info.event_id)
6442 {
6443
6444 case OMX_SWVDEC_EVENT_FTB:
6445 {
6446 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6447
6448 index = event_info.event_param2;
6449
6450 // compensate decrement in async_process_event_fbd()
6451 m_port_op.num_pending_buffers++;
6452
6453 retval = async_process_event_fbd(p_buffer_hdr, index);
6454 break;
6455 }
6456
6457 case OMX_SWVDEC_EVENT_FBD:
6458 {
6459 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6460
6461 index = event_info.event_param2;
6462
6463 retval = async_process_event_fbd(p_buffer_hdr, index);
6464 break;
6465 }
6466
6467 default:
6468 {
6469 assert(0);
6470 break;
6471 }
6472
6473 }
6474 }
6475
6476 assert(m_port_op.num_pending_buffers == 0);
6477
6478 if ((retval == OMX_ErrorNone) &&
6479 (m_status_flags & (1 << PENDING_PORT_FLUSH_OP)))
6480 {
6481 m_status_flags &= ~(1 << PENDING_PORT_FLUSH_OP);
6482
6483 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
6484 OMX_CommandFlush,
6485 OMX_CORE_PORT_INDEX_OP);
6486 }
6487
6488 if ((retval == OMX_ErrorNone) &&
6489 (m_status_flags & (1 << PENDING_STATE_EXECUTING_TO_IDLE)))
6490 {
6491 m_status_flags &= ~(1 << PENDING_STATE_EXECUTING_TO_IDLE);
6492
6493 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
6494 OMX_CommandStateSet,
6495 OMX_StateIdle);
6496 }
6497
6498 if (m_port_reconfig_inprogress == false)
6499 {
6500 OMX_SWVDEC_LOG_LOW("flushing %zu elements in timestamp queue",
6501 m_queue_timestamp.size());
6502
6503 while (m_queue_timestamp.empty() == false)
6504 {
6505 m_queue_timestamp.pop();
6506 }
6507 }
6508
6509 m_port_op.flush_inprogress = OMX_FALSE;
6510
6511 return retval;
6512 }
6513
6514 /**
6515 * @brief Process port reconfiguration event.
6516 *
6517 * @retval OMX_ERRORTYPE
6518 */
async_process_event_port_reconfig()6519 OMX_ERRORTYPE omx_swvdec::async_process_event_port_reconfig()
6520 {
6521 OMX_ERRORTYPE retval = OMX_ErrorNone;
6522
6523 if (m_port_reconfig_inprogress)
6524 {
6525 OMX_SWVDEC_LOG_ERROR("port reconfiguration already in progress");
6526
6527 retval = OMX_ErrorIncorrectStateOperation;
6528 }
6529 else
6530 {
6531 m_port_reconfig_inprogress = true;
6532
6533 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
6534 "OMX_EventPortSettingsChanged, port index %d",
6535 OMX_CORE_PORT_INDEX_OP);
6536
6537 m_callback.EventHandler(&m_cmp,
6538 m_app_data,
6539 OMX_EventPortSettingsChanged,
6540 OMX_CORE_PORT_INDEX_OP,
6541 0,
6542 NULL);
6543 }
6544
6545 return retval;
6546 }
6547
6548 /**
6549 * @brief Process dimensions updated event.
6550 *
6551 * @retval OMX_ERRORTYPE
6552 */
async_process_event_dimensions_updated()6553 OMX_ERRORTYPE omx_swvdec::async_process_event_dimensions_updated()
6554 {
6555 OMX_ERRORTYPE retval = OMX_ErrorNone;
6556
6557 if (m_dimensions_update_inprogress)
6558 {
6559 OMX_SWVDEC_LOG_ERROR("dimensions update already in progress");
6560
6561 retval = OMX_ErrorIncorrectStateOperation;
6562 }
6563 else
6564 {
6565 m_dimensions_update_inprogress = true;
6566
6567 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
6568 "OMX_EventPortSettingsChanged, port index %d, "
6569 "OMX_IndexConfigCommonOutputCrop",
6570 OMX_CORE_PORT_INDEX_OP);
6571
6572 m_callback.EventHandler(&m_cmp,
6573 m_app_data,
6574 OMX_EventPortSettingsChanged,
6575 OMX_CORE_PORT_INDEX_OP,
6576 OMX_IndexConfigCommonOutputCrop,
6577 NULL);
6578 }
6579
6580 return retval;
6581 }
6582