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