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