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