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