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