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