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