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