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