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