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