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