1 /**
2 * @copyright
3 *
4 * Copyright (c) 2015-2020, 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.vc1sw",
196 OMX_MAX_STRINGNAME_SIZE)))||
197 ((!strncmp(cmp_name,
198 "OMX.qti.video.decoder.wmvsw",
199 OMX_MAX_STRINGNAME_SIZE))))
200 {
201 char platform_name[PROP_VALUE_MAX] = {0};
202 char version[PROP_VALUE_MAX] = {0};
203 property_get("ro.board.platform", platform_name, "0"); //HW ID
204 if (!strcmp(platform_name, "sm6150"))
205 {
206 if (property_get("vendor.media.target.version", version, "0") &&
207 (atoi(version) == 0))
208 {
209 //Sku version, VC1 is disabled on this target
210 OMX_SWVDEC_LOG_ERROR("VC1 decoder not supported on this target");
211 retval = OMX_ErrorInvalidComponentName;
212 goto component_init_exit;
213 }
214 }
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 && !(m_status_flags & (1 << PENDING_STATE_LOADED_TO_IDLE)))
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 = ion_map(p_private_handle->fd,p_private_handle->size);
2221
2222 if (bufferaddr == MAP_FAILED)
2223 {
2224 OMX_SWVDEC_LOG_ERROR("mmap() failed for "
2225 "fd %d of size %d",
2226 p_private_handle->fd,
2227 p_private_handle->size);
2228
2229 pthread_mutex_unlock(&m_meta_buffer_array_mutex);
2230
2231 retval = OMX_ErrorInsufficientResources;
2232 goto fill_this_buffer_exit;
2233 }
2234
2235 p_buffer_payload->bufferaddr = bufferaddr;
2236 p_buffer_payload->pmem_fd = p_private_handle->fd;
2237 p_buffer_payload->buffer_len = p_private_handle->size;
2238 p_buffer_payload->mmaped_size = p_private_handle->size;
2239
2240 p_buffer_swvdec->p_buffer = bufferaddr;
2241 p_buffer_swvdec->size = p_private_handle->size;
2242 p_buffer_swvdec->p_client_data = (void *) ((unsigned long) ii);
2243 }
2244
2245 meta_buffer_ref_add(ii, p_buffer_payload->pmem_fd);
2246
2247 pthread_mutex_unlock(&m_meta_buffer_array_mutex);
2248 }
2249
2250 OMX_SWVDEC_LOG_LOW("%p: buffer %p",
2251 p_buffer_hdr,
2252 p_buffer_swvdec->p_buffer);
2253
2254 async_post_event(OMX_SWVDEC_EVENT_FTB,
2255 (unsigned long) p_buffer_hdr,
2256 (unsigned long) ii);
2257
2258 fill_this_buffer_exit:
2259 return retval;
2260 }
2261
2262 /**
2263 * @brief Set component's callback structure.
2264 *
2265 * @param[in] cmp_handle: Component handle.
2266 * @param[in] p_callbacks: Pointer to callback structure.
2267 * @param[in] p_app_data: Pointer to IL client app data.
2268 *
2269 * @retval OMX_ERRORTYPE
2270 */
set_callbacks(OMX_HANDLETYPE cmp_handle,OMX_CALLBACKTYPE * p_callbacks,OMX_PTR p_app_data)2271 OMX_ERRORTYPE omx_swvdec::set_callbacks(OMX_HANDLETYPE cmp_handle,
2272 OMX_CALLBACKTYPE *p_callbacks,
2273 OMX_PTR p_app_data)
2274 {
2275 OMX_ERRORTYPE retval = OMX_ErrorNone;
2276
2277 OMX_SWVDEC_LOG_API("");
2278
2279 if (m_state == OMX_StateInvalid)
2280 {
2281 OMX_SWVDEC_LOG_ERROR("in invalid state");
2282
2283 retval = OMX_ErrorInvalidState;
2284 }
2285 else if (cmp_handle == NULL)
2286 {
2287 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
2288
2289 retval = OMX_ErrorInvalidComponent;
2290 }
2291 else if (p_callbacks->EventHandler == NULL)
2292 {
2293 OMX_SWVDEC_LOG_ERROR("p_callbacks->EventHandler = NULL");
2294
2295 retval = OMX_ErrorBadParameter;
2296 }
2297 else if (p_callbacks->EmptyBufferDone == NULL)
2298 {
2299 OMX_SWVDEC_LOG_ERROR("p_callbacks->EmptyBufferDone = NULL");
2300
2301 retval = OMX_ErrorBadParameter;
2302 }
2303 else if (p_callbacks->FillBufferDone == NULL)
2304 {
2305 OMX_SWVDEC_LOG_ERROR("p_callbacks->FillBufferDone = NULL");
2306
2307 retval = OMX_ErrorBadParameter;
2308 }
2309 else
2310 {
2311 m_callback = *p_callbacks;
2312 m_app_data = p_app_data;
2313 }
2314
2315 return retval;
2316 }
2317
2318 /**
2319 * @brief Use EGL image.
2320 *
2321 * @retval OMX_ErrorNotImplemented
2322 */
use_EGL_image(OMX_HANDLETYPE cmp_handle,OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_U32 port,OMX_PTR p_app_data,void * egl_image)2323 OMX_ERRORTYPE omx_swvdec::use_EGL_image(OMX_HANDLETYPE cmp_handle,
2324 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
2325 OMX_U32 port,
2326 OMX_PTR p_app_data,
2327 void *egl_image)
2328 {
2329 (void) cmp_handle;
2330 (void) pp_buffer_hdr;
2331 (void) port;
2332 (void) p_app_data;
2333 (void) egl_image;
2334
2335 OMX_SWVDEC_LOG_API("");
2336
2337 OMX_SWVDEC_LOG_ERROR("not implemented");
2338
2339 return OMX_ErrorNotImplemented;
2340 }
2341
2342 /**
2343 * @brief Enumerate component role.
2344 *
2345 * @param[in] cmp_handle: Component handle.
2346 * @param[in,out] p_role: Pointer to component role string.
2347 * @param[in] index: Role index being queried.
2348 *
2349 * @retval OMX_ERRORTYPE
2350 */
component_role_enum(OMX_HANDLETYPE cmp_handle,OMX_U8 * p_role,OMX_U32 index)2351 OMX_ERRORTYPE omx_swvdec::component_role_enum(OMX_HANDLETYPE cmp_handle,
2352 OMX_U8 *p_role,
2353 OMX_U32 index)
2354 {
2355 OMX_ERRORTYPE retval = OMX_ErrorNone;
2356
2357 if (m_state == OMX_StateInvalid)
2358 {
2359 OMX_SWVDEC_LOG_ERROR("in invalid state");
2360
2361 retval = OMX_ErrorInvalidState;
2362 }
2363 else if (cmp_handle == NULL)
2364 {
2365 OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
2366
2367 retval = OMX_ErrorInvalidComponent;
2368 }
2369 else if (index > 0)
2370 {
2371 OMX_SWVDEC_LOG_HIGH("index '%d' unsupported; no more roles", index);
2372
2373 retval = OMX_ErrorNoMore;
2374 }
2375 else
2376 {
2377 memcpy(p_role, m_role_name, OMX_MAX_STRINGNAME_SIZE);
2378
2379 OMX_SWVDEC_LOG_API("index '%d': '%s'", index, p_role);
2380 }
2381
2382 return retval;
2383 }
2384
2385 /**
2386 * -------------------------
2387 * SwVdec callback functions
2388 * -------------------------
2389 */
2390
2391 /**
2392 * @brief SwVdec empty buffer done callback.
2393 *
2394 * @param[in] swvdec_handle: SwVdec handle.
2395 * @param[in] p_buffer_ip: Pointer to input buffer structure.
2396 * @param[in] p_client_handle: Pointer to SwVdec's client handle.
2397 *
2398 * @retval SWVDEC_STATUS_SUCCESS
2399 * @retval SWVDEC_STATUS_NULL_POINTER
2400 * @retval SWVDEC_STATUS_INVALID_PARAMETERS
2401 */
swvdec_empty_buffer_done_callback(SWVDEC_HANDLE swvdec_handle,SWVDEC_BUFFER * p_buffer_ip,void * p_client_handle)2402 SWVDEC_STATUS omx_swvdec::swvdec_empty_buffer_done_callback(
2403 SWVDEC_HANDLE swvdec_handle,
2404 SWVDEC_BUFFER *p_buffer_ip,
2405 void *p_client_handle)
2406 {
2407 SWVDEC_STATUS retval = SWVDEC_STATUS_SUCCESS;
2408
2409 if (p_buffer_ip == NULL)
2410 {
2411 OMX_SWVDEC_LOG_ERROR("p_buffer_ip = NULL");
2412
2413 retval = SWVDEC_STATUS_NULL_POINTER;
2414 }
2415 else if (p_client_handle == NULL)
2416 {
2417 OMX_SWVDEC_LOG_ERROR("p_client_handle = NULL");
2418
2419 retval = SWVDEC_STATUS_NULL_POINTER;
2420 }
2421 else
2422 {
2423 omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_client_handle;
2424
2425 if (swvdec_handle != p_omx_swvdec->m_swvdec_handle)
2426 {
2427 OMX_SWVDEC_LOG_ERROR("invalid SwVdec handle");
2428
2429 retval = SWVDEC_STATUS_INVALID_PARAMETERS;
2430 }
2431 else
2432 {
2433 p_omx_swvdec->swvdec_empty_buffer_done(p_buffer_ip);
2434 }
2435 }
2436
2437 return retval;
2438 }
2439
2440 /**
2441 * @brief SwVdec fill buffer done callback.
2442 *
2443 * @param[in] swvdec_handle: SwVdec handle.
2444 * @param[in] p_buffer_op: Pointer to output buffer structure.
2445 * @param[in] p_client_handle: Pointer to SwVdec's client handle.
2446 *
2447 * @retval SWVDEC_STATUS_SUCCESS
2448 * @retval SWVDEC_STATUS_NULL_POINTER
2449 * @retval SWVDEC_STATUS_INVALID_PARAMETERS
2450 */
swvdec_fill_buffer_done_callback(SWVDEC_HANDLE swvdec_handle,SWVDEC_BUFFER * p_buffer_op,void * p_client_handle)2451 SWVDEC_STATUS omx_swvdec::swvdec_fill_buffer_done_callback(
2452 SWVDEC_HANDLE swvdec_handle,
2453 SWVDEC_BUFFER *p_buffer_op,
2454 void *p_client_handle)
2455 {
2456 SWVDEC_STATUS retval = SWVDEC_STATUS_SUCCESS;
2457
2458 if (p_buffer_op == NULL)
2459 {
2460 OMX_SWVDEC_LOG_ERROR("p_buffer_op = NULL");
2461
2462 retval = SWVDEC_STATUS_NULL_POINTER;
2463 }
2464 else if (p_client_handle == NULL)
2465 {
2466 OMX_SWVDEC_LOG_ERROR("p_client_handle = NULL");
2467
2468 retval = SWVDEC_STATUS_NULL_POINTER;
2469 }
2470 else
2471 {
2472 omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_client_handle;
2473
2474 if (swvdec_handle != p_omx_swvdec->m_swvdec_handle)
2475 {
2476 OMX_SWVDEC_LOG_ERROR("invalid SwVdec handle");
2477
2478 retval = SWVDEC_STATUS_INVALID_PARAMETERS;
2479 }
2480 else
2481 {
2482 p_omx_swvdec->swvdec_fill_buffer_done(p_buffer_op);
2483 }
2484 }
2485
2486 return retval;
2487 }
2488
2489 /**
2490 * @brief SwVdec event handler callback.
2491 *
2492 * @param[in] swvdec_handle: SwVdec handle.
2493 * @param[in] event: Event.
2494 * @param[in] p_data: Pointer to event-specific data.
2495 * @param[in] p_client_handle: Pointer to SwVdec's client handle.
2496 *
2497 * @retval SWVDEC_STATUS_SUCCESS
2498 * @retval SWVDEC_STATUS_NULL_POINTER
2499 * @retval SWVDEC_STATUS_INVALID_PARAMETERS
2500 */
swvdec_event_handler_callback(SWVDEC_HANDLE swvdec_handle,SWVDEC_EVENT event,void * p_data,void * p_client_handle)2501 SWVDEC_STATUS omx_swvdec::swvdec_event_handler_callback(
2502 SWVDEC_HANDLE swvdec_handle,
2503 SWVDEC_EVENT event,
2504 void *p_data,
2505 void *p_client_handle)
2506 {
2507 SWVDEC_STATUS retval = SWVDEC_STATUS_SUCCESS;
2508
2509 if ((event == SWVDEC_EVENT_RELEASE_REFERENCE) && (p_data == NULL))
2510 {
2511 OMX_SWVDEC_LOG_ERROR("p_data = NULL");
2512
2513 retval = SWVDEC_STATUS_NULL_POINTER;
2514 }
2515 else if (p_client_handle == NULL)
2516 {
2517 OMX_SWVDEC_LOG_ERROR("p_client_handle = NULL");
2518
2519 retval = SWVDEC_STATUS_NULL_POINTER;
2520 }
2521 else
2522 {
2523 omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_client_handle;
2524
2525 if (swvdec_handle != p_omx_swvdec->m_swvdec_handle)
2526 {
2527 OMX_SWVDEC_LOG_ERROR("invalid SwVdec handle");
2528
2529 retval = SWVDEC_STATUS_INVALID_PARAMETERS;
2530 }
2531 else
2532 {
2533 p_omx_swvdec->swvdec_event_handler(event, p_data);
2534 }
2535 }
2536
2537 return retval;
2538 }
2539
2540 /**
2541 * -----------------
2542 * PRIVATE FUNCTIONS
2543 * -----------------
2544 */
2545
2546 /**
2547 * @brief Set frame dimensions for OMX component & SwVdec core.
2548 *
2549 * @param[in] width: Frame width.
2550 * @param[in] height: Frame height.
2551 *
2552 * @retval OMX_ERRORTYPE
2553 */
set_frame_dimensions(unsigned int width,unsigned int height)2554 OMX_ERRORTYPE omx_swvdec::set_frame_dimensions(unsigned int width,
2555 unsigned int height)
2556 {
2557 OMX_ERRORTYPE retval;
2558
2559 m_frame_dimensions.width = width;
2560 m_frame_dimensions.height = height;
2561
2562 OMX_SWVDEC_LOG_HIGH("%d x %d",
2563 m_frame_dimensions.width,
2564 m_frame_dimensions.height);
2565
2566 retval = set_frame_dimensions_swvdec();
2567
2568 return retval;
2569 }
2570
2571 /**
2572 * @brief Set frame attributes for OMX component & SwVdec core, based on
2573 * frame dimensions & color format.
2574 *
2575 * @param[in] color_format: Color format.
2576 *
2577 * @retval OMX_ERRORTYPE
2578 */
set_frame_attributes(OMX_COLOR_FORMATTYPE color_format)2579 OMX_ERRORTYPE omx_swvdec::set_frame_attributes(
2580 OMX_COLOR_FORMATTYPE color_format)
2581 {
2582 OMX_ERRORTYPE retval = OMX_ErrorNone;
2583
2584 unsigned int width = m_frame_dimensions.width;
2585 unsigned int height = m_frame_dimensions.height;
2586
2587 unsigned int scanlines_uv;
2588
2589 unsigned int plane_size_y;
2590 unsigned int plane_size_uv;
2591
2592 switch (color_format)
2593 {
2594
2595 case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m:
2596 {
2597 /**
2598 * alignment factors:
2599 *
2600 * - stride: 128
2601 * - scanlines_y: 32
2602 * - scanlines_uv: 16
2603 * - size: 4096
2604 */
2605
2606 m_frame_attributes.stride = ALIGN(width, 128);
2607 m_frame_attributes.scanlines = ALIGN(height, 32);
2608
2609 scanlines_uv = ALIGN(height / 2, 16);
2610
2611 plane_size_y = (m_frame_attributes.stride *
2612 m_frame_attributes.scanlines);
2613
2614 plane_size_uv = m_frame_attributes.stride * scanlines_uv;
2615
2616 m_frame_attributes.size = ALIGN(plane_size_y + plane_size_uv, 4096);
2617
2618 OMX_SWVDEC_LOG_HIGH("'OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m': "
2619 "stride %d, scanlines %d, size %d",
2620 m_frame_attributes.stride,
2621 m_frame_attributes.scanlines,
2622 m_frame_attributes.size);
2623
2624 break;
2625 }
2626
2627 case OMX_COLOR_FormatYUV420SemiPlanar:
2628 {
2629 /**
2630 * alignment factors:
2631 *
2632 * - stride: 16
2633 * - scanlines_y: 16
2634 * - scanlines_uv: 16
2635 * - size: 4096
2636 */
2637
2638 m_frame_attributes.stride = ALIGN(width, 16);
2639 m_frame_attributes.scanlines = ALIGN(height, 16);
2640
2641 scanlines_uv = ALIGN(height / 2, 16);
2642
2643 plane_size_y = (m_frame_attributes.stride *
2644 m_frame_attributes.scanlines);
2645
2646 plane_size_uv = m_frame_attributes.stride * scanlines_uv;
2647
2648 m_frame_attributes.size = ALIGN(plane_size_y + plane_size_uv, 4096);
2649
2650 OMX_SWVDEC_LOG_HIGH("'OMX_COLOR_FormatYUV420SemiPlanar': "
2651 "stride %d, scanlines %d, size %d",
2652 m_frame_attributes.stride,
2653 m_frame_attributes.scanlines,
2654 m_frame_attributes.size);
2655
2656 break;
2657 }
2658
2659 default:
2660 {
2661 OMX_SWVDEC_LOG_ERROR("'0x%08x' color format invalid or unsupported",
2662 color_format);
2663
2664 retval = OMX_ErrorBadParameter;
2665 break;
2666 }
2667
2668 } // switch (color_format)
2669
2670 if (retval == OMX_ErrorNone)
2671 {
2672 m_omx_color_formattype = color_format;
2673
2674 retval = set_frame_attributes_swvdec();
2675 }
2676
2677 return retval;
2678 }
2679
2680 /**
2681 * @brief Set maximum adaptive playback frame dimensions for OMX component &
2682 * SwVdec core.
2683 *
2684 * @param[in] width: Max adaptive playback frame width.
2685 * @param[in] height: Max adaptive playback frame height.
2686 *
2687 * @retval OMX_ERRORTYPE
2688 */
set_adaptive_playback(unsigned int max_width,unsigned int max_height)2689 OMX_ERRORTYPE omx_swvdec::set_adaptive_playback(unsigned int max_width,
2690 unsigned int max_height)
2691 {
2692 OMX_ERRORTYPE retval;
2693
2694 m_frame_dimensions_max.width = max_width;
2695 m_frame_dimensions_max.height = max_height;
2696
2697 OMX_SWVDEC_LOG_HIGH("%d x %d",
2698 m_frame_dimensions_max.width,
2699 m_frame_dimensions_max.height);
2700
2701 retval = set_adaptive_playback_swvdec();
2702
2703 if (retval == OMX_ErrorNone)
2704 {
2705 retval = set_frame_dimensions(max_width, max_height);
2706 }
2707
2708 if (retval == OMX_ErrorNone)
2709 {
2710 retval = set_frame_attributes(m_omx_color_formattype);
2711 }
2712
2713 return retval;
2714 }
2715
2716 /**
2717 * @brief Get video port format for input or output port.
2718 *
2719 * @param[in,out] p_port_format: Pointer to video port format type.
2720 *
2721 * @retval OMX_ERRORTYPE
2722 */
get_video_port_format(OMX_VIDEO_PARAM_PORTFORMATTYPE * p_port_format)2723 OMX_ERRORTYPE omx_swvdec::get_video_port_format(
2724 OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format)
2725 {
2726 OMX_ERRORTYPE retval = OMX_ErrorNone;
2727
2728 if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_IP)
2729 {
2730 if (p_port_format->nIndex == 0)
2731 {
2732 p_port_format->eColorFormat = OMX_COLOR_FormatUnused;
2733
2734 p_port_format->eCompressionFormat = m_omx_video_codingtype;
2735
2736 OMX_SWVDEC_LOG_HIGH("color format 0x%08x, "
2737 "compression format 0x%08x",
2738 p_port_format->eColorFormat,
2739 p_port_format->eCompressionFormat);
2740 }
2741 else
2742 {
2743 OMX_SWVDEC_LOG_HIGH("index '%d' unsupported; "
2744 "no more compression formats",
2745 p_port_format->nIndex);
2746
2747 retval = OMX_ErrorNoMore;
2748 }
2749 }
2750 else if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_OP)
2751 {
2752 if (p_port_format->nIndex == 0)
2753 {
2754 p_port_format->eColorFormat =
2755 OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m;
2756
2757 p_port_format->eCompressionFormat = OMX_VIDEO_CodingUnused;
2758
2759 OMX_SWVDEC_LOG_HIGH("color format 0x%08x, "
2760 "compression format 0x%08x",
2761 p_port_format->eColorFormat,
2762 p_port_format->eCompressionFormat);
2763 }
2764 else if (p_port_format->nIndex == 1)
2765 {
2766 p_port_format->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2767
2768 p_port_format->eCompressionFormat = OMX_VIDEO_CodingUnused;
2769
2770 OMX_SWVDEC_LOG_HIGH("color format 0x%08x, "
2771 "compression format 0x%08x",
2772 p_port_format->eColorFormat,
2773 p_port_format->eCompressionFormat);
2774 }
2775 else
2776 {
2777 OMX_SWVDEC_LOG_HIGH("index '%d' unsupported; no more color formats",
2778 p_port_format->nIndex);
2779
2780 retval = OMX_ErrorNoMore;
2781 }
2782 }
2783 else
2784 {
2785 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
2786 p_port_format->nPortIndex);
2787
2788 retval = OMX_ErrorBadPortIndex;
2789 }
2790
2791 return retval;
2792 }
2793
2794 /**
2795 * @brief Set video port format for input or output port.
2796 *
2797 * @param[in] p_port_format: Pointer to video port format type.
2798 *
2799 * @retval OMX_ERRORTYPE
2800 */
set_video_port_format(OMX_VIDEO_PARAM_PORTFORMATTYPE * p_port_format)2801 OMX_ERRORTYPE omx_swvdec::set_video_port_format(
2802 OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format)
2803 {
2804 OMX_ERRORTYPE retval = OMX_ErrorNone;
2805
2806 if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_IP)
2807 {
2808 OMX_SWVDEC_LOG_HIGH("OMX_IndexParamVideoPortFormat, port index 0; "
2809 "doing nothing");
2810 }
2811 else if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_OP)
2812 {
2813 retval = set_frame_attributes(p_port_format->eColorFormat);
2814 }
2815 else
2816 {
2817 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
2818 p_port_format->nPortIndex);
2819
2820 retval = OMX_ErrorBadPortIndex;
2821 }
2822
2823 return retval;
2824 }
2825
2826 /**
2827 * @brief Get port definition for input or output port.
2828 *
2829 * @param[in,out] p_port_def: Pointer to port definition type.
2830 *
2831 * @retval OMX_ERRORTYPE
2832 */
get_port_definition(OMX_PARAM_PORTDEFINITIONTYPE * p_port_def)2833 OMX_ERRORTYPE omx_swvdec::get_port_definition(
2834 OMX_PARAM_PORTDEFINITIONTYPE *p_port_def)
2835 {
2836 OMX_ERRORTYPE retval = OMX_ErrorNone;
2837
2838 p_port_def->eDomain = OMX_PortDomainVideo;
2839
2840 if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP)
2841 {
2842 if ((retval = get_buffer_requirements_swvdec(OMX_CORE_PORT_INDEX_IP)) !=
2843 OMX_ErrorNone)
2844 {
2845 goto get_port_definition_exit;
2846 }
2847
2848 p_port_def->eDir = OMX_DirInput;
2849 p_port_def->nBufferCountActual = m_port_ip.def.nBufferCountActual;
2850 p_port_def->nBufferCountMin = m_port_ip.def.nBufferCountMin;
2851 p_port_def->nBufferSize = m_port_ip.def.nBufferSize;
2852 p_port_def->bEnabled = m_port_ip.enabled;
2853 p_port_def->bPopulated = m_port_ip.populated;
2854
2855 // VTS uses input port dimensions to set OP dimensions
2856 if ((retval = get_frame_dimensions_swvdec()) != OMX_ErrorNone)
2857 {
2858 goto get_port_definition_exit;
2859 }
2860
2861 p_port_def->format.video.nFrameWidth = m_frame_dimensions.width;
2862 p_port_def->format.video.nFrameHeight = m_frame_dimensions.height;
2863
2864 OMX_SWVDEC_LOG_HIGH("port index %d: "
2865 "count actual %d, count min %d, size %d, %d x %d",
2866 p_port_def->nPortIndex,
2867 p_port_def->nBufferCountActual,
2868 p_port_def->nBufferCountMin,
2869 p_port_def->nBufferSize,
2870 p_port_def->format.video.nFrameWidth,
2871 p_port_def->format.video.nFrameHeight);
2872
2873 p_port_def->format.video.eColorFormat = OMX_COLOR_FormatUnused;
2874 p_port_def->format.video.eCompressionFormat = m_omx_video_codingtype;
2875 }
2876 else if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP)
2877 {
2878 if ((retval = get_frame_dimensions_swvdec()) != OMX_ErrorNone)
2879 {
2880 goto get_port_definition_exit;
2881 }
2882
2883 p_port_def->format.video.nFrameWidth = m_frame_dimensions.width;
2884 p_port_def->format.video.nFrameHeight = m_frame_dimensions.height;
2885
2886 if (m_port_reconfig_inprogress)
2887 {
2888 if ((retval = set_frame_attributes(m_omx_color_formattype)) !=
2889 OMX_ErrorNone)
2890 {
2891 goto get_port_definition_exit;
2892 }
2893 }
2894
2895 if ((retval = get_frame_attributes_swvdec()) != OMX_ErrorNone)
2896 {
2897 goto get_port_definition_exit;
2898 }
2899
2900 p_port_def->format.video.nStride = m_frame_attributes.stride;
2901 p_port_def->format.video.nSliceHeight = m_frame_attributes.scanlines;
2902
2903 OMX_SWVDEC_LOG_HIGH("port index %d: "
2904 "%d x %d, stride %d, sliceheight %d",
2905 p_port_def->nPortIndex,
2906 p_port_def->format.video.nFrameWidth,
2907 p_port_def->format.video.nFrameHeight,
2908 p_port_def->format.video.nStride,
2909 p_port_def->format.video.nSliceHeight);
2910
2911 /**
2912 * Query to SwVdec core for buffer requirements is not allowed in
2913 * executing state since it will overwrite the component's buffer
2914 * requirements updated via the most recent set_parameter().
2915 *
2916 * Buffer requirements communicated to component via set_parameter() are
2917 * not propagated to SwVdec core.
2918 *
2919 * The only execption is if port reconfiguration is in progress, in
2920 * which case the query to SwVdec core is required since buffer
2921 * requirements can change based on new dimensions.
2922 */
2923 if ((m_state != OMX_StateExecuting) || m_port_reconfig_inprogress)
2924 {
2925 if ((retval =
2926 get_buffer_requirements_swvdec(OMX_CORE_PORT_INDEX_OP)) !=
2927 OMX_ErrorNone)
2928 {
2929 goto get_port_definition_exit;
2930 }
2931 }
2932
2933 p_port_def->eDir = OMX_DirOutput;
2934 p_port_def->nBufferCountActual = m_port_op.def.nBufferCountActual;
2935 p_port_def->nBufferCountMin = m_port_op.def.nBufferCountMin;
2936 p_port_def->nBufferSize = m_port_op.def.nBufferSize;
2937 p_port_def->bEnabled = m_port_op.enabled;
2938 p_port_def->bPopulated = m_port_op.populated;
2939
2940 OMX_SWVDEC_LOG_HIGH("port index %d: "
2941 "count actual %d, count min %d, size %d",
2942 p_port_def->nPortIndex,
2943 p_port_def->nBufferCountActual,
2944 p_port_def->nBufferCountMin,
2945 p_port_def->nBufferSize);
2946
2947 p_port_def->format.video.eColorFormat = m_omx_color_formattype;
2948 p_port_def->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2949
2950 if (m_omx_color_formattype ==
2951 OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m)
2952 {
2953 OMX_SWVDEC_LOG_HIGH(
2954 "port index %d: color format '0x%08x': "
2955 "OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m",
2956 p_port_def->nPortIndex,
2957 p_port_def->format.video.eColorFormat);
2958 }
2959 else if (m_omx_color_formattype == OMX_COLOR_FormatYUV420SemiPlanar)
2960 {
2961 OMX_SWVDEC_LOG_HIGH("port index %d: color format '0x%08x': "
2962 "OMX_COLOR_FormatYUV420SemiPlanar",
2963 p_port_def->nPortIndex,
2964 p_port_def->format.video.eColorFormat);
2965 }
2966 else
2967 {
2968 assert(0);
2969 retval = OMX_ErrorUndefined;
2970 }
2971 }
2972 else
2973 {
2974 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", p_port_def->nPortIndex);
2975
2976 retval = OMX_ErrorBadPortIndex;
2977 }
2978
2979 get_port_definition_exit:
2980 return retval;
2981 }
2982
2983 /**
2984 * @brief Set port definition for input or output port.
2985 *
2986 * @param[in] p_port_def: Pointer to port definition type.
2987 *
2988 * @retval OMX_ERRORTYPE
2989 */
set_port_definition(OMX_PARAM_PORTDEFINITIONTYPE * p_port_def)2990 OMX_ERRORTYPE omx_swvdec::set_port_definition(
2991 OMX_PARAM_PORTDEFINITIONTYPE *p_port_def)
2992 {
2993 OMX_ERRORTYPE retval = OMX_ErrorNone;
2994
2995 OMX_SWVDEC_LOG_HIGH("port index %d: "
2996 "count actual %d, count min %d, size %d",
2997 p_port_def->nPortIndex,
2998 p_port_def->nBufferCountActual,
2999 p_port_def->nBufferCountMin,
3000 p_port_def->nBufferSize);
3001
3002 if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP)
3003 {
3004 m_port_ip.def.nBufferCountActual = p_port_def->nBufferCountActual;
3005 m_port_ip.def.nBufferCountMin = p_port_def->nBufferCountMin;
3006 m_port_ip.def.nBufferSize = p_port_def->nBufferSize;
3007 }
3008 else if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP)
3009 {
3010 /**
3011 * OMX component's output port nBufferSize is not updated based on what
3012 * IL client sends; instead it is updated based on the possibly updated
3013 * frame attributes.
3014 *
3015 * This is because set_parameter() for output port definition only has
3016 * updates to buffer counts or frame dimensions.
3017 */
3018
3019 m_port_op.def.nBufferCountActual = p_port_def->nBufferCountActual;
3020
3021 OMX_SWVDEC_LOG_HIGH("port index %d: %d x %d",
3022 p_port_def->nPortIndex,
3023 p_port_def->format.video.nFrameWidth,
3024 p_port_def->format.video.nFrameHeight);
3025
3026 /**
3027 * Update frame dimensions & attributes if:
3028 *
3029 * 1. not in adaptive playback mode
3030 * OR
3031 * 2. new frame dimensions greater than adaptive playback mode's
3032 * max frame dimensions
3033 */
3034
3035 if ((m_adaptive_playback_mode == false) ||
3036 (p_port_def->format.video.nFrameWidth >
3037 m_frame_dimensions_max.width) ||
3038 (p_port_def->format.video.nFrameHeight >
3039 m_frame_dimensions_max.height))
3040 {
3041 OMX_SWVDEC_LOG_HIGH("updating frame dimensions & attributes");
3042
3043 if ((retval =
3044 set_frame_dimensions(p_port_def->format.video.nFrameWidth,
3045 p_port_def->format.video.nFrameHeight)) !=
3046 OMX_ErrorNone)
3047 {
3048 goto set_port_definition_exit;
3049 }
3050
3051 if ((retval = set_frame_attributes(m_omx_color_formattype)) !=
3052 OMX_ErrorNone)
3053 {
3054 goto set_port_definition_exit;
3055 }
3056
3057 // nBufferSize updated based on (possibly new) frame attributes
3058
3059 m_port_op.def.nBufferSize = m_frame_attributes.size;
3060 }
3061 else
3062 {
3063 OMX_SWVDEC_LOG_HIGH("not updating frame dimensions & attributes");
3064 }
3065 }
3066 else
3067 {
3068 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", p_port_def->nPortIndex);
3069
3070 retval = OMX_ErrorBadPortIndex;
3071 }
3072
3073 set_port_definition_exit:
3074 return retval;
3075 }
3076
3077 /**
3078 * @brief Get supported profile & level.
3079 *
3080 * The supported profiles & levels are not queried from SwVdec core, but
3081 * hard-coded. This should ideally be replaced with a query to SwVdec core.
3082 *
3083 * @param[in,out] p_profilelevel: Pointer to video profile & level type.
3084 *
3085 * @retval OMX_ERRORTYPE
3086 */
get_supported_profilelevel(OMX_VIDEO_PARAM_PROFILELEVELTYPE * p_profilelevel)3087 OMX_ERRORTYPE omx_swvdec::get_supported_profilelevel(
3088 OMX_VIDEO_PARAM_PROFILELEVELTYPE *p_profilelevel)
3089 {
3090 OMX_ERRORTYPE retval = OMX_ErrorNone;
3091
3092 if (p_profilelevel == NULL)
3093 {
3094 OMX_SWVDEC_LOG_ERROR("p_profilelevel = NULL");
3095
3096 retval = OMX_ErrorBadParameter;
3097 goto get_supported_profilelevel_exit;
3098 }
3099
3100 if (p_profilelevel->nPortIndex != OMX_CORE_PORT_INDEX_IP)
3101 {
3102 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
3103 p_profilelevel->nPortIndex);
3104
3105 retval = OMX_ErrorBadPortIndex;
3106 goto get_supported_profilelevel_exit;
3107 }
3108
3109 if (m_omx_video_codingtype == OMX_VIDEO_CodingH263)
3110 {
3111 if (p_profilelevel->nProfileIndex == 0)
3112 {
3113 p_profilelevel->eProfile = OMX_VIDEO_H263ProfileBaseline;
3114 p_profilelevel->eLevel = OMX_VIDEO_H263Level70;
3115
3116 OMX_SWVDEC_LOG_HIGH("H.263 baseline profile, level 70");
3117 }
3118 else
3119 {
3120 OMX_SWVDEC_LOG_HIGH("profile index '%d' unsupported; "
3121 "no more profiles",
3122 p_profilelevel->nProfileIndex);
3123
3124 retval = OMX_ErrorNoMore;
3125 }
3126 }
3127 else if ((m_omx_video_codingtype == OMX_VIDEO_CodingMPEG4) ||
3128 (m_omx_video_codingtype ==
3129 ((OMX_VIDEO_CODINGTYPE) QOMX_VIDEO_CodingDivx)))
3130 {
3131 if (p_profilelevel->nProfileIndex == 0)
3132 {
3133 p_profilelevel->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
3134 p_profilelevel->eLevel = OMX_VIDEO_MPEG4Level6;
3135
3136 OMX_SWVDEC_LOG_HIGH("MPEG-4 simple profile, level 6");
3137 }
3138 else if (p_profilelevel->nProfileIndex == 1)
3139 {
3140 p_profilelevel->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
3141 p_profilelevel->eLevel = OMX_VIDEO_MPEG4Level5;
3142
3143 OMX_SWVDEC_LOG_HIGH("MPEG-4 advanced simple profile, level 5");
3144 }
3145 else
3146 {
3147 OMX_SWVDEC_LOG_HIGH("profile index '%d' unsupported; "
3148 "no more profiles",
3149 p_profilelevel->nProfileIndex);
3150
3151 retval = OMX_ErrorNoMore;
3152 }
3153 }
3154 else
3155 {
3156 assert(0);
3157 retval = OMX_ErrorUndefined;
3158 }
3159
3160 get_supported_profilelevel_exit:
3161 return retval;
3162 }
3163
3164 /**
3165 * @brief Describe color format.
3166 *
3167 * @param[in,out] p_params: Pointer to 'DescribeColorFormatParams' structure.
3168 *
3169 * @retval OMX_ERRORTYPE
3170 */
describe_color_format(DescribeColorFormatParams * p_params)3171 OMX_ERRORTYPE omx_swvdec::describe_color_format(
3172 DescribeColorFormatParams *p_params)
3173 {
3174 OMX_ERRORTYPE retval = OMX_ErrorNone;
3175
3176 if (p_params == NULL)
3177 {
3178 OMX_SWVDEC_LOG_ERROR("p_params = NULL");
3179
3180 retval = OMX_ErrorBadParameter;
3181 }
3182 else
3183 {
3184 MediaImage *p_img = &p_params->sMediaImage;
3185
3186 switch (p_params->eColorFormat)
3187 {
3188
3189 case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m:
3190 {
3191 size_t stride, scanlines;
3192
3193 p_img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
3194 p_img->mNumPlanes = 3;
3195
3196 p_img->mWidth = p_params->nFrameWidth;
3197 p_img->mHeight = p_params->nFrameHeight;
3198
3199 /**
3200 * alignment factors:
3201 *
3202 * - stride: 128
3203 * - scanlines: 32
3204 */
3205 stride = ALIGN(p_img->mWidth, 128);
3206 scanlines = ALIGN(p_img->mHeight, 32);
3207
3208 p_img->mBitDepth = 8;
3209
3210 // plane 0 (Y)
3211 p_img->mPlane[MediaImage::Y].mOffset = 0;
3212 p_img->mPlane[MediaImage::Y].mColInc = 1;
3213 p_img->mPlane[MediaImage::Y].mRowInc = stride;
3214 p_img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
3215 p_img->mPlane[MediaImage::Y].mVertSubsampling = 1;
3216
3217 // plane 1 (U)
3218 p_img->mPlane[MediaImage::U].mOffset = stride * scanlines;
3219 p_img->mPlane[MediaImage::U].mColInc = 2;
3220 p_img->mPlane[MediaImage::U].mRowInc = stride;
3221 p_img->mPlane[MediaImage::U].mHorizSubsampling = 2;
3222 p_img->mPlane[MediaImage::U].mVertSubsampling = 2;
3223
3224 // plane 2 (V)
3225 p_img->mPlane[MediaImage::V].mOffset = stride * scanlines + 1;
3226 p_img->mPlane[MediaImage::V].mColInc = 2;
3227 p_img->mPlane[MediaImage::V].mRowInc = stride;
3228 p_img->mPlane[MediaImage::V].mHorizSubsampling = 2;
3229 p_img->mPlane[MediaImage::V].mVertSubsampling = 2;
3230
3231 break;
3232 }
3233
3234 case OMX_COLOR_FormatYUV420SemiPlanar:
3235 {
3236 // do nothing; standard OMX color formats should not be described
3237 retval = OMX_ErrorUnsupportedSetting;
3238 break;
3239 }
3240
3241 default:
3242 {
3243 OMX_SWVDEC_LOG_ERROR("color format '0x%08x' invalid/unsupported",
3244 p_params->eColorFormat);
3245
3246 p_img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3247
3248 retval = OMX_ErrorBadParameter;
3249 break;
3250 }
3251
3252 } // switch (p_params->eColorFormat)
3253 }
3254
3255 return retval;
3256 }
3257
3258 /**
3259 * @brief Set QTI vendor-specific port definition for input or output port.
3260 *
3261 * @param[in] p_port_def: Pointer to QTI vendor-specific port definition type.
3262 *
3263 * @retval OMX_ERRORTYPE
3264 */
set_port_definition_qcom(OMX_QCOM_PARAM_PORTDEFINITIONTYPE * p_port_def)3265 OMX_ERRORTYPE omx_swvdec::set_port_definition_qcom(
3266 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *p_port_def)
3267 {
3268 OMX_ERRORTYPE retval = OMX_ErrorNone;
3269
3270 if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP)
3271 {
3272 switch (p_port_def->nFramePackingFormat)
3273 {
3274
3275 case OMX_QCOM_FramePacking_Arbitrary:
3276 {
3277 OMX_SWVDEC_LOG_HIGH("OMX_QCOM_FramePacking_Arbitrary");
3278
3279 m_arbitrary_bytes_mode = true;
3280
3281 break;
3282 }
3283
3284 case OMX_QCOM_FramePacking_OnlyOneCompleteFrame:
3285 {
3286 OMX_SWVDEC_LOG_HIGH(
3287 "OMX_QCOM_FramePacking_OnlyOneCompleteFrame");
3288
3289 break;
3290 }
3291
3292 default:
3293 {
3294 OMX_SWVDEC_LOG_ERROR(
3295 "frame packing format '%d' unsupported",
3296 p_port_def->nFramePackingFormat);
3297
3298 retval = OMX_ErrorUnsupportedSetting;
3299 break;
3300 }
3301
3302 }
3303 }
3304 else if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP)
3305 {
3306 OMX_SWVDEC_LOG_HIGH("nMemRegion %d, nCacheAttr %d",
3307 p_port_def->nMemRegion,
3308 p_port_def->nCacheAttr);
3309 }
3310 else
3311 {
3312 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
3313 p_port_def->nPortIndex);
3314
3315 retval = OMX_ErrorBadPortIndex;
3316 }
3317
3318 return retval;
3319 }
3320
3321 /**
3322 * @brief Set SwVdec frame dimensions based on OMX component frame dimensions.
3323 *
3324 * @retval OMX_ERRORTYPE
3325 */
set_frame_dimensions_swvdec()3326 OMX_ERRORTYPE omx_swvdec::set_frame_dimensions_swvdec()
3327 {
3328 OMX_ERRORTYPE retval = OMX_ErrorNone;
3329
3330 SWVDEC_PROPERTY property;
3331
3332 SWVDEC_STATUS retval_swvdec;
3333
3334 property.id = SWVDEC_PROPERTY_ID_FRAME_DIMENSIONS;
3335
3336 property.info.frame_dimensions.width = m_frame_dimensions.width;
3337 property.info.frame_dimensions.height = m_frame_dimensions.height;
3338
3339 if ((retval_swvdec = swvdec_setproperty(m_swvdec_handle, &property)) !=
3340 SWVDEC_STATUS_SUCCESS)
3341 {
3342 retval = retval_swvdec2omx(retval_swvdec);
3343 }
3344
3345 return retval;
3346 }
3347
3348 /**
3349 * @brief Set SwVdec frame attributes based on OMX component frame attributes.
3350 *
3351 * @retval OMX_ERRORTYPE
3352 */
set_frame_attributes_swvdec()3353 OMX_ERRORTYPE omx_swvdec::set_frame_attributes_swvdec()
3354 {
3355 OMX_ERRORTYPE retval = OMX_ErrorNone;
3356
3357 SWVDEC_FRAME_ATTRIBUTES *p_frame_attributes;
3358
3359 SWVDEC_PROPERTY property;
3360
3361 SWVDEC_STATUS retval_swvdec;
3362
3363 p_frame_attributes = &property.info.frame_attributes;
3364
3365 property.id = SWVDEC_PROPERTY_ID_FRAME_ATTRIBUTES;
3366
3367 if(m_omx_color_formattype == OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m)
3368 p_frame_attributes->color_format = SWVDEC_COLOR_FORMAT_SEMIPLANAR_NV12_32;
3369 else
3370 p_frame_attributes->color_format = SWVDEC_COLOR_FORMAT_SEMIPLANAR_NV12;
3371
3372 p_frame_attributes->stride = m_frame_attributes.stride;
3373 p_frame_attributes->scanlines = m_frame_attributes.scanlines;
3374 p_frame_attributes->size = m_frame_attributes.size;
3375
3376 if ((retval_swvdec = swvdec_setproperty(m_swvdec_handle, &property)) !=
3377 SWVDEC_STATUS_SUCCESS)
3378 {
3379 retval = retval_swvdec2omx(retval_swvdec);
3380 }
3381
3382 return retval;
3383 }
3384
3385 /**
3386 * @brief Set maximum adaptive playback frame dimensions for SwVdec core.
3387 */
set_adaptive_playback_swvdec()3388 OMX_ERRORTYPE omx_swvdec::set_adaptive_playback_swvdec()
3389 {
3390 OMX_ERRORTYPE retval = OMX_ErrorNone;
3391
3392 SWVDEC_PROPERTY property;
3393
3394 SWVDEC_STATUS retval_swvdec;
3395
3396 property.id = SWVDEC_PROPERTY_ID_ADAPTIVE_PLAYBACK;
3397
3398 property.info.frame_dimensions.width = m_frame_dimensions_max.width;
3399 property.info.frame_dimensions.height = m_frame_dimensions_max.height;
3400
3401 if ((retval_swvdec = swvdec_setproperty(m_swvdec_handle, &property)) !=
3402 SWVDEC_STATUS_SUCCESS)
3403 {
3404 retval = retval_swvdec2omx(retval_swvdec);
3405 }
3406
3407 return retval;
3408 }
3409
3410 /**
3411 * @brief Set thumbnail mode for SwVdec core.
3412 */
set_thumbnail_mode_swvdec()3413 OMX_ERRORTYPE omx_swvdec::set_thumbnail_mode_swvdec()
3414 {
3415 OMX_ERRORTYPE retval = OMX_ErrorNone;
3416
3417 SWVDEC_PROPERTY property;
3418
3419 SWVDEC_STATUS retval_swvdec;
3420
3421 property.id = SWVDEC_PROPERTY_ID_THUMBNAIL_MODE;
3422
3423 if ((retval_swvdec = swvdec_setproperty(m_swvdec_handle, &property)) !=
3424 SWVDEC_STATUS_SUCCESS)
3425 {
3426 retval = retval_swvdec2omx(retval_swvdec);
3427 }
3428
3429 return retval;
3430 }
3431
3432 /**
3433 * @brief Get SwVdec frame dimensions and set OMX component frame dimensions.
3434 *
3435 * @retval OMX_ERRORTYPE
3436 */
get_frame_dimensions_swvdec()3437 OMX_ERRORTYPE omx_swvdec::get_frame_dimensions_swvdec()
3438 {
3439 OMX_ERRORTYPE retval = OMX_ErrorNone;
3440
3441 SWVDEC_PROPERTY property;
3442
3443 SWVDEC_STATUS retval_swvdec;
3444
3445 property.id = SWVDEC_PROPERTY_ID_FRAME_DIMENSIONS;
3446
3447 if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
3448 SWVDEC_STATUS_SUCCESS)
3449 {
3450 retval = retval_swvdec2omx(retval_swvdec);
3451 }
3452 else
3453 {
3454 m_frame_dimensions.width = property.info.frame_dimensions.width;
3455 m_frame_dimensions.height = property.info.frame_dimensions.height;
3456 }
3457
3458 return retval;
3459 }
3460
3461 /**
3462 * @brief Get SwVdec frame attributes and set OMX component frame attributes.
3463 *
3464 * @retval OMX_ERRORTYPE
3465 */
get_frame_attributes_swvdec()3466 OMX_ERRORTYPE omx_swvdec::get_frame_attributes_swvdec()
3467 {
3468 OMX_ERRORTYPE retval = OMX_ErrorNone;
3469
3470 SWVDEC_PROPERTY property;
3471
3472 SWVDEC_STATUS retval_swvdec;
3473
3474 property.id = SWVDEC_PROPERTY_ID_FRAME_ATTRIBUTES;
3475
3476 if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
3477 SWVDEC_STATUS_SUCCESS)
3478 {
3479 retval = retval_swvdec2omx(retval_swvdec);
3480 }
3481 else
3482 {
3483 m_frame_attributes.stride = property.info.frame_attributes.stride;
3484 m_frame_attributes.scanlines = property.info.frame_attributes.scanlines;
3485 m_frame_attributes.size = property.info.frame_attributes.size;
3486 }
3487
3488 return retval;
3489 }
3490
3491 /**
3492 * @brief Get SwVdec buffer requirements; set input or output port definitions.
3493 *
3494 * @param[in] port_index: Port index.
3495 *
3496 * @retval OMX_ERRORTYPE
3497 */
get_buffer_requirements_swvdec(unsigned int port_index)3498 OMX_ERRORTYPE omx_swvdec::get_buffer_requirements_swvdec(
3499 unsigned int port_index)
3500 {
3501 OMX_ERRORTYPE retval = OMX_ErrorNone;
3502
3503 SWVDEC_PROPERTY property;
3504
3505 SWVDEC_STATUS retval_swvdec;
3506
3507 SWVDEC_BUFFER_REQ *p_buffer_req;
3508
3509 if (port_index == OMX_CORE_PORT_INDEX_IP)
3510 {
3511 property.id = SWVDEC_PROPERTY_ID_BUFFER_REQ_IP;
3512
3513 p_buffer_req = &property.info.buffer_req_ip;
3514
3515 if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
3516 SWVDEC_STATUS_SUCCESS)
3517 {
3518 retval = retval_swvdec2omx(retval_swvdec);
3519 goto get_buffer_requirements_swvdec_exit;
3520 }
3521
3522 m_port_ip.def.nBufferSize = p_buffer_req->size;
3523 m_port_ip.def.nBufferCountMin = p_buffer_req->mincount;
3524 m_port_ip.def.nBufferCountActual = MAX((MAX(p_buffer_req->mincount,
3525 OMX_SWVDEC_IP_BUFFER_COUNT_MIN)),
3526 m_port_ip.def.nBufferCountActual);
3527 m_port_ip.def.nBufferAlignment = p_buffer_req->alignment;
3528
3529 OMX_SWVDEC_LOG_HIGH("ip port: %d bytes x %d, %d-byte aligned",
3530 m_port_ip.def.nBufferSize,
3531 m_port_ip.def.nBufferCountActual,
3532 m_port_ip.def.nBufferAlignment);
3533 }
3534 else if (port_index == OMX_CORE_PORT_INDEX_OP)
3535 {
3536 property.id = SWVDEC_PROPERTY_ID_BUFFER_REQ_OP;
3537
3538 p_buffer_req = &property.info.buffer_req_op;
3539
3540 if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
3541 SWVDEC_STATUS_SUCCESS)
3542 {
3543 retval = retval_swvdec2omx(retval_swvdec);
3544 goto get_buffer_requirements_swvdec_exit;
3545 }
3546
3547 if (m_sync_frame_decoding_mode)
3548 {
3549 p_buffer_req->mincount = 1;
3550 }
3551
3552 m_port_op.def.nBufferSize = p_buffer_req->size;
3553 m_port_op.def.nBufferCountMin = p_buffer_req->mincount;
3554 m_port_op.def.nBufferCountActual = MAX(p_buffer_req->mincount,
3555 m_port_op.def.nBufferCountActual);
3556 m_port_op.def.nBufferAlignment = p_buffer_req->alignment;
3557
3558 OMX_SWVDEC_LOG_HIGH("op port: %d bytes x %d, %d-byte aligned",
3559 m_port_op.def.nBufferSize,
3560 m_port_op.def.nBufferCountActual,
3561 m_port_op.def.nBufferAlignment);
3562 }
3563 else
3564 {
3565 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", port_index);
3566
3567 retval = OMX_ErrorBadPortIndex;
3568 }
3569
3570 get_buffer_requirements_swvdec_exit:
3571 return retval;
3572 }
3573
3574 /**
3575 * @brief Allocate input buffer, and input buffer info array if ncessary.
3576 *
3577 * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
3578 * structure.
3579 * @param[in] p_app_data: Pointer to IL client app data.
3580 * @param[in] size: Size of buffer to be allocated in bytes.
3581 *
3582 * @retval OMX_ERRORTYPE
3583 */
buffer_allocate_ip(OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_PTR p_app_data,OMX_U32 size)3584 OMX_ERRORTYPE omx_swvdec::buffer_allocate_ip(
3585 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
3586 OMX_PTR p_app_data,
3587 OMX_U32 size)
3588 {
3589 OMX_ERRORTYPE retval = OMX_ErrorNone;
3590 SWVDEC_STATUS retval_swvdec = SWVDEC_STATUS_SUCCESS;
3591
3592 unsigned int ii;
3593
3594 if (size != m_port_ip.def.nBufferSize)
3595 {
3596 OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
3597 "configured size (%d bytes)",
3598 size,
3599 m_port_ip.def.nBufferSize);
3600
3601 return OMX_ErrorBadParameter;
3602 }
3603
3604 if (m_buffer_array_ip == NULL)
3605 {
3606 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3607 m_port_ip.def.nBufferCountActual,
3608 (m_port_ip.def.nBufferCountActual > 1) ? "s" : "");
3609
3610 if ((retval = buffer_allocate_ip_info_array()) != OMX_ErrorNone)
3611 {
3612 return retval;
3613 }
3614 }
3615
3616 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
3617 {
3618 if (m_buffer_array_ip[ii].buffer_populated == false)
3619 {
3620 OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
3621 break;
3622 }
3623 }
3624
3625 if (ii < m_port_ip.def.nBufferCountActual)
3626 {
3627 int pmem_fd = -1;
3628
3629 unsigned char *bufferaddr;
3630
3631 OMX_SWVDEC_LOG_HIGH("ip buffer %d: %d bytes being allocated",
3632 ii,
3633 size);
3634
3635 m_buffer_array_ip[ii].ion_info.dev_fd=
3636 ion_memory_alloc_map(&m_buffer_array_ip[ii].ion_info,size,
3637 m_port_ip.def.nBufferAlignment);
3638
3639 if (m_buffer_array_ip[ii].ion_info.dev_fd< 0)
3640 {
3641 return OMX_ErrorInsufficientResources;
3642 }
3643
3644 pmem_fd = m_buffer_array_ip[ii].ion_info.data_fd;
3645
3646 bufferaddr = ion_map(pmem_fd,size);
3647
3648 if (bufferaddr == MAP_FAILED)
3649 {
3650 OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d error %s",
3651 pmem_fd,
3652 size, strerror(errno));
3653
3654 close(pmem_fd);
3655 ion_memory_free(&m_buffer_array_ip[ii].ion_info);
3656
3657 return OMX_ErrorInsufficientResources;
3658 }
3659
3660 *pp_buffer_hdr = &m_buffer_array_ip[ii].buffer_header;
3661
3662 m_buffer_array_ip[ii].buffer_payload.bufferaddr = bufferaddr;
3663 m_buffer_array_ip[ii].buffer_payload.pmem_fd = pmem_fd;
3664 m_buffer_array_ip[ii].buffer_payload.buffer_len = size;
3665 m_buffer_array_ip[ii].buffer_payload.mmaped_size = size;
3666 m_buffer_array_ip[ii].buffer_payload.offset = 0;
3667
3668 m_buffer_array_ip[ii].buffer_swvdec.p_buffer = bufferaddr;
3669 m_buffer_array_ip[ii].buffer_swvdec.size = size;
3670 m_buffer_array_ip[ii].buffer_swvdec.p_client_data =
3671 (void *) ((unsigned long) ii);
3672 m_buffer_array_ip[ii].buffer_swvdec.fd = pmem_fd;
3673
3674 m_buffer_array_ip[ii].buffer_populated = true;
3675
3676 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
3677 {
3678 OMX_SWVDEC_LOG_LOW("map ip buffer");
3679
3680 if((retval_swvdec = swvdec_register_buffer(m_swvdec_handle,
3681 &m_buffer_array_ip[ii].buffer_swvdec))
3682 != SWVDEC_STATUS_SUCCESS)
3683 {
3684 OMX_SWVDEC_LOG_ERROR("swvdec_map failed for ip buffer %d: %p",ii,bufferaddr);
3685
3686 close(pmem_fd);
3687 ion_memory_free(&m_buffer_array_ip[ii].ion_info);
3688
3689 return retval_swvdec2omx(retval_swvdec);
3690 }
3691 }
3692
3693 OMX_SWVDEC_LOG_HIGH("ip buffer %d: %p, fd = %d %d bytes",
3694 ii,
3695 bufferaddr,
3696 pmem_fd,
3697 size);
3698
3699 (*pp_buffer_hdr)->pBuffer = (OMX_U8 *) bufferaddr;
3700 (*pp_buffer_hdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3701 (*pp_buffer_hdr)->nVersion.nVersion = OMX_SPEC_VERSION;
3702 (*pp_buffer_hdr)->nAllocLen = size;
3703 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
3704 (*pp_buffer_hdr)->nInputPortIndex = OMX_CORE_PORT_INDEX_IP;
3705 (*pp_buffer_hdr)->pInputPortPrivate =
3706 (void *) &(m_buffer_array_ip[ii].buffer_payload);
3707
3708 m_port_ip.populated = port_ip_populated();
3709 m_port_ip.unpopulated = OMX_FALSE;
3710 }
3711 else
3712 {
3713 OMX_SWVDEC_LOG_ERROR("all %d ip buffers allocated",
3714 m_port_ip.def.nBufferCountActual);
3715
3716 return OMX_ErrorInsufficientResources;
3717 }
3718
3719 return retval;
3720 }
3721
3722 /**
3723 * @brief Allocate output buffer, and output buffer info array if necessary.
3724 *
3725 * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
3726 * structure.
3727 * @param[in] p_app_data: Pointer to IL client app data.
3728 * @param[in] size: Size of buffer to be allocated in bytes.
3729 *
3730 * @retval OMX_ERRORTYPE
3731 */
buffer_allocate_op(OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_PTR p_app_data,OMX_U32 size)3732 OMX_ERRORTYPE omx_swvdec::buffer_allocate_op(
3733 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
3734 OMX_PTR p_app_data,
3735 OMX_U32 size)
3736 {
3737 OMX_ERRORTYPE retval = OMX_ErrorNone;
3738 SWVDEC_STATUS retval_swvdec = SWVDEC_STATUS_SUCCESS;
3739 unsigned int ii;
3740
3741 if (size != m_port_op.def.nBufferSize)
3742 {
3743 OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
3744 "configured size (%d bytes)",
3745 size,
3746 m_port_op.def.nBufferSize);
3747
3748 return OMX_ErrorBadParameter;
3749 }
3750
3751 if (m_buffer_array_op == NULL)
3752 {
3753 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3754 m_port_op.def.nBufferCountActual,
3755 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
3756
3757 if ((retval = buffer_allocate_op_info_array()) != OMX_ErrorNone)
3758 {
3759 return retval;
3760 }
3761 }
3762
3763 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
3764 {
3765 if (m_buffer_array_op[ii].buffer_populated == false)
3766 {
3767 OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
3768 break;
3769 }
3770 }
3771
3772 if (ii < m_port_op.def.nBufferCountActual)
3773 {
3774 int pmem_fd = -1;
3775
3776 unsigned char *bufferaddr;
3777
3778 OMX_SWVDEC_LOG_HIGH("op buffer %d: %d bytes being allocated",
3779 ii,
3780 size);
3781
3782 m_buffer_array_op[ii].ion_info.dev_fd=
3783 ion_memory_alloc_map(&m_buffer_array_op[ii].ion_info,size,
3784 m_port_op.def.nBufferAlignment);
3785
3786 if (m_buffer_array_op[ii].ion_info.dev_fd < 0)
3787 {
3788 return OMX_ErrorInsufficientResources;
3789 }
3790
3791 pmem_fd = m_buffer_array_op[ii].ion_info.data_fd;
3792
3793 bufferaddr = ion_map(pmem_fd,size);
3794
3795 if (bufferaddr == MAP_FAILED)
3796 {
3797 OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d",
3798 pmem_fd,
3799 size);
3800
3801 close(pmem_fd);
3802 ion_memory_free(&m_buffer_array_op[ii].ion_info);
3803
3804 return OMX_ErrorInsufficientResources;
3805 }
3806
3807 *pp_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
3808
3809 m_buffer_array_op[ii].buffer_payload.bufferaddr = bufferaddr;
3810 m_buffer_array_op[ii].buffer_payload.pmem_fd = pmem_fd;
3811 m_buffer_array_op[ii].buffer_payload.buffer_len = size;
3812 m_buffer_array_op[ii].buffer_payload.mmaped_size = size;
3813 m_buffer_array_op[ii].buffer_payload.offset = 0;
3814
3815 m_buffer_array_op[ii].buffer_swvdec.p_buffer = bufferaddr;
3816 m_buffer_array_op[ii].buffer_swvdec.size = size;
3817 m_buffer_array_op[ii].buffer_swvdec.p_client_data =
3818 (void *) ((unsigned long) ii);
3819
3820 m_buffer_array_op[ii].buffer_populated = true;
3821
3822 m_buffer_array_op[ii].buffer_swvdec.fd = pmem_fd ;
3823
3824 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
3825 {
3826 OMX_SWVDEC_LOG_LOW("map op buffer");
3827
3828 if((retval_swvdec = swvdec_map(m_swvdec_handle,&m_buffer_array_op[ii].buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
3829 {
3830 OMX_SWVDEC_LOG_ERROR("swvdec_map failed for op buffer %d: %p",ii,bufferaddr);
3831
3832 close(pmem_fd);
3833 ion_memory_free(&m_buffer_array_op[ii].ion_info);
3834
3835 return retval_swvdec2omx(retval_swvdec);
3836 }
3837 }
3838 OMX_SWVDEC_LOG_HIGH("op buffer %d: %p, fd = %d %d bytes",
3839 ii,
3840 bufferaddr,
3841 pmem_fd,
3842 size);
3843
3844 (*pp_buffer_hdr)->pBuffer = (OMX_U8 *) bufferaddr;
3845 (*pp_buffer_hdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3846 (*pp_buffer_hdr)->nVersion.nVersion = OMX_SPEC_VERSION;
3847 (*pp_buffer_hdr)->nAllocLen = size;
3848 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
3849 (*pp_buffer_hdr)->nOutputPortIndex = OMX_CORE_PORT_INDEX_OP;
3850 (*pp_buffer_hdr)->pOutputPortPrivate =
3851 (void *) &(m_buffer_array_op[ii].buffer_payload);
3852
3853 m_port_op.populated = port_op_populated();
3854 m_port_op.unpopulated = OMX_FALSE;
3855 }
3856 else
3857 {
3858 OMX_SWVDEC_LOG_ERROR("all %d op buffers allocated",
3859 m_port_op.def.nBufferCountActual);
3860
3861 retval = OMX_ErrorInsufficientResources;
3862 }
3863
3864 return retval;
3865 }
3866
3867 /**
3868 * @brief Allocate input buffer info array.
3869 */
buffer_allocate_ip_info_array()3870 OMX_ERRORTYPE omx_swvdec::buffer_allocate_ip_info_array()
3871 {
3872 OMX_ERRORTYPE retval = OMX_ErrorNone;
3873
3874 unsigned int ii;
3875
3876 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
3877
3878 if (m_buffer_array_ip != NULL)
3879 {
3880 OMX_SWVDEC_LOG_ERROR("buffer info array already allocated");
3881
3882 retval = OMX_ErrorInsufficientResources;
3883 goto buffer_allocate_ip_info_array_exit;
3884 }
3885
3886 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3887 m_port_ip.def.nBufferCountActual,
3888 (m_port_ip.def.nBufferCountActual > 1) ? "s" : "");
3889
3890 m_buffer_array_ip =
3891 (OMX_SWVDEC_BUFFER_INFO *) calloc(sizeof(OMX_SWVDEC_BUFFER_INFO),
3892 m_port_ip.def.nBufferCountActual);
3893
3894 if (m_buffer_array_ip == NULL)
3895 {
3896 OMX_SWVDEC_LOG_ERROR("failed to allocate buffer info array; "
3897 "%d element%s, %zu bytes requested",
3898 m_port_ip.def.nBufferCountActual,
3899 (m_port_ip.def.nBufferCountActual > 1) ? "s" : "",
3900 sizeof(OMX_SWVDEC_BUFFER_INFO) *
3901 m_port_ip.def.nBufferCountActual);
3902
3903 retval = OMX_ErrorInsufficientResources;
3904 goto buffer_allocate_ip_info_array_exit;
3905 }
3906
3907 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
3908 {
3909 p_buffer_hdr = &m_buffer_array_ip[ii].buffer_header;
3910
3911 // reset file descriptors
3912
3913 m_buffer_array_ip[ii].buffer_payload.pmem_fd = -1;
3914 m_buffer_array_ip[ii].ion_info.dev_fd= -1;
3915
3916 m_buffer_array_ip[ii].buffer_swvdec.p_client_data =
3917 (void *) ((unsigned long) ii);
3918
3919 p_buffer_hdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3920 p_buffer_hdr->nVersion.nVersion = OMX_SPEC_VERSION;
3921 p_buffer_hdr->nInputPortIndex = OMX_CORE_PORT_INDEX_IP;
3922 p_buffer_hdr->pInputPortPrivate =
3923 (void *) &(m_buffer_array_ip[ii].buffer_payload);
3924 }
3925
3926 buffer_allocate_ip_info_array_exit:
3927 return retval;
3928 }
3929
3930 /**
3931 * @brief Allocate output buffer info array.
3932 */
buffer_allocate_op_info_array()3933 OMX_ERRORTYPE omx_swvdec::buffer_allocate_op_info_array()
3934 {
3935 OMX_ERRORTYPE retval = OMX_ErrorNone;
3936
3937 unsigned int ii;
3938
3939 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
3940
3941 if (m_buffer_array_op != NULL)
3942 {
3943 OMX_SWVDEC_LOG_ERROR("buffer info array already allocated");
3944
3945 retval = OMX_ErrorInsufficientResources;
3946 goto buffer_allocate_op_info_array_exit;
3947 }
3948
3949 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3950 m_port_op.def.nBufferCountActual,
3951 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
3952
3953 m_buffer_array_op =
3954 (OMX_SWVDEC_BUFFER_INFO *) calloc(sizeof(OMX_SWVDEC_BUFFER_INFO),
3955 m_port_op.def.nBufferCountActual);
3956
3957 if (m_buffer_array_op == NULL)
3958 {
3959 OMX_SWVDEC_LOG_ERROR("failed to allocate buffer info array; "
3960 "%d element%s, %zu bytes requested",
3961 m_port_op.def.nBufferCountActual,
3962 (m_port_op.def.nBufferCountActual > 1) ? "s" : "",
3963 sizeof(OMX_SWVDEC_BUFFER_INFO) *
3964 m_port_op.def.nBufferCountActual);
3965
3966 retval = OMX_ErrorInsufficientResources;
3967 goto buffer_allocate_op_info_array_exit;
3968 }
3969
3970 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
3971 {
3972 p_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
3973
3974 // reset file descriptors
3975
3976 m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
3977 m_buffer_array_op[ii].ion_info.dev_fd = -1;
3978
3979 m_buffer_array_op[ii].buffer_swvdec.p_client_data =
3980 (void *) ((unsigned long) ii);
3981
3982 p_buffer_hdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3983 p_buffer_hdr->nVersion.nVersion = OMX_SPEC_VERSION;
3984 p_buffer_hdr->nOutputPortIndex = OMX_CORE_PORT_INDEX_OP;
3985 p_buffer_hdr->pOutputPortPrivate =
3986 (void *) &(m_buffer_array_op[ii].buffer_payload);
3987 }
3988
3989 buffer_allocate_op_info_array_exit:
3990 return retval;
3991 }
3992
3993 /**
3994 * @brief Use buffer allocated by IL client; allocate output buffer info array
3995 * if necessary.
3996 *
3997 * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
3998 * structure.
3999 * @param[in] p_app_data: Pointer to IL client app data.
4000 * @param[in] size: Size of buffer to be allocated in bytes.
4001 * @param[in] p_buffer: Pointer to buffer to be used.
4002 *
4003 * @retval OMX_ERRORTYPE
4004 */
buffer_use_op(OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_PTR p_app_data,OMX_U32 size,OMX_U8 * p_buffer)4005 OMX_ERRORTYPE omx_swvdec::buffer_use_op(
4006 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
4007 OMX_PTR p_app_data,
4008 OMX_U32 size,
4009 OMX_U8 *p_buffer)
4010 {
4011 OMX_ERRORTYPE retval = OMX_ErrorNone;
4012 SWVDEC_STATUS retval_swvdec;
4013 unsigned int ii;
4014
4015 (void) size;
4016
4017 if (m_buffer_array_op == NULL)
4018 {
4019 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
4020 m_port_op.def.nBufferCountActual,
4021 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
4022
4023 if ((retval = buffer_allocate_op_info_array()) != OMX_ErrorNone)
4024 {
4025 goto buffer_use_op_exit;
4026 }
4027 }
4028
4029 if (m_meta_buffer_mode && (m_meta_buffer_array == NULL))
4030 {
4031 OMX_SWVDEC_LOG_HIGH("allocating meta buffer info array, %d element%s",
4032 m_port_op.def.nBufferCountActual,
4033 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
4034
4035 if ((retval = meta_buffer_array_allocate()) != OMX_ErrorNone)
4036 {
4037 goto buffer_use_op_exit;
4038 }
4039 }
4040
4041 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4042 {
4043 if (m_buffer_array_op[ii].buffer_populated == false)
4044 {
4045 OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
4046 break;
4047 }
4048 }
4049
4050 if (ii < m_port_op.def.nBufferCountActual)
4051 {
4052 struct vdec_bufferpayload *p_buffer_payload;
4053
4054 SWVDEC_BUFFER *p_buffer_swvdec;
4055
4056 *pp_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
4057 p_buffer_payload = &m_buffer_array_op[ii].buffer_payload;
4058 p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
4059
4060 if (m_meta_buffer_mode)
4061 {
4062 p_buffer_swvdec->size = m_port_op.def.nBufferSize;
4063 p_buffer_swvdec->p_client_data = (void *) ((unsigned long) ii);
4064
4065 m_buffer_array_op[ii].buffer_populated = true;
4066
4067 (*pp_buffer_hdr)->pBuffer = p_buffer;
4068 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
4069 (*pp_buffer_hdr)->nAllocLen =
4070 sizeof(struct VideoDecoderOutputMetaData);
4071
4072 OMX_SWVDEC_LOG_HIGH("op buffer %d: %p (meta buffer)",
4073 ii,
4074 *pp_buffer_hdr);
4075
4076 m_port_op.populated = port_op_populated();
4077 m_port_op.unpopulated = OMX_FALSE;
4078 }
4079 else if (m_android_native_buffers)
4080 {
4081 private_handle_t *p_handle;
4082
4083 OMX_U8 *p_buffer_mapped;
4084
4085 p_handle = (private_handle_t *) p_buffer;
4086
4087 if (((OMX_U32) p_handle->size) < m_port_op.def.nBufferSize)
4088 {
4089 OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
4090 "configured size (%d bytes)",
4091 p_handle->size,
4092 m_port_op.def.nBufferSize);
4093
4094 retval = OMX_ErrorBadParameter;
4095 goto buffer_use_op_exit;
4096 }
4097
4098 m_port_op.def.nBufferSize = p_handle->size;
4099
4100 p_buffer_mapped = ion_map(p_handle->fd,p_handle->size);
4101
4102 if (p_buffer_mapped == MAP_FAILED)
4103 {
4104 OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d",
4105 p_handle->fd,
4106 p_handle->size);
4107
4108 retval = OMX_ErrorInsufficientResources;
4109 goto buffer_use_op_exit;
4110 }
4111
4112 p_buffer_payload->bufferaddr = p_buffer_mapped;
4113 p_buffer_payload->pmem_fd = p_handle->fd;
4114 p_buffer_payload->buffer_len = p_handle->size;
4115 p_buffer_payload->mmaped_size = p_handle->size;
4116 p_buffer_payload->offset = 0;
4117
4118 p_buffer_swvdec->p_buffer = p_buffer_mapped;
4119 p_buffer_swvdec->size = m_port_op.def.nBufferSize;
4120 p_buffer_swvdec->p_client_data = (void *) ((unsigned long) ii);
4121 p_buffer_swvdec->fd = p_buffer_payload->pmem_fd ;
4122
4123 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
4124 {
4125 OMX_SWVDEC_LOG_LOW("map op buffer");
4126
4127 if((retval_swvdec = swvdec_map(m_swvdec_handle,p_buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
4128 {
4129 OMX_SWVDEC_LOG_ERROR("swvdec_map failed for op buffer %d: %p",ii,p_buffer_mapped);
4130 retval = retval_swvdec2omx(retval_swvdec);;
4131 goto buffer_use_op_exit;
4132 }
4133 }
4134 m_buffer_array_op[ii].buffer_populated = true;
4135
4136 (*pp_buffer_hdr)->pBuffer = (m_android_native_buffers ?
4137 ((OMX_U8 *) p_handle) :
4138 p_buffer_mapped);
4139 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
4140 (*pp_buffer_hdr)->nAllocLen = m_port_op.def.nBufferSize;
4141
4142 m_buffer_array_op[ii].ion_info.data_fd = p_handle->fd;
4143
4144 OMX_SWVDEC_LOG_HIGH("op buffer %d: %p",
4145 ii,
4146 *pp_buffer_hdr);
4147
4148 m_port_op.populated = port_op_populated();
4149 m_port_op.unpopulated = OMX_FALSE;
4150 }
4151 else
4152 {
4153 OMX_SWVDEC_LOG_ERROR("neither 'meta buffer mode' nor "
4154 "'android native buffers' enabled");
4155
4156 retval = OMX_ErrorBadParameter;
4157 }
4158 }
4159 else
4160 {
4161 OMX_SWVDEC_LOG_ERROR("all %d op buffers populated",
4162 m_port_op.def.nBufferCountActual);
4163
4164 retval = OMX_ErrorInsufficientResources;
4165 }
4166
4167 buffer_use_op_exit:
4168 return retval;
4169 }
4170
4171 /**
4172 * @brief De-allocate input buffer.
4173 *
4174 * @param[in] p_buffer_hdr: Pointer to buffer header structure.
4175 *
4176 * @retval OMX_ERRORTYPE
4177 */
buffer_deallocate_ip(OMX_BUFFERHEADERTYPE * p_buffer_hdr)4178 OMX_ERRORTYPE omx_swvdec::buffer_deallocate_ip(
4179 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
4180 {
4181 OMX_ERRORTYPE retval = OMX_ErrorNone;
4182 SWVDEC_STATUS retval_swvdec = SWVDEC_STATUS_SUCCESS;
4183
4184 unsigned int ii;
4185
4186 if (p_buffer_hdr == NULL)
4187 {
4188 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
4189
4190 retval = OMX_ErrorBadParameter;
4191 goto buffer_deallocate_ip_exit;
4192 }
4193 else if (m_buffer_array_ip == NULL)
4194 {
4195 OMX_SWVDEC_LOG_ERROR("ip buffer array not allocated");
4196
4197 retval = OMX_ErrorBadParameter;
4198 goto buffer_deallocate_ip_exit;
4199 }
4200
4201 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
4202 {
4203 if (p_buffer_hdr == &(m_buffer_array_ip[ii].buffer_header))
4204 {
4205 OMX_SWVDEC_LOG_LOW("%p has index %d",
4206 p_buffer_hdr->pBuffer,
4207 ii);
4208 break;
4209 }
4210 }
4211
4212 if (ii < m_port_ip.def.nBufferCountActual)
4213 {
4214 if (m_buffer_array_ip[ii].buffer_payload.pmem_fd > 0)
4215 {
4216
4217 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
4218 {
4219 SWVDEC_BUFFER *p_buffer_swvdec;
4220 p_buffer_swvdec = &m_buffer_array_ip[ii].buffer_swvdec;
4221 OMX_SWVDEC_LOG_LOW("unmap ip buffer");
4222
4223 if((retval_swvdec = swvdec_unregister_buffer(m_swvdec_handle,p_buffer_swvdec))
4224 != SWVDEC_STATUS_SUCCESS)
4225 {
4226 OMX_SWVDEC_LOG_ERROR("swvdec_unmap failed for ip buffer %d: %p",
4227 ii,p_buffer_swvdec->p_buffer);
4228 retval = retval_swvdec2omx(retval_swvdec);;
4229 }
4230 }
4231
4232 m_buffer_array_ip[ii].buffer_populated = false;
4233
4234 m_port_ip.populated = OMX_FALSE;
4235
4236 ion_unmap(m_buffer_array_ip[ii].buffer_payload.pmem_fd,
4237 m_buffer_array_ip[ii].buffer_payload.bufferaddr,
4238 m_buffer_array_ip[ii].buffer_payload.mmaped_size);
4239
4240 close(m_buffer_array_ip[ii].buffer_payload.pmem_fd);
4241 m_buffer_array_ip[ii].buffer_payload.pmem_fd = -1;
4242
4243 ion_memory_free(&m_buffer_array_ip[ii].ion_info);
4244
4245 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
4246 {
4247 if (m_buffer_array_ip[ii].buffer_populated)
4248 {
4249 break;
4250 }
4251 }
4252
4253 if (ii == m_port_ip.def.nBufferCountActual)
4254 {
4255 buffer_deallocate_ip_info_array();
4256
4257 m_port_ip.unpopulated = OMX_TRUE;
4258 }
4259 }
4260 else
4261 {
4262 OMX_SWVDEC_LOG_ERROR("%p: pmem_fd %d",
4263 p_buffer_hdr->pBuffer,
4264 m_buffer_array_ip[ii].buffer_payload.pmem_fd);
4265 }
4266 }
4267 else
4268 {
4269 OMX_SWVDEC_LOG_ERROR("%p not found", p_buffer_hdr->pBuffer);
4270
4271 retval = OMX_ErrorBadParameter;
4272 }
4273
4274 buffer_deallocate_ip_exit:
4275 return retval;
4276 }
4277
4278 /**
4279 * @brief De-allocate output buffer.
4280 *
4281 * @param[in] p_buffer_hdr: Pointer to buffer header structure.
4282 *
4283 * @retval OMX_ERRORTYPE
4284 */
buffer_deallocate_op(OMX_BUFFERHEADERTYPE * p_buffer_hdr)4285 OMX_ERRORTYPE omx_swvdec::buffer_deallocate_op(
4286 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
4287 {
4288 OMX_ERRORTYPE retval = OMX_ErrorNone;
4289 SWVDEC_STATUS retval_swvdec = SWVDEC_STATUS_SUCCESS;
4290 unsigned int ii;
4291
4292 if (p_buffer_hdr == NULL)
4293 {
4294 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
4295
4296 retval = OMX_ErrorBadParameter;
4297 goto buffer_deallocate_op_exit;
4298 }
4299 else if (m_buffer_array_op == NULL)
4300 {
4301 OMX_SWVDEC_LOG_ERROR("op buffer array not allocated");
4302
4303 retval = OMX_ErrorBadParameter;
4304 goto buffer_deallocate_op_exit;
4305 }
4306
4307 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4308 {
4309 if (p_buffer_hdr == &(m_buffer_array_op[ii].buffer_header))
4310 {
4311 OMX_SWVDEC_LOG_LOW("%p has index %d",
4312 p_buffer_hdr->pBuffer,
4313 ii);
4314 break;
4315 }
4316 }
4317
4318 if (ii < m_port_op.def.nBufferCountActual)
4319 {
4320 if (m_meta_buffer_mode)
4321 {
4322 // do nothing; munmap() & FD reset done in FBD or RR
4323 }
4324 else if (m_android_native_buffers)
4325 {
4326
4327 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
4328 {
4329 SWVDEC_BUFFER *p_buffer_swvdec;
4330 p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
4331 OMX_SWVDEC_LOG_LOW("unmap op buffer");
4332
4333 if((retval_swvdec = swvdec_unmap(m_swvdec_handle,p_buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
4334 {
4335 OMX_SWVDEC_LOG_ERROR("swvdec_unmap failed for op buffer %d: %p",ii,p_buffer_swvdec->p_buffer);
4336 retval = retval_swvdec2omx(retval_swvdec);;
4337 }
4338 }
4339 ion_unmap(m_buffer_array_op[ii].buffer_payload.pmem_fd ,
4340 m_buffer_array_op[ii].buffer_payload.bufferaddr,
4341 m_buffer_array_op[ii].buffer_payload.mmaped_size);
4342
4343 m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
4344 }
4345 else
4346 {
4347 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
4348 {
4349 SWVDEC_BUFFER *p_buffer_swvdec;
4350 p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
4351 OMX_SWVDEC_LOG_LOW("unmap op buffer");
4352
4353 if((retval_swvdec = swvdec_unmap(m_swvdec_handle,p_buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
4354 {
4355 OMX_SWVDEC_LOG_ERROR("swvdec_unmap failed for op buffer %d: %p",ii,p_buffer_swvdec->p_buffer);
4356 retval = retval_swvdec2omx(retval_swvdec);;
4357 }
4358 }
4359 ion_unmap(m_buffer_array_op[ii].buffer_payload.pmem_fd,
4360 m_buffer_array_op[ii].buffer_payload.bufferaddr,
4361 m_buffer_array_op[ii].buffer_payload.mmaped_size);
4362
4363 close(m_buffer_array_op[ii].buffer_payload.pmem_fd);
4364
4365 m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
4366
4367 ion_memory_free(&m_buffer_array_op[ii].ion_info);
4368 }
4369
4370 m_buffer_array_op[ii].buffer_populated = false;
4371
4372 m_port_op.populated = OMX_FALSE;
4373
4374 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4375 {
4376 if (m_buffer_array_op[ii].buffer_populated)
4377 {
4378 break;
4379 }
4380 }
4381
4382 if (ii == m_port_op.def.nBufferCountActual)
4383 {
4384 buffer_deallocate_op_info_array();
4385
4386 m_port_op.unpopulated = OMX_TRUE;
4387
4388 if (m_meta_buffer_mode)
4389 {
4390 meta_buffer_array_deallocate();
4391 }
4392 }
4393 }
4394 else
4395 {
4396 OMX_SWVDEC_LOG_ERROR("%p not found", p_buffer_hdr->pBuffer);
4397
4398 retval = OMX_ErrorBadParameter;
4399 }
4400
4401 buffer_deallocate_op_exit:
4402 return retval;
4403 }
4404
4405 /**
4406 * @brief De-allocate input buffer info array.
4407 */
buffer_deallocate_ip_info_array()4408 void omx_swvdec::buffer_deallocate_ip_info_array()
4409 {
4410 assert(m_buffer_array_ip != NULL);
4411
4412 free(m_buffer_array_ip);
4413
4414 m_buffer_array_ip = NULL;
4415 }
4416
4417 /**
4418 * @brief De-allocate output buffer info array.
4419 */
buffer_deallocate_op_info_array()4420 void omx_swvdec::buffer_deallocate_op_info_array()
4421 {
4422 assert(m_buffer_array_op != NULL);
4423
4424 free(m_buffer_array_op);
4425
4426 m_buffer_array_op = NULL;
4427 }
4428
4429 /**
4430 * @brief Allocate meta buffer info array.
4431 *
4432 * @retval OMX_ERRORTYPE
4433 */
meta_buffer_array_allocate()4434 OMX_ERRORTYPE omx_swvdec::meta_buffer_array_allocate()
4435 {
4436 OMX_ERRORTYPE retval = OMX_ErrorNone;
4437
4438 m_meta_buffer_array = ((OMX_SWVDEC_META_BUFFER_INFO *)
4439 calloc(sizeof(OMX_SWVDEC_META_BUFFER_INFO),
4440 m_port_op.def.nBufferCountActual));
4441
4442 if (m_meta_buffer_array == NULL)
4443 {
4444 OMX_SWVDEC_LOG_ERROR("failed to allocate meta_buffer info array; "
4445 "%d element%s, %zu bytes requested",
4446 m_port_op.def.nBufferCountActual,
4447 (m_port_op.def.nBufferCountActual > 1) ? "s" : "",
4448 sizeof(OMX_SWVDEC_META_BUFFER_INFO) *
4449 m_port_op.def.nBufferCountActual);
4450
4451 retval = OMX_ErrorInsufficientResources;
4452 }
4453 else
4454 {
4455 unsigned int ii;
4456
4457 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4458 {
4459 m_meta_buffer_array[ii].fd = -1;
4460 }
4461 }
4462
4463 return retval;
4464 }
4465
4466 /**
4467 * @brief De-allocate meta buffer info array.
4468 */
meta_buffer_array_deallocate()4469 void omx_swvdec::meta_buffer_array_deallocate()
4470 {
4471 assert(m_meta_buffer_array != NULL);
4472
4473 free(m_meta_buffer_array);
4474
4475 m_meta_buffer_array = NULL;
4476 }
4477
4478 /**
4479 * @brief Add meta buffer reference.
4480 *
4481 * @param[in] index: Buffer index.
4482 * @param[in] fd: File descriptor.
4483 */
meta_buffer_ref_add(unsigned int index,int fd)4484 void omx_swvdec::meta_buffer_ref_add(unsigned int index, int fd)
4485 {
4486 if (m_meta_buffer_array[index].ref_count == 0)
4487 {
4488 m_meta_buffer_array[index].fd = fd;
4489 }
4490
4491 m_meta_buffer_array[index].ref_count++;
4492 }
4493
4494 /**
4495 * @brief Remove meta buffer reference.
4496 *
4497 * @param[in] index: Buffer index.
4498 */
meta_buffer_ref_remove(unsigned int index)4499 void omx_swvdec::meta_buffer_ref_remove(unsigned int index)
4500 {
4501 pthread_mutex_lock(&m_meta_buffer_array_mutex);
4502
4503 m_meta_buffer_array[index].ref_count--;
4504
4505 if (m_meta_buffer_array[index].ref_count == 0)
4506 {
4507 ion_unmap(m_meta_buffer_array[index].fd,
4508 m_buffer_array_op[index].buffer_payload.bufferaddr,
4509 m_buffer_array_op[index].buffer_payload.mmaped_size);
4510
4511 m_meta_buffer_array[index].fd = -1;
4512 m_buffer_array_op[index].buffer_payload.bufferaddr = NULL;
4513 m_buffer_array_op[index].buffer_payload.offset = 0;
4514 m_buffer_array_op[index].buffer_payload.mmaped_size = 0;
4515
4516 m_buffer_array_op[index].buffer_swvdec.p_buffer = NULL;
4517 m_buffer_array_op[index].buffer_swvdec.size = 0;
4518 }
4519
4520 pthread_mutex_unlock(&m_meta_buffer_array_mutex);
4521 }
4522
4523 /**
4524 * @brief Split MPEG-4 bitstream buffer into multiple frames (if they exist).
4525 *
4526 * @param[in,out] offset_array: Array of offsets to frame headers.
4527 * @param[in] p_buffer_hdr: Pointer to buffer header.
4528 *
4529 * @retval Number of frames in buffer.
4530 */
split_buffer_mpeg4(unsigned int * offset_array,OMX_BUFFERHEADERTYPE * p_buffer_hdr)4531 unsigned int split_buffer_mpeg4(unsigned int *offset_array,
4532 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
4533 {
4534 unsigned char *p_buffer = p_buffer_hdr->pBuffer;
4535
4536 unsigned int byte_count = 0;
4537
4538 unsigned int num_frame_headers = 0;
4539
4540 unsigned int next_4bytes;
4541
4542 while ((byte_count < p_buffer_hdr->nFilledLen) &&
4543 (num_frame_headers < OMX_SWVDEC_MAX_FRAMES_PER_ETB))
4544 {
4545 next_4bytes = *((unsigned int *) p_buffer);
4546
4547 next_4bytes = __builtin_bswap32(next_4bytes);
4548
4549 if (next_4bytes == 0x000001B6)
4550 {
4551 OMX_SWVDEC_LOG_HIGH("%p, buffer %p: "
4552 "frame header at %d bytes offset",
4553 p_buffer_hdr,
4554 p_buffer_hdr->pBuffer,
4555 byte_count);
4556
4557 offset_array[num_frame_headers] = byte_count;
4558
4559 num_frame_headers++;
4560
4561 p_buffer += 4;
4562 byte_count += 4;
4563 }
4564 else
4565 {
4566 p_buffer++;
4567 byte_count++;
4568 }
4569 }
4570
4571 return num_frame_headers;
4572 }
4573
4574 /**
4575 * @brief Check if ip port is populated, i.e., if all ip buffers are populated.
4576 *
4577 * @retval true
4578 * @retval false
4579 */
port_ip_populated()4580 OMX_BOOL omx_swvdec::port_ip_populated()
4581 {
4582 OMX_BOOL retval = OMX_FALSE;
4583
4584 if (m_buffer_array_ip != NULL)
4585 {
4586 unsigned int ii;
4587
4588 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
4589 {
4590 if (m_buffer_array_ip[ii].buffer_populated == false)
4591 {
4592 break;
4593 }
4594 }
4595
4596 if (ii == m_port_ip.def.nBufferCountActual)
4597 {
4598 retval = OMX_TRUE;
4599 }
4600 }
4601
4602 return retval;
4603 }
4604
4605 /**
4606 * @brief Check if op port is populated, i.e., if all op buffers are populated.
4607 *
4608 * @retval true
4609 * @retval false
4610 */
port_op_populated()4611 OMX_BOOL omx_swvdec::port_op_populated()
4612 {
4613 OMX_BOOL retval = OMX_FALSE;
4614
4615 if (m_buffer_array_op != NULL)
4616 {
4617 unsigned int ii;
4618
4619 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4620 {
4621 if (m_buffer_array_op[ii].buffer_populated == false)
4622 {
4623 break;
4624 }
4625 }
4626
4627 if (ii == m_port_op.def.nBufferCountActual)
4628 {
4629 retval = OMX_TRUE;
4630 }
4631 }
4632
4633 return retval;
4634 }
4635
4636 /**
4637 * @brief Flush input, output, or both input & output ports.
4638 *
4639 * @param[in] port_index: Index of port to flush.
4640 *
4641 * @retval OMX_ERRORTYPE
4642 */
flush(unsigned int port_index)4643 OMX_ERRORTYPE omx_swvdec::flush(unsigned int port_index)
4644 {
4645 OMX_ERRORTYPE retval = OMX_ErrorNone;
4646
4647 if (((port_index == OMX_CORE_PORT_INDEX_IP) &&
4648 m_port_ip.flush_inprogress) ||
4649 ((port_index == OMX_CORE_PORT_INDEX_OP) &&
4650 m_port_op.flush_inprogress) ||
4651 ((port_index == OMX_ALL) &&
4652 m_port_ip.flush_inprogress &&
4653 m_port_op.flush_inprogress))
4654 {
4655 OMX_SWVDEC_LOG_HIGH("flush port index %d already in progress",
4656 port_index);
4657 }
4658 else
4659 {
4660 SWVDEC_FLUSH_TYPE swvdec_flush_type;
4661
4662 SWVDEC_STATUS retval_swvdec;
4663
4664 if (port_index == OMX_CORE_PORT_INDEX_IP)
4665 {
4666 m_port_ip.flush_inprogress = OMX_TRUE;
4667
4668 //for VTS test case IP flush , trigger flush all
4669 // for IP flush, similar behavior is for hwcodecs
4670 m_port_ip.flush_inprogress = OMX_TRUE;
4671 m_port_op.flush_inprogress = OMX_TRUE;
4672
4673 swvdec_flush_type = SWVDEC_FLUSH_TYPE_ALL;
4674
4675 if ((retval_swvdec = swvdec_flush(m_swvdec_handle,
4676 swvdec_flush_type)) !=
4677 SWVDEC_STATUS_SUCCESS)
4678 {
4679 retval = retval_swvdec2omx(retval_swvdec);
4680 }
4681 }
4682 else if (port_index == OMX_CORE_PORT_INDEX_OP)
4683 {
4684 m_port_op.flush_inprogress = OMX_TRUE;
4685
4686 swvdec_flush_type = (m_port_ip.flush_inprogress ?
4687 SWVDEC_FLUSH_TYPE_ALL :
4688 SWVDEC_FLUSH_TYPE_OP);
4689
4690 if ((retval_swvdec = swvdec_flush(m_swvdec_handle,
4691 swvdec_flush_type)) !=
4692 SWVDEC_STATUS_SUCCESS)
4693 {
4694 retval = retval_swvdec2omx(retval_swvdec);
4695 }
4696 }
4697 else if (port_index == OMX_ALL)
4698 {
4699 m_port_ip.flush_inprogress = OMX_TRUE;
4700 m_port_op.flush_inprogress = OMX_TRUE;
4701
4702 swvdec_flush_type = SWVDEC_FLUSH_TYPE_ALL;
4703
4704 if ((retval_swvdec = swvdec_flush(m_swvdec_handle,
4705 swvdec_flush_type)) !=
4706 SWVDEC_STATUS_SUCCESS)
4707 {
4708 retval = retval_swvdec2omx(retval_swvdec);
4709 }
4710 }
4711 else
4712 {
4713 assert(0);
4714 }
4715 }
4716
4717 return retval;
4718 }
4719
4720 /**
4721 * @brief Allocate & map ION memory.
4722 */
ion_memory_alloc_map(vdec_ion * p_ion_info,OMX_U32 size,OMX_U32 alignment)4723 int omx_swvdec::ion_memory_alloc_map(vdec_ion *p_ion_info, OMX_U32 size, OMX_U32 alignment)
4724 {
4725 int rc = -EINVAL;
4726
4727 if((!p_ion_info) || (size == 0))
4728 {
4729 OMX_SWVDEC_LOG_ERROR("invalid arguments");
4730 goto ion_memory_alloc_map_exit;
4731 }
4732
4733 p_ion_info->dev_fd = -EINVAL;
4734
4735 if ((p_ion_info->dev_fd = ion_open()) < 0)
4736 {
4737 OMX_SWVDEC_LOG_ERROR("failed to open ion device; fd = %d", p_ion_info->dev_fd);
4738 goto ion_memory_alloc_map_exit;
4739 }
4740
4741 p_ion_info->alloc_data.len = size;
4742 p_ion_info->alloc_data.heap_id_mask = ION_HEAP(ION_SYSTEM_HEAP_ID);
4743 p_ion_info->alloc_data.flags = 0;//check if ION_FLAG_CACHED need to be set;
4744 alignment = ALIGN(alignment,4096);
4745
4746 OMX_SWVDEC_LOG_LOW("heap_id_mask 0x%08x, len %zu",
4747 p_ion_info->alloc_data.heap_id_mask,
4748 p_ion_info->alloc_data.len);
4749
4750 rc = ion_alloc_fd(p_ion_info->dev_fd, p_ion_info->alloc_data.len, alignment,
4751 p_ion_info->alloc_data.heap_id_mask, p_ion_info->alloc_data.flags,
4752 &p_ion_info->data_fd);
4753
4754 if (rc || p_ion_info->data_fd == 0)
4755 {
4756 OMX_SWVDEC_LOG_ERROR("ion_alloc_fd() for allocation failed");
4757 ion_close(p_ion_info->dev_fd);
4758 p_ion_info->data_fd = -1;
4759 p_ion_info->dev_fd = -1;
4760 goto ion_memory_alloc_map_exit;
4761 }
4762
4763
4764 OMX_SWVDEC_LOG_HIGH("Alloc ion memory: fd (dev:%d data:%d) len %d flags %#x mask %#x",
4765 p_ion_info->dev_fd, p_ion_info->data_fd, (unsigned int)p_ion_info->alloc_data.len,
4766 (unsigned int)p_ion_info->alloc_data.flags,
4767 (unsigned int)p_ion_info->alloc_data.heap_id_mask);
4768
4769 ion_memory_alloc_map_exit:
4770 return (p_ion_info == nullptr) ? -EINVAL : p_ion_info->dev_fd;
4771 }
4772
4773 /**
4774 * @brief Free ION memory.
4775 */
ion_memory_free(struct vdec_ion * p_ion_buf_info)4776 void omx_swvdec::ion_memory_free(struct vdec_ion *p_ion_buf_info)
4777 {
4778 if (p_ion_buf_info == NULL)
4779 {
4780 OMX_SWVDEC_LOG_ERROR("p_ion_buf_info = NULL");
4781 goto ion_memory_free_exit;
4782 }
4783
4784 OMX_SWVDEC_LOG_HIGH("Free ion memory: map fd %d ion_dev fd %d len %d flags %#x mask %#x",
4785 p_ion_buf_info->data_fd, p_ion_buf_info->dev_fd,
4786 (unsigned int)p_ion_buf_info->alloc_data.len,
4787 (unsigned int)p_ion_buf_info->alloc_data.flags,
4788 (unsigned int)p_ion_buf_info->alloc_data.heap_id_mask);
4789
4790 if (p_ion_buf_info->data_fd >= 0) {
4791 close(p_ion_buf_info->data_fd);
4792 p_ion_buf_info->data_fd = -1;
4793 }
4794
4795 if (p_ion_buf_info->dev_fd >= 0) {
4796 ion_close(p_ion_buf_info->dev_fd);
4797 p_ion_buf_info->dev_fd = -1;
4798 }
4799
4800 ion_memory_free_exit:
4801 return;
4802 }
4803
4804 /**
4805 * @brief Flush cached ION output buffer.
4806 *
4807 * @param[in] index: Index of buffer in output buffer info array.
4808 */
ion_flush_op(unsigned int index)4809 void omx_swvdec::ion_flush_op(unsigned int index)
4810 {
4811 if (index < m_port_op.def.nBufferCountActual)
4812 {
4813 #ifdef USE_ION
4814 struct dma_buf_sync dma_buf_sync_data[2];
4815 dma_buf_sync_data[0].flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_WRITE;
4816 dma_buf_sync_data[1].flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_WRITE;
4817
4818 for (unsigned int i=0; i<2; i++)
4819 {
4820 int ret = ioctl(m_buffer_array_op[index].buffer_swvdec.fd,
4821 DMA_BUF_IOCTL_SYNC, &dma_buf_sync_data[i]);
4822 if (ret < 0)
4823 {
4824 OMX_SWVDEC_LOG_ERROR("Cache %s failed for fd %d : %s\n",
4825 (i==0) ? "START" : "END",
4826 m_buffer_array_op[index].buffer_swvdec.fd,
4827 strerror(errno));
4828 goto ion_flush_op_exit;
4829 }
4830 }
4831 #endif
4832 }
4833 else
4834 {
4835 OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
4836 }
4837
4838 ion_flush_op_exit:
4839 return;
4840 }
4841
4842
4843 /**
4844 * ----------------------------
4845 * component callback functions
4846 * ----------------------------
4847 */
4848
4849 /**
4850 * @brief Empty buffer done callback.
4851 *
4852 * @param[in] p_buffer_ip: Pointer to input buffer structure.
4853 */
swvdec_empty_buffer_done(SWVDEC_BUFFER * p_buffer_ip)4854 void omx_swvdec::swvdec_empty_buffer_done(SWVDEC_BUFFER *p_buffer_ip)
4855 {
4856 unsigned long index = (unsigned long) p_buffer_ip->p_client_data;
4857
4858 m_buffer_array_ip[index].buffer_header.nFilledLen =
4859 p_buffer_ip->filled_length;
4860
4861 async_post_event(OMX_SWVDEC_EVENT_EBD,
4862 (unsigned long) &m_buffer_array_ip[index].buffer_header,
4863 index);
4864 }
4865
4866 /**
4867 * @brief Fill buffer done callback.
4868 *
4869 * @param[in] p_buffer_op: Pointer to output buffer structure.
4870 */
swvdec_fill_buffer_done(SWVDEC_BUFFER * p_buffer_op)4871 void omx_swvdec::swvdec_fill_buffer_done(SWVDEC_BUFFER *p_buffer_op)
4872 {
4873 unsigned long index = (unsigned long) p_buffer_op->p_client_data;
4874
4875 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
4876
4877 if (index < ((unsigned long) m_port_op.def.nBufferCountActual))
4878 {
4879 p_buffer_hdr = &m_buffer_array_op[index].buffer_header;
4880
4881 p_buffer_hdr->nFlags = p_buffer_op->flags;
4882 p_buffer_hdr->nTimeStamp = p_buffer_op->timestamp;
4883 p_buffer_hdr->nFilledLen = ((m_meta_buffer_mode &&
4884 p_buffer_op->filled_length) ?
4885 p_buffer_hdr->nAllocLen :
4886 p_buffer_op->filled_length);
4887 }
4888
4889 async_post_event(OMX_SWVDEC_EVENT_FBD,
4890 (unsigned long) &m_buffer_array_op[index].buffer_header,
4891 index);
4892 }
4893
4894 /**
4895 * @brief Event handler callback.
4896 *
4897 * @param[in] event: Event.
4898 * @param[in] p_data: Pointer to event-specific data.
4899 */
swvdec_event_handler(SWVDEC_EVENT event,void * p_data)4900 void omx_swvdec::swvdec_event_handler(SWVDEC_EVENT event, void *p_data)
4901 {
4902 switch (event)
4903 {
4904
4905 case SWVDEC_EVENT_FLUSH_ALL_DONE:
4906 {
4907 async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_IP, 0, 0);
4908 async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_OP, 0, 0);
4909
4910 break;
4911 }
4912
4913 case SWVDEC_EVENT_FLUSH_OP_DONE:
4914 {
4915 async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_OP, 0, 0);
4916
4917 break;
4918 }
4919
4920 case SWVDEC_EVENT_RELEASE_REFERENCE:
4921 {
4922 SWVDEC_BUFFER *p_buffer_op = (SWVDEC_BUFFER *) p_data;
4923
4924 unsigned long index = (unsigned long) p_buffer_op->p_client_data;
4925
4926 OMX_SWVDEC_LOG_LOW("release reference: %p", p_buffer_op->p_buffer);
4927
4928 assert(index < ((unsigned long) m_port_op.def.nBufferCountActual));
4929
4930 if (m_meta_buffer_mode)
4931 {
4932 meta_buffer_ref_remove(index);
4933 }
4934
4935 break;
4936 }
4937
4938 case SWVDEC_EVENT_RECONFIG_REQUIRED:
4939 {
4940 async_post_event(OMX_SWVDEC_EVENT_PORT_RECONFIG, 0, 0);
4941
4942 break;
4943 }
4944
4945 case SWVDEC_EVENT_DIMENSIONS_UPDATED:
4946 {
4947 async_post_event(OMX_SWVDEC_EVENT_DIMENSIONS_UPDATED, 0, 0);
4948
4949 break;
4950 }
4951
4952 case SWVDEC_EVENT_FATAL_ERROR:
4953 default:
4954 {
4955 async_post_event(OMX_SWVDEC_EVENT_ERROR, OMX_ErrorHardware, 0);
4956
4957 break;
4958 }
4959
4960 }
4961 }
4962
4963 /**
4964 * @brief Translate SwVdec status return value to OMX error type return value.
4965 *
4966 * @param[in] retval_swvdec: SwVdec status return value.
4967 *
4968 * @retval OMX_ERRORTYPE
4969 */
retval_swvdec2omx(SWVDEC_STATUS retval_swvdec)4970 OMX_ERRORTYPE omx_swvdec::retval_swvdec2omx(SWVDEC_STATUS retval_swvdec)
4971 {
4972 OMX_ERRORTYPE retval_omx;
4973
4974 switch (retval_swvdec) {
4975 case SWVDEC_STATUS_SUCCESS:
4976 retval_omx = OMX_ErrorNone;
4977 break;
4978
4979 case SWVDEC_STATUS_FAILURE:
4980 retval_omx = OMX_ErrorUndefined;
4981 break;
4982
4983 case SWVDEC_STATUS_NULL_POINTER:
4984 case SWVDEC_STATUS_INVALID_PARAMETERS:
4985 retval_omx = OMX_ErrorBadParameter;
4986 break;
4987
4988 case SWVDEC_STATUS_INVALID_STATE:
4989 retval_omx = OMX_ErrorInvalidState;
4990 break;
4991
4992 case SWVDEC_STATUS_INSUFFICIENT_RESOURCES:
4993 retval_omx = OMX_ErrorInsufficientResources;
4994 break;
4995
4996 case SWVDEC_STATUS_UNSUPPORTED:
4997 retval_omx = OMX_ErrorUnsupportedSetting;
4998 break;
4999
5000 case SWVDEC_STATUS_NOT_IMPLEMENTED:
5001 retval_omx = OMX_ErrorNotImplemented;
5002 break;
5003
5004 default:
5005 retval_omx = OMX_ErrorUndefined;
5006 break;
5007 }
5008
5009 return retval_omx;
5010 }
5011
5012 /**
5013 * @brief Create asynchronous thread.
5014 *
5015 * @retval OMX_ERRORTYPE
5016 */
async_thread_create()5017 OMX_ERRORTYPE omx_swvdec::async_thread_create()
5018 {
5019 OMX_ERRORTYPE retval = OMX_ErrorNone;
5020
5021 pthread_attr_t thread_attributes;
5022
5023 if (sem_init(&m_async_thread.sem_thread_created, 0, 0))
5024 {
5025 OMX_SWVDEC_LOG_ERROR("failed to create async thread created semaphore");
5026
5027 retval = OMX_ErrorInsufficientResources;
5028 }
5029 else if (sem_init(&m_async_thread.sem_event, 0, 0))
5030 {
5031 OMX_SWVDEC_LOG_ERROR("failed to create async thread event semaphore");
5032
5033 retval = OMX_ErrorInsufficientResources;
5034 }
5035 else if (pthread_attr_init(&thread_attributes))
5036 {
5037 OMX_SWVDEC_LOG_ERROR("failed to create thread attributes object");
5038
5039 retval = OMX_ErrorInsufficientResources;
5040 }
5041 else if (pthread_attr_setdetachstate(&thread_attributes,
5042 PTHREAD_CREATE_JOINABLE))
5043 {
5044 OMX_SWVDEC_LOG_ERROR("failed to set detach state attribute");
5045
5046 retval = OMX_ErrorInsufficientResources;
5047
5048 pthread_attr_destroy(&thread_attributes);
5049 }
5050 else
5051 {
5052 m_async_thread.created = false;
5053 m_async_thread.exit = false;
5054
5055 if (pthread_create(&m_async_thread.handle,
5056 &thread_attributes,
5057 (void *(*)(void *)) async_thread,
5058 this))
5059 {
5060 OMX_SWVDEC_LOG_ERROR("failed to create async thread");
5061
5062 retval = OMX_ErrorInsufficientResources;
5063
5064 pthread_attr_destroy(&thread_attributes);
5065 }
5066 else
5067 {
5068 if (pthread_setname_np(m_async_thread.handle, "swvdec_async"))
5069 {
5070 // don't return error
5071 OMX_SWVDEC_LOG_ERROR("failed to set async thread name");
5072 }
5073
5074 sem_wait(&m_async_thread.sem_thread_created);
5075
5076 m_async_thread.created = true;
5077 }
5078 }
5079
5080 return retval;
5081 }
5082
5083 /**
5084 * @brief Destroy asynchronous thread.
5085 */
async_thread_destroy()5086 void omx_swvdec::async_thread_destroy()
5087 {
5088 if (m_async_thread.created)
5089 {
5090 m_async_thread.exit = true;
5091
5092 sem_post(&m_async_thread.sem_event);
5093
5094 pthread_join(m_async_thread.handle, NULL);
5095
5096 m_async_thread.created = false;
5097 }
5098
5099 m_async_thread.exit = false;
5100
5101 sem_destroy(&m_async_thread.sem_event);
5102 sem_destroy(&m_async_thread.sem_thread_created);
5103 }
5104
5105 /**
5106 * @brief Post event to appropriate queue.
5107 *
5108 * @param[in] event_id: Event ID.
5109 * @param[in] event_param1: Event parameter 1.
5110 * @param[in] event_param2: Event parameter 2.
5111 */
async_post_event(unsigned long event_id,unsigned long event_param1,unsigned long event_param2)5112 void omx_swvdec::async_post_event(unsigned long event_id,
5113 unsigned long event_param1,
5114 unsigned long event_param2)
5115 {
5116 OMX_SWVDEC_EVENT_INFO event_info;
5117
5118 event_info.event_id = event_id;
5119 event_info.event_param1 = event_param1;
5120 event_info.event_param2 = event_param2;
5121
5122 switch (event_id)
5123 {
5124
5125 case OMX_SWVDEC_EVENT_ETB:
5126 case OMX_SWVDEC_EVENT_EBD:
5127 {
5128 m_queue_port_ip.push(&event_info);
5129 break;
5130 }
5131
5132 case OMX_SWVDEC_EVENT_FTB:
5133 case OMX_SWVDEC_EVENT_FBD:
5134 {
5135 m_queue_port_op.push(&event_info);
5136 break;
5137 }
5138
5139 default:
5140 {
5141 m_queue_command.push(&event_info);
5142 break;
5143 }
5144
5145 }
5146
5147 sem_post(&m_async_thread.sem_event);
5148 }
5149
5150 /**
5151 * @brief Asynchronous thread.
5152 *
5153 * @param[in] p_cmp: Pointer to OMX SwVdec component class.
5154 */
async_thread(void * p_cmp)5155 void omx_swvdec::async_thread(void *p_cmp)
5156 {
5157 if (p_cmp == NULL)
5158 {
5159 OMX_SWVDEC_LOG_ERROR("p_cmp = NULL");
5160 }
5161 else
5162 {
5163 omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_cmp;
5164
5165 ASYNC_THREAD *p_async_thread = &p_omx_swvdec->m_async_thread;
5166
5167 OMX_SWVDEC_LOG_HIGH("created");
5168
5169 sem_post(&p_async_thread->sem_thread_created);
5170
5171 while (p_async_thread->exit == false)
5172 {
5173 sem_wait(&p_async_thread->sem_event);
5174
5175 if (p_async_thread->exit == true)
5176 {
5177 break;
5178 }
5179
5180 p_omx_swvdec->async_process_event(p_cmp);
5181 }
5182 }
5183
5184 OMX_SWVDEC_LOG_HIGH("exiting");
5185 }
5186
5187 /**
5188 * @brief Process event.
5189 *
5190 * @param[in] p_cmp: Pointer to OMX SwVdec component class.
5191 */
async_process_event(void * p_cmp)5192 void omx_swvdec::async_process_event(void *p_cmp)
5193 {
5194 omx_swvdec *p_omx_swvdec;
5195
5196 OMX_SWVDEC_EVENT_INFO event_info;
5197
5198 OMX_ERRORTYPE retval = OMX_ErrorNone;
5199
5200 if (p_cmp == NULL)
5201 {
5202 OMX_SWVDEC_LOG_ERROR("p_cmp = NULL");
5203
5204 goto async_process_event_exit;
5205 }
5206
5207 p_omx_swvdec = (omx_swvdec *) p_cmp;
5208
5209 // NOTE: queues popped in order of priority; do not change!
5210
5211 if ((p_omx_swvdec->m_queue_command.pop(&event_info) == false) &&
5212 (p_omx_swvdec->m_queue_port_op.pop(&event_info) == false) &&
5213 (p_omx_swvdec->m_queue_port_ip.pop(&event_info) == false))
5214 {
5215 OMX_SWVDEC_LOG_LOW("no event popped");
5216
5217 goto async_process_event_exit;
5218 }
5219
5220 switch (event_info.event_id)
5221 {
5222
5223 case OMX_SWVDEC_EVENT_CMD:
5224 {
5225 OMX_COMMANDTYPE cmd = (OMX_COMMANDTYPE) event_info.event_param1;
5226 OMX_U32 param = (OMX_U32) event_info.event_param2;
5227
5228 retval = p_omx_swvdec->async_process_event_cmd(cmd, param);
5229 break;
5230 }
5231
5232 case OMX_SWVDEC_EVENT_CMD_ACK:
5233 {
5234 OMX_COMMANDTYPE cmd = (OMX_COMMANDTYPE) event_info.event_param1;
5235 OMX_U32 param = (OMX_U32) event_info.event_param2;
5236
5237 retval = p_omx_swvdec->async_process_event_cmd_ack(cmd, param);
5238 break;
5239 }
5240
5241 case OMX_SWVDEC_EVENT_ERROR:
5242 {
5243 OMX_ERRORTYPE error_code = (OMX_ERRORTYPE) event_info.event_param1;
5244
5245 retval = p_omx_swvdec->async_process_event_error(error_code);
5246 break;
5247 }
5248
5249 case OMX_SWVDEC_EVENT_ETB:
5250 {
5251 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5252 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5253
5254 unsigned int index = event_info.event_param2;
5255
5256 retval = p_omx_swvdec->async_process_event_etb(p_buffer_hdr, index);
5257 break;
5258 }
5259
5260 case OMX_SWVDEC_EVENT_FTB:
5261 {
5262 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5263 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5264
5265 unsigned int index = event_info.event_param2;
5266
5267 retval = p_omx_swvdec->async_process_event_ftb(p_buffer_hdr, index);
5268 break;
5269 }
5270
5271 case OMX_SWVDEC_EVENT_EBD:
5272 {
5273 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5274 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5275
5276 unsigned int index = event_info.event_param2;
5277
5278 retval = p_omx_swvdec->async_process_event_ebd(p_buffer_hdr, index);
5279 break;
5280 }
5281
5282 case OMX_SWVDEC_EVENT_FBD:
5283 {
5284 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5285 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5286
5287 unsigned int index = event_info.event_param2;
5288
5289 retval = p_omx_swvdec->async_process_event_fbd(p_buffer_hdr, index);
5290 break;
5291 }
5292
5293 case OMX_SWVDEC_EVENT_EOS:
5294 {
5295 retval = p_omx_swvdec->async_process_event_eos();
5296 break;
5297 }
5298
5299 case OMX_SWVDEC_EVENT_FLUSH_PORT_IP:
5300 {
5301 retval = p_omx_swvdec->async_process_event_flush_port_ip();
5302 break;
5303 }
5304
5305 case OMX_SWVDEC_EVENT_FLUSH_PORT_OP:
5306 {
5307 retval = p_omx_swvdec->async_process_event_flush_port_op();
5308 break;
5309 }
5310
5311 case OMX_SWVDEC_EVENT_PORT_RECONFIG:
5312 {
5313 retval = p_omx_swvdec->async_process_event_port_reconfig();
5314 break;
5315 }
5316
5317 case OMX_SWVDEC_EVENT_DIMENSIONS_UPDATED:
5318 {
5319 retval = p_omx_swvdec->async_process_event_dimensions_updated();
5320 break;
5321 }
5322
5323 default:
5324 {
5325 assert(0);
5326
5327 retval = OMX_ErrorUndefined;
5328 break;
5329 }
5330
5331 }
5332
5333 if (retval != OMX_ErrorNone)
5334 {
5335 p_omx_swvdec->async_post_event(OMX_SWVDEC_EVENT_ERROR, retval, 0);
5336 }
5337
5338 async_process_event_exit:
5339 return;
5340 }
5341
5342 /**
5343 * @brief Process command event.
5344 *
5345 * @param[in] cmd: Command.
5346 * @param[in] param: Command parameter.
5347 *
5348 * @retval OMX_ERRORTYPE
5349 */
async_process_event_cmd(OMX_COMMANDTYPE cmd,OMX_U32 param)5350 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd(OMX_COMMANDTYPE cmd,
5351 OMX_U32 param)
5352 {
5353 OMX_ERRORTYPE retval = OMX_ErrorNone;
5354
5355 bool cmd_ack = false;
5356
5357 switch (cmd)
5358 {
5359
5360 case OMX_CommandStateSet:
5361 {
5362 retval = async_process_event_cmd_state_set(&cmd_ack,
5363 (OMX_STATETYPE) param);
5364 break;
5365 }
5366
5367 case OMX_CommandFlush:
5368 {
5369 retval = async_process_event_cmd_flush((unsigned int) param);
5370 break;
5371 }
5372
5373 case OMX_CommandPortDisable:
5374 {
5375 retval = async_process_event_cmd_port_disable(&cmd_ack,
5376 (unsigned int) param);
5377 break;
5378 }
5379
5380 case OMX_CommandPortEnable:
5381 {
5382 retval = async_process_event_cmd_port_enable(&cmd_ack,
5383 (unsigned int) param);
5384 break;
5385 }
5386
5387 default:
5388 {
5389 OMX_SWVDEC_LOG_ERROR("cmd '%d' invalid", (int) cmd);
5390
5391 retval = OMX_ErrorBadParameter;
5392 break;
5393 }
5394
5395 } // switch (cmd)
5396
5397 if (retval != OMX_ErrorNone)
5398 {
5399 async_post_event(OMX_SWVDEC_EVENT_ERROR, retval, 0);
5400 }
5401 else if (cmd_ack)
5402 {
5403 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK, cmd, param);
5404 }
5405
5406 sem_post(&m_sem_cmd);
5407
5408 return retval;
5409 }
5410
5411 /**
5412 * @brief Process command acknowledgement event.
5413 *
5414 * @param[in] cmd: Command.
5415 * @param[in] param: Command parameter.
5416 *
5417 * @retval OMX_ERRORTYPE
5418 */
async_process_event_cmd_ack(OMX_COMMANDTYPE cmd,OMX_U32 param)5419 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_ack(OMX_COMMANDTYPE cmd,
5420 OMX_U32 param)
5421 {
5422 OMX_ERRORTYPE retval = OMX_ErrorNone;
5423
5424 switch (cmd)
5425 {
5426
5427 case OMX_CommandStateSet:
5428 {
5429 OMX_SWVDEC_LOG_HIGH("%s -> %s",
5430 OMX_STATETYPE_STRING(m_state),
5431 OMX_STATETYPE_STRING((OMX_STATETYPE) param));
5432
5433 m_state = (OMX_STATETYPE) param;
5434
5435 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventCmdComplete, "
5436 "OMX_CommandStateSet, %s",
5437 OMX_STATETYPE_STRING(m_state));
5438
5439 m_callback.EventHandler(&m_cmp,
5440 m_app_data,
5441 OMX_EventCmdComplete,
5442 OMX_CommandStateSet,
5443 (OMX_U32) m_state,
5444 NULL);
5445 break;
5446 }
5447
5448 case OMX_CommandFlush:
5449 case OMX_CommandPortEnable:
5450 case OMX_CommandPortDisable:
5451 {
5452 if ((cmd == OMX_CommandPortEnable) && m_port_reconfig_inprogress)
5453 {
5454 m_port_reconfig_inprogress = false;
5455 }
5456
5457 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventCmdComplete, "
5458 "%s, port index %d",
5459 OMX_COMMANDTYPE_STRING(cmd),
5460 param);
5461
5462 m_callback.EventHandler(&m_cmp,
5463 m_app_data,
5464 OMX_EventCmdComplete,
5465 cmd,
5466 param,
5467 NULL);
5468 break;
5469 }
5470
5471 default:
5472 {
5473 OMX_SWVDEC_LOG_ERROR("cmd '%d' invalid", (int) cmd);
5474
5475 retval = OMX_ErrorBadParameter;
5476 break;
5477 }
5478
5479 } // switch (cmd)
5480
5481 return retval;
5482 }
5483
5484 /**
5485 * @brief Process error event.
5486 *
5487 * @param[in] error_code: Error code.
5488 *
5489 * @retval OMX_ErrorNone
5490 */
async_process_event_error(OMX_ERRORTYPE error_code)5491 OMX_ERRORTYPE omx_swvdec::async_process_event_error(OMX_ERRORTYPE error_code)
5492 {
5493 if (error_code == OMX_ErrorInvalidState)
5494 {
5495 OMX_SWVDEC_LOG_HIGH("%s -> OMX_StateInvalid",
5496 OMX_STATETYPE_STRING(m_state));
5497
5498 m_state = OMX_StateInvalid;
5499 }
5500
5501 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventError, 0x%08x",
5502 error_code);
5503
5504 m_callback.EventHandler(&m_cmp,
5505 m_app_data,
5506 OMX_EventError,
5507 (OMX_U32) error_code,
5508 0,
5509 NULL);
5510
5511 return OMX_ErrorNone;
5512 }
5513
5514 /**
5515 * @brief Process OMX_CommandStateSet.
5516 *
5517 * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
5518 * @param[in] state_new: New state to which transition is requested.
5519 *
5520 * @retval OMX_ERRORTYPE
5521 */
async_process_event_cmd_state_set(bool * p_cmd_ack,OMX_STATETYPE state_new)5522 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_state_set(
5523 bool *p_cmd_ack,
5524 OMX_STATETYPE state_new)
5525 {
5526 OMX_ERRORTYPE retval = OMX_ErrorNone;
5527
5528 SWVDEC_STATUS retval_swvdec;
5529
5530 OMX_SWVDEC_LOG_HIGH("'%s-to-%s' requested",
5531 OMX_STATETYPE_STRING(m_state),
5532 OMX_STATETYPE_STRING(state_new));
5533
5534 /**
5535 * Only the following state transitions are allowed via CommandStateSet:
5536 *
5537 * LOADED -> IDLE -> EXECUTING
5538 * LOADED <- IDLE <- EXECUTING
5539 */
5540
5541 if (m_state == OMX_StateInvalid)
5542 {
5543 OMX_SWVDEC_LOG_ERROR("in state %s", OMX_STATETYPE_STRING(m_state));
5544
5545 retval = OMX_ErrorInvalidState;
5546 }
5547 else if (state_new == OMX_StateInvalid)
5548 {
5549 OMX_SWVDEC_LOG_ERROR("requested transition to state %s",
5550 OMX_STATETYPE_STRING(state_new));
5551
5552 retval = OMX_ErrorInvalidState;
5553 }
5554 else if ((m_state == OMX_StateLoaded) &&
5555 (state_new == OMX_StateIdle))
5556 {
5557 if ((m_port_ip.populated == OMX_TRUE) &&
5558 (m_port_op.populated == OMX_TRUE))
5559 {
5560 if ((retval_swvdec = swvdec_start(m_swvdec_handle)) ==
5561 SWVDEC_STATUS_SUCCESS)
5562 {
5563 *p_cmd_ack = true;
5564 }
5565 else
5566 {
5567 OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
5568
5569 retval = retval_swvdec2omx(retval_swvdec);
5570 }
5571 }
5572 else
5573 {
5574 m_status_flags |= (1 << PENDING_STATE_LOADED_TO_IDLE);
5575
5576 OMX_SWVDEC_LOG_LOW("'loaded-to-idle' pending");
5577 }
5578 }
5579 else if ((m_state == OMX_StateIdle) &&
5580 (state_new == OMX_StateExecuting))
5581 {
5582 *p_cmd_ack = true;
5583 }
5584 else if ((m_state == OMX_StateExecuting) &&
5585 (state_new == OMX_StateIdle))
5586 {
5587 m_status_flags |= (1 << PENDING_STATE_EXECUTING_TO_IDLE);
5588
5589 OMX_SWVDEC_LOG_LOW("'executing-to-idle' pending");
5590
5591 retval = flush(OMX_ALL);
5592 }
5593 else if ((m_state == OMX_StateIdle) &&
5594 (state_new == OMX_StateLoaded))
5595 {
5596 if ((m_port_ip.unpopulated == OMX_TRUE) &&
5597 (m_port_op.unpopulated == OMX_TRUE))
5598 {
5599 if ((retval_swvdec = swvdec_stop(m_swvdec_handle)) ==
5600 SWVDEC_STATUS_SUCCESS)
5601 {
5602 *p_cmd_ack = true;
5603 }
5604 else
5605 {
5606 OMX_SWVDEC_LOG_ERROR("failed to stop SwVdec");
5607
5608 retval = retval_swvdec2omx(retval_swvdec);
5609 }
5610 }
5611 else
5612 {
5613 m_status_flags |= (1 << PENDING_STATE_IDLE_TO_LOADED);
5614
5615 OMX_SWVDEC_LOG_LOW("'idle-to-loaded' pending");
5616 }
5617 }
5618 else
5619 {
5620 OMX_SWVDEC_LOG_ERROR("state transition '%s -> %s' illegal",
5621 OMX_STATETYPE_STRING(m_state),
5622 OMX_STATETYPE_STRING(state_new));
5623
5624 retval = ((state_new == m_state) ?
5625 OMX_ErrorSameState :
5626 OMX_ErrorIncorrectStateTransition);
5627 }
5628
5629 return retval;
5630 }
5631
5632 /**
5633 * @brief Process OMX_CommandFlush.
5634 *
5635 * @param[in] port_index: Index of port to flush.
5636 *
5637 * @retval OMX_ERRORTYPE
5638 */
async_process_event_cmd_flush(unsigned int port_index)5639 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_flush(unsigned int port_index)
5640 {
5641 OMX_ERRORTYPE retval = OMX_ErrorNone;
5642
5643 OMX_SWVDEC_LOG_HIGH("flush port index %d requested", port_index);
5644
5645 if (port_index == OMX_CORE_PORT_INDEX_IP)
5646 {
5647 m_status_flags |= (1 << PENDING_PORT_FLUSH_IP);
5648
5649 OMX_SWVDEC_LOG_LOW("ip port flush pending");
5650 }
5651 else if (port_index == OMX_CORE_PORT_INDEX_OP)
5652 {
5653 m_status_flags |= (1 << PENDING_PORT_FLUSH_OP);
5654
5655 OMX_SWVDEC_LOG_LOW("op port flush pending");
5656 }
5657 else if (port_index == OMX_ALL)
5658 {
5659 m_status_flags |= (1 << PENDING_PORT_FLUSH_IP);
5660 m_status_flags |= (1 << PENDING_PORT_FLUSH_OP);
5661
5662 OMX_SWVDEC_LOG_LOW("ip & op ports flush pending");
5663 }
5664
5665 retval = flush(port_index);
5666
5667 return retval;
5668 }
5669
5670 /**
5671 * @brief Process OMX_CommandPortDisable.
5672 *
5673 * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
5674 * @param[in] port_index: Index of port to disable.
5675 *
5676 * @retval OMX_ERRORTYPE
5677 */
async_process_event_cmd_port_disable(bool * p_cmd_ack,unsigned int port_index)5678 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_port_disable(
5679 bool *p_cmd_ack,
5680 unsigned int port_index)
5681 {
5682 OMX_ERRORTYPE retval = OMX_ErrorNone;
5683
5684 OMX_SWVDEC_LOG_HIGH("disable port index %d requested", port_index);
5685
5686 if (port_index == OMX_CORE_PORT_INDEX_IP)
5687 {
5688 if (m_port_ip.enabled == OMX_FALSE)
5689 {
5690 OMX_SWVDEC_LOG_ERROR("ip port already disabled");
5691
5692 retval = OMX_ErrorBadPortIndex;
5693 }
5694 else
5695 {
5696 m_port_ip.enabled = OMX_FALSE;
5697
5698 if (m_port_ip.unpopulated)
5699 {
5700 *p_cmd_ack = true;
5701 }
5702 else
5703 {
5704 m_status_flags |= (1 << PENDING_PORT_DISABLE_IP);
5705
5706 OMX_SWVDEC_LOG_LOW("ip port disable pending");
5707
5708 if (m_port_ip.num_pending_buffers)
5709 {
5710 retval = flush(port_index);
5711 }
5712 }
5713 }
5714 }
5715 else if (port_index == OMX_CORE_PORT_INDEX_OP)
5716 {
5717 if (m_port_op.enabled == OMX_FALSE)
5718 {
5719 OMX_SWVDEC_LOG_ERROR("op port already disabled");
5720
5721 retval = OMX_ErrorBadPortIndex;
5722 }
5723 else
5724 {
5725 m_port_op.enabled = OMX_FALSE;
5726
5727 if (m_port_op.unpopulated)
5728 {
5729 *p_cmd_ack = true;
5730 }
5731 else
5732 {
5733 m_status_flags |= (1 << PENDING_PORT_DISABLE_OP);
5734
5735 OMX_SWVDEC_LOG_LOW("op port disable pending");
5736
5737 if (m_port_op.num_pending_buffers)
5738 {
5739 retval = flush(port_index);
5740 }
5741 }
5742 }
5743 }
5744 else if (port_index == OMX_ALL)
5745 {
5746 if (m_port_ip.enabled == OMX_FALSE)
5747 {
5748 OMX_SWVDEC_LOG_ERROR("ip port already disabled");
5749
5750 retval = OMX_ErrorBadPortIndex;
5751 }
5752 else if (m_port_op.enabled == OMX_FALSE)
5753 {
5754 OMX_SWVDEC_LOG_ERROR("op port already disabled");
5755
5756 retval = OMX_ErrorBadPortIndex;
5757 }
5758 else
5759 {
5760 if (m_port_ip.unpopulated && m_port_op.unpopulated)
5761 {
5762 *p_cmd_ack = true;
5763 }
5764 else
5765 {
5766 m_port_ip.enabled = OMX_FALSE;
5767 m_port_op.enabled = OMX_FALSE;
5768
5769 if (m_port_ip.unpopulated == OMX_FALSE)
5770 {
5771 m_status_flags |= (1 << PENDING_PORT_DISABLE_IP);
5772
5773 OMX_SWVDEC_LOG_LOW("ip port disable pending");
5774
5775 if (m_port_ip.num_pending_buffers)
5776 {
5777 retval = flush(port_index);
5778 }
5779 }
5780
5781 if ((retval == OMX_ErrorNone) &&
5782 (m_port_op.unpopulated == OMX_FALSE))
5783 {
5784 m_status_flags |= (1 << PENDING_PORT_DISABLE_OP);
5785
5786 OMX_SWVDEC_LOG_LOW("op port disable pending");
5787
5788 if (m_port_op.num_pending_buffers)
5789 {
5790 retval = flush(port_index);
5791 }
5792 }
5793 }
5794 }
5795 }
5796 else
5797 {
5798 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
5799 port_index);
5800
5801 retval = OMX_ErrorBadPortIndex;
5802 }
5803
5804 return retval;
5805 }
5806
5807 /**
5808 * @brief Process OMX_CommandPortEnable.
5809 *
5810 * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
5811 * @param[in] port_index: Index of port to enable.
5812 *
5813 * @retval OMX_ERRORTYPE
5814 */
async_process_event_cmd_port_enable(bool * p_cmd_ack,unsigned int port_index)5815 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_port_enable(
5816 bool *p_cmd_ack,
5817 unsigned int port_index)
5818 {
5819 OMX_ERRORTYPE retval = OMX_ErrorNone;
5820
5821 OMX_SWVDEC_LOG_HIGH("enable port index %d requested", port_index);
5822
5823 if (port_index == OMX_CORE_PORT_INDEX_IP)
5824 {
5825 if (m_port_ip.enabled)
5826 {
5827 OMX_SWVDEC_LOG_ERROR("ip port already enabled");
5828
5829 retval = OMX_ErrorBadPortIndex;
5830 }
5831 else
5832 {
5833 m_port_ip.enabled = OMX_TRUE;
5834
5835 if (m_port_ip.populated)
5836 {
5837 *p_cmd_ack = true;
5838 }
5839 else
5840 {
5841 m_status_flags |= (1 << PENDING_PORT_ENABLE_IP);
5842
5843 OMX_SWVDEC_LOG_LOW("ip port enable pending");
5844 }
5845 }
5846 }
5847 else if (port_index == OMX_CORE_PORT_INDEX_OP)
5848 {
5849 if (m_port_op.enabled)
5850 {
5851 OMX_SWVDEC_LOG_ERROR("op port already enabled");
5852
5853 retval = OMX_ErrorBadPortIndex;
5854 }
5855 else
5856 {
5857 m_port_op.enabled = OMX_TRUE;
5858
5859 if (m_port_op.populated)
5860 {
5861 *p_cmd_ack = true;
5862 }
5863 else
5864 {
5865 m_status_flags |= (1 << PENDING_PORT_ENABLE_OP);
5866
5867 OMX_SWVDEC_LOG_LOW("op port enable pending");
5868 }
5869 }
5870 }
5871 else if (port_index == OMX_ALL)
5872 {
5873 if (m_port_ip.enabled)
5874 {
5875 OMX_SWVDEC_LOG_ERROR("ip port already enabled");
5876
5877 retval = OMX_ErrorBadPortIndex;
5878 }
5879 else if (m_port_op.enabled)
5880 {
5881 OMX_SWVDEC_LOG_ERROR("op port already enabled");
5882
5883 retval = OMX_ErrorBadPortIndex;
5884 }
5885 else
5886 {
5887 m_port_ip.enabled = OMX_TRUE;
5888 m_port_op.enabled = OMX_TRUE;
5889
5890 if (m_port_ip.populated && m_port_op.populated)
5891 {
5892 *p_cmd_ack = true;
5893 }
5894 else if (m_port_ip.populated == false)
5895 {
5896 m_status_flags |= (1 << PENDING_PORT_ENABLE_IP);
5897
5898 OMX_SWVDEC_LOG_LOW("ip port enable pending");
5899 }
5900 else if (m_port_op.populated == false)
5901 {
5902 m_status_flags |= (1 << PENDING_PORT_ENABLE_OP);
5903
5904 OMX_SWVDEC_LOG_LOW("op port enable pending");
5905 }
5906 }
5907 }
5908 else
5909 {
5910 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
5911 port_index);
5912
5913 retval = OMX_ErrorBadPortIndex;
5914 }
5915
5916 return retval;
5917 }
5918
5919 /**
5920 * @brief Process ETB event.
5921 *
5922 * @param[in] p_buffer_hdr: Pointer to buffer header.
5923 * @param[in] index: Index of buffer in input buffer info array.
5924 *
5925 * @retval OMX_ERRORTYPE
5926 */
async_process_event_etb(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)5927 OMX_ERRORTYPE omx_swvdec::async_process_event_etb(
5928 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
5929 unsigned int index)
5930 {
5931 OMX_ERRORTYPE retval = OMX_ErrorNone;
5932
5933 m_port_ip.num_pending_buffers++;
5934
5935 if ((p_buffer_hdr->nFilledLen == 0) &&
5936 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5937 {
5938 OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p,"
5939 "zero length & no EOS flag",
5940 p_buffer_hdr,
5941 p_buffer_hdr->pBuffer);
5942
5943 async_post_event(OMX_SWVDEC_EVENT_EBD,
5944 (unsigned long) p_buffer_hdr,
5945 (unsigned long) index);
5946 }
5947 else if (m_port_ip.flush_inprogress)
5948 {
5949 OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p; "
5950 "ip port flush in progress",
5951 p_buffer_hdr,
5952 p_buffer_hdr->pBuffer);
5953
5954 async_post_event(OMX_SWVDEC_EVENT_EBD,
5955 (unsigned long) p_buffer_hdr,
5956 (unsigned long) index);
5957 }
5958 else
5959 {
5960 SWVDEC_STATUS retval_swvdec;
5961
5962 SWVDEC_BUFFER *p_buffer_swvdec =
5963 &(m_buffer_array_ip[index].buffer_swvdec);
5964
5965 if (p_buffer_hdr->nFilledLen &&
5966 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == 0))
5967 {
5968 m_queue_timestamp.push(p_buffer_hdr->nTimeStamp);
5969 }
5970
5971 assert(p_buffer_swvdec->p_buffer == p_buffer_hdr->pBuffer);
5972 //sending the fd info
5973 p_buffer_swvdec->fd = m_buffer_array_ip[index].buffer_payload.pmem_fd;
5974 if (m_arbitrary_bytes_mode &&
5975 p_buffer_hdr->nFilledLen &&
5976 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == 0))
5977 {
5978 unsigned int offset_array[OMX_SWVDEC_MAX_FRAMES_PER_ETB] = {0};
5979
5980 unsigned int num_frame_headers = 1;
5981
5982 if ((m_omx_video_codingtype ==
5983 ((OMX_VIDEO_CODINGTYPE) QOMX_VIDEO_CodingDivx)) ||
5984 (m_omx_video_codingtype == OMX_VIDEO_CodingMPEG4))
5985 {
5986 num_frame_headers = split_buffer_mpeg4(offset_array,
5987 p_buffer_hdr);
5988 }
5989 else
5990 {
5991 assert(0);
5992 }
5993
5994 if(num_frame_headers > 1)
5995 {
5996 m_buffer_array_ip[index].split_count = num_frame_headers - 1;
5997
5998 for (unsigned int ii = 0; ii < num_frame_headers; ii++)
5999 {
6000 p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
6001 p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
6002
6003 if (ii == 0)
6004 {
6005 p_buffer_swvdec->offset = 0;
6006 p_buffer_swvdec->filled_length = (offset_array[ii + 1] ?
6007 offset_array[ii + 1] :
6008 p_buffer_hdr->nFilledLen);
6009 }
6010 else
6011 {
6012 p_buffer_swvdec->offset = offset_array[ii];
6013 p_buffer_swvdec->filled_length =
6014 p_buffer_hdr->nFilledLen - offset_array[ii];
6015 }
6016
6017 m_diag.dump_ip(p_buffer_swvdec->p_buffer +
6018 p_buffer_swvdec->offset,
6019 p_buffer_swvdec->filled_length);
6020
6021 retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
6022 p_buffer_swvdec);
6023
6024 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6025 {
6026 retval = retval_swvdec2omx(retval_swvdec);
6027 break;
6028 }
6029 }
6030 }
6031 else
6032 {
6033 OMX_SWVDEC_LOG_HIGH("No frame detected for Buffer %p, with TS %lld",
6034 p_buffer_hdr->pBuffer, p_buffer_hdr->nTimeStamp );
6035
6036 p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
6037 p_buffer_swvdec->offset = 0;
6038 p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
6039 p_buffer_swvdec->filled_length = p_buffer_hdr->nFilledLen;
6040
6041 m_diag.dump_ip(p_buffer_swvdec->p_buffer + p_buffer_swvdec->offset,
6042 p_buffer_swvdec->filled_length);
6043
6044 retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
6045 p_buffer_swvdec);
6046
6047 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6048 {
6049 retval = retval_swvdec2omx(retval_swvdec);
6050 }
6051 }
6052 }
6053 else
6054 {
6055 p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
6056 p_buffer_swvdec->offset = 0;
6057 p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
6058 p_buffer_swvdec->filled_length = p_buffer_hdr->nFilledLen;
6059
6060 m_diag.dump_ip(p_buffer_swvdec->p_buffer + p_buffer_swvdec->offset,
6061 p_buffer_swvdec->filled_length);
6062
6063 retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
6064 p_buffer_swvdec);
6065
6066 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6067 {
6068 retval = retval_swvdec2omx(retval_swvdec);
6069 }
6070 }
6071 }
6072 return retval;
6073 }
6074
6075 /**
6076 * @brief Process FTB event.
6077 *
6078 * @param[in] p_buffer_hdr: Pointer to buffer header.
6079 * @param[in] index: Index of buffer in output buffer info array.
6080 *
6081 * @retval OMX_ERRORTYPE
6082 */
async_process_event_ftb(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)6083 OMX_ERRORTYPE omx_swvdec::async_process_event_ftb(
6084 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
6085 unsigned int index)
6086 {
6087 OMX_ERRORTYPE retval = OMX_ErrorNone;
6088
6089 m_port_op.num_pending_buffers++;
6090
6091 if (m_port_op.flush_inprogress)
6092 {
6093 OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p; "
6094 "op port flush in progress",
6095 p_buffer_hdr,
6096 m_buffer_array_op[index].buffer_swvdec.p_buffer);
6097
6098 async_post_event(OMX_SWVDEC_EVENT_FBD,
6099 (unsigned long) p_buffer_hdr,
6100 (unsigned long) index);
6101 }
6102 else
6103 {
6104 SWVDEC_STATUS retval_swvdec;
6105
6106 SWVDEC_BUFFER *p_buffer_swvdec =
6107 &(m_buffer_array_op[index].buffer_swvdec);
6108 p_buffer_swvdec->fd = m_buffer_array_op[index].buffer_payload.pmem_fd;
6109 retval_swvdec = swvdec_fillthisbuffer(m_swvdec_handle, p_buffer_swvdec);
6110
6111 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6112 {
6113 retval = retval_swvdec2omx(retval_swvdec);
6114 }
6115 }
6116
6117 return retval;
6118 }
6119
6120 /**
6121 * @brief Process EBD event.
6122 *
6123 * @param[in] p_buffer_hdr: Pointer to buffer header.
6124 * @param[in] index: Index of buffer in output buffer info array.
6125 *
6126 * @retval OMX_ERRORTYPE
6127 */
async_process_event_ebd(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)6128 OMX_ERRORTYPE omx_swvdec::async_process_event_ebd(
6129 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
6130 unsigned int index)
6131 {
6132 OMX_ERRORTYPE retval = OMX_ErrorNone;
6133
6134 if (index < m_port_ip.def.nBufferCountActual)
6135 {
6136 if (m_arbitrary_bytes_mode && m_buffer_array_ip[index].split_count)
6137 {
6138 m_buffer_array_ip[index].split_count--;
6139 }
6140 else
6141 {
6142 m_port_ip.num_pending_buffers--;
6143
6144 OMX_SWVDEC_LOG_CALLBACK(
6145 "EmptyBufferDone(): %p, buffer %p",
6146 p_buffer_hdr,
6147 m_buffer_array_ip[index].buffer_swvdec.p_buffer);
6148
6149 m_callback.EmptyBufferDone(&m_cmp, m_app_data, p_buffer_hdr);
6150 }
6151 }
6152 else
6153 {
6154 OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
6155
6156 retval = OMX_ErrorBadParameter;
6157 }
6158
6159 return retval;
6160 }
6161
6162 /**
6163 * @brief Process FBD event.
6164 *
6165 * @param[in] p_buffer_hdr: Pointer to buffer header.
6166 * @param[in] index: Index of buffer in output buffer info array.
6167 *
6168 * @retval OMX_ERRORTYPE
6169 */
async_process_event_fbd(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)6170 OMX_ERRORTYPE omx_swvdec::async_process_event_fbd(
6171 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
6172 unsigned int index)
6173 {
6174 OMX_ERRORTYPE retval = OMX_ErrorNone;
6175
6176 static long long timestamp_prev = 0;
6177
6178 if (index < m_port_op.def.nBufferCountActual)
6179 {
6180 OMX_U8 *p_buffer;
6181
6182 p_buffer = m_buffer_array_op[index].buffer_swvdec.p_buffer;
6183
6184 m_port_op.num_pending_buffers--;
6185
6186 if (m_port_op.flush_inprogress)
6187 {
6188 p_buffer_hdr->nFilledLen = 0;
6189 p_buffer_hdr->nTimeStamp = 0;
6190 p_buffer_hdr->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6191 }
6192
6193 if (p_buffer_hdr->nFilledLen)
6194 {
6195 if (m_sync_frame_decoding_mode)
6196 {
6197 OMX_SWVDEC_LOG_LOW("sync frame decoding mode; "
6198 "setting timestamp to zero");
6199
6200 p_buffer_hdr->nTimeStamp = 0;
6201 }
6202 else
6203 {
6204 if (m_queue_timestamp.empty())
6205 {
6206 OMX_SWVDEC_LOG_ERROR("timestamp queue empty; "
6207 "re-using previous timestamp %lld",
6208 timestamp_prev);
6209
6210 p_buffer_hdr->nTimeStamp = timestamp_prev;
6211 }
6212 else
6213 {
6214 p_buffer_hdr->nTimeStamp = m_queue_timestamp.top();
6215
6216 m_queue_timestamp.pop();
6217
6218 timestamp_prev = p_buffer_hdr->nTimeStamp;
6219 }
6220 }
6221
6222 ion_flush_op(index);
6223
6224 if (m_meta_buffer_mode)
6225 {
6226 pthread_mutex_lock(&m_meta_buffer_array_mutex);
6227 }
6228
6229 m_diag.dump_op(p_buffer,
6230 m_frame_dimensions.width,
6231 m_frame_dimensions.height,
6232 m_frame_attributes.stride,
6233 m_frame_attributes.scanlines);
6234
6235 if (m_meta_buffer_mode)
6236 {
6237 pthread_mutex_unlock(&m_meta_buffer_array_mutex);
6238 }
6239 }
6240 else
6241 {
6242 OMX_SWVDEC_LOG_LOW("filled length zero; "
6243 "setting timestamp to zero");
6244
6245 p_buffer_hdr->nTimeStamp = 0;
6246 }
6247
6248 if (p_buffer_hdr->nFlags & OMX_BUFFERFLAG_EOS)
6249 {
6250 async_post_event(OMX_SWVDEC_EVENT_EOS, 0, 0);
6251
6252 OMX_SWVDEC_LOG_LOW("flushing %zu elements in timestamp queue",
6253 m_queue_timestamp.size());
6254
6255 while (m_queue_timestamp.empty() == false)
6256 {
6257 m_queue_timestamp.pop();
6258 }
6259 }
6260
6261 if (m_meta_buffer_mode &&
6262 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_READONLY)) == 0)
6263 {
6264 meta_buffer_ref_remove(index);
6265 }
6266
6267 OMX_SWVDEC_LOG_CALLBACK(
6268 "FillBufferDone(): %p, buffer %p, "
6269 "flags 0x%08x, filled length %d, timestamp %lld",
6270 p_buffer_hdr,
6271 p_buffer,
6272 p_buffer_hdr->nFlags,
6273 p_buffer_hdr->nFilledLen,
6274 p_buffer_hdr->nTimeStamp);
6275
6276 m_callback.FillBufferDone(&m_cmp, m_app_data, p_buffer_hdr);
6277 }
6278 else
6279 {
6280 OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
6281
6282 retval = OMX_ErrorBadParameter;
6283 }
6284
6285 return retval;
6286 }
6287
6288 /**
6289 * @brief Process EOS event.
6290 *
6291 * @retval OMX_ErrorNone
6292 */
async_process_event_eos()6293 OMX_ERRORTYPE omx_swvdec::async_process_event_eos()
6294 {
6295 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
6296 "OMX_EventBufferFlag, port index %d, EOS",
6297 OMX_CORE_PORT_INDEX_OP);
6298
6299 m_callback.EventHandler(&m_cmp,
6300 m_app_data,
6301 OMX_EventBufferFlag,
6302 OMX_CORE_PORT_INDEX_OP,
6303 OMX_BUFFERFLAG_EOS,
6304 NULL);
6305
6306 return OMX_ErrorNone;
6307 }
6308
6309 /**
6310 * @brief Process input port flush event.
6311 *
6312 * @retval OMX_ERRORTYPE
6313 */
async_process_event_flush_port_ip()6314 OMX_ERRORTYPE omx_swvdec::async_process_event_flush_port_ip()
6315 {
6316 OMX_ERRORTYPE retval = OMX_ErrorNone;
6317
6318 OMX_SWVDEC_EVENT_INFO event_info;
6319
6320 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
6321
6322 unsigned int index;
6323
6324 while (m_queue_port_ip.pop(&event_info))
6325 {
6326 switch (event_info.event_id)
6327 {
6328
6329 case OMX_SWVDEC_EVENT_ETB:
6330 {
6331 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6332
6333 index = event_info.event_param2;
6334
6335 // compensate decrement in async_process_event_ebd()
6336 m_port_ip.num_pending_buffers++;
6337
6338 retval = async_process_event_ebd(p_buffer_hdr, index);
6339 break;
6340 }
6341
6342 case OMX_SWVDEC_EVENT_EBD:
6343 {
6344 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6345
6346 index = event_info.event_param2;
6347
6348 retval = async_process_event_ebd(p_buffer_hdr, index);
6349 break;
6350 }
6351
6352 default:
6353 {
6354 assert(0);
6355 break;
6356 }
6357
6358 }
6359 }
6360
6361 assert(m_port_ip.num_pending_buffers == 0);
6362
6363 if ((retval == OMX_ErrorNone) &&
6364 (m_status_flags & (1 << PENDING_PORT_FLUSH_IP)))
6365 {
6366 m_status_flags &= ~(1 << PENDING_PORT_FLUSH_IP);
6367
6368 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
6369 OMX_CommandFlush,
6370 OMX_CORE_PORT_INDEX_IP);
6371 }
6372
6373 m_port_ip.flush_inprogress = OMX_FALSE;
6374
6375 return retval;
6376 }
6377
6378 /**
6379 * @brief Process output port flush event.
6380 *
6381 * @retval OMX_ERRORTYPE
6382 */
async_process_event_flush_port_op()6383 OMX_ERRORTYPE omx_swvdec::async_process_event_flush_port_op()
6384 {
6385 OMX_ERRORTYPE retval = OMX_ErrorNone;
6386
6387 OMX_SWVDEC_EVENT_INFO event_info;
6388
6389 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
6390
6391 unsigned int index;
6392
6393 while (m_queue_port_op.pop(&event_info))
6394 {
6395 switch (event_info.event_id)
6396 {
6397
6398 case OMX_SWVDEC_EVENT_FTB:
6399 {
6400 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6401
6402 index = event_info.event_param2;
6403
6404 // compensate decrement in async_process_event_fbd()
6405 m_port_op.num_pending_buffers++;
6406
6407 retval = async_process_event_fbd(p_buffer_hdr, index);
6408 break;
6409 }
6410
6411 case OMX_SWVDEC_EVENT_FBD:
6412 {
6413 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6414
6415 index = event_info.event_param2;
6416
6417 retval = async_process_event_fbd(p_buffer_hdr, index);
6418 break;
6419 }
6420
6421 default:
6422 {
6423 assert(0);
6424 break;
6425 }
6426
6427 }
6428 }
6429
6430 assert(m_port_op.num_pending_buffers == 0);
6431
6432 if ((retval == OMX_ErrorNone) &&
6433 (m_status_flags & (1 << PENDING_PORT_FLUSH_OP)))
6434 {
6435 m_status_flags &= ~(1 << PENDING_PORT_FLUSH_OP);
6436
6437 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
6438 OMX_CommandFlush,
6439 OMX_CORE_PORT_INDEX_OP);
6440 }
6441
6442 if ((retval == OMX_ErrorNone) &&
6443 (m_status_flags & (1 << PENDING_STATE_EXECUTING_TO_IDLE)))
6444 {
6445 m_status_flags &= ~(1 << PENDING_STATE_EXECUTING_TO_IDLE);
6446
6447 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
6448 OMX_CommandStateSet,
6449 OMX_StateIdle);
6450 }
6451
6452 if (m_port_reconfig_inprogress == false)
6453 {
6454 OMX_SWVDEC_LOG_LOW("flushing %zu elements in timestamp queue",
6455 m_queue_timestamp.size());
6456
6457 while (m_queue_timestamp.empty() == false)
6458 {
6459 m_queue_timestamp.pop();
6460 }
6461 }
6462
6463 m_port_op.flush_inprogress = OMX_FALSE;
6464
6465 return retval;
6466 }
6467
6468 /**
6469 * @brief Process port reconfiguration event.
6470 *
6471 * @retval OMX_ERRORTYPE
6472 */
async_process_event_port_reconfig()6473 OMX_ERRORTYPE omx_swvdec::async_process_event_port_reconfig()
6474 {
6475 OMX_ERRORTYPE retval = OMX_ErrorNone;
6476
6477 if (m_port_reconfig_inprogress)
6478 {
6479 OMX_SWVDEC_LOG_ERROR("port reconfiguration already in progress");
6480
6481 retval = OMX_ErrorIncorrectStateOperation;
6482 }
6483 else
6484 {
6485 m_port_reconfig_inprogress = true;
6486
6487 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
6488 "OMX_EventPortSettingsChanged, port index %d",
6489 OMX_CORE_PORT_INDEX_OP);
6490
6491 m_callback.EventHandler(&m_cmp,
6492 m_app_data,
6493 OMX_EventPortSettingsChanged,
6494 OMX_CORE_PORT_INDEX_OP,
6495 OMX_IndexParamPortDefinition,
6496 NULL);
6497 }
6498
6499 return retval;
6500 }
6501
6502 /**
6503 * @brief Process dimensions updated event.
6504 *
6505 * @retval OMX_ERRORTYPE
6506 */
async_process_event_dimensions_updated()6507 OMX_ERRORTYPE omx_swvdec::async_process_event_dimensions_updated()
6508 {
6509 OMX_ERRORTYPE retval = OMX_ErrorNone;
6510
6511 if (m_dimensions_update_inprogress)
6512 {
6513 OMX_SWVDEC_LOG_ERROR("dimensions update already in progress");
6514
6515 retval = OMX_ErrorIncorrectStateOperation;
6516 }
6517 else
6518 {
6519 m_dimensions_update_inprogress = true;
6520
6521 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
6522 "OMX_EventPortSettingsChanged, port index %d, "
6523 "OMX_IndexConfigCommonOutputCrop",
6524 OMX_CORE_PORT_INDEX_OP);
6525
6526 m_callback.EventHandler(&m_cmp,
6527 m_app_data,
6528 OMX_EventPortSettingsChanged,
6529 OMX_CORE_PORT_INDEX_OP,
6530 OMX_IndexConfigCommonOutputCrop,
6531 NULL);
6532 }
6533
6534 return retval;
6535 }
6536
6537 /**
6538 * @brief Map the memory and run the ioctl SYNC operations
6539 *.on ION fd with DMA_BUF_IOCTL_SYNC
6540 *.@param[in] fd: ION header.
6541 * @param[in] len:Lenth of the memory.
6542 * @retval mapped memory pointer
6543 */
ion_map(int fd,int len)6544 unsigned char *omx_swvdec::ion_map(int fd, int len)
6545 {
6546 unsigned char *bufaddr = (unsigned char*)mmap(NULL, len, PROT_READ|PROT_WRITE,
6547 MAP_SHARED, fd, 0);
6548 if (bufaddr != MAP_FAILED) {
6549 #ifdef USE_ION
6550 struct dma_buf_sync buf_sync;
6551 buf_sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
6552 int rc = ioctl(fd, DMA_BUF_IOCTL_SYNC, &buf_sync);
6553 if (rc) {
6554 OMX_SWVDEC_LOG_ERROR("Failed DMA_BUF_IOCTL_SYNC");
6555 }
6556 #endif
6557 }
6558 return bufaddr;
6559 }
6560
6561 /**
6562 * @brief Unmap the memory
6563 *.@param[in] fd: ION header.
6564 .*.@param[in].bufaddr : buffer address
6565 * @param[in] len:Lenth of the memory.
6566 * @retval OMX_ERRORTYPE
6567 */
ion_unmap(int fd,void * bufaddr,int len)6568 OMX_ERRORTYPE omx_swvdec::ion_unmap(int fd, void *bufaddr, int len)
6569 {
6570 #ifdef USE_ION
6571 struct dma_buf_sync buf_sync;
6572 buf_sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
6573 int rc = ioctl(fd, DMA_BUF_IOCTL_SYNC, &buf_sync);
6574 if (rc) {
6575 OMX_SWVDEC_LOG_ERROR("Failed DMA_BUF_IOCTL_SYNC");
6576 }
6577 #endif
6578 if (-1 == munmap(bufaddr, len)) {
6579 OMX_SWVDEC_LOG_ERROR("munmap failed.");
6580 return OMX_ErrorInsufficientResources;
6581 }
6582 return OMX_ErrorNone;
6583 }
6584
6585