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