1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2021, Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
11 * Neither the name of The Linux Foundation nor
12 the names of its contributors may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28 /*============================================================================
29 O p e n M A X w r a p p e r s
30 O p e n M A X C o r e
31
32 *//** @file omx_video_base.cpp
33 This module contains the implementation of the OpenMAX core & component.
34
35 *//*========================================================================*/
36
37 //////////////////////////////////////////////////////////////////////////////
38 // Include Files
39 //////////////////////////////////////////////////////////////////////////////
40
41 #define __STDC_FORMAT_MACROS //enables the format specifiers in inttypes.h
42 #include <inttypes.h>
43 #include <string.h>
44 #include <qdMetaData.h>
45 #include "omx_video_base.h"
46 #include "fastcv.h"
47 #include <stdlib.h>
48 #include <errno.h>
49 #include <fcntl.h>
50 #include <unistd.h>
51 #include <sys/prctl.h>
52 #include <sys/ioctl.h>
53 #ifdef _ANDROID_ICS_
54 #include <media/hardware/HardwareAPI.h>
55 #include <gralloc_priv.h>
56 #endif
57 #ifdef _USE_GLIB_
58 #include <glib.h>
59 #define strlcpy g_strlcpy
60 #endif
61 #define H264_SUPPORTED_WIDTH (480)
62 #define H264_SUPPORTED_HEIGHT (368)
63
64 #define VC1_SP_MP_START_CODE 0xC5000000
65 #define VC1_SP_MP_START_CODE_MASK 0xFF000000
66 #define VC1_AP_START_CODE 0x00000100
67 #define VC1_AP_START_CODE_MASK 0xFFFFFF00
68 #define VC1_STRUCT_C_PROFILE_MASK 0xF0
69 #define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
70 #define VC1_SIMPLE_PROFILE 0
71 #define VC1_MAIN_PROFILE 1
72 #define VC1_ADVANCE_PROFILE 3
73 #define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
74 #define VC1_SIMPLE_PROFILE_MED_LEVEL 2
75 #define VC1_STRUCT_C_LEN 4
76 #define VC1_STRUCT_C_POS 8
77 #define VC1_STRUCT_A_POS 12
78 #define VC1_STRUCT_B_POS 24
79 #define VC1_SEQ_LAYER_SIZE 36
80
81 #define SZ_4K 0x1000
82 #define SZ_1M 0x100000
83 #undef ALIGN
84 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
85
86 #ifndef ION_FLAG_CP_BITSTREAM
87 #define ION_FLAG_CP_BITSTREAM 0
88 #endif
89
90 #ifndef ION_FLAG_CP_PIXEL
91 #define ION_FLAG_CP_PIXEL 0
92 #endif
93
94 #undef MEM_HEAP_ID
95
96 #ifdef SLAVE_SIDE_CP
97 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID
98 #define SECURE_ALIGN SZ_1M
99 #define SECURE_FLAGS_INPUT_BUFFER ION_FLAG_SECURE
100 #define SECURE_FLAGS_OUTPUT_BUFFER ION_FLAG_SECURE
101 #else //MASTER_SIDE_CP
102 #define MEM_HEAP_ID ION_SECURE_HEAP_ID
103 #define SECURE_ALIGN SZ_4K
104 #define SECURE_FLAGS_INPUT_BUFFER (ION_FLAG_SECURE | ION_FLAG_CP_PIXEL)
105 #define SECURE_FLAGS_OUTPUT_BUFFER (ION_FLAG_SECURE | ION_FLAG_CP_BITSTREAM)
106 #endif
107
108 // Gralloc flag to indicate UBWC
109 #define GRALLOC1_CONSUMER_USAGE_UBWC_FLAG GRALLOC1_CONSUMER_USAGE_PRIVATE_0
110
111 typedef struct OMXComponentCapabilityFlagsType {
112 ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS
113 OMX_U32 nSize;
114 OMX_VERSIONTYPE nVersion;
115 OMX_BOOL iIsOMXComponentMultiThreaded;
116 OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc;
117 OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc;
118 OMX_BOOL iOMXComponentSupportsMovableInputBuffers;
119 OMX_BOOL iOMXComponentSupportsPartialFrames;
120 OMX_BOOL iOMXComponentUsesNALStartCodes;
121 OMX_BOOL iOMXComponentCanHandleIncompleteFrames;
122 OMX_BOOL iOMXComponentUsesFullAVCFrames;
123
124 } OMXComponentCapabilityFlagsType;
125 #define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347
126
message_thread_enc(void * input)127 void* message_thread_enc(void *input)
128 {
129 omx_video* omx = reinterpret_cast<omx_video*>(input);
130 int ret;
131
132 DEBUG_PRINT_HIGH("omx_venc: message thread start");
133 prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0);
134 while (!omx->msg_thread_stop) {
135 ret = omx->signal.wait(2 * 1000000000);
136 if (ret == ETIMEDOUT || omx->msg_thread_stop) {
137 continue;
138 } else if (ret) {
139 DEBUG_PRINT_ERROR("omx_venc: message_thread_enc wait on condition failed, exiting");
140 break;
141 }
142 omx->process_event_cb(omx);
143 }
144 DEBUG_PRINT_HIGH("omx_venc: message thread stop");
145 return 0;
146 }
147
post_message(omx_video * omx,unsigned char id)148 void post_message(omx_video *omx, unsigned char id)
149 {
150 DEBUG_PRINT_LOW("omx_venc: post_message %d", id);
151 omx->signal.signal();
152 }
153
154 // omx_cmd_queue destructor
~omx_cmd_queue()155 omx_video::omx_cmd_queue::~omx_cmd_queue()
156 {
157 // Nothing to do
158 }
159
160 // omx cmd queue constructor
omx_cmd_queue()161 omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
162 {
163 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
164 }
165
166 // omx cmd queue insert
insert_entry(unsigned long p1,unsigned long p2,unsigned long id)167 bool omx_video::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id)
168 {
169 bool ret = true;
170 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
171 m_q[m_write].id = id;
172 m_q[m_write].param1 = p1;
173 m_q[m_write].param2 = p2;
174 m_write++;
175 m_size ++;
176 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
177 m_write = 0;
178 }
179 } else {
180 ret = false;
181 DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full");
182 }
183 return ret;
184 }
185
186 // omx cmd queue pop
pop_entry(unsigned long * p1,unsigned long * p2,unsigned long * id)187 bool omx_video::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id)
188 {
189 bool ret = true;
190 if (m_size > 0) {
191 *id = m_q[m_read].id;
192 *p1 = m_q[m_read].param1;
193 *p2 = m_q[m_read].param2;
194 // Move the read pointer ahead
195 ++m_read;
196 --m_size;
197 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
198 m_read = 0;
199 }
200 } else {
201 ret = false;
202 }
203 return ret;
204 }
205
206 // Retrieve the first mesg type in the queue
get_q_msg_type()207 unsigned omx_video::omx_cmd_queue::get_q_msg_type()
208 {
209 return m_q[m_read].id;
210 }
211
212
213 /* ======================================================================
214 FUNCTION
215 omx_venc::omx_venc
216
217 DESCRIPTION
218 Constructor
219
220 PARAMETERS
221 None
222
223 RETURN VALUE
224 None.
225 ========================================================================== */
omx_video()226 omx_video::omx_video():
227 c2d_opened(false),
228 psource_frame(NULL),
229 pdest_frame(NULL),
230 secure_session(false),
231 #ifdef _UBWC_
232 m_ubwc_supported(true),
233 #else
234 m_ubwc_supported(false),
235 #endif
236 mUsesColorConversion(false),
237 mC2dSrcFmt(NO_COLOR_FORMAT),
238 mC2dDestFmt(NO_COLOR_FORMAT),
239 mC2DFrameHeight(0),
240 mC2DFrameWidth(0),
241 m_pInput_pmem(NULL),
242 m_pOutput_pmem(NULL),
243 #ifdef USE_ION
244 m_pInput_ion(NULL),
245 m_pOutput_ion(NULL),
246 #endif
247 m_error_propogated(false),
248 m_state(OMX_StateInvalid),
249 m_app_data(NULL),
250 m_use_input_pmem(OMX_FALSE),
251 m_use_output_pmem(OMX_FALSE),
252 m_sExtraData(0),
253 m_sParamConsumerUsage(0),
254 m_input_msg_id(OMX_COMPONENT_GENERATE_ETB),
255 m_nOperatingRate(0),
256 m_inp_mem_ptr(NULL),
257 m_out_mem_ptr(NULL),
258 m_client_output_extradata_mem_ptr(NULL),
259 input_flush_progress (false),
260 output_flush_progress (false),
261 input_use_buffer (false),
262 output_use_buffer (false),
263 pending_input_buffers(0),
264 pending_output_buffers(0),
265 allocate_native_handle(false),
266 m_out_bm_count(0),
267 m_client_out_bm_count(0),
268 m_client_in_bm_count(0),
269 m_inp_bm_count(0),
270 m_out_extradata_bm_count(0),
271 m_flags(0),
272 m_etb_count(0),
273 m_fbd_count(0),
274 m_event_port_settings_sent(false),
275 hw_overload(false),
276 m_graphicbuffer_size(0),
277 m_buffer_freed(0),
278 profile_mode(false),
279 profile_frame_count(0),
280 profile_start_time(0),
281 profile_last_time(0),
282 m_fastCV_init_done(false)
283 {
284 DEBUG_PRINT_HIGH("omx_video(): Inside Constructor()");
285 memset(&m_cmp,0,sizeof(m_cmp));
286 memset(&m_pCallbacks,0,sizeof(m_pCallbacks));
287 async_thread_created = false;
288 msg_thread_created = false;
289 msg_thread_stop = false;
290 is_stop_in_progress = false;
291
292 OMX_INIT_STRUCT(&m_blurInfo, OMX_QTI_VIDEO_CONFIG_BLURINFO);
293 m_blurInfo.nPortIndex == (OMX_U32)PORT_INDEX_IN;
294
295 mMapPixelFormat2Converter.insert({
296 {HAL_PIXEL_FORMAT_RGBA_8888, RGBA8888},
297 {HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC, NV12_UBWC},
298 {HAL_PIXEL_FORMAT_NV12_ENCODEABLE, NV12_128m},
299 {HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS, NV12_128m},
300 });
301
302 pthread_mutex_init(&m_lock, NULL);
303 pthread_mutex_init(&m_TimeStampInfo.m_lock, NULL);
304 m_TimeStampInfo.deferred_inbufq.m_size=0;
305 m_TimeStampInfo.deferred_inbufq.m_read = m_TimeStampInfo.deferred_inbufq.m_write = 0;
306 sem_init(&m_cmd_lock,0,0);
307 DEBUG_PRINT_LOW("meta_buffer_hdr = %p", meta_buffer_hdr);
308
309 memset(m_platform, 0, sizeof(m_platform));
310 #ifdef _ANDROID_
311 char property_value[PROPERTY_VALUE_MAX] = {0};
312 property_get("ro.board.platform", property_value, "0");
313 strlcpy(m_platform, property_value, sizeof(m_platform));
314 property_get("vendor.vidc.enc.profile.in", property_value, "0");
315 profile_mode = !!atoi(property_value);
316 #endif
317
318 pthread_mutex_init(&m_buf_lock, NULL);
319 }
320
321
322 /* ======================================================================
323 FUNCTION
324 omx_venc::~omx_venc
325
326 DESCRIPTION
327 Destructor
328
329 PARAMETERS
330 None
331
332 RETURN VALUE
333 None.
334 ========================================================================== */
~omx_video()335 omx_video::~omx_video()
336 {
337 DEBUG_PRINT_HIGH("~omx_video(): Inside Destructor()");
338 /*For V4L2 based drivers, pthread_join is done in device_close
339 * so no need to do it here*/
340 pthread_mutex_destroy(&m_lock);
341 pthread_mutex_destroy(&m_TimeStampInfo.m_lock);
342 sem_destroy(&m_cmd_lock);
343 DEBUG_PRINT_HIGH("m_etb_count = %" PRIu64 ", m_fbd_count = %" PRIu64, m_etb_count,
344 m_fbd_count);
345
346 pthread_mutex_destroy(&m_buf_lock);
347 if (profile_mode && (profile_start_time < profile_last_time)) {
348 DEBUG_PRINT_HIGH("Input frame rate = %f",
349 ((profile_frame_count - 1) * 1e6) / (profile_last_time - profile_start_time));
350 }
351 if (m_fastCV_init_done) {
352 fcvMemDeInit();
353 fcvCleanUp();
354 m_fastCV_init_done = false;
355 }
356 DEBUG_PRINT_HIGH("omx_video: Destructor exit");
357 DEBUG_PRINT_HIGH("Exiting OMX Video Encoder ...");
358 }
359
360 /* ======================================================================
361 FUNCTION
362 omx_venc::OMXCntrlProcessMsgCb
363
364 DESCRIPTION
365 IL Client callbacks are generated through this routine. The decoder
366 provides the thread context for this routine.
367
368 PARAMETERS
369 ctxt -- Context information related to the self.
370 id -- Event identifier. This could be any of the following:
371 1. Command completion event
372 2. Buffer done callback event
373 3. Frame done callback event
374
375 RETURN VALUE
376 None.
377
378 ========================================================================== */
process_event_cb(void * ctxt)379 void omx_video::process_event_cb(void *ctxt)
380 {
381 unsigned long p1; // Parameter - 1
382 unsigned long p2; // Parameter - 2
383 unsigned long ident;
384 unsigned qsize=0; // qsize
385 omx_video *pThis = (omx_video *) ctxt;
386
387 if (!pThis) {
388 DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out");
389 return;
390 }
391
392 // Protect the shared queue data structure
393 do {
394 /*Read the message id's from the queue*/
395
396 pthread_mutex_lock(&pThis->m_lock);
397 qsize = pThis->m_cmd_q.m_size;
398 if (qsize) {
399 pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
400 }
401
402 if (qsize == 0) {
403 qsize = pThis->m_ftb_q.m_size;
404 if (qsize) {
405 pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
406 }
407 }
408
409 if (qsize == 0) {
410 qsize = pThis->m_etb_q.m_size;
411 if (qsize) {
412 pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
413 }
414 }
415
416 pthread_mutex_unlock(&pThis->m_lock);
417
418 /*process message if we have one*/
419 if (qsize > 0) {
420 switch (ident) {
421 case OMX_COMPONENT_GENERATE_EVENT:
422 if (pThis->m_pCallbacks.EventHandler) {
423 switch (p1) {
424 case OMX_CommandStateSet:
425 pThis->m_state = (OMX_STATETYPE) p2;
426 DEBUG_PRINT_LOW("Process -> state set to %d", pThis->m_state);
427 if (pThis->m_state == OMX_StateLoaded) {
428 m_buffer_freed = false;
429 }
430 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
431 OMX_EventCmdComplete, p1, p2, NULL);
432 break;
433
434 case OMX_EventError:
435 DEBUG_PRINT_ERROR("ERROR: OMX_EventError: p2 = %lu", p2);
436 if (p2 == (unsigned)OMX_ErrorHardware) {
437 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
438 OMX_EventError,OMX_ErrorHardware,0,NULL);
439 } else {
440 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
441 OMX_EventError, p2, 0, 0);
442
443 }
444 break;
445
446 case OMX_CommandPortDisable:
447 DEBUG_PRINT_LOW("Process -> Port %lu set to PORT_STATE_DISABLED" \
448 "state", p2);
449 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
450 OMX_EventCmdComplete, p1, p2, NULL );
451 break;
452 case OMX_CommandPortEnable:
453 DEBUG_PRINT_LOW("Process ->Port %lu set PORT_STATE_ENABLED state" \
454 , p2);
455 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
456 OMX_EventCmdComplete, p1, p2, NULL );
457 break;
458
459 default:
460 DEBUG_PRINT_LOW("process_event_cb forwarding EventCmdComplete %lu", p1);
461 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
462 OMX_EventCmdComplete, p1, p2, NULL );
463 break;
464
465 }
466 } else {
467 DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks");
468 }
469 break;
470 case OMX_COMPONENT_GENERATE_ETB_OPQ:
471 if (pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\
472 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
473 DEBUG_PRINT_ERROR("ERROR: ETBProxy() failed!");
474 pThis->omx_report_error ();
475 }
476 break;
477 case OMX_COMPONENT_GENERATE_ETB: {
478 OMX_ERRORTYPE iret;
479 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB");
480 iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
481 if (iret == OMX_ErrorInsufficientResources) {
482 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
483 pThis->omx_report_hw_overload ();
484 } else if (iret != OMX_ErrorNone) {
485 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
486 pThis->omx_report_error ();
487 }
488 }
489 break;
490
491 case OMX_COMPONENT_GENERATE_FTB:
492 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
493 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
494 DEBUG_PRINT_ERROR("ERROR: FTBProxy() failed!");
495 pThis->omx_report_error ();
496 }
497 break;
498
499 case OMX_COMPONENT_GENERATE_COMMAND:
500 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
501 (OMX_U32)p2,(OMX_PTR)NULL);
502 break;
503
504 case OMX_COMPONENT_GENERATE_EBD:
505 if ( pThis->empty_buffer_done(&pThis->m_cmp,
506 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
507 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
508 pThis->omx_report_error ();
509 }
510 break;
511
512 case OMX_COMPONENT_GENERATE_FBD:
513 if ( pThis->fill_buffer_done(&pThis->m_cmp,
514 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
515 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
516 pThis->omx_report_error ();
517 }
518 break;
519
520 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
521
522 pThis->input_flush_progress = false;
523 DEBUG_PRINT_HIGH("m_etb_count at i/p flush = %" PRIu64, m_etb_count);
524 m_etb_count = 0;
525 if (pThis->m_pCallbacks.EventHandler) {
526 /*Check if we need generate event for Flush done*/
527 if (BITMASK_PRESENT(&pThis->m_flags,
528 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
529 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
530 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
531 OMX_EventCmdComplete,OMX_CommandFlush,
532 PORT_INDEX_IN,NULL );
533 } else if (BITMASK_PRESENT(&pThis->m_flags,
534 OMX_COMPONENT_IDLE_PENDING)) {
535 if (!pThis->output_flush_progress) {
536 DEBUG_PRINT_LOW("dev_stop called after input flush complete");
537 if (dev_stop() != 0) {
538 DEBUG_PRINT_ERROR("ERROR: dev_stop() failed in i/p flush!");
539 pThis->omx_report_error ();
540 }
541 }
542 }
543 }
544
545 break;
546
547 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
548
549 pThis->output_flush_progress = false;
550 DEBUG_PRINT_HIGH("m_fbd_count at o/p flush = %" PRIu64, m_fbd_count);
551 m_fbd_count = 0;
552 if (pThis->m_pCallbacks.EventHandler) {
553 /*Check if we need generate event for Flush done*/
554 if (BITMASK_PRESENT(&pThis->m_flags,
555 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
556 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
557
558 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
559 OMX_EventCmdComplete,OMX_CommandFlush,
560 PORT_INDEX_OUT,NULL );
561 } else if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
562 DEBUG_PRINT_LOW("dev_stop called after Output flush complete");
563 if (!pThis->input_flush_progress) {
564 if (dev_stop() != 0) {
565 DEBUG_PRINT_ERROR("ERROR: dev_stop() failed in o/p flush!");
566 pThis->omx_report_error ();
567 }
568 }
569 }
570 }
571 break;
572
573 case OMX_COMPONENT_GENERATE_START_DONE:
574 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE msg");
575
576 if (pThis->m_pCallbacks.EventHandler) {
577 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
578 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
579 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Move to \
580 executing");
581 // Send the callback now
582 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
583 pThis->m_state = OMX_StateExecuting;
584 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
585 OMX_EventCmdComplete,OMX_CommandStateSet,
586 OMX_StateExecuting, NULL);
587 } else if (BITMASK_PRESENT(&pThis->m_flags,
588 OMX_COMPONENT_PAUSE_PENDING)) {
589 if (dev_pause()) {
590 DEBUG_PRINT_ERROR("ERROR: dev_pause() failed in Start Done!");
591 pThis->omx_report_error ();
592 }
593 } else if (BITMASK_PRESENT(&pThis->m_flags,
594 OMX_COMPONENT_LOADED_START_PENDING)) {
595 if (dev_loaded_start_done()) {
596 DEBUG_PRINT_LOW("successful loaded Start Done!");
597 } else {
598 DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!");
599 pThis->omx_report_error ();
600 }
601 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING);
602 } else {
603 DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags);
604 }
605 } else {
606 DEBUG_PRINT_LOW("Event Handler callback is NULL");
607 }
608 break;
609
610 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
611 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE msg");
612 if (pThis->m_pCallbacks.EventHandler) {
613 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
614 //Send the callback now
615 pThis->complete_pending_buffer_done_cbs();
616 DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD");
617 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
618 pThis->m_state = OMX_StatePause;
619 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
620 OMX_EventCmdComplete,OMX_CommandStateSet,
621 OMX_StatePause, NULL);
622 }
623 }
624
625 break;
626
627 case OMX_COMPONENT_GENERATE_RESUME_DONE:
628 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_RESUME_DONE msg");
629 if (pThis->m_pCallbacks.EventHandler) {
630 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
631 // Send the callback now
632 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
633 pThis->m_state = OMX_StateExecuting;
634 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
635 OMX_EventCmdComplete,OMX_CommandStateSet,
636 OMX_StateExecuting,NULL);
637 }
638 }
639
640 break;
641
642 case OMX_COMPONENT_GENERATE_STOP_DONE:
643 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE msg");
644 if (pThis->m_pCallbacks.EventHandler) {
645 pThis->complete_pending_buffer_done_cbs();
646 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
647 // Send the callback now
648 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
649 pThis->m_state = OMX_StateIdle;
650 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data,
651 OMX_EventCmdComplete,OMX_CommandStateSet,
652 OMX_StateIdle,NULL);
653 } else if (BITMASK_PRESENT(&pThis->m_flags,
654 OMX_COMPONENT_LOADED_STOP_PENDING)) {
655 if (dev_loaded_stop_done()) {
656 DEBUG_PRINT_LOW("successful loaded Stop Done!");
657 } else {
658 DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!");
659 pThis->omx_report_error ();
660 }
661 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING);
662 } else {
663 DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags);
664 }
665 }
666
667 is_stop_in_progress = false;
668 break;
669
670 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
671 DEBUG_PRINT_ERROR("ERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!");
672 pThis->omx_report_error ();
673 break;
674 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
675 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
676 pThis->omx_report_unsupported_setting();
677 break;
678
679 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
680 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
681 pThis->omx_report_hw_overload();
682 break;
683
684 default:
685 DEBUG_PRINT_LOW("process_event_cb unknown msg id 0x%02x", (unsigned int)ident);
686 break;
687 }
688 }
689
690 pthread_mutex_lock(&pThis->m_lock);
691 qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
692 pThis->m_etb_q.m_size;
693
694 pthread_mutex_unlock(&pThis->m_lock);
695
696 } while (qsize>0);
697 DEBUG_PRINT_LOW("exited the while loop");
698
699 }
700
701
702
703
704 /* ======================================================================
705 FUNCTION
706 omx_venc::GetComponentVersion
707
708 DESCRIPTION
709 Returns the component version.
710
711 PARAMETERS
712 TBD.
713
714 RETURN VALUE
715 OMX_ErrorNone.
716
717 ========================================================================== */
get_component_version(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_STRING componentName,OMX_OUT OMX_VERSIONTYPE * componentVersion,OMX_OUT OMX_VERSIONTYPE * specVersion,OMX_OUT OMX_UUIDTYPE * componentUUID)718 OMX_ERRORTYPE omx_video::get_component_version
719 (
720 OMX_IN OMX_HANDLETYPE hComp,
721 OMX_OUT OMX_STRING componentName,
722 OMX_OUT OMX_VERSIONTYPE* componentVersion,
723 OMX_OUT OMX_VERSIONTYPE* specVersion,
724 OMX_OUT OMX_UUIDTYPE* componentUUID
725 )
726 {
727 (void)hComp;
728 (void)componentName;
729 (void)componentVersion;
730 (void)componentUUID;
731 if (m_state == OMX_StateInvalid) {
732 DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State");
733 return OMX_ErrorInvalidState;
734 }
735 /* TBD -- Return the proper version */
736 if (specVersion) {
737 specVersion->nVersion = OMX_SPEC_VERSION;
738 }
739 return OMX_ErrorNone;
740 }
741 /* ======================================================================
742 FUNCTION
743 omx_venc::SendCommand
744
745 DESCRIPTION
746 Returns zero if all the buffers released..
747
748 PARAMETERS
749 None.
750
751 RETURN VALUE
752 true/false
753
754 ========================================================================== */
send_command(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)755 OMX_ERRORTYPE omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp,
756 OMX_IN OMX_COMMANDTYPE cmd,
757 OMX_IN OMX_U32 param1,
758 OMX_IN OMX_PTR cmdData
759 )
760 {
761 (void)hComp;
762 if (m_state == OMX_StateInvalid) {
763 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
764 return OMX_ErrorInvalidState;
765 }
766
767 if (cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable) {
768 if ((param1 != (OMX_U32)PORT_INDEX_IN) && (param1 != (OMX_U32)PORT_INDEX_OUT) && (param1 != (OMX_U32)PORT_INDEX_BOTH)) {
769 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index");
770 return OMX_ErrorBadPortIndex;
771 }
772 }
773 if (cmd == OMX_CommandMarkBuffer) {
774 if (param1 != PORT_INDEX_IN) {
775 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index");
776 return OMX_ErrorBadPortIndex;
777 }
778 if (!cmdData) {
779 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null");
780 return OMX_ErrorBadParameter;
781 }
782 }
783
784 post_event((unsigned long)cmd,(unsigned long)param1,OMX_COMPONENT_GENERATE_COMMAND);
785 sem_wait(&m_cmd_lock);
786 return OMX_ErrorNone;
787 }
788
789 /* ======================================================================
790 FUNCTION
791 omx_venc::SendCommand
792
793 DESCRIPTION
794 Returns zero if all the buffers released..
795
796 PARAMETERS
797 None.
798
799 RETURN VALUE
800 true/false
801
802 ========================================================================== */
send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)803 OMX_ERRORTYPE omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
804 OMX_IN OMX_COMMANDTYPE cmd,
805 OMX_IN OMX_U32 param1,
806 OMX_IN OMX_PTR cmdData
807 )
808 {
809 (void)hComp;
810 (void)cmdData;
811
812 OMX_ERRORTYPE eRet = OMX_ErrorNone;
813 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
814 int bFlag = 1;
815
816 if (cmd == OMX_CommandStateSet) {
817 /***************************/
818 /* Current State is Loaded */
819 /***************************/
820 if (m_state == OMX_StateLoaded) {
821 if (eState == OMX_StateIdle) {
822 //if all buffers are allocated or all ports disabled
823 if (allocate_done() ||
824 ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE)) {
825 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle");
826 } else {
827 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending");
828 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
829 // Skip the event notification
830 bFlag = 0;
831 }
832 }
833 /* Requesting transition from Loaded to Loaded */
834 else if (eState == OMX_StateLoaded) {
835 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded");
836 post_event(OMX_EventError,OMX_ErrorSameState,\
837 OMX_COMPONENT_GENERATE_EVENT);
838 eRet = OMX_ErrorSameState;
839 }
840 /* Requesting transition from Loaded to WaitForResources */
841 else if (eState == OMX_StateWaitForResources) {
842 /* Since error is None , we will post an event
843 at the end of this function definition */
844 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources");
845 }
846 /* Requesting transition from Loaded to Executing */
847 else if (eState == OMX_StateExecuting) {
848 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing");
849 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
850 OMX_COMPONENT_GENERATE_EVENT);
851 eRet = OMX_ErrorIncorrectStateTransition;
852 }
853 /* Requesting transition from Loaded to Pause */
854 else if (eState == OMX_StatePause) {
855 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause");
856 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
857 OMX_COMPONENT_GENERATE_EVENT);
858 eRet = OMX_ErrorIncorrectStateTransition;
859 }
860 /* Requesting transition from Loaded to Invalid */
861 else if (eState == OMX_StateInvalid) {
862 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid");
863 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
864 eRet = OMX_ErrorInvalidState;
865 } else {
866 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled",\
867 eState);
868 eRet = OMX_ErrorBadParameter;
869 }
870 }
871
872 /***************************/
873 /* Current State is IDLE */
874 /***************************/
875 else if (m_state == OMX_StateIdle) {
876 if (eState == OMX_StateLoaded) {
877 if (release_done()) {
878 /*
879 Since error is None , we will post an event at the end
880 of this function definition
881 */
882 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded");
883 if (dev_stop() != 0) {
884 DEBUG_PRINT_ERROR("ERROR: dev_stop() failed at Idle --> Loaded");
885 eRet = OMX_ErrorHardware;
886 }
887 } else {
888 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending");
889 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
890 // Skip the event notification
891 bFlag = 0;
892 }
893 }
894 /* Requesting transition from Idle to Executing */
895 else if (eState == OMX_StateExecuting) {
896 if ( dev_start() ) {
897 DEBUG_PRINT_ERROR("ERROR: dev_start() failed in SCP on Idle --> Exe");
898 omx_report_error ();
899 eRet = OMX_ErrorHardware;
900 } else {
901 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
902 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing");
903 bFlag = 0;
904 }
905
906 dev_start_done();
907 }
908 /* Requesting transition from Idle to Idle */
909 else if (eState == OMX_StateIdle) {
910 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle");
911 post_event(OMX_EventError,OMX_ErrorSameState,\
912 OMX_COMPONENT_GENERATE_EVENT);
913 eRet = OMX_ErrorSameState;
914 }
915 /* Requesting transition from Idle to WaitForResources */
916 else if (eState == OMX_StateWaitForResources) {
917 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources");
918 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
919 OMX_COMPONENT_GENERATE_EVENT);
920 eRet = OMX_ErrorIncorrectStateTransition;
921 }
922 /* Requesting transition from Idle to Pause */
923 else if (eState == OMX_StatePause) {
924 /*To pause the Video core we need to start the driver*/
925 if ( dev_start() ) {
926 DEBUG_PRINT_ERROR("ERROR: dev_start() failed in SCP on Idle --> Pause");
927 omx_report_error ();
928 eRet = OMX_ErrorHardware;
929 } else {
930 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
931 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause");
932 bFlag = 0;
933 }
934 }
935 /* Requesting transition from Idle to Invalid */
936 else if (eState == OMX_StateInvalid) {
937 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid");
938 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
939 eRet = OMX_ErrorInvalidState;
940 } else {
941 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled",eState);
942 eRet = OMX_ErrorBadParameter;
943 }
944 }
945
946 /******************************/
947 /* Current State is Executing */
948 /******************************/
949 else if (m_state == OMX_StateExecuting) {
950 /* Requesting transition from Executing to Idle */
951 if (eState == OMX_StateIdle) {
952 /* Since error is None , we will post an event
953 at the end of this function definition
954 */
955 DEBUG_PRINT_LOW("OMXCORE-SM: Executing --> Idle");
956 //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle
957 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
958 execute_omx_flush(OMX_ALL);
959 bFlag = 0;
960 }
961 /* Requesting transition from Executing to Paused */
962 else if (eState == OMX_StatePause) {
963
964 if (dev_pause()) {
965 DEBUG_PRINT_ERROR("ERROR: dev_pause() failed in SCP on Exe --> Pause");
966 post_event(OMX_EventError,OMX_ErrorHardware,\
967 OMX_COMPONENT_GENERATE_EVENT);
968 eRet = OMX_ErrorHardware;
969 } else {
970 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
971 DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause");
972 bFlag = 0;
973 }
974 }
975 /* Requesting transition from Executing to Loaded */
976 else if (eState == OMX_StateLoaded) {
977 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Loaded");
978 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
979 OMX_COMPONENT_GENERATE_EVENT);
980 eRet = OMX_ErrorIncorrectStateTransition;
981 }
982 /* Requesting transition from Executing to WaitForResources */
983 else if (eState == OMX_StateWaitForResources) {
984 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> WaitForResources");
985 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
986 OMX_COMPONENT_GENERATE_EVENT);
987 eRet = OMX_ErrorIncorrectStateTransition;
988 }
989 /* Requesting transition from Executing to Executing */
990 else if (eState == OMX_StateExecuting) {
991 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Executing");
992 post_event(OMX_EventError,OMX_ErrorSameState,\
993 OMX_COMPONENT_GENERATE_EVENT);
994 eRet = OMX_ErrorSameState;
995 }
996 /* Requesting transition from Executing to Invalid */
997 else if (eState == OMX_StateInvalid) {
998 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Invalid");
999 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1000 eRet = OMX_ErrorInvalidState;
1001 } else {
1002 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled",eState);
1003 eRet = OMX_ErrorBadParameter;
1004 }
1005 }
1006 /***************************/
1007 /* Current State is Pause */
1008 /***************************/
1009 else if (m_state == OMX_StatePause) {
1010 /* Requesting transition from Pause to Executing */
1011 if (eState == OMX_StateExecuting) {
1012 DEBUG_PRINT_LOW("Pause --> Executing");
1013 if ( dev_resume() ) {
1014 post_event(OMX_EventError,OMX_ErrorHardware,\
1015 OMX_COMPONENT_GENERATE_EVENT);
1016 eRet = OMX_ErrorHardware;
1017 } else {
1018 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
1019 DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing");
1020 post_event (0, 0, OMX_COMPONENT_GENERATE_RESUME_DONE);
1021 bFlag = 0;
1022 }
1023 }
1024 /* Requesting transition from Pause to Idle */
1025 else if (eState == OMX_StateIdle) {
1026 /* Since error is None , we will post an event
1027 at the end of this function definition */
1028 DEBUG_PRINT_LOW("Pause --> Idle");
1029 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1030 execute_omx_flush(OMX_ALL);
1031 bFlag = 0;
1032 }
1033 /* Requesting transition from Pause to loaded */
1034 else if (eState == OMX_StateLoaded) {
1035 DEBUG_PRINT_ERROR("ERROR: Pause --> loaded");
1036 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1037 OMX_COMPONENT_GENERATE_EVENT);
1038 eRet = OMX_ErrorIncorrectStateTransition;
1039 }
1040 /* Requesting transition from Pause to WaitForResources */
1041 else if (eState == OMX_StateWaitForResources) {
1042 DEBUG_PRINT_ERROR("ERROR: Pause --> WaitForResources");
1043 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1044 OMX_COMPONENT_GENERATE_EVENT);
1045 eRet = OMX_ErrorIncorrectStateTransition;
1046 }
1047 /* Requesting transition from Pause to Pause */
1048 else if (eState == OMX_StatePause) {
1049 DEBUG_PRINT_ERROR("ERROR: Pause --> Pause");
1050 post_event(OMX_EventError,OMX_ErrorSameState,\
1051 OMX_COMPONENT_GENERATE_EVENT);
1052 eRet = OMX_ErrorSameState;
1053 }
1054 /* Requesting transition from Pause to Invalid */
1055 else if (eState == OMX_StateInvalid) {
1056 DEBUG_PRINT_ERROR("ERROR: Pause --> Invalid");
1057 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1058 eRet = OMX_ErrorInvalidState;
1059 } else {
1060 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled",eState);
1061 eRet = OMX_ErrorBadParameter;
1062 }
1063 }
1064 /***************************/
1065 /* Current State is WaitForResources */
1066 /***************************/
1067 else if (m_state == OMX_StateWaitForResources) {
1068 /* Requesting transition from WaitForResources to Loaded */
1069 if (eState == OMX_StateLoaded) {
1070 /* Since error is None , we will post an event
1071 at the end of this function definition */
1072 DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded");
1073 }
1074 /* Requesting transition from WaitForResources to WaitForResources */
1075 else if (eState == OMX_StateWaitForResources) {
1076 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources");
1077 post_event(OMX_EventError,OMX_ErrorSameState,
1078 OMX_COMPONENT_GENERATE_EVENT);
1079 eRet = OMX_ErrorSameState;
1080 }
1081 /* Requesting transition from WaitForResources to Executing */
1082 else if (eState == OMX_StateExecuting) {
1083 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing");
1084 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1085 OMX_COMPONENT_GENERATE_EVENT);
1086 eRet = OMX_ErrorIncorrectStateTransition;
1087 }
1088 /* Requesting transition from WaitForResources to Pause */
1089 else if (eState == OMX_StatePause) {
1090 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause");
1091 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1092 OMX_COMPONENT_GENERATE_EVENT);
1093 eRet = OMX_ErrorIncorrectStateTransition;
1094 }
1095 /* Requesting transition from WaitForResources to Invalid */
1096 else if (eState == OMX_StateInvalid) {
1097 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid");
1098 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1099 eRet = OMX_ErrorInvalidState;
1100 }
1101 /* Requesting transition from WaitForResources to Loaded -
1102 is NOT tested by Khronos TS */
1103
1104 } else {
1105 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)",m_state,eState);
1106 eRet = OMX_ErrorBadParameter;
1107 }
1108 }
1109 /********************************/
1110 /* Current State is Invalid */
1111 /*******************************/
1112 else if (m_state == OMX_StateInvalid) {
1113 /* State Transition from Inavlid to any state */
1114 if ((eState == OMX_StateLoaded) || (eState == OMX_StateWaitForResources) ||
1115 (eState == OMX_StateIdle) || (eState == OMX_StateExecuting) ||
1116 (eState == OMX_StatePause) || (eState == OMX_StateInvalid)) {
1117 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded");
1118 post_event(OMX_EventError,OMX_ErrorInvalidState,\
1119 OMX_COMPONENT_GENERATE_EVENT);
1120 eRet = OMX_ErrorInvalidState;
1121 }
1122 } else if (cmd == OMX_CommandFlush) {
1123 if (0 == param1 || OMX_ALL == param1) {
1124 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
1125 }
1126 if (1 == param1 || OMX_ALL == param1) {
1127 //generate output flush event only.
1128 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1129 }
1130
1131 execute_omx_flush(param1);
1132 bFlag = 0;
1133 } else if ( cmd == OMX_CommandPortEnable) {
1134 if (param1 == PORT_INDEX_IN || param1 == OMX_ALL) {
1135 m_sInPortDef.bEnabled = OMX_TRUE;
1136
1137 if ( (m_state == OMX_StateLoaded &&
1138 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1139 || allocate_input_done()) {
1140 post_event(OMX_CommandPortEnable,PORT_INDEX_IN,
1141 OMX_COMPONENT_GENERATE_EVENT);
1142 } else {
1143 DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending");
1144 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
1145 // Skip the event notification
1146 bFlag = 0;
1147 }
1148 }
1149 if (param1 == PORT_INDEX_OUT || param1 == OMX_ALL) {
1150 m_sOutPortDef.bEnabled = OMX_TRUE;
1151
1152 if ( (m_state == OMX_StateLoaded &&
1153 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1154 || (allocate_output_done())) {
1155 post_event(OMX_CommandPortEnable,PORT_INDEX_OUT,
1156 OMX_COMPONENT_GENERATE_EVENT);
1157
1158 } else {
1159 DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending");
1160 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
1161 // Skip the event notification
1162 bFlag = 0;
1163 }
1164 }
1165 } else if (cmd == OMX_CommandPortDisable) {
1166 if (param1 == PORT_INDEX_IN || param1 == OMX_ALL) {
1167 m_sInPortDef.bEnabled = OMX_FALSE;
1168 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1169 && release_input_done()) {
1170 post_event(OMX_CommandPortDisable,PORT_INDEX_IN,
1171 OMX_COMPONENT_GENERATE_EVENT);
1172 } else {
1173 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
1174 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
1175 execute_omx_flush(PORT_INDEX_IN);
1176 }
1177
1178 // Skip the event notification
1179 bFlag = 0;
1180 }
1181 }
1182 if (param1 == PORT_INDEX_OUT || param1 == OMX_ALL) {
1183 m_sOutPortDef.bEnabled = OMX_FALSE;
1184
1185 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1186 && release_output_done()) {
1187 post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\
1188 OMX_COMPONENT_GENERATE_EVENT);
1189 } else {
1190 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
1191 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
1192 execute_omx_flush(PORT_INDEX_OUT);
1193 }
1194 // Skip the event notification
1195 bFlag = 0;
1196
1197 }
1198 }
1199 } else {
1200 DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)",cmd);
1201 eRet = OMX_ErrorNotImplemented;
1202 }
1203 if (eRet == OMX_ErrorNone && bFlag) {
1204 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
1205 }
1206 sem_post(&m_cmd_lock);
1207 return eRet;
1208 }
1209
1210 /* ======================================================================
1211 FUNCTION
1212 omx_venc::ExecuteOmxFlush
1213
1214 DESCRIPTION
1215 Executes the OMX flush.
1216
1217 PARAMETERS
1218 flushtype - input flush(1)/output flush(0)/ both.
1219
1220 RETURN VALUE
1221 true/false
1222
1223 ========================================================================== */
execute_omx_flush(OMX_U32 flushType)1224 bool omx_video::execute_omx_flush(OMX_U32 flushType)
1225 {
1226 bool bRet = false;
1227 DEBUG_PRINT_LOW("execute_omx_flush - %u", (unsigned int)flushType);
1228 /* XXX: The driver/hardware does not support flushing of individual ports
1229 * in all states. So we pretty much need to flush both ports internally,
1230 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
1231 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
1232 * we automatically omit sending the FLUSH done for the "opposite" port. */
1233
1234 input_flush_progress = true;
1235 output_flush_progress = true;
1236 bRet = execute_flush_all();
1237 return bRet;
1238 }
1239 /*=========================================================================
1240 FUNCTION : execute_output_flush
1241
1242 DESCRIPTION
1243 Executes the OMX flush at OUTPUT PORT.
1244
1245 PARAMETERS
1246 None.
1247
1248 RETURN VALUE
1249 true/false
1250 ==========================================================================*/
execute_output_flush(void)1251 bool omx_video::execute_output_flush(void)
1252 {
1253 unsigned long p1 = 0; // Parameter - 1
1254 unsigned long p2 = 0; // Parameter - 2
1255 unsigned long ident = 0;
1256 bool bRet = true;
1257
1258 /*Generate FBD for all Buffers in the FTBq*/
1259 DEBUG_PRINT_LOW("execute_output_flush");
1260 pthread_mutex_lock(&m_lock);
1261 while (m_ftb_q.m_size) {
1262 m_ftb_q.pop_entry(&p1,&p2,&ident);
1263
1264 if (ident == OMX_COMPONENT_GENERATE_FTB ) {
1265 pending_output_buffers++;
1266 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
1267 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1268 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
1269 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1270 }
1271 }
1272
1273 pthread_mutex_unlock(&m_lock);
1274 /*Check if there are buffers with the Driver*/
1275 if (dev_flush(PORT_INDEX_OUT)) {
1276 DEBUG_PRINT_ERROR("ERROR: o/p dev_flush() Failed");
1277 return false;
1278 }
1279
1280 return bRet;
1281 }
1282 /*=========================================================================
1283 FUNCTION : execute_input_flush
1284
1285 DESCRIPTION
1286 Executes the OMX flush at INPUT PORT.
1287
1288 PARAMETERS
1289 None.
1290
1291 RETURN VALUE
1292 true/false
1293 ==========================================================================*/
execute_input_flush(void)1294 bool omx_video::execute_input_flush(void)
1295 {
1296 unsigned long p1 = 0; // Parameter - 1
1297 unsigned long p2 = 0; // Parameter - 2
1298 unsigned long ident = 0;
1299 bool bRet = true;
1300
1301 /*Generate EBD for all Buffers in the ETBq*/
1302 DEBUG_PRINT_LOW("execute_input_flush");
1303
1304 pthread_mutex_lock(&m_lock);
1305 while (m_etb_q.m_size) {
1306 m_etb_q.pop_entry(&p1,&p2,&ident);
1307 if (ident == OMX_COMPONENT_GENERATE_ETB) {
1308 pending_input_buffers++;
1309 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
1310 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1311 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
1312 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1313 } else if (ident == OMX_COMPONENT_GENERATE_ETB_OPQ) {
1314 print_omx_buffer("Flush ETB_OPQ", (OMX_BUFFERHEADERTYPE *)p2);
1315 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2);
1316 }
1317 }
1318 while (m_TimeStampInfo.deferred_inbufq.m_size) {
1319 m_TimeStampInfo.deferred_inbufq.pop_entry(&p1,&p2,&ident);
1320 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p1);
1321 }
1322 if (mUseProxyColorFormat) {
1323 if (psource_frame) {
1324 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame);
1325 psource_frame = NULL;
1326 }
1327 while (m_opq_meta_q.m_size) {
1328 unsigned long p1,p2,id;
1329 m_opq_meta_q.pop_entry(&p1,&p2,&id);
1330 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,
1331 (OMX_BUFFERHEADERTYPE *)p1);
1332 }
1333 if (pdest_frame) {
1334 m_opq_pmem_q.insert_entry((unsigned long)pdest_frame,0,0);
1335 pdest_frame = NULL;
1336 }
1337 }
1338 pthread_mutex_unlock(&m_lock);
1339 /*Check if there are buffers with the Driver*/
1340 if (dev_flush(PORT_INDEX_IN)) {
1341 DEBUG_PRINT_ERROR("ERROR: i/p dev_flush() Failed");
1342 return false;
1343 }
1344
1345 return bRet;
1346 }
1347
1348
1349 /*=========================================================================
1350 FUNCTION : execute_flush
1351
1352 DESCRIPTION
1353 Executes the OMX flush at INPUT & OUTPUT PORT.
1354
1355 PARAMETERS
1356 None.
1357
1358 RETURN VALUE
1359 true/false
1360 ==========================================================================*/
execute_flush_all(void)1361 bool omx_video::execute_flush_all(void)
1362 {
1363 unsigned long p1 = 0; // Parameter - 1
1364 unsigned long p2 = 0; // Parameter - 2
1365 unsigned long ident = 0;
1366 bool bRet = true;
1367
1368 DEBUG_PRINT_LOW("execute_flush_all");
1369
1370 /*Generate EBD for all Buffers in the ETBq*/
1371 pthread_mutex_lock(&m_lock);
1372 while (m_etb_q.m_size) {
1373 m_etb_q.pop_entry(&p1,&p2,&ident);
1374 if (ident == OMX_COMPONENT_GENERATE_ETB) {
1375 pending_input_buffers++;
1376 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
1377 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1378 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
1379 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1380 } else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ) {
1381 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2);
1382 }
1383 }
1384
1385 while (m_TimeStampInfo.deferred_inbufq.m_size) {
1386 m_TimeStampInfo.deferred_inbufq.pop_entry(&p1,&p2,&ident);
1387 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p1);
1388 }
1389
1390 if(mUseProxyColorFormat) {
1391 if(psource_frame) {
1392 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame);
1393 psource_frame = NULL;
1394 }
1395 while(m_opq_meta_q.m_size) {
1396 unsigned long p1,p2,id;
1397 m_opq_meta_q.pop_entry(&p1,&p2,&id);
1398 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,
1399 (OMX_BUFFERHEADERTYPE *)p1);
1400 }
1401 if(pdest_frame){
1402 m_opq_pmem_q.insert_entry((unsigned long)pdest_frame,0,0);
1403 pdest_frame = NULL;
1404 }
1405 }
1406
1407 /*Generate FBD for all Buffers in the FTBq*/
1408 DEBUG_PRINT_LOW("execute_output_flush");
1409 while (m_ftb_q.m_size) {
1410 m_ftb_q.pop_entry(&p1,&p2,&ident);
1411
1412 if (ident == OMX_COMPONENT_GENERATE_FTB ) {
1413 pending_output_buffers++;
1414 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
1415 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1416 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
1417 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1418 }
1419 }
1420
1421 pthread_mutex_unlock(&m_lock);
1422 /*Check if there are buffers with the Driver*/
1423 if (dev_flush(PORT_INDEX_BOTH)) {
1424 DEBUG_PRINT_ERROR("ERROR: dev_flush() Failed");
1425 return false;
1426 }
1427
1428 return bRet;
1429 }
1430
1431 /* ======================================================================
1432 FUNCTION
1433 omx_venc::SendCommandEvent
1434
1435 DESCRIPTION
1436 Send the event to decoder pipe. This is needed to generate the callbacks
1437 in decoder thread context.
1438
1439 PARAMETERS
1440 None.
1441
1442 RETURN VALUE
1443 true/false
1444
1445 ========================================================================== */
post_event(unsigned long p1,unsigned long p2,unsigned long id)1446 bool omx_video::post_event(unsigned long p1,
1447 unsigned long p2,
1448 unsigned long id)
1449 {
1450 bool bRet = false;
1451
1452 pthread_mutex_lock(&m_lock);
1453
1454 if ((id == OMX_COMPONENT_GENERATE_FTB) ||
1455 (id == OMX_COMPONENT_GENERATE_FBD) ||
1456 (id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH)) {
1457 m_ftb_q.insert_entry(p1,p2,id);
1458 } else if ((id == OMX_COMPONENT_GENERATE_ETB) ||
1459 (id == OMX_COMPONENT_GENERATE_EBD) ||
1460 (id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH)) {
1461 m_etb_q.insert_entry(p1,p2,id);
1462 } else {
1463 m_cmd_q.insert_entry(p1,p2,id);
1464 }
1465
1466 bRet = true;
1467 post_message(this, id);
1468 pthread_mutex_unlock(&m_lock);
1469
1470 return bRet;
1471 }
1472
1473 /* ======================================================================
1474 FUNCTION
1475 omx_venc::GetParameter
1476
1477 DESCRIPTION
1478 OMX Get Parameter method implementation
1479
1480 PARAMETERS
1481 <TBD>.
1482
1483 RETURN VALUE
1484 Error None if successful.
1485
1486 ========================================================================== */
get_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_INOUT OMX_PTR paramData)1487 OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
1488 OMX_IN OMX_INDEXTYPE paramIndex,
1489 OMX_INOUT OMX_PTR paramData)
1490 {
1491 (void)hComp;
1492 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1493 unsigned int height=0,width = 0;
1494
1495 if (m_state == OMX_StateInvalid) {
1496 DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State");
1497 return OMX_ErrorInvalidState;
1498 }
1499 if (paramData == NULL) {
1500 DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData");
1501 return OMX_ErrorBadParameter;
1502 }
1503
1504 switch ((int)paramIndex) {
1505 case OMX_IndexParamPortDefinition:
1506 {
1507 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
1508 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
1509 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
1510
1511 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition: port %d", portDefn->nPortIndex);
1512 if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
1513 dev_get_buf_req (&m_sInPortDef.nBufferCountMin,
1514 &m_sInPortDef.nBufferCountActual,
1515 &m_sInPortDef.nBufferSize,
1516 m_sInPortDef.nPortIndex);
1517
1518 memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef));
1519 #ifdef _ANDROID_ICS_
1520 if (meta_mode_enable) {
1521 // request size of largest metadata (happens to be NativeHandleSource) since
1522 // we do not know the exact metadata-type yet
1523 portDefn->nBufferSize = sizeof(LEGACY_CAM_METADATA_TYPE);
1524 }
1525 if (mUseProxyColorFormat) {
1526 portDefn->format.video.eColorFormat =
1527 (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
1528 }
1529 #endif
1530 } else if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1531 if (m_state != OMX_StateExecuting) {
1532 dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
1533 &m_sOutPortDef.nBufferCountActual,
1534 &m_sOutPortDef.nBufferSize,
1535 m_sOutPortDef.nPortIndex);
1536 dev_get_dimensions(m_sOutPortDef.nPortIndex,
1537 &m_sOutPortDef.format.video.nFrameWidth,
1538 &m_sOutPortDef.format.video.nFrameHeight);
1539 }
1540
1541 memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef));
1542 // Tiling in HW expects output port def to be aligned to tile size
1543 // At the same time, FWK needs original WxH for various purposes
1544 // Sending input WxH as output port def WxH to FWK
1545 if (m_sOutPortDef.format.video.eCompressionFormat ==
1546 OMX_VIDEO_CodingImageHEIC) {
1547 portDefn->format.video.nFrameWidth =
1548 m_sInPortDef.format.video.nFrameWidth;
1549 portDefn->format.video.nFrameHeight =
1550 m_sInPortDef.format.video.nFrameHeight;
1551 }
1552
1553 if (secure_session || allocate_native_handle) {
1554 portDefn->nBufferSize =
1555 sizeof(native_handle_t) + (sizeof(int) * (1/*numFds*/ + 3/*numInts*/));
1556 }
1557 } else if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_EXTRADATA_OUT) {
1558 portDefn->nBufferSize = m_client_out_extradata_info.getSize();
1559 portDefn->nBufferCountMin= m_sOutPortDef.nBufferCountMin;
1560 portDefn->nBufferCountActual = m_client_out_extradata_info.getBufferCount();
1561 portDefn->eDir = OMX_DirOutput;
1562 DEBUG_PRINT_LOW("extradata port: size = %u, min cnt = %u, actual cnt = %u",
1563 (unsigned int)portDefn->nBufferSize, (unsigned int)portDefn->nBufferCountMin,
1564 (unsigned int)portDefn->nBufferCountActual);
1565 } else if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_EXTRADATA_IN) {
1566 portDefn->nBufferSize = m_client_in_extradata_info.getSize();
1567 portDefn->nBufferCountMin= m_sInPortDef.nBufferCountMin;
1568 portDefn->nBufferCountActual = m_client_in_extradata_info.getBufferCount();
1569 portDefn->eDir = OMX_DirInput;
1570 DEBUG_PRINT_LOW("extradata port: size = %u, min cnt = %u, actual cnt = %u",
1571 (unsigned int)portDefn->nBufferSize, (unsigned int)portDefn->nBufferCountMin,
1572 (unsigned int)portDefn->nBufferCountActual);
1573 } else {
1574 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1575 eRet = OMX_ErrorBadPortIndex;
1576 }
1577
1578 DEBUG_PRINT_HIGH("get_parameter: OMX_IndexParamPortDefinition: port %d, wxh %dx%d, min %d, actual %d, size %d, colorformat %#x, compression format %#x",
1579 portDefn->nPortIndex, portDefn->format.video.nFrameWidth,
1580 portDefn->format.video.nFrameHeight, portDefn->nBufferCountMin,
1581 portDefn->nBufferCountActual, portDefn->nBufferSize,
1582 portDefn->format.video.eColorFormat, portDefn->format.video.eCompressionFormat);
1583
1584 break;
1585 }
1586 case OMX_IndexParamVideoInit:
1587 {
1588 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
1589 OMX_PORT_PARAM_TYPE *portParamType =
1590 (OMX_PORT_PARAM_TYPE *) paramData;
1591 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
1592
1593 memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam));
1594 break;
1595 }
1596 case OMX_IndexParamVideoPortFormat:
1597 {
1598 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
1599 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
1600 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1601 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
1602
1603 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
1604 unsigned index = portFmt->nIndex;
1605 OMX_U32 colorFormat = OMX_COLOR_FormatUnused;
1606 if(dev_get_supported_color_format(index, &colorFormat)) {
1607 memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
1608 portFmt->nIndex = index; //restore index set from client
1609 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
1610 } else {
1611 eRet = OMX_ErrorNoMore;
1612 }
1613 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1614 memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat));
1615 } else {
1616 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1617 eRet = OMX_ErrorBadPortIndex;
1618 }
1619 break;
1620 }
1621 case OMX_IndexParamVideoBitrate:
1622 {
1623 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_BITRATETYPE);
1624 OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1625 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate");
1626
1627 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
1628 memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate));
1629 } else {
1630 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1631 eRet = OMX_ErrorBadPortIndex;
1632 }
1633
1634 break;
1635 }
1636 case OMX_IndexParamVideoMpeg4:
1637 {
1638 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_MPEG4TYPE);
1639 OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1640 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4");
1641 memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4));
1642 break;
1643 }
1644 case OMX_IndexParamVideoH263:
1645 {
1646 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_H263TYPE);
1647 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1648 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263");
1649 memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263));
1650 break;
1651 }
1652 case OMX_IndexParamVideoAvc:
1653 {
1654 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_AVCTYPE);
1655 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1656 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc");
1657 memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC));
1658 break;
1659 }
1660 case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
1661 {
1662 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_VP8TYPE);
1663 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
1664 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoVp8");
1665 memcpy(pParam, &m_sParamVP8, sizeof(m_sParamVP8));
1666 break;
1667 }
1668 case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
1669 {
1670 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_HEVCTYPE);
1671 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
1672 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoHevc");
1673 memcpy(pParam, &m_sParamHEVC, sizeof(m_sParamHEVC));
1674 break;
1675 }
1676 case OMX_IndexParamVideoAndroidImageGrid:
1677 {
1678 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE);
1679 OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE* pParam =
1680 (OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE*)paramData;
1681 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAndroidImageGrid");
1682 m_sParamAndroidImageGrid.bEnabled = OMX_TRUE;
1683 m_sParamAndroidImageGrid.nTileWidth = DEFAULT_TILE_DIMENSION;
1684 m_sParamAndroidImageGrid.nTileHeight = DEFAULT_TILE_DIMENSION;
1685 m_sParamAndroidImageGrid.nGridRows =
1686 m_sInPortDef.format.video.nFrameHeight > 0 ?
1687 ((m_sInPortDef.format.video.nFrameHeight - 1) / DEFAULT_TILE_DIMENSION + 1) :
1688 DEFAULT_TILE_ROWS;
1689 m_sParamAndroidImageGrid.nGridCols =
1690 m_sInPortDef.format.video.nFrameWidth > 0 ?
1691 ((m_sInPortDef.format.video.nFrameWidth - 1) / DEFAULT_TILE_DIMENSION + 1) :
1692 DEFAULT_TILE_COLS;
1693 memcpy(pParam, &m_sParamAndroidImageGrid, sizeof(m_sParamAndroidImageGrid));
1694 break;
1695 }
1696 case OMX_IndexParamVideoProfileLevelQuerySupported:
1697 {
1698 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
1699 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
1700 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported");
1701 eRet = dev_get_supported_profile_level(pParam);
1702 if (eRet && eRet != OMX_ErrorNoMore)
1703 DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %u, %u",
1704 (unsigned int)pParam->eProfile, (unsigned int)pParam->eLevel);
1705 break;
1706 }
1707 case OMX_IndexParamVideoProfileLevelCurrent:
1708 {
1709 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
1710 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
1711 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent");
1712 memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel));
1713 break;
1714 }
1715 /*Component should support this port definition*/
1716 case OMX_IndexParamAudioInit:
1717 {
1718 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
1719 OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
1720 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
1721 memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio));
1722 break;
1723 }
1724 /*Component should support this port definition*/
1725 case OMX_IndexParamImageInit:
1726 {
1727 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
1728 OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
1729 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
1730 memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img));
1731 break;
1732
1733 }
1734 /*Component should support this port definition*/
1735 case OMX_IndexParamOtherInit:
1736 {
1737 DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x", paramIndex);
1738 eRet =OMX_ErrorUnsupportedIndex;
1739 break;
1740 }
1741 case OMX_IndexParamStandardComponentRole:
1742 {
1743 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
1744 OMX_PARAM_COMPONENTROLETYPE *comp_role;
1745 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
1746 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
1747 comp_role->nSize = sizeof(*comp_role);
1748
1749 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",paramIndex);
1750 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE);
1751 break;
1752 }
1753 /* Added for parameter test */
1754 case OMX_IndexParamPriorityMgmt:
1755 {
1756 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
1757 OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData;
1758 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
1759 memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt));
1760 break;
1761 }
1762 /* Added for parameter test */
1763 case OMX_IndexParamCompBufferSupplier:
1764 {
1765 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
1766 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
1767 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
1768 if (bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN) {
1769 memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier));
1770 } else if (bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT) {
1771 memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier));
1772 } else {
1773 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1774 eRet = OMX_ErrorBadPortIndex;
1775 }
1776 break;
1777 }
1778
1779 case OMX_IndexParamVideoQuantization:
1780 {
1781 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_QUANTIZATIONTYPE);
1782 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
1783 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization");
1784 memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization));
1785 break;
1786 }
1787
1788 case QOMX_IndexParamVideoInitialQp:
1789 {
1790 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_INITIALQP);
1791 QOMX_EXTNINDEX_VIDEO_INITIALQP *initial_qp = (QOMX_EXTNINDEX_VIDEO_INITIALQP*) paramData;
1792 DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoInitialQp");
1793 initial_qp->nQpI = m_sSessionQuantization.nQpI;
1794 initial_qp->nQpP = m_sSessionQuantization.nQpP;
1795 initial_qp->nQpB = m_sSessionQuantization.nQpB;
1796 initial_qp->bEnableInitQp = m_QPSet;
1797 break;
1798 }
1799
1800 case OMX_QcomIndexParamVideoIPBQPRange:
1801 {
1802 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE);
1803 OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE*) paramData;
1804 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoIPBQPRange");
1805 memcpy(qp_range, &m_sSessionQPRange, sizeof(m_sSessionQPRange));
1806 break;
1807 }
1808
1809 case OMX_IndexParamVideoErrorCorrection:
1810 {
1811 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE);
1812 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
1813 DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection");
1814 errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC;
1815 errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync;
1816 errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing;
1817 break;
1818 }
1819 case OMX_IndexParamVideoIntraRefresh:
1820 {
1821 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_INTRAREFRESHTYPE);
1822 OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
1823 DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh");
1824 DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET");
1825 intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode;
1826 intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs;
1827 break;
1828 }
1829 case OMX_QcomIndexPortDefn:
1830 //TODO
1831 break;
1832 case OMX_COMPONENT_CAPABILITY_TYPE_INDEX:
1833 {
1834 VALIDATE_OMX_PARAM_DATA(paramData, OMXComponentCapabilityFlagsType);
1835 OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData);
1836 DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX");
1837 pParam->iIsOMXComponentMultiThreaded = OMX_TRUE;
1838 pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE;
1839 pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
1840 pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
1841 pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE;
1842 pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE;
1843 pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE;
1844 pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE;
1845 m_use_input_pmem = OMX_TRUE;
1846 DEBUG_PRINT_LOW("Supporting capability index in encoder node");
1847 break;
1848 }
1849 case OMX_QcomIndexParamIndexExtraDataType:
1850 {
1851 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
1852 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType");
1853 QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
1854 if (pParam->nIndex == (OMX_INDEXTYPE)OMX_QTI_ExtraDataCategory_Advanced) {
1855 if (pParam->nPortIndex == PORT_INDEX_OUT) {
1856 pParam->bEnabled = (OMX_BOOL)(m_sExtraData & EXTRADATA_ADVANCED);
1857 DEBUG_PRINT_HIGH("Advanced extradata %d", pParam->bEnabled);
1858 } else {
1859 DEBUG_PRINT_ERROR("get_parameter: Advanced extradata is "
1860 "valid for output port only");
1861 eRet = OMX_ErrorUnsupportedIndex;
1862 }
1863 } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_QTI_ExtraDataCategory_Enc_ROI) {
1864 if (pParam->nPortIndex == PORT_INDEX_IN) {
1865 pParam->bEnabled = (OMX_BOOL)(m_sExtraData & EXTRADATA_ENC_INPUT_ROI);
1866 DEBUG_PRINT_HIGH("ROI %d", pParam->bEnabled);
1867 } else {
1868 DEBUG_PRINT_ERROR("get_parameter: ROI is valid for input port only");
1869 eRet = OMX_ErrorUnsupportedIndex;
1870 }
1871 } else {
1872 DEBUG_PRINT_ERROR("get_parameter: unsupported extradata index (0x%x)",
1873 pParam->nPortIndex);
1874 eRet = OMX_ErrorUnsupportedIndex;
1875 }
1876 break;
1877 }
1878 case OMX_QTIIndexParamVideoClientExtradata:
1879 {
1880 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
1881 DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVideoClientExtradata");
1882 QOMX_EXTRADATA_ENABLE *pParam =
1883 (QOMX_EXTRADATA_ENABLE *)paramData;
1884 if (pParam->nPortIndex == PORT_INDEX_EXTRADATA_OUT) {
1885 OMX_U32 output_extradata_mask = EXTRADATA_ADVANCED;
1886 pParam->bEnable = (m_sExtraData & output_extradata_mask) ? OMX_TRUE : OMX_FALSE;
1887 eRet = OMX_ErrorNone;
1888 } else if (pParam->nPortIndex == PORT_INDEX_EXTRADATA_IN) {
1889 OMX_U32 input_extradata_mask = EXTRADATA_ENC_INPUT_ROI;
1890 pParam->bEnable = (m_sExtraData & input_extradata_mask) ? OMX_TRUE : OMX_FALSE;
1891 eRet = OMX_ErrorNone;
1892 } else {
1893 DEBUG_PRINT_ERROR("get_parameter: unsupported extradata index (0x%x)",
1894 pParam->nPortIndex);
1895 eRet = OMX_ErrorUnsupportedIndex;
1896 }
1897 break;
1898 }
1899 case OMX_QcomIndexParamVideoLTRCount:
1900 {
1901 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE);
1902 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoLTRCount");
1903 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE *pParam =
1904 reinterpret_cast<OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*>(paramData);
1905 memcpy(pParam, &m_sParamLTRCount, sizeof(m_sParamLTRCount));
1906 break;
1907 }
1908 case QOMX_IndexParamVideoSyntaxHdr:
1909 {
1910 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_PARAMTYPE);
1911 DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr");
1912 QOMX_EXTNINDEX_PARAMTYPE* pParam =
1913 reinterpret_cast<QOMX_EXTNINDEX_PARAMTYPE*>(paramData);
1914 if (pParam->pData == NULL) {
1915 DEBUG_PRINT_ERROR("Error: Data buffer is NULL");
1916 eRet = OMX_ErrorBadParameter;
1917 break;
1918 }
1919 if (get_syntaxhdr_enable == false) {
1920 DEBUG_PRINT_ERROR("ERROR: get_parameter: Get syntax header disabled");
1921 eRet = OMX_ErrorUnsupportedIndex;
1922 break;
1923 }
1924 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
1925 if (dev_loaded_start()) {
1926 DEBUG_PRINT_LOW("device start successful");
1927 } else {
1928 DEBUG_PRINT_ERROR("device start failed");
1929 BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
1930 return OMX_ErrorHardware;
1931 }
1932 if (dev_get_seq_hdr(pParam->pData,
1933 (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)),
1934 (unsigned *)(void *)&pParam->nDataSize)) {
1935 DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %u)",
1936 (unsigned int)pParam->nDataSize);
1937 for (unsigned i = 0; i < pParam->nDataSize; i++) {
1938 DEBUG_PRINT_LOW("Header[%d] = %x", i, *((char *)pParam->pData + i));
1939 }
1940 } else {
1941 DEBUG_PRINT_ERROR("Error returned from GetSyntaxHeader()");
1942 eRet = OMX_ErrorHardware;
1943 }
1944 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
1945 if (dev_loaded_stop()) {
1946 DEBUG_PRINT_LOW("device stop successful");
1947 } else {
1948 DEBUG_PRINT_ERROR("device stop failed");
1949 BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
1950 eRet = OMX_ErrorHardware;
1951 }
1952 break;
1953 }
1954 case OMX_QcomIndexHierarchicalStructure:
1955 {
1956 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_HIERARCHICALLAYERS);
1957 QOMX_VIDEO_HIERARCHICALLAYERS* hierp = (QOMX_VIDEO_HIERARCHICALLAYERS*) paramData;
1958 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexHierarchicalStructure");
1959 memcpy(hierp, &m_sHierLayers, sizeof(m_sHierLayers));
1960 break;
1961 }
1962 case OMX_QcomIndexParamH264VUITimingInfo:
1963 {
1964 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO);
1965 OMX_U32 enabled;
1966 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
1967 reinterpret_cast<OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO*>(paramData);
1968 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamH264VUITimingInfo");
1969 if (!dev_get_vui_timing_info(&enabled)) {
1970 DEBUG_PRINT_ERROR("Invalid entry returned from get_vui_Timing_info %d",
1971 pParam->bEnable);
1972 } else {
1973 pParam->bEnable = (OMX_BOOL)enabled;
1974 }
1975 break;
1976 }
1977 case OMX_QcomIndexParamBatchSize:
1978 {
1979 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_U32TYPE);
1980 OMX_PARAM_U32TYPE* batch =
1981 reinterpret_cast<OMX_PARAM_U32TYPE *>(paramData);
1982
1983 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamBatchSize");
1984 if (!dev_get_batch_size(&batch->nU32)) {
1985 DEBUG_PRINT_ERROR("Invalid entry returned from dev_get_batch_size %u",
1986 (unsigned int)batch->nSize);
1987 eRet = OMX_ErrorUnsupportedIndex;
1988 break;
1989 }
1990
1991 batch->nPortIndex = PORT_INDEX_IN;
1992 break;
1993 }
1994 case OMX_QcomIndexParamSequenceHeaderWithIDR:
1995 {
1996 VALIDATE_OMX_PARAM_DATA(paramData, PrependSPSPPSToIDRFramesParams);
1997 PrependSPSPPSToIDRFramesParams * pParam =
1998 reinterpret_cast<PrependSPSPPSToIDRFramesParams *>(paramData);
1999 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamSequenceHeaderWithIDR");
2000 memcpy(pParam, &m_sPrependSPSPPS, sizeof(m_sPrependSPSPPS));
2001 break;
2002 }
2003 case OMX_QcomIndexParamVencAspectRatio:
2004 {
2005 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_VENC_SAR);
2006 QOMX_EXTNINDEX_VIDEO_VENC_SAR * pParam =
2007 reinterpret_cast<QOMX_EXTNINDEX_VIDEO_VENC_SAR *>(paramData);
2008 memcpy(pParam, &m_sSar, sizeof(m_sSar));
2009 break;
2010 }
2011 case OMX_IndexParamAndroidVideoTemporalLayering:
2012 {
2013 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
2014 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pLayerInfo =
2015 reinterpret_cast<OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*>(paramData);
2016 if (!dev_get_temporal_layer_caps(&m_sParamTemporalLayers.nLayerCountMax,
2017 &m_sParamTemporalLayers.nBLayerCountMax, &m_sParamTemporalLayers.eSupportedPatterns)) {
2018 DEBUG_PRINT_ERROR("Failed to get temporal layer capabilities");
2019 eRet = OMX_ErrorHardware;
2020 }
2021 memcpy(pLayerInfo, &m_sParamTemporalLayers, sizeof(m_sParamTemporalLayers));
2022 break;
2023 }
2024 case OMX_QcomIndexParamVideoDownScalar:
2025 {
2026 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR);
2027 QOMX_INDEXDOWNSCALAR *pDownScalarParam =
2028 reinterpret_cast<QOMX_INDEXDOWNSCALAR *>(paramData);
2029 memcpy(pDownScalarParam, &m_sParamDownScalar, sizeof(m_sParamDownScalar));
2030 break;
2031 }
2032 case OMX_IndexParamVideoAndroidVp8Encoder:
2033 {
2034 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE);
2035 OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *pVp8Params =
2036 reinterpret_cast<OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE*>(paramData);
2037 memcpy(pVp8Params,&m_sParamVP8Encoder,sizeof(m_sParamVP8Encoder));
2038 break;
2039 }
2040 case OMX_IndexParamConsumerUsageBits:
2041 {
2042 /* Consumer usage bits
2043 * --------------------------------------------------------------------
2044 * GRALLOC_USAGE_PRIVATE_ | GRALLOC_USAGE_PRIVATE_ | Color |
2045 * ALLOC_UBWC | ALLOC_10BITS | Format |
2046 * (bit 28) | (bit30) | |
2047 * --------------------------------------------------------------------
2048 * 0 | 0 | NV12 |
2049 * 0 | 1 | P010 |
2050 * 1 | 0 | UBWC_NV12 |
2051 * 1 | 1 | BPP10_UBWC |
2052 * --------------------------------------------------------------------
2053 */
2054
2055 if (paramData == NULL) { return OMX_ErrorBadParameter; }
2056
2057 OMX_U32 *consumerUsage = (OMX_U32 *)paramData;
2058 m_sParamConsumerUsage = 0;
2059 dev_get_consumer_usage(&m_sParamConsumerUsage);
2060 memcpy(consumerUsage, &m_sParamConsumerUsage, sizeof(m_sParamConsumerUsage));
2061 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamConsumerUsageBits %x",
2062 m_sParamConsumerUsage);
2063 break;
2064 }
2065 case OMX_IndexParamVideoSliceFMO:
2066 default:
2067 {
2068 DEBUG_PRINT_LOW("ERROR: get_parameter: unknown param %08x", paramIndex);
2069 eRet =OMX_ErrorUnsupportedIndex;
2070 break;
2071 }
2072
2073 }
2074
2075 return eRet;
2076
2077 }
2078 /* ======================================================================
2079 FUNCTION
2080 omx_video::GetConfig
2081
2082 DESCRIPTION
2083 OMX Get Config Method implementation.
2084
2085 PARAMETERS
2086 <TBD>.
2087
2088 RETURN VALUE
2089 OMX Error None if successful.
2090
2091 ========================================================================== */
get_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_INOUT OMX_PTR configData)2092 OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp,
2093 OMX_IN OMX_INDEXTYPE configIndex,
2094 OMX_INOUT OMX_PTR configData)
2095 {
2096 (void)hComp;
2097 ////////////////////////////////////////////////////////////////
2098 // Supported Config Index Type
2099 // =============================================================
2100 // OMX_IndexConfigVideoBitrate OMX_VIDEO_CONFIG_BITRATETYPE
2101 // OMX_IndexConfigVideoFramerate OMX_CONFIG_FRAMERATETYPE
2102 // OMX_IndexConfigCommonRotate OMX_CONFIG_ROTATIONTYPE
2103 ////////////////////////////////////////////////////////////////
2104
2105 if (configData == NULL) {
2106 DEBUG_PRINT_ERROR("ERROR: param is null");
2107 return OMX_ErrorBadParameter;
2108 }
2109
2110 if (m_state == OMX_StateInvalid) {
2111 DEBUG_PRINT_ERROR("ERROR: can't be in invalid state");
2112 return OMX_ErrorIncorrectStateOperation;
2113 }
2114
2115 //@todo need to validate params
2116 switch ((int)configIndex) {
2117 case OMX_IndexConfigVideoBitrate:
2118 {
2119 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_BITRATETYPE);
2120 OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
2121 memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate));
2122 break;
2123 }
2124 case OMX_IndexConfigVideoFramerate:
2125 {
2126 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_FRAMERATETYPE);
2127 OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
2128 memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate));
2129 break;
2130 }
2131 case OMX_IndexConfigCommonRotate:
2132 {
2133 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ROTATIONTYPE);
2134 OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
2135 memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation));
2136 break;
2137 }
2138 case OMX_IndexConfigCommonMirror:
2139 {
2140 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_MIRRORTYPE);
2141 OMX_CONFIG_MIRRORTYPE* pParam = reinterpret_cast<OMX_CONFIG_MIRRORTYPE*>(configData);
2142 memcpy(pParam, &m_sConfigFrameMirror, sizeof(m_sConfigFrameMirror));
2143 break;
2144 }
2145 case QOMX_IndexConfigVideoIntraperiod:
2146 {
2147 DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod nPframes : %d nBframes : %d",
2148 m_sIntraperiod.nPFrames, m_sIntraperiod.nBFrames);
2149 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_INTRAPERIODTYPE);
2150 QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
2151 memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod));
2152 break;
2153 }
2154 case OMX_IndexConfigVideoAVCIntraPeriod:
2155 {
2156 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_AVCINTRAPERIOD);
2157 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam =
2158 reinterpret_cast<OMX_VIDEO_CONFIG_AVCINTRAPERIOD*>(configData);
2159 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoAVCIntraPeriod");
2160 memcpy(pParam, &m_sConfigAVCIDRPeriod, sizeof(m_sConfigAVCIDRPeriod));
2161 break;
2162 }
2163 case OMX_IndexConfigVideoVp8ReferenceFrame:
2164 {
2165 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_VP8REFERENCEFRAMETYPE);
2166 OMX_VIDEO_VP8REFERENCEFRAMETYPE* pParam =
2167 reinterpret_cast<OMX_VIDEO_VP8REFERENCEFRAMETYPE*>(configData);
2168 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoVp8ReferenceFrame");
2169 memcpy(pParam, &m_sConfigVp8ReferenceFrame, sizeof(m_sConfigVp8ReferenceFrame));
2170 break;
2171 }
2172 case OMX_QcomIndexConfigNumHierPLayers:
2173 {
2174 VALIDATE_OMX_PARAM_DATA(configData, QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS);
2175 QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS* pParam =
2176 reinterpret_cast<QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS*>(configData);
2177 DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigNumHierPLayers");
2178 memcpy(pParam, &m_sHPlayers, sizeof(m_sHPlayers));
2179 break;
2180 }
2181 case OMX_QcomIndexConfigQp:
2182 {
2183 VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_QP);
2184 OMX_SKYPE_VIDEO_CONFIG_QP* pParam =
2185 reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_QP*>(configData);
2186 DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigQp");
2187 memcpy(pParam, &m_sConfigQP, sizeof(m_sConfigQP));
2188 break;
2189 }
2190 case OMX_QcomIndexConfigBaseLayerId:
2191 {
2192 VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID);
2193 OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
2194 reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*>(configData);
2195 DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigBaseLayerId");
2196 memcpy(pParam, &m_sBaseLayerID, sizeof(m_sBaseLayerID));
2197 break;
2198 }
2199 case OMX_IndexConfigAndroidIntraRefresh:
2200 {
2201 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE);
2202 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE* pParam =
2203 reinterpret_cast<OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE*>(configData);
2204 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidIntraRefresh");
2205 memcpy(pParam, &m_sConfigIntraRefresh, sizeof(m_sConfigIntraRefresh));
2206 break;
2207 }
2208 case OMX_IndexConfigOperatingRate:
2209 {
2210 VALIDATE_OMX_PARAM_DATA(configData, OMX_PARAM_U32TYPE);
2211 OMX_PARAM_U32TYPE* pParam =
2212 reinterpret_cast<OMX_PARAM_U32TYPE*>(configData);
2213 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigOperatingRate");
2214 pParam->nU32 = m_nOperatingRate;
2215 break;
2216 }
2217 case OMX_QTIIndexConfigVideoBlurResolution:
2218 {
2219 VALIDATE_OMX_PARAM_DATA(configData, OMX_QTI_VIDEO_CONFIG_BLURINFO);
2220 OMX_QTI_VIDEO_CONFIG_BLURINFO* pParam =
2221 reinterpret_cast<OMX_QTI_VIDEO_CONFIG_BLURINFO*>(configData);
2222 DEBUG_PRINT_LOW("get_config: OMX_QTIIndexConfigVideoBlurResolution");
2223 memcpy(pParam, &m_blurInfo, sizeof(OMX_QTI_VIDEO_CONFIG_BLURINFO));
2224 break;
2225 }
2226 case OMX_QTIIndexConfigDescribeColorAspects:
2227 {
2228 VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
2229 DescribeColorAspectsParams* pParam =
2230 reinterpret_cast<DescribeColorAspectsParams*>(configData);
2231 DEBUG_PRINT_LOW("get_config: OMX_QTIIndexConfigDescribeColorAspects");
2232 if (pParam->bRequestingDataSpace) {
2233 DEBUG_PRINT_LOW("Does not handle dataspace request. Please ignore this Unsupported Setting (0x80001019).");
2234 return OMX_ErrorUnsupportedSetting;
2235 }
2236 if (pParam->bDataSpaceChanged == OMX_TRUE) {
2237
2238 print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) Client says");
2239 // If the dataspace says RGB, recommend 601-limited;
2240 // since that is the destination colorspace that C2D or Venus will convert to.
2241 if (pParam->nPixelFormat == HAL_PIXEL_FORMAT_RGBA_8888) {
2242 DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: Recommend 601 for RGBA8888");
2243 pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
2244 // keep client-default setting for range
2245 // pParam->sAspects.mRange = ColorAspects::RangeLimited;
2246 pParam->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
2247 pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
2248 } else {
2249 DEBUG_PRINT_INFO("get_config (dataspace changed): dataspace=0x%x", pParam->nDataSpace);
2250 if (pParam->nDataSpace == HAL_DATASPACE_JFIF || pParam->nDataSpace == HAL_DATASPACE_V0_JFIF) {
2251 DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: for HAL_DATASPACE_JFIF");
2252 pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
2253 pParam->sAspects.mRange = ColorAspects::RangeFull;
2254 pParam->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
2255 pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
2256 } else if (pParam->nDataSpace == HAL_DATASPACE_BT601_525 || pParam->nDataSpace == HAL_DATASPACE_V0_BT601_525) {
2257 DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: for HAL_DATASPACE_BT601_525");
2258 pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_525;
2259 pParam->sAspects.mRange = ColorAspects::RangeLimited;
2260 pParam->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
2261 pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
2262 } else if (pParam->nDataSpace == HAL_DATASPACE_BT601_625 || pParam->nDataSpace == HAL_DATASPACE_V0_BT601_625) {
2263 DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: for HAL_DATASPACE_BT601_625");
2264 pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
2265 pParam->sAspects.mRange = ColorAspects::RangeLimited;
2266 pParam->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
2267 pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
2268 } else if (pParam->nDataSpace == HAL_DATASPACE_BT709 || pParam->nDataSpace == HAL_DATASPACE_V0_BT709) {
2269 DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: for HAL_DATASPACE_BT709");
2270 pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT709_5;
2271 pParam->sAspects.mRange = ColorAspects::RangeLimited;
2272 pParam->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
2273 pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT709_5;
2274 } else if (pParam->nDataSpace == HAL_DATASPACE_BT2020) {
2275 DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: for HAL_DATASPACE_BT2020");
2276 pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT2020;
2277 pParam->sAspects.mRange = ColorAspects::RangeFull;
2278 pParam->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
2279 pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT2020;
2280 } else if (pParam->nDataSpace == (HAL_DATASPACE_STANDARD_BT2020|HAL_DATASPACE_TRANSFER_HLG|HAL_DATASPACE_RANGE_LIMITED)) {
2281 //For SONY HDR
2282 DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: for HAL_DATASPACE_STANDARD_BT2020|HAL_DATASPACE_TRANSFER_HLG|HAL_DATASPACE_RANGE_LIMITED");
2283 pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT2020;
2284 pParam->sAspects.mRange = ColorAspects::RangeLimited;
2285 pParam->sAspects.mTransfer = ColorAspects::TransferHLG;
2286 pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT2020;
2287 } else {
2288 // Stick to client's defaults.
2289 DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: use client-default for format=%x",
2290 pParam->nPixelFormat);
2291 }
2292 }
2293 print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) recommended");
2294 } else {
2295 memcpy(pParam, &m_sConfigColorAspects, sizeof(m_sConfigColorAspects));
2296 print_debug_color_aspects(&(pParam->sAspects), "get_config");
2297 }
2298 break;
2299 }
2300 case OMX_IndexConfigAndroidVideoTemporalLayering:
2301 {
2302 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE);
2303 OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *layerConfig =
2304 (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *)configData;
2305 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidVideoTemporalLayering");
2306 memcpy(configData, &m_sConfigTemporalLayers, sizeof(m_sConfigTemporalLayers));
2307 break;
2308 }
2309 case OMX_IndexConfigAndroidVendorExtension:
2310 {
2311 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
2312
2313 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
2314 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
2315 VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
2316 return get_vendor_extension_config(ext);
2317 }
2318
2319 default:
2320 DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
2321 return OMX_ErrorUnsupportedIndex;
2322 }
2323 return OMX_ErrorNone;
2324
2325 }
2326
2327 #define extn_equals(param, extn) (!strcmp(param, extn))
2328
2329 /* ======================================================================
2330 FUNCTION
2331 omx_video::GetExtensionIndex
2332
2333 DESCRIPTION
2334 OMX GetExtensionIndex method implementaion. <TBD>
2335
2336 PARAMETERS
2337 <TBD>.
2338
2339 RETURN VALUE
2340 OMX Error None if everything successful.
2341
2342 ========================================================================== */
get_extension_index(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_STRING paramName,OMX_OUT OMX_INDEXTYPE * indexType)2343 OMX_ERRORTYPE omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
2344 OMX_IN OMX_STRING paramName,
2345 OMX_OUT OMX_INDEXTYPE* indexType)
2346 {
2347 (void)hComp;
2348 if (m_state == OMX_StateInvalid) {
2349 DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State");
2350 return OMX_ErrorInvalidState;
2351 }
2352
2353 #ifdef _ANDROID_ICS_
2354 if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
2355 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
2356 return OMX_ErrorNone;
2357 }
2358 #endif
2359 if (extn_equals(paramName, "OMX.google.android.index.prependSPSPPSToIDRFrames")) {
2360 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR;
2361 return OMX_ErrorNone;
2362 }
2363
2364 if (extn_equals(paramName, "OMX.QCOM.index.param.video.HierStructure")) {
2365 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexHierarchicalStructure;
2366 return OMX_ErrorNone;
2367 }
2368
2369 if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRCount")) {
2370 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoLTRCount;
2371 return OMX_ErrorNone;
2372 }
2373
2374 if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRPeriod")) {
2375 return OMX_ErrorNone;
2376 }
2377
2378 if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRUse")) {
2379 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRUse;
2380 return OMX_ErrorNone;
2381 }
2382
2383 if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRMark")) {
2384 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRMark;
2385 return OMX_ErrorNone;
2386 }
2387
2388 if (extn_equals(paramName, "OMX.QCOM.index.config.video.hierplayers")) {
2389 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigNumHierPLayers;
2390 return OMX_ErrorNone;
2391 }
2392
2393 if (extn_equals(paramName, "OMX.QCOM.index.param.video.baselayerid")) {
2394 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigBaseLayerId;
2395 return OMX_ErrorNone;
2396 }
2397
2398 if (extn_equals(paramName, "OMX.QCOM.index.config.video.qp")) {
2399 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigQp;
2400 return OMX_ErrorNone;
2401 }
2402
2403 if (extn_equals(paramName, "OMX.QCOM.index.param.video.sar")) {
2404 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVencAspectRatio;
2405 return OMX_ErrorNone;
2406 }
2407
2408 if (extn_equals(paramName, "OMX.QCOM.index.param.video.InputBatch")) {
2409 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamBatchSize;
2410 return OMX_ErrorNone;
2411 }
2412
2413 if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_SETTIMEDATA)) {
2414 *indexType = (OMX_INDEXTYPE)OMX_IndexConfigTimePosition;
2415 return OMX_ErrorNone;
2416 }
2417
2418 if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_ENABLE_ROIINFO)) {
2419 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoEnableRoiInfo;
2420 return OMX_ErrorNone;
2421 }
2422
2423 if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_ROIINFO)) {
2424 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoRoiInfo;
2425 return OMX_ErrorNone;
2426 }
2427
2428 if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_BLURINFO)) {
2429 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoBlurResolution;
2430 return OMX_ErrorNone;
2431 }
2432
2433 if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) {
2434 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
2435 return OMX_ErrorNone;
2436 }
2437
2438 if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) {
2439 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle;
2440 return OMX_ErrorNone;
2441 }
2442
2443 if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_CLIENT_EXTRADATA)) {
2444 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoClientExtradata;
2445 return OMX_ErrorNone;
2446 }
2447
2448 if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_NATIVE_RECORDER)) {
2449 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamNativeRecorder;
2450 return OMX_ErrorNone;
2451 }
2452
2453 return OMX_ErrorNotImplemented;
2454 }
2455
2456 /* ======================================================================
2457 FUNCTION
2458 omx_video::GetState
2459
2460 DESCRIPTION
2461 Returns the state information back to the caller.<TBD>
2462
2463 PARAMETERS
2464 <TBD>.
2465
2466 RETURN VALUE
2467 Error None if everything is successful.
2468 ========================================================================== */
get_state(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_STATETYPE * state)2469 OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp,
2470 OMX_OUT OMX_STATETYPE* state)
2471 {
2472 (void)hComp;
2473 *state = m_state;
2474 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
2475 return OMX_ErrorNone;
2476 }
2477
2478 /* ======================================================================
2479 FUNCTION
2480 omx_video::ComponentTunnelRequest
2481
2482 DESCRIPTION
2483 OMX Component Tunnel Request method implementation. <TBD>
2484
2485 PARAMETERS
2486 None.
2487
2488 RETURN VALUE
2489 OMX Error None if everything successful.
2490
2491 ========================================================================== */
component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_HANDLETYPE peerComponent,OMX_IN OMX_U32 peerPort,OMX_INOUT OMX_TUNNELSETUPTYPE * tunnelSetup)2492 OMX_ERRORTYPE omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
2493 OMX_IN OMX_U32 port,
2494 OMX_IN OMX_HANDLETYPE peerComponent,
2495 OMX_IN OMX_U32 peerPort,
2496 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
2497 {
2498 (void) hComp, (void) port, (void) peerComponent, (void) peerPort, (void) tunnelSetup;
2499 DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented");
2500 return OMX_ErrorNotImplemented;
2501 }
2502
2503 /* ======================================================================
2504 FUNCTION
2505 omx_video::UseInputBuffer
2506
2507 DESCRIPTION
2508 Helper function for Use buffer in the input pin
2509
2510 PARAMETERS
2511 None.
2512
2513 RETURN VALUE
2514 true/false
2515
2516 ========================================================================== */
use_input_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)2517 OMX_ERRORTYPE omx_video::use_input_buffer(
2518 OMX_IN OMX_HANDLETYPE hComp,
2519 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2520 OMX_IN OMX_U32 port,
2521 OMX_IN OMX_PTR appData,
2522 OMX_IN OMX_U32 bytes,
2523 OMX_IN OMX_U8* buffer)
2524 {
2525 (void) hComp;
2526 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2527
2528 unsigned i = 0;
2529 unsigned char *buf_addr = NULL;
2530
2531 DEBUG_PRINT_HIGH("use_input_buffer: port = %u appData = %p bytes = %u buffer = %p",(unsigned int)port,appData,(unsigned int)bytes,buffer);
2532 if (bytes < m_sInPortDef.nBufferSize) {
2533 DEBUG_PRINT_ERROR("ERROR: use_input_buffer: Size Mismatch!! "
2534 "bytes[%u] < Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize);
2535 return OMX_ErrorBadParameter;
2536 }
2537
2538 if (!m_inp_mem_ptr) {
2539 input_use_buffer = true;
2540 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
2541 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
2542 if (m_inp_mem_ptr == NULL) {
2543 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr");
2544 return OMX_ErrorInsufficientResources;
2545 }
2546 DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);
2547
2548
2549 m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
2550 if (m_pInput_pmem == NULL) {
2551 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_pmem");
2552 return OMX_ErrorInsufficientResources;
2553 }
2554 #ifdef USE_ION
2555 m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
2556 if (m_pInput_ion == NULL) {
2557 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_ion");
2558 return OMX_ErrorInsufficientResources;
2559 }
2560 #endif
2561
2562 for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
2563 m_pInput_pmem[i].fd = -1;
2564 #ifdef USE_ION
2565 m_pInput_ion[i].data_fd =-1;
2566 m_pInput_ion[i].dev_fd =-1;
2567 #endif
2568 }
2569
2570 }
2571
2572 for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
2573 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
2574 break;
2575 }
2576 }
2577
2578 if (i < m_sInPortDef.nBufferCountActual) {
2579
2580 *bufferHdr = (m_inp_mem_ptr + i);
2581 BITMASK_SET(&m_inp_bm_count,i);
2582 BITMASK_SET(&m_client_in_bm_count,i);
2583
2584 (*bufferHdr)->pBuffer = (OMX_U8 *)buffer;
2585 (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
2586 (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
2587 (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize;
2588 (*bufferHdr)->pAppPrivate = appData;
2589 (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN;
2590
2591 if (!m_use_input_pmem) {
2592 #ifdef USE_ION
2593 bool status = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
2594 &m_pInput_ion[i],
2595 secure_session ? SECURE_FLAGS_INPUT_BUFFER : 0);
2596 if (status == false) {
2597 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
2598 return OMX_ErrorInsufficientResources;
2599 }
2600 m_pInput_pmem[i].fd = m_pInput_ion[i].data_fd;
2601 #endif
2602 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
2603 m_pInput_pmem[i].offset = 0;
2604
2605 m_pInput_pmem[i].buffer = NULL;
2606 if(!secure_session) {
2607 m_pInput_pmem[i].buffer = (unsigned char *)ion_map(m_pInput_pmem[i].fd,
2608 m_pInput_pmem[i].size);
2609
2610 if (m_pInput_pmem[i].buffer == MAP_FAILED) {
2611 DEBUG_PRINT_ERROR("ERROR: mmap() Failed");
2612 m_pInput_pmem[i].buffer = NULL;
2613 #ifdef USE_ION
2614 free_ion_memory(&m_pInput_ion[i]);
2615 #endif
2616 return OMX_ErrorInsufficientResources;
2617 }
2618 }
2619
2620 } else {
2621 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate);
2622 DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (unsigned)pParam->offset);
2623
2624 if (pParam) {
2625 m_pInput_pmem[i].fd = pParam->pmem_fd;
2626 m_pInput_pmem[i].offset = pParam->offset;
2627 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
2628 m_pInput_pmem[i].buffer = (unsigned char *)buffer;
2629 DEBUG_PRINT_LOW("DBG:: pParam->pmem_fd = %u, pParam->offset = %u",
2630 (unsigned int)pParam->pmem_fd, (unsigned int)pParam->offset);
2631 } else {
2632 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case");
2633 return OMX_ErrorBadParameter;
2634 }
2635 }
2636
2637 DEBUG_PRINT_LOW("use_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p",
2638 (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer);
2639 if (dev_use_buf(PORT_INDEX_IN) != true) {
2640 DEBUG_PRINT_ERROR("ERROR: dev_use_buf() Failed for i/p buf");
2641 return OMX_ErrorInsufficientResources;
2642 }
2643 } else {
2644 DEBUG_PRINT_ERROR("ERROR: All buffers are already used, invalid use_buf call for "
2645 "index = %u", i);
2646 eRet = OMX_ErrorInsufficientResources;
2647 }
2648
2649 return eRet;
2650 }
2651
2652
2653
2654 /* ======================================================================
2655 FUNCTION
2656 omx_video::UseOutputBuffer
2657
2658 DESCRIPTION
2659 Helper function for Use buffer in the input pin
2660
2661 PARAMETERS
2662 None.
2663
2664 RETURN VALUE
2665 true/false
2666
2667 ========================================================================== */
use_output_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)2668 OMX_ERRORTYPE omx_video::use_output_buffer(
2669 OMX_IN OMX_HANDLETYPE hComp,
2670 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2671 OMX_IN OMX_U32 port,
2672 OMX_IN OMX_PTR appData,
2673 OMX_IN OMX_U32 bytes,
2674 OMX_IN OMX_U8* buffer)
2675 {
2676 (void)hComp, (void)port;
2677 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2678 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
2679 unsigned i= 0; // Temporary counter
2680 unsigned char *buf_addr = NULL;
2681 int align_size;
2682
2683 DEBUG_PRINT_HIGH("Inside use_output_buffer()");
2684 if (bytes < m_sOutPortDef.nBufferSize) {
2685 DEBUG_PRINT_ERROR("ERROR: use_output_buffer: Size Mismatch!! "
2686 "bytes[%u] < Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sOutPortDef.nBufferSize);
2687 return OMX_ErrorBadParameter;
2688 }
2689
2690 if (!m_out_mem_ptr) {
2691 output_use_buffer = true;
2692 int nBufHdrSize = 0;
2693
2694 DEBUG_PRINT_LOW("Allocating First Output Buffer(%u)",(unsigned int)m_sOutPortDef.nBufferCountActual);
2695 nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
2696 /*
2697 * Memory for output side involves the following:
2698 * 1. Array of Buffer Headers
2699 * 2. Bitmask array to hold the buffer allocation details
2700 * In order to minimize the memory management entire allocation
2701 * is done in one step.
2702 */
2703 //OMX Buffer header
2704 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
2705 if (m_out_mem_ptr == NULL) {
2706 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_out_mem_ptr");
2707 return OMX_ErrorInsufficientResources;
2708 }
2709
2710 m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual);
2711 if (m_pOutput_pmem == NULL) {
2712 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_pmem");
2713 return OMX_ErrorInsufficientResources;
2714 }
2715 #ifdef USE_ION
2716 m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
2717 if (m_pOutput_ion == NULL) {
2718 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_ion");
2719 return OMX_ErrorInsufficientResources;
2720 }
2721 #endif
2722 if (m_out_mem_ptr) {
2723 bufHdr = m_out_mem_ptr;
2724 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
2725 // Settting the entire storage nicely
2726 for (i=0; i < m_sOutPortDef.nBufferCountActual ; i++) {
2727 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
2728 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
2729 bufHdr->nAllocLen = bytes;
2730 bufHdr->nFilledLen = 0;
2731 bufHdr->pAppPrivate = appData;
2732 bufHdr->nOutputPortIndex = PORT_INDEX_OUT;
2733 bufHdr->pBuffer = NULL;
2734 bufHdr++;
2735 m_pOutput_pmem[i].fd = -1;
2736 #ifdef USE_ION
2737 m_pOutput_ion[i].data_fd =-1;
2738 m_pOutput_ion[i].dev_fd =-1;
2739 #endif
2740 }
2741 } else {
2742 DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%p]",m_out_mem_ptr);
2743 eRet = OMX_ErrorInsufficientResources;
2744 }
2745 }
2746
2747 for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) {
2748 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
2749 break;
2750 }
2751 }
2752
2753 if (eRet == OMX_ErrorNone) {
2754 if (i < m_sOutPortDef.nBufferCountActual) {
2755 *bufferHdr = (m_out_mem_ptr + i );
2756 (*bufferHdr)->pBuffer = (OMX_U8 *)buffer;
2757 (*bufferHdr)->pAppPrivate = appData;
2758
2759 if (!m_use_output_pmem) {
2760 #ifdef USE_ION
2761 align_size = (m_sOutPortDef.nBufferSize + (SZ_4K - 1)) & ~(SZ_4K - 1);
2762 bool status = alloc_map_ion_memory(align_size,
2763 &m_pOutput_ion[i],
2764 secure_session ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
2765 if (status == false) {
2766 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
2767 return OMX_ErrorInsufficientResources;
2768 }
2769 m_pOutput_pmem[i].fd = m_pOutput_ion[i].data_fd;
2770 #endif
2771 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
2772 m_pOutput_pmem[i].offset = 0;
2773
2774 m_pOutput_pmem[i].buffer = NULL;
2775 if(!secure_session) {
2776 m_pOutput_pmem[i].buffer = (unsigned char *)ion_map(m_pOutput_pmem[i].fd,
2777 align_size);
2778 if (m_pOutput_pmem[i].buffer == MAP_FAILED) {
2779 DEBUG_PRINT_ERROR("ERROR: mmap() Failed");
2780 m_pOutput_pmem[i].buffer = NULL;
2781 #ifdef USE_ION
2782 free_ion_memory(&m_pOutput_ion[i]);
2783 #endif
2784 return OMX_ErrorInsufficientResources;
2785 }
2786 }
2787 } else {
2788 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate);
2789 DEBUG_PRINT_LOW("Inside qcom_ext pParam: %p", pParam);
2790
2791 if (pParam) {
2792 DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (int)pParam->offset);
2793 m_pOutput_pmem[i].fd = pParam->pmem_fd;
2794 m_pOutput_pmem[i].offset = pParam->offset;
2795 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
2796 m_pOutput_pmem[i].buffer = (unsigned char *)buffer;
2797 } else {
2798 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case");
2799 return OMX_ErrorBadParameter;
2800 }
2801 buf_addr = (unsigned char *)buffer;
2802 }
2803
2804 DEBUG_PRINT_LOW("use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p",
2805 (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer);
2806 if (dev_use_buf(PORT_INDEX_OUT) != true) {
2807 DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf");
2808 return OMX_ErrorInsufficientResources;
2809 }
2810
2811 BITMASK_SET(&m_out_bm_count,i);
2812 BITMASK_SET(&m_client_out_bm_count,i);
2813 } else {
2814 DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for "
2815 "index = %u", i);
2816 eRet = OMX_ErrorInsufficientResources;
2817 }
2818 }
2819 return eRet;
2820 }
2821
2822
2823 /* ======================================================================
2824 FUNCTION
2825 omx_video::UseBuffer
2826
2827 DESCRIPTION
2828 OMX Use Buffer method implementation.
2829
2830 PARAMETERS
2831 <TBD>.
2832
2833 RETURN VALUE
2834 OMX Error None , if everything successful.
2835
2836 ========================================================================== */
use_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)2837 OMX_ERRORTYPE omx_video::use_buffer(
2838 OMX_IN OMX_HANDLETYPE hComp,
2839 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2840 OMX_IN OMX_U32 port,
2841 OMX_IN OMX_PTR appData,
2842 OMX_IN OMX_U32 bytes,
2843 OMX_IN OMX_U8* buffer)
2844 {
2845 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2846 if (m_state == OMX_StateInvalid) {
2847 DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State");
2848 return OMX_ErrorInvalidState;
2849 }
2850
2851 auto_lock l(m_buf_lock);
2852 if (port == PORT_INDEX_IN) {
2853 eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
2854 } else if (port == PORT_INDEX_OUT) {
2855 eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
2856 } else if (port == PORT_INDEX_EXTRADATA_OUT) {
2857 eRet = use_client_output_extradata_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
2858 } else if (port == PORT_INDEX_EXTRADATA_IN) {
2859 eRet = use_client_input_extradata_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
2860 } else {
2861 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port);
2862 eRet = OMX_ErrorBadPortIndex;
2863 }
2864 if (eRet == OMX_ErrorNone) {
2865 if (allocate_done()) {
2866 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
2867 // Send the callback now
2868 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
2869 post_event(OMX_CommandStateSet,OMX_StateIdle,
2870 OMX_COMPONENT_GENERATE_EVENT);
2871 }
2872 }
2873 if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) {
2874 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
2875 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
2876 post_event(OMX_CommandPortEnable,
2877 PORT_INDEX_IN,
2878 OMX_COMPONENT_GENERATE_EVENT);
2879 }
2880
2881 } else if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) {
2882 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
2883 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2884 post_event(OMX_CommandPortEnable,
2885 PORT_INDEX_OUT,
2886 OMX_COMPONENT_GENERATE_EVENT);
2887 m_event_port_settings_sent = false;
2888 }
2889 }
2890 }
2891 return eRet;
2892 }
2893
allocate_client_output_extradata_headers()2894 OMX_ERRORTYPE omx_video::allocate_client_output_extradata_headers() {
2895 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2896 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
2897 int i = 0;
2898
2899 if (!m_client_output_extradata_mem_ptr) {
2900 int nBufferCount = 0;
2901
2902 nBufferCount = m_client_out_extradata_info.getBufferCount();
2903 DEBUG_PRINT_HIGH("allocate_client_output_extradata_headers buffer_count - %d", nBufferCount);
2904
2905 m_client_output_extradata_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufferCount, sizeof(OMX_BUFFERHEADERTYPE));
2906
2907 if (m_client_output_extradata_mem_ptr) {
2908 bufHdr = m_client_output_extradata_mem_ptr;
2909 for (i=0; i < nBufferCount; i++) {
2910 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
2911 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
2912 // Set the values when we determine the right HxW param
2913 bufHdr->nAllocLen = 0;
2914 bufHdr->nFilledLen = 0;
2915 bufHdr->pAppPrivate = NULL;
2916 bufHdr->nOutputPortIndex = PORT_INDEX_EXTRADATA_OUT;
2917 bufHdr->pBuffer = NULL;
2918 bufHdr->pOutputPortPrivate = NULL;
2919 bufHdr++;
2920 }
2921 } else {
2922 DEBUG_PRINT_ERROR("Extradata header buf mem alloc failed[0x%p]",\
2923 m_client_output_extradata_mem_ptr);
2924 eRet = OMX_ErrorInsufficientResources;
2925 }
2926 }
2927 return eRet;
2928 }
2929
allocate_client_input_extradata_headers()2930 OMX_ERRORTYPE omx_video::allocate_client_input_extradata_headers() {
2931 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2932 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
2933 int i = 0;
2934
2935 if (!m_client_input_extradata_mem_ptr) {
2936 int nBufferCount = 0;
2937
2938 nBufferCount = m_client_in_extradata_info.getBufferCount();
2939 DEBUG_PRINT_HIGH("allocate_client_input_extradata_headers buffer_count - %d", nBufferCount);
2940
2941 m_client_input_extradata_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufferCount, sizeof(OMX_BUFFERHEADERTYPE));
2942
2943 if (m_client_input_extradata_mem_ptr) {
2944 bufHdr = m_client_input_extradata_mem_ptr;
2945 for (i=0; i < nBufferCount; i++) {
2946 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
2947 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
2948 // Set the values when we determine the right HxW param
2949 bufHdr->nAllocLen = 0;
2950 bufHdr->nFilledLen = 0;
2951 bufHdr->pAppPrivate = NULL;
2952 bufHdr->nInputPortIndex = PORT_INDEX_EXTRADATA_IN;
2953 bufHdr->pBuffer = NULL;
2954 bufHdr->pOutputPortPrivate = NULL;
2955 bufHdr++;
2956 }
2957 } else {
2958 DEBUG_PRINT_ERROR("Extradata header buf mem alloc failed[0x%p]",\
2959 m_client_input_extradata_mem_ptr);
2960 eRet = OMX_ErrorInsufficientResources;
2961 }
2962 }
2963 return eRet;
2964 }
2965
use_client_output_extradata_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)2966 OMX_ERRORTYPE omx_video::use_client_output_extradata_buffer(
2967 OMX_IN OMX_HANDLETYPE hComp,
2968 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2969 OMX_IN OMX_U32 port,
2970 OMX_IN OMX_PTR appData,
2971 OMX_IN OMX_U32 bytes,
2972 OMX_IN OMX_U8* buffer)
2973 {
2974 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2975 unsigned i = 0; // Temporary counter
2976 unsigned buffer_count = m_client_out_extradata_info.getBufferCount();;
2977 OMX_U32 buffer_size = m_client_out_extradata_info.getSize();
2978 (void) hComp;
2979
2980 if (port != PORT_INDEX_EXTRADATA_OUT ||
2981 !m_sExtraData || bytes != buffer_size|| bufferHdr == NULL) {
2982 DEBUG_PRINT_ERROR("Bad Parameters PortIndex is - %d expected is- %d,"
2983 "client_extradata - %d, bytes = %d expected is %d bufferHdr - %p", port,
2984 PORT_INDEX_EXTRADATA_OUT, m_sExtraData, bytes, buffer_size, bufferHdr);
2985 eRet = OMX_ErrorBadParameter;
2986 return eRet;
2987 }
2988
2989 if (!m_client_output_extradata_mem_ptr) {
2990 eRet = allocate_client_output_extradata_headers();
2991 }
2992
2993 if (eRet == OMX_ErrorNone) {
2994 for (i = 0; i < buffer_count; i++) {
2995 if (BITMASK_ABSENT(&m_out_extradata_bm_count,i)) {
2996 break;
2997 }
2998 }
2999 }
3000
3001 if (i >= buffer_count) {
3002 DEBUG_PRINT_ERROR("invalid buffer index");
3003 eRet = OMX_ErrorInsufficientResources;
3004 }
3005
3006 if (eRet == OMX_ErrorNone) {
3007 BITMASK_SET(&m_out_extradata_bm_count,i);
3008 *bufferHdr = (m_client_output_extradata_mem_ptr + i );
3009 (*bufferHdr)->pAppPrivate = appData;
3010 (*bufferHdr)->pBuffer = buffer;
3011 (*bufferHdr)->nAllocLen = bytes;
3012 }
3013
3014 return eRet;
3015 }
3016
use_client_input_extradata_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)3017 OMX_ERRORTYPE omx_video::use_client_input_extradata_buffer(
3018 OMX_IN OMX_HANDLETYPE hComp,
3019 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3020 OMX_IN OMX_U32 port,
3021 OMX_IN OMX_PTR appData,
3022 OMX_IN OMX_U32 bytes,
3023 OMX_IN OMX_U8* buffer)
3024 {
3025 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3026 unsigned i = 0; // Temporary counter
3027 unsigned buffer_count = m_client_in_extradata_info.getBufferCount();
3028 OMX_U32 buffer_size = m_client_in_extradata_info.getSize();
3029 (void) hComp;
3030
3031 if (port != PORT_INDEX_EXTRADATA_IN ||
3032 !m_sExtraData || bytes != buffer_size|| bufferHdr == NULL) {
3033 DEBUG_PRINT_ERROR("Bad Parameters PortIndex is - %d expected is- %d,"
3034 "client_extradata - %d, bytes = %d expected is %d bufferHdr - %p", port,
3035 PORT_INDEX_EXTRADATA_IN, m_sExtraData, bytes, buffer_size, bufferHdr);
3036 eRet = OMX_ErrorBadParameter;
3037 return eRet;
3038 }
3039
3040 if (!m_client_input_extradata_mem_ptr) {
3041 eRet = allocate_client_input_extradata_headers();
3042 }
3043
3044 if (eRet == OMX_ErrorNone) {
3045 for (i = 0; i < buffer_count; i++) {
3046 if (BITMASK_ABSENT(&m_in_extradata_bm_count,i)) {
3047 break;
3048 }
3049 }
3050 }
3051
3052 if (i >= buffer_count) {
3053 DEBUG_PRINT_ERROR("invalid buffer index");
3054 eRet = OMX_ErrorInsufficientResources;
3055 }
3056
3057 if (eRet == OMX_ErrorNone) {
3058 BITMASK_SET(&m_in_extradata_bm_count,i);
3059 *bufferHdr = (m_client_input_extradata_mem_ptr + i );
3060 (*bufferHdr)->pAppPrivate = appData;
3061 (*bufferHdr)->pBuffer = buffer;
3062 (*bufferHdr)->nAllocLen = bytes;
3063 }
3064
3065 return eRet;
3066 }
3067
free_input_buffer(OMX_BUFFERHEADERTYPE * bufferHdr)3068 OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
3069 {
3070 unsigned int index = 0;
3071 OMX_U8 *temp_buff ;
3072
3073 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
3074 DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]",
3075 bufferHdr, m_inp_mem_ptr);
3076 return OMX_ErrorBadParameter;
3077 }
3078
3079 print_omx_buffer("free_input_buffer", bufferHdr);
3080
3081 index = bufferHdr - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
3082 #ifdef _ANDROID_ICS_
3083 if (meta_mode_enable) {
3084 if (index < m_sInPortDef.nBufferCountActual) {
3085 memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
3086 memset(&meta_buffers[index], 0, sizeof(meta_buffers[index]));
3087 }
3088 if (!mUseProxyColorFormat)
3089 return OMX_ErrorNone;
3090 else {
3091 opaque_buffer_hdr[index] = NULL;
3092 }
3093 }
3094 #endif
3095 if (index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat &&
3096 dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) {
3097 DEBUG_PRINT_LOW("ERROR: dev_free_buf() Failed for i/p buf");
3098 }
3099
3100 if (index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) {
3101
3102 if (mUseProxyColorFormat) {
3103 if (m_opq_pmem_q.m_size) {
3104 unsigned long addr, p1, id;
3105 m_opq_pmem_q.pop_entry(&addr, &p1, &id);
3106 DEBUG_PRINT_LOW("Removed entry in m_opq_pmem_q: address %lu", addr);
3107 }
3108 }
3109
3110 if (m_pInput_pmem[index].fd > 0 && input_use_buffer == false) {
3111 DEBUG_PRINT_LOW("FreeBuffer:: i/p AllocateBuffer case");
3112 if(!secure_session) {
3113 ion_unmap(m_pInput_ion[index].data_fd,
3114 m_pInput_pmem[index].buffer,
3115 m_pInput_pmem[index].size);
3116 } else {
3117 free(m_pInput_pmem[index].buffer);
3118 }
3119 m_pInput_pmem[index].buffer = NULL;
3120 #ifdef USE_ION
3121 free_ion_memory(&m_pInput_ion[index]);
3122 #endif
3123 m_pInput_pmem[index].fd = -1;
3124 } else if (m_pInput_pmem[index].fd > 0 && (input_use_buffer == true &&
3125 m_use_input_pmem == OMX_FALSE)) {
3126 DEBUG_PRINT_LOW("FreeBuffer:: i/p Heap UseBuffer case");
3127 if (dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) {
3128 DEBUG_PRINT_ERROR("ERROR: dev_free_buf() Failed for i/p buf");
3129 }
3130 if(!secure_session) {
3131 ion_unmap(m_pInput_ion[index].data_fd,
3132 m_pInput_pmem[index].buffer,
3133 m_pInput_pmem[index].size);
3134 m_pInput_pmem[index].buffer = NULL;
3135 }
3136 #ifdef USE_ION
3137 free_ion_memory(&m_pInput_ion[index]);
3138 #endif
3139 m_pInput_pmem[index].fd = -1;
3140 } else {
3141 DEBUG_PRINT_ERROR("FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case");
3142 }
3143 }
3144 return OMX_ErrorNone;
3145 }
3146
free_output_buffer(OMX_BUFFERHEADERTYPE * bufferHdr)3147 OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
3148 {
3149 unsigned int index = 0;
3150 OMX_U8 *temp_buff ;
3151
3152 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
3153 DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]",
3154 bufferHdr, m_out_mem_ptr);
3155 return OMX_ErrorBadParameter;
3156 }
3157 index = bufferHdr - m_out_mem_ptr;
3158
3159 print_omx_buffer("free_output_buffer", bufferHdr);
3160
3161 if (index < m_sOutPortDef.nBufferCountActual &&
3162 dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) {
3163 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
3164 }
3165
3166 if (index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) {
3167 if (m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) {
3168 DEBUG_PRINT_LOW("FreeBuffer:: o/p AllocateBuffer case");
3169 if(!secure_session) {
3170 ion_unmap(m_pOutput_pmem[index].fd,
3171 m_pOutput_pmem[index].buffer,
3172 m_pOutput_pmem[index].size);
3173 } else if (m_pOutput_pmem[index].buffer) {
3174 native_handle_t *handle;
3175 if (allocate_native_handle) {
3176 handle = (native_handle_t *)m_pOutput_pmem[index].buffer;
3177 } else {
3178 handle = ((output_metabuffer *)m_pOutput_pmem[index].buffer)->nh;
3179 free(m_pOutput_pmem[index].buffer);
3180 }
3181 native_handle_close(handle);
3182 native_handle_delete(handle);
3183 }
3184 #ifdef USE_ION
3185 free_ion_memory(&m_pOutput_ion[index]);
3186 #endif
3187
3188 m_pOutput_pmem[index].buffer = NULL;
3189 m_pOutput_pmem[index].fd = -1;
3190 } else if ( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true
3191 && m_use_output_pmem == OMX_FALSE)) {
3192 DEBUG_PRINT_LOW("FreeBuffer:: o/p Heap UseBuffer case");
3193 if (dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) {
3194 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
3195 }
3196 if(!secure_session) {
3197 ion_unmap(m_pOutput_pmem[index].fd,
3198 m_pOutput_pmem[index].buffer,
3199 m_pOutput_pmem[index].size);
3200 }
3201 #ifdef USE_ION
3202 free_ion_memory(&m_pOutput_ion[index]);
3203 #endif
3204 m_pOutput_pmem[index].fd = -1;
3205 } else {
3206 DEBUG_PRINT_LOW("FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case");
3207 }
3208 }
3209 return OMX_ErrorNone;
3210 }
3211 #ifdef _ANDROID_ICS_
allocate_input_meta_buffer(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_PTR appData,OMX_U32 bytes)3212 OMX_ERRORTYPE omx_video::allocate_input_meta_buffer(
3213 OMX_HANDLETYPE hComp,
3214 OMX_BUFFERHEADERTYPE **bufferHdr,
3215 OMX_PTR appData,
3216 OMX_U32 bytes)
3217 {
3218 unsigned index = 0;
3219 // In meta-mode alloc-length is not known conclusively
3220 // Allow allocation for atleast gralloc metadata handles
3221 // and check for size in ETB
3222 if (!bufferHdr || bytes < sizeof(VideoGrallocMetadata)) {
3223 DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %u",
3224 bufferHdr, (unsigned int)bytes);
3225 return OMX_ErrorBadParameter;
3226 }
3227
3228 if (!m_inp_mem_ptr && !mUseProxyColorFormat) {
3229 m_inp_mem_ptr = meta_buffer_hdr;
3230 DEBUG_PRINT_LOW("use meta_buffer_hdr (%p) as m_inp_mem_ptr = %p",
3231 meta_buffer_hdr, m_inp_mem_ptr);
3232 }
3233 for (index = 0; ((index < m_sInPortDef.nBufferCountActual) &&
3234 meta_buffer_hdr[index].pBuffer &&
3235 BITMASK_PRESENT(&m_inp_bm_count, index)); index++);
3236
3237 if (index == m_sInPortDef.nBufferCountActual) {
3238 DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer");
3239 return OMX_ErrorBadParameter;
3240 }
3241 if (mUseProxyColorFormat) {
3242 if (opaque_buffer_hdr[index]) {
3243 DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
3244 return OMX_ErrorBadParameter;
3245 }
3246 if (allocate_input_buffer(hComp,&opaque_buffer_hdr[index],
3247 PORT_INDEX_IN,appData,m_sInPortDef.nBufferSize) != OMX_ErrorNone) {
3248 DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
3249 return OMX_ErrorBadParameter;
3250 }
3251 }
3252 BITMASK_SET(&m_inp_bm_count,index);
3253 *bufferHdr = &meta_buffer_hdr[index];
3254 memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
3255 meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]);
3256 meta_buffer_hdr[index].nAllocLen = bytes;
3257 meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION;
3258 meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN;
3259 meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index];
3260 meta_buffer_hdr[index].pAppPrivate = appData;
3261 if (mUseProxyColorFormat) {
3262 m_opq_pmem_q.insert_entry((unsigned long)opaque_buffer_hdr[index],0,0);
3263 DEBUG_PRINT_HIGH("opaque_buffer_hdr insert %p", opaque_buffer_hdr[index]);
3264 }
3265 return OMX_ErrorNone;
3266 }
3267 #endif
3268 /* ======================================================================
3269 FUNCTION
3270 omx_venc::AllocateInputBuffer
3271
3272 DESCRIPTION
3273 Helper function for allocate buffer in the input pin
3274
3275 PARAMETERS
3276 None.
3277
3278 RETURN VALUE
3279 true/false
3280
3281 ========================================================================== */
allocate_input_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes)3282 OMX_ERRORTYPE omx_video::allocate_input_buffer(
3283 OMX_IN OMX_HANDLETYPE hComp,
3284 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3285 OMX_IN OMX_U32 port,
3286 OMX_IN OMX_PTR appData,
3287 OMX_IN OMX_U32 bytes)
3288 {
3289 (void)hComp, (void)port;
3290 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3291 unsigned i = 0;
3292
3293 DEBUG_PRINT_HIGH("allocate_input_buffer()::");
3294 if (bytes < m_sInPortDef.nBufferSize) {
3295 DEBUG_PRINT_ERROR("ERROR: Buffer size mismatch error: bytes[%u] < nBufferSize[%u]",
3296 (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize);
3297 return OMX_ErrorBadParameter;
3298 }
3299
3300 if (!m_inp_mem_ptr) {
3301 DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__,
3302 (unsigned int)m_sInPortDef.nBufferSize, (unsigned int)m_sInPortDef.nBufferCountActual);
3303 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
3304 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
3305 if (m_inp_mem_ptr == NULL) {
3306 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr");
3307 return OMX_ErrorInsufficientResources;
3308 }
3309
3310 DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);
3311 m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
3312
3313 if (m_pInput_pmem == NULL) {
3314 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_pmem");
3315 return OMX_ErrorInsufficientResources;
3316 }
3317 #ifdef USE_ION
3318 m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
3319 if (m_pInput_ion == NULL) {
3320 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_ion");
3321 return OMX_ErrorInsufficientResources;
3322 }
3323 #endif
3324 for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
3325 m_pInput_pmem[i].fd = -1;
3326 #ifdef USE_ION
3327 m_pInput_ion[i].data_fd = -1;
3328 m_pInput_ion[i].dev_fd = -1;
3329 #endif
3330 }
3331 }
3332
3333 for (i=0; i< m_sInPortDef.nBufferCountActual; i++) {
3334 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
3335 break;
3336 }
3337 }
3338 if (i < m_sInPortDef.nBufferCountActual) {
3339
3340 *bufferHdr = (m_inp_mem_ptr + i);
3341 (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3342 (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
3343 (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize;
3344 (*bufferHdr)->pAppPrivate = appData;
3345 (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN;
3346 // make fd available to app layer, help with testing
3347 (*bufferHdr)->pInputPortPrivate = (OMX_PTR)&m_pInput_pmem[i];
3348
3349 #ifdef USE_ION
3350 // No use case where caching encoder makes sense
3351 bool status = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
3352 &m_pInput_ion[i],
3353 secure_session ? SECURE_FLAGS_INPUT_BUFFER : 0);
3354 if (status == false) {
3355 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
3356 return OMX_ErrorInsufficientResources;
3357 }
3358 m_pInput_pmem[i].fd = m_pInput_ion[i].data_fd;
3359 #endif
3360 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
3361 m_pInput_pmem[i].offset = 0;
3362
3363 m_pInput_pmem[i].buffer = NULL;
3364 if(!secure_session) {
3365 m_pInput_pmem[i].buffer = (unsigned char *)ion_map(m_pInput_pmem[i].fd,
3366 m_pInput_pmem[i].size);
3367 if (m_pInput_pmem[i].buffer == MAP_FAILED) {
3368 DEBUG_PRINT_ERROR("ERROR: mmap FAILED= %d", errno);
3369 m_pInput_pmem[i].buffer = NULL;
3370 #ifdef USE_ION
3371 free_ion_memory(&m_pInput_ion[i]);
3372 #endif
3373 return OMX_ErrorInsufficientResources;
3374 }
3375 } else {
3376 //This should only be used for passing reference to source type and
3377 //secure handle fd struct native_handle_t*
3378 m_pInput_pmem[i].buffer = malloc(sizeof(OMX_U32) + sizeof(native_handle_t*));
3379 if (m_pInput_pmem[i].buffer == NULL) {
3380 DEBUG_PRINT_ERROR("%s: failed to allocate native-handle", __func__);
3381 return OMX_ErrorInsufficientResources;
3382 }
3383 (*bufferHdr)->nAllocLen = sizeof(OMX_U32) + sizeof(native_handle_t*);
3384 }
3385
3386 (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer;
3387 DEBUG_PRINT_LOW("Virtual address in allocate buffer is %p", m_pInput_pmem[i].buffer);
3388 BITMASK_SET(&m_inp_bm_count,i);
3389 //here change the I/P param here from buf_adr to pmem
3390 if (!mUseProxyColorFormat && (dev_use_buf(PORT_INDEX_IN) != true)) {
3391 DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for i/p buf");
3392 return OMX_ErrorInsufficientResources;
3393 }
3394 } else {
3395 DEBUG_PRINT_ERROR("ERROR: All i/p buffers are allocated, invalid allocate buf call"
3396 "for index [%d]", i);
3397 eRet = OMX_ErrorInsufficientResources;
3398 }
3399
3400 return eRet;
3401 }
3402
3403
3404 /* ======================================================================
3405 FUNCTION
3406 omx_venc::AllocateOutputBuffer
3407
3408 DESCRIPTION
3409 Helper fn for AllocateBuffer in the output pin
3410
3411 PARAMETERS
3412 <TBD>.
3413
3414 RETURN VALUE
3415 OMX Error None if everything went well.
3416
3417 ========================================================================== */
allocate_output_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes)3418 OMX_ERRORTYPE omx_video::allocate_output_buffer(
3419 OMX_IN OMX_HANDLETYPE hComp,
3420 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3421 OMX_IN OMX_U32 port,
3422 OMX_IN OMX_PTR appData,
3423 OMX_IN OMX_U32 bytes)
3424 {
3425 (void)hComp, (void)port;
3426 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3427 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
3428 unsigned i= 0; // Temporary counter
3429 int align_size;
3430
3431 DEBUG_PRINT_HIGH("allocate_output_buffer()for %u bytes", (unsigned int)bytes);
3432 if (!m_out_mem_ptr) {
3433 int nBufHdrSize = 0;
3434 DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__,
3435 (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)m_sOutPortDef.nBufferCountActual);
3436 nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
3437
3438 /*
3439 * Memory for output side involves the following:
3440 * 1. Array of Buffer Headers
3441 * 2. Bitmask array to hold the buffer allocation details
3442 * In order to minimize the memory management entire allocation
3443 * is done in one step.
3444 */
3445 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
3446
3447 #ifdef USE_ION
3448 m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
3449 if (m_pOutput_ion == NULL) {
3450 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_ion");
3451 return OMX_ErrorInsufficientResources;
3452 }
3453 #endif
3454 m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual);
3455 if (m_pOutput_pmem == NULL) {
3456 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_pmem");
3457 return OMX_ErrorInsufficientResources;
3458 }
3459 if (m_out_mem_ptr && m_pOutput_pmem) {
3460 bufHdr = m_out_mem_ptr;
3461
3462 for (i=0; i < m_sOutPortDef.nBufferCountActual ; i++) {
3463 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3464 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
3465 // Set the values when we determine the right HxW param
3466 bufHdr->nAllocLen = bytes;
3467 bufHdr->nFilledLen = 0;
3468 bufHdr->pAppPrivate = appData;
3469 bufHdr->nOutputPortIndex = PORT_INDEX_OUT;
3470 // make fd available to app layer, help with testing
3471 bufHdr->pOutputPortPrivate = (OMX_PTR)&m_pOutput_pmem[i];
3472 bufHdr->pBuffer = NULL;
3473 bufHdr++;
3474 m_pOutput_pmem[i].fd = -1;
3475 #ifdef USE_ION
3476 m_pOutput_ion[i].data_fd = -1;
3477 m_pOutput_ion[i].dev_fd = -1;
3478 #endif
3479 }
3480 } else {
3481 DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem");
3482 eRet = OMX_ErrorInsufficientResources;
3483 }
3484 }
3485
3486 DEBUG_PRINT_HIGH("actual cnt = %u", (unsigned int)m_sOutPortDef.nBufferCountActual);
3487 for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) {
3488 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
3489 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
3490 break;
3491 }
3492 }
3493 if (eRet == OMX_ErrorNone) {
3494 if (i < m_sOutPortDef.nBufferCountActual) {
3495 #ifdef USE_ION
3496 align_size = ALIGN(m_sOutPortDef.nBufferSize, 4096);
3497 // Output buffers are cached so that muxer writing is faster
3498 bool status = alloc_map_ion_memory(align_size,
3499 &m_pOutput_ion[i],
3500 secure_session ? SECURE_FLAGS_OUTPUT_BUFFER : ION_FLAG_CACHED);
3501 if (status == false) {
3502 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed");
3503 return OMX_ErrorInsufficientResources;
3504 }
3505
3506 m_pOutput_pmem[i].fd = m_pOutput_ion[i].data_fd;
3507 #endif
3508 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
3509 m_pOutput_pmem[i].offset = 0;
3510
3511 m_pOutput_pmem[i].buffer = NULL;
3512 *bufferHdr = (m_out_mem_ptr + i );
3513
3514 if(!secure_session) {
3515 m_pOutput_pmem[i].buffer = (unsigned char *)ion_map(m_pOutput_pmem[i].fd,
3516 align_size);
3517 if (m_pOutput_pmem[i].buffer == MAP_FAILED) {
3518 DEBUG_PRINT_ERROR("ERROR: MMAP_FAILED in o/p alloc buffer");
3519 m_pOutput_pmem[i].buffer = NULL;
3520 #ifdef USE_ION
3521 free_ion_memory(&m_pOutput_ion[i]);
3522 #endif
3523 return OMX_ErrorInsufficientResources;
3524 }
3525 }
3526 else {
3527 //This should only be used for passing reference to source type and
3528 //secure handle fd struct native_handle_t*
3529 if (allocate_native_handle) {
3530 native_handle_t *nh = native_handle_create(1 /*numFds*/, 3 /*numInts*/);
3531 if (!nh) {
3532 DEBUG_PRINT_ERROR("Native handle create failed");
3533 return OMX_ErrorInsufficientResources;
3534 }
3535 nh->data[0] = m_pOutput_pmem[i].fd;
3536 nh->data[1] = 0;
3537 nh->data[2] = 0;
3538 nh->data[3] = ALIGN(m_sOutPortDef.nBufferSize, 4096);
3539 m_pOutput_pmem[i].buffer = (OMX_U8 *)nh;
3540 } else {
3541 native_handle_t *handle = native_handle_create(1, 3); //fd, offset, size, alloc length
3542 if (!handle) {
3543 DEBUG_PRINT_ERROR("ERROR: native handle creation failed");
3544 return OMX_ErrorInsufficientResources;
3545 }
3546 m_pOutput_pmem[i].buffer = malloc(sizeof(output_metabuffer));
3547 if (m_pOutput_pmem[i].buffer == NULL) {
3548 DEBUG_PRINT_ERROR("%s: Failed to allocate meta buffer", __func__);
3549 return OMX_ErrorInsufficientResources;
3550 }
3551 (*bufferHdr)->nAllocLen = sizeof(output_metabuffer);
3552 handle->data[0] = m_pOutput_pmem[i].fd;
3553 handle->data[1] = 0;
3554 handle->data[2] = 0;
3555 handle->data[3] = ALIGN(m_sOutPortDef.nBufferSize, 4096);
3556 output_metabuffer *buffer = (output_metabuffer*) m_pOutput_pmem[i].buffer;
3557 buffer->type = 1;
3558 buffer->nh = handle;
3559 }
3560 }
3561
3562 (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
3563 (*bufferHdr)->pAppPrivate = appData;
3564
3565 BITMASK_SET(&m_out_bm_count,i);
3566
3567 if (dev_use_buf(PORT_INDEX_OUT) != true) {
3568 DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for o/p buf");
3569 return OMX_ErrorInsufficientResources;
3570 }
3571 } else {
3572 DEBUG_PRINT_ERROR("ERROR: All o/p buffers are allocated, invalid allocate buf call"
3573 "for index [%d] actual: %u", i, (unsigned int)m_sOutPortDef.nBufferCountActual);
3574 }
3575 }
3576
3577 return eRet;
3578 }
3579
3580
3581 // AllocateBuffer -- API Call
3582 /* ======================================================================
3583 FUNCTION
3584 omx_video::AllocateBuffer
3585
3586 DESCRIPTION
3587 Returns zero if all the buffers released..
3588
3589 PARAMETERS
3590 None.
3591
3592 RETURN VALUE
3593 true/false
3594
3595 ========================================================================== */
allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes)3596 OMX_ERRORTYPE omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
3597 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3598 OMX_IN OMX_U32 port,
3599 OMX_IN OMX_PTR appData,
3600 OMX_IN OMX_U32 bytes)
3601 {
3602
3603 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
3604
3605 DEBUG_PRINT_LOW("Allocate buffer of size = %u on port %d", (unsigned int)bytes, (int)port);
3606 if (m_state == OMX_StateInvalid) {
3607 DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State");
3608 return OMX_ErrorInvalidState;
3609 }
3610 auto_lock l(m_buf_lock);
3611 // What if the client calls again.
3612 if (port == PORT_INDEX_IN) {
3613 #ifdef _ANDROID_ICS_
3614 if (meta_mode_enable)
3615 eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes);
3616 else
3617 #endif
3618 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
3619 } else if (port == PORT_INDEX_OUT) {
3620 eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
3621 } else {
3622 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port);
3623 eRet = OMX_ErrorBadPortIndex;
3624 }
3625 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
3626 if (eRet == OMX_ErrorNone) {
3627 if (allocate_done()) {
3628 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3629 // Send the callback now
3630 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
3631 post_event(OMX_CommandStateSet,OMX_StateIdle,
3632 OMX_COMPONENT_GENERATE_EVENT);
3633 }
3634 }
3635 if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) {
3636 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
3637 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
3638 post_event(OMX_CommandPortEnable,
3639 PORT_INDEX_IN,
3640 OMX_COMPONENT_GENERATE_EVENT);
3641 }
3642 }
3643 if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) {
3644 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
3645 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
3646 post_event(OMX_CommandPortEnable,
3647 PORT_INDEX_OUT,
3648 OMX_COMPONENT_GENERATE_EVENT);
3649 m_event_port_settings_sent = false;
3650 }
3651 }
3652 }
3653 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
3654 return eRet;
3655 }
3656
3657
3658 // Free Buffer - API call
3659 /* ======================================================================
3660 FUNCTION
3661 omx_video::FreeBuffer
3662
3663 DESCRIPTION
3664
3665 PARAMETERS
3666 None.
3667
3668 RETURN VALUE
3669 true/false
3670
3671 ========================================================================== */
free_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3672 OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
3673 OMX_IN OMX_U32 port,
3674 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3675 {
3676 (void)hComp;
3677 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3678 unsigned int nPortIndex;
3679
3680 DEBUG_PRINT_LOW("In for encoder free_buffer");
3681 auto_lock l(m_buf_lock);
3682 if (port == PORT_INDEX_OUT) { //client called freebuffer, clearing client buffer bitmask right away to avoid use after free
3683 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
3684 if(BITMASK_PRESENT(&m_client_out_bm_count, nPortIndex))
3685 BITMASK_CLEAR(&m_client_out_bm_count,nPortIndex);
3686 } else if (port == PORT_INDEX_IN) {
3687 nPortIndex = buffer - (meta_mode_enable?meta_buffer_hdr:m_inp_mem_ptr);
3688 if(BITMASK_PRESENT(&m_client_in_bm_count, nPortIndex))
3689 BITMASK_CLEAR(&m_client_in_bm_count,nPortIndex);
3690 }
3691 if (m_state == OMX_StateIdle &&
3692 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
3693 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
3694 } else if ((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)||
3695 (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) {
3696 DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
3697 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
3698 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled");
3699 m_buffer_freed = true;
3700 post_event(OMX_EventError,
3701 OMX_ErrorPortUnpopulated,
3702 OMX_COMPONENT_GENERATE_EVENT);
3703 return eRet;
3704 } else {
3705 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers");
3706 m_buffer_freed = true;
3707 post_event(OMX_EventError,
3708 OMX_ErrorPortUnpopulated,
3709 OMX_COMPONENT_GENERATE_EVENT);
3710 }
3711
3712 if (port == PORT_INDEX_IN) {
3713 // check if the buffer is valid
3714 nPortIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
3715
3716 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %u, actual cnt %u",
3717 nPortIndex, (unsigned int)m_sInPortDef.nBufferCountActual);
3718 if (nPortIndex < m_sInPortDef.nBufferCountActual &&
3719 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
3720 // Clear the bit associated with it.
3721 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
3722 free_input_buffer (buffer);
3723 m_sInPortDef.bPopulated = OMX_FALSE;
3724
3725 /*Free the Buffer Header*/
3726 if (release_input_done()) {
3727 input_use_buffer = false;
3728 // "m_inp_mem_ptr" may point to "meta_buffer_hdr" in some modes,
3729 // in which case, it was not explicitly allocated
3730 if (m_inp_mem_ptr && m_inp_mem_ptr != meta_buffer_hdr) {
3731 DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr");
3732 free (m_inp_mem_ptr);
3733 }
3734 m_inp_mem_ptr = NULL;
3735 if (m_pInput_pmem) {
3736 DEBUG_PRINT_LOW("Freeing m_pInput_pmem");
3737 free(m_pInput_pmem);
3738 m_pInput_pmem = NULL;
3739 }
3740 #ifdef USE_ION
3741 if (m_pInput_ion) {
3742 DEBUG_PRINT_LOW("Freeing m_pInput_ion");
3743 free(m_pInput_ion);
3744 m_pInput_ion = NULL;
3745 }
3746 #endif
3747 }
3748 } else {
3749 DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid");
3750 eRet = OMX_ErrorBadPortIndex;
3751 }
3752
3753 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
3754 && release_input_done()) {
3755 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
3756 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
3757 post_event(OMX_CommandPortDisable,
3758 PORT_INDEX_IN,
3759 OMX_COMPONENT_GENERATE_EVENT);
3760 }
3761 } else if (port == PORT_INDEX_OUT) {
3762 // check if the buffer is valid
3763 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
3764
3765 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %u, actual cnt %u",
3766 nPortIndex, (unsigned int)m_sOutPortDef.nBufferCountActual);
3767 if (nPortIndex < m_sOutPortDef.nBufferCountActual &&
3768 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
3769 // Clear the bit associated with it.
3770 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
3771 m_sOutPortDef.bPopulated = OMX_FALSE;
3772 free_output_buffer (buffer);
3773
3774 if (release_output_done()) {
3775 output_use_buffer = false;
3776 if (m_out_mem_ptr) {
3777 DEBUG_PRINT_LOW("Freeing m_out_mem_ptr");
3778 free (m_out_mem_ptr);
3779 m_out_mem_ptr = NULL;
3780 }
3781 if (m_pOutput_pmem) {
3782 DEBUG_PRINT_LOW("Freeing m_pOutput_pmem");
3783 free(m_pOutput_pmem);
3784 m_pOutput_pmem = NULL;
3785 }
3786 #ifdef USE_ION
3787 if (m_pOutput_ion) {
3788 DEBUG_PRINT_LOW("Freeing m_pOutput_ion");
3789 free(m_pOutput_ion);
3790 m_pOutput_ion = NULL;
3791 }
3792 #endif
3793 }
3794 } else {
3795 DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid");
3796 eRet = OMX_ErrorBadPortIndex;
3797 }
3798 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
3799 && release_output_done() ) {
3800 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
3801
3802 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
3803 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
3804 post_event(OMX_CommandPortDisable,
3805 PORT_INDEX_OUT,
3806 OMX_COMPONENT_GENERATE_EVENT);
3807
3808 }
3809 } else if (port == PORT_INDEX_EXTRADATA_OUT) {
3810 nPortIndex = buffer - m_client_output_extradata_mem_ptr;
3811 DEBUG_PRINT_LOW("free_buffer on extradata output port - Port idx %d", nPortIndex);
3812
3813 BITMASK_CLEAR(&m_out_extradata_bm_count,nPortIndex);
3814
3815 if (release_output_extradata_done()) {
3816 free_output_extradata_buffer_header();
3817 }
3818 } else if (port == PORT_INDEX_EXTRADATA_IN) {
3819 nPortIndex = buffer - m_client_input_extradata_mem_ptr;
3820 DEBUG_PRINT_LOW("free_buffer on extradata input port - Port idx %d", nPortIndex);
3821
3822 BITMASK_CLEAR(&m_in_extradata_bm_count,nPortIndex);
3823
3824 if (release_input_extradata_done()) {
3825 free_input_extradata_buffer_header();
3826 }
3827 } else {
3828 eRet = OMX_ErrorBadPortIndex;
3829 }
3830 if ((eRet == OMX_ErrorNone) &&
3831 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
3832 if (release_done()) {
3833 if (dev_stop() != 0) {
3834 DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED");
3835 eRet = OMX_ErrorHardware;
3836 }
3837 // Send the callback now
3838 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
3839 post_event(OMX_CommandStateSet, OMX_StateLoaded,
3840 OMX_COMPONENT_GENERATE_EVENT);
3841 } else {
3842 DEBUG_PRINT_HIGH("in free buffer, release not done, need to free more buffers output %" PRIx64" input %" PRIx64,
3843 m_out_bm_count, m_inp_bm_count);
3844 }
3845 }
3846 if (eRet != OMX_ErrorNone) {
3847 m_buffer_freed = true;
3848 }
3849
3850 return eRet;
3851 }
3852
free_output_extradata_buffer_header()3853 void omx_video::free_output_extradata_buffer_header() {
3854 m_sExtraData = false;
3855 if (m_client_output_extradata_mem_ptr) {
3856 DEBUG_PRINT_LOW("Free extradata pmem Pointer area");
3857 free(m_client_output_extradata_mem_ptr);
3858 m_client_output_extradata_mem_ptr = NULL;
3859 }
3860 }
3861
free_input_extradata_buffer_header()3862 void omx_video::free_input_extradata_buffer_header() {
3863 m_sExtraData = false;
3864 if (m_client_input_extradata_mem_ptr) {
3865 DEBUG_PRINT_LOW("Free extradata pmem Pointer area");
3866 free(m_client_input_extradata_mem_ptr);
3867 m_client_input_extradata_mem_ptr = NULL;
3868 }
3869 }
3870
3871 /* ======================================================================
3872 FUNCTION
3873 omx_video::EmptyThisBuffer
3874
3875 DESCRIPTION
3876 This routine is used to push the encoded video frames to
3877 the video decoder.
3878
3879 PARAMETERS
3880 None.
3881
3882 RETURN VALUE
3883 OMX Error None if everything went successful.
3884
3885 ========================================================================== */
empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3886 OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
3887 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3888 {
3889 if(buffer != NULL && buffer->nInputPortIndex == PORT_INDEX_EXTRADATA_IN) {
3890 if(!dev_handle_client_input_extradata(buffer)) {
3891 DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> handling client extradata failed");
3892 return OMX_ErrorMax;
3893 }
3894 return OMX_ErrorNone;
3895 }
3896 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
3897 unsigned int nBufferIndex ;
3898
3899 if (m_state != OMX_StateExecuting &&
3900 m_state != OMX_StatePause &&
3901 m_state != OMX_StateIdle) {
3902 DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State");
3903 return OMX_ErrorInvalidState;
3904 }
3905
3906 if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
3907 DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> buffer is null or buffer size is invalid");
3908 return OMX_ErrorBadParameter;
3909 }
3910
3911 if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
3912 DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> OMX Version Invalid");
3913 return OMX_ErrorVersionMismatch;
3914 }
3915
3916 print_omx_buffer("EmptyThisBuffer", buffer);
3917 if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) {
3918 DEBUG_PRINT_ERROR("ERROR: Bad port index to call empty_this_buffer");
3919 return OMX_ErrorBadPortIndex;
3920 }
3921 if (!m_sInPortDef.bEnabled) {
3922 DEBUG_PRINT_ERROR("ERROR: Cannot call empty_this_buffer while I/P port is disabled");
3923 return OMX_ErrorIncorrectStateOperation;
3924 }
3925
3926 nBufferIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
3927
3928 if (nBufferIndex > m_sInPortDef.nBufferCountActual ) {
3929 DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]", nBufferIndex);
3930 return OMX_ErrorBadParameter;
3931 }
3932
3933 m_etb_count++;
3934 m_etb_timestamp = buffer->nTimeStamp;
3935 post_event ((unsigned long)hComp,(unsigned long)buffer,m_input_msg_id);
3936 return OMX_ErrorNone;
3937 }
3938
profile_etb()3939 bool omx_video::profile_etb() {
3940 if (profile_mode) {
3941 struct timeval act_time = {0, 0};
3942 gettimeofday(&act_time, NULL);
3943 if (profile_start_time == 0) {
3944 profile_start_time = (act_time.tv_usec + act_time.tv_sec * 1e6);
3945 } else {
3946 profile_last_time = (act_time.tv_usec + act_time.tv_sec * 1e6);
3947 }
3948 profile_frame_count++;
3949 return true;
3950 }
3951 return false;
3952 }
3953
3954 /* ======================================================================
3955 FUNCTION
3956 omx_video::empty_this_buffer_proxy
3957
3958 DESCRIPTION
3959 This routine is used to push the encoded video frames to
3960 the video decoder.
3961
3962 PARAMETERS
3963 None.
3964
3965 RETURN VALUE
3966 OMX Error None if everything went successful.
3967
3968 ========================================================================== */
empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3969 OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
3970 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3971 {
3972 VIDC_TRACE_NAME_HIGH("ETB");
3973 (void)hComp;
3974 OMX_U8 *pmem_data_buf = NULL;
3975 int push_cnt = 0;
3976 unsigned nBufIndex = 0;
3977 OMX_ERRORTYPE ret = OMX_ErrorNone;
3978 LEGACY_CAM_METADATA_TYPE *media_buffer = NULL;
3979
3980 int fd = 0;
3981
3982 DEBUG_PRINT_LOW("ETBProxy: buffer->pBuffer[%p]", buffer->pBuffer);
3983 if (buffer == NULL) {
3984 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid buffer[%p]", buffer);
3985 return OMX_ErrorBadParameter;
3986 }
3987
3988 if (profile_etb()) {
3989 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
3990 return OMX_ErrorNone;
3991 }
3992
3993 // Buffer sanity checks
3994 if (meta_mode_enable && !mUsesColorConversion) {
3995 //For color-conversion case, we have an internal buffer and not a meta buffer
3996 bool met_error = false;
3997 nBufIndex = buffer - meta_buffer_hdr;
3998 if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
3999 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid meta-bufIndex = %u", nBufIndex);
4000 return OMX_ErrorBadParameter;
4001 }
4002 media_buffer = (LEGACY_CAM_METADATA_TYPE *)meta_buffer_hdr[nBufIndex].pBuffer;
4003 if (!media_buffer) {
4004 DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
4005 return OMX_ErrorBadParameter;
4006 }
4007 if ((media_buffer->buffer_type == LEGACY_CAM_SOURCE)
4008 && buffer->nAllocLen != sizeof(LEGACY_CAM_METADATA_TYPE)) {
4009 DEBUG_PRINT_ERROR("Invalid metadata size expected(%u) v/s recieved(%zu)",
4010 buffer->nAllocLen, sizeof(LEGACY_CAM_METADATA_TYPE));
4011 met_error = true;
4012 } else if (media_buffer) {
4013 if (media_buffer->buffer_type != LEGACY_CAM_SOURCE &&
4014 media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) {
4015 DEBUG_PRINT_ERROR("Buffer type is neither LEGACY_CAM_SOURCE nor gralloc source");
4016 met_error = true;
4017 } else {
4018 if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
4019 if (media_buffer->meta_handle == NULL) {
4020 DEBUG_PRINT_ERROR("Buffer type is LEGACY_CAM_SOURCE but handle is null");
4021 met_error = true;
4022 }
4023 else {
4024 // TBD: revisit this check !
4025 int nFds = media_buffer->meta_handle->numFds,
4026 nInt = media_buffer->meta_handle->numInts;
4027 met_error = ((nFds == 1 && nInt >= 2) /*normal*/ ||
4028 (nFds < 16 && nInt >= nFds*3) /*batch*/) ? false : true;
4029 if (met_error) {
4030 DEBUG_PRINT_ERROR("Unbalanced fds in handle: fds=%d ints=%d",
4031 nFds, nInt);
4032 }
4033 }
4034 }
4035 }
4036 } else {
4037 met_error = true;
4038 DEBUG_PRINT_ERROR("Unrecognized camera source type");
4039 }
4040 if (met_error) {
4041 DEBUG_PRINT_ERROR("ERROR: Unkown source/metahandle in ETB call");
4042 post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
4043 return OMX_ErrorBadParameter;
4044 }
4045 } else {
4046 nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
4047 if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
4048 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid bufIndex = %u", nBufIndex);
4049 return OMX_ErrorBadParameter;
4050 }
4051 }
4052
4053 if (buffer->nFilledLen == 0 && (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
4054 DEBUG_PRINT_LOW("Zero length EOS buffer");
4055 handle_empty_eos_buffer();
4056 post_event ((unsigned long)buffer,0,
4057 OMX_COMPONENT_GENERATE_EBD);
4058 return OMX_ErrorNone;
4059 }
4060
4061 pending_input_buffers++;
4062 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
4063 if (input_flush_progress == true) {
4064 post_event ((unsigned long)buffer,0,
4065 OMX_COMPONENT_GENERATE_EBD);
4066 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Input flush in progress");
4067 return OMX_ErrorNone;
4068 }
4069
4070 if (is_stop_in_progress == true) {
4071 post_event ((unsigned long)buffer,0,
4072 OMX_COMPONENT_GENERATE_EBD);
4073 DEBUG_PRINT_ERROR("ERROR: ETBProxy: stop in progress");
4074 return OMX_ErrorNone;
4075 }
4076
4077 if (!meta_mode_enable) {
4078 fd = m_pInput_pmem[nBufIndex].fd;
4079 }
4080 #ifdef _ANDROID_ICS_
4081 if (meta_mode_enable && !mUsesColorConversion) {
4082 // Camera or Gralloc-source meta-buffers queued with encodeable color-format
4083 struct pmem Input_pmem_info;
4084 if (!media_buffer) {
4085 DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
4086 return OMX_ErrorBadParameter;
4087 }
4088 if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
4089 Input_pmem_info.buffer = media_buffer;
4090 Input_pmem_info.fd = MetaBufferUtil::getFdAt(media_buffer->meta_handle, 0);
4091 fd = Input_pmem_info.fd;
4092
4093 int offset = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
4094 int size = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_SIZE);
4095 if (offset < 0 || size < 0) {
4096 DEBUG_PRINT_ERROR("meta-buffer is invalid!");
4097 return OMX_ErrorBadParameter;
4098 }
4099 Input_pmem_info.offset = offset;
4100 Input_pmem_info.size = size;
4101 DEBUG_PRINT_HIGH("ETB (meta-Camera) fd = %d, offset = %d, size = %d",
4102 Input_pmem_info.fd, Input_pmem_info.offset,
4103 Input_pmem_info.size);
4104 } else {
4105 VideoGrallocMetadata *media_buffer = (VideoGrallocMetadata *)meta_buffer_hdr[nBufIndex].pBuffer;
4106 private_handle_t *handle = (private_handle_t *)media_buffer->pHandle;
4107 Input_pmem_info.buffer = media_buffer;
4108 Input_pmem_info.fd = handle->fd;
4109 fd = Input_pmem_info.fd;
4110 Input_pmem_info.offset = 0;
4111 Input_pmem_info.size = handle->size;
4112 DEBUG_PRINT_LOW("ETB (meta-gralloc) fd = %d, offset = %d, size = %d",
4113 Input_pmem_info.fd, Input_pmem_info.offset,
4114 Input_pmem_info.size);
4115 // if input buffer dimensions is different from what is configured,
4116 // reject the buffer
4117 if (ALIGN((int)m_sInPortDef.format.video.nFrameWidth,32) != ALIGN(handle->unaligned_width,32) ||
4118 ALIGN((int)m_sInPortDef.format.video.nFrameHeight,32) != ALIGN(handle->unaligned_height,32)) {
4119 ALOGE("Graphic buf size(%dx%d) does not match configured size(%ux%u)",
4120 handle->unaligned_width, handle->unaligned_height,
4121 m_sInPortDef.format.video.nFrameWidth, m_sInPortDef.format.video.nFrameHeight);
4122 post_event ((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD);
4123 return OMX_ErrorNone;
4124 }
4125 }
4126 if (dev_use_buf(PORT_INDEX_IN) != true) {
4127 DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
4128 post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
4129 return OMX_ErrorBadParameter;
4130 }
4131 } else if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
4132 #else
4133 if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
4134 #endif
4135 {
4136 DEBUG_PRINT_LOW("Heap UseBuffer case, so memcpy the data");
4137
4138 auto_lock l(m_buf_lock);
4139 pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
4140 if (pmem_data_buf && BITMASK_PRESENT(&m_client_in_bm_count, nBufIndex)) {
4141 memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
4142 buffer->nFilledLen);
4143 }
4144 DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
4145 } else if (mUseProxyColorFormat) {
4146 // Gralloc-source buffers with color-conversion
4147 fd = m_pInput_pmem[nBufIndex].fd;
4148 DEBUG_PRINT_LOW("ETB (color-converted) fd = %d, size = %u",
4149 fd, (unsigned int)buffer->nFilledLen);
4150 } else if (m_sInPortDef.format.video.eColorFormat ==
4151 OMX_COLOR_FormatYUV420SemiPlanar) {
4152 //For the case where YUV420SP buffers are qeueued to component
4153 //by sources other than camera (Apps via MediaCodec), conversion
4154 //to vendor flavoured NV12 color format is required.
4155 if (!dev_color_align(buffer, m_sInPortDef.format.video.nFrameWidth,
4156 m_sInPortDef.format.video.nFrameHeight)) {
4157 DEBUG_PRINT_ERROR("Failed to adjust buffer color");
4158 post_event((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD);
4159 return OMX_ErrorUndefined;
4160 }
4161 }
4162 if (dev_empty_buf(buffer, pmem_data_buf,nBufIndex,fd) != true)
4163 {
4164 DEBUG_PRINT_ERROR("ERROR: ETBProxy: dev_empty_buf failed");
4165 #ifdef _ANDROID_ICS_
4166 omx_release_meta_buffer(buffer);
4167 #endif
4168 post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
4169 /*Generate an async error and move to invalid state*/
4170 pending_input_buffers--;
4171 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
4172 if (hw_overload) {
4173 return OMX_ErrorInsufficientResources;
4174 }
4175 return OMX_ErrorBadParameter;
4176 }
4177 return ret;
4178 }
4179
4180 /* ======================================================================
4181 FUNCTION
4182 omx_video::FillThisBuffer
4183
4184 DESCRIPTION
4185 IL client uses this method to release the frame buffer
4186 after displaying them.
4187
4188 PARAMETERS
4189 None.
4190
4191 RETURN VALUE
4192 true/false
4193
4194 ========================================================================== */
fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)4195 OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
4196 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4197 {
4198 if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
4199 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size");
4200 return OMX_ErrorBadParameter;
4201 }
4202
4203 print_omx_buffer("FillThisBuffer", buffer);
4204
4205 if (m_state != OMX_StateExecuting &&
4206 m_state != OMX_StatePause &&
4207 m_state != OMX_StateIdle) {
4208 DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State");
4209 return OMX_ErrorInvalidState;
4210 }
4211
4212 if (buffer->nOutputPortIndex == PORT_INDEX_EXTRADATA_OUT) {
4213 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->invalid port in header");
4214 return OMX_ErrorBadParameter;
4215 }
4216
4217 if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
4218 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid");
4219 return OMX_ErrorVersionMismatch;
4220 }
4221
4222 if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) {
4223 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index");
4224 return OMX_ErrorBadPortIndex;
4225 }
4226
4227 if (!m_sOutPortDef.bEnabled) {
4228 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled");
4229 return OMX_ErrorIncorrectStateOperation;
4230 }
4231
4232 post_event((unsigned long) hComp, (unsigned long)buffer,OMX_COMPONENT_GENERATE_FTB);
4233 return OMX_ErrorNone;
4234 }
4235
4236 /* ======================================================================
4237 FUNCTION
4238 omx_video::fill_this_buffer_proxy
4239
4240 DESCRIPTION
4241 IL client uses this method to release the frame buffer
4242 after displaying them.
4243
4244 PARAMETERS
4245 None.
4246
4247 RETURN VALUE
4248 true/false
4249
4250 ========================================================================== */
fill_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * bufferAdd)4251 OMX_ERRORTYPE omx_video::fill_this_buffer_proxy(
4252 OMX_IN OMX_HANDLETYPE hComp,
4253 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
4254 {
4255 VIDC_TRACE_NAME_HIGH("FTB");
4256 (void)hComp;
4257 OMX_U8 *pmem_data_buf = NULL;
4258 OMX_ERRORTYPE nRet = OMX_ErrorNone;
4259 auto_lock l(m_buf_lock);
4260 if (m_buffer_freed == true) {
4261 DEBUG_PRINT_ERROR("ERROR: FTBProxy: Invalid call. Called after freebuffer");
4262 return OMX_ErrorBadParameter;
4263 }
4264
4265 if (bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= (int)m_sOutPortDef.nBufferCountActual) ) {
4266 DEBUG_PRINT_ERROR("ERROR: FTBProxy: Invalid i/p params");
4267 return OMX_ErrorBadParameter;
4268 }
4269
4270 pending_output_buffers++;
4271 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
4272 /*Return back the output buffer to client*/
4273 if ( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) {
4274 DEBUG_PRINT_LOW("o/p port is Disabled or Flush in Progress");
4275 post_event ((unsigned long)bufferAdd,0,
4276 OMX_COMPONENT_GENERATE_FBD);
4277 return OMX_ErrorNone;
4278 }
4279
4280 if (output_use_buffer && !m_use_output_pmem) {
4281 DEBUG_PRINT_LOW("Heap UseBuffer case");
4282 pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer;
4283 }
4284
4285 if (dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) {
4286 DEBUG_PRINT_ERROR("ERROR: dev_fill_buf() Failed");
4287 post_event ((unsigned long)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD);
4288 pending_output_buffers--;
4289 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
4290 return OMX_ErrorBadParameter;
4291 }
4292
4293 return OMX_ErrorNone;
4294 }
4295
4296 /* ======================================================================
4297 FUNCTION
4298 omx_video::SetCallbacks
4299
4300 DESCRIPTION
4301 Set the callbacks.
4302
4303 PARAMETERS
4304 None.
4305
4306 RETURN VALUE
4307 OMX Error None if everything successful.
4308
4309 ========================================================================== */
set_callbacks(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_CALLBACKTYPE * callbacks,OMX_IN OMX_PTR appData)4310 OMX_ERRORTYPE omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
4311 OMX_IN OMX_CALLBACKTYPE* callbacks,
4312 OMX_IN OMX_PTR appData)
4313 {
4314 (void)hComp;
4315
4316 if (!callbacks)
4317 return OMX_ErrorBadParameter;
4318
4319 m_pCallbacks = *callbacks;
4320 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\
4321 m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone);
4322 m_app_data = appData;
4323 return OMX_ErrorNone;
4324 }
4325
4326
4327 /* ======================================================================
4328 FUNCTION
4329 omx_venc::UseEGLImage
4330
4331 DESCRIPTION
4332 OMX Use EGL Image method implementation <TBD>.
4333
4334 PARAMETERS
4335 <TBD>.
4336
4337 RETURN VALUE
4338 Not Implemented error.
4339
4340 ========================================================================== */
use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN void * eglImage)4341 OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
4342 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4343 OMX_IN OMX_U32 port,
4344 OMX_IN OMX_PTR appData,
4345 OMX_IN void* eglImage)
4346 {
4347 (void)hComp, (void)bufferHdr, (void)port, (void)appData, (void)eglImage;
4348 DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented");
4349 return OMX_ErrorNotImplemented;
4350 }
4351
4352 /* ======================================================================
4353 FUNCTION
4354 omx_venc::ComponentRoleEnum
4355
4356 DESCRIPTION
4357 OMX Component Role Enum method implementation.
4358
4359 PARAMETERS
4360 <TBD>.
4361
4362 RETURN VALUE
4363 OMX Error None if everything is successful.
4364 ========================================================================== */
component_role_enum(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_U8 * role,OMX_IN OMX_U32 index)4365 OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
4366 OMX_OUT OMX_U8* role,
4367 OMX_IN OMX_U32 index)
4368 {
4369 (void)hComp;
4370 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4371 if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
4372 if ((0 == index) && role) {
4373 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
4374 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
4375 } else {
4376 DEBUG_PRINT_ERROR("ERROR: No more roles");
4377 eRet = OMX_ErrorNoMore;
4378 }
4379 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE) ||
4380 !strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
4381 if ((0 == index) && role) {
4382 strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
4383 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
4384 } else {
4385 DEBUG_PRINT_ERROR("ERROR: No more roles");
4386 eRet = OMX_ErrorNoMore;
4387 }
4388 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
4389 if ((0 == index) && role) {
4390 strlcpy((char *)role, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE);
4391 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
4392 } else {
4393 DEBUG_PRINT_ERROR("ERROR: No more roles");
4394 eRet = OMX_ErrorNoMore;
4395 }
4396 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE) ||
4397 !strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc.cq", OMX_MAX_STRINGNAME_SIZE) ||
4398 !strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc.secure", OMX_MAX_STRINGNAME_SIZE) ||
4399 !strncmp((char*)m_nkind, "OMX.qcom.video.encoder.heic", OMX_MAX_STRINGNAME_SIZE)) {
4400 if ((0 == index) && role) {
4401 strlcpy((char *)role, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
4402 DEBUG_PRINT_LOW("component_role_enum: role %s", role);
4403 } else {
4404 DEBUG_PRINT_ERROR("ERROR: No more roles");
4405 eRet = OMX_ErrorNoMore;
4406 }
4407 } else {
4408 DEBUG_PRINT_ERROR("ERROR: Querying Role on Unknown Component");
4409 eRet = OMX_ErrorInvalidComponentName;
4410 }
4411 return eRet;
4412 }
4413
4414
4415
4416
4417 /* ======================================================================
4418 FUNCTION
4419 omx_venc::AllocateDone
4420
4421 DESCRIPTION
4422 Checks if entire buffer pool is allocated by IL Client or not.
4423 Need this to move to IDLE state.
4424
4425 PARAMETERS
4426 None.
4427
4428 RETURN VALUE
4429 true/false.
4430
4431 ========================================================================== */
allocate_done(void)4432 bool omx_video::allocate_done(void)
4433 {
4434 bool bRet = false;
4435 bool bRet_In = false;
4436 bool bRet_Out = false;
4437 bool bRet_Out_Extra = false;
4438 bool bRet_In_Extra = false;
4439
4440 bRet_In = allocate_input_done();
4441 bRet_Out = allocate_output_done();
4442 bRet_In_Extra = allocate_input_extradata_done();
4443 bRet_Out_Extra = allocate_output_extradata_done();
4444
4445 if (bRet_In && bRet_Out && bRet_Out_Extra && bRet_In_Extra) {
4446 bRet = true;
4447 }
4448
4449 return bRet;
4450 }
4451 /* ======================================================================
4452 FUNCTION
4453 omx_venc::AllocateInputDone
4454
4455 DESCRIPTION
4456 Checks if I/P buffer pool is allocated by IL Client or not.
4457
4458 PARAMETERS
4459 None.
4460
4461 RETURN VALUE
4462 true/false.
4463
4464 ========================================================================== */
allocate_input_done(void)4465 bool omx_video::allocate_input_done(void)
4466 {
4467 bool bRet = false;
4468 unsigned i=0;
4469
4470 if (m_inp_mem_ptr == NULL) {
4471 return bRet;
4472 }
4473 if (m_inp_mem_ptr ) {
4474 for (; i<m_sInPortDef.nBufferCountActual; i++) {
4475 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4476 break;
4477 }
4478 }
4479 }
4480 if (i==m_sInPortDef.nBufferCountActual) {
4481 bRet = true;
4482 }
4483 if (i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled) {
4484 m_sInPortDef.bPopulated = OMX_TRUE;
4485 }
4486 return bRet;
4487 }
4488 /* ======================================================================
4489 FUNCTION
4490 omx_venc::AllocateOutputDone
4491
4492 DESCRIPTION
4493 Checks if entire O/P buffer pool is allocated by IL Client or not.
4494
4495 PARAMETERS
4496 None.
4497
4498 RETURN VALUE
4499 true/false.
4500
4501 ========================================================================== */
allocate_output_done(void)4502 bool omx_video::allocate_output_done(void)
4503 {
4504 bool bRet = false;
4505 unsigned j=0;
4506
4507 if (m_out_mem_ptr == NULL) {
4508 return bRet;
4509 }
4510
4511 if (m_out_mem_ptr ) {
4512 for (; j<m_sOutPortDef.nBufferCountActual; j++) {
4513 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
4514 break;
4515 }
4516 }
4517 }
4518
4519 if (j==m_sOutPortDef.nBufferCountActual) {
4520 bRet = true;
4521 }
4522
4523 if (j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled) {
4524 m_sOutPortDef.bPopulated = OMX_TRUE;
4525 }
4526 return bRet;
4527 }
4528
allocate_output_extradata_done(void)4529 bool omx_video::allocate_output_extradata_done(void) {
4530 bool bRet = false;
4531 unsigned j=0;
4532 unsigned nBufferCount = 0;
4533
4534 nBufferCount = m_client_out_extradata_info.getBufferCount();
4535
4536 if (!m_client_out_extradata_info.is_client_extradata_enabled()) {
4537 return true;
4538 }
4539
4540 if (m_client_output_extradata_mem_ptr) {
4541 for (; j < nBufferCount; j++) {
4542 if (BITMASK_ABSENT(&m_out_extradata_bm_count,j)) {
4543 break;
4544 }
4545 }
4546
4547 if (j == nBufferCount) {
4548 bRet = true;
4549 DEBUG_PRINT_HIGH("Allocate done for all extradata o/p buffers");
4550 }
4551 }
4552
4553 return bRet;
4554 }
4555
allocate_input_extradata_done(void)4556 bool omx_video::allocate_input_extradata_done(void) {
4557 bool bRet = false;
4558 unsigned j=0;
4559 unsigned nBufferCount = 0;
4560
4561 nBufferCount = m_client_in_extradata_info.getBufferCount();
4562
4563 if (!m_client_in_extradata_info.is_client_extradata_enabled()) {
4564 return true;
4565 }
4566
4567 if (m_client_input_extradata_mem_ptr) {
4568 for (; j < nBufferCount; j++) {
4569 if (BITMASK_ABSENT(&m_in_extradata_bm_count,j)) {
4570 break;
4571 }
4572 }
4573
4574 if (j == nBufferCount) {
4575 bRet = true;
4576 DEBUG_PRINT_HIGH("Allocate done for all extradata i/p buffers");
4577 }
4578 }
4579
4580 return bRet;
4581 }
4582
4583 /* ======================================================================
4584 FUNCTION
4585 omx_venc::ReleaseDone
4586
4587 DESCRIPTION
4588 Checks if IL client has released all the buffers.
4589
4590 PARAMETERS
4591 None.
4592
4593 RETURN VALUE
4594 true/false
4595
4596 ========================================================================== */
release_done(void)4597 bool omx_video::release_done(void)
4598 {
4599 bool bRet = false;
4600 DEBUG_PRINT_LOW("Inside release_done()");
4601 if (release_input_done()) {
4602 if (release_output_done()) {
4603 if (release_output_extradata_done()) {
4604 bRet = true;
4605 }
4606 }
4607 }
4608 return bRet;
4609 }
4610
4611
4612 /* ======================================================================
4613 FUNCTION
4614 omx_venc::ReleaseOutputDone
4615
4616 DESCRIPTION
4617 Checks if IL client has released all the buffers.
4618
4619 PARAMETERS
4620 None.
4621
4622 RETURN VALUE
4623 true/false
4624
4625 ========================================================================== */
release_output_done(void)4626 bool omx_video::release_output_done(void)
4627 {
4628 bool bRet = false;
4629 unsigned i=0,j=0;
4630
4631 DEBUG_PRINT_LOW("Inside release_output_done()");
4632 if (m_out_mem_ptr) {
4633 for (; j<m_sOutPortDef.nBufferCountActual; j++) {
4634 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
4635 break;
4636 }
4637 }
4638 if (j==m_sOutPortDef.nBufferCountActual) {
4639 bRet = true;
4640 }
4641 } else {
4642 bRet = true;
4643 }
4644 return bRet;
4645 }
4646 /* ======================================================================
4647 FUNCTION
4648 omx_venc::ReleaseInputDone
4649
4650 DESCRIPTION
4651 Checks if IL client has released all the buffers.
4652
4653 PARAMETERS
4654 None.
4655
4656 RETURN VALUE
4657 true/false
4658
4659 ========================================================================== */
release_input_done(void)4660 bool omx_video::release_input_done(void)
4661 {
4662 bool bRet = false;
4663 unsigned i=0,j=0;
4664
4665 DEBUG_PRINT_LOW("Inside release_input_done()");
4666 if (m_inp_mem_ptr) {
4667 for (; j<m_sInPortDef.nBufferCountActual; j++) {
4668 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
4669 break;
4670 }
4671 }
4672 if (j==m_sInPortDef.nBufferCountActual) {
4673 bRet = true;
4674 }
4675 } else {
4676 bRet = true;
4677 }
4678 return bRet;
4679 }
4680
release_output_extradata_done(void)4681 bool omx_video::release_output_extradata_done(void) {
4682 bool bRet = false;
4683 unsigned i=0,j=0, buffer_count=0;
4684
4685 buffer_count = m_client_out_extradata_info.getBufferCount();
4686 DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d",
4687 m_client_output_extradata_mem_ptr, buffer_count);
4688
4689 if (m_client_output_extradata_mem_ptr) {
4690 for (; j<buffer_count; j++) {
4691 if ( BITMASK_PRESENT(&m_out_extradata_bm_count,j)) {
4692 break;
4693 }
4694 }
4695 if (j == buffer_count) {
4696 bRet = true;
4697 }
4698 } else {
4699 bRet = true;
4700 }
4701 return bRet;
4702 }
4703
release_input_extradata_done(void)4704 bool omx_video::release_input_extradata_done(void) {
4705 bool bRet = false;
4706 unsigned i=0,j=0, buffer_count=0;
4707
4708 buffer_count = m_client_in_extradata_info.getBufferCount();
4709 DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d",
4710 m_client_input_extradata_mem_ptr, buffer_count);
4711
4712 if (m_client_input_extradata_mem_ptr) {
4713 for (; j<buffer_count; j++) {
4714 if ( BITMASK_PRESENT(&m_in_extradata_bm_count,j)) {
4715 break;
4716 }
4717 }
4718 if (j == buffer_count) {
4719 bRet = true;
4720 }
4721 } else {
4722 bRet = true;
4723 }
4724 return bRet;
4725 }
4726
fill_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)4727 OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp,
4728 OMX_BUFFERHEADERTYPE * buffer)
4729 {
4730 VIDC_TRACE_NAME_HIGH("FBD");
4731 int index = buffer - m_out_mem_ptr;
4732
4733 if (buffer == NULL || ((buffer - m_out_mem_ptr) > (int)m_sOutPortDef.nBufferCountActual)) {
4734 return OMX_ErrorBadParameter;
4735 }
4736
4737 pending_output_buffers--;
4738 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
4739 VIDC_TRACE_INT_LOW("FBD-TS", buffer->nTimeStamp / 1000);
4740 VIDC_TRACE_INT_LOW("FBD-size", buffer->nFilledLen);
4741
4742 print_omx_buffer("FillBufferDone", buffer);
4743 if (secure_session && m_pCallbacks.FillBufferDone) {
4744 if (buffer->nFilledLen > 0)
4745 m_fbd_count++;
4746 m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
4747 return OMX_ErrorNone;
4748 }
4749
4750 /* For use buffer we need to copy the data */
4751 if (m_pCallbacks.FillBufferDone) {
4752 if (buffer->nFilledLen > 0) {
4753 m_fbd_count++;
4754
4755 if (dev_get_output_log_flag()) {
4756 sync_start_read(m_pOutput_ion[index].data_fd);
4757 dev_output_log_buffers((const char*)buffer->pBuffer + buffer->nOffset, buffer->nFilledLen,
4758 buffer->nTimeStamp);
4759 sync_end_read(m_pOutput_ion[index].data_fd);
4760
4761 }
4762 }
4763 if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
4764 if (!dev_handle_output_extradata((void *)buffer, index))
4765 DEBUG_PRINT_ERROR("Failed to parse output extradata");
4766 }
4767 m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
4768 } else {
4769 return OMX_ErrorBadParameter;
4770 }
4771 return OMX_ErrorNone;
4772 }
4773
empty_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)4774 OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp,
4775 OMX_BUFFERHEADERTYPE* buffer)
4776 {
4777 VIDC_TRACE_NAME_HIGH("EBD");
4778 int buffer_index = -1;
4779
4780 buffer_index = buffer - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr);
4781 if (buffer == NULL ||
4782 ((buffer_index > (int)m_sInPortDef.nBufferCountActual))) {
4783 DEBUG_PRINT_ERROR("ERROR in empty_buffer_done due to index buffer");
4784 return OMX_ErrorBadParameter;
4785 }
4786
4787 print_omx_buffer("EmptyBufferDone", buffer);
4788 pending_input_buffers--;
4789 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
4790
4791 if (mUseProxyColorFormat &&
4792 (buffer_index >= 0 && (buffer_index < (int)m_sInPortDef.nBufferCountActual))) {
4793 if (!pdest_frame && !input_flush_progress && mUsesColorConversion) {
4794 pdest_frame = buffer;
4795 DEBUG_PRINT_LOW("empty_buffer_done pdest_frame address is %p",pdest_frame);
4796 return push_input_buffer(hComp);
4797 }
4798 if (mUsesColorConversion) {
4799 // return color-conversion buffer back to the pool
4800 DEBUG_PRINT_LOW("empty_buffer_done insert address is %p",buffer);
4801 if (!m_opq_pmem_q.insert_entry((unsigned long)buffer, 0, 0)) {
4802 DEBUG_PRINT_ERROR("empty_buffer_done: pmem queue is full");
4803 return OMX_ErrorBadParameter;
4804 }
4805 } else {
4806 // We are not dealing with color-conversion, Buffer being returned
4807 // here is client's buffer, return it back to client
4808 if (m_pCallbacks.EmptyBufferDone && buffer) {
4809 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
4810 DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p", buffer);
4811 }
4812 }
4813 } else if (m_pCallbacks.EmptyBufferDone) {
4814 m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
4815 }
4816 return OMX_ErrorNone;
4817 }
4818
complete_pending_buffer_done_cbs()4819 void omx_video::complete_pending_buffer_done_cbs()
4820 {
4821 unsigned long p1;
4822 unsigned long p2;
4823 unsigned long ident;
4824 omx_cmd_queue tmp_q, pending_bd_q;
4825 pthread_mutex_lock(&m_lock);
4826 // pop all pending GENERATE FDB from ftb queue
4827 while (m_ftb_q.m_size) {
4828 m_ftb_q.pop_entry(&p1,&p2,&ident);
4829 if (ident == OMX_COMPONENT_GENERATE_FBD) {
4830 pending_bd_q.insert_entry(p1,p2,ident);
4831 } else {
4832 tmp_q.insert_entry(p1,p2,ident);
4833 }
4834 }
4835 //return all non GENERATE FDB to ftb queue
4836 while (tmp_q.m_size) {
4837 tmp_q.pop_entry(&p1,&p2,&ident);
4838 m_ftb_q.insert_entry(p1,p2,ident);
4839 }
4840 // pop all pending GENERATE EDB from etb queue
4841 while (m_etb_q.m_size) {
4842 m_etb_q.pop_entry(&p1,&p2,&ident);
4843 if (ident == OMX_COMPONENT_GENERATE_EBD) {
4844 pending_bd_q.insert_entry(p1,p2,ident);
4845 } else {
4846 tmp_q.insert_entry(p1,p2,ident);
4847 }
4848 }
4849 //return all non GENERATE FDB to etb queue
4850 while (tmp_q.m_size) {
4851 tmp_q.pop_entry(&p1,&p2,&ident);
4852 m_etb_q.insert_entry(p1,p2,ident);
4853 }
4854 pthread_mutex_unlock(&m_lock);
4855 // process all pending buffer dones
4856 while (pending_bd_q.m_size) {
4857 pending_bd_q.pop_entry(&p1,&p2,&ident);
4858 switch (ident) {
4859 case OMX_COMPONENT_GENERATE_EBD:
4860 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
4861 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
4862 omx_report_error ();
4863 }
4864 break;
4865
4866 case OMX_COMPONENT_GENERATE_FBD:
4867 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
4868 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
4869 omx_report_error ();
4870 }
4871 break;
4872 }
4873 }
4874 }
4875
ion_map(int fd,int len)4876 char *omx_video::ion_map(int fd, int len)
4877 {
4878 char *bufaddr = (char*)mmap(NULL, len, PROT_READ|PROT_WRITE,
4879 MAP_SHARED, fd, 0);
4880 if (bufaddr != MAP_FAILED)
4881 cache_clean_invalidate(fd);
4882 return bufaddr;
4883 }
4884
ion_unmap(int fd,void * bufaddr,int len)4885 OMX_ERRORTYPE omx_video::ion_unmap(int fd, void *bufaddr, int len)
4886 {
4887 cache_clean_invalidate(fd);
4888 if (-1 == munmap(bufaddr, len)) {
4889 DEBUG_PRINT_ERROR("munmap failed.");
4890 return OMX_ErrorInsufficientResources;
4891 }
4892 return OMX_ErrorNone;
4893 }
4894
4895 #ifdef USE_ION
alloc_map_ion_memory(int size,venc_ion * ion_info,int flag)4896 bool omx_video::alloc_map_ion_memory(int size, venc_ion *ion_info, int flag)
4897 {
4898 struct venc_ion buf_ion_info;
4899 int rc=0;
4900
4901 if (size <=0 || !ion_info) {
4902 DEBUG_PRINT_ERROR("Invalid input to alloc_map_ion_memory");
4903 return false;
4904 }
4905
4906 if (is_stop_in_progress) {
4907 DEBUG_PRINT_ERROR("Stop in progress: do not allocate any memory");
4908 return false;
4909 }
4910
4911 ion_info->data_fd = -1;
4912 ion_info->dev_fd = ion_open();
4913 if (ion_info->dev_fd <= 0) {
4914 DEBUG_PRINT_ERROR("ERROR: ION Device open() Failed");
4915 return false;
4916 }
4917
4918 if(secure_session) {
4919 ion_info->alloc_data.len = (size + (SECURE_ALIGN - 1)) & ~(SECURE_ALIGN - 1);
4920 ion_info->alloc_data.flags = flag;
4921 ion_info->alloc_data.heap_id_mask = ION_HEAP(MEM_HEAP_ID);
4922 if (ion_info->alloc_data.flags & ION_FLAG_CP_BITSTREAM) {
4923 ion_info->alloc_data.heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
4924 }
4925 DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %u flags %x",
4926 (unsigned int)ion_info->alloc_data.len,
4927 ion_info->alloc_data.flags);
4928 } else {
4929 ion_info->alloc_data.len = (size + (SZ_4K - 1)) & ~(SZ_4K - 1);
4930 ion_info->alloc_data.flags = (flag & ION_FLAG_CACHED);
4931
4932 /* If color format is Vanilla NV12, we will need to use caching for optimal
4933 color alignment performance.
4934 */
4935
4936 if (m_sInPortDef.format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)
4937 {
4938 DEBUG_PRINT_HIGH("Enabling cacheing for this buffer");
4939 ion_info->alloc_data.flags = ION_FLAG_CACHED;
4940 }
4941 ion_info->alloc_data.heap_id_mask = (ION_HEAP(MEM_HEAP_ID) |
4942 ION_HEAP(ION_SYSTEM_HEAP_ID));
4943 DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %u flags %x",
4944 (unsigned int)ion_info->alloc_data.len,
4945 ion_info->alloc_data.flags);
4946 }
4947
4948 rc = ion_alloc_fd(ion_info->dev_fd, ion_info->alloc_data.len, 0,
4949 ion_info->alloc_data.heap_id_mask,
4950 ion_info->alloc_data.flags, &ion_info->data_fd);
4951 if (rc || ion_info->data_fd < 0) {
4952 DEBUG_PRINT_ERROR("ION ALLOC memory failed 0x%x", rc);
4953 ion_close(ion_info->dev_fd);
4954 ion_info->data_fd = -1;
4955 ion_info->dev_fd = -1;
4956 return false;
4957 }
4958
4959 DEBUG_PRINT_HIGH("Alloc ion memory: fd (dev:%d data:%d) len %d flags %#x mask %#x",
4960 ion_info->dev_fd, ion_info->data_fd, (unsigned int)ion_info->alloc_data.len,
4961 (unsigned int)ion_info->alloc_data.flags,
4962 (unsigned int)ion_info->alloc_data.heap_id_mask);
4963
4964 return true;
4965 }
4966
free_ion_memory(struct venc_ion * buf_ion_info)4967 void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
4968 {
4969 if (!buf_ion_info) {
4970 DEBUG_PRINT_ERROR("Invalid input to free_ion_memory");
4971 return;
4972 }
4973 DEBUG_PRINT_HIGH("Free ion memory: fd (dev:%d data:%d) len %d flags %#x mask %#x",
4974 buf_ion_info->dev_fd, buf_ion_info->data_fd,
4975 (unsigned int)buf_ion_info->alloc_data.len,
4976 (unsigned int)buf_ion_info->alloc_data.flags,
4977 (unsigned int)buf_ion_info->alloc_data.heap_id_mask);
4978 if (buf_ion_info->data_fd >= 0) {
4979 close(buf_ion_info->data_fd);
4980 buf_ion_info->data_fd = -1;
4981 }
4982 if (buf_ion_info->dev_fd >= 0) {
4983 ion_close(buf_ion_info->dev_fd);
4984 buf_ion_info->dev_fd = -1;
4985 }
4986 }
4987 #endif
4988
4989 #ifdef _ANDROID_ICS_
omx_release_meta_buffer(OMX_BUFFERHEADERTYPE * buffer)4990 void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer)
4991 {
4992 if (buffer && meta_mode_enable) {
4993 LEGACY_CAM_METADATA_TYPE *media_ptr;
4994 struct pmem Input_pmem;
4995 unsigned int index_pmem = 0;
4996
4997 index_pmem = (buffer - m_inp_mem_ptr);
4998 if (mUsesColorConversion &&
4999 (index_pmem < m_sInPortDef.nBufferCountActual)) {
5000 if (!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)) {
5001 DEBUG_PRINT_ERROR("omx_release_meta_buffer dev free failed");
5002 }
5003 } else {
5004 media_ptr = (LEGACY_CAM_METADATA_TYPE *) buffer->pBuffer;
5005 if (media_ptr && media_ptr->meta_handle) {
5006 if (media_ptr->buffer_type == LEGACY_CAM_SOURCE) {
5007 Input_pmem.buffer = media_ptr;
5008 Input_pmem.fd = MetaBufferUtil::getFdAt(media_ptr->meta_handle, 0);
5009 int size = MetaBufferUtil::getIntAt(media_ptr->meta_handle, 0, MetaBufferUtil::INT_SIZE);
5010 int offset = MetaBufferUtil::getIntAt(media_ptr->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
5011 if (Input_pmem.fd < 0 || size < 0 || offset < 0)
5012 DEBUG_PRINT_ERROR("Invalid meta buffer");
5013
5014 Input_pmem.size = size;
5015 Input_pmem.offset = offset;
5016 DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd,
5017 Input_pmem.offset,
5018 Input_pmem.size);
5019 } else if (media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) {
5020 VideoGrallocMetadata *media_ptr = (VideoGrallocMetadata *)buffer->pBuffer;
5021 private_handle_t *handle = (private_handle_t *)media_ptr->pHandle;
5022 Input_pmem.buffer = media_ptr;
5023 Input_pmem.fd = handle->fd;
5024 Input_pmem.offset = 0;
5025 Input_pmem.size = handle->size;
5026 }
5027 }
5028 }
5029 }
5030 }
5031 #endif
5032
is_ubwc_interlaced(private_handle_t * handle)5033 bool is_ubwc_interlaced(private_handle_t *handle) {
5034 int interlace_flag = 0;
5035
5036 if (getMetaData(const_cast<private_handle_t *>(handle),
5037 GET_PP_PARAM_INTERLACED, &interlace_flag)) {
5038 interlace_flag = 0;
5039 }
5040 return (handle->format == HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC) &&
5041 !!interlace_flag;
5042 }
5043
is_rotation_enabled()5044 bool omx_video::is_rotation_enabled()
5045 {
5046 bool bRet = false;
5047
5048 if (m_sConfigFrameRotation.nRotation == 90 ||
5049 m_sConfigFrameRotation.nRotation == 180 ||
5050 m_sConfigFrameRotation.nRotation == 270) {
5051 bRet = true;
5052 }
5053
5054 return bRet;
5055 }
5056
initFastCV()5057 void omx_video::initFastCV() {
5058 fcvSetOperationMode(FASTCV_OP_CPU_PERFORMANCE);
5059 fcvMemInit();
5060 m_fastCV_init_done = true;
5061 }
5062
is_flip_conv_needed(private_handle_t * handle)5063 bool omx_video::is_flip_conv_needed(private_handle_t *handle) {
5064 OMX_MIRRORTYPE mirror;
5065 mirror = m_sConfigFrameMirror.eMirror;
5066 OMX_U32 captureRate = m_nOperatingRate >> 16;
5067 bool is_flip_needed = false;
5068
5069 if (m_no_vpss && m_fastCV_init_done && captureRate <= 30 &&
5070 (mirror == OMX_MirrorVertical || mirror == OMX_MirrorHorizontal ||
5071 mirror == OMX_MirrorBoth)) {
5072 is_flip_needed = true;
5073 }
5074
5075 if (handle && !(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE ||
5076 handle->format == HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS)) {
5077 is_flip_needed = false;
5078 }
5079
5080 return is_flip_needed;
5081 }
5082
do_flip_conversion(struct pmem * buffer)5083 OMX_ERRORTYPE omx_video::do_flip_conversion(struct pmem *buffer) {
5084 OMX_U32 width = m_sInPortDef.format.video.nFrameWidth;
5085 OMX_U32 height = m_sInPortDef.format.video.nFrameHeight;
5086 OMX_U32 stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
5087 OMX_U32 scanLines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
5088 fcvFlipDir direction;
5089 OMX_ERRORTYPE ret = OMX_ErrorNone;
5090
5091 switch(m_sConfigFrameMirror.eMirror) {
5092 case OMX_MirrorVertical:
5093 direction = FASTCV_FLIP_VERT;
5094 break;
5095 case OMX_MirrorHorizontal:
5096 direction = FASTCV_FLIP_HORIZ;
5097 break;
5098 case OMX_MirrorBoth:
5099 direction = FASTCV_FLIP_BOTH;
5100 break;
5101 default:
5102 return OMX_ErrorBadParameter;
5103 }
5104
5105 unsigned char *uva = (unsigned char *)ion_map(buffer->fd, buffer->size);
5106 if (uva == MAP_FAILED) {
5107 ret = OMX_ErrorBadParameter;
5108 return ret;
5109 }
5110 unsigned char *src = uva;
5111 DEBUG_PRINT_LOW("start flip conversion");
5112 fcvFlipu8( src, width, height, stride, src, stride, direction);
5113 src = src + (stride * scanLines);
5114 fcvFlipu16((OMX_U16 *)src,width/2,height/2,stride,(OMX_U16 *)src,stride,direction);
5115
5116 ion_unmap(buffer->fd, uva, buffer->size);
5117 return ret;
5118 }
5119
is_conv_needed(private_handle_t * handle)5120 bool omx_video::is_conv_needed(private_handle_t *handle)
5121 {
5122 bool bRet = false;
5123 bool interlaced = is_ubwc_interlaced(handle);
5124
5125 if (!strncmp(m_platform, "msm8996", 7)) {
5126 bRet = handle->format == HAL_PIXEL_FORMAT_RGBA_8888 &&
5127 !(handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED ||
5128 handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED_PI);
5129 } else {
5130 bRet = handle->format == HAL_PIXEL_FORMAT_RGBA_8888;
5131 }
5132
5133 #ifdef _HW_RGBA
5134 bRet = false;
5135 #endif
5136 bRet |= interlaced;
5137 if (m_no_vpss && is_rotation_enabled()) {
5138 bRet = true;
5139 }
5140 DEBUG_PRINT_LOW("RGBA conversion %s. Format %d Flag %d interlace_flag = %d",
5141 bRet ? "Needed":"Not-Needed", handle->format,
5142 handle->flags, interlaced);
5143 return bRet;
5144 }
5145
print_debug_color_aspects(ColorAspects * aspects,const char * prefix)5146 void omx_video::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) {
5147 DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d",
5148 prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs);
5149 }
5150
empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)5151 OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,
5152 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5153 {
5154 VIDC_TRACE_NAME_LOW("ETB-Opaque");
5155 unsigned nBufIndex = 0;
5156 OMX_ERRORTYPE ret = OMX_ErrorNone;
5157 VideoGrallocMetadata *media_buffer; // This method primarily assumes gralloc-metadata
5158 private_handle_t *handle = NULL;
5159 DEBUG_PRINT_LOW("ETBProxyOpaque: buffer[%p]", buffer);
5160
5161 if (buffer == NULL) {
5162 DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid buffer[%p]",buffer);
5163 return OMX_ErrorBadParameter;
5164 }
5165
5166 if (profile_etb()) {
5167 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5168 return OMX_ErrorNone;
5169 }
5170
5171 if (!dev_buffer_ready_to_queue(buffer)) {
5172 DEBUG_PRINT_HIGH("Info: ETBProxyA: buffer[%p] is deffered", buffer);
5173 return OMX_ErrorNone;
5174 }
5175
5176 nBufIndex = buffer - meta_buffer_hdr;
5177 if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
5178 DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid bufindex = %u",
5179 nBufIndex);
5180 return OMX_ErrorBadParameter;
5181 }
5182
5183 media_buffer = (VideoGrallocMetadata *)buffer->pBuffer;
5184 if (!media_buffer) {
5185 DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
5186 return OMX_ErrorBadParameter;
5187 }
5188 if ((media_buffer->eType == LEGACY_CAM_SOURCE)
5189 && buffer->nAllocLen != sizeof(LEGACY_CAM_METADATA_TYPE)) {
5190 DEBUG_PRINT_ERROR("Invalid metadata size expected(%u) v/s recieved(%zu)",
5191 buffer->nAllocLen, sizeof(LEGACY_CAM_METADATA_TYPE));
5192 return OMX_ErrorBadParameter;
5193 }
5194
5195 if (media_buffer && media_buffer->eType == LEGACY_CAM_SOURCE) {
5196 return empty_this_buffer_proxy(hComp, buffer);
5197 }
5198
5199 if ((!media_buffer || !media_buffer->pHandle || media_buffer->eType != kMetadataBufferTypeGrallocSource) &&
5200 !(buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5201 DEBUG_PRINT_ERROR("Incorrect Buffer queued media buffer = %p",
5202 media_buffer);
5203 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
5204 return OMX_ErrorBadParameter;
5205 } else if (media_buffer) {
5206 handle = (private_handle_t *)media_buffer->pHandle;
5207 }
5208
5209 /*Enable following code once private handle color format is
5210 updated correctly*/
5211
5212 if (buffer->nFilledLen > 0 && handle && !is_streamon_done((OMX_U32) PORT_INDEX_OUT)) {
5213
5214 ColorConvertFormat c2dSrcFmt = RGBA8888;
5215 ColorConvertFormat c2dDestFmt = m_ubwc_supported ? NV12_UBWC : NV12_128m;
5216
5217 ColorMapping::const_iterator found =
5218 mMapPixelFormat2Converter.find(handle->format);
5219
5220 if (found != mMapPixelFormat2Converter.end() && is_conv_needed(handle)) {
5221 c2dSrcFmt = (ColorConvertFormat)found->second;
5222 c2dcc.setConversionNeeded(true);
5223 } else {
5224 DEBUG_PRINT_HIGH("Couldn't find color mapping for (%x).", handle->format);
5225 c2dcc.setConversionNeeded(false);
5226 }
5227
5228 mUsesColorConversion = is_conv_needed(handle);
5229 bool interlaced = is_ubwc_interlaced(handle);
5230 int full_range_flag = m_sConfigColorAspects.sAspects.mRange == ColorAspects::RangeFull ?
5231 private_handle_t::PRIV_FLAGS_ITU_R_601_FR : 0;
5232
5233 if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingImageHEIC)
5234 c2dDestFmt = NV12_512;
5235
5236 if (c2dcc.getConversionNeeded() &&
5237 c2dcc.isPropChanged(m_sInPortDef.format.video.nFrameWidth,
5238 interlaced ? ((m_sInPortDef.format.video.nFrameHeight + 1) / 2) :
5239 m_sInPortDef.format.video.nFrameHeight,
5240 m_sInPortDef.format.video.nFrameWidth,
5241 m_sInPortDef.format.video.nFrameHeight,
5242 c2dSrcFmt, c2dDestFmt,
5243 handle->flags, handle->width)) {
5244 DEBUG_PRINT_HIGH("C2D setRotation - %u", m_sConfigFrameRotation.nRotation);
5245 if (m_no_vpss && is_rotation_enabled()) {
5246 c2dcc.setRotation(m_sConfigFrameRotation.nRotation);
5247 }
5248 DEBUG_PRINT_HIGH("C2D setResolution (0x%X -> 0x%x) HxW (%dx%d) Stride (%d)",
5249 c2dSrcFmt, c2dDestFmt,
5250 m_sInPortDef.format.video.nFrameHeight,
5251 m_sInPortDef.format.video.nFrameWidth,
5252 handle->width);
5253 if (!c2dcc.setResolution(m_sInPortDef.format.video.nFrameWidth,
5254 interlaced ? ((m_sInPortDef.format.video.nFrameHeight + 1) / 2) :
5255 m_sInPortDef.format.video.nFrameHeight,
5256 m_sInPortDef.format.video.nFrameWidth,
5257 m_sInPortDef.format.video.nFrameHeight,
5258 c2dSrcFmt, c2dDestFmt,
5259 handle->flags | full_range_flag, handle->width)) {
5260 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5261 DEBUG_PRINT_ERROR("SetResolution failed");
5262 return OMX_ErrorBadParameter;
5263 }
5264
5265 mC2dSrcFmt = c2dSrcFmt;
5266 mC2DFrameHeight = m_sInPortDef.format.video.nFrameHeight;
5267 mC2DFrameWidth = m_sInPortDef.format.video.nFrameWidth;
5268
5269 if (mC2dDestFmt != c2dDestFmt && !dev_set_format(c2dDestFmt)) {
5270 DEBUG_PRINT_ERROR("cannot set color format");
5271 return OMX_ErrorBadParameter;
5272 }
5273 mC2dDestFmt = c2dDestFmt;
5274 }
5275
5276 dev_get_buf_req (&m_sInPortDef.nBufferCountMin,
5277 &m_sInPortDef.nBufferCountActual,
5278 &m_sInPortDef.nBufferSize,
5279 m_sInPortDef.nPortIndex);
5280 }
5281
5282 if (input_flush_progress == true) {
5283 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5284 DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Input flush in progress");
5285 return OMX_ErrorNone;
5286 }
5287
5288 if (dev_is_meta_mode()) {
5289 LEGACY_CAM_METADATA_TYPE * meta_buf = NULL;
5290
5291 meta_buf = (LEGACY_CAM_METADATA_TYPE *)buffer->pBuffer;
5292
5293 if (meta_buf && m_no_vpss && is_rotation_enabled() &&
5294 meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
5295 VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)buffer->pBuffer;
5296 #ifdef USE_GBM
5297 struct gbm_bo *handle = (struct gbm_bo *)meta_buf->pHandle;
5298 #else
5299 private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
5300 #endif
5301 if (!handle) {
5302 DEBUG_PRINT_ERROR("%s : handle is null!", __FUNCTION__);
5303 return OMX_ErrorUndefined;
5304 }
5305
5306 // if input buffer dimensions is different from what is configured,
5307 // reject the buffer
5308 #ifdef USE_GBM
5309 if (ALIGN((int)m_sInPortDef.format.video.nFrameWidth,32) != ALIGN(handle->width,32) ||
5310 ALIGN((int)m_sInPortDef.format.video.nFrameHeight,32) != ALIGN(handle->height,32)) {
5311 ALOGE("%s: Graphic buf size(%dx%d) does not match configured size(%ux%u)",
5312 __func__, handle->width, handle->height,
5313 #else
5314 if (ALIGN((int)m_sInPortDef.format.video.nFrameWidth,32) != ALIGN(handle->unaligned_width,32) ||
5315 ALIGN((int)m_sInPortDef.format.video.nFrameHeight,32) != ALIGN(handle->unaligned_height,32)) {
5316 ALOGE("%s: Graphic buf size(%dx%d) does not match configured size(%ux%u)",
5317 __func__, handle->unaligned_width, handle->unaligned_height,
5318 #endif
5319 m_sInPortDef.format.video.nFrameWidth, m_sInPortDef.format.video.nFrameHeight);
5320 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
5321 return OMX_ErrorNone;
5322 }
5323 }
5324 }
5325
5326 if (!psource_frame) {
5327 psource_frame = buffer;
5328 ret = push_input_buffer(hComp);
5329 } else {
5330 if (!m_opq_meta_q.insert_entry((unsigned long)buffer,0,0)) {
5331 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Queue is full");
5332 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5333 ret = OMX_ErrorBadParameter;
5334 }
5335 }
5336 return ret;
5337 }
5338
5339 OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp)
5340 {
5341
5342 OMX_ERRORTYPE ret = OMX_ErrorNone;
5343 unsigned long address = 0,p2,id;
5344
5345 DEBUG_PRINT_LOW("In queue Meta Buffer");
5346 if (!psource_frame || !pdest_frame) {
5347 DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
5348 return OMX_ErrorBadParameter;
5349 }
5350
5351 if (psource_frame->nFilledLen > 0) {
5352 if (dev_use_buf(PORT_INDEX_IN) != true) {
5353 DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
5354 post_event ((unsigned long)psource_frame,0,OMX_COMPONENT_GENERATE_EBD);
5355 ret = OMX_ErrorBadParameter;
5356 }
5357 }
5358
5359 if (ret == OMX_ErrorNone)
5360 ret = empty_this_buffer_proxy(hComp,psource_frame);
5361
5362 if (ret == OMX_ErrorNone) {
5363 psource_frame = NULL;
5364 if (!psource_frame && m_opq_meta_q.m_size) {
5365 m_opq_meta_q.pop_entry(&address,&p2,&id);
5366 psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
5367 }
5368 } else {
5369 // there has been an error and source frame has been scheduled for an EBD
5370 psource_frame = NULL;
5371 }
5372 return ret;
5373 }
5374
5375 OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp,
5376 struct pmem &Input_pmem_info,unsigned long &index)
5377 {
5378
5379 unsigned char *uva;
5380 OMX_ERRORTYPE ret = OMX_ErrorNone;
5381 unsigned long address = 0,p2,id;
5382 LEGACY_CAM_METADATA_TYPE * meta_buf = NULL;
5383
5384 DEBUG_PRINT_LOW("In Convert and queue Meta Buffer");
5385 if (!psource_frame || !pdest_frame) {
5386 DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
5387 return OMX_ErrorBadParameter;
5388 }
5389 if (secure_session) {
5390 DEBUG_PRINT_ERROR("cannot convert buffer during secure session");
5391 return OMX_ErrorInvalidState;
5392 }
5393
5394 if (!psource_frame->nFilledLen) {
5395 if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
5396 pdest_frame->nFilledLen = psource_frame->nFilledLen;
5397 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
5398 pdest_frame->nFlags = psource_frame->nFlags;
5399 DEBUG_PRINT_HIGH("Skipping color conversion for empty EOS Buffer "
5400 "header=%p filled-len=%u", pdest_frame, (unsigned int)pdest_frame->nFilledLen);
5401 } else {
5402 pdest_frame->nOffset = 0;
5403 pdest_frame->nFilledLen = 0;
5404 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
5405 pdest_frame->nFlags = psource_frame->nFlags;
5406 DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
5407 pdest_frame, (unsigned int)pdest_frame->nFilledLen);
5408 }
5409 } else if (c2dcc.getConversionNeeded()) {
5410 uva = (unsigned char *)ion_map(Input_pmem_info.fd,Input_pmem_info.size);
5411 if (uva == MAP_FAILED) {
5412 ret = OMX_ErrorBadParameter;
5413 } else {
5414 DEBUG_PRINT_HIGH("Start Color Conversion...");
5415 if (!c2dcc.convertC2D(Input_pmem_info.fd, uva,
5416 uva, m_pInput_pmem[index].fd,
5417 pdest_frame->pBuffer,
5418 pdest_frame->pBuffer)) {
5419 DEBUG_PRINT_ERROR("Color Conversion failed");
5420 ret = OMX_ErrorBadParameter;
5421 } else {
5422 if (dev_is_avtimer_needed() && dev_is_meta_mode()) {
5423 meta_buf = (LEGACY_CAM_METADATA_TYPE *)psource_frame->pBuffer;
5424
5425 if (meta_buf && m_no_vpss && is_rotation_enabled() &&
5426 meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
5427 VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)psource_frame->pBuffer;
5428 private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
5429
5430 if (!handle) {
5431 DEBUG_PRINT_ERROR("%s : handle is null!", __FUNCTION__);
5432 ret = OMX_ErrorUndefined;
5433 return ret;
5434 }
5435
5436 uint64_t avTimerTimestampNs = psource_frame->nTimeStamp * 1000;
5437 if (getMetaData(handle, GET_VT_TIMESTAMP, &avTimerTimestampNs) == 0
5438 && avTimerTimestampNs > 0) {
5439 psource_frame->nTimeStamp = avTimerTimestampNs / 1000;
5440 DEBUG_PRINT_LOW("C2d AVTimer TS : %llu us", (unsigned long long)psource_frame->nTimeStamp);
5441 }
5442 }
5443 }
5444 unsigned int buf_size = 0;
5445 buf_size = c2dcc.getBuffSize(C2D_OUTPUT);
5446 pdest_frame->nOffset = 0;
5447 pdest_frame->nFilledLen = buf_size;
5448 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
5449 pdest_frame->nFlags = psource_frame->nFlags;
5450 DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
5451 pdest_frame,
5452 (unsigned int)pdest_frame->nFilledLen);
5453 }
5454 ion_unmap(Input_pmem_info.fd, uva,Input_pmem_info.size);
5455 }
5456 }
5457 if (dev_use_buf(PORT_INDEX_IN) != true) {
5458 DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
5459 post_event ((unsigned long)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD);
5460 ret = OMX_ErrorBadParameter;
5461 }
5462 if (ret == OMX_ErrorNone)
5463 ret = empty_this_buffer_proxy(hComp,pdest_frame);
5464 if (ret == OMX_ErrorNone) {
5465 m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame);
5466 psource_frame = NULL;
5467 pdest_frame = NULL;
5468 if (!psource_frame && m_opq_meta_q.m_size) {
5469 m_opq_meta_q.pop_entry(&address,&p2,&id);
5470 psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
5471 }
5472 if (!pdest_frame && m_opq_pmem_q.m_size) {
5473 m_opq_pmem_q.pop_entry(&address,&p2,&id);
5474 pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
5475 DEBUG_PRINT_LOW("pdest_frame pop address is %p",pdest_frame);
5476 }
5477 } else {
5478 // there has been an error and source frame has been scheduled for an EBD
5479 psource_frame = NULL;
5480 }
5481 return ret;
5482 }
5483
5484 OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp)
5485 {
5486 unsigned long address = 0,p2,id, index = 0;
5487 OMX_ERRORTYPE ret = OMX_ErrorNone;
5488
5489 DEBUG_PRINT_LOW("In push input buffer");
5490 if (!psource_frame && m_opq_meta_q.m_size) {
5491 m_opq_meta_q.pop_entry(&address,&p2,&id);
5492 psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
5493 }
5494 if (!pdest_frame && m_opq_pmem_q.m_size) {
5495 m_opq_pmem_q.pop_entry(&address,&p2,&id);
5496 pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
5497 }
5498 while (psource_frame != NULL && pdest_frame != NULL &&
5499 ret == OMX_ErrorNone) {
5500 struct pmem Input_pmem_info;
5501 LEGACY_CAM_METADATA_TYPE *media_buffer;
5502 index = pdest_frame - m_inp_mem_ptr;
5503 if (index >= m_sInPortDef.nBufferCountActual) {
5504 DEBUG_PRINT_ERROR("Output buffer index is wrong %u act count %u",
5505 (unsigned int)index, (unsigned int)m_sInPortDef.nBufferCountActual);
5506 return OMX_ErrorBadParameter;
5507 }
5508
5509 if (psource_frame->nFilledLen == 0 && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
5510 return handle_empty_eos_buffer();
5511 }
5512 media_buffer = (LEGACY_CAM_METADATA_TYPE *)psource_frame->pBuffer;
5513 /*Will enable to verify camcorder in current TIPS can be removed*/
5514 if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
5515 Input_pmem_info.buffer = media_buffer;
5516 Input_pmem_info.fd = MetaBufferUtil::getFdAt(media_buffer->meta_handle, 0);
5517 Input_pmem_info.offset = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
5518 Input_pmem_info.size = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_SIZE);
5519 m_graphicbuffer_size = Input_pmem_info.size;
5520 DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
5521 Input_pmem_info.offset,
5522 Input_pmem_info.size);
5523 ret = queue_meta_buffer(hComp);
5524 } else {
5525 VideoGrallocMetadata *media_buffer = (VideoGrallocMetadata *)psource_frame->pBuffer;
5526 private_handle_t *handle = (private_handle_t *)media_buffer->pHandle;
5527
5528 Input_pmem_info.buffer = media_buffer;
5529 Input_pmem_info.fd = handle->fd;
5530 Input_pmem_info.offset = 0;
5531 Input_pmem_info.size = handle->size;
5532
5533 if (is_flip_conv_needed(handle)) {
5534 ret = do_flip_conversion(&Input_pmem_info);
5535 if (ret != OMX_ErrorNone) {
5536 return ret;
5537 }
5538 }
5539
5540 m_graphicbuffer_size = Input_pmem_info.size;
5541 if (is_conv_needed(handle))
5542 ret = convert_queue_buffer(hComp,Input_pmem_info,index);
5543 else
5544 ret = queue_meta_buffer(hComp);
5545 }
5546 }
5547 return ret;
5548 }
5549
5550 OMX_ERRORTYPE omx_video::handle_empty_eos_buffer(void)
5551 {
5552 if(!dev_handle_empty_eos_buffer())
5553 return OMX_ErrorHardware;
5554 else
5555 return OMX_ErrorNone;
5556 }
5557
5558 // no code beyond this !
5559
5560 // inline import of vendor extensions implementation
5561 #include "omx_video_extensions.hpp"
5562