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