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 /* Content for which low delay is 0 for ex: XVID clips
3550 minimum two buffers are required to generate thumbnail */
3551 p_buffer_req->mincount = 2;
3552 }
3553
3554 m_port_op.def.nBufferSize = p_buffer_req->size;
3555 m_port_op.def.nBufferCountMin = p_buffer_req->mincount;
3556 m_port_op.def.nBufferCountActual = MAX(p_buffer_req->mincount,
3557 m_port_op.def.nBufferCountActual);
3558 m_port_op.def.nBufferAlignment = p_buffer_req->alignment;
3559
3560 OMX_SWVDEC_LOG_HIGH("op port: %d bytes x %d, %d-byte aligned",
3561 m_port_op.def.nBufferSize,
3562 m_port_op.def.nBufferCountActual,
3563 m_port_op.def.nBufferAlignment);
3564 }
3565 else
3566 {
3567 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", port_index);
3568
3569 retval = OMX_ErrorBadPortIndex;
3570 }
3571
3572 get_buffer_requirements_swvdec_exit:
3573 return retval;
3574 }
3575
3576 /**
3577 * @brief Allocate input buffer, and input buffer info array if ncessary.
3578 *
3579 * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
3580 * structure.
3581 * @param[in] p_app_data: Pointer to IL client app data.
3582 * @param[in] size: Size of buffer to be allocated in bytes.
3583 *
3584 * @retval OMX_ERRORTYPE
3585 */
buffer_allocate_ip(OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_PTR p_app_data,OMX_U32 size)3586 OMX_ERRORTYPE omx_swvdec::buffer_allocate_ip(
3587 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
3588 OMX_PTR p_app_data,
3589 OMX_U32 size)
3590 {
3591 OMX_ERRORTYPE retval = OMX_ErrorNone;
3592 SWVDEC_STATUS retval_swvdec = SWVDEC_STATUS_SUCCESS;
3593
3594 unsigned int ii;
3595
3596 if (size != m_port_ip.def.nBufferSize)
3597 {
3598 OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
3599 "configured size (%d bytes)",
3600 size,
3601 m_port_ip.def.nBufferSize);
3602
3603 return OMX_ErrorBadParameter;
3604 }
3605
3606 if (m_buffer_array_ip == NULL)
3607 {
3608 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3609 m_port_ip.def.nBufferCountActual,
3610 (m_port_ip.def.nBufferCountActual > 1) ? "s" : "");
3611
3612 if ((retval = buffer_allocate_ip_info_array()) != OMX_ErrorNone)
3613 {
3614 return retval;
3615 }
3616 }
3617
3618 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
3619 {
3620 if (m_buffer_array_ip[ii].buffer_populated == false)
3621 {
3622 OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
3623 break;
3624 }
3625 }
3626
3627 if (ii < m_port_ip.def.nBufferCountActual)
3628 {
3629 int pmem_fd = -1;
3630
3631 unsigned char *bufferaddr;
3632
3633 OMX_SWVDEC_LOG_HIGH("ip buffer %d: %d bytes being allocated",
3634 ii,
3635 size);
3636
3637 m_buffer_array_ip[ii].ion_info.dev_fd=
3638 ion_memory_alloc_map(&m_buffer_array_ip[ii].ion_info,size,
3639 m_port_ip.def.nBufferAlignment);
3640
3641 if (m_buffer_array_ip[ii].ion_info.dev_fd< 0)
3642 {
3643 return OMX_ErrorInsufficientResources;
3644 }
3645
3646 pmem_fd = m_buffer_array_ip[ii].ion_info.data_fd;
3647
3648 bufferaddr = ion_map(pmem_fd,size);
3649
3650 if (bufferaddr == MAP_FAILED)
3651 {
3652 OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d error %s",
3653 pmem_fd,
3654 size, strerror(errno));
3655
3656 close(pmem_fd);
3657 ion_memory_free(&m_buffer_array_ip[ii].ion_info);
3658
3659 return OMX_ErrorInsufficientResources;
3660 }
3661
3662 *pp_buffer_hdr = &m_buffer_array_ip[ii].buffer_header;
3663
3664 m_buffer_array_ip[ii].buffer_payload.bufferaddr = bufferaddr;
3665 m_buffer_array_ip[ii].buffer_payload.pmem_fd = pmem_fd;
3666 m_buffer_array_ip[ii].buffer_payload.buffer_len = size;
3667 m_buffer_array_ip[ii].buffer_payload.mmaped_size = size;
3668 m_buffer_array_ip[ii].buffer_payload.offset = 0;
3669
3670 m_buffer_array_ip[ii].buffer_swvdec.p_buffer = bufferaddr;
3671 m_buffer_array_ip[ii].buffer_swvdec.size = size;
3672 m_buffer_array_ip[ii].buffer_swvdec.p_client_data =
3673 (void *) ((unsigned long) ii);
3674 m_buffer_array_ip[ii].buffer_swvdec.fd = pmem_fd;
3675
3676 m_buffer_array_ip[ii].buffer_populated = true;
3677
3678 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
3679 {
3680 OMX_SWVDEC_LOG_LOW("map ip buffer");
3681
3682 if((retval_swvdec = swvdec_register_buffer(m_swvdec_handle,
3683 &m_buffer_array_ip[ii].buffer_swvdec))
3684 != SWVDEC_STATUS_SUCCESS)
3685 {
3686 OMX_SWVDEC_LOG_ERROR("swvdec_map failed for ip buffer %d: %p",ii,bufferaddr);
3687
3688 close(pmem_fd);
3689 ion_memory_free(&m_buffer_array_ip[ii].ion_info);
3690
3691 return retval_swvdec2omx(retval_swvdec);
3692 }
3693 }
3694
3695 OMX_SWVDEC_LOG_HIGH("ip buffer %d: %p, fd = %d %d bytes",
3696 ii,
3697 bufferaddr,
3698 pmem_fd,
3699 size);
3700
3701 (*pp_buffer_hdr)->pBuffer = (OMX_U8 *) bufferaddr;
3702 (*pp_buffer_hdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3703 (*pp_buffer_hdr)->nVersion.nVersion = OMX_SPEC_VERSION;
3704 (*pp_buffer_hdr)->nAllocLen = size;
3705 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
3706 (*pp_buffer_hdr)->nInputPortIndex = OMX_CORE_PORT_INDEX_IP;
3707 (*pp_buffer_hdr)->pInputPortPrivate =
3708 (void *) &(m_buffer_array_ip[ii].buffer_payload);
3709
3710 m_port_ip.populated = port_ip_populated();
3711 m_port_ip.unpopulated = OMX_FALSE;
3712 }
3713 else
3714 {
3715 OMX_SWVDEC_LOG_ERROR("all %d ip buffers allocated",
3716 m_port_ip.def.nBufferCountActual);
3717
3718 return OMX_ErrorInsufficientResources;
3719 }
3720
3721 return retval;
3722 }
3723
3724 /**
3725 * @brief Allocate output buffer, and output buffer info array if necessary.
3726 *
3727 * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
3728 * structure.
3729 * @param[in] p_app_data: Pointer to IL client app data.
3730 * @param[in] size: Size of buffer to be allocated in bytes.
3731 *
3732 * @retval OMX_ERRORTYPE
3733 */
buffer_allocate_op(OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_PTR p_app_data,OMX_U32 size)3734 OMX_ERRORTYPE omx_swvdec::buffer_allocate_op(
3735 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
3736 OMX_PTR p_app_data,
3737 OMX_U32 size)
3738 {
3739 OMX_ERRORTYPE retval = OMX_ErrorNone;
3740 SWVDEC_STATUS retval_swvdec = SWVDEC_STATUS_SUCCESS;
3741 unsigned int ii;
3742
3743 if (size != m_port_op.def.nBufferSize)
3744 {
3745 OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
3746 "configured size (%d bytes)",
3747 size,
3748 m_port_op.def.nBufferSize);
3749
3750 return OMX_ErrorBadParameter;
3751 }
3752
3753 if (m_buffer_array_op == NULL)
3754 {
3755 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3756 m_port_op.def.nBufferCountActual,
3757 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
3758
3759 if ((retval = buffer_allocate_op_info_array()) != OMX_ErrorNone)
3760 {
3761 return retval;
3762 }
3763 }
3764
3765 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
3766 {
3767 if (m_buffer_array_op[ii].buffer_populated == false)
3768 {
3769 OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
3770 break;
3771 }
3772 }
3773
3774 if (ii < m_port_op.def.nBufferCountActual)
3775 {
3776 int pmem_fd = -1;
3777
3778 unsigned char *bufferaddr;
3779
3780 OMX_SWVDEC_LOG_HIGH("op buffer %d: %d bytes being allocated",
3781 ii,
3782 size);
3783
3784 m_buffer_array_op[ii].ion_info.dev_fd=
3785 ion_memory_alloc_map(&m_buffer_array_op[ii].ion_info,size,
3786 m_port_op.def.nBufferAlignment);
3787
3788 if (m_buffer_array_op[ii].ion_info.dev_fd < 0)
3789 {
3790 return OMX_ErrorInsufficientResources;
3791 }
3792
3793 pmem_fd = m_buffer_array_op[ii].ion_info.data_fd;
3794
3795 bufferaddr = ion_map(pmem_fd,size);
3796
3797 if (bufferaddr == MAP_FAILED)
3798 {
3799 OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d",
3800 pmem_fd,
3801 size);
3802
3803 close(pmem_fd);
3804 ion_memory_free(&m_buffer_array_op[ii].ion_info);
3805
3806 return OMX_ErrorInsufficientResources;
3807 }
3808
3809 *pp_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
3810
3811 m_buffer_array_op[ii].buffer_payload.bufferaddr = bufferaddr;
3812 m_buffer_array_op[ii].buffer_payload.pmem_fd = pmem_fd;
3813 m_buffer_array_op[ii].buffer_payload.buffer_len = size;
3814 m_buffer_array_op[ii].buffer_payload.mmaped_size = size;
3815 m_buffer_array_op[ii].buffer_payload.offset = 0;
3816
3817 m_buffer_array_op[ii].buffer_swvdec.p_buffer = bufferaddr;
3818 m_buffer_array_op[ii].buffer_swvdec.size = size;
3819 m_buffer_array_op[ii].buffer_swvdec.p_client_data =
3820 (void *) ((unsigned long) ii);
3821
3822 m_buffer_array_op[ii].buffer_populated = true;
3823
3824 m_buffer_array_op[ii].buffer_swvdec.fd = pmem_fd ;
3825
3826 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
3827 {
3828 OMX_SWVDEC_LOG_LOW("map op buffer");
3829
3830 if((retval_swvdec = swvdec_map(m_swvdec_handle,&m_buffer_array_op[ii].buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
3831 {
3832 OMX_SWVDEC_LOG_ERROR("swvdec_map failed for op buffer %d: %p",ii,bufferaddr);
3833
3834 close(pmem_fd);
3835 ion_memory_free(&m_buffer_array_op[ii].ion_info);
3836
3837 return retval_swvdec2omx(retval_swvdec);
3838 }
3839 }
3840 OMX_SWVDEC_LOG_HIGH("op buffer %d: %p, fd = %d %d bytes",
3841 ii,
3842 bufferaddr,
3843 pmem_fd,
3844 size);
3845
3846 (*pp_buffer_hdr)->pBuffer = (OMX_U8 *) bufferaddr;
3847 (*pp_buffer_hdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3848 (*pp_buffer_hdr)->nVersion.nVersion = OMX_SPEC_VERSION;
3849 (*pp_buffer_hdr)->nAllocLen = size;
3850 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
3851 (*pp_buffer_hdr)->nOutputPortIndex = OMX_CORE_PORT_INDEX_OP;
3852 (*pp_buffer_hdr)->pOutputPortPrivate =
3853 (void *) &(m_buffer_array_op[ii].buffer_payload);
3854
3855 m_port_op.populated = port_op_populated();
3856 m_port_op.unpopulated = OMX_FALSE;
3857 }
3858 else
3859 {
3860 OMX_SWVDEC_LOG_ERROR("all %d op buffers allocated",
3861 m_port_op.def.nBufferCountActual);
3862
3863 retval = OMX_ErrorInsufficientResources;
3864 }
3865
3866 return retval;
3867 }
3868
3869 /**
3870 * @brief Allocate input buffer info array.
3871 */
buffer_allocate_ip_info_array()3872 OMX_ERRORTYPE omx_swvdec::buffer_allocate_ip_info_array()
3873 {
3874 OMX_ERRORTYPE retval = OMX_ErrorNone;
3875
3876 unsigned int ii;
3877
3878 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
3879
3880 if (m_buffer_array_ip != NULL)
3881 {
3882 OMX_SWVDEC_LOG_ERROR("buffer info array already allocated");
3883
3884 retval = OMX_ErrorInsufficientResources;
3885 goto buffer_allocate_ip_info_array_exit;
3886 }
3887
3888 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3889 m_port_ip.def.nBufferCountActual,
3890 (m_port_ip.def.nBufferCountActual > 1) ? "s" : "");
3891
3892 m_buffer_array_ip =
3893 (OMX_SWVDEC_BUFFER_INFO *) calloc(sizeof(OMX_SWVDEC_BUFFER_INFO),
3894 m_port_ip.def.nBufferCountActual);
3895
3896 if (m_buffer_array_ip == NULL)
3897 {
3898 OMX_SWVDEC_LOG_ERROR("failed to allocate buffer info array; "
3899 "%d element%s, %zu bytes requested",
3900 m_port_ip.def.nBufferCountActual,
3901 (m_port_ip.def.nBufferCountActual > 1) ? "s" : "",
3902 sizeof(OMX_SWVDEC_BUFFER_INFO) *
3903 m_port_ip.def.nBufferCountActual);
3904
3905 retval = OMX_ErrorInsufficientResources;
3906 goto buffer_allocate_ip_info_array_exit;
3907 }
3908
3909 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
3910 {
3911 p_buffer_hdr = &m_buffer_array_ip[ii].buffer_header;
3912
3913 // reset file descriptors
3914
3915 m_buffer_array_ip[ii].buffer_payload.pmem_fd = -1;
3916 m_buffer_array_ip[ii].ion_info.dev_fd= -1;
3917
3918 m_buffer_array_ip[ii].buffer_swvdec.p_client_data =
3919 (void *) ((unsigned long) ii);
3920
3921 p_buffer_hdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3922 p_buffer_hdr->nVersion.nVersion = OMX_SPEC_VERSION;
3923 p_buffer_hdr->nInputPortIndex = OMX_CORE_PORT_INDEX_IP;
3924 p_buffer_hdr->pInputPortPrivate =
3925 (void *) &(m_buffer_array_ip[ii].buffer_payload);
3926 }
3927
3928 buffer_allocate_ip_info_array_exit:
3929 return retval;
3930 }
3931
3932 /**
3933 * @brief Allocate output buffer info array.
3934 */
buffer_allocate_op_info_array()3935 OMX_ERRORTYPE omx_swvdec::buffer_allocate_op_info_array()
3936 {
3937 OMX_ERRORTYPE retval = OMX_ErrorNone;
3938
3939 unsigned int ii;
3940
3941 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
3942
3943 if (m_buffer_array_op != NULL)
3944 {
3945 OMX_SWVDEC_LOG_ERROR("buffer info array already allocated");
3946
3947 retval = OMX_ErrorInsufficientResources;
3948 goto buffer_allocate_op_info_array_exit;
3949 }
3950
3951 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
3952 m_port_op.def.nBufferCountActual,
3953 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
3954
3955 m_buffer_array_op =
3956 (OMX_SWVDEC_BUFFER_INFO *) calloc(sizeof(OMX_SWVDEC_BUFFER_INFO),
3957 m_port_op.def.nBufferCountActual);
3958
3959 if (m_buffer_array_op == NULL)
3960 {
3961 OMX_SWVDEC_LOG_ERROR("failed to allocate buffer info array; "
3962 "%d element%s, %zu bytes requested",
3963 m_port_op.def.nBufferCountActual,
3964 (m_port_op.def.nBufferCountActual > 1) ? "s" : "",
3965 sizeof(OMX_SWVDEC_BUFFER_INFO) *
3966 m_port_op.def.nBufferCountActual);
3967
3968 retval = OMX_ErrorInsufficientResources;
3969 goto buffer_allocate_op_info_array_exit;
3970 }
3971
3972 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
3973 {
3974 p_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
3975
3976 // reset file descriptors
3977
3978 m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
3979 m_buffer_array_op[ii].ion_info.dev_fd = -1;
3980
3981 m_buffer_array_op[ii].buffer_swvdec.p_client_data =
3982 (void *) ((unsigned long) ii);
3983
3984 p_buffer_hdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3985 p_buffer_hdr->nVersion.nVersion = OMX_SPEC_VERSION;
3986 p_buffer_hdr->nOutputPortIndex = OMX_CORE_PORT_INDEX_OP;
3987 p_buffer_hdr->pOutputPortPrivate =
3988 (void *) &(m_buffer_array_op[ii].buffer_payload);
3989 }
3990
3991 buffer_allocate_op_info_array_exit:
3992 return retval;
3993 }
3994
3995 /**
3996 * @brief Use buffer allocated by IL client; allocate output buffer info array
3997 * if necessary.
3998 *
3999 * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
4000 * structure.
4001 * @param[in] p_app_data: Pointer to IL client app data.
4002 * @param[in] size: Size of buffer to be allocated in bytes.
4003 * @param[in] p_buffer: Pointer to buffer to be used.
4004 *
4005 * @retval OMX_ERRORTYPE
4006 */
buffer_use_op(OMX_BUFFERHEADERTYPE ** pp_buffer_hdr,OMX_PTR p_app_data,OMX_U32 size,OMX_U8 * p_buffer)4007 OMX_ERRORTYPE omx_swvdec::buffer_use_op(
4008 OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
4009 OMX_PTR p_app_data,
4010 OMX_U32 size,
4011 OMX_U8 *p_buffer)
4012 {
4013 OMX_ERRORTYPE retval = OMX_ErrorNone;
4014 SWVDEC_STATUS retval_swvdec;
4015 unsigned int ii;
4016
4017 (void) size;
4018
4019 if (m_buffer_array_op == NULL)
4020 {
4021 OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
4022 m_port_op.def.nBufferCountActual,
4023 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
4024
4025 if ((retval = buffer_allocate_op_info_array()) != OMX_ErrorNone)
4026 {
4027 goto buffer_use_op_exit;
4028 }
4029 }
4030
4031 if (m_meta_buffer_mode && (m_meta_buffer_array == NULL))
4032 {
4033 OMX_SWVDEC_LOG_HIGH("allocating meta buffer info array, %d element%s",
4034 m_port_op.def.nBufferCountActual,
4035 (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
4036
4037 if ((retval = meta_buffer_array_allocate()) != OMX_ErrorNone)
4038 {
4039 goto buffer_use_op_exit;
4040 }
4041 }
4042
4043 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4044 {
4045 if (m_buffer_array_op[ii].buffer_populated == false)
4046 {
4047 OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
4048 break;
4049 }
4050 }
4051
4052 if (ii < m_port_op.def.nBufferCountActual)
4053 {
4054 struct vdec_bufferpayload *p_buffer_payload;
4055
4056 SWVDEC_BUFFER *p_buffer_swvdec;
4057
4058 *pp_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
4059 p_buffer_payload = &m_buffer_array_op[ii].buffer_payload;
4060 p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
4061
4062 if (m_meta_buffer_mode)
4063 {
4064 p_buffer_swvdec->size = m_port_op.def.nBufferSize;
4065 p_buffer_swvdec->p_client_data = (void *) ((unsigned long) ii);
4066
4067 m_buffer_array_op[ii].buffer_populated = true;
4068
4069 (*pp_buffer_hdr)->pBuffer = p_buffer;
4070 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
4071 (*pp_buffer_hdr)->nAllocLen =
4072 sizeof(struct VideoDecoderOutputMetaData);
4073
4074 OMX_SWVDEC_LOG_HIGH("op buffer %d: %p (meta buffer)",
4075 ii,
4076 *pp_buffer_hdr);
4077
4078 m_port_op.populated = port_op_populated();
4079 m_port_op.unpopulated = OMX_FALSE;
4080 }
4081 else if (m_android_native_buffers)
4082 {
4083 private_handle_t *p_handle;
4084
4085 OMX_U8 *p_buffer_mapped;
4086
4087 p_handle = (private_handle_t *) p_buffer;
4088
4089 if (((OMX_U32) p_handle->size) < m_port_op.def.nBufferSize)
4090 {
4091 OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
4092 "configured size (%d bytes)",
4093 p_handle->size,
4094 m_port_op.def.nBufferSize);
4095
4096 retval = OMX_ErrorBadParameter;
4097 goto buffer_use_op_exit;
4098 }
4099
4100 m_port_op.def.nBufferSize = p_handle->size;
4101
4102 p_buffer_mapped = ion_map(p_handle->fd,p_handle->size);
4103
4104 if (p_buffer_mapped == MAP_FAILED)
4105 {
4106 OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d",
4107 p_handle->fd,
4108 p_handle->size);
4109
4110 retval = OMX_ErrorInsufficientResources;
4111 goto buffer_use_op_exit;
4112 }
4113
4114 p_buffer_payload->bufferaddr = p_buffer_mapped;
4115 p_buffer_payload->pmem_fd = p_handle->fd;
4116 p_buffer_payload->buffer_len = p_handle->size;
4117 p_buffer_payload->mmaped_size = p_handle->size;
4118 p_buffer_payload->offset = 0;
4119
4120 p_buffer_swvdec->p_buffer = p_buffer_mapped;
4121 p_buffer_swvdec->size = m_port_op.def.nBufferSize;
4122 p_buffer_swvdec->p_client_data = (void *) ((unsigned long) ii);
4123 p_buffer_swvdec->fd = p_buffer_payload->pmem_fd ;
4124
4125 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
4126 {
4127 OMX_SWVDEC_LOG_LOW("map op buffer");
4128
4129 if((retval_swvdec = swvdec_map(m_swvdec_handle,p_buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
4130 {
4131 OMX_SWVDEC_LOG_ERROR("swvdec_map failed for op buffer %d: %p",ii,p_buffer_mapped);
4132 retval = retval_swvdec2omx(retval_swvdec);;
4133 goto buffer_use_op_exit;
4134 }
4135 }
4136 m_buffer_array_op[ii].buffer_populated = true;
4137
4138 (*pp_buffer_hdr)->pBuffer = (m_android_native_buffers ?
4139 ((OMX_U8 *) p_handle) :
4140 p_buffer_mapped);
4141 (*pp_buffer_hdr)->pAppPrivate = p_app_data;
4142 (*pp_buffer_hdr)->nAllocLen = m_port_op.def.nBufferSize;
4143
4144 m_buffer_array_op[ii].ion_info.data_fd = p_handle->fd;
4145
4146 OMX_SWVDEC_LOG_HIGH("op buffer %d: %p",
4147 ii,
4148 *pp_buffer_hdr);
4149
4150 m_port_op.populated = port_op_populated();
4151 m_port_op.unpopulated = OMX_FALSE;
4152 }
4153 else
4154 {
4155 OMX_SWVDEC_LOG_ERROR("neither 'meta buffer mode' nor "
4156 "'android native buffers' enabled");
4157
4158 retval = OMX_ErrorBadParameter;
4159 }
4160 }
4161 else
4162 {
4163 OMX_SWVDEC_LOG_ERROR("all %d op buffers populated",
4164 m_port_op.def.nBufferCountActual);
4165
4166 retval = OMX_ErrorInsufficientResources;
4167 }
4168
4169 buffer_use_op_exit:
4170 return retval;
4171 }
4172
4173 /**
4174 * @brief De-allocate input buffer.
4175 *
4176 * @param[in] p_buffer_hdr: Pointer to buffer header structure.
4177 *
4178 * @retval OMX_ERRORTYPE
4179 */
buffer_deallocate_ip(OMX_BUFFERHEADERTYPE * p_buffer_hdr)4180 OMX_ERRORTYPE omx_swvdec::buffer_deallocate_ip(
4181 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
4182 {
4183 OMX_ERRORTYPE retval = OMX_ErrorNone;
4184 SWVDEC_STATUS retval_swvdec = SWVDEC_STATUS_SUCCESS;
4185
4186 unsigned int ii;
4187
4188 if (p_buffer_hdr == NULL)
4189 {
4190 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
4191
4192 retval = OMX_ErrorBadParameter;
4193 goto buffer_deallocate_ip_exit;
4194 }
4195 else if (m_buffer_array_ip == NULL)
4196 {
4197 OMX_SWVDEC_LOG_ERROR("ip buffer array not allocated");
4198
4199 retval = OMX_ErrorBadParameter;
4200 goto buffer_deallocate_ip_exit;
4201 }
4202
4203 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
4204 {
4205 if (p_buffer_hdr == &(m_buffer_array_ip[ii].buffer_header))
4206 {
4207 OMX_SWVDEC_LOG_LOW("%p has index %d",
4208 p_buffer_hdr->pBuffer,
4209 ii);
4210 break;
4211 }
4212 }
4213
4214 if (ii < m_port_ip.def.nBufferCountActual)
4215 {
4216 if (m_buffer_array_ip[ii].buffer_payload.pmem_fd > 0)
4217 {
4218
4219 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
4220 {
4221 SWVDEC_BUFFER *p_buffer_swvdec;
4222 p_buffer_swvdec = &m_buffer_array_ip[ii].buffer_swvdec;
4223 OMX_SWVDEC_LOG_LOW("unmap ip buffer");
4224
4225 if((retval_swvdec = swvdec_unregister_buffer(m_swvdec_handle,p_buffer_swvdec))
4226 != SWVDEC_STATUS_SUCCESS)
4227 {
4228 OMX_SWVDEC_LOG_ERROR("swvdec_unmap failed for ip buffer %d: %p",
4229 ii,p_buffer_swvdec->p_buffer);
4230 retval = retval_swvdec2omx(retval_swvdec);;
4231 }
4232 }
4233
4234 m_buffer_array_ip[ii].buffer_populated = false;
4235
4236 m_port_ip.populated = OMX_FALSE;
4237
4238 ion_unmap(m_buffer_array_ip[ii].buffer_payload.pmem_fd,
4239 m_buffer_array_ip[ii].buffer_payload.bufferaddr,
4240 m_buffer_array_ip[ii].buffer_payload.mmaped_size);
4241
4242 close(m_buffer_array_ip[ii].buffer_payload.pmem_fd);
4243 m_buffer_array_ip[ii].buffer_payload.pmem_fd = -1;
4244
4245 ion_memory_free(&m_buffer_array_ip[ii].ion_info);
4246
4247 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
4248 {
4249 if (m_buffer_array_ip[ii].buffer_populated)
4250 {
4251 break;
4252 }
4253 }
4254
4255 if (ii == m_port_ip.def.nBufferCountActual)
4256 {
4257 buffer_deallocate_ip_info_array();
4258
4259 m_port_ip.unpopulated = OMX_TRUE;
4260 }
4261 }
4262 else
4263 {
4264 OMX_SWVDEC_LOG_ERROR("%p: pmem_fd %d",
4265 p_buffer_hdr->pBuffer,
4266 m_buffer_array_ip[ii].buffer_payload.pmem_fd);
4267 }
4268 }
4269 else
4270 {
4271 OMX_SWVDEC_LOG_ERROR("%p not found", p_buffer_hdr->pBuffer);
4272
4273 retval = OMX_ErrorBadParameter;
4274 }
4275
4276 buffer_deallocate_ip_exit:
4277 return retval;
4278 }
4279
4280 /**
4281 * @brief De-allocate output buffer.
4282 *
4283 * @param[in] p_buffer_hdr: Pointer to buffer header structure.
4284 *
4285 * @retval OMX_ERRORTYPE
4286 */
buffer_deallocate_op(OMX_BUFFERHEADERTYPE * p_buffer_hdr)4287 OMX_ERRORTYPE omx_swvdec::buffer_deallocate_op(
4288 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
4289 {
4290 OMX_ERRORTYPE retval = OMX_ErrorNone;
4291 SWVDEC_STATUS retval_swvdec = SWVDEC_STATUS_SUCCESS;
4292 unsigned int ii;
4293
4294 if (p_buffer_hdr == NULL)
4295 {
4296 OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
4297
4298 retval = OMX_ErrorBadParameter;
4299 goto buffer_deallocate_op_exit;
4300 }
4301 else if (m_buffer_array_op == NULL)
4302 {
4303 OMX_SWVDEC_LOG_ERROR("op buffer array not allocated");
4304
4305 retval = OMX_ErrorBadParameter;
4306 goto buffer_deallocate_op_exit;
4307 }
4308
4309 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4310 {
4311 if (p_buffer_hdr == &(m_buffer_array_op[ii].buffer_header))
4312 {
4313 OMX_SWVDEC_LOG_LOW("%p has index %d",
4314 p_buffer_hdr->pBuffer,
4315 ii);
4316 break;
4317 }
4318 }
4319
4320 if (ii < m_port_op.def.nBufferCountActual)
4321 {
4322 if (m_meta_buffer_mode)
4323 {
4324 // do nothing; munmap() & FD reset done in FBD or RR
4325 }
4326 else if (m_android_native_buffers)
4327 {
4328
4329 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
4330 {
4331 SWVDEC_BUFFER *p_buffer_swvdec;
4332 p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
4333 OMX_SWVDEC_LOG_LOW("unmap op buffer");
4334
4335 if((retval_swvdec = swvdec_unmap(m_swvdec_handle,p_buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
4336 {
4337 OMX_SWVDEC_LOG_ERROR("swvdec_unmap failed for op buffer %d: %p",ii,p_buffer_swvdec->p_buffer);
4338 retval = retval_swvdec2omx(retval_swvdec);;
4339 }
4340 }
4341 ion_unmap(m_buffer_array_op[ii].buffer_payload.pmem_fd ,
4342 m_buffer_array_op[ii].buffer_payload.bufferaddr,
4343 m_buffer_array_op[ii].buffer_payload.mmaped_size);
4344
4345 m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
4346 }
4347 else
4348 {
4349 if(m_swvdec_codec == SWVDEC_CODEC_VC1)
4350 {
4351 SWVDEC_BUFFER *p_buffer_swvdec;
4352 p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
4353 OMX_SWVDEC_LOG_LOW("unmap op buffer");
4354
4355 if((retval_swvdec = swvdec_unmap(m_swvdec_handle,p_buffer_swvdec)) != SWVDEC_STATUS_SUCCESS)
4356 {
4357 OMX_SWVDEC_LOG_ERROR("swvdec_unmap failed for op buffer %d: %p",ii,p_buffer_swvdec->p_buffer);
4358 retval = retval_swvdec2omx(retval_swvdec);;
4359 }
4360 }
4361 ion_unmap(m_buffer_array_op[ii].buffer_payload.pmem_fd,
4362 m_buffer_array_op[ii].buffer_payload.bufferaddr,
4363 m_buffer_array_op[ii].buffer_payload.mmaped_size);
4364
4365 close(m_buffer_array_op[ii].buffer_payload.pmem_fd);
4366
4367 m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
4368
4369 ion_memory_free(&m_buffer_array_op[ii].ion_info);
4370 }
4371
4372 m_buffer_array_op[ii].buffer_populated = false;
4373
4374 m_port_op.populated = OMX_FALSE;
4375
4376 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4377 {
4378 if (m_buffer_array_op[ii].buffer_populated)
4379 {
4380 break;
4381 }
4382 }
4383
4384 if (ii == m_port_op.def.nBufferCountActual)
4385 {
4386 buffer_deallocate_op_info_array();
4387
4388 m_port_op.unpopulated = OMX_TRUE;
4389
4390 if (m_meta_buffer_mode)
4391 {
4392 meta_buffer_array_deallocate();
4393 }
4394 }
4395 }
4396 else
4397 {
4398 OMX_SWVDEC_LOG_ERROR("%p not found", p_buffer_hdr->pBuffer);
4399
4400 retval = OMX_ErrorBadParameter;
4401 }
4402
4403 buffer_deallocate_op_exit:
4404 return retval;
4405 }
4406
4407 /**
4408 * @brief De-allocate input buffer info array.
4409 */
buffer_deallocate_ip_info_array()4410 void omx_swvdec::buffer_deallocate_ip_info_array()
4411 {
4412 assert(m_buffer_array_ip != NULL);
4413
4414 free(m_buffer_array_ip);
4415
4416 m_buffer_array_ip = NULL;
4417 }
4418
4419 /**
4420 * @brief De-allocate output buffer info array.
4421 */
buffer_deallocate_op_info_array()4422 void omx_swvdec::buffer_deallocate_op_info_array()
4423 {
4424 assert(m_buffer_array_op != NULL);
4425
4426 free(m_buffer_array_op);
4427
4428 m_buffer_array_op = NULL;
4429 }
4430
4431 /**
4432 * @brief Allocate meta buffer info array.
4433 *
4434 * @retval OMX_ERRORTYPE
4435 */
meta_buffer_array_allocate()4436 OMX_ERRORTYPE omx_swvdec::meta_buffer_array_allocate()
4437 {
4438 OMX_ERRORTYPE retval = OMX_ErrorNone;
4439
4440 m_meta_buffer_array = ((OMX_SWVDEC_META_BUFFER_INFO *)
4441 calloc(sizeof(OMX_SWVDEC_META_BUFFER_INFO),
4442 m_port_op.def.nBufferCountActual));
4443
4444 if (m_meta_buffer_array == NULL)
4445 {
4446 OMX_SWVDEC_LOG_ERROR("failed to allocate meta_buffer info array; "
4447 "%d element%s, %zu bytes requested",
4448 m_port_op.def.nBufferCountActual,
4449 (m_port_op.def.nBufferCountActual > 1) ? "s" : "",
4450 sizeof(OMX_SWVDEC_META_BUFFER_INFO) *
4451 m_port_op.def.nBufferCountActual);
4452
4453 retval = OMX_ErrorInsufficientResources;
4454 }
4455 else
4456 {
4457 unsigned int ii;
4458
4459 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4460 {
4461 m_meta_buffer_array[ii].fd = -1;
4462 }
4463 }
4464
4465 return retval;
4466 }
4467
4468 /**
4469 * @brief De-allocate meta buffer info array.
4470 */
meta_buffer_array_deallocate()4471 void omx_swvdec::meta_buffer_array_deallocate()
4472 {
4473 assert(m_meta_buffer_array != NULL);
4474
4475 free(m_meta_buffer_array);
4476
4477 m_meta_buffer_array = NULL;
4478 }
4479
4480 /**
4481 * @brief Add meta buffer reference.
4482 *
4483 * @param[in] index: Buffer index.
4484 * @param[in] fd: File descriptor.
4485 */
meta_buffer_ref_add(unsigned int index,int fd)4486 void omx_swvdec::meta_buffer_ref_add(unsigned int index, int fd)
4487 {
4488 if (m_meta_buffer_array[index].ref_count == 0)
4489 {
4490 m_meta_buffer_array[index].fd = fd;
4491 }
4492
4493 m_meta_buffer_array[index].ref_count++;
4494 }
4495
4496 /**
4497 * @brief Remove meta buffer reference.
4498 *
4499 * @param[in] index: Buffer index.
4500 */
meta_buffer_ref_remove(unsigned int index)4501 void omx_swvdec::meta_buffer_ref_remove(unsigned int index)
4502 {
4503 pthread_mutex_lock(&m_meta_buffer_array_mutex);
4504
4505 m_meta_buffer_array[index].ref_count--;
4506
4507 if (m_meta_buffer_array[index].ref_count == 0)
4508 {
4509 ion_unmap(m_meta_buffer_array[index].fd,
4510 m_buffer_array_op[index].buffer_payload.bufferaddr,
4511 m_buffer_array_op[index].buffer_payload.mmaped_size);
4512
4513 m_meta_buffer_array[index].fd = -1;
4514 m_buffer_array_op[index].buffer_payload.bufferaddr = NULL;
4515 m_buffer_array_op[index].buffer_payload.offset = 0;
4516 m_buffer_array_op[index].buffer_payload.mmaped_size = 0;
4517
4518 m_buffer_array_op[index].buffer_swvdec.p_buffer = NULL;
4519 m_buffer_array_op[index].buffer_swvdec.size = 0;
4520 }
4521
4522 pthread_mutex_unlock(&m_meta_buffer_array_mutex);
4523 }
4524
4525 /**
4526 * @brief Split MPEG-4 bitstream buffer into multiple frames (if they exist).
4527 *
4528 * @param[in,out] offset_array: Array of offsets to frame headers.
4529 * @param[in] p_buffer_hdr: Pointer to buffer header.
4530 *
4531 * @retval Number of frames in buffer.
4532 */
split_buffer_mpeg4(unsigned int * offset_array,OMX_BUFFERHEADERTYPE * p_buffer_hdr)4533 unsigned int split_buffer_mpeg4(unsigned int *offset_array,
4534 OMX_BUFFERHEADERTYPE *p_buffer_hdr)
4535 {
4536 unsigned char *p_buffer = p_buffer_hdr->pBuffer;
4537
4538 unsigned int byte_count = 0;
4539
4540 unsigned int num_frame_headers = 0;
4541
4542 unsigned int next_4bytes;
4543
4544 while ((byte_count < p_buffer_hdr->nFilledLen) &&
4545 (num_frame_headers < OMX_SWVDEC_MAX_FRAMES_PER_ETB))
4546 {
4547 next_4bytes = *((unsigned int *) p_buffer);
4548
4549 next_4bytes = __builtin_bswap32(next_4bytes);
4550
4551 if (next_4bytes == 0x000001B6)
4552 {
4553 OMX_SWVDEC_LOG_HIGH("%p, buffer %p: "
4554 "frame header at %d bytes offset",
4555 p_buffer_hdr,
4556 p_buffer_hdr->pBuffer,
4557 byte_count);
4558
4559 offset_array[num_frame_headers] = byte_count;
4560
4561 num_frame_headers++;
4562
4563 p_buffer += 4;
4564 byte_count += 4;
4565 }
4566 else
4567 {
4568 p_buffer++;
4569 byte_count++;
4570 }
4571 }
4572
4573 return num_frame_headers;
4574 }
4575
4576 /**
4577 * @brief Check if ip port is populated, i.e., if all ip buffers are populated.
4578 *
4579 * @retval true
4580 * @retval false
4581 */
port_ip_populated()4582 OMX_BOOL omx_swvdec::port_ip_populated()
4583 {
4584 OMX_BOOL retval = OMX_FALSE;
4585
4586 if (m_buffer_array_ip != NULL)
4587 {
4588 unsigned int ii;
4589
4590 for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
4591 {
4592 if (m_buffer_array_ip[ii].buffer_populated == false)
4593 {
4594 break;
4595 }
4596 }
4597
4598 if (ii == m_port_ip.def.nBufferCountActual)
4599 {
4600 retval = OMX_TRUE;
4601 }
4602 }
4603
4604 return retval;
4605 }
4606
4607 /**
4608 * @brief Check if op port is populated, i.e., if all op buffers are populated.
4609 *
4610 * @retval true
4611 * @retval false
4612 */
port_op_populated()4613 OMX_BOOL omx_swvdec::port_op_populated()
4614 {
4615 OMX_BOOL retval = OMX_FALSE;
4616
4617 if (m_buffer_array_op != NULL)
4618 {
4619 unsigned int ii;
4620
4621 for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
4622 {
4623 if (m_buffer_array_op[ii].buffer_populated == false)
4624 {
4625 break;
4626 }
4627 }
4628
4629 if (ii == m_port_op.def.nBufferCountActual)
4630 {
4631 retval = OMX_TRUE;
4632 }
4633 }
4634
4635 return retval;
4636 }
4637
4638 /**
4639 * @brief Flush input, output, or both input & output ports.
4640 *
4641 * @param[in] port_index: Index of port to flush.
4642 *
4643 * @retval OMX_ERRORTYPE
4644 */
flush(unsigned int port_index)4645 OMX_ERRORTYPE omx_swvdec::flush(unsigned int port_index)
4646 {
4647 OMX_ERRORTYPE retval = OMX_ErrorNone;
4648
4649 if (((port_index == OMX_CORE_PORT_INDEX_IP) &&
4650 m_port_ip.flush_inprogress) ||
4651 ((port_index == OMX_CORE_PORT_INDEX_OP) &&
4652 m_port_op.flush_inprogress) ||
4653 ((port_index == OMX_ALL) &&
4654 m_port_ip.flush_inprogress &&
4655 m_port_op.flush_inprogress))
4656 {
4657 OMX_SWVDEC_LOG_HIGH("flush port index %d already in progress",
4658 port_index);
4659 }
4660 else
4661 {
4662 SWVDEC_FLUSH_TYPE swvdec_flush_type;
4663
4664 SWVDEC_STATUS retval_swvdec;
4665
4666 if (port_index == OMX_CORE_PORT_INDEX_IP)
4667 {
4668 m_port_ip.flush_inprogress = OMX_TRUE;
4669
4670 //for VTS test case IP flush , trigger flush all
4671 // for IP flush, similar behavior is for hwcodecs
4672 m_port_ip.flush_inprogress = OMX_TRUE;
4673 m_port_op.flush_inprogress = OMX_TRUE;
4674
4675 swvdec_flush_type = SWVDEC_FLUSH_TYPE_ALL;
4676
4677 if ((retval_swvdec = swvdec_flush(m_swvdec_handle,
4678 swvdec_flush_type)) !=
4679 SWVDEC_STATUS_SUCCESS)
4680 {
4681 retval = retval_swvdec2omx(retval_swvdec);
4682 }
4683 }
4684 else if (port_index == OMX_CORE_PORT_INDEX_OP)
4685 {
4686 m_port_op.flush_inprogress = OMX_TRUE;
4687
4688 swvdec_flush_type = (m_port_ip.flush_inprogress ?
4689 SWVDEC_FLUSH_TYPE_ALL :
4690 SWVDEC_FLUSH_TYPE_OP);
4691
4692 if ((retval_swvdec = swvdec_flush(m_swvdec_handle,
4693 swvdec_flush_type)) !=
4694 SWVDEC_STATUS_SUCCESS)
4695 {
4696 retval = retval_swvdec2omx(retval_swvdec);
4697 }
4698 }
4699 else if (port_index == OMX_ALL)
4700 {
4701 m_port_ip.flush_inprogress = OMX_TRUE;
4702 m_port_op.flush_inprogress = OMX_TRUE;
4703
4704 swvdec_flush_type = SWVDEC_FLUSH_TYPE_ALL;
4705
4706 if ((retval_swvdec = swvdec_flush(m_swvdec_handle,
4707 swvdec_flush_type)) !=
4708 SWVDEC_STATUS_SUCCESS)
4709 {
4710 retval = retval_swvdec2omx(retval_swvdec);
4711 }
4712 }
4713 else
4714 {
4715 assert(0);
4716 }
4717 }
4718
4719 return retval;
4720 }
4721
4722 /**
4723 * @brief Allocate & map ION memory.
4724 */
ion_memory_alloc_map(vdec_ion * p_ion_info,OMX_U32 size,OMX_U32 alignment)4725 int omx_swvdec::ion_memory_alloc_map(vdec_ion *p_ion_info, OMX_U32 size, OMX_U32 alignment)
4726 {
4727 int rc = -EINVAL;
4728
4729 if((!p_ion_info) || (size == 0))
4730 {
4731 OMX_SWVDEC_LOG_ERROR("invalid arguments");
4732 goto ion_memory_alloc_map_exit;
4733 }
4734
4735 p_ion_info->dev_fd = -EINVAL;
4736
4737 if ((p_ion_info->dev_fd = ion_open()) < 0)
4738 {
4739 OMX_SWVDEC_LOG_ERROR("failed to open ion device; fd = %d", p_ion_info->dev_fd);
4740 goto ion_memory_alloc_map_exit;
4741 }
4742
4743 p_ion_info->alloc_data.len = size;
4744 p_ion_info->alloc_data.heap_id_mask = ION_HEAP(ION_SYSTEM_HEAP_ID);
4745 p_ion_info->alloc_data.flags = 0;//check if ION_FLAG_CACHED need to be set;
4746 alignment = ALIGN(alignment,4096);
4747
4748 OMX_SWVDEC_LOG_LOW("heap_id_mask 0x%08x, len %zu",
4749 p_ion_info->alloc_data.heap_id_mask,
4750 p_ion_info->alloc_data.len);
4751
4752 rc = ion_alloc_fd(p_ion_info->dev_fd, p_ion_info->alloc_data.len, alignment,
4753 p_ion_info->alloc_data.heap_id_mask, p_ion_info->alloc_data.flags,
4754 &p_ion_info->data_fd);
4755
4756 if (rc || p_ion_info->data_fd == 0)
4757 {
4758 OMX_SWVDEC_LOG_ERROR("ion_alloc_fd() for allocation failed");
4759 ion_close(p_ion_info->dev_fd);
4760 p_ion_info->data_fd = -1;
4761 p_ion_info->dev_fd = -1;
4762 goto ion_memory_alloc_map_exit;
4763 }
4764
4765
4766 OMX_SWVDEC_LOG_HIGH("Alloc ion memory: fd (dev:%d data:%d) len %d flags %#x mask %#x",
4767 p_ion_info->dev_fd, p_ion_info->data_fd, (unsigned int)p_ion_info->alloc_data.len,
4768 (unsigned int)p_ion_info->alloc_data.flags,
4769 (unsigned int)p_ion_info->alloc_data.heap_id_mask);
4770
4771 ion_memory_alloc_map_exit:
4772 return (p_ion_info == nullptr) ? -EINVAL : p_ion_info->dev_fd;
4773 }
4774
4775 /**
4776 * @brief Free ION memory.
4777 */
ion_memory_free(struct vdec_ion * p_ion_buf_info)4778 void omx_swvdec::ion_memory_free(struct vdec_ion *p_ion_buf_info)
4779 {
4780 if (p_ion_buf_info == NULL)
4781 {
4782 OMX_SWVDEC_LOG_ERROR("p_ion_buf_info = NULL");
4783 goto ion_memory_free_exit;
4784 }
4785
4786 OMX_SWVDEC_LOG_HIGH("Free ion memory: map fd %d ion_dev fd %d len %d flags %#x mask %#x",
4787 p_ion_buf_info->data_fd, p_ion_buf_info->dev_fd,
4788 (unsigned int)p_ion_buf_info->alloc_data.len,
4789 (unsigned int)p_ion_buf_info->alloc_data.flags,
4790 (unsigned int)p_ion_buf_info->alloc_data.heap_id_mask);
4791
4792 if (p_ion_buf_info->data_fd >= 0) {
4793 close(p_ion_buf_info->data_fd);
4794 p_ion_buf_info->data_fd = -1;
4795 }
4796
4797 if (p_ion_buf_info->dev_fd >= 0) {
4798 ion_close(p_ion_buf_info->dev_fd);
4799 p_ion_buf_info->dev_fd = -1;
4800 }
4801
4802 ion_memory_free_exit:
4803 return;
4804 }
4805
4806 /**
4807 * @brief Flush cached ION output buffer.
4808 *
4809 * @param[in] index: Index of buffer in output buffer info array.
4810 */
ion_flush_op(unsigned int index)4811 void omx_swvdec::ion_flush_op(unsigned int index)
4812 {
4813 if (index < m_port_op.def.nBufferCountActual)
4814 {
4815 #ifdef USE_ION
4816 struct dma_buf_sync dma_buf_sync_data[2];
4817 dma_buf_sync_data[0].flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_WRITE;
4818 dma_buf_sync_data[1].flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_WRITE;
4819
4820 for (unsigned int i=0; i<2; i++)
4821 {
4822 int ret = ioctl(m_buffer_array_op[index].buffer_swvdec.fd,
4823 DMA_BUF_IOCTL_SYNC, &dma_buf_sync_data[i]);
4824 if (ret < 0)
4825 {
4826 OMX_SWVDEC_LOG_ERROR("Cache %s failed for fd %d : %s\n",
4827 (i==0) ? "START" : "END",
4828 m_buffer_array_op[index].buffer_swvdec.fd,
4829 strerror(errno));
4830 goto ion_flush_op_exit;
4831 }
4832 }
4833 #endif
4834 }
4835 else
4836 {
4837 OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
4838 }
4839
4840 ion_flush_op_exit:
4841 return;
4842 }
4843
4844
4845 /**
4846 * ----------------------------
4847 * component callback functions
4848 * ----------------------------
4849 */
4850
4851 /**
4852 * @brief Empty buffer done callback.
4853 *
4854 * @param[in] p_buffer_ip: Pointer to input buffer structure.
4855 */
swvdec_empty_buffer_done(SWVDEC_BUFFER * p_buffer_ip)4856 void omx_swvdec::swvdec_empty_buffer_done(SWVDEC_BUFFER *p_buffer_ip)
4857 {
4858 unsigned long index = (unsigned long) p_buffer_ip->p_client_data;
4859
4860 m_buffer_array_ip[index].buffer_header.nFilledLen =
4861 p_buffer_ip->filled_length;
4862
4863 async_post_event(OMX_SWVDEC_EVENT_EBD,
4864 (unsigned long) &m_buffer_array_ip[index].buffer_header,
4865 index);
4866 }
4867
4868 /**
4869 * @brief Fill buffer done callback.
4870 *
4871 * @param[in] p_buffer_op: Pointer to output buffer structure.
4872 */
swvdec_fill_buffer_done(SWVDEC_BUFFER * p_buffer_op)4873 void omx_swvdec::swvdec_fill_buffer_done(SWVDEC_BUFFER *p_buffer_op)
4874 {
4875 unsigned long index = (unsigned long) p_buffer_op->p_client_data;
4876
4877 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
4878
4879 if (index < ((unsigned long) m_port_op.def.nBufferCountActual))
4880 {
4881 p_buffer_hdr = &m_buffer_array_op[index].buffer_header;
4882
4883 p_buffer_hdr->nFlags = p_buffer_op->flags;
4884 p_buffer_hdr->nTimeStamp = p_buffer_op->timestamp;
4885 p_buffer_hdr->nFilledLen = ((m_meta_buffer_mode &&
4886 p_buffer_op->filled_length) ?
4887 p_buffer_hdr->nAllocLen :
4888 p_buffer_op->filled_length);
4889 }
4890
4891 async_post_event(OMX_SWVDEC_EVENT_FBD,
4892 (unsigned long) &m_buffer_array_op[index].buffer_header,
4893 index);
4894 }
4895
4896 /**
4897 * @brief Event handler callback.
4898 *
4899 * @param[in] event: Event.
4900 * @param[in] p_data: Pointer to event-specific data.
4901 */
swvdec_event_handler(SWVDEC_EVENT event,void * p_data)4902 void omx_swvdec::swvdec_event_handler(SWVDEC_EVENT event, void *p_data)
4903 {
4904 switch (event)
4905 {
4906
4907 case SWVDEC_EVENT_FLUSH_ALL_DONE:
4908 {
4909 async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_IP, 0, 0);
4910 async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_OP, 0, 0);
4911
4912 break;
4913 }
4914
4915 case SWVDEC_EVENT_FLUSH_OP_DONE:
4916 {
4917 async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_OP, 0, 0);
4918
4919 break;
4920 }
4921
4922 case SWVDEC_EVENT_RELEASE_REFERENCE:
4923 {
4924 SWVDEC_BUFFER *p_buffer_op = (SWVDEC_BUFFER *) p_data;
4925
4926 unsigned long index = (unsigned long) p_buffer_op->p_client_data;
4927
4928 OMX_SWVDEC_LOG_LOW("release reference: %p", p_buffer_op->p_buffer);
4929
4930 assert(index < ((unsigned long) m_port_op.def.nBufferCountActual));
4931
4932 if (m_meta_buffer_mode)
4933 {
4934 meta_buffer_ref_remove(index);
4935 }
4936
4937 break;
4938 }
4939
4940 case SWVDEC_EVENT_RECONFIG_REQUIRED:
4941 {
4942 async_post_event(OMX_SWVDEC_EVENT_PORT_RECONFIG, 0, 0);
4943
4944 break;
4945 }
4946
4947 case SWVDEC_EVENT_DIMENSIONS_UPDATED:
4948 {
4949 async_post_event(OMX_SWVDEC_EVENT_DIMENSIONS_UPDATED, 0, 0);
4950
4951 break;
4952 }
4953
4954 case SWVDEC_EVENT_FATAL_ERROR:
4955 default:
4956 {
4957 async_post_event(OMX_SWVDEC_EVENT_ERROR, OMX_ErrorHardware, 0);
4958
4959 break;
4960 }
4961
4962 }
4963 }
4964
4965 /**
4966 * @brief Translate SwVdec status return value to OMX error type return value.
4967 *
4968 * @param[in] retval_swvdec: SwVdec status return value.
4969 *
4970 * @retval OMX_ERRORTYPE
4971 */
retval_swvdec2omx(SWVDEC_STATUS retval_swvdec)4972 OMX_ERRORTYPE omx_swvdec::retval_swvdec2omx(SWVDEC_STATUS retval_swvdec)
4973 {
4974 OMX_ERRORTYPE retval_omx;
4975
4976 switch (retval_swvdec) {
4977 case SWVDEC_STATUS_SUCCESS:
4978 retval_omx = OMX_ErrorNone;
4979 break;
4980
4981 case SWVDEC_STATUS_FAILURE:
4982 retval_omx = OMX_ErrorUndefined;
4983 break;
4984
4985 case SWVDEC_STATUS_NULL_POINTER:
4986 case SWVDEC_STATUS_INVALID_PARAMETERS:
4987 retval_omx = OMX_ErrorBadParameter;
4988 break;
4989
4990 case SWVDEC_STATUS_INVALID_STATE:
4991 retval_omx = OMX_ErrorInvalidState;
4992 break;
4993
4994 case SWVDEC_STATUS_INSUFFICIENT_RESOURCES:
4995 retval_omx = OMX_ErrorInsufficientResources;
4996 break;
4997
4998 case SWVDEC_STATUS_UNSUPPORTED:
4999 retval_omx = OMX_ErrorUnsupportedSetting;
5000 break;
5001
5002 case SWVDEC_STATUS_NOT_IMPLEMENTED:
5003 retval_omx = OMX_ErrorNotImplemented;
5004 break;
5005
5006 default:
5007 retval_omx = OMX_ErrorUndefined;
5008 break;
5009 }
5010
5011 return retval_omx;
5012 }
5013
5014 /**
5015 * @brief Create asynchronous thread.
5016 *
5017 * @retval OMX_ERRORTYPE
5018 */
async_thread_create()5019 OMX_ERRORTYPE omx_swvdec::async_thread_create()
5020 {
5021 OMX_ERRORTYPE retval = OMX_ErrorNone;
5022
5023 pthread_attr_t thread_attributes;
5024
5025 if (sem_init(&m_async_thread.sem_thread_created, 0, 0))
5026 {
5027 OMX_SWVDEC_LOG_ERROR("failed to create async thread created semaphore");
5028
5029 retval = OMX_ErrorInsufficientResources;
5030 }
5031 else if (sem_init(&m_async_thread.sem_event, 0, 0))
5032 {
5033 OMX_SWVDEC_LOG_ERROR("failed to create async thread event semaphore");
5034
5035 retval = OMX_ErrorInsufficientResources;
5036 }
5037 else if (pthread_attr_init(&thread_attributes))
5038 {
5039 OMX_SWVDEC_LOG_ERROR("failed to create thread attributes object");
5040
5041 retval = OMX_ErrorInsufficientResources;
5042 }
5043 else if (pthread_attr_setdetachstate(&thread_attributes,
5044 PTHREAD_CREATE_JOINABLE))
5045 {
5046 OMX_SWVDEC_LOG_ERROR("failed to set detach state attribute");
5047
5048 retval = OMX_ErrorInsufficientResources;
5049
5050 pthread_attr_destroy(&thread_attributes);
5051 }
5052 else
5053 {
5054 m_async_thread.created = false;
5055 m_async_thread.exit = false;
5056
5057 if (pthread_create(&m_async_thread.handle,
5058 &thread_attributes,
5059 (void *(*)(void *)) async_thread,
5060 this))
5061 {
5062 OMX_SWVDEC_LOG_ERROR("failed to create async thread");
5063
5064 retval = OMX_ErrorInsufficientResources;
5065
5066 pthread_attr_destroy(&thread_attributes);
5067 }
5068 else
5069 {
5070 if (pthread_setname_np(m_async_thread.handle, "swvdec_async"))
5071 {
5072 // don't return error
5073 OMX_SWVDEC_LOG_ERROR("failed to set async thread name");
5074 }
5075
5076 sem_wait(&m_async_thread.sem_thread_created);
5077
5078 m_async_thread.created = true;
5079 }
5080 }
5081
5082 return retval;
5083 }
5084
5085 /**
5086 * @brief Destroy asynchronous thread.
5087 */
async_thread_destroy()5088 void omx_swvdec::async_thread_destroy()
5089 {
5090 if (m_async_thread.created)
5091 {
5092 m_async_thread.exit = true;
5093
5094 sem_post(&m_async_thread.sem_event);
5095
5096 pthread_join(m_async_thread.handle, NULL);
5097
5098 m_async_thread.created = false;
5099 }
5100
5101 m_async_thread.exit = false;
5102
5103 sem_destroy(&m_async_thread.sem_event);
5104 sem_destroy(&m_async_thread.sem_thread_created);
5105 }
5106
5107 /**
5108 * @brief Post event to appropriate queue.
5109 *
5110 * @param[in] event_id: Event ID.
5111 * @param[in] event_param1: Event parameter 1.
5112 * @param[in] event_param2: Event parameter 2.
5113 */
async_post_event(unsigned long event_id,unsigned long event_param1,unsigned long event_param2)5114 void omx_swvdec::async_post_event(unsigned long event_id,
5115 unsigned long event_param1,
5116 unsigned long event_param2)
5117 {
5118 OMX_SWVDEC_EVENT_INFO event_info;
5119
5120 event_info.event_id = event_id;
5121 event_info.event_param1 = event_param1;
5122 event_info.event_param2 = event_param2;
5123
5124 switch (event_id)
5125 {
5126
5127 case OMX_SWVDEC_EVENT_ETB:
5128 case OMX_SWVDEC_EVENT_EBD:
5129 {
5130 m_queue_port_ip.push(&event_info);
5131 break;
5132 }
5133
5134 case OMX_SWVDEC_EVENT_FTB:
5135 case OMX_SWVDEC_EVENT_FBD:
5136 {
5137 m_queue_port_op.push(&event_info);
5138 break;
5139 }
5140
5141 default:
5142 {
5143 m_queue_command.push(&event_info);
5144 break;
5145 }
5146
5147 }
5148
5149 sem_post(&m_async_thread.sem_event);
5150 }
5151
5152 /**
5153 * @brief Asynchronous thread.
5154 *
5155 * @param[in] p_cmp: Pointer to OMX SwVdec component class.
5156 */
async_thread(void * p_cmp)5157 void omx_swvdec::async_thread(void *p_cmp)
5158 {
5159 if (p_cmp == NULL)
5160 {
5161 OMX_SWVDEC_LOG_ERROR("p_cmp = NULL");
5162 }
5163 else
5164 {
5165 omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_cmp;
5166
5167 ASYNC_THREAD *p_async_thread = &p_omx_swvdec->m_async_thread;
5168
5169 OMX_SWVDEC_LOG_HIGH("created");
5170
5171 sem_post(&p_async_thread->sem_thread_created);
5172
5173 while (p_async_thread->exit == false)
5174 {
5175 sem_wait(&p_async_thread->sem_event);
5176
5177 if (p_async_thread->exit == true)
5178 {
5179 break;
5180 }
5181
5182 p_omx_swvdec->async_process_event(p_cmp);
5183 }
5184 }
5185
5186 OMX_SWVDEC_LOG_HIGH("exiting");
5187 }
5188
5189 /**
5190 * @brief Process event.
5191 *
5192 * @param[in] p_cmp: Pointer to OMX SwVdec component class.
5193 */
async_process_event(void * p_cmp)5194 void omx_swvdec::async_process_event(void *p_cmp)
5195 {
5196 omx_swvdec *p_omx_swvdec;
5197
5198 OMX_SWVDEC_EVENT_INFO event_info;
5199
5200 OMX_ERRORTYPE retval = OMX_ErrorNone;
5201
5202 if (p_cmp == NULL)
5203 {
5204 OMX_SWVDEC_LOG_ERROR("p_cmp = NULL");
5205
5206 goto async_process_event_exit;
5207 }
5208
5209 p_omx_swvdec = (omx_swvdec *) p_cmp;
5210
5211 // NOTE: queues popped in order of priority; do not change!
5212
5213 if ((p_omx_swvdec->m_queue_command.pop(&event_info) == false) &&
5214 (p_omx_swvdec->m_queue_port_op.pop(&event_info) == false) &&
5215 (p_omx_swvdec->m_queue_port_ip.pop(&event_info) == false))
5216 {
5217 OMX_SWVDEC_LOG_LOW("no event popped");
5218
5219 goto async_process_event_exit;
5220 }
5221
5222 switch (event_info.event_id)
5223 {
5224
5225 case OMX_SWVDEC_EVENT_CMD:
5226 {
5227 OMX_COMMANDTYPE cmd = (OMX_COMMANDTYPE) event_info.event_param1;
5228 OMX_U32 param = (OMX_U32) event_info.event_param2;
5229
5230 retval = p_omx_swvdec->async_process_event_cmd(cmd, param);
5231 break;
5232 }
5233
5234 case OMX_SWVDEC_EVENT_CMD_ACK:
5235 {
5236 OMX_COMMANDTYPE cmd = (OMX_COMMANDTYPE) event_info.event_param1;
5237 OMX_U32 param = (OMX_U32) event_info.event_param2;
5238
5239 retval = p_omx_swvdec->async_process_event_cmd_ack(cmd, param);
5240 break;
5241 }
5242
5243 case OMX_SWVDEC_EVENT_ERROR:
5244 {
5245 OMX_ERRORTYPE error_code = (OMX_ERRORTYPE) event_info.event_param1;
5246
5247 retval = p_omx_swvdec->async_process_event_error(error_code);
5248 break;
5249 }
5250
5251 case OMX_SWVDEC_EVENT_ETB:
5252 {
5253 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5254 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5255
5256 unsigned int index = event_info.event_param2;
5257
5258 retval = p_omx_swvdec->async_process_event_etb(p_buffer_hdr, index);
5259 break;
5260 }
5261
5262 case OMX_SWVDEC_EVENT_FTB:
5263 {
5264 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5265 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5266
5267 unsigned int index = event_info.event_param2;
5268
5269 retval = p_omx_swvdec->async_process_event_ftb(p_buffer_hdr, index);
5270 break;
5271 }
5272
5273 case OMX_SWVDEC_EVENT_EBD:
5274 {
5275 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5276 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5277
5278 unsigned int index = event_info.event_param2;
5279
5280 retval = p_omx_swvdec->async_process_event_ebd(p_buffer_hdr, index);
5281 break;
5282 }
5283
5284 case OMX_SWVDEC_EVENT_FBD:
5285 {
5286 OMX_BUFFERHEADERTYPE *p_buffer_hdr =
5287 (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
5288
5289 unsigned int index = event_info.event_param2;
5290
5291 retval = p_omx_swvdec->async_process_event_fbd(p_buffer_hdr, index);
5292 break;
5293 }
5294
5295 case OMX_SWVDEC_EVENT_EOS:
5296 {
5297 retval = p_omx_swvdec->async_process_event_eos();
5298 break;
5299 }
5300
5301 case OMX_SWVDEC_EVENT_FLUSH_PORT_IP:
5302 {
5303 retval = p_omx_swvdec->async_process_event_flush_port_ip();
5304 break;
5305 }
5306
5307 case OMX_SWVDEC_EVENT_FLUSH_PORT_OP:
5308 {
5309 retval = p_omx_swvdec->async_process_event_flush_port_op();
5310 break;
5311 }
5312
5313 case OMX_SWVDEC_EVENT_PORT_RECONFIG:
5314 {
5315 retval = p_omx_swvdec->async_process_event_port_reconfig();
5316 break;
5317 }
5318
5319 case OMX_SWVDEC_EVENT_DIMENSIONS_UPDATED:
5320 {
5321 retval = p_omx_swvdec->async_process_event_dimensions_updated();
5322 break;
5323 }
5324
5325 default:
5326 {
5327 assert(0);
5328
5329 retval = OMX_ErrorUndefined;
5330 break;
5331 }
5332
5333 }
5334
5335 if (retval != OMX_ErrorNone)
5336 {
5337 p_omx_swvdec->async_post_event(OMX_SWVDEC_EVENT_ERROR, retval, 0);
5338 }
5339
5340 async_process_event_exit:
5341 return;
5342 }
5343
5344 /**
5345 * @brief Process command event.
5346 *
5347 * @param[in] cmd: Command.
5348 * @param[in] param: Command parameter.
5349 *
5350 * @retval OMX_ERRORTYPE
5351 */
async_process_event_cmd(OMX_COMMANDTYPE cmd,OMX_U32 param)5352 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd(OMX_COMMANDTYPE cmd,
5353 OMX_U32 param)
5354 {
5355 OMX_ERRORTYPE retval = OMX_ErrorNone;
5356
5357 bool cmd_ack = false;
5358
5359 switch (cmd)
5360 {
5361
5362 case OMX_CommandStateSet:
5363 {
5364 retval = async_process_event_cmd_state_set(&cmd_ack,
5365 (OMX_STATETYPE) param);
5366 break;
5367 }
5368
5369 case OMX_CommandFlush:
5370 {
5371 retval = async_process_event_cmd_flush((unsigned int) param);
5372 break;
5373 }
5374
5375 case OMX_CommandPortDisable:
5376 {
5377 retval = async_process_event_cmd_port_disable(&cmd_ack,
5378 (unsigned int) param);
5379 break;
5380 }
5381
5382 case OMX_CommandPortEnable:
5383 {
5384 retval = async_process_event_cmd_port_enable(&cmd_ack,
5385 (unsigned int) param);
5386 break;
5387 }
5388
5389 default:
5390 {
5391 OMX_SWVDEC_LOG_ERROR("cmd '%d' invalid", (int) cmd);
5392
5393 retval = OMX_ErrorBadParameter;
5394 break;
5395 }
5396
5397 } // switch (cmd)
5398
5399 if (retval != OMX_ErrorNone)
5400 {
5401 async_post_event(OMX_SWVDEC_EVENT_ERROR, retval, 0);
5402 }
5403 else if (cmd_ack)
5404 {
5405 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK, cmd, param);
5406 }
5407
5408 sem_post(&m_sem_cmd);
5409
5410 return retval;
5411 }
5412
5413 /**
5414 * @brief Process command acknowledgement event.
5415 *
5416 * @param[in] cmd: Command.
5417 * @param[in] param: Command parameter.
5418 *
5419 * @retval OMX_ERRORTYPE
5420 */
async_process_event_cmd_ack(OMX_COMMANDTYPE cmd,OMX_U32 param)5421 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_ack(OMX_COMMANDTYPE cmd,
5422 OMX_U32 param)
5423 {
5424 OMX_ERRORTYPE retval = OMX_ErrorNone;
5425
5426 switch (cmd)
5427 {
5428
5429 case OMX_CommandStateSet:
5430 {
5431 OMX_SWVDEC_LOG_HIGH("%s -> %s",
5432 OMX_STATETYPE_STRING(m_state),
5433 OMX_STATETYPE_STRING((OMX_STATETYPE) param));
5434
5435 m_state = (OMX_STATETYPE) param;
5436
5437 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventCmdComplete, "
5438 "OMX_CommandStateSet, %s",
5439 OMX_STATETYPE_STRING(m_state));
5440
5441 m_callback.EventHandler(&m_cmp,
5442 m_app_data,
5443 OMX_EventCmdComplete,
5444 OMX_CommandStateSet,
5445 (OMX_U32) m_state,
5446 NULL);
5447 break;
5448 }
5449
5450 case OMX_CommandFlush:
5451 case OMX_CommandPortEnable:
5452 case OMX_CommandPortDisable:
5453 {
5454 if ((cmd == OMX_CommandPortEnable) && m_port_reconfig_inprogress)
5455 {
5456 m_port_reconfig_inprogress = false;
5457 }
5458
5459 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventCmdComplete, "
5460 "%s, port index %d",
5461 OMX_COMMANDTYPE_STRING(cmd),
5462 param);
5463
5464 m_callback.EventHandler(&m_cmp,
5465 m_app_data,
5466 OMX_EventCmdComplete,
5467 cmd,
5468 param,
5469 NULL);
5470 break;
5471 }
5472
5473 default:
5474 {
5475 OMX_SWVDEC_LOG_ERROR("cmd '%d' invalid", (int) cmd);
5476
5477 retval = OMX_ErrorBadParameter;
5478 break;
5479 }
5480
5481 } // switch (cmd)
5482
5483 return retval;
5484 }
5485
5486 /**
5487 * @brief Process error event.
5488 *
5489 * @param[in] error_code: Error code.
5490 *
5491 * @retval OMX_ErrorNone
5492 */
async_process_event_error(OMX_ERRORTYPE error_code)5493 OMX_ERRORTYPE omx_swvdec::async_process_event_error(OMX_ERRORTYPE error_code)
5494 {
5495 if (error_code == OMX_ErrorInvalidState)
5496 {
5497 OMX_SWVDEC_LOG_HIGH("%s -> OMX_StateInvalid",
5498 OMX_STATETYPE_STRING(m_state));
5499
5500 m_state = OMX_StateInvalid;
5501 }
5502
5503 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventError, 0x%08x",
5504 error_code);
5505
5506 m_callback.EventHandler(&m_cmp,
5507 m_app_data,
5508 OMX_EventError,
5509 (OMX_U32) error_code,
5510 0,
5511 NULL);
5512
5513 return OMX_ErrorNone;
5514 }
5515
5516 /**
5517 * @brief Process OMX_CommandStateSet.
5518 *
5519 * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
5520 * @param[in] state_new: New state to which transition is requested.
5521 *
5522 * @retval OMX_ERRORTYPE
5523 */
async_process_event_cmd_state_set(bool * p_cmd_ack,OMX_STATETYPE state_new)5524 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_state_set(
5525 bool *p_cmd_ack,
5526 OMX_STATETYPE state_new)
5527 {
5528 OMX_ERRORTYPE retval = OMX_ErrorNone;
5529
5530 SWVDEC_STATUS retval_swvdec;
5531
5532 OMX_SWVDEC_LOG_HIGH("'%s-to-%s' requested",
5533 OMX_STATETYPE_STRING(m_state),
5534 OMX_STATETYPE_STRING(state_new));
5535
5536 /**
5537 * Only the following state transitions are allowed via CommandStateSet:
5538 *
5539 * LOADED -> IDLE -> EXECUTING
5540 * LOADED <- IDLE <- EXECUTING
5541 */
5542
5543 if (m_state == OMX_StateInvalid)
5544 {
5545 OMX_SWVDEC_LOG_ERROR("in state %s", OMX_STATETYPE_STRING(m_state));
5546
5547 retval = OMX_ErrorInvalidState;
5548 }
5549 else if (state_new == OMX_StateInvalid)
5550 {
5551 OMX_SWVDEC_LOG_ERROR("requested transition to state %s",
5552 OMX_STATETYPE_STRING(state_new));
5553
5554 retval = OMX_ErrorInvalidState;
5555 }
5556 else if ((m_state == OMX_StateLoaded) &&
5557 (state_new == OMX_StateIdle))
5558 {
5559 if ((m_port_ip.populated == OMX_TRUE) &&
5560 (m_port_op.populated == OMX_TRUE))
5561 {
5562 if ((retval_swvdec = swvdec_start(m_swvdec_handle)) ==
5563 SWVDEC_STATUS_SUCCESS)
5564 {
5565 *p_cmd_ack = true;
5566 }
5567 else
5568 {
5569 OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
5570
5571 retval = retval_swvdec2omx(retval_swvdec);
5572 }
5573 }
5574 else
5575 {
5576 m_status_flags |= (1 << PENDING_STATE_LOADED_TO_IDLE);
5577
5578 OMX_SWVDEC_LOG_LOW("'loaded-to-idle' pending");
5579 }
5580 }
5581 else if ((m_state == OMX_StateIdle) &&
5582 (state_new == OMX_StateExecuting))
5583 {
5584 *p_cmd_ack = true;
5585 }
5586 else if ((m_state == OMX_StateExecuting) &&
5587 (state_new == OMX_StateIdle))
5588 {
5589 m_status_flags |= (1 << PENDING_STATE_EXECUTING_TO_IDLE);
5590
5591 OMX_SWVDEC_LOG_LOW("'executing-to-idle' pending");
5592
5593 retval = flush(OMX_ALL);
5594 }
5595 else if ((m_state == OMX_StateIdle) &&
5596 (state_new == OMX_StateLoaded))
5597 {
5598 if ((m_port_ip.unpopulated == OMX_TRUE) &&
5599 (m_port_op.unpopulated == OMX_TRUE))
5600 {
5601 if ((retval_swvdec = swvdec_stop(m_swvdec_handle)) ==
5602 SWVDEC_STATUS_SUCCESS)
5603 {
5604 *p_cmd_ack = true;
5605 }
5606 else
5607 {
5608 OMX_SWVDEC_LOG_ERROR("failed to stop SwVdec");
5609
5610 retval = retval_swvdec2omx(retval_swvdec);
5611 }
5612 }
5613 else
5614 {
5615 m_status_flags |= (1 << PENDING_STATE_IDLE_TO_LOADED);
5616
5617 OMX_SWVDEC_LOG_LOW("'idle-to-loaded' pending");
5618 }
5619 }
5620 else
5621 {
5622 OMX_SWVDEC_LOG_ERROR("state transition '%s -> %s' illegal",
5623 OMX_STATETYPE_STRING(m_state),
5624 OMX_STATETYPE_STRING(state_new));
5625
5626 retval = ((state_new == m_state) ?
5627 OMX_ErrorSameState :
5628 OMX_ErrorIncorrectStateTransition);
5629 }
5630
5631 return retval;
5632 }
5633
5634 /**
5635 * @brief Process OMX_CommandFlush.
5636 *
5637 * @param[in] port_index: Index of port to flush.
5638 *
5639 * @retval OMX_ERRORTYPE
5640 */
async_process_event_cmd_flush(unsigned int port_index)5641 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_flush(unsigned int port_index)
5642 {
5643 OMX_ERRORTYPE retval = OMX_ErrorNone;
5644
5645 OMX_SWVDEC_LOG_HIGH("flush port index %d requested", port_index);
5646
5647 if (port_index == OMX_CORE_PORT_INDEX_IP)
5648 {
5649 m_status_flags |= (1 << PENDING_PORT_FLUSH_IP);
5650
5651 OMX_SWVDEC_LOG_LOW("ip port flush pending");
5652 }
5653 else if (port_index == OMX_CORE_PORT_INDEX_OP)
5654 {
5655 m_status_flags |= (1 << PENDING_PORT_FLUSH_OP);
5656
5657 OMX_SWVDEC_LOG_LOW("op port flush pending");
5658 }
5659 else if (port_index == OMX_ALL)
5660 {
5661 m_status_flags |= (1 << PENDING_PORT_FLUSH_IP);
5662 m_status_flags |= (1 << PENDING_PORT_FLUSH_OP);
5663
5664 OMX_SWVDEC_LOG_LOW("ip & op ports flush pending");
5665 }
5666
5667 retval = flush(port_index);
5668
5669 return retval;
5670 }
5671
5672 /**
5673 * @brief Process OMX_CommandPortDisable.
5674 *
5675 * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
5676 * @param[in] port_index: Index of port to disable.
5677 *
5678 * @retval OMX_ERRORTYPE
5679 */
async_process_event_cmd_port_disable(bool * p_cmd_ack,unsigned int port_index)5680 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_port_disable(
5681 bool *p_cmd_ack,
5682 unsigned int port_index)
5683 {
5684 OMX_ERRORTYPE retval = OMX_ErrorNone;
5685
5686 OMX_SWVDEC_LOG_HIGH("disable port index %d requested", port_index);
5687
5688 if (port_index == OMX_CORE_PORT_INDEX_IP)
5689 {
5690 if (m_port_ip.enabled == OMX_FALSE)
5691 {
5692 OMX_SWVDEC_LOG_ERROR("ip port already disabled");
5693
5694 retval = OMX_ErrorBadPortIndex;
5695 }
5696 else
5697 {
5698 m_port_ip.enabled = OMX_FALSE;
5699
5700 if (m_port_ip.unpopulated)
5701 {
5702 *p_cmd_ack = true;
5703 }
5704 else
5705 {
5706 m_status_flags |= (1 << PENDING_PORT_DISABLE_IP);
5707
5708 OMX_SWVDEC_LOG_LOW("ip port disable pending");
5709
5710 if (m_port_ip.num_pending_buffers)
5711 {
5712 retval = flush(port_index);
5713 }
5714 }
5715 }
5716 }
5717 else if (port_index == OMX_CORE_PORT_INDEX_OP)
5718 {
5719 if (m_port_op.enabled == OMX_FALSE)
5720 {
5721 OMX_SWVDEC_LOG_ERROR("op port already disabled");
5722
5723 retval = OMX_ErrorBadPortIndex;
5724 }
5725 else
5726 {
5727 m_port_op.enabled = OMX_FALSE;
5728
5729 if (m_port_op.unpopulated)
5730 {
5731 *p_cmd_ack = true;
5732 }
5733 else
5734 {
5735 m_status_flags |= (1 << PENDING_PORT_DISABLE_OP);
5736
5737 OMX_SWVDEC_LOG_LOW("op port disable pending");
5738
5739 if (m_port_op.num_pending_buffers)
5740 {
5741 retval = flush(port_index);
5742 }
5743 }
5744 }
5745 }
5746 else if (port_index == OMX_ALL)
5747 {
5748 if (m_port_ip.enabled == OMX_FALSE)
5749 {
5750 OMX_SWVDEC_LOG_ERROR("ip port already disabled");
5751
5752 retval = OMX_ErrorBadPortIndex;
5753 }
5754 else if (m_port_op.enabled == OMX_FALSE)
5755 {
5756 OMX_SWVDEC_LOG_ERROR("op port already disabled");
5757
5758 retval = OMX_ErrorBadPortIndex;
5759 }
5760 else
5761 {
5762 if (m_port_ip.unpopulated && m_port_op.unpopulated)
5763 {
5764 *p_cmd_ack = true;
5765 }
5766 else
5767 {
5768 m_port_ip.enabled = OMX_FALSE;
5769 m_port_op.enabled = OMX_FALSE;
5770
5771 if (m_port_ip.unpopulated == OMX_FALSE)
5772 {
5773 m_status_flags |= (1 << PENDING_PORT_DISABLE_IP);
5774
5775 OMX_SWVDEC_LOG_LOW("ip port disable pending");
5776
5777 if (m_port_ip.num_pending_buffers)
5778 {
5779 retval = flush(port_index);
5780 }
5781 }
5782
5783 if ((retval == OMX_ErrorNone) &&
5784 (m_port_op.unpopulated == OMX_FALSE))
5785 {
5786 m_status_flags |= (1 << PENDING_PORT_DISABLE_OP);
5787
5788 OMX_SWVDEC_LOG_LOW("op port disable pending");
5789
5790 if (m_port_op.num_pending_buffers)
5791 {
5792 retval = flush(port_index);
5793 }
5794 }
5795 }
5796 }
5797 }
5798 else
5799 {
5800 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
5801 port_index);
5802
5803 retval = OMX_ErrorBadPortIndex;
5804 }
5805
5806 return retval;
5807 }
5808
5809 /**
5810 * @brief Process OMX_CommandPortEnable.
5811 *
5812 * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
5813 * @param[in] port_index: Index of port to enable.
5814 *
5815 * @retval OMX_ERRORTYPE
5816 */
async_process_event_cmd_port_enable(bool * p_cmd_ack,unsigned int port_index)5817 OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_port_enable(
5818 bool *p_cmd_ack,
5819 unsigned int port_index)
5820 {
5821 OMX_ERRORTYPE retval = OMX_ErrorNone;
5822
5823 OMX_SWVDEC_LOG_HIGH("enable port index %d requested", port_index);
5824
5825 if (port_index == OMX_CORE_PORT_INDEX_IP)
5826 {
5827 if (m_port_ip.enabled)
5828 {
5829 OMX_SWVDEC_LOG_ERROR("ip port already enabled");
5830
5831 retval = OMX_ErrorBadPortIndex;
5832 }
5833 else
5834 {
5835 m_port_ip.enabled = OMX_TRUE;
5836
5837 if (m_port_ip.populated)
5838 {
5839 *p_cmd_ack = true;
5840 }
5841 else
5842 {
5843 m_status_flags |= (1 << PENDING_PORT_ENABLE_IP);
5844
5845 OMX_SWVDEC_LOG_LOW("ip port enable pending");
5846 }
5847 }
5848 }
5849 else if (port_index == OMX_CORE_PORT_INDEX_OP)
5850 {
5851 if (m_port_op.enabled)
5852 {
5853 OMX_SWVDEC_LOG_ERROR("op port already enabled");
5854
5855 retval = OMX_ErrorBadPortIndex;
5856 }
5857 else
5858 {
5859 m_port_op.enabled = OMX_TRUE;
5860
5861 if (m_port_op.populated)
5862 {
5863 *p_cmd_ack = true;
5864 }
5865 else
5866 {
5867 m_status_flags |= (1 << PENDING_PORT_ENABLE_OP);
5868
5869 OMX_SWVDEC_LOG_LOW("op port enable pending");
5870 }
5871 }
5872 }
5873 else if (port_index == OMX_ALL)
5874 {
5875 if (m_port_ip.enabled)
5876 {
5877 OMX_SWVDEC_LOG_ERROR("ip port already enabled");
5878
5879 retval = OMX_ErrorBadPortIndex;
5880 }
5881 else if (m_port_op.enabled)
5882 {
5883 OMX_SWVDEC_LOG_ERROR("op port already enabled");
5884
5885 retval = OMX_ErrorBadPortIndex;
5886 }
5887 else
5888 {
5889 m_port_ip.enabled = OMX_TRUE;
5890 m_port_op.enabled = OMX_TRUE;
5891
5892 if (m_port_ip.populated && m_port_op.populated)
5893 {
5894 *p_cmd_ack = true;
5895 }
5896 else if (m_port_ip.populated == false)
5897 {
5898 m_status_flags |= (1 << PENDING_PORT_ENABLE_IP);
5899
5900 OMX_SWVDEC_LOG_LOW("ip port enable pending");
5901 }
5902 else if (m_port_op.populated == false)
5903 {
5904 m_status_flags |= (1 << PENDING_PORT_ENABLE_OP);
5905
5906 OMX_SWVDEC_LOG_LOW("op port enable pending");
5907 }
5908 }
5909 }
5910 else
5911 {
5912 OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
5913 port_index);
5914
5915 retval = OMX_ErrorBadPortIndex;
5916 }
5917
5918 return retval;
5919 }
5920
5921 /**
5922 * @brief Process ETB event.
5923 *
5924 * @param[in] p_buffer_hdr: Pointer to buffer header.
5925 * @param[in] index: Index of buffer in input buffer info array.
5926 *
5927 * @retval OMX_ERRORTYPE
5928 */
async_process_event_etb(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)5929 OMX_ERRORTYPE omx_swvdec::async_process_event_etb(
5930 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
5931 unsigned int index)
5932 {
5933 OMX_ERRORTYPE retval = OMX_ErrorNone;
5934
5935 m_port_ip.num_pending_buffers++;
5936
5937 if ((p_buffer_hdr->nFilledLen == 0) &&
5938 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5939 {
5940 OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p,"
5941 "zero length & no EOS flag",
5942 p_buffer_hdr,
5943 p_buffer_hdr->pBuffer);
5944
5945 async_post_event(OMX_SWVDEC_EVENT_EBD,
5946 (unsigned long) p_buffer_hdr,
5947 (unsigned long) index);
5948 }
5949 else if (m_port_ip.flush_inprogress)
5950 {
5951 OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p; "
5952 "ip port flush in progress",
5953 p_buffer_hdr,
5954 p_buffer_hdr->pBuffer);
5955
5956 async_post_event(OMX_SWVDEC_EVENT_EBD,
5957 (unsigned long) p_buffer_hdr,
5958 (unsigned long) index);
5959 }
5960 else
5961 {
5962 SWVDEC_STATUS retval_swvdec;
5963
5964 SWVDEC_BUFFER *p_buffer_swvdec =
5965 &(m_buffer_array_ip[index].buffer_swvdec);
5966
5967 if (p_buffer_hdr->nFilledLen &&
5968 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == 0))
5969 {
5970 m_queue_timestamp.push(p_buffer_hdr->nTimeStamp);
5971 }
5972
5973 assert(p_buffer_swvdec->p_buffer == p_buffer_hdr->pBuffer);
5974 //sending the fd info
5975 p_buffer_swvdec->fd = m_buffer_array_ip[index].buffer_payload.pmem_fd;
5976 if (m_arbitrary_bytes_mode &&
5977 p_buffer_hdr->nFilledLen &&
5978 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == 0))
5979 {
5980 unsigned int offset_array[OMX_SWVDEC_MAX_FRAMES_PER_ETB] = {0};
5981
5982 unsigned int num_frame_headers = 1;
5983
5984 if ((m_omx_video_codingtype ==
5985 ((OMX_VIDEO_CODINGTYPE) QOMX_VIDEO_CodingDivx)) ||
5986 (m_omx_video_codingtype == OMX_VIDEO_CodingMPEG4))
5987 {
5988 num_frame_headers = split_buffer_mpeg4(offset_array,
5989 p_buffer_hdr);
5990 }
5991 else
5992 {
5993 assert(0);
5994 }
5995
5996 if(num_frame_headers > 1)
5997 {
5998 m_buffer_array_ip[index].split_count = num_frame_headers - 1;
5999
6000 for (unsigned int ii = 0; ii < num_frame_headers; ii++)
6001 {
6002 p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
6003 p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
6004
6005 if (ii == 0)
6006 {
6007 p_buffer_swvdec->offset = 0;
6008 p_buffer_swvdec->filled_length = (offset_array[ii + 1] ?
6009 offset_array[ii + 1] :
6010 p_buffer_hdr->nFilledLen);
6011 }
6012 else
6013 {
6014 p_buffer_swvdec->offset = offset_array[ii];
6015 p_buffer_swvdec->filled_length =
6016 p_buffer_hdr->nFilledLen - offset_array[ii];
6017 }
6018
6019 m_diag.dump_ip(p_buffer_swvdec->p_buffer +
6020 p_buffer_swvdec->offset,
6021 p_buffer_swvdec->filled_length);
6022
6023 retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
6024 p_buffer_swvdec);
6025
6026 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6027 {
6028 retval = retval_swvdec2omx(retval_swvdec);
6029 break;
6030 }
6031 }
6032 }
6033 else
6034 {
6035 OMX_SWVDEC_LOG_HIGH("No frame detected for Buffer %p, with TS %lld",
6036 p_buffer_hdr->pBuffer, p_buffer_hdr->nTimeStamp );
6037
6038 p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
6039 p_buffer_swvdec->offset = 0;
6040 p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
6041 p_buffer_swvdec->filled_length = p_buffer_hdr->nFilledLen;
6042
6043 m_diag.dump_ip(p_buffer_swvdec->p_buffer + p_buffer_swvdec->offset,
6044 p_buffer_swvdec->filled_length);
6045
6046 retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
6047 p_buffer_swvdec);
6048
6049 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6050 {
6051 retval = retval_swvdec2omx(retval_swvdec);
6052 }
6053 }
6054 }
6055 else
6056 {
6057 p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
6058 p_buffer_swvdec->offset = 0;
6059 p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
6060 p_buffer_swvdec->filled_length = p_buffer_hdr->nFilledLen;
6061
6062 m_diag.dump_ip(p_buffer_swvdec->p_buffer + p_buffer_swvdec->offset,
6063 p_buffer_swvdec->filled_length);
6064
6065 retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
6066 p_buffer_swvdec);
6067
6068 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6069 {
6070 retval = retval_swvdec2omx(retval_swvdec);
6071 }
6072 }
6073 }
6074 return retval;
6075 }
6076
6077 /**
6078 * @brief Process FTB event.
6079 *
6080 * @param[in] p_buffer_hdr: Pointer to buffer header.
6081 * @param[in] index: Index of buffer in output buffer info array.
6082 *
6083 * @retval OMX_ERRORTYPE
6084 */
async_process_event_ftb(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)6085 OMX_ERRORTYPE omx_swvdec::async_process_event_ftb(
6086 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
6087 unsigned int index)
6088 {
6089 OMX_ERRORTYPE retval = OMX_ErrorNone;
6090
6091 m_port_op.num_pending_buffers++;
6092
6093 if (m_port_op.flush_inprogress)
6094 {
6095 OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p; "
6096 "op port flush in progress",
6097 p_buffer_hdr,
6098 m_buffer_array_op[index].buffer_swvdec.p_buffer);
6099
6100 async_post_event(OMX_SWVDEC_EVENT_FBD,
6101 (unsigned long) p_buffer_hdr,
6102 (unsigned long) index);
6103 }
6104 else
6105 {
6106 SWVDEC_STATUS retval_swvdec;
6107
6108 SWVDEC_BUFFER *p_buffer_swvdec =
6109 &(m_buffer_array_op[index].buffer_swvdec);
6110 p_buffer_swvdec->fd = m_buffer_array_op[index].buffer_payload.pmem_fd;
6111 retval_swvdec = swvdec_fillthisbuffer(m_swvdec_handle, p_buffer_swvdec);
6112
6113 if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
6114 {
6115 retval = retval_swvdec2omx(retval_swvdec);
6116 }
6117 }
6118
6119 return retval;
6120 }
6121
6122 /**
6123 * @brief Process EBD event.
6124 *
6125 * @param[in] p_buffer_hdr: Pointer to buffer header.
6126 * @param[in] index: Index of buffer in output buffer info array.
6127 *
6128 * @retval OMX_ERRORTYPE
6129 */
async_process_event_ebd(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)6130 OMX_ERRORTYPE omx_swvdec::async_process_event_ebd(
6131 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
6132 unsigned int index)
6133 {
6134 OMX_ERRORTYPE retval = OMX_ErrorNone;
6135
6136 if (index < m_port_ip.def.nBufferCountActual)
6137 {
6138 if (m_arbitrary_bytes_mode && m_buffer_array_ip[index].split_count)
6139 {
6140 m_buffer_array_ip[index].split_count--;
6141 }
6142 else
6143 {
6144 m_port_ip.num_pending_buffers--;
6145
6146 OMX_SWVDEC_LOG_CALLBACK(
6147 "EmptyBufferDone(): %p, buffer %p",
6148 p_buffer_hdr,
6149 m_buffer_array_ip[index].buffer_swvdec.p_buffer);
6150
6151 m_callback.EmptyBufferDone(&m_cmp, m_app_data, p_buffer_hdr);
6152 }
6153 }
6154 else
6155 {
6156 OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
6157
6158 retval = OMX_ErrorBadParameter;
6159 }
6160
6161 return retval;
6162 }
6163
6164 /**
6165 * @brief Process FBD event.
6166 *
6167 * @param[in] p_buffer_hdr: Pointer to buffer header.
6168 * @param[in] index: Index of buffer in output buffer info array.
6169 *
6170 * @retval OMX_ERRORTYPE
6171 */
async_process_event_fbd(OMX_BUFFERHEADERTYPE * p_buffer_hdr,unsigned int index)6172 OMX_ERRORTYPE omx_swvdec::async_process_event_fbd(
6173 OMX_BUFFERHEADERTYPE *p_buffer_hdr,
6174 unsigned int index)
6175 {
6176 OMX_ERRORTYPE retval = OMX_ErrorNone;
6177
6178 static long long timestamp_prev = 0;
6179
6180 if (index < m_port_op.def.nBufferCountActual)
6181 {
6182 OMX_U8 *p_buffer;
6183
6184 p_buffer = m_buffer_array_op[index].buffer_swvdec.p_buffer;
6185
6186 m_port_op.num_pending_buffers--;
6187
6188 if (m_port_op.flush_inprogress)
6189 {
6190 p_buffer_hdr->nFilledLen = 0;
6191 p_buffer_hdr->nTimeStamp = 0;
6192 p_buffer_hdr->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6193 }
6194
6195 if (p_buffer_hdr->nFilledLen)
6196 {
6197 if (m_sync_frame_decoding_mode)
6198 {
6199 OMX_SWVDEC_LOG_LOW("sync frame decoding mode; "
6200 "setting timestamp to zero");
6201
6202 p_buffer_hdr->nTimeStamp = 0;
6203 }
6204 else
6205 {
6206 if (m_queue_timestamp.empty())
6207 {
6208 OMX_SWVDEC_LOG_ERROR("timestamp queue empty; "
6209 "re-using previous timestamp %lld",
6210 timestamp_prev);
6211
6212 p_buffer_hdr->nTimeStamp = timestamp_prev;
6213 }
6214 else
6215 {
6216 p_buffer_hdr->nTimeStamp = m_queue_timestamp.top();
6217
6218 m_queue_timestamp.pop();
6219
6220 timestamp_prev = p_buffer_hdr->nTimeStamp;
6221 }
6222 }
6223
6224 ion_flush_op(index);
6225
6226 if (m_meta_buffer_mode)
6227 {
6228 pthread_mutex_lock(&m_meta_buffer_array_mutex);
6229 }
6230
6231 m_diag.dump_op(p_buffer,
6232 m_frame_dimensions.width,
6233 m_frame_dimensions.height,
6234 m_frame_attributes.stride,
6235 m_frame_attributes.scanlines);
6236
6237 if (m_meta_buffer_mode)
6238 {
6239 pthread_mutex_unlock(&m_meta_buffer_array_mutex);
6240 }
6241 }
6242 else
6243 {
6244 OMX_SWVDEC_LOG_LOW("filled length zero; "
6245 "setting timestamp to zero");
6246
6247 p_buffer_hdr->nTimeStamp = 0;
6248 }
6249
6250 if (p_buffer_hdr->nFlags & OMX_BUFFERFLAG_EOS)
6251 {
6252 async_post_event(OMX_SWVDEC_EVENT_EOS, 0, 0);
6253
6254 OMX_SWVDEC_LOG_LOW("flushing %zu elements in timestamp queue",
6255 m_queue_timestamp.size());
6256
6257 while (m_queue_timestamp.empty() == false)
6258 {
6259 m_queue_timestamp.pop();
6260 }
6261 }
6262
6263 if (m_meta_buffer_mode &&
6264 ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_READONLY)) == 0)
6265 {
6266 meta_buffer_ref_remove(index);
6267 }
6268
6269 OMX_SWVDEC_LOG_CALLBACK(
6270 "FillBufferDone(): %p, buffer %p, "
6271 "flags 0x%08x, filled length %d, timestamp %lld",
6272 p_buffer_hdr,
6273 p_buffer,
6274 p_buffer_hdr->nFlags,
6275 p_buffer_hdr->nFilledLen,
6276 p_buffer_hdr->nTimeStamp);
6277
6278 m_callback.FillBufferDone(&m_cmp, m_app_data, p_buffer_hdr);
6279 }
6280 else
6281 {
6282 OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
6283
6284 retval = OMX_ErrorBadParameter;
6285 }
6286
6287 return retval;
6288 }
6289
6290 /**
6291 * @brief Process EOS event.
6292 *
6293 * @retval OMX_ErrorNone
6294 */
async_process_event_eos()6295 OMX_ERRORTYPE omx_swvdec::async_process_event_eos()
6296 {
6297 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
6298 "OMX_EventBufferFlag, port index %d, EOS",
6299 OMX_CORE_PORT_INDEX_OP);
6300
6301 m_callback.EventHandler(&m_cmp,
6302 m_app_data,
6303 OMX_EventBufferFlag,
6304 OMX_CORE_PORT_INDEX_OP,
6305 OMX_BUFFERFLAG_EOS,
6306 NULL);
6307
6308 return OMX_ErrorNone;
6309 }
6310
6311 /**
6312 * @brief Process input port flush event.
6313 *
6314 * @retval OMX_ERRORTYPE
6315 */
async_process_event_flush_port_ip()6316 OMX_ERRORTYPE omx_swvdec::async_process_event_flush_port_ip()
6317 {
6318 OMX_ERRORTYPE retval = OMX_ErrorNone;
6319
6320 OMX_SWVDEC_EVENT_INFO event_info;
6321
6322 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
6323
6324 unsigned int index;
6325
6326 while (m_queue_port_ip.pop(&event_info))
6327 {
6328 switch (event_info.event_id)
6329 {
6330
6331 case OMX_SWVDEC_EVENT_ETB:
6332 {
6333 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6334
6335 index = event_info.event_param2;
6336
6337 // compensate decrement in async_process_event_ebd()
6338 m_port_ip.num_pending_buffers++;
6339
6340 retval = async_process_event_ebd(p_buffer_hdr, index);
6341 break;
6342 }
6343
6344 case OMX_SWVDEC_EVENT_EBD:
6345 {
6346 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6347
6348 index = event_info.event_param2;
6349
6350 retval = async_process_event_ebd(p_buffer_hdr, index);
6351 break;
6352 }
6353
6354 default:
6355 {
6356 assert(0);
6357 break;
6358 }
6359
6360 }
6361 }
6362
6363 assert(m_port_ip.num_pending_buffers == 0);
6364
6365 if ((retval == OMX_ErrorNone) &&
6366 (m_status_flags & (1 << PENDING_PORT_FLUSH_IP)))
6367 {
6368 m_status_flags &= ~(1 << PENDING_PORT_FLUSH_IP);
6369
6370 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
6371 OMX_CommandFlush,
6372 OMX_CORE_PORT_INDEX_IP);
6373 }
6374
6375 m_port_ip.flush_inprogress = OMX_FALSE;
6376
6377 return retval;
6378 }
6379
6380 /**
6381 * @brief Process output port flush event.
6382 *
6383 * @retval OMX_ERRORTYPE
6384 */
async_process_event_flush_port_op()6385 OMX_ERRORTYPE omx_swvdec::async_process_event_flush_port_op()
6386 {
6387 OMX_ERRORTYPE retval = OMX_ErrorNone;
6388
6389 OMX_SWVDEC_EVENT_INFO event_info;
6390
6391 OMX_BUFFERHEADERTYPE *p_buffer_hdr;
6392
6393 unsigned int index;
6394
6395 while (m_queue_port_op.pop(&event_info))
6396 {
6397 switch (event_info.event_id)
6398 {
6399
6400 case OMX_SWVDEC_EVENT_FTB:
6401 {
6402 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6403
6404 index = event_info.event_param2;
6405
6406 // compensate decrement in async_process_event_fbd()
6407 m_port_op.num_pending_buffers++;
6408
6409 retval = async_process_event_fbd(p_buffer_hdr, index);
6410 break;
6411 }
6412
6413 case OMX_SWVDEC_EVENT_FBD:
6414 {
6415 p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
6416
6417 index = event_info.event_param2;
6418
6419 retval = async_process_event_fbd(p_buffer_hdr, index);
6420 break;
6421 }
6422
6423 default:
6424 {
6425 assert(0);
6426 break;
6427 }
6428
6429 }
6430 }
6431
6432 assert(m_port_op.num_pending_buffers == 0);
6433
6434 if ((retval == OMX_ErrorNone) &&
6435 (m_status_flags & (1 << PENDING_PORT_FLUSH_OP)))
6436 {
6437 m_status_flags &= ~(1 << PENDING_PORT_FLUSH_OP);
6438
6439 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
6440 OMX_CommandFlush,
6441 OMX_CORE_PORT_INDEX_OP);
6442 }
6443
6444 if ((retval == OMX_ErrorNone) &&
6445 (m_status_flags & (1 << PENDING_STATE_EXECUTING_TO_IDLE)))
6446 {
6447 m_status_flags &= ~(1 << PENDING_STATE_EXECUTING_TO_IDLE);
6448
6449 async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
6450 OMX_CommandStateSet,
6451 OMX_StateIdle);
6452 }
6453
6454 if (m_port_reconfig_inprogress == false)
6455 {
6456 OMX_SWVDEC_LOG_LOW("flushing %zu elements in timestamp queue",
6457 m_queue_timestamp.size());
6458
6459 while (m_queue_timestamp.empty() == false)
6460 {
6461 m_queue_timestamp.pop();
6462 }
6463 }
6464
6465 m_port_op.flush_inprogress = OMX_FALSE;
6466
6467 return retval;
6468 }
6469
6470 /**
6471 * @brief Process port reconfiguration event.
6472 *
6473 * @retval OMX_ERRORTYPE
6474 */
async_process_event_port_reconfig()6475 OMX_ERRORTYPE omx_swvdec::async_process_event_port_reconfig()
6476 {
6477 OMX_ERRORTYPE retval = OMX_ErrorNone;
6478
6479 if (m_port_reconfig_inprogress)
6480 {
6481 OMX_SWVDEC_LOG_ERROR("port reconfiguration already in progress");
6482
6483 retval = OMX_ErrorIncorrectStateOperation;
6484 }
6485 else
6486 {
6487 m_port_reconfig_inprogress = true;
6488
6489 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
6490 "OMX_EventPortSettingsChanged, port index %d",
6491 OMX_CORE_PORT_INDEX_OP);
6492
6493 m_callback.EventHandler(&m_cmp,
6494 m_app_data,
6495 OMX_EventPortSettingsChanged,
6496 OMX_CORE_PORT_INDEX_OP,
6497 OMX_IndexParamPortDefinition,
6498 NULL);
6499 }
6500
6501 return retval;
6502 }
6503
6504 /**
6505 * @brief Process dimensions updated event.
6506 *
6507 * @retval OMX_ERRORTYPE
6508 */
async_process_event_dimensions_updated()6509 OMX_ERRORTYPE omx_swvdec::async_process_event_dimensions_updated()
6510 {
6511 OMX_ERRORTYPE retval = OMX_ErrorNone;
6512
6513 if (m_dimensions_update_inprogress)
6514 {
6515 OMX_SWVDEC_LOG_ERROR("dimensions update already in progress");
6516
6517 retval = OMX_ErrorIncorrectStateOperation;
6518 }
6519 else
6520 {
6521 m_dimensions_update_inprogress = true;
6522
6523 OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
6524 "OMX_EventPortSettingsChanged, port index %d, "
6525 "OMX_IndexConfigCommonOutputCrop",
6526 OMX_CORE_PORT_INDEX_OP);
6527
6528 m_callback.EventHandler(&m_cmp,
6529 m_app_data,
6530 OMX_EventPortSettingsChanged,
6531 OMX_CORE_PORT_INDEX_OP,
6532 OMX_IndexConfigCommonOutputCrop,
6533 NULL);
6534 }
6535
6536 return retval;
6537 }
6538
6539 /**
6540 * @brief Map the memory and run the ioctl SYNC operations
6541 *.on ION fd with DMA_BUF_IOCTL_SYNC
6542 *.@param[in] fd: ION header.
6543 * @param[in] len:Lenth of the memory.
6544 * @retval mapped memory pointer
6545 */
ion_map(int fd,int len)6546 unsigned char *omx_swvdec::ion_map(int fd, int len)
6547 {
6548 unsigned char *bufaddr = (unsigned char*)mmap(NULL, len, PROT_READ|PROT_WRITE,
6549 MAP_SHARED, fd, 0);
6550 if (bufaddr != MAP_FAILED) {
6551 #ifdef USE_ION
6552 struct dma_buf_sync buf_sync;
6553 buf_sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
6554 int rc = ioctl(fd, DMA_BUF_IOCTL_SYNC, &buf_sync);
6555 if (rc) {
6556 OMX_SWVDEC_LOG_ERROR("Failed DMA_BUF_IOCTL_SYNC");
6557 }
6558 #endif
6559 }
6560 return bufaddr;
6561 }
6562
6563 /**
6564 * @brief Unmap the memory
6565 *.@param[in] fd: ION header.
6566 .*.@param[in].bufaddr : buffer address
6567 * @param[in] len:Lenth of the memory.
6568 * @retval OMX_ERRORTYPE
6569 */
ion_unmap(int fd,void * bufaddr,int len)6570 OMX_ERRORTYPE omx_swvdec::ion_unmap(int fd, void *bufaddr, int len)
6571 {
6572 #ifdef USE_ION
6573 struct dma_buf_sync buf_sync;
6574 buf_sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
6575 int rc = ioctl(fd, DMA_BUF_IOCTL_SYNC, &buf_sync);
6576 if (rc) {
6577 OMX_SWVDEC_LOG_ERROR("Failed DMA_BUF_IOCTL_SYNC");
6578 }
6579 #endif
6580 if (-1 == munmap(bufaddr, len)) {
6581 OMX_SWVDEC_LOG_ERROR("munmap failed.");
6582 return OMX_ErrorInsufficientResources;
6583 }
6584 return OMX_ErrorNone;
6585 }
6586
6587