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 native_handle_close(handle);
3700 native_handle_delete(handle);
3701 return OMX_ErrorInsufficientResources;
3702 }
3703 (*bufferHdr)->nAllocLen = sizeof(output_metabuffer);
3704 handle->data[0] = m_pOutput_pmem[i].fd;
3705 handle->data[1] = 0;
3706 handle->data[2] = 0;
3707 handle->data[3] = ALIGN(m_sOutPortDef.nBufferSize, 4096);
3708 output_metabuffer *buffer = (output_metabuffer*) m_pOutput_pmem[i].buffer;
3709 buffer->type = 1;
3710 buffer->nh = handle;
3711 }
3712 }
3713
3714 (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
3715 (*bufferHdr)->pAppPrivate = appData;
3716
3717 BITMASK_SET(&m_out_bm_count,i);
3718
3719 if (dev_use_buf(PORT_INDEX_OUT) != true) {
3720 DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for o/p buf");
3721 return OMX_ErrorInsufficientResources;
3722 }
3723 } else {
3724 DEBUG_PRINT_ERROR("ERROR: All o/p buffers are allocated, invalid allocate buf call"
3725 "for index [%d] actual: %u", i, (unsigned int)m_sOutPortDef.nBufferCountActual);
3726 }
3727 }
3728
3729 return eRet;
3730 }
3731
3732
3733 // AllocateBuffer -- API Call
3734 /* ======================================================================
3735 FUNCTION
3736 omx_video::AllocateBuffer
3737
3738 DESCRIPTION
3739 Returns zero if all the buffers released..
3740
3741 PARAMETERS
3742 None.
3743
3744 RETURN VALUE
3745 true/false
3746
3747 ========================================================================== */
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)3748 OMX_ERRORTYPE omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
3749 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3750 OMX_IN OMX_U32 port,
3751 OMX_IN OMX_PTR appData,
3752 OMX_IN OMX_U32 bytes)
3753 {
3754
3755 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
3756
3757 DEBUG_PRINT_LOW("Allocate buffer of size = %u on port %d", (unsigned int)bytes, (int)port);
3758 if (m_state == OMX_StateInvalid) {
3759 DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State");
3760 return OMX_ErrorInvalidState;
3761 }
3762 auto_lock l(m_buf_lock);
3763 // What if the client calls again.
3764 if (port == PORT_INDEX_IN) {
3765 #ifdef _ANDROID_ICS_
3766 if (meta_mode_enable)
3767 eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes);
3768 else
3769 #endif
3770 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
3771 } else if (port == PORT_INDEX_OUT) {
3772 eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
3773 } else {
3774 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port);
3775 eRet = OMX_ErrorBadPortIndex;
3776 }
3777 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
3778 if (eRet == OMX_ErrorNone) {
3779 if (allocate_done()) {
3780 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3781 // Send the callback now
3782 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
3783 post_event(OMX_CommandStateSet,OMX_StateIdle,
3784 OMX_COMPONENT_GENERATE_EVENT);
3785 }
3786 }
3787 if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) {
3788 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
3789 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
3790 post_event(OMX_CommandPortEnable,
3791 PORT_INDEX_IN,
3792 OMX_COMPONENT_GENERATE_EVENT);
3793 }
3794 }
3795 if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) {
3796 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
3797 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
3798 post_event(OMX_CommandPortEnable,
3799 PORT_INDEX_OUT,
3800 OMX_COMPONENT_GENERATE_EVENT);
3801 m_event_port_settings_sent = false;
3802 }
3803 }
3804 }
3805 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
3806 return eRet;
3807 }
3808
3809
3810 // Free Buffer - API call
3811 /* ======================================================================
3812 FUNCTION
3813 omx_video::FreeBuffer
3814
3815 DESCRIPTION
3816
3817 PARAMETERS
3818 None.
3819
3820 RETURN VALUE
3821 true/false
3822
3823 ========================================================================== */
free_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3824 OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
3825 OMX_IN OMX_U32 port,
3826 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3827 {
3828 (void)hComp;
3829 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3830 unsigned int nPortIndex;
3831
3832 DEBUG_PRINT_LOW("In for encoder free_buffer");
3833 auto_lock l(m_buf_lock);
3834 if (port == PORT_INDEX_OUT) { //client called freebuffer, clearing client buffer bitmask right away to avoid use after free
3835 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
3836 if(BITMASK_PRESENT(&m_client_out_bm_count, nPortIndex))
3837 BITMASK_CLEAR(&m_client_out_bm_count,nPortIndex);
3838 } else if (port == PORT_INDEX_IN) {
3839 nPortIndex = buffer - (meta_mode_enable?meta_buffer_hdr:m_inp_mem_ptr);
3840 if(BITMASK_PRESENT(&m_client_in_bm_count, nPortIndex))
3841 BITMASK_CLEAR(&m_client_in_bm_count,nPortIndex);
3842 }
3843 if (m_state == OMX_StateIdle &&
3844 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
3845 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
3846 } else if ((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)||
3847 (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) {
3848 DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
3849 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
3850 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled");
3851 m_buffer_freed = true;
3852 post_event(OMX_EventError,
3853 OMX_ErrorPortUnpopulated,
3854 OMX_COMPONENT_GENERATE_EVENT);
3855 return eRet;
3856 } else {
3857 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers");
3858 m_buffer_freed = true;
3859 post_event(OMX_EventError,
3860 OMX_ErrorPortUnpopulated,
3861 OMX_COMPONENT_GENERATE_EVENT);
3862 }
3863
3864 if (port == PORT_INDEX_IN) {
3865 // check if the buffer is valid
3866 nPortIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
3867
3868 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %u, actual cnt %u",
3869 nPortIndex, (unsigned int)m_sInPortDef.nBufferCountActual);
3870 if (nPortIndex < m_sInPortDef.nBufferCountActual &&
3871 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
3872 // Clear the bit associated with it.
3873 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
3874 free_input_buffer (buffer);
3875 m_sInPortDef.bPopulated = OMX_FALSE;
3876
3877 /*Free the Buffer Header*/
3878 if (release_input_done()) {
3879 input_use_buffer = false;
3880 // "m_inp_mem_ptr" may point to "meta_buffer_hdr" in some modes,
3881 // in which case, it was not explicitly allocated
3882 if (m_inp_mem_ptr && m_inp_mem_ptr != meta_buffer_hdr) {
3883 DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr");
3884 free (m_inp_mem_ptr);
3885 }
3886 m_inp_mem_ptr = NULL;
3887 if (m_pInput_pmem) {
3888 DEBUG_PRINT_LOW("Freeing m_pInput_pmem");
3889 free(m_pInput_pmem);
3890 m_pInput_pmem = NULL;
3891 }
3892 #ifdef USE_ION
3893 if (m_pInput_ion) {
3894 DEBUG_PRINT_LOW("Freeing m_pInput_ion");
3895 free(m_pInput_ion);
3896 m_pInput_ion = NULL;
3897 }
3898 #endif
3899 }
3900 } else {
3901 DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid");
3902 eRet = OMX_ErrorBadPortIndex;
3903 }
3904
3905 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
3906 && release_input_done()) {
3907 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
3908 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
3909 post_event(OMX_CommandPortDisable,
3910 PORT_INDEX_IN,
3911 OMX_COMPONENT_GENERATE_EVENT);
3912 }
3913 } else if (port == PORT_INDEX_OUT) {
3914 // check if the buffer is valid
3915 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
3916
3917 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %u, actual cnt %u",
3918 nPortIndex, (unsigned int)m_sOutPortDef.nBufferCountActual);
3919 if (nPortIndex < m_sOutPortDef.nBufferCountActual &&
3920 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
3921 // Clear the bit associated with it.
3922 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
3923 m_sOutPortDef.bPopulated = OMX_FALSE;
3924 free_output_buffer (buffer);
3925
3926 if (release_output_done()) {
3927 output_use_buffer = false;
3928 if (m_out_mem_ptr) {
3929 DEBUG_PRINT_LOW("Freeing m_out_mem_ptr");
3930 free (m_out_mem_ptr);
3931 m_out_mem_ptr = NULL;
3932 }
3933 if (m_pOutput_pmem) {
3934 DEBUG_PRINT_LOW("Freeing m_pOutput_pmem");
3935 free(m_pOutput_pmem);
3936 m_pOutput_pmem = NULL;
3937 }
3938 #ifdef USE_ION
3939 if (m_pOutput_ion) {
3940 DEBUG_PRINT_LOW("Freeing m_pOutput_ion");
3941 free(m_pOutput_ion);
3942 m_pOutput_ion = NULL;
3943 }
3944 #endif
3945 }
3946 } else {
3947 DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid");
3948 eRet = OMX_ErrorBadPortIndex;
3949 }
3950 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
3951 && release_output_done() ) {
3952 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
3953
3954 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
3955 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
3956 post_event(OMX_CommandPortDisable,
3957 PORT_INDEX_OUT,
3958 OMX_COMPONENT_GENERATE_EVENT);
3959
3960 }
3961 } else if (port == PORT_INDEX_EXTRADATA_OUT) {
3962 nPortIndex = buffer - m_client_output_extradata_mem_ptr;
3963 DEBUG_PRINT_LOW("free_buffer on extradata output port - Port idx %d", nPortIndex);
3964
3965 BITMASK_CLEAR(&m_out_extradata_bm_count,nPortIndex);
3966
3967 if (release_output_extradata_done()) {
3968 free_output_extradata_buffer_header();
3969 }
3970 } else if (port == PORT_INDEX_EXTRADATA_IN) {
3971 nPortIndex = buffer - m_client_input_extradata_mem_ptr;
3972 DEBUG_PRINT_LOW("free_buffer on extradata input port - Port idx %d", nPortIndex);
3973
3974 BITMASK_CLEAR(&m_in_extradata_bm_count,nPortIndex);
3975
3976 if (release_input_extradata_done()) {
3977 free_input_extradata_buffer_header();
3978 }
3979 } else {
3980 eRet = OMX_ErrorBadPortIndex;
3981 }
3982 if ((eRet == OMX_ErrorNone) &&
3983 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
3984 if (release_done()) {
3985 if (dev_stop() != 0) {
3986 DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED");
3987 eRet = OMX_ErrorHardware;
3988 }
3989 // Send the callback now
3990 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
3991 post_event(OMX_CommandStateSet, OMX_StateLoaded,
3992 OMX_COMPONENT_GENERATE_EVENT);
3993 } else {
3994 DEBUG_PRINT_HIGH("in free buffer, release not done, need to free more buffers output %" PRIx64" input %" PRIx64,
3995 m_out_bm_count, m_inp_bm_count);
3996 }
3997 }
3998 if (eRet != OMX_ErrorNone) {
3999 m_buffer_freed = true;
4000 }
4001
4002 return eRet;
4003 }
4004
free_output_extradata_buffer_header()4005 void omx_video::free_output_extradata_buffer_header() {
4006 m_sExtraData = false;
4007 if (m_client_output_extradata_mem_ptr) {
4008 DEBUG_PRINT_LOW("Free extradata pmem Pointer area");
4009 free(m_client_output_extradata_mem_ptr);
4010 m_client_output_extradata_mem_ptr = NULL;
4011 }
4012 }
4013
free_input_extradata_buffer_header()4014 void omx_video::free_input_extradata_buffer_header() {
4015 m_sExtraData = false;
4016 if (m_client_input_extradata_mem_ptr) {
4017 DEBUG_PRINT_LOW("Free extradata pmem Pointer area");
4018 free(m_client_input_extradata_mem_ptr);
4019 m_client_input_extradata_mem_ptr = NULL;
4020 }
4021 }
4022
4023 /* ======================================================================
4024 FUNCTION
4025 omx_video::EmptyThisBuffer
4026
4027 DESCRIPTION
4028 This routine is used to push the encoded video frames to
4029 the video decoder.
4030
4031 PARAMETERS
4032 None.
4033
4034 RETURN VALUE
4035 OMX Error None if everything went successful.
4036
4037 ========================================================================== */
empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)4038 OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
4039 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4040 {
4041 if(buffer != NULL && buffer->nInputPortIndex == PORT_INDEX_EXTRADATA_IN) {
4042 if(!dev_handle_client_input_extradata(buffer)) {
4043 DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> handling client extradata failed");
4044 return OMX_ErrorMax;
4045 }
4046 return OMX_ErrorNone;
4047 }
4048 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
4049 unsigned int nBufferIndex ;
4050
4051 if (m_state != OMX_StateExecuting &&
4052 m_state != OMX_StatePause &&
4053 m_state != OMX_StateIdle) {
4054 DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State");
4055 return OMX_ErrorInvalidState;
4056 }
4057
4058 if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
4059 DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> buffer is null or buffer size is invalid");
4060 return OMX_ErrorBadParameter;
4061 }
4062
4063 if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
4064 DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> OMX Version Invalid");
4065 return OMX_ErrorVersionMismatch;
4066 }
4067
4068 DEBUG_PRINT_LOW("ETB: buffer = %p, buffer->pBuffer[%p]", buffer, buffer->pBuffer);
4069 if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) {
4070 DEBUG_PRINT_ERROR("ERROR: Bad port index to call empty_this_buffer");
4071 return OMX_ErrorBadPortIndex;
4072 }
4073 if (!m_sInPortDef.bEnabled) {
4074 DEBUG_PRINT_ERROR("ERROR: Cannot call empty_this_buffer while I/P port is disabled");
4075 return OMX_ErrorIncorrectStateOperation;
4076 }
4077
4078 nBufferIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
4079
4080 if (nBufferIndex > m_sInPortDef.nBufferCountActual ) {
4081 DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]", nBufferIndex);
4082 return OMX_ErrorBadParameter;
4083 }
4084
4085 m_etb_count++;
4086 m_etb_timestamp = buffer->nTimeStamp;
4087 DEBUG_PRINT_LOW("DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp);
4088 post_event ((unsigned long)hComp,(unsigned long)buffer,m_input_msg_id);
4089 return OMX_ErrorNone;
4090 }
4091
profile_etb()4092 bool omx_video::profile_etb() {
4093 if (profile_mode) {
4094 struct timeval act_time = {0, 0};
4095 gettimeofday(&act_time, NULL);
4096 if (profile_start_time == 0) {
4097 profile_start_time = (act_time.tv_usec + act_time.tv_sec * 1e6);
4098 } else {
4099 profile_last_time = (act_time.tv_usec + act_time.tv_sec * 1e6);
4100 }
4101 profile_frame_count++;
4102 return true;
4103 }
4104 return false;
4105 }
4106
4107 /* ======================================================================
4108 FUNCTION
4109 omx_video::empty_this_buffer_proxy
4110
4111 DESCRIPTION
4112 This routine is used to push the encoded video frames to
4113 the video decoder.
4114
4115 PARAMETERS
4116 None.
4117
4118 RETURN VALUE
4119 OMX Error None if everything went successful.
4120
4121 ========================================================================== */
empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)4122 OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
4123 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4124 {
4125 VIDC_TRACE_NAME_HIGH("ETB");
4126 (void)hComp;
4127 OMX_U8 *pmem_data_buf = NULL;
4128 int push_cnt = 0;
4129 unsigned nBufIndex = 0;
4130 OMX_ERRORTYPE ret = OMX_ErrorNone;
4131 LEGACY_CAM_METADATA_TYPE *media_buffer = NULL;
4132
4133 int fd = 0;
4134
4135 DEBUG_PRINT_LOW("ETBProxy: buffer->pBuffer[%p]", buffer->pBuffer);
4136 if (buffer == NULL) {
4137 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid buffer[%p]", buffer);
4138 return OMX_ErrorBadParameter;
4139 }
4140
4141 if (profile_etb()) {
4142 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4143 return OMX_ErrorNone;
4144 }
4145
4146 // Buffer sanity checks
4147 if (meta_mode_enable && !mUsesColorConversion) {
4148 //For color-conversion case, we have an internal buffer and not a meta buffer
4149 bool met_error = false;
4150 nBufIndex = buffer - meta_buffer_hdr;
4151 if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
4152 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid meta-bufIndex = %u", nBufIndex);
4153 return OMX_ErrorBadParameter;
4154 }
4155 media_buffer = (LEGACY_CAM_METADATA_TYPE *)meta_buffer_hdr[nBufIndex].pBuffer;
4156 if (!media_buffer) {
4157 DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
4158 return OMX_ErrorBadParameter;
4159 }
4160 if ((media_buffer->buffer_type == LEGACY_CAM_SOURCE)
4161 && buffer->nAllocLen != sizeof(LEGACY_CAM_METADATA_TYPE)) {
4162 DEBUG_PRINT_ERROR("Invalid metadata size expected(%u) v/s recieved(%zu)",
4163 buffer->nAllocLen, sizeof(LEGACY_CAM_METADATA_TYPE));
4164 met_error = true;
4165 } else if (media_buffer) {
4166 if (media_buffer->buffer_type != LEGACY_CAM_SOURCE &&
4167 media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) {
4168 DEBUG_PRINT_ERROR("Buffer type is neither LEGACY_CAM_SOURCE nor gralloc source");
4169 met_error = true;
4170 } else {
4171 if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
4172 if (media_buffer->meta_handle == NULL) {
4173 DEBUG_PRINT_ERROR("Buffer type is LEGACY_CAM_SOURCE but handle is null");
4174 met_error = true;
4175 }
4176 else {
4177 // TBD: revisit this check !
4178 int nFds = media_buffer->meta_handle->numFds,
4179 nInt = media_buffer->meta_handle->numInts;
4180 met_error = ((nFds == 1 && nInt >= 2) /*normal*/ ||
4181 (nFds < 16 && nInt >= nFds*3) /*batch*/) ? false : true;
4182 if (met_error) {
4183 DEBUG_PRINT_ERROR("Unbalanced fds in handle: fds=%d ints=%d",
4184 nFds, nInt);
4185 }
4186 }
4187 }
4188 }
4189 } else {
4190 met_error = true;
4191 DEBUG_PRINT_ERROR("Unrecognized camera source type");
4192 }
4193 if (met_error) {
4194 DEBUG_PRINT_ERROR("ERROR: Unkown source/metahandle in ETB call");
4195 post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
4196 return OMX_ErrorBadParameter;
4197 }
4198 } else {
4199 nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
4200 if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
4201 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid bufIndex = %u", nBufIndex);
4202 return OMX_ErrorBadParameter;
4203 }
4204 }
4205
4206 if (buffer->nFilledLen == 0 && (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
4207 DEBUG_PRINT_LOW("Zero length EOS buffer");
4208 handle_empty_eos_buffer();
4209 post_event ((unsigned long)buffer,0,
4210 OMX_COMPONENT_GENERATE_EBD);
4211 return OMX_ErrorNone;
4212 }
4213
4214 pending_input_buffers++;
4215 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
4216 if (input_flush_progress == true) {
4217 post_event ((unsigned long)buffer,0,
4218 OMX_COMPONENT_GENERATE_EBD);
4219 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Input flush in progress");
4220 return OMX_ErrorNone;
4221 }
4222 if (!meta_mode_enable) {
4223 fd = m_pInput_pmem[nBufIndex].fd;
4224 }
4225 #ifdef _ANDROID_ICS_
4226 if (meta_mode_enable && !mUsesColorConversion) {
4227 // Camera or Gralloc-source meta-buffers queued with encodeable color-format
4228 struct pmem Input_pmem_info;
4229 if (!media_buffer) {
4230 DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
4231 return OMX_ErrorBadParameter;
4232 }
4233 if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
4234 Input_pmem_info.buffer = media_buffer;
4235 Input_pmem_info.fd = MetaBufferUtil::getFdAt(media_buffer->meta_handle, 0);
4236 fd = Input_pmem_info.fd;
4237
4238 int offset = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
4239 int size = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_SIZE);
4240 if (offset < 0 || size < 0) {
4241 DEBUG_PRINT_ERROR("meta-buffer is invalid!");
4242 return OMX_ErrorBadParameter;
4243 }
4244 Input_pmem_info.offset = offset;
4245 Input_pmem_info.size = size;
4246 DEBUG_PRINT_HIGH("ETB (meta-Camera) fd = %d, offset = %d, size = %d",
4247 Input_pmem_info.fd, Input_pmem_info.offset,
4248 Input_pmem_info.size);
4249 } else {
4250 VideoGrallocMetadata *media_buffer = (VideoGrallocMetadata *)meta_buffer_hdr[nBufIndex].pBuffer;
4251 private_handle_t *handle = (private_handle_t *)media_buffer->pHandle;
4252 Input_pmem_info.buffer = media_buffer;
4253 Input_pmem_info.fd = handle->fd;
4254 fd = Input_pmem_info.fd;
4255 Input_pmem_info.offset = 0;
4256 Input_pmem_info.size = handle->size;
4257 DEBUG_PRINT_LOW("ETB (meta-gralloc) fd = %d, offset = %d, size = %d",
4258 Input_pmem_info.fd, Input_pmem_info.offset,
4259 Input_pmem_info.size);
4260 // if input buffer dimensions is different from what is configured,
4261 // reject the buffer
4262 if (ALIGN((int)m_sInPortDef.format.video.nFrameWidth,32) != ALIGN(handle->unaligned_width,32) ||
4263 ALIGN((int)m_sInPortDef.format.video.nFrameHeight,32) != ALIGN(handle->unaligned_height,32)) {
4264 ALOGE("Graphic buf size(%dx%d) does not match configured size(%ux%u)",
4265 handle->unaligned_width, handle->unaligned_height,
4266 m_sInPortDef.format.video.nFrameWidth, m_sInPortDef.format.video.nFrameHeight);
4267 post_event ((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD);
4268 return OMX_ErrorNone;
4269 }
4270 }
4271 if (dev_use_buf(PORT_INDEX_IN) != true) {
4272 DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
4273 post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
4274 return OMX_ErrorBadParameter;
4275 }
4276 } else if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
4277 #else
4278 if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
4279 #endif
4280 {
4281 DEBUG_PRINT_LOW("Heap UseBuffer case, so memcpy the data");
4282
4283 auto_lock l(m_buf_lock);
4284 pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
4285 if (pmem_data_buf && BITMASK_PRESENT(&m_client_in_bm_count, nBufIndex)) {
4286 memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
4287 buffer->nFilledLen);
4288 }
4289 DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
4290 } else if (mUseProxyColorFormat) {
4291 // Gralloc-source buffers with color-conversion
4292 fd = m_pInput_pmem[nBufIndex].fd;
4293 DEBUG_PRINT_LOW("ETB (color-converted) fd = %d, size = %u",
4294 fd, (unsigned int)buffer->nFilledLen);
4295 } else if (m_sInPortDef.format.video.eColorFormat ==
4296 OMX_COLOR_FormatYUV420SemiPlanar) {
4297 //For the case where YUV420SP buffers are qeueued to component
4298 //by sources other than camera (Apps via MediaCodec), conversion
4299 //to vendor flavoured NV12 color format is required.
4300 if (!dev_color_align(buffer, m_sInPortDef.format.video.nFrameWidth,
4301 m_sInPortDef.format.video.nFrameHeight)) {
4302 DEBUG_PRINT_ERROR("Failed to adjust buffer color");
4303 post_event((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD);
4304 return OMX_ErrorUndefined;
4305 }
4306 }
4307 if (dev_empty_buf(buffer, pmem_data_buf,nBufIndex,fd) != true)
4308 {
4309 DEBUG_PRINT_ERROR("ERROR: ETBProxy: dev_empty_buf failed");
4310 #ifdef _ANDROID_ICS_
4311 omx_release_meta_buffer(buffer);
4312 #endif
4313 post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
4314 /*Generate an async error and move to invalid state*/
4315 pending_input_buffers--;
4316 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
4317 if (hw_overload) {
4318 return OMX_ErrorInsufficientResources;
4319 }
4320 return OMX_ErrorBadParameter;
4321 }
4322 return ret;
4323 }
4324
4325 /* ======================================================================
4326 FUNCTION
4327 omx_video::FillThisBuffer
4328
4329 DESCRIPTION
4330 IL client uses this method to release the frame buffer
4331 after displaying them.
4332
4333 PARAMETERS
4334 None.
4335
4336 RETURN VALUE
4337 true/false
4338
4339 ========================================================================== */
fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)4340 OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
4341 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4342 {
4343 if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
4344 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size");
4345 return OMX_ErrorBadParameter;
4346 }
4347
4348 DEBUG_PRINT_LOW("FTB: buffer->pBuffer[%p]", buffer->pBuffer);
4349
4350 if (m_state != OMX_StateExecuting &&
4351 m_state != OMX_StatePause &&
4352 m_state != OMX_StateIdle) {
4353 DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State");
4354 return OMX_ErrorInvalidState;
4355 }
4356
4357 if (buffer->nOutputPortIndex == PORT_INDEX_EXTRADATA_OUT) {
4358 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->invalid port in header");
4359 return OMX_ErrorBadParameter;
4360 }
4361
4362 if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
4363 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid");
4364 return OMX_ErrorVersionMismatch;
4365 }
4366
4367 if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) {
4368 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index");
4369 return OMX_ErrorBadPortIndex;
4370 }
4371
4372 if (!m_sOutPortDef.bEnabled) {
4373 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled");
4374 return OMX_ErrorIncorrectStateOperation;
4375 }
4376
4377 post_event((unsigned long) hComp, (unsigned long)buffer,OMX_COMPONENT_GENERATE_FTB);
4378 return OMX_ErrorNone;
4379 }
4380
4381 /* ======================================================================
4382 FUNCTION
4383 omx_video::fill_this_buffer_proxy
4384
4385 DESCRIPTION
4386 IL client uses this method to release the frame buffer
4387 after displaying them.
4388
4389 PARAMETERS
4390 None.
4391
4392 RETURN VALUE
4393 true/false
4394
4395 ========================================================================== */
fill_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * bufferAdd)4396 OMX_ERRORTYPE omx_video::fill_this_buffer_proxy(
4397 OMX_IN OMX_HANDLETYPE hComp,
4398 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
4399 {
4400 VIDC_TRACE_NAME_HIGH("FTB");
4401 (void)hComp;
4402 OMX_U8 *pmem_data_buf = NULL;
4403 OMX_ERRORTYPE nRet = OMX_ErrorNone;
4404 auto_lock l(m_buf_lock);
4405 if (m_buffer_freed == true) {
4406 DEBUG_PRINT_ERROR("ERROR: FTBProxy: Invalid call. Called after freebuffer");
4407 return OMX_ErrorBadParameter;
4408 }
4409
4410 if (bufferAdd != NULL) {
4411 DEBUG_PRINT_LOW("FTBProxy: bufferAdd->pBuffer[%p]", bufferAdd->pBuffer);
4412 }
4413 if (bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= (int)m_sOutPortDef.nBufferCountActual) ) {
4414 DEBUG_PRINT_ERROR("ERROR: FTBProxy: Invalid i/p params");
4415 return OMX_ErrorBadParameter;
4416 }
4417
4418 pending_output_buffers++;
4419 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
4420 /*Return back the output buffer to client*/
4421 if ( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) {
4422 DEBUG_PRINT_LOW("o/p port is Disabled or Flush in Progress");
4423 post_event ((unsigned long)bufferAdd,0,
4424 OMX_COMPONENT_GENERATE_FBD);
4425 return OMX_ErrorNone;
4426 }
4427
4428 if (output_use_buffer && !m_use_output_pmem) {
4429 DEBUG_PRINT_LOW("Heap UseBuffer case");
4430 pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer;
4431 }
4432
4433 if (dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) {
4434 DEBUG_PRINT_ERROR("ERROR: dev_fill_buf() Failed");
4435 post_event ((unsigned long)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD);
4436 pending_output_buffers--;
4437 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
4438 return OMX_ErrorBadParameter;
4439 }
4440
4441 return OMX_ErrorNone;
4442 }
4443
4444 /* ======================================================================
4445 FUNCTION
4446 omx_video::SetCallbacks
4447
4448 DESCRIPTION
4449 Set the callbacks.
4450
4451 PARAMETERS
4452 None.
4453
4454 RETURN VALUE
4455 OMX Error None if everything successful.
4456
4457 ========================================================================== */
set_callbacks(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_CALLBACKTYPE * callbacks,OMX_IN OMX_PTR appData)4458 OMX_ERRORTYPE omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
4459 OMX_IN OMX_CALLBACKTYPE* callbacks,
4460 OMX_IN OMX_PTR appData)
4461 {
4462 (void)hComp;
4463
4464 if (!callbacks)
4465 return OMX_ErrorBadParameter;
4466
4467 m_pCallbacks = *callbacks;
4468 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\
4469 m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone);
4470 m_app_data = appData;
4471 return OMX_ErrorNone;
4472 }
4473
4474
4475 /* ======================================================================
4476 FUNCTION
4477 omx_venc::UseEGLImage
4478
4479 DESCRIPTION
4480 OMX Use EGL Image method implementation <TBD>.
4481
4482 PARAMETERS
4483 <TBD>.
4484
4485 RETURN VALUE
4486 Not Implemented error.
4487
4488 ========================================================================== */
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)4489 OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
4490 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4491 OMX_IN OMX_U32 port,
4492 OMX_IN OMX_PTR appData,
4493 OMX_IN void* eglImage)
4494 {
4495 (void)hComp, (void)bufferHdr, (void)port, (void)appData, (void)eglImage;
4496 DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented");
4497 return OMX_ErrorNotImplemented;
4498 }
4499
4500 /* ======================================================================
4501 FUNCTION
4502 omx_venc::ComponentRoleEnum
4503
4504 DESCRIPTION
4505 OMX Component Role Enum method implementation.
4506
4507 PARAMETERS
4508 <TBD>.
4509
4510 RETURN VALUE
4511 OMX Error None if everything is successful.
4512 ========================================================================== */
component_role_enum(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_U8 * role,OMX_IN OMX_U32 index)4513 OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
4514 OMX_OUT OMX_U8* role,
4515 OMX_IN OMX_U32 index)
4516 {
4517 (void)hComp;
4518 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4519 if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
4520 if ((0 == index) && role) {
4521 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
4522 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
4523 } else {
4524 DEBUG_PRINT_ERROR("ERROR: No more roles");
4525 eRet = OMX_ErrorNoMore;
4526 }
4527 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
4528 if ((0 == index) && role) {
4529 strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
4530 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
4531 } else {
4532 DEBUG_PRINT_ERROR("ERROR: No more roles");
4533 eRet = OMX_ErrorNoMore;
4534 }
4535 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
4536 if ((0 == index) && role) {
4537 strlcpy((char *)role, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE);
4538 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
4539 } else {
4540 DEBUG_PRINT_ERROR("ERROR: No more roles");
4541 eRet = OMX_ErrorNoMore;
4542 }
4543 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE) ||
4544 !strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc.cq", OMX_MAX_STRINGNAME_SIZE) ||
4545 !strncmp((char*)m_nkind, "OMX.qcom.video.encoder.heic", OMX_MAX_STRINGNAME_SIZE)) {
4546 if ((0 == index) && role) {
4547 strlcpy((char *)role, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
4548 DEBUG_PRINT_LOW("component_role_enum: role %s", role);
4549 } else {
4550 DEBUG_PRINT_ERROR("ERROR: No more roles");
4551 eRet = OMX_ErrorNoMore;
4552 }
4553 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.tme", OMX_MAX_STRINGNAME_SIZE)) {
4554 if ((0 == index) && role) {
4555 strlcpy((char *)role, "video_encoder.tme", OMX_MAX_STRINGNAME_SIZE);
4556 DEBUG_PRINT_LOW("component_role_enum: role %s", role);
4557 } else {
4558 DEBUG_PRINT_ERROR("ERROR: No more roles");
4559 eRet = OMX_ErrorNoMore;
4560 }
4561 }
4562 else {
4563 DEBUG_PRINT_ERROR("ERROR: Querying Role on Unknown Component");
4564 eRet = OMX_ErrorInvalidComponentName;
4565 }
4566 return eRet;
4567 }
4568
4569
4570
4571
4572 /* ======================================================================
4573 FUNCTION
4574 omx_venc::AllocateDone
4575
4576 DESCRIPTION
4577 Checks if entire buffer pool is allocated by IL Client or not.
4578 Need this to move to IDLE state.
4579
4580 PARAMETERS
4581 None.
4582
4583 RETURN VALUE
4584 true/false.
4585
4586 ========================================================================== */
allocate_done(void)4587 bool omx_video::allocate_done(void)
4588 {
4589 bool bRet = false;
4590 bool bRet_In = false;
4591 bool bRet_Out = false;
4592 bool bRet_Out_Extra = false;
4593 bool bRet_In_Extra = false;
4594
4595 bRet_In = allocate_input_done();
4596 bRet_Out = allocate_output_done();
4597 bRet_In_Extra = allocate_input_extradata_done();
4598 bRet_Out_Extra = allocate_output_extradata_done();
4599
4600 if (bRet_In && bRet_Out && bRet_Out_Extra && bRet_In_Extra) {
4601 bRet = true;
4602 }
4603
4604 return bRet;
4605 }
4606 /* ======================================================================
4607 FUNCTION
4608 omx_venc::AllocateInputDone
4609
4610 DESCRIPTION
4611 Checks if I/P buffer pool is allocated by IL Client or not.
4612
4613 PARAMETERS
4614 None.
4615
4616 RETURN VALUE
4617 true/false.
4618
4619 ========================================================================== */
allocate_input_done(void)4620 bool omx_video::allocate_input_done(void)
4621 {
4622 bool bRet = false;
4623 unsigned i=0;
4624
4625 if (m_inp_mem_ptr == NULL) {
4626 return bRet;
4627 }
4628 if (m_inp_mem_ptr ) {
4629 for (; i<m_sInPortDef.nBufferCountActual; i++) {
4630 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4631 break;
4632 }
4633 }
4634 }
4635 if (i==m_sInPortDef.nBufferCountActual) {
4636 bRet = true;
4637 }
4638 if (i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled) {
4639 m_sInPortDef.bPopulated = OMX_TRUE;
4640 }
4641 return bRet;
4642 }
4643 /* ======================================================================
4644 FUNCTION
4645 omx_venc::AllocateOutputDone
4646
4647 DESCRIPTION
4648 Checks if entire O/P buffer pool is allocated by IL Client or not.
4649
4650 PARAMETERS
4651 None.
4652
4653 RETURN VALUE
4654 true/false.
4655
4656 ========================================================================== */
allocate_output_done(void)4657 bool omx_video::allocate_output_done(void)
4658 {
4659 bool bRet = false;
4660 unsigned j=0;
4661
4662 if (m_out_mem_ptr == NULL) {
4663 return bRet;
4664 }
4665
4666 if (m_out_mem_ptr ) {
4667 for (; j<m_sOutPortDef.nBufferCountActual; j++) {
4668 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
4669 break;
4670 }
4671 }
4672 }
4673
4674 if (j==m_sOutPortDef.nBufferCountActual) {
4675 bRet = true;
4676 }
4677
4678 if (j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled) {
4679 m_sOutPortDef.bPopulated = OMX_TRUE;
4680 }
4681 return bRet;
4682 }
4683
allocate_output_extradata_done(void)4684 bool omx_video::allocate_output_extradata_done(void) {
4685 bool bRet = false;
4686 unsigned j=0;
4687 unsigned nBufferCount = 0;
4688
4689 nBufferCount = m_client_out_extradata_info.getBufferCount();
4690
4691 if (!m_client_out_extradata_info.is_client_extradata_enabled()) {
4692 return true;
4693 }
4694
4695 if (m_client_output_extradata_mem_ptr) {
4696 for (; j < nBufferCount; j++) {
4697 if (BITMASK_ABSENT(&m_out_extradata_bm_count,j)) {
4698 break;
4699 }
4700 }
4701
4702 if (j == nBufferCount) {
4703 bRet = true;
4704 DEBUG_PRINT_HIGH("Allocate done for all extradata o/p buffers");
4705 }
4706 }
4707
4708 return bRet;
4709 }
4710
allocate_input_extradata_done(void)4711 bool omx_video::allocate_input_extradata_done(void) {
4712 bool bRet = false;
4713 unsigned j=0;
4714 unsigned nBufferCount = 0;
4715
4716 nBufferCount = m_client_in_extradata_info.getBufferCount();
4717
4718 if (!m_client_in_extradata_info.is_client_extradata_enabled()) {
4719 return true;
4720 }
4721
4722 if (m_client_input_extradata_mem_ptr) {
4723 for (; j < nBufferCount; j++) {
4724 if (BITMASK_ABSENT(&m_in_extradata_bm_count,j)) {
4725 break;
4726 }
4727 }
4728
4729 if (j == nBufferCount) {
4730 bRet = true;
4731 DEBUG_PRINT_HIGH("Allocate done for all extradata i/p buffers");
4732 }
4733 }
4734
4735 return bRet;
4736 }
4737
4738 /* ======================================================================
4739 FUNCTION
4740 omx_venc::ReleaseDone
4741
4742 DESCRIPTION
4743 Checks if IL client has released all the buffers.
4744
4745 PARAMETERS
4746 None.
4747
4748 RETURN VALUE
4749 true/false
4750
4751 ========================================================================== */
release_done(void)4752 bool omx_video::release_done(void)
4753 {
4754 bool bRet = false;
4755 DEBUG_PRINT_LOW("Inside release_done()");
4756 if (release_input_done()) {
4757 if (release_output_done()) {
4758 if (release_output_extradata_done()) {
4759 bRet = true;
4760 }
4761 }
4762 }
4763 return bRet;
4764 }
4765
4766
4767 /* ======================================================================
4768 FUNCTION
4769 omx_venc::ReleaseOutputDone
4770
4771 DESCRIPTION
4772 Checks if IL client has released all the buffers.
4773
4774 PARAMETERS
4775 None.
4776
4777 RETURN VALUE
4778 true/false
4779
4780 ========================================================================== */
release_output_done(void)4781 bool omx_video::release_output_done(void)
4782 {
4783 bool bRet = false;
4784 unsigned i=0,j=0;
4785
4786 DEBUG_PRINT_LOW("Inside release_output_done()");
4787 if (m_out_mem_ptr) {
4788 for (; j<m_sOutPortDef.nBufferCountActual; j++) {
4789 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
4790 break;
4791 }
4792 }
4793 if (j==m_sOutPortDef.nBufferCountActual) {
4794 bRet = true;
4795 }
4796 } else {
4797 bRet = true;
4798 }
4799 return bRet;
4800 }
4801 /* ======================================================================
4802 FUNCTION
4803 omx_venc::ReleaseInputDone
4804
4805 DESCRIPTION
4806 Checks if IL client has released all the buffers.
4807
4808 PARAMETERS
4809 None.
4810
4811 RETURN VALUE
4812 true/false
4813
4814 ========================================================================== */
release_input_done(void)4815 bool omx_video::release_input_done(void)
4816 {
4817 bool bRet = false;
4818 unsigned i=0,j=0;
4819
4820 DEBUG_PRINT_LOW("Inside release_input_done()");
4821 if (m_inp_mem_ptr) {
4822 for (; j<m_sInPortDef.nBufferCountActual; j++) {
4823 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
4824 break;
4825 }
4826 }
4827 if (j==m_sInPortDef.nBufferCountActual) {
4828 bRet = true;
4829 }
4830 } else {
4831 bRet = true;
4832 }
4833 return bRet;
4834 }
4835
release_output_extradata_done(void)4836 bool omx_video::release_output_extradata_done(void) {
4837 bool bRet = false;
4838 unsigned i=0,j=0, buffer_count=0;
4839
4840 buffer_count = m_client_out_extradata_info.getBufferCount();
4841 DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d",
4842 m_client_output_extradata_mem_ptr, buffer_count);
4843
4844 if (m_client_output_extradata_mem_ptr) {
4845 for (; j<buffer_count; j++) {
4846 if ( BITMASK_PRESENT(&m_out_extradata_bm_count,j)) {
4847 break;
4848 }
4849 }
4850 if (j == buffer_count) {
4851 bRet = true;
4852 }
4853 } else {
4854 bRet = true;
4855 }
4856 return bRet;
4857 }
4858
release_input_extradata_done(void)4859 bool omx_video::release_input_extradata_done(void) {
4860 bool bRet = false;
4861 unsigned i=0,j=0, buffer_count=0;
4862
4863 buffer_count = m_client_in_extradata_info.getBufferCount();
4864 DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d",
4865 m_client_input_extradata_mem_ptr, buffer_count);
4866
4867 if (m_client_input_extradata_mem_ptr) {
4868 for (; j<buffer_count; j++) {
4869 if ( BITMASK_PRESENT(&m_in_extradata_bm_count,j)) {
4870 break;
4871 }
4872 }
4873 if (j == buffer_count) {
4874 bRet = true;
4875 }
4876 } else {
4877 bRet = true;
4878 }
4879 return bRet;
4880 }
4881
fill_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)4882 OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp,
4883 OMX_BUFFERHEADERTYPE * buffer)
4884 {
4885 VIDC_TRACE_NAME_HIGH("FBD");
4886 int index = buffer - m_out_mem_ptr;
4887
4888 DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x size = %u",
4889 buffer->pBuffer, (unsigned)buffer->nFlags, (unsigned int)buffer->nFilledLen);
4890 if (buffer == NULL || ((buffer - m_out_mem_ptr) > (int)m_sOutPortDef.nBufferCountActual)) {
4891 return OMX_ErrorBadParameter;
4892 }
4893
4894 pending_output_buffers--;
4895 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
4896 VIDC_TRACE_INT_LOW("FBD-TS", buffer->nTimeStamp / 1000);
4897 VIDC_TRACE_INT_LOW("FBD-size", buffer->nFilledLen);
4898
4899 if (secure_session && m_pCallbacks.FillBufferDone) {
4900 if (buffer->nFilledLen > 0)
4901 m_fbd_count++;
4902 m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
4903 return OMX_ErrorNone;
4904 }
4905
4906 /* For use buffer we need to copy the data */
4907 if (m_pCallbacks.FillBufferDone) {
4908 if (buffer->nFilledLen > 0) {
4909 m_fbd_count++;
4910
4911 if (dev_get_output_log_flag()) {
4912 do_cache_operations(m_pOutput_ion[index].data_fd);
4913 dev_output_log_buffers((const char*)buffer->pBuffer + buffer->nOffset, buffer->nFilledLen,
4914 buffer->nTimeStamp);
4915 do_cache_operations(m_pOutput_ion[index].data_fd);
4916
4917 }
4918 }
4919 if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
4920 if (!dev_handle_output_extradata((void *)buffer, index))
4921 DEBUG_PRINT_ERROR("Failed to parse output extradata");
4922
4923 dev_extradata_log_buffers((char *)(((unsigned long)buffer->pBuffer + buffer->nOffset +
4924 buffer->nFilledLen + 3) & (~3)), false);
4925 }
4926 m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
4927 } else {
4928 return OMX_ErrorBadParameter;
4929 }
4930 return OMX_ErrorNone;
4931 }
4932
empty_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)4933 OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp,
4934 OMX_BUFFERHEADERTYPE* buffer)
4935 {
4936 VIDC_TRACE_NAME_HIGH("EBD");
4937 int buffer_index = -1;
4938
4939 buffer_index = buffer - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr);
4940 DEBUG_PRINT_LOW("empty_buffer_done: buffer[%p]", buffer);
4941 if (buffer == NULL ||
4942 ((buffer_index > (int)m_sInPortDef.nBufferCountActual))) {
4943 DEBUG_PRINT_ERROR("ERROR in empty_buffer_done due to index buffer");
4944 return OMX_ErrorBadParameter;
4945 }
4946
4947 pending_input_buffers--;
4948 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
4949
4950 if (mUseProxyColorFormat &&
4951 (buffer_index >= 0 && (buffer_index < (int)m_sInPortDef.nBufferCountActual))) {
4952 if (!pdest_frame && !input_flush_progress && mUsesColorConversion) {
4953 pdest_frame = buffer;
4954 DEBUG_PRINT_LOW("empty_buffer_done pdest_frame address is %p",pdest_frame);
4955 return push_input_buffer(hComp);
4956 }
4957 if (mUsesColorConversion) {
4958 // return color-conversion buffer back to the pool
4959 DEBUG_PRINT_LOW("empty_buffer_done insert address is %p",buffer);
4960 if (!m_opq_pmem_q.insert_entry((unsigned long)buffer, 0, 0)) {
4961 DEBUG_PRINT_ERROR("empty_buffer_done: pmem queue is full");
4962 return OMX_ErrorBadParameter;
4963 }
4964 } else {
4965 // We are not dealing with color-conversion, Buffer being returned
4966 // here is client's buffer, return it back to client
4967 if (m_pCallbacks.EmptyBufferDone && buffer) {
4968 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
4969 DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p", buffer);
4970 }
4971 }
4972 } else if (m_pCallbacks.EmptyBufferDone) {
4973 m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
4974 }
4975 return OMX_ErrorNone;
4976 }
4977
complete_pending_buffer_done_cbs()4978 void omx_video::complete_pending_buffer_done_cbs()
4979 {
4980 unsigned long p1;
4981 unsigned long p2;
4982 unsigned long ident;
4983 omx_cmd_queue tmp_q, pending_bd_q;
4984 pthread_mutex_lock(&m_lock);
4985 // pop all pending GENERATE FDB from ftb queue
4986 while (m_ftb_q.m_size) {
4987 m_ftb_q.pop_entry(&p1,&p2,&ident);
4988 if (ident == OMX_COMPONENT_GENERATE_FBD) {
4989 pending_bd_q.insert_entry(p1,p2,ident);
4990 } else {
4991 tmp_q.insert_entry(p1,p2,ident);
4992 }
4993 }
4994 //return all non GENERATE FDB to ftb queue
4995 while (tmp_q.m_size) {
4996 tmp_q.pop_entry(&p1,&p2,&ident);
4997 m_ftb_q.insert_entry(p1,p2,ident);
4998 }
4999 // pop all pending GENERATE EDB from etb queue
5000 while (m_etb_q.m_size) {
5001 m_etb_q.pop_entry(&p1,&p2,&ident);
5002 if (ident == OMX_COMPONENT_GENERATE_EBD) {
5003 pending_bd_q.insert_entry(p1,p2,ident);
5004 } else {
5005 tmp_q.insert_entry(p1,p2,ident);
5006 }
5007 }
5008 //return all non GENERATE FDB to etb queue
5009 while (tmp_q.m_size) {
5010 tmp_q.pop_entry(&p1,&p2,&ident);
5011 m_etb_q.insert_entry(p1,p2,ident);
5012 }
5013 pthread_mutex_unlock(&m_lock);
5014 // process all pending buffer dones
5015 while (pending_bd_q.m_size) {
5016 pending_bd_q.pop_entry(&p1,&p2,&ident);
5017 switch (ident) {
5018 case OMX_COMPONENT_GENERATE_EBD:
5019 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
5020 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
5021 omx_report_error ();
5022 }
5023 break;
5024
5025 case OMX_COMPONENT_GENERATE_FBD:
5026 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
5027 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
5028 omx_report_error ();
5029 }
5030 break;
5031 }
5032 }
5033 }
5034
do_cache_operations(int fd)5035 void omx_video::do_cache_operations(int fd)
5036 {
5037 #ifdef USE_ION
5038 struct dma_buf_sync buf_sync;
5039
5040 if (fd < 0)
5041 return;
5042
5043 struct dma_buf_sync dma_buf_sync_data[2];
5044 dma_buf_sync_data[0].flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
5045 dma_buf_sync_data[1].flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
5046
5047 for(unsigned int i=0; i<2; i++) {
5048 int rc = ioctl(fd, DMA_BUF_IOCTL_SYNC, &dma_buf_sync_data[i]);
5049 if (rc < 0) {
5050 DEBUG_PRINT_ERROR("Failed DMA_BUF_IOCTL_SYNC %s fd : %d", i==0?"start":"end", fd);
5051 return;
5052 }
5053 }
5054 #else
5055 (void)fd;
5056 return;
5057 #endif
5058 }
5059
ion_map(int fd,int len)5060 char *omx_video::ion_map(int fd, int len)
5061 {
5062 char *bufaddr = (char*)mmap(NULL, len, PROT_READ|PROT_WRITE,
5063 MAP_SHARED, fd, 0);
5064 #ifdef USE_ION
5065 if (bufaddr != MAP_FAILED) {
5066 do_cache_operations(fd);
5067 }
5068 #endif
5069 return bufaddr;
5070 }
5071
ion_unmap(int fd,void * bufaddr,int len)5072 OMX_ERRORTYPE omx_video::ion_unmap(int fd, void *bufaddr, int len)
5073 {
5074 #ifdef USE_ION
5075 do_cache_operations(fd);
5076 #else
5077 (void)fd;
5078 #endif
5079 if (-1 == munmap(bufaddr, len)) {
5080 DEBUG_PRINT_ERROR("munmap failed.");
5081 return OMX_ErrorInsufficientResources;
5082 }
5083 return OMX_ErrorNone;
5084 }
5085
5086 #ifdef USE_ION
alloc_map_ion_memory(int size,venc_ion * ion_info,int flag)5087 bool omx_video::alloc_map_ion_memory(int size, venc_ion *ion_info, int flag)
5088 {
5089 struct venc_ion buf_ion_info;
5090 int rc=0;
5091
5092 if (size <=0 || !ion_info) {
5093 DEBUG_PRINT_ERROR("Invalid input to alloc_map_ion_memory");
5094 return false;
5095 }
5096
5097 ion_info->data_fd = -1;
5098 ion_info->dev_fd = ion_open();
5099 if (ion_info->dev_fd <= 0) {
5100 DEBUG_PRINT_ERROR("ERROR: ION Device open() Failed");
5101 return false;
5102 }
5103
5104 if(secure_session) {
5105 ion_info->alloc_data.len = (size + (SECURE_ALIGN - 1)) & ~(SECURE_ALIGN - 1);
5106 ion_info->alloc_data.flags = flag;
5107 ion_info->alloc_data.heap_id_mask = ION_HEAP(MEM_HEAP_ID);
5108 if (ion_info->alloc_data.flags & ION_FLAG_CP_BITSTREAM) {
5109 ion_info->alloc_data.heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
5110 }
5111 DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %u flags %x",
5112 (unsigned int)ion_info->alloc_data.len,
5113 ion_info->alloc_data.flags);
5114 } else {
5115 ion_info->alloc_data.len = (size + (SZ_4K - 1)) & ~(SZ_4K - 1);
5116 ion_info->alloc_data.flags = (flag & ION_FLAG_CACHED);
5117
5118 /* If color format is Vanilla NV12, we will need to use caching for optimal
5119 color alignment performance.
5120 */
5121
5122 if (m_sInPortDef.format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)
5123 {
5124 DEBUG_PRINT_HIGH("Enabling cacheing for this buffer");
5125 ion_info->alloc_data.flags = ION_FLAG_CACHED;
5126 }
5127 ion_info->alloc_data.heap_id_mask = (ION_HEAP(MEM_HEAP_ID) |
5128 ION_HEAP(ION_SYSTEM_HEAP_ID));
5129 DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %u flags %x",
5130 (unsigned int)ion_info->alloc_data.len,
5131 ion_info->alloc_data.flags);
5132 }
5133 #ifdef HYPERVISOR
5134 ion_info->alloc_data.flags &= (~ION_FLAG_CACHED);
5135 #endif
5136
5137 rc = ion_alloc_fd(ion_info->dev_fd, ion_info->alloc_data.len, 0,
5138 ion_info->alloc_data.heap_id_mask,
5139 ion_info->alloc_data.flags, &ion_info->data_fd);
5140 if (rc || ion_info->data_fd < 0) {
5141 DEBUG_PRINT_ERROR("ION ALLOC memory failed 0x%x", rc);
5142 ion_close(ion_info->dev_fd);
5143 ion_info->data_fd = -1;
5144 ion_info->dev_fd = -1;
5145 return false;
5146 }
5147
5148 return true;
5149 }
5150
free_ion_memory(struct venc_ion * buf_ion_info)5151 void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
5152 {
5153 if (!buf_ion_info) {
5154 DEBUG_PRINT_ERROR("Invalid input to free_ion_memory");
5155 return;
5156 }
5157 if (buf_ion_info->data_fd >= 0) {
5158 close(buf_ion_info->data_fd);
5159 buf_ion_info->data_fd = -1;
5160 }
5161 if (buf_ion_info->dev_fd >= 0) {
5162 ion_close(buf_ion_info->dev_fd);
5163 buf_ion_info->dev_fd = -1;
5164 }
5165 }
5166 #endif
5167
5168 #ifdef _ANDROID_ICS_
omx_release_meta_buffer(OMX_BUFFERHEADERTYPE * buffer)5169 void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer)
5170 {
5171 if (buffer && meta_mode_enable) {
5172 LEGACY_CAM_METADATA_TYPE *media_ptr;
5173 struct pmem Input_pmem;
5174 unsigned int index_pmem = 0;
5175 bool meta_error = false;
5176
5177 index_pmem = (buffer - m_inp_mem_ptr);
5178 if (mUsesColorConversion &&
5179 (index_pmem < m_sInPortDef.nBufferCountActual)) {
5180 if (!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)) {
5181 DEBUG_PRINT_ERROR("omx_release_meta_buffer dev free failed");
5182 }
5183 } else {
5184 media_ptr = (LEGACY_CAM_METADATA_TYPE *) buffer->pBuffer;
5185 if (media_ptr && media_ptr->meta_handle) {
5186 if (media_ptr->buffer_type == LEGACY_CAM_SOURCE) {
5187 Input_pmem.buffer = media_ptr;
5188 Input_pmem.fd = MetaBufferUtil::getFdAt(media_ptr->meta_handle, 0);
5189 int size = MetaBufferUtil::getIntAt(media_ptr->meta_handle, 0, MetaBufferUtil::INT_SIZE);
5190 int offset = MetaBufferUtil::getIntAt(media_ptr->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
5191 if (Input_pmem.fd < 0 || size < 0 || offset < 0) {
5192 DEBUG_PRINT_ERROR("Invalid meta buffer");
5193 meta_error = true;
5194 }
5195 Input_pmem.size = size;
5196 Input_pmem.offset = offset;
5197 DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd,
5198 Input_pmem.offset,
5199 Input_pmem.size);
5200 } else if (media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) {
5201 VideoGrallocMetadata *media_ptr = (VideoGrallocMetadata *)buffer->pBuffer;
5202 private_handle_t *handle = (private_handle_t *)media_ptr->pHandle;
5203 Input_pmem.buffer = media_ptr;
5204 Input_pmem.fd = handle->fd;
5205 Input_pmem.offset = 0;
5206 Input_pmem.size = handle->size;
5207 } else {
5208 meta_error = true;
5209 }
5210 if (!meta_error)
5211 meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN);
5212 if (meta_error) {
5213 DEBUG_PRINT_HIGH("In batchmode or dev_free_buf failed, flush %d",
5214 input_flush_progress);
5215 }
5216 }
5217 }
5218 }
5219 }
5220 #endif
5221
is_ubwc_interlaced(private_handle_t * handle)5222 bool is_ubwc_interlaced(private_handle_t *handle) {
5223 int interlace_flag = 0;
5224
5225 if (getMetaData(const_cast<private_handle_t *>(handle),
5226 GET_PP_PARAM_INTERLACED, &interlace_flag)) {
5227 interlace_flag = 0;
5228 }
5229 return (handle->format == HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC) &&
5230 !!interlace_flag;
5231 }
5232
is_conv_needed(private_handle_t * handle)5233 bool omx_video::is_conv_needed(private_handle_t *handle)
5234 {
5235 bool bRet = false;
5236 bool interlaced = is_ubwc_interlaced(handle);
5237
5238 if (!strncmp(m_platform, "msm8996", 7)) {
5239 bRet = handle->format == HAL_PIXEL_FORMAT_RGBA_8888 &&
5240 !(handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED ||
5241 handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED_PI);
5242 } else {
5243 bRet = handle->format == HAL_PIXEL_FORMAT_RGBA_8888;
5244 }
5245
5246 #ifdef _HW_RGBA
5247 bRet = false;
5248 #endif
5249 bRet |= interlaced;
5250 DEBUG_PRINT_LOW("RGBA conversion %s. Format %d Flag %d interlace_flag = %d",
5251 bRet ? "Needed":"Not-Needed", handle->format,
5252 handle->flags, interlaced);
5253 return bRet;
5254 }
5255
print_debug_color_aspects(ColorAspects * aspects,const char * prefix)5256 void omx_video::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) {
5257 DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d",
5258 prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs);
5259 }
5260
empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)5261 OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,
5262 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5263 {
5264 VIDC_TRACE_NAME_LOW("ETB-Opaque");
5265 unsigned nBufIndex = 0;
5266 OMX_ERRORTYPE ret = OMX_ErrorNone;
5267 VideoGrallocMetadata *media_buffer; // This method primarily assumes gralloc-metadata
5268 private_handle_t *handle = NULL;
5269 DEBUG_PRINT_LOW("ETBProxyOpaque: buffer[%p]", buffer);
5270
5271 if (buffer == NULL) {
5272 DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid buffer[%p]",buffer);
5273 return OMX_ErrorBadParameter;
5274 }
5275
5276 if (profile_etb()) {
5277 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5278 return OMX_ErrorNone;
5279 }
5280
5281 if (!dev_buffer_ready_to_queue(buffer)) {
5282 DEBUG_PRINT_HIGH("Info: ETBProxyA: buffer[%p] is deffered", buffer);
5283 return OMX_ErrorNone;
5284 }
5285
5286 nBufIndex = buffer - meta_buffer_hdr;
5287 if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
5288 DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid bufindex = %u",
5289 nBufIndex);
5290 return OMX_ErrorBadParameter;
5291 }
5292
5293 media_buffer = (VideoGrallocMetadata *)buffer->pBuffer;
5294 if (!media_buffer) {
5295 DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
5296 return OMX_ErrorBadParameter;
5297 }
5298 if ((media_buffer->eType == LEGACY_CAM_SOURCE)
5299 && buffer->nAllocLen != sizeof(LEGACY_CAM_METADATA_TYPE)) {
5300 DEBUG_PRINT_ERROR("Invalid metadata size expected(%u) v/s recieved(%zu)",
5301 buffer->nAllocLen, sizeof(LEGACY_CAM_METADATA_TYPE));
5302 return OMX_ErrorBadParameter;
5303 }
5304
5305 if (media_buffer && media_buffer->eType == LEGACY_CAM_SOURCE) {
5306 return empty_this_buffer_proxy(hComp, buffer);
5307 }
5308
5309 if ((!media_buffer || !media_buffer->pHandle || media_buffer->eType != kMetadataBufferTypeGrallocSource) &&
5310 !(buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5311 DEBUG_PRINT_ERROR("Incorrect Buffer queued media buffer = %p",
5312 media_buffer);
5313 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
5314 return OMX_ErrorBadParameter;
5315 } else if (media_buffer) {
5316 handle = (private_handle_t *)media_buffer->pHandle;
5317 }
5318
5319 /*Enable following code once private handle color format is
5320 updated correctly*/
5321
5322 if (buffer->nFilledLen > 0 && handle && !is_streamon_done((OMX_U32) PORT_INDEX_OUT)) {
5323
5324 ColorConvertFormat c2dSrcFmt = RGBA8888;
5325 ColorConvertFormat c2dDestFmt = m_ubwc_supported ? NV12_UBWC : NV12_128m;
5326
5327 ColorMapping::const_iterator found =
5328 mMapPixelFormat2Converter.find(handle->format);
5329
5330 if (found != mMapPixelFormat2Converter.end() && is_conv_needed(handle)) {
5331 c2dSrcFmt = (ColorConvertFormat)found->second;
5332 c2dcc.setConversionNeeded(true);
5333 } else {
5334 DEBUG_PRINT_HIGH("Couldn't find color mapping for (%x).", handle->format);
5335 c2dcc.setConversionNeeded(false);
5336 }
5337
5338 mUsesColorConversion = is_conv_needed(handle);
5339 bool interlaced = is_ubwc_interlaced(handle);
5340 int full_range_flag = m_sConfigColorAspects.sAspects.mRange == ColorAspects::RangeFull ?
5341 private_handle_t::PRIV_FLAGS_ITU_R_601_FR : 0;
5342
5343 if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingImageHEIC)
5344 c2dDestFmt = NV12_512;
5345
5346 if (c2dcc.getConversionNeeded() &&
5347 c2dcc.isPropChanged(m_sInPortDef.format.video.nFrameWidth,
5348 interlaced ? ((m_sInPortDef.format.video.nFrameHeight + 1) / 2) :
5349 m_sInPortDef.format.video.nFrameHeight,
5350 m_sInPortDef.format.video.nFrameWidth,
5351 m_sInPortDef.format.video.nFrameHeight,
5352 c2dSrcFmt, c2dDestFmt,
5353 handle->flags, handle->width)) {
5354 DEBUG_PRINT_HIGH("C2D setResolution (0x%X -> 0x%x) HxW (%dx%d) Stride (%d)",
5355 c2dSrcFmt, c2dDestFmt,
5356 m_sInPortDef.format.video.nFrameHeight,
5357 m_sInPortDef.format.video.nFrameWidth,
5358 handle->width);
5359 if (!c2dcc.setResolution(m_sInPortDef.format.video.nFrameWidth,
5360 interlaced ? ((m_sInPortDef.format.video.nFrameHeight + 1) / 2) :
5361 m_sInPortDef.format.video.nFrameHeight,
5362 m_sInPortDef.format.video.nFrameWidth,
5363 m_sInPortDef.format.video.nFrameHeight,
5364 c2dSrcFmt, c2dDestFmt,
5365 handle->flags | full_range_flag, handle->width)) {
5366 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5367 DEBUG_PRINT_ERROR("SetResolution failed");
5368 return OMX_ErrorBadParameter;
5369 }
5370
5371 mC2dSrcFmt = c2dSrcFmt;
5372 mC2DFrameHeight = m_sInPortDef.format.video.nFrameHeight;
5373 mC2DFrameWidth = m_sInPortDef.format.video.nFrameWidth;
5374
5375 if (mC2dDestFmt != c2dDestFmt && !dev_set_format(c2dDestFmt)) {
5376 DEBUG_PRINT_ERROR("cannot set color format");
5377 return OMX_ErrorBadParameter;
5378 }
5379 mC2dDestFmt = c2dDestFmt;
5380 }
5381
5382 dev_get_buf_req (&m_sInPortDef.nBufferCountMin,
5383 &m_sInPortDef.nBufferCountActual,
5384 &m_sInPortDef.nBufferSize,
5385 m_sInPortDef.nPortIndex);
5386 }
5387
5388 if (input_flush_progress == true) {
5389 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5390 DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Input flush in progress");
5391 return OMX_ErrorNone;
5392 }
5393
5394 if (!psource_frame) {
5395 psource_frame = buffer;
5396 ret = push_input_buffer(hComp);
5397 } else {
5398 if (!m_opq_meta_q.insert_entry((unsigned long)buffer,0,0)) {
5399 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Queue is full");
5400 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5401 ret = OMX_ErrorBadParameter;
5402 }
5403 }
5404 return ret;
5405 }
5406
queue_meta_buffer(OMX_HANDLETYPE hComp)5407 OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp)
5408 {
5409
5410 OMX_ERRORTYPE ret = OMX_ErrorNone;
5411 unsigned long address = 0,p2,id;
5412
5413 DEBUG_PRINT_LOW("In queue Meta Buffer");
5414 if (!psource_frame || !pdest_frame) {
5415 DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
5416 return OMX_ErrorBadParameter;
5417 }
5418
5419 if (psource_frame->nFilledLen > 0) {
5420 if (dev_use_buf(PORT_INDEX_IN) != true) {
5421 DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
5422 post_event ((unsigned long)psource_frame,0,OMX_COMPONENT_GENERATE_EBD);
5423 ret = OMX_ErrorBadParameter;
5424 }
5425 }
5426
5427 if (ret == OMX_ErrorNone)
5428 ret = empty_this_buffer_proxy(hComp,psource_frame);
5429
5430 if (ret == OMX_ErrorNone) {
5431 psource_frame = NULL;
5432 if (!psource_frame && m_opq_meta_q.m_size) {
5433 m_opq_meta_q.pop_entry(&address,&p2,&id);
5434 psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
5435 }
5436 } else {
5437 // there has been an error and source frame has been scheduled for an EBD
5438 psource_frame = NULL;
5439 }
5440 return ret;
5441 }
5442
convert_queue_buffer(OMX_HANDLETYPE hComp,struct pmem & Input_pmem_info,unsigned long & index)5443 OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp,
5444 struct pmem &Input_pmem_info,unsigned long &index)
5445 {
5446
5447 unsigned char *uva;
5448 OMX_ERRORTYPE ret = OMX_ErrorNone;
5449 unsigned long address = 0,p2,id;
5450
5451 DEBUG_PRINT_LOW("In Convert and queue Meta Buffer");
5452 if (!psource_frame || !pdest_frame) {
5453 DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
5454 return OMX_ErrorBadParameter;
5455 }
5456 if (secure_session) {
5457 DEBUG_PRINT_ERROR("cannot convert buffer during secure session");
5458 return OMX_ErrorInvalidState;
5459 }
5460
5461 if (!psource_frame->nFilledLen) {
5462 if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
5463 pdest_frame->nFilledLen = psource_frame->nFilledLen;
5464 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
5465 pdest_frame->nFlags = psource_frame->nFlags;
5466 DEBUG_PRINT_HIGH("Skipping color conversion for empty EOS Buffer "
5467 "header=%p filled-len=%u", pdest_frame, (unsigned int)pdest_frame->nFilledLen);
5468 } else {
5469 pdest_frame->nOffset = 0;
5470 pdest_frame->nFilledLen = 0;
5471 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
5472 pdest_frame->nFlags = psource_frame->nFlags;
5473 DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
5474 pdest_frame, (unsigned int)pdest_frame->nFilledLen);
5475 }
5476 } else if (c2dcc.getConversionNeeded()) {
5477 uva = (unsigned char *)ion_map(Input_pmem_info.fd,Input_pmem_info.size);
5478 if (uva == MAP_FAILED) {
5479 ret = OMX_ErrorBadParameter;
5480 } else {
5481 DEBUG_PRINT_HIGH("Start Color Conversion...");
5482 if (!c2dcc.convertC2D(Input_pmem_info.fd, uva,
5483 uva, m_pInput_pmem[index].fd,
5484 pdest_frame->pBuffer,
5485 pdest_frame->pBuffer)) {
5486 DEBUG_PRINT_ERROR("Color Conversion failed");
5487 ret = OMX_ErrorBadParameter;
5488 } else {
5489 unsigned int buf_size = 0;
5490 buf_size = c2dcc.getBuffSize(C2D_OUTPUT);
5491 pdest_frame->nOffset = 0;
5492 pdest_frame->nFilledLen = buf_size;
5493 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
5494 pdest_frame->nFlags = psource_frame->nFlags;
5495 DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
5496 pdest_frame,
5497 (unsigned int)pdest_frame->nFilledLen);
5498 }
5499 ion_unmap(Input_pmem_info.fd, uva,Input_pmem_info.size);
5500 }
5501 }
5502 if (dev_use_buf(PORT_INDEX_IN) != true) {
5503 DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
5504 post_event ((unsigned long)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD);
5505 ret = OMX_ErrorBadParameter;
5506 }
5507 if (ret == OMX_ErrorNone)
5508 ret = empty_this_buffer_proxy(hComp,pdest_frame);
5509 if (ret == OMX_ErrorNone) {
5510 m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame);
5511 psource_frame = NULL;
5512 pdest_frame = NULL;
5513 if (!psource_frame && m_opq_meta_q.m_size) {
5514 m_opq_meta_q.pop_entry(&address,&p2,&id);
5515 psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
5516 }
5517 if (!pdest_frame && m_opq_pmem_q.m_size) {
5518 m_opq_pmem_q.pop_entry(&address,&p2,&id);
5519 pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
5520 DEBUG_PRINT_LOW("pdest_frame pop address is %p",pdest_frame);
5521 }
5522 } else {
5523 // there has been an error and source frame has been scheduled for an EBD
5524 psource_frame = NULL;
5525 }
5526 return ret;
5527 }
5528
push_input_buffer(OMX_HANDLETYPE hComp)5529 OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp)
5530 {
5531 unsigned long address = 0,p2,id, index = 0;
5532 OMX_ERRORTYPE ret = OMX_ErrorNone;
5533
5534 DEBUG_PRINT_LOW("In push input buffer");
5535 if (!psource_frame && m_opq_meta_q.m_size) {
5536 m_opq_meta_q.pop_entry(&address,&p2,&id);
5537 psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
5538 }
5539 if (!pdest_frame && m_opq_pmem_q.m_size) {
5540 m_opq_pmem_q.pop_entry(&address,&p2,&id);
5541 pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
5542 }
5543 while (psource_frame != NULL && pdest_frame != NULL &&
5544 ret == OMX_ErrorNone) {
5545 struct pmem Input_pmem_info;
5546 LEGACY_CAM_METADATA_TYPE *media_buffer;
5547 index = pdest_frame - m_inp_mem_ptr;
5548 if (index >= m_sInPortDef.nBufferCountActual) {
5549 DEBUG_PRINT_ERROR("Output buffer index is wrong %u act count %u",
5550 (unsigned int)index, (unsigned int)m_sInPortDef.nBufferCountActual);
5551 return OMX_ErrorBadParameter;
5552 }
5553
5554 if (psource_frame->nFilledLen == 0 && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
5555 return handle_empty_eos_buffer();
5556 }
5557 media_buffer = (LEGACY_CAM_METADATA_TYPE *)psource_frame->pBuffer;
5558 /*Will enable to verify camcorder in current TIPS can be removed*/
5559 if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
5560 Input_pmem_info.buffer = media_buffer;
5561 Input_pmem_info.fd = MetaBufferUtil::getFdAt(media_buffer->meta_handle, 0);
5562 Input_pmem_info.offset = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
5563 Input_pmem_info.size = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_SIZE);
5564 m_graphicbuffer_size = Input_pmem_info.size;
5565 DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
5566 Input_pmem_info.offset,
5567 Input_pmem_info.size);
5568 ret = queue_meta_buffer(hComp);
5569 } else {
5570 VideoGrallocMetadata *media_buffer = (VideoGrallocMetadata *)psource_frame->pBuffer;
5571 private_handle_t *handle = (private_handle_t *)media_buffer->pHandle;
5572 bool is_venus_supported_format = (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE ||
5573 handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
5574 handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed ||
5575 handle->format == QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus ||
5576 handle->format == QOMX_COLOR_Format32bitRGBA8888Compressed ||
5577 handle->format == HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC ||
5578 handle->format == HAL_PIXEL_FORMAT_NV21_ZSL ||
5579 handle->format == QOMX_COLOR_FormatYVU420SemiPlanar ||
5580 handle->format == HAL_PIXEL_FORMAT_NV12_HEIF);
5581
5582 Input_pmem_info.buffer = media_buffer;
5583 Input_pmem_info.fd = handle->fd;
5584 Input_pmem_info.offset = 0;
5585 Input_pmem_info.size = handle->size;
5586 m_graphicbuffer_size = Input_pmem_info.size;
5587 if (is_conv_needed(handle))
5588 ret = convert_queue_buffer(hComp,Input_pmem_info,index);
5589 else if (is_venus_supported_format)
5590 ret = queue_meta_buffer(hComp);
5591 else
5592 ret = OMX_ErrorBadParameter;
5593 }
5594 }
5595 return ret;
5596 }
5597
handle_empty_eos_buffer(void)5598 OMX_ERRORTYPE omx_video::handle_empty_eos_buffer(void)
5599 {
5600 if(!dev_handle_empty_eos_buffer())
5601 return OMX_ErrorHardware;
5602 else
5603 return OMX_ErrorNone;
5604 }
5605
5606 // no code beyond this !
5607
5608 // inline import of vendor extensions implementation
5609 #include "omx_video_extensions.hpp"
5610