1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010 - 2018, The 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 /*============================================================================
30 O p e n M A X w r a p p e r s
31 O p e n M A X C o r e
32
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
42 #include <inttypes.h>
43
44 #include <string.h>
45 #include <pthread.h>
46 #include <sys/prctl.h>
47 #include <stdlib.h>
48 #include <unistd.h>
49 #include <errno.h>
50 #include "omx_vdec.h"
51 #include "vidc_common.h"
52 #include <fcntl.h>
53 #include <limits.h>
54 #include <stdlib.h>
55 #include <media/hardware/HardwareAPI.h>
56 #include <sys/eventfd.h>
57 #include "PlatformConfig.h"
58 #include <linux/dma-buf.h>
59 #include <linux/videodev2.h>
60
61 #if !defined(_ANDROID_) || defined(SYS_IOCTL)
62 #include <sys/ioctl.h>
63 #include <sys/mman.h>
64 #endif
65
66 #ifdef _ANDROID_
67 #include <cutils/properties.h>
68
69 #ifdef _QUERY_DISP_RES_
70 #include "display_config.h"
71 #endif
72 #endif
73
74 #ifdef _USE_GLIB_
75 #include <glib.h>
76 #define strlcpy g_strlcpy
77 #endif
78
79 #include <qdMetaData.h>
80 #include <gralloc_priv.h>
81
82 #ifdef ANDROID_JELLYBEAN_MR2
83 #include "QComOMXMetadata.h"
84 #endif
85
86 #define BUFFER_LOG_LOC "/data/vendor/media"
87
88 #ifdef OUTPUT_EXTRADATA_LOG
89 FILE *outputExtradataFile;
90 char output_extradata_filename [] = "/data/vendor/media/extradata";
91 #endif
92
93 #define DEFAULT_FPS 30
94 #define MAX_SUPPORTED_FPS 240
95 #define DEFAULT_WIDTH_ALIGNMENT 128
96 #define DEFAULT_HEIGHT_ALIGNMENT 32
97
98 #define POLL_TIMEOUT 0x7fffffff
99
100 #ifdef _ANDROID_
101 extern "C" {
102 #include<utils/Log.h>
103 }
104 #endif//_ANDROID_
105
106 #define SZ_4K 0x1000
107 #define SZ_1M 0x100000
108
109 #define PREFETCH_PIXEL_BUFFER_COUNT 16
110 #define PREFETCH_NON_PIXEL_BUFFER_COUNT 1
111
112 #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
113 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); }
114 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
115 #undef ALIGN
116 #define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1))
117
118 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA | OMX_OUTPUTCROP_EXTRADATA \
119 | OMX_DISPLAY_INFO_EXTRADATA | OMX_UBWC_CR_STATS_INFO_EXTRADATA)
120
121 // Y=16(0-9bits), Cb(10-19bits)=Cr(20-29bits)=128, black by default
122 #define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8020010
123
124 #ifndef ION_FLAG_CP_BITSTREAM
125 #define ION_FLAG_CP_BITSTREAM 0
126 #endif
127
128 #ifndef ION_FLAG_CP_PIXEL
129 #define ION_FLAG_CP_PIXEL 0
130 #endif
131
132 #ifdef SLAVE_SIDE_CP
133 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID
134 #define SECURE_ALIGN SZ_1M
135 #define SECURE_FLAGS_INPUT_BUFFER ION_FLAG_SECURE
136 #define SECURE_FLAGS_OUTPUT_BUFFER ION_FLAG_SECURE
137 #else //MASTER_SIDE_CP
138 #define MEM_HEAP_ID ION_SECURE_HEAP_ID
139 #define SECURE_ALIGN SZ_4K
140 #define SECURE_FLAGS_INPUT_BUFFER (ION_FLAG_SECURE | ION_FLAG_CP_BITSTREAM)
141 #define SECURE_FLAGS_OUTPUT_BUFFER (ION_FLAG_SECURE | ION_FLAG_CP_PIXEL)
142 #endif
143
144 #define LUMINANCE_DIV_FACTOR 10000.0
145
146 /* defined in mp-ctl.h */
147 #define MPCTLV3_VIDEO_DECODE_PB_HINT 0x41C04000
148
149 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
150 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
151
152 using namespace android;
153
154 static OMX_U32 maxSmoothStreamingWidth = 1920;
155 static OMX_U32 maxSmoothStreamingHeight = 1088;
156
print_omx_buffer(const char * str,OMX_BUFFERHEADERTYPE * pHeader)157 void print_omx_buffer(const char *str, OMX_BUFFERHEADERTYPE *pHeader)
158 {
159 if (!pHeader)
160 return;
161
162 DEBUG_PRINT_HIGH("%s: Header %p buffer %p alloclen %d offset %d filledlen %d timestamp %lld flags %#x",
163 str, pHeader, pHeader->pBuffer, pHeader->nAllocLen,
164 pHeader->nOffset, pHeader->nFilledLen,
165 pHeader->nTimeStamp, pHeader->nFlags);
166 }
167
print_v4l2_buffer(const char * str,struct v4l2_buffer * v4l2)168 void print_v4l2_buffer(const char *str, struct v4l2_buffer *v4l2)
169 {
170 if (!v4l2)
171 return;
172
173 if (v4l2->length == 1)
174 DEBUG_PRINT_HIGH(
175 "%s: %s: idx %2d userptr %#lx fd %d off %d size %d filled %d flags %#x\n",
176 str, v4l2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
177 "OUTPUT" : "CAPTURE", v4l2->index,
178 v4l2->m.planes[0].m.userptr, v4l2->m.planes[0].reserved[0],
179 v4l2->m.planes[0].reserved[1], v4l2->m.planes[0].length,
180 v4l2->m.planes[0].bytesused, v4l2->flags);
181 else
182 DEBUG_PRINT_HIGH(
183 "%s: %s: idx %2d userptr %#lx fd %d off %d size %d filled %d flags %#x, extradata: fd %d off %d size %d filled %d\n",
184 str, v4l2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
185 "OUTPUT" : "CAPTURE", v4l2->index,
186 v4l2->m.planes[0].m.userptr, v4l2->m.planes[0].reserved[0],
187 v4l2->m.planes[0].reserved[1], v4l2->m.planes[0].length,
188 v4l2->m.planes[0].bytesused, v4l2->m.planes[1].reserved[0],
189 v4l2->flags, v4l2->m.planes[1].reserved[1],
190 v4l2->m.planes[1].length, v4l2->m.planes[1].bytesused);
191 }
192
async_message_thread(void * input)193 void* async_message_thread (void *input)
194 {
195 OMX_BUFFERHEADERTYPE *buffer;
196 struct v4l2_plane plane[VIDEO_MAX_PLANES];
197 struct pollfd pfds[2];
198 struct v4l2_buffer v4l2_buf;
199 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
200 struct v4l2_event dqevent;
201 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
202 pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
203 pfds[1].events = POLLIN | POLLERR;
204 pfds[0].fd = omx->drv_ctx.video_driver_fd;
205 pfds[1].fd = omx->m_poll_efd;
206 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
207 DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
208 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
209 while (!omx->async_thread_force_stop) {
210 rc = poll(pfds, 2, POLL_TIMEOUT);
211 if (!rc) {
212 DEBUG_PRINT_ERROR("Poll timedout");
213 break;
214 } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
215 DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
216 break;
217 }
218 if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
219 DEBUG_PRINT_HIGH("async_message_thread interrupted to be exited");
220 break;
221 }
222 if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
223 struct vdec_msginfo vdec_msg;
224 memset(&vdec_msg, 0, sizeof(vdec_msg));
225 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
226 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
227 v4l2_buf.length = omx->drv_ctx.num_planes;
228 v4l2_buf.m.planes = plane;
229 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
230 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
231 vdec_msg.status_code=VDEC_S_SUCCESS;
232 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
233 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
234 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
235 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
236 (uint64_t)v4l2_buf.timestamp.tv_usec;
237
238 if (omx->async_message_process(input,&vdec_msg) < 0) {
239 DEBUG_PRINT_HIGH("async_message_thread Exited");
240 break;
241 }
242 }
243 }
244 if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) {
245 struct vdec_msginfo vdec_msg;
246 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
247 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
248 v4l2_buf.length = 1;
249 v4l2_buf.m.planes = plane;
250 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
251 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
252 vdec_msg.status_code=VDEC_S_SUCCESS;
253 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
254 if (omx->async_message_process(input,&vdec_msg) < 0) {
255 DEBUG_PRINT_HIGH("async_message_thread Exited");
256 break;
257 }
258 }
259 }
260 if (pfds[0].revents & POLLPRI) {
261 rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
262 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
263 struct vdec_msginfo vdec_msg;
264 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
265
266 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
267 vdec_msg.status_code=VDEC_S_SUCCESS;
268 vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0];
269 vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1];
270 vdec_msg.msgdata.output_frame.flags = true; // INSUFFICIENT event
271 DEBUG_PRINT_HIGH("VIDC Port Reconfig received insufficient");
272 omx->dpb_bit_depth = ptr[2];
273 DEBUG_PRINT_HIGH("VIDC Port Reconfig Bitdepth - %d", ptr[3]);
274 omx->m_progressive = ptr[3];
275 DEBUG_PRINT_HIGH("VIDC Port Reconfig PicStruct - %d", ptr[4]);
276 omx->m_color_space = (ptr[4] == MSM_VIDC_BT2020 ? (omx_vdec::BT2020):
277 (omx_vdec:: EXCEPT_BT2020));
278 DEBUG_PRINT_HIGH("VIDC Port Reconfig ColorSpace - %d", omx->m_color_space);
279 if (omx->async_message_process(input,&vdec_msg) < 0) {
280 DEBUG_PRINT_HIGH("async_message_thread Exited");
281 break;
282 }
283 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT) {
284
285 bool event_fields_changed = false;
286 bool send_msg = false;
287 omx_vdec::color_space_type tmp_color_space;
288 struct vdec_msginfo vdec_msg;
289 DEBUG_PRINT_HIGH("VIDC Port Reconfig received sufficient");
290 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
291 int tmp_profile = 0;
292 int tmp_level = 0;
293 int codec = omx->get_session_codec_type();
294 event_fields_changed |= (omx->dpb_bit_depth != (int)ptr[2]);
295 event_fields_changed |= (omx->m_progressive != (int)ptr[3]);
296 tmp_color_space = (ptr[4] == MSM_VIDC_BT2020 ? (omx_vdec::BT2020):
297 (omx_vdec:: EXCEPT_BT2020));
298 event_fields_changed |= (omx->m_color_space != tmp_color_space);
299
300 /*
301 * If the resolution is different due to 16\32 pixel alignment,
302 * let's handle as Sufficient. Ex : 1080 & 1088 or 2160 & 2176.
303 * When FBD comes, component updates the clients with actual
304 * resolution through set_buffer_geometry.
305 */
306
307 event_fields_changed |= (omx->drv_ctx.video_resolution.frame_height != ptr[0]);
308 event_fields_changed |= (omx->drv_ctx.video_resolution.frame_width != ptr[1]);
309
310 if ((codec == V4L2_PIX_FMT_H264) ||
311 (codec == V4L2_PIX_FMT_HEVC)) {
312 if (profile_level_converter::convert_v4l2_profile_to_omx(
313 codec, ptr[9], &tmp_profile) &&
314 profile_level_converter::convert_v4l2_level_to_omx(
315 codec, ptr[10], &tmp_level)) {
316 event_fields_changed |= (omx->mClientSessionForSufficiency &&
317 ((tmp_profile != (int)omx->mClientSetProfile) ||
318 (tmp_level > (int)omx->mClientSetLevel)));
319 }
320 }
321
322 if (!omx->is_down_scalar_enabled && omx->m_is_split_mode &&
323 (omx->drv_ctx.video_resolution.frame_height != ptr[0] ||
324 omx->drv_ctx.video_resolution.frame_width != ptr[1])) {
325 event_fields_changed = true;
326 }
327
328 if (event_fields_changed) {
329 DEBUG_PRINT_HIGH("VIDC Port Reconfig Old Resolution(H,W) = (%d,%d) New Resolution(H,W) = (%d,%d))",
330 omx->drv_ctx.video_resolution.frame_height,
331 omx->drv_ctx.video_resolution.frame_width,
332 ptr[0], ptr[1]);
333 DEBUG_PRINT_HIGH("VIDC Port Reconfig Old bitdepth = %d New bitdepth = %d",
334 omx->dpb_bit_depth, ptr[2]);
335 DEBUG_PRINT_HIGH("VIDC Port Reconfig Old picstruct = %d New picstruct = %d",
336 omx->m_progressive, ptr[3]);
337 DEBUG_PRINT_HIGH("VIDC Port Reconfig Old colorSpace = %s New colorspace = %s",
338 (omx->m_color_space == omx_vdec::BT2020 ? "BT2020": "EXCEPT_BT2020"),
339 (tmp_color_space == omx_vdec::BT2020 ? "BT2020": "EXCEPT_BT2020"));
340 DEBUG_PRINT_HIGH("Client Session for sufficiency feature is %s", omx->mClientSessionForSufficiency ? "enabled": "disabled");
341 DEBUG_PRINT_HIGH("VIDC Port Reconfig Client (Profile,Level) = (%d,%d) bitstream(Profile,Level) = (%d,%d))",
342 omx->mClientSetProfile,
343 omx->mClientSetLevel,
344 tmp_profile, tmp_level);
345 omx->dpb_bit_depth = ptr[2];
346 omx->m_progressive = ptr[3];
347 omx->m_color_space = (ptr[4] == MSM_VIDC_BT2020 ? (omx_vdec::BT2020):
348 (omx_vdec:: EXCEPT_BT2020));
349 send_msg = true;
350 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
351 vdec_msg.status_code=VDEC_S_SUCCESS;
352 vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0];
353 vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1];
354 vdec_msg.msgdata.output_frame.flags = false; // SUFFICIENT event
355 } else {
356 struct v4l2_decoder_cmd dec;
357 memset(&dec, 0, sizeof(dec));
358 dec.cmd = V4L2_QCOM_CMD_SESSION_CONTINUE;
359 rc = ioctl(pfds[0].fd, VIDIOC_DECODER_CMD, &dec);
360 if (rc < 0) {
361 DEBUG_PRINT_ERROR("Session continue failed");
362 send_msg = true;
363 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
364 vdec_msg.status_code=VDEC_S_SUCCESS;
365 } else {
366 DEBUG_PRINT_HIGH("Sent Session continue");
367 }
368 }
369
370 if (send_msg) {
371 if (omx->async_message_process(input,&vdec_msg) < 0) {
372 DEBUG_PRINT_HIGH("async_message_thread Exited");
373 break;
374 }
375 }
376
377 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
378 struct vdec_msginfo vdec_msg;
379 uint32_t flush_type = *(uint32_t *)dqevent.u.data;
380 // Old driver doesn't send flushType information.
381 // To make this backward compatible fallback to old approach
382 // if the flush_type is not present.
383 vdec_msg.status_code=VDEC_S_SUCCESS;
384 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_OUTPUT)) {
385 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
386 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
387 if (omx->async_message_process(input,&vdec_msg) < 0) {
388 DEBUG_PRINT_HIGH("async_message_thread Exited");
389 break;
390 }
391 }
392
393 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_CAPTURE)) {
394 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
395 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
396 if (omx->async_message_process(input,&vdec_msg) < 0) {
397 DEBUG_PRINT_HIGH("async_message_thread Exited");
398 break;
399 }
400 }
401 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
402 struct vdec_msginfo vdec_msg;
403 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
404 vdec_msg.status_code=VDEC_S_SUCCESS;
405 DEBUG_PRINT_ERROR("HW Overload received");
406 if (omx->async_message_process(input,&vdec_msg) < 0) {
407 DEBUG_PRINT_HIGH("async_message_thread Exited");
408 break;
409 }
410 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) {
411 struct vdec_msginfo vdec_msg;
412 vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED;
413 vdec_msg.status_code=VDEC_S_SUCCESS;
414 DEBUG_PRINT_ERROR("HW Unsupported received");
415 if (omx->async_message_process(input,&vdec_msg) < 0) {
416 DEBUG_PRINT_HIGH("async_message_thread Exited");
417 break;
418 }
419 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
420 struct vdec_msginfo vdec_msg;
421 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR;
422 vdec_msg.status_code = VDEC_S_SUCCESS;
423 DEBUG_PRINT_HIGH("SYS Error Recieved");
424 if (omx->async_message_process(input,&vdec_msg) < 0) {
425 DEBUG_PRINT_HIGH("async_message_thread Exited");
426 break;
427 }
428 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
429 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
430
431 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
432 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
433 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
434 struct vdec_msginfo vdec_msg;
435
436 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
437
438 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
439 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
440 v4l2_buf.length = omx->drv_ctx.num_planes;
441 v4l2_buf.m.planes = plane;
442 v4l2_buf.index = ptr[5];
443 v4l2_buf.flags = 0;
444
445 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
446 vdec_msg.status_code = VDEC_S_SUCCESS;
447 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
448 vdec_msg.msgdata.output_frame.len = 0;
449 vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2];
450 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
451 (uint64_t)ptr[4];
452 if (omx->async_message_process(input,&vdec_msg) < 0) {
453 DEBUG_PRINT_HIGH("async_message_thread Exitedn");
454 break;
455 }
456 } else {
457 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
458 continue;
459 }
460 }
461 }
462 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
463 return NULL;
464 }
465
message_thread_dec(void * input)466 void* message_thread_dec(void *input)
467 {
468 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
469 int res = 0;
470
471 DEBUG_PRINT_HIGH("omx_vdec: message thread start");
472 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
473 while (!omx->message_thread_stop) {
474 res = omx->signal.wait(2 * 1000000000);
475 if (res == ETIMEDOUT || omx->message_thread_stop) {
476 continue;
477 } else if (res) {
478 DEBUG_PRINT_ERROR("omx_vdec: message_thread_dec wait on condition failed, exiting");
479 break;
480 }
481 omx->process_event_cb(omx);
482 }
483 DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
484 return 0;
485 }
486
post_message(omx_vdec * omx,unsigned char id)487 void post_message(omx_vdec *omx, unsigned char id)
488 {
489 (void)id;
490 omx->signal.signal();
491 }
492
493 // omx_cmd_queue destructor
~omx_cmd_queue()494 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
495 {
496 // Nothing to do
497 }
498
499 // omx cmd queue constructor
omx_cmd_queue()500 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
501 {
502 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
503 }
504
505 // omx cmd queue insert
insert_entry(unsigned long p1,unsigned long p2,unsigned long id)506 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id)
507 {
508 bool ret = true;
509 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
510 m_q[m_write].id = id;
511 m_q[m_write].param1 = p1;
512 m_q[m_write].param2 = p2;
513 m_write++;
514 m_size ++;
515 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
516 m_write = 0;
517 }
518 } else {
519 ret = false;
520 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
521 }
522 return ret;
523 }
524
525 // omx cmd queue pop
pop_entry(unsigned long * p1,unsigned long * p2,unsigned long * id)526 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id)
527 {
528 bool ret = true;
529 if (m_size > 0) {
530 *id = m_q[m_read].id;
531 *p1 = m_q[m_read].param1;
532 *p2 = m_q[m_read].param2;
533 // Move the read pointer ahead
534 ++m_read;
535 --m_size;
536 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
537 m_read = 0;
538 }
539 } else {
540 ret = false;
541 }
542 return ret;
543 }
544
545 // Retrieve the first mesg type in the queue
get_q_msg_type()546 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
547 {
548 return m_q[m_read].id;
549 }
550
551 #ifdef _ANDROID_
ts_arr_list()552 omx_vdec::ts_arr_list::ts_arr_list()
553 {
554 //initialize timestamps array
555 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
556 }
~ts_arr_list()557 omx_vdec::ts_arr_list::~ts_arr_list()
558 {
559 //free m_ts_arr_list?
560 }
561
insert_ts(OMX_TICKS ts)562 bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
563 {
564 bool ret = true;
565 bool duplicate_ts = false;
566 int idx = 0;
567
568 //insert at the first available empty location
569 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
570 if (!m_ts_arr_list[idx].valid) {
571 //found invalid or empty entry, save timestamp
572 m_ts_arr_list[idx].valid = true;
573 m_ts_arr_list[idx].timestamp = ts;
574 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
575 ts, idx);
576 break;
577 }
578 }
579
580 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
581 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
582 ret = false;
583 }
584 return ret;
585 }
586
pop_min_ts(OMX_TICKS & ts)587 bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
588 {
589 bool ret = true;
590 int min_idx = -1;
591 OMX_TICKS min_ts = 0;
592 int idx = 0;
593
594 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
595
596 if (m_ts_arr_list[idx].valid) {
597 //found valid entry, save index
598 if (min_idx < 0) {
599 //first valid entry
600 min_ts = m_ts_arr_list[idx].timestamp;
601 min_idx = idx;
602 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
603 min_ts = m_ts_arr_list[idx].timestamp;
604 min_idx = idx;
605 }
606 }
607
608 }
609
610 if (min_idx < 0) {
611 //no valid entries found
612 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
613 ts = 0;
614 ret = false;
615 } else {
616 ts = m_ts_arr_list[min_idx].timestamp;
617 m_ts_arr_list[min_idx].valid = false;
618 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
619 ts, min_idx);
620 }
621
622 return ret;
623
624 }
625
626
reset_ts_list()627 bool omx_vdec::ts_arr_list::reset_ts_list()
628 {
629 bool ret = true;
630 int idx = 0;
631
632 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
633 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
634 m_ts_arr_list[idx].valid = false;
635 }
636 return ret;
637 }
638 #endif
639
640 // factory function executed by the core to create instances
get_omx_component_factory_fn(void)641 void *get_omx_component_factory_fn(void)
642 {
643 return (new omx_vdec);
644 }
645
is_platform_tp10capture_supported()646 bool is_platform_tp10capture_supported()
647 {
648 DEBUG_PRINT_HIGH("TP10 on capture port is supported");
649 return true;
650 }
651
get_session_codec_type()652 inline int omx_vdec::get_session_codec_type()
653 {
654 return output_capability;
655 }
656 /* ======================================================================
657 FUNCTION
658 omx_vdec::omx_vdec
659
660 DESCRIPTION
661 Constructor
662
663 PARAMETERS
664 None
665
666 RETURN VALUE
667 None.
668 ========================================================================== */
omx_vdec()669 omx_vdec::omx_vdec(): m_error_propogated(false),
670 m_state(OMX_StateInvalid),
671 m_app_data(NULL),
672 m_inp_mem_ptr(NULL),
673 m_out_mem_ptr(NULL),
674 m_intermediate_out_mem_ptr(NULL),
675 m_client_output_extradata_mem_ptr(NULL),
676 input_flush_progress (false),
677 output_flush_progress (false),
678 input_use_buffer (false),
679 output_use_buffer (false),
680 ouput_egl_buffers(false),
681 m_use_output_pmem(OMX_FALSE),
682 pending_input_buffers(0),
683 pending_output_buffers(0),
684 m_out_bm_count(0),
685 m_inp_bm_count(0),
686 m_out_extradata_bm_count(0),
687 m_inp_bPopulated(OMX_FALSE),
688 m_out_bPopulated(OMX_FALSE),
689 m_flags(0),
690 m_inp_bEnabled(OMX_TRUE),
691 m_out_bEnabled(OMX_TRUE),
692 m_in_alloc_cnt(0),
693 m_platform_list(NULL),
694 m_platform_entry(NULL),
695 m_pmem_info(NULL),
696 h264_parser(NULL),
697 arbitrary_bytes (false),
698 psource_frame (NULL),
699 pdest_frame (NULL),
700 m_inp_heap_ptr (NULL),
701 m_phdr_pmem_ptr(NULL),
702 m_heap_inp_bm_count (0),
703 codec_type_parse ((codec_type)0),
704 first_frame_meta (true),
705 frame_count (0),
706 nal_count (0),
707 nal_length(0),
708 look_ahead_nal (false),
709 first_frame(0),
710 first_buffer(NULL),
711 first_frame_size (0),
712 m_device_file_ptr(NULL),
713 h264_last_au_ts(LLONG_MAX),
714 h264_last_au_flags(0),
715 m_disp_hor_size(0),
716 m_disp_vert_size(0),
717 prev_ts(LLONG_MAX),
718 prev_ts_actual(LLONG_MAX),
719 rst_prev_ts(true),
720 frm_int(0),
721 m_fps_received(0),
722 m_fps_prev(0),
723 m_drc_enable(0),
724 in_reconfig(false),
725 c2d_enable_pending(false),
726 m_display_id(NULL),
727 client_extradata(0),
728 #ifdef _ANDROID_
729 m_enable_android_native_buffers(OMX_FALSE),
730 m_use_android_native_buffers(OMX_FALSE),
731 #endif
732 m_disable_dynamic_buf_mode(0),
733 m_desc_buffer_ptr(NULL),
734 secure_mode(false),
735 allocate_native_handle(false),
736 client_set_fps(false),
737 stereo_output_mode(HAL_NO_3D),
738 m_last_rendered_TS(-1),
739 m_dec_hfr_fps(0),
740 m_dec_secure_prefetch_size_internal(0),
741 m_dec_secure_prefetch_size_output(0),
742 m_arb_mode_override(0),
743 m_queued_codec_config_count(0),
744 secure_scaling_to_non_secure_opb(false),
745 m_force_compressed_for_dpb(true),
746 m_is_display_session(false),
747 m_prefetch_done(0),
748 m_is_split_mode(false),
749 m_buffer_error(false)
750 {
751 m_poll_efd = -1;
752 memset(&drv_ctx, 0, sizeof(drv_ctx));
753 drv_ctx.video_driver_fd = -1;
754 drv_ctx.extradata_info.ion.data_fd = -1;
755 drv_ctx.extradata_info.ion.dev_fd = -1;
756 /* Assumption is that , to begin with , we have all the frames with decoder */
757 DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8);
758 memset(&m_debug,0,sizeof(m_debug));
759 #ifdef _ANDROID_
760
761 char property_value[PROPERTY_VALUE_MAX] = {0};
762 property_get("vendor.vidc.debug.level", property_value, "1");
763 debug_level = strtoul(property_value, NULL, 16);
764 property_value[0] = '\0';
765
766 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
767
768 // TODO: Support in XML
769 perf_flag = 0;
770 if (perf_flag) {
771 DEBUG_PRINT_HIGH("perf flag is %d", perf_flag);
772 dec_time.start();
773 }
774 proc_frms = latency = 0;
775 prev_n_filled_len = 0;
776
777 Platform::Config::getInt32(Platform::vidc_dec_log_in,
778 (int32_t *)&m_debug.in_buffer_log, 0);
779 Platform::Config::getInt32(Platform::vidc_dec_log_out,
780 (int32_t *)&m_debug.out_buffer_log, 0);
781
782 Platform::Config::getInt32(Platform::vidc_dec_hfr_fps,
783 (int32_t *)&m_dec_hfr_fps, 0);
784
785 DEBUG_PRINT_HIGH("HFR fps value = %d", m_dec_hfr_fps);
786
787 if (m_dec_hfr_fps) {
788 m_last_rendered_TS = 0;
789 }
790
791 Platform::Config::getInt32(Platform::vidc_dec_sec_prefetch_size_internal,
792 (int32_t *)&m_dec_secure_prefetch_size_internal, 0);
793 Platform::Config::getInt32(Platform::vidc_dec_sec_prefetch_size_output,
794 (int32_t *)&m_dec_secure_prefetch_size_output, 0);
795
796 DEBUG_PRINT_HIGH("Prefetch size internal = %d, output = %d",
797 m_dec_secure_prefetch_size_internal, m_dec_secure_prefetch_size_output);
798
799 Platform::Config::getInt32(Platform::vidc_dec_arb_mode_override,
800 (int32_t *)&m_arb_mode_override, 0);
801
802 Platform::Config::getInt32(Platform::vidc_perf_control_enable,
803 (int32_t *)&m_perf_control.m_perf_control_enable, 0);
804 if (m_perf_control.m_perf_control_enable) {
805 DEBUG_PRINT_HIGH("perf cotrol enabled");
806 m_perf_control.load_perf_library();
807 }
808
809 property_value[0] = '\0';
810 property_get("vendor.vidc.dec.log.in", property_value, "0");
811 m_debug.in_buffer_log |= atoi(property_value);
812
813 DEBUG_PRINT_HIGH("vendor.vidc.dec.log.in value is %d", m_debug.in_buffer_log);
814
815 property_value[0] = '\0';
816 property_get("vendor.vidc.dec.log.out", property_value, "0");
817 m_debug.out_buffer_log |= atoi(property_value);
818
819 DEBUG_PRINT_HIGH("vendor.vidc.dec.log.out value is %d", m_debug.out_buffer_log);
820
821 property_value[0] = '\0';
822 property_get("vendor.vidc.dec.log.cc.out", property_value, "0");
823 m_debug.out_cc_buffer_log |= atoi(property_value);
824
825 DEBUG_PRINT_HIGH("vendor.vidc.dec.log.cc.out value is %d", m_debug.out_buffer_log);
826
827 property_value[0] = '\0';
828 property_get("vendor.vidc.dec.meta.log.out", property_value, "0");
829 m_debug.out_meta_buffer_log = atoi(property_value);
830
831 property_value[0] = '\0';
832 property_get("vendor.vidc.log.loc", property_value, BUFFER_LOG_LOC);
833 if (*property_value)
834 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
835
836 struct timeval te;
837 gettimeofday(&te, NULL);
838 m_debug.session_id = te.tv_sec*1000LL + te.tv_usec/1000;
839 m_debug.seq_count = 0;
840
841 #ifdef _UBWC_
842 property_value[0] = '\0';
843 property_get("vendor.gralloc.disable_ubwc", property_value, "0");
844 m_disable_ubwc_mode = atoi(property_value);
845 DEBUG_PRINT_HIGH("UBWC mode is %s", m_disable_ubwc_mode ? "disabled" : "enabled");
846 #else
847 m_disable_ubwc_mode = true;
848 #endif
849 #endif
850 memset(&m_cmp,0,sizeof(m_cmp));
851 memset(&m_cb,0,sizeof(m_cb));
852 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
853 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
854 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
855 memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
856 memset(&m_client_color_space, 0, sizeof(DescribeColorAspectsParams));
857 memset(&m_internal_color_space, 0, sizeof(DescribeColorAspectsParams));
858 memset(&m_client_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams));
859 memset(&m_internal_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams));
860 m_demux_entries = 0;
861 msg_thread_id = 0;
862 async_thread_id = 0;
863 msg_thread_created = false;
864 async_thread_created = false;
865 async_thread_force_stop = false;
866 message_thread_stop = false;
867 #ifdef _ANDROID_ICS_
868 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
869 #endif
870
871 /* invalidate m_frame_pack_arrangement */
872 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
873 m_frame_pack_arrangement.cancel_flag = 1;
874
875 drv_ctx.timestamp_adjust = false;
876 m_vendor_config.pData = NULL;
877 pthread_mutex_init(&m_lock, NULL);
878 pthread_mutex_init(&c_lock, NULL);
879 pthread_mutex_init(&buf_lock, NULL);
880 sem_init(&m_cmd_lock,0,0);
881 sem_init(&m_safe_flush, 0, 0);
882 streaming[CAPTURE_PORT] =
883 streaming[OUTPUT_PORT] = false;
884 #ifdef _ANDROID_
885 // TODO: Support in XML
886 m_debug_extradata = 0;
887 #endif
888 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
889 client_buffers.set_vdec_client(this);
890 dynamic_buf_mode = false;
891 is_down_scalar_enabled = false;
892 m_downscalar_width = 0;
893 m_downscalar_height = 0;
894 m_force_down_scalar = 0;
895 m_reconfig_height = 0;
896 m_reconfig_width = 0;
897 m_smoothstreaming_mode = false;
898 m_smoothstreaming_width = 0;
899 m_smoothstreaming_height = 0;
900 m_decode_order_mode = false;
901 m_perf_control.perf_lock_acquire();
902 m_client_req_turbo_mode = false;
903 is_q6_platform = false;
904 m_input_pass_buffer_fd = false;
905 memset(&m_extradata_info, 0, sizeof(m_extradata_info));
906 m_client_color_space.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX;
907 m_client_color_space.sAspects.mRange = ColorAspects::RangeUnspecified;
908 m_client_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
909 m_client_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
910 m_client_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
911
912 m_internal_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
913 m_internal_color_space.sAspects.mRange = ColorAspects::RangeUnspecified;
914 m_internal_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
915 m_internal_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
916 m_internal_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
917 m_internal_color_space.nSize = sizeof(DescribeColorAspectsParams);
918
919 m_client_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX;
920 m_internal_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
921
922 m_dither_config = DITHER_DISABLE;
923
924 DEBUG_PRINT_HIGH("Dither config is %d", m_dither_config);
925 m_color_space = EXCEPT_BT2020;
926
927 init_color_aspects_map();
928
929 profile_level_converter::init();
930 mClientSessionForSufficiency = false;
931 mClientSetProfile = 0;
932 mClientSetLevel = 0;
933 #ifdef USE_GBM
934 drv_ctx.gbm_device_fd = -1;
935 #endif
936 }
937
938 static const int event_type[] = {
939 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
940 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
941 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
942 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
943 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
944 V4L2_EVENT_MSM_VIDC_SYS_ERROR,
945 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD,
946 V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED
947 };
948
subscribe_to_events(int fd)949 static OMX_ERRORTYPE subscribe_to_events(int fd)
950 {
951 OMX_ERRORTYPE eRet = OMX_ErrorNone;
952 struct v4l2_event_subscription sub;
953 int array_sz = sizeof(event_type)/sizeof(int);
954 int i,rc;
955 if (fd < 0) {
956 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
957 return OMX_ErrorBadParameter;
958 }
959
960 for (i = 0; i < array_sz; ++i) {
961 memset(&sub, 0, sizeof(sub));
962 sub.type = event_type[i];
963 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
964 if (rc) {
965 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
966 break;
967 }
968 }
969 if (i < array_sz) {
970 for (--i; i >=0 ; i--) {
971 memset(&sub, 0, sizeof(sub));
972 sub.type = event_type[i];
973 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
974 if (rc)
975 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
976 }
977 eRet = OMX_ErrorNotImplemented;
978 }
979 return eRet;
980 }
981
982
unsubscribe_to_events(int fd)983 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
984 {
985 OMX_ERRORTYPE eRet = OMX_ErrorNone;
986 struct v4l2_event_subscription sub;
987 int array_sz = sizeof(event_type)/sizeof(int);
988 int i,rc;
989 if (fd < 0) {
990 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
991 return OMX_ErrorBadParameter;
992 }
993
994 for (i = 0; i < array_sz; ++i) {
995 memset(&sub, 0, sizeof(sub));
996 sub.type = event_type[i];
997 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
998 if (rc) {
999 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
1000 break;
1001 }
1002 }
1003 return eRet;
1004 }
1005
1006 /* ======================================================================
1007 FUNCTION
1008 omx_vdec::~omx_vdec
1009
1010 DESCRIPTION
1011 Destructor
1012
1013 PARAMETERS
1014 None
1015
1016 RETURN VALUE
1017 None.
1018 ========================================================================== */
~omx_vdec()1019 omx_vdec::~omx_vdec()
1020 {
1021 m_pmem_info = NULL;
1022 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
1023 if (msg_thread_created) {
1024 DEBUG_PRINT_HIGH("Signalling close to OMX Msg Thread");
1025 message_thread_stop = true;
1026 post_message(this, OMX_COMPONENT_CLOSE_MSG);
1027 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
1028 pthread_join(msg_thread_id,NULL);
1029 }
1030 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
1031 if(eventfd_write(m_poll_efd, 1)) {
1032 DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
1033 async_thread_force_stop = true;
1034 }
1035 if (async_thread_created)
1036 pthread_join(async_thread_id,NULL);
1037
1038 if (m_prefetch_done & 0x1)
1039 prefetch_buffers(PREFETCH_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_output, ION_IOC_DRAIN, ION_FLAG_CP_PIXEL);
1040 if (m_prefetch_done & 0x2)
1041 prefetch_buffers(PREFETCH_NON_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_internal, ION_IOC_DRAIN, ION_FLAG_CP_NON_PIXEL);
1042
1043 unsubscribe_to_events(drv_ctx.video_driver_fd);
1044 close(m_poll_efd);
1045 close(drv_ctx.video_driver_fd);
1046 pthread_mutex_destroy(&m_lock);
1047 pthread_mutex_destroy(&c_lock);
1048 pthread_mutex_destroy(&buf_lock);
1049 sem_destroy(&m_cmd_lock);
1050 if (perf_flag) {
1051 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
1052 dec_time.end();
1053 }
1054 DEBUG_PRINT_INFO("Exit OMX vdec Destructor: fd=%d",drv_ctx.video_driver_fd);
1055 m_perf_control.perf_lock_release();
1056 }
1057
set_dpb(bool is_split_mode)1058 OMX_ERRORTYPE omx_vdec::set_dpb(bool is_split_mode)
1059 {
1060 int rc = 0;
1061 struct v4l2_ext_control ctrl[1];
1062 struct v4l2_ext_controls controls;
1063
1064 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
1065 if (is_split_mode) {
1066 ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
1067 } else {
1068 ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY;
1069 }
1070
1071 controls.count = 1;
1072 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
1073 controls.controls = ctrl;
1074
1075 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls);
1076 if (rc) {
1077 DEBUG_PRINT_ERROR("Failed to set ext ctrls for opb_dpb: %d\n", rc);
1078 return OMX_ErrorUnsupportedSetting;
1079 }
1080 m_is_split_mode = is_split_mode;
1081 return OMX_ErrorNone;
1082
1083 }
1084
decide_dpb_buffer_mode()1085 OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode()
1086 {
1087 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1088 struct v4l2_format fmt;
1089 int rc = 0;
1090
1091 // Default is Combined Mode
1092 bool enable_split = false;
1093 bool is_client_dest_format_non_ubwc = (
1094 capture_capability != V4L2_PIX_FMT_NV12_UBWC &&
1095 capture_capability != V4L2_PIX_FMT_NV12_TP10_UBWC);
1096 bool dither_enable = false;
1097 bool capability_changed = false;
1098
1099 switch (m_dither_config) {
1100 case DITHER_DISABLE:
1101 dither_enable = false;
1102 break;
1103 case DITHER_COLORSPACE_EXCEPTBT2020:
1104 dither_enable = (m_color_space == EXCEPT_BT2020);
1105 break;
1106 case DITHER_ALL_COLORSPACE:
1107 dither_enable = true;
1108 break;
1109 default:
1110 DEBUG_PRINT_ERROR("Unsupported dither configuration:%d", m_dither_config);
1111 }
1112
1113 // Reset v4l2_foramt struct object
1114 memset(&fmt, 0x0, sizeof(struct v4l2_format));
1115
1116 if (is_client_dest_format_non_ubwc){
1117 // Assuming all the else blocks are for 8 bit depth
1118 if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
1119 enable_split = true;
1120 if(is_flexible_format){ // if flexible formats are expected, P010 is set for 10bit cases here
1121 drv_ctx.output_format = VDEC_YUV_FORMAT_P010_VENUS;
1122 capture_capability = V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS;
1123 capability_changed = true;
1124 }
1125 } else if (m_progressive == MSM_VIDC_PIC_STRUCT_PROGRESSIVE) {
1126 enable_split = true;
1127 } else {
1128 // Hardware does not support NV12+interlace clips.
1129 // Request NV12_UBWC and convert it to NV12+interlace using C2D
1130 // in combined mode
1131 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
1132 capture_capability = V4L2_PIX_FMT_NV12_UBWC;
1133 capability_changed = true;
1134 }
1135 } else {
1136 if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
1137 enable_split = dither_enable;
1138
1139 if (dither_enable) {
1140 capture_capability = m_disable_ubwc_mode ?
1141 V4L2_PIX_FMT_NV12 : V4L2_PIX_FMT_NV12_UBWC;
1142 capability_changed = true;
1143 } else {
1144 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_TP10_UBWC;
1145 capture_capability = V4L2_PIX_FMT_NV12_TP10_UBWC;
1146 capability_changed = true;
1147 }
1148 }
1149 // 8 bit depth uses the default.
1150 // Combined mode
1151 // V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE
1152 }
1153
1154 if (capability_changed == true) {
1155 // Get format for CAPTURE port
1156 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1157 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
1158 if (rc) {
1159 DEBUG_PRINT_ERROR("%s: Failed get format on capture mplane", __func__);
1160 return OMX_ErrorUnsupportedSetting;
1161 }
1162
1163 // Set Capability for CAPTURE port if there is a change
1164 fmt.fmt.pix_mp.pixelformat = capture_capability;
1165 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1166 if (rc) {
1167 DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
1168 return OMX_ErrorUnsupportedSetting;
1169 }
1170 }
1171 // Check the component for its valid current state
1172 if (!BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_IDLE_PENDING) &&
1173 !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
1174 DEBUG_PRINT_LOW("Invalid state to decide on dpb-opb split");
1175 return OMX_ErrorNone;
1176 }
1177 eRet = set_dpb(enable_split);
1178 if (eRet) {
1179 DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet);
1180 }
1181
1182 return eRet;
1183 }
1184
check_supported_flexible_formats(OMX_COLOR_FORMATTYPE required_format)1185 bool omx_vdec::check_supported_flexible_formats(OMX_COLOR_FORMATTYPE required_format)
1186 {
1187 if(required_format == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
1188 required_format == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus) {
1189 //for now, the flexible formats should be NV12 by default for 8bit cases
1190 //it will change to P010 after 10bit port-reconfig accordingly
1191 return TRUE;
1192 }
1193 else {
1194 return FALSE;
1195 }
1196 }
1197
enable_downscalar()1198 int omx_vdec::enable_downscalar()
1199 {
1200 int rc = 0;
1201 struct v4l2_control control;
1202 struct v4l2_format fmt;
1203
1204 if (is_down_scalar_enabled) {
1205 DEBUG_PRINT_LOW("%s: already enabled", __func__);
1206 return 0;
1207 }
1208
1209 DEBUG_PRINT_LOW("omx_vdec::enable_downscalar");
1210 rc = decide_dpb_buffer_mode();
1211 if (rc) {
1212 DEBUG_PRINT_ERROR("%s: decide_dpb_buffer_mode Failed ", __func__);
1213 return rc;
1214 }
1215 is_down_scalar_enabled = true;
1216
1217 return 0;
1218 }
1219
disable_downscalar()1220 int omx_vdec::disable_downscalar()
1221 {
1222 int rc = 0;
1223 struct v4l2_control control;
1224
1225 if (!is_down_scalar_enabled) {
1226 DEBUG_PRINT_LOW("omx_vdec::disable_downscalar: already disabled");
1227 return 0;
1228 }
1229 rc = decide_dpb_buffer_mode();
1230 if (rc < 0) {
1231 DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed\n", __func__);
1232 return rc;
1233 }
1234 is_down_scalar_enabled = false;
1235
1236 return rc;
1237 }
1238
decide_downscalar()1239 int omx_vdec::decide_downscalar()
1240 {
1241 int rc = 0;
1242 struct v4l2_format fmt;
1243 enum color_fmts color_format;
1244 OMX_U32 width, height;
1245 OMX_BOOL isPortraitVideo = OMX_FALSE;
1246
1247 if (capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC) {
1248 rc = disable_downscalar();
1249 if (rc) {
1250 DEBUG_PRINT_ERROR("Disable downscalar failed!");
1251 return rc;
1252 }
1253 return 0;
1254 }
1255
1256 #ifdef _QUERY_DISP_RES_
1257 memset(&fmt, 0x0, sizeof(struct v4l2_format));
1258 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1259 fmt.fmt.pix_mp.pixelformat = capture_capability;
1260 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
1261 if (rc < 0) {
1262 DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
1263 return rc;
1264 }
1265 isPortraitVideo = fmt.fmt.pix_mp.width < fmt.fmt.pix_mp.height ? OMX_TRUE : OMX_FALSE;
1266 if (!m_downscalar_width || !m_downscalar_height) {
1267 qdutils::DisplayAttributes dpa = {}, dsa = {}, dva = {};
1268 int prim_config, ext_config, virt_config;
1269
1270 prim_config = qdutils::getActiveConfig(qdutils::DISPLAY_PRIMARY);
1271 dpa = qdutils::getDisplayAttributes(prim_config, qdutils::DISPLAY_PRIMARY);
1272 DEBUG_PRINT_HIGH("%s: Primary dpa.xres = %d dpa.yres=%d dpa.xdpi = %f dpa.ydpi = %f ",
1273 __func__, dpa.xres, dpa.yres, dpa.xdpi, dpa.ydpi);
1274
1275 ext_config = qdutils::getActiveConfig(qdutils::DISPLAY_EXTERNAL);
1276 dsa = qdutils::getDisplayAttributes(ext_config, qdutils::DISPLAY_EXTERNAL);
1277 DEBUG_PRINT_HIGH("%s: HDMI dsa.xres = %d dsa.yres = %d dsa.xdpi = %f dsa.ydpi = %f ",
1278 __func__, dsa.xres, dsa.yres, dsa.xdpi, dsa.ydpi);
1279
1280 virt_config = qdutils::getActiveConfig(qdutils::DISPLAY_VIRTUAL);
1281 dva = qdutils::getDisplayAttributes(virt_config, qdutils::DISPLAY_VIRTUAL);
1282 DEBUG_PRINT_HIGH("%s: Virtual dva.xres = %d dva.yres = %d dva.xdpi = %f dva.ydpi = %f ",
1283 __func__, dva.xres, dva.yres, dva.xdpi, dva.ydpi);
1284
1285 /* Below logic takes care of following conditions:
1286 * 1. Choose display resolution as maximum resolution of all the connected
1287 * displays (secondary, primary, virtual), so that we do not downscale
1288 * unnecessarily which might be supported on one of the display losing quality.
1289 * 2. Displays connected might be in landscape or portrait mode, so the xres might
1290 * be smaller or greater than the yres. So we first take the max of the two
1291 * in width and min of two in height and then rotate it if below point is true.
1292 * 3. Video might also be in portrait mode, so invert the downscalar width and
1293 * height for such cases.
1294 */
1295 if (dsa.xres * dsa.yres > dpa.xres * dpa.yres) {
1296 m_downscalar_width = MAX(dsa.xres, dsa.yres);
1297 m_downscalar_height = MIN(dsa.xres, dsa.yres);
1298 } else if (dva.xres * dva.yres > dpa.xres * dpa.yres) {
1299 m_downscalar_width = MAX(dva.xres, dva.yres);
1300 m_downscalar_height = MIN(dva.xres, dva.yres);
1301
1302 } else {
1303 m_downscalar_width = MAX(dpa.xres, dpa.yres);
1304 m_downscalar_height = MIN(dpa.xres, dpa.yres);
1305 }
1306 if (isPortraitVideo) {
1307 // Swap width and height
1308 m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
1309 m_downscalar_height = m_downscalar_width ^ m_downscalar_height;
1310 m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
1311 }
1312 }
1313 m_downscalar_width = ALIGN(m_downscalar_width, 128);
1314 m_downscalar_height = ALIGN(m_downscalar_height, 32);
1315 #endif
1316
1317 if (!m_downscalar_width || !m_downscalar_height) {
1318 DEBUG_PRINT_LOW("%s: Invalid downscalar configuration", __func__);
1319 return 0;
1320 }
1321
1322 if (m_force_down_scalar) {
1323 DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar);
1324 return 0;
1325 }
1326
1327 memset(&fmt, 0x0, sizeof(struct v4l2_format));
1328 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1329 fmt.fmt.pix_mp.pixelformat = capture_capability;
1330 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
1331 if (rc < 0) {
1332 DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
1333 return rc;
1334 }
1335
1336 height = fmt.fmt.pix_mp.height;
1337 width = fmt.fmt.pix_mp.width;
1338
1339 DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d m_is_display_session = %d", __func__,
1340 fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height, m_is_display_session);
1341
1342 if ((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) &&
1343 m_is_display_session) {
1344 rc = enable_downscalar();
1345 if (rc < 0) {
1346 DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
1347 return rc;
1348 }
1349
1350 width = m_downscalar_width > fmt.fmt.pix_mp.width ?
1351 fmt.fmt.pix_mp.width : m_downscalar_width;
1352 height = m_downscalar_height > fmt.fmt.pix_mp.height ?
1353 fmt.fmt.pix_mp.height : m_downscalar_height;
1354 switch (capture_capability) {
1355 case V4L2_PIX_FMT_NV12:
1356 color_format = COLOR_FMT_NV12;
1357 break;
1358 case V4L2_PIX_FMT_NV12_UBWC:
1359 color_format = COLOR_FMT_NV12_UBWC;
1360 break;
1361 case V4L2_PIX_FMT_NV12_TP10_UBWC:
1362 color_format = COLOR_FMT_NV12_BPP10_UBWC;
1363 break;
1364 default:
1365 DEBUG_PRINT_ERROR("Color format not recognized\n");
1366 rc = OMX_ErrorUndefined;
1367 return rc;
1368 }
1369 } else {
1370
1371 rc = disable_downscalar();
1372 if (rc < 0) {
1373 DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
1374 return rc;
1375 }
1376 }
1377
1378 memset(&fmt, 0x0, sizeof(struct v4l2_format));
1379 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1380 fmt.fmt.pix_mp.height = height;
1381 fmt.fmt.pix_mp.width = width;
1382 fmt.fmt.pix_mp.pixelformat = capture_capability;
1383 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1384 if (rc) {
1385 DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
1386 return rc;
1387 }
1388
1389 rc = get_buffer_req(&drv_ctx.op_buf);
1390 if (rc) {
1391 DEBUG_PRINT_ERROR("%s: Failed to get output buffer requirements", __func__);
1392 return rc;
1393 }
1394
1395 return rc;
1396 }
1397
1398 /* ======================================================================
1399 FUNCTION
1400 omx_vdec::OMXCntrlProcessMsgCb
1401
1402 DESCRIPTION
1403 IL Client callbacks are generated through this routine. The decoder
1404 provides the thread context for this routine.
1405
1406 PARAMETERS
1407 ctxt -- Context information related to the self.
1408 id -- Event identifier. This could be any of the following:
1409 1. Command completion event
1410 2. Buffer done callback event
1411 3. Frame done callback event
1412
1413 RETURN VALUE
1414 None.
1415
1416 ========================================================================== */
process_event_cb(void * ctxt)1417 void omx_vdec::process_event_cb(void *ctxt)
1418 {
1419 unsigned long p1; // Parameter - 1
1420 unsigned long p2; // Parameter - 2
1421 unsigned long ident;
1422 unsigned qsize=0; // qsize
1423 omx_vdec *pThis = (omx_vdec *) ctxt;
1424
1425 if (!pThis) {
1426 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
1427 __func__);
1428 return;
1429 }
1430
1431 // Protect the shared queue data structure
1432 do {
1433 /*Read the message id's from the queue*/
1434 pthread_mutex_lock(&pThis->m_lock);
1435 qsize = pThis->m_cmd_q.m_size;
1436 if (qsize) {
1437 pThis->m_cmd_q.pop_entry(&p1, &p2, &ident);
1438 }
1439
1440 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
1441 qsize = pThis->m_ftb_q.m_size;
1442 if (qsize) {
1443 pThis->m_ftb_q.pop_entry(&p1, &p2, &ident);
1444 }
1445 }
1446
1447 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
1448 qsize = pThis->m_etb_q.m_size;
1449 if (qsize) {
1450 pThis->m_etb_q.pop_entry(&p1, &p2, &ident);
1451 }
1452 }
1453 pthread_mutex_unlock(&pThis->m_lock);
1454
1455 /*process message if we have one*/
1456 if (qsize > 0) {
1457 switch (ident) {
1458 case OMX_COMPONENT_GENERATE_EVENT:
1459 if (pThis->m_cb.EventHandler) {
1460 switch (p1) {
1461 case OMX_CommandStateSet:
1462 pThis->m_state = (OMX_STATETYPE) p2;
1463 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
1464 pThis->m_state);
1465 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1466 OMX_EventCmdComplete, p1, p2, NULL);
1467 break;
1468
1469 case OMX_EventError:
1470 if (p2 == OMX_StateInvalid) {
1471 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
1472 pThis->m_state = (OMX_STATETYPE) p2;
1473 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1474 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
1475 } else if (p2 == (unsigned long)OMX_ErrorHardware) {
1476 pThis->omx_report_error();
1477 } else {
1478 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1479 OMX_EventError, p2, (OMX_U32)NULL, NULL );
1480 }
1481 break;
1482
1483 case OMX_CommandPortDisable:
1484 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%lu]", p2);
1485 if (BITMASK_PRESENT(&pThis->m_flags,
1486 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
1487 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1488 break;
1489 }
1490 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
1491 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1492 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
1493 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
1494 pThis->in_reconfig = false;
1495 pThis->client_buffers.enable_color_conversion(pThis->c2d_enable_pending);
1496 if (eRet != OMX_ErrorNone) {
1497 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
1498 pThis->omx_report_error();
1499 break;
1500 }
1501 }
1502 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1503 OMX_EventCmdComplete, p1, p2, NULL );
1504 break;
1505 case OMX_CommandPortEnable:
1506 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%lu]", p2);
1507 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
1508 OMX_EventCmdComplete, p1, p2, NULL );
1509 break;
1510
1511 default:
1512 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1513 OMX_EventCmdComplete, p1, p2, NULL );
1514 break;
1515
1516 }
1517 } else {
1518 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1519 }
1520 break;
1521 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
1522 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
1523 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
1524 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
1525 pThis->omx_report_error ();
1526 }
1527 break;
1528 case OMX_COMPONENT_GENERATE_ETB: {
1529 OMX_ERRORTYPE iret;
1530 iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
1531 if (iret == OMX_ErrorInsufficientResources) {
1532 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
1533 pThis->omx_report_hw_overload ();
1534 } else if (iret != OMX_ErrorNone) {
1535 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
1536 pThis->omx_report_error ();
1537 }
1538 }
1539 break;
1540
1541 case OMX_COMPONENT_GENERATE_FTB:
1542 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\
1543 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
1544 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
1545 pThis->omx_report_error ();
1546 }
1547 break;
1548
1549 case OMX_COMPONENT_GENERATE_COMMAND:
1550 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
1551 (OMX_U32)p2,(OMX_PTR)NULL);
1552 break;
1553
1554 case OMX_COMPONENT_GENERATE_EBD:
1555
1556 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
1557 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
1558 pThis->omx_report_error ();
1559 } else {
1560 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
1561 pThis->time_stamp_dts.remove_time_stamp(
1562 ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp,
1563 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
1564 ?true:false);
1565 }
1566
1567 if ( pThis->empty_buffer_done(&pThis->m_cmp,
1568 (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) {
1569 DEBUG_PRINT_ERROR("empty_buffer_done failure");
1570 pThis->omx_report_error ();
1571 }
1572 }
1573 break;
1574 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
1575 int64_t *timestamp = (int64_t *)(intptr_t)p1;
1576 if (p1) {
1577 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
1578 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
1579 ?true:false);
1580 free(timestamp);
1581 }
1582 }
1583 break;
1584 case OMX_COMPONENT_GENERATE_FBD:
1585 if (p2 != VDEC_S_SUCCESS) {
1586 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
1587 pThis->omx_report_error ();
1588 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
1589 (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) {
1590 DEBUG_PRINT_ERROR("fill_buffer_done failure");
1591 pThis->omx_report_error ();
1592 }
1593 break;
1594
1595 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
1596 DEBUG_PRINT_HIGH("Driver flush i/p Port complete, flags %#llx",
1597 (unsigned long long)pThis->m_flags);
1598 if (!pThis->input_flush_progress) {
1599 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
1600 } else {
1601 pThis->execute_input_flush();
1602 if (pThis->m_cb.EventHandler) {
1603 if (p2 != VDEC_S_SUCCESS) {
1604 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
1605 pThis->omx_report_error ();
1606 } else {
1607 /*Check if we need generate event for Flush done*/
1608 pThis->notify_flush_done(ctxt);
1609
1610 if (BITMASK_PRESENT(&pThis->m_flags,
1611 OMX_COMPONENT_IDLE_PENDING)) {
1612 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
1613 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
1614 pThis->omx_report_error ();
1615 } else {
1616 pThis->streaming[OUTPUT_PORT] = false;
1617 }
1618 if (!pThis->output_flush_progress) {
1619 DEBUG_PRINT_LOW("Input flush done hence issue stop");
1620 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1621 OMX_COMPONENT_GENERATE_STOP_DONE);
1622 }
1623 }
1624 }
1625 } else {
1626 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1627 }
1628 }
1629 break;
1630
1631 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1632 DEBUG_PRINT_HIGH("Driver flush o/p Port complete, flags %#llx",
1633 (unsigned long long)pThis->m_flags);
1634 if (!pThis->output_flush_progress) {
1635 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
1636 } else {
1637 pThis->execute_output_flush();
1638 if (pThis->m_cb.EventHandler) {
1639 if (p2 != VDEC_S_SUCCESS) {
1640 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1641 pThis->omx_report_error ();
1642 } else {
1643 /*Check if we need generate event for Flush done*/
1644 pThis->notify_flush_done(ctxt);
1645
1646 if (BITMASK_PRESENT(&pThis->m_flags,
1647 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
1648 DEBUG_PRINT_LOW("Internal flush complete");
1649 BITMASK_CLEAR (&pThis->m_flags,
1650 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1651 if (BITMASK_PRESENT(&pThis->m_flags,
1652 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1653 pThis->post_event(OMX_CommandPortDisable,
1654 OMX_CORE_OUTPUT_PORT_INDEX,
1655 OMX_COMPONENT_GENERATE_EVENT);
1656 BITMASK_CLEAR (&pThis->m_flags,
1657 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1658 BITMASK_CLEAR (&pThis->m_flags,
1659 OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
1660
1661 }
1662 }
1663
1664 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1665 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
1666 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
1667 pThis->omx_report_error ();
1668 break;
1669 }
1670 pThis->streaming[CAPTURE_PORT] = false;
1671 if (!pThis->input_flush_progress) {
1672 DEBUG_PRINT_LOW("Output flush done hence issue stop");
1673 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1674 OMX_COMPONENT_GENERATE_STOP_DONE);
1675 }
1676 }
1677 }
1678 } else {
1679 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1680 }
1681 }
1682 break;
1683
1684 case OMX_COMPONENT_GENERATE_START_DONE:
1685 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE, flags %#llx",
1686 (unsigned long long)pThis->m_flags);
1687 if (pThis->m_cb.EventHandler) {
1688 if (p2 != VDEC_S_SUCCESS) {
1689 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
1690 pThis->omx_report_error ();
1691 } else {
1692 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
1693 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1694 DEBUG_PRINT_LOW("Move to executing");
1695 // Send the callback now
1696 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1697 pThis->m_state = OMX_StateExecuting;
1698 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1699 OMX_EventCmdComplete,OMX_CommandStateSet,
1700 OMX_StateExecuting, NULL);
1701 } else if (BITMASK_PRESENT(&pThis->m_flags,
1702 OMX_COMPONENT_PAUSE_PENDING)) {
1703 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1704 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
1705 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
1706 pThis->omx_report_error ();
1707 }
1708 }
1709 }
1710 } else {
1711 DEBUG_PRINT_LOW("Event Handler callback is NULL");
1712 }
1713 break;
1714
1715 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1716 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1717 if (pThis->m_cb.EventHandler) {
1718 if (p2 != VDEC_S_SUCCESS) {
1719 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1720 pThis->omx_report_error ();
1721 } else {
1722 pThis->complete_pending_buffer_done_cbs();
1723 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
1724 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1725 //Send the callback now
1726 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1727 pThis->m_state = OMX_StatePause;
1728 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1729 OMX_EventCmdComplete,OMX_CommandStateSet,
1730 OMX_StatePause, NULL);
1731 }
1732 }
1733 } else {
1734 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1735 }
1736
1737 break;
1738
1739 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1740 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1741 if (pThis->m_cb.EventHandler) {
1742 if (p2 != VDEC_S_SUCCESS) {
1743 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1744 pThis->omx_report_error ();
1745 } else {
1746 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1747 DEBUG_PRINT_LOW("Moving the decoder to execute state");
1748 // Send the callback now
1749 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1750 pThis->m_state = OMX_StateExecuting;
1751 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1752 OMX_EventCmdComplete,OMX_CommandStateSet,
1753 OMX_StateExecuting,NULL);
1754 }
1755 }
1756 } else {
1757 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1758 }
1759
1760 break;
1761
1762 case OMX_COMPONENT_GENERATE_STOP_DONE:
1763 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1764 if (pThis->m_cb.EventHandler) {
1765 if (p2 != VDEC_S_SUCCESS) {
1766 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1767 pThis->omx_report_error ();
1768 } else {
1769 pThis->complete_pending_buffer_done_cbs();
1770 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
1771 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
1772 // Send the callback now
1773 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1774 pThis->m_state = OMX_StateIdle;
1775 DEBUG_PRINT_LOW("Move to Idle State");
1776 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1777 OMX_EventCmdComplete,OMX_CommandStateSet,
1778 OMX_StateIdle,NULL);
1779 }
1780 }
1781 } else {
1782 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1783 }
1784
1785 break;
1786
1787 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1788 if (p2 == OMX_IndexParamPortDefinition) {
1789 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
1790 pThis->in_reconfig = true;
1791 pThis->prev_n_filled_len = 0;
1792 } else if (p2 == OMX_IndexConfigCommonOutputCrop) {
1793 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
1794
1795 /* Check if resolution is changed in smooth streaming mode */
1796 if (pThis->m_smoothstreaming_mode &&
1797 (pThis->framesize.nWidth !=
1798 pThis->drv_ctx.video_resolution.frame_width) ||
1799 (pThis->framesize.nHeight !=
1800 pThis->drv_ctx.video_resolution.frame_height)) {
1801
1802 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
1803 pThis->framesize.nWidth,
1804 pThis->framesize.nHeight,
1805 pThis->drv_ctx.video_resolution.frame_width,
1806 pThis->drv_ctx.video_resolution.frame_height);
1807
1808 /* Update new resolution */
1809 pThis->framesize.nWidth =
1810 pThis->drv_ctx.video_resolution.frame_width;
1811 pThis->framesize.nHeight =
1812 pThis->drv_ctx.video_resolution.frame_height;
1813
1814 /* Update C2D with new resolution */
1815 if (!pThis->client_buffers.update_buffer_req()) {
1816 DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
1817 }
1818 }
1819
1820 /* Update new crop information */
1821 pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
1822 pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
1823 pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
1824 pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
1825
1826 /* Validate the new crop information */
1827 if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
1828 pThis->drv_ctx.video_resolution.frame_width) {
1829
1830 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
1831 pThis->rectangle.nLeft, pThis->rectangle.nWidth,
1832 pThis->drv_ctx.video_resolution.frame_width);
1833 pThis->rectangle.nLeft = 0;
1834
1835 if (pThis->rectangle.nWidth >
1836 pThis->drv_ctx.video_resolution.frame_width) {
1837
1838 DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
1839 pThis->rectangle.nWidth,
1840 pThis->drv_ctx.video_resolution.frame_width);
1841 pThis->rectangle.nWidth =
1842 pThis->drv_ctx.video_resolution.frame_width;
1843 }
1844 }
1845 if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
1846 pThis->drv_ctx.video_resolution.frame_height) {
1847
1848 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
1849 pThis->rectangle.nTop, pThis->rectangle.nHeight,
1850 pThis->drv_ctx.video_resolution.frame_height);
1851 pThis->rectangle.nTop = 0;
1852
1853 if (pThis->rectangle.nHeight >
1854 pThis->drv_ctx.video_resolution.frame_height) {
1855
1856 DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
1857 pThis->rectangle.nHeight,
1858 pThis->drv_ctx.video_resolution.frame_height);
1859 pThis->rectangle.nHeight =
1860 pThis->drv_ctx.video_resolution.frame_height;
1861 }
1862 }
1863 DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
1864 pThis->rectangle.nLeft, pThis->rectangle.nTop,
1865 pThis->rectangle.nWidth, pThis->rectangle.nHeight);
1866 } else if (p2 == OMX_QTIIndexConfigDescribeColorAspects) {
1867 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeColorAspects");
1868 } else if (p2 == OMX_QTIIndexConfigDescribeHDRColorInfo) {
1869 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeHDRcolorinfo");
1870 } else {
1871 DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
1872 break;
1873 }
1874 if (pThis->m_debug.outfile) {
1875 fclose(pThis->m_debug.outfile);
1876 pThis->m_debug.outfile = NULL;
1877 }
1878 if (pThis->m_debug.ccoutfile) {
1879 fclose(pThis->m_debug.ccoutfile);
1880 pThis->m_debug.ccoutfile = NULL;
1881 }
1882 if (pThis->m_debug.out_ymeta_file) {
1883 fclose(pThis->m_debug.out_ymeta_file);
1884 pThis->m_debug.out_ymeta_file = NULL;
1885 }
1886 if (pThis->m_debug.out_uvmeta_file) {
1887 fclose(pThis->m_debug.out_uvmeta_file);
1888 pThis->m_debug.out_uvmeta_file = NULL;
1889 }
1890 pThis->m_debug.seq_count++;
1891
1892 if (pThis->m_cb.EventHandler) {
1893 void *frame_data = NULL;
1894 reconfig_client_data port_data;
1895 reconfig_client_crop_data crop_data;
1896 if (p2 == OMX_IndexConfigCommonOutputCrop) {
1897 crop_data.width = pThis->rectangle.nWidth;
1898 crop_data.height = pThis->rectangle.nHeight;
1899 crop_data.left = pThis->rectangle.nLeft;
1900 crop_data.top = pThis->rectangle.nTop;
1901 crop_data.isPortReconfigInsufficient = pThis->isPortReconfigInsufficient;
1902 frame_data = (void*)&crop_data;
1903 } else if (p2 == OMX_IndexParamPortDefinition){
1904 port_data.width = pThis->m_reconfig_width;
1905 port_data.height = pThis->m_reconfig_height;
1906 port_data.dpb_bit_depth = pThis->dpb_bit_depth;
1907 port_data.m_progressive = pThis->m_progressive;
1908 port_data.isPortReconfigInsufficient = pThis->isPortReconfigInsufficient;
1909 frame_data = (void*)&port_data;
1910 }
1911 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1912 OMX_EventPortSettingsChanged, p1, p2, (void*)frame_data);
1913 } else {
1914 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1915 }
1916 break;
1917
1918 case OMX_COMPONENT_GENERATE_EOS_DONE:
1919 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1920 if (pThis->m_cb.EventHandler) {
1921 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1922 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1923 } else {
1924 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1925 }
1926 pThis->prev_ts = LLONG_MAX;
1927 pThis->rst_prev_ts = true;
1928 break;
1929
1930 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1931 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1932 pThis->omx_report_error();
1933 break;
1934
1935 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1936 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
1937 pThis->omx_report_unsupported_setting();
1938 break;
1939
1940 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
1941 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
1942 pThis->omx_report_hw_overload();
1943 break;
1944
1945 case OMX_COMPONENT_GENERATE_ION_PREFETCH_PIXEL:
1946 DEBUG_PRINT_HIGH("OMX_COMPONENT_GENERATE_ION_PREFETCH_PIXEL");
1947 pThis->m_prefetch_done |= pThis->prefetch_buffers(p1, p2, ION_IOC_PREFETCH, ION_FLAG_CP_PIXEL);
1948 break;
1949
1950 case OMX_COMPONENT_GENERATE_ION_PREFETCH_NON_PIXEL:
1951 DEBUG_PRINT_HIGH("OMX_COMPONENT_GENERATE_ION_PREFETCH_NON_PIXEL");
1952 pThis->m_prefetch_done |= pThis->prefetch_buffers(p1, p2, ION_IOC_PREFETCH, ION_FLAG_CP_NON_PIXEL) << 1;
1953 break;
1954
1955 default:
1956 break;
1957 }
1958 }
1959 pthread_mutex_lock(&pThis->m_lock);
1960 qsize = pThis->m_cmd_q.m_size;
1961 if (pThis->m_state != OMX_StatePause)
1962 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1963 pthread_mutex_unlock(&pThis->m_lock);
1964 } while (qsize>0);
1965
1966 }
1967
update_resolution(int width,int height,int stride,int scan_lines)1968 int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
1969 {
1970 int format_changed = 0;
1971 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1972 (width != (int)drv_ctx.video_resolution.frame_width)) {
1973 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
1974 width, drv_ctx.video_resolution.frame_width,
1975 height,drv_ctx.video_resolution.frame_height);
1976 format_changed = 1;
1977 }
1978 drv_ctx.video_resolution.frame_height = height;
1979 drv_ctx.video_resolution.frame_width = width;
1980 drv_ctx.video_resolution.scan_lines = scan_lines;
1981 drv_ctx.video_resolution.stride = stride;
1982
1983 if (!is_down_scalar_enabled) {
1984 rectangle.nLeft = m_extradata_info.output_crop_rect.nLeft;
1985 rectangle.nTop = m_extradata_info.output_crop_rect.nTop;
1986 rectangle.nWidth = m_extradata_info.output_crop_rect.nWidth;
1987 rectangle.nHeight = m_extradata_info.output_crop_rect.nHeight;
1988 }
1989 return format_changed;
1990 }
1991
log_input_buffers(const char * buffer_addr,int buffer_len,uint64_t timeStamp,int fd)1992 int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len, uint64_t timeStamp, int fd)
1993 {
1994 if (!m_debug.in_buffer_log)
1995 return 0;
1996
1997 #ifdef USE_ION
1998 do_cache_operations(fd);
1999 #else
2000 (void)fd;
2001 #endif
2002 if (m_debug.in_buffer_log && !m_debug.infile) {
2003 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
2004 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p_%" PRId64 ".mpg", m_debug.log_loc,
2005 drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this, m_debug.session_id);
2006 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) ||
2007 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
2008 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.264",
2009 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2010 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
2011 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.265",
2012 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2013 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
2014 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
2015 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2016 } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
2017 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
2018 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2019 } else {
2020 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.bin",
2021 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2022 }
2023 m_debug.infile = fopen (m_debug.infile_name, "ab");
2024 if (!m_debug.infile) {
2025 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging (%d:%s)",
2026 m_debug.infile_name, errno, strerror(errno));
2027 m_debug.infile_name[0] = '\0';
2028 #ifdef USE_ION
2029 do_cache_operations(fd);
2030 #endif
2031 return -1;
2032 }
2033 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
2034 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
2035 bool isVp9 = drv_ctx.decoder_format == VDEC_CODECTYPE_VP9;
2036 int width = drv_ctx.video_resolution.frame_width;
2037 int height = drv_ctx.video_resolution.frame_height;
2038 int fps = drv_ctx.frame_rate.fps_numerator;
2039 IvfFileHeader ivfHeader(isVp9, width, height, 1, fps, 0);
2040 fwrite((const char *)&ivfHeader,
2041 sizeof(ivfHeader),1,m_debug.infile);
2042 }
2043 }
2044 if (m_debug.infile && buffer_addr && buffer_len) {
2045 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
2046 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
2047 IvfFrameHeader ivfFrameHeader(buffer_len, timeStamp);
2048 fwrite(&ivfFrameHeader, sizeof(ivfFrameHeader), 1, m_debug.infile);
2049 }
2050 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
2051 }
2052 #ifdef USE_ION
2053 do_cache_operations(fd);
2054 #endif
2055 return 0;
2056 }
2057
log_cc_output_buffers(OMX_BUFFERHEADERTYPE * buffer)2058 int omx_vdec::log_cc_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
2059 if (client_buffers.client_buffers_invalid() ||
2060 !m_debug.out_cc_buffer_log || !buffer || !buffer->nFilledLen)
2061 return 0;
2062
2063 if (m_debug.out_cc_buffer_log && !m_debug.ccoutfile) {
2064 snprintf(m_debug.ccoutfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_cc_%d_%d_%p_%" PRId64 "_%d.yuv",
2065 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this,
2066 m_debug.session_id, m_debug.seq_count);
2067 m_debug.ccoutfile = fopen (m_debug.ccoutfile_name, "ab");
2068 if (!m_debug.ccoutfile) {
2069 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
2070 m_debug.ccoutfile_name[0] = '\0';
2071 return -1;
2072 }
2073 DEBUG_PRINT_HIGH("Opened CC output file: %s for logging", m_debug.ccoutfile_name);
2074 }
2075
2076 fwrite(buffer->pBuffer, buffer->nFilledLen, 1, m_debug.ccoutfile);
2077 return 0;
2078 }
2079
log_output_buffers(OMX_BUFFERHEADERTYPE * buffer)2080 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
2081 int buf_index = 0;
2082 char *temp = NULL;
2083 char *bufaddr = NULL;
2084
2085 if (!(m_debug.out_buffer_log || m_debug.out_meta_buffer_log) || !buffer || !buffer->nFilledLen)
2086 return 0;
2087
2088 if (m_debug.out_buffer_log && !m_debug.outfile) {
2089 snprintf(m_debug.outfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p_%" PRId64 "_%d.yuv",
2090 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this,
2091 m_debug.session_id, m_debug.seq_count);
2092 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
2093 if (!m_debug.outfile) {
2094 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
2095 m_debug.outfile_name[0] = '\0';
2096 return -1;
2097 }
2098 DEBUG_PRINT_HIGH("Opened output file: %s for logging", m_debug.outfile_name);
2099 }
2100
2101 if (m_debug.out_meta_buffer_log && !m_debug.out_ymeta_file && !m_debug.out_uvmeta_file) {
2102 snprintf(m_debug.out_ymetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.ymeta",
2103 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2104 snprintf(m_debug.out_uvmetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.uvmeta",
2105 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
2106 m_debug.out_ymeta_file = fopen (m_debug.out_ymetafile_name, "ab");
2107 m_debug.out_uvmeta_file = fopen (m_debug.out_uvmetafile_name, "ab");
2108 if (!m_debug.out_ymeta_file || !m_debug.out_uvmeta_file) {
2109 DEBUG_PRINT_HIGH("Failed to open output y/uv meta file: %s for logging", m_debug.log_loc);
2110 m_debug.out_ymetafile_name[0] = '\0';
2111 m_debug.out_uvmetafile_name[0] = '\0';
2112 return -1;
2113 }
2114 }
2115
2116 buf_index = buffer - m_out_mem_ptr;
2117 bufaddr = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
2118 if (dynamic_buf_mode && !secure_mode) {
2119 bufaddr = ion_map(drv_ctx.ptr_outputbuffer[buf_index].pmem_fd,
2120 drv_ctx.ptr_outputbuffer[buf_index].buffer_len);
2121 //mmap returns (void *)-1 on failure and sets error code in errno.
2122 if (bufaddr == MAP_FAILED) {
2123 DEBUG_PRINT_ERROR("mmap failed - errno: %d", errno);
2124 return -1;
2125 }
2126 }
2127 temp = bufaddr;
2128
2129 if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC ||
2130 drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
2131 DEBUG_PRINT_HIGH("Logging UBWC yuv width/height(%u/%u)",
2132 drv_ctx.video_resolution.frame_width,
2133 drv_ctx.video_resolution.frame_height);
2134
2135 if (m_debug.outfile)
2136 fwrite(temp, buffer->nFilledLen, 1, m_debug.outfile);
2137
2138 if (m_debug.out_ymeta_file && m_debug.out_uvmeta_file) {
2139 unsigned int width = 0, height = 0;
2140 unsigned int y_plane, y_meta_plane;
2141 int y_stride = 0, y_sclines = 0;
2142 int y_meta_stride = 0, y_meta_scanlines = 0, uv_meta_stride = 0, uv_meta_scanlines = 0;
2143 int color_fmt = (drv_ctx.output_format== VDEC_YUV_FORMAT_NV12_UBWC)? COLOR_FMT_NV12_UBWC: COLOR_FMT_NV12_BPP10_UBWC;
2144 int i;
2145 int bytes_written = 0;
2146
2147 width = drv_ctx.video_resolution.frame_width;
2148 height = drv_ctx.video_resolution.frame_height;
2149 y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width);
2150 y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height);
2151 y_stride = VENUS_Y_STRIDE(color_fmt, width);
2152 y_sclines = VENUS_Y_SCANLINES(color_fmt, height);
2153 uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width);
2154 uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height);
2155
2156 y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096);
2157 y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
2158
2159 for (i = 0; i < y_meta_scanlines; i++) {
2160 bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file);
2161 temp += y_meta_stride;
2162 }
2163
2164 temp = bufaddr + y_meta_plane + y_plane;
2165 for(i = 0; i < uv_meta_scanlines; i++) {
2166 bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file);
2167 temp += uv_meta_stride;
2168 }
2169 }
2170 } else if (m_debug.outfile && drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
2171 int stride = drv_ctx.video_resolution.stride;
2172 int scanlines = drv_ctx.video_resolution.scan_lines;
2173 if (m_smoothstreaming_mode) {
2174 stride = drv_ctx.video_resolution.frame_width;
2175 scanlines = drv_ctx.video_resolution.frame_height;
2176 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
2177 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
2178 }
2179 unsigned i;
2180 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
2181 drv_ctx.video_resolution.frame_width,
2182 drv_ctx.video_resolution.frame_height, stride, scanlines);
2183 int bytes_written = 0;
2184 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
2185 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
2186 temp += stride;
2187 }
2188 temp = bufaddr + stride * scanlines;
2189 int stride_c = stride;
2190 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
2191 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
2192 temp += stride_c;
2193 }
2194 } else if (m_debug.outfile && drv_ctx.output_format == VDEC_YUV_FORMAT_P010_VENUS) {
2195 int stride = drv_ctx.video_resolution.stride;
2196 int scanlines = drv_ctx.video_resolution.scan_lines;
2197 if (m_smoothstreaming_mode) {
2198 stride = drv_ctx.video_resolution.frame_width * 2;
2199 scanlines = drv_ctx.video_resolution.frame_height;
2200 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
2201 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
2202 }
2203 unsigned i;
2204 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
2205 drv_ctx.video_resolution.frame_width,
2206 drv_ctx.video_resolution.frame_height, stride, scanlines);
2207 int bytes_written = 0;
2208 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
2209 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 2, m_debug.outfile);
2210 temp += stride;
2211 }
2212 temp = bufaddr + stride * scanlines;
2213 int stride_c = stride;
2214 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
2215 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 2, m_debug.outfile);
2216 temp += stride_c;
2217 }
2218 }
2219
2220 if (dynamic_buf_mode && !secure_mode) {
2221 ion_unmap(drv_ctx.ptr_outputbuffer[buf_index].pmem_fd, bufaddr,
2222 drv_ctx.ptr_outputbuffer[buf_index].buffer_len);
2223 }
2224 return 0;
2225 }
2226
init_color_aspects_map()2227 void omx_vdec::init_color_aspects_map()
2228 {
2229 mPrimariesMap.insert({
2230 {ColorAspects::PrimariesUnspecified, (ColorPrimaries)(2)},
2231 {ColorAspects::PrimariesBT709_5, ColorPrimaries_BT709_5},
2232 {ColorAspects::PrimariesBT470_6M, ColorPrimaries_BT470_6M},
2233 {ColorAspects::PrimariesBT601_6_625, ColorPrimaries_BT601_6_625},
2234 {ColorAspects::PrimariesBT601_6_525, ColorPrimaries_BT601_6_525},
2235 {ColorAspects::PrimariesGenericFilm, ColorPrimaries_GenericFilm},
2236 {ColorAspects::PrimariesBT2020, ColorPrimaries_BT2020},
2237 });
2238 mTransferMap.insert({
2239 {ColorAspects::TransferUnspecified, (GammaTransfer)(2)},
2240 {ColorAspects::TransferLinear, Transfer_Linear},
2241 {ColorAspects::TransferSRGB, Transfer_sRGB},
2242 {ColorAspects::TransferSMPTE170M, Transfer_SMPTE_170M},
2243 {ColorAspects::TransferGamma22, Transfer_Gamma2_2},
2244 {ColorAspects::TransferGamma28, Transfer_Gamma2_8},
2245 {ColorAspects::TransferST2084, Transfer_SMPTE_ST2084},
2246 {ColorAspects::TransferHLG, Transfer_HLG},
2247 {ColorAspects::TransferSMPTE240M, Transfer_SMPTE_240M},
2248 {ColorAspects::TransferXvYCC, Transfer_XvYCC},
2249 {ColorAspects::TransferBT1361, Transfer_BT1361},
2250 {ColorAspects::TransferST428, Transfer_ST_428},
2251 });
2252 mMatrixCoeffMap.insert({
2253 {ColorAspects::MatrixUnspecified, (MatrixCoEfficients)(2)},
2254 {ColorAspects::MatrixBT709_5, MatrixCoEff_BT709_5},
2255 {ColorAspects::MatrixBT470_6M, MatrixCoeff_FCC_73_682},
2256 {ColorAspects::MatrixBT601_6, MatrixCoEff_BT601_6_625},
2257 {ColorAspects::MatrixSMPTE240M, MatrixCoEff_SMPTE240M},
2258 {ColorAspects::MatrixBT2020, MatrixCoEff_BT2020},
2259 {ColorAspects::MatrixBT2020Constant, MatrixCoEff_BT2020Constant},
2260 });
2261 mColorRangeMap.insert({
2262 {ColorAspects::RangeUnspecified, (ColorRange)(2)},
2263 {ColorAspects::RangeFull, Range_Full},
2264 {ColorAspects::RangeLimited, Range_Limited},
2265 });
2266 }
2267 /* ======================================================================
2268 FUNCTION
2269 omx_vdec::ComponentInit
2270
2271 DESCRIPTION
2272 Initialize the component.
2273
2274 PARAMETERS
2275 ctxt -- Context information related to the self.
2276 id -- Event identifier. This could be any of the following:
2277 1. Command completion event
2278 2. Buffer done callback event
2279 3. Frame done callback event
2280
2281 RETURN VALUE
2282 None.
2283
2284 ========================================================================== */
component_init(OMX_STRING role)2285 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
2286 {
2287
2288 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2289 struct v4l2_fmtdesc fdesc;
2290 struct v4l2_format fmt;
2291 struct v4l2_requestbuffers bufreq;
2292 struct v4l2_control control;
2293 struct v4l2_frmsizeenum frmsize;
2294 struct v4l2_queryctrl query;
2295 unsigned int alignment = 0,buffer_size = 0;
2296 int fds[2];
2297 int r,ret=0;
2298 bool codec_ambiguous = false;
2299 OMX_STRING device_name = (OMX_STRING)"/dev/video32";
2300 char property_value[PROPERTY_VALUE_MAX] = {0};
2301 FILE *soc_file = NULL;
2302 char buffer[10];
2303 struct v4l2_ext_control ctrl[2];
2304 struct v4l2_ext_controls controls;
2305 int conceal_color_8bit = 0, conceal_color_10bit = 0;
2306
2307 #ifdef _ANDROID_
2308 char platform_name[PROPERTY_VALUE_MAX];
2309 property_get("ro.board.platform", platform_name, "0");
2310 if (!strncmp(platform_name, "msm8610", 7)) {
2311 device_name = (OMX_STRING)"/dev/video/q6_dec";
2312 is_q6_platform = true;
2313 maxSmoothStreamingWidth = 1280;
2314 maxSmoothStreamingHeight = 720;
2315 }
2316 #endif
2317
2318 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",
2319 OMX_MAX_STRINGNAME_SIZE)) {
2320 secure_mode = true;
2321 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
2322 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
2323 OMX_MAX_STRINGNAME_SIZE)) {
2324 secure_mode = true;
2325 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
2326 } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure",
2327 OMX_MAX_STRINGNAME_SIZE)) {
2328 secure_mode = true;
2329 role = (OMX_STRING)"OMX.qcom.video.decoder.hevc";
2330 } else if (!strncmp(role, "OMX.qcom.video.decoder.vp9.secure",
2331 OMX_MAX_STRINGNAME_SIZE)) {
2332 secure_mode = true;
2333 role = (OMX_STRING)"OMX.qcom.video.decoder.vp9";
2334 }
2335
2336 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
2337
2338 DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd);
2339
2340 if (drv_ctx.video_driver_fd < 0) {
2341 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
2342 return OMX_ErrorInsufficientResources;
2343 }
2344 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
2345 drv_ctx.frame_rate.fps_denominator = 1;
2346 operating_frame_rate = DEFAULT_FPS;
2347 m_poll_efd = eventfd(0, 0);
2348 if (m_poll_efd < 0) {
2349 DEBUG_PRINT_ERROR("Failed to create event fd(%s)", strerror(errno));
2350 return OMX_ErrorInsufficientResources;
2351 }
2352 ret = subscribe_to_events(drv_ctx.video_driver_fd);
2353 if (!ret) {
2354 async_thread_created = true;
2355 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
2356 }
2357 if (ret) {
2358 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
2359 async_thread_created = false;
2360 return OMX_ErrorInsufficientResources;
2361 }
2362
2363 #ifdef OUTPUT_EXTRADATA_LOG
2364 outputExtradataFile = fopen (output_extradata_filename, "ab");
2365 #endif
2366
2367 // Copy the role information which provides the decoder kind
2368 strlcpy(drv_ctx.kind,role,128);
2369
2370
2371 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
2372 OMX_MAX_STRINGNAME_SIZE)) {
2373 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
2374 OMX_MAX_STRINGNAME_SIZE);
2375 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
2376 output_capability = V4L2_PIX_FMT_MPEG2;
2377 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
2378 /*Initialize Start Code for MPEG2*/
2379 codec_type_parse = CODEC_TYPE_MPEG2;
2380 m_frame_parser.init_start_codes(codec_type_parse);
2381 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
2382 OMX_MAX_STRINGNAME_SIZE)) {
2383 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
2384 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
2385 output_capability=V4L2_PIX_FMT_H264;
2386 eCompressionFormat = OMX_VIDEO_CodingAVC;
2387 codec_type_parse = CODEC_TYPE_H264;
2388 m_frame_parser.init_start_codes(codec_type_parse);
2389 m_frame_parser.init_nal_length(nal_length);
2390 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\
2391 OMX_MAX_STRINGNAME_SIZE)) {
2392 strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
2393 drv_ctx.decoder_format = VDEC_CODECTYPE_MVC;
2394 output_capability = V4L2_PIX_FMT_H264_MVC;
2395 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC;
2396 codec_type_parse = CODEC_TYPE_H264;
2397 m_frame_parser.init_start_codes(codec_type_parse);
2398 m_frame_parser.init_nal_length(nal_length);
2399 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\
2400 OMX_MAX_STRINGNAME_SIZE)) {
2401 strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE);
2402 drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC;
2403 output_capability = V4L2_PIX_FMT_HEVC;
2404 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
2405 codec_type_parse = CODEC_TYPE_HEVC;
2406 m_frame_parser.init_start_codes(codec_type_parse);
2407 m_frame_parser.init_nal_length(nal_length);
2408 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
2409 OMX_MAX_STRINGNAME_SIZE)) {
2410 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
2411 drv_ctx.decoder_format = VDEC_CODECTYPE_VP8;
2412 output_capability = V4L2_PIX_FMT_VP8;
2413 eCompressionFormat = OMX_VIDEO_CodingVP8;
2414 codec_type_parse = CODEC_TYPE_VP8;
2415 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", \
2416 OMX_MAX_STRINGNAME_SIZE)) {
2417 strlcpy((char *)m_cRole, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
2418 drv_ctx.decoder_format = VDEC_CODECTYPE_VP9;
2419 output_capability = V4L2_PIX_FMT_VP9;
2420 eCompressionFormat = OMX_VIDEO_CodingVP9;
2421 codec_type_parse = CODEC_TYPE_VP9;
2422 } else {
2423 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
2424 eRet = OMX_ErrorInvalidComponentName;
2425 }
2426
2427 m_progressive = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
2428
2429 if (eRet == OMX_ErrorNone) {
2430 OMX_COLOR_FORMATTYPE dest_color_format;
2431 if (m_disable_ubwc_mode) {
2432 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
2433 } else {
2434 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
2435 }
2436 if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC)
2437 dest_color_format = (OMX_COLOR_FORMATTYPE)
2438 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
2439 else
2440 dest_color_format = (OMX_COLOR_FORMATTYPE)
2441 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2442 if (!client_buffers.set_color_format(dest_color_format)) {
2443 DEBUG_PRINT_ERROR("Setting color format failed");
2444 eRet = OMX_ErrorInsufficientResources;
2445 }
2446
2447 dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8;
2448 is_flexible_format = FALSE;
2449 is_mbaff = FALSE;
2450
2451 if (m_disable_ubwc_mode) {
2452 capture_capability = V4L2_PIX_FMT_NV12;
2453 } else {
2454 capture_capability = V4L2_PIX_FMT_NV12_UBWC;
2455 }
2456
2457 struct v4l2_capability cap;
2458 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
2459 if (ret) {
2460 DEBUG_PRINT_ERROR("Failed to query capabilities");
2461 /*TODO: How to handle this case */
2462 } else {
2463 DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
2464 " version = %d, capabilities = %x", cap.driver, cap.card,
2465 cap.bus_info, cap.version, cap.capabilities);
2466 }
2467 ret=0;
2468 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2469 fdesc.index=0;
2470 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
2471 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
2472 fdesc.pixelformat, fdesc.flags);
2473 fdesc.index++;
2474 }
2475 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2476 fdesc.index=0;
2477 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
2478
2479 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
2480 fdesc.pixelformat, fdesc.flags);
2481 fdesc.index++;
2482 }
2483 m_extradata_info.output_crop_rect.nLeft = 0;
2484 m_extradata_info.output_crop_rect.nTop = 0;
2485 m_extradata_info.output_crop_rect.nWidth = 320;
2486 m_extradata_info.output_crop_rect.nHeight = 240;
2487 update_resolution(320, 240, 320, 240);
2488
2489 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2490 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2491 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2492 fmt.fmt.pix_mp.pixelformat = output_capability;
2493 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2494 if (ret) {
2495 /*TODO: How to handle this case */
2496 DEBUG_PRINT_ERROR("Failed to set format on output port");
2497 return OMX_ErrorInsufficientResources;
2498 }
2499 DEBUG_PRINT_HIGH("Set Format was successful");
2500
2501 /*
2502 * refer macro DEFAULT_CONCEAL_COLOR to set conceal color values
2503 */
2504 Platform::Config::getInt32(Platform::vidc_dec_conceal_color_8bit, &conceal_color_8bit, DEFAULT_VIDEO_CONCEAL_COLOR_BLACK);
2505 Platform::Config::getInt32(Platform::vidc_dec_conceal_color_10bit, &conceal_color_10bit, DEFAULT_VIDEO_CONCEAL_COLOR_BLACK);
2506 memset(&controls, 0, sizeof(controls));
2507 memset(ctrl, 0, sizeof(ctrl));
2508 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT;
2509 ctrl[0].value = conceal_color_8bit;
2510 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT;
2511 ctrl[1].value = conceal_color_10bit;
2512
2513 controls.count = 2;
2514 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
2515 controls.controls = ctrl;
2516 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls);
2517 if (ret) {
2518 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
2519 }
2520
2521 //Get the hardware capabilities
2522 memset((void *)&frmsize,0,sizeof(frmsize));
2523 frmsize.index = 0;
2524 frmsize.pixel_format = output_capability;
2525 ret = ioctl(drv_ctx.video_driver_fd,
2526 VIDIOC_ENUM_FRAMESIZES, &frmsize);
2527 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
2528 DEBUG_PRINT_ERROR("Failed to get framesizes");
2529 return OMX_ErrorHardware;
2530 }
2531
2532 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
2533 m_decoder_capability.min_width = frmsize.stepwise.min_width;
2534 m_decoder_capability.max_width = frmsize.stepwise.max_width;
2535 m_decoder_capability.min_height = frmsize.stepwise.min_height;
2536 m_decoder_capability.max_height = frmsize.stepwise.max_height;
2537 }
2538
2539 /* Based on UBWC enable, decide split mode to driver before calling S_FMT */
2540 eRet = set_dpb(m_disable_ubwc_mode);
2541
2542 memset(&fmt, 0x0, sizeof(struct v4l2_format));
2543 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2544 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2545 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2546 fmt.fmt.pix_mp.pixelformat = capture_capability;
2547 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2548 if (ret) {
2549 /*TODO: How to handle this case */
2550 DEBUG_PRINT_ERROR("Failed to set format on capture port");
2551 }
2552 memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
2553 framesize.nWidth = drv_ctx.video_resolution.frame_width;
2554 framesize.nHeight = drv_ctx.video_resolution.frame_height;
2555
2556 memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
2557 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
2558 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
2559
2560 DEBUG_PRINT_HIGH("Set Format was successful");
2561 if (secure_mode) {
2562 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
2563 control.value = 1;
2564 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
2565 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2566 if (ret) {
2567 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
2568 return OMX_ErrorInsufficientResources;
2569 }
2570 }
2571
2572 /*Get the Buffer requirements for input and output ports*/
2573 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
2574 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
2575
2576 if (secure_mode) {
2577 drv_ctx.op_buf.alignment = SECURE_ALIGN;
2578 drv_ctx.ip_buf.alignment = SECURE_ALIGN;
2579 } else {
2580 drv_ctx.op_buf.alignment = SZ_4K;
2581 drv_ctx.ip_buf.alignment = SZ_4K;
2582 }
2583
2584 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
2585 drv_ctx.extradata = 0;
2586 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
2587 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
2588 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
2589 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
2590 drv_ctx.idr_only_decoding = 0;
2591
2592 #ifdef _ANDROID_
2593 if (m_dec_hfr_fps) {
2594 memset(&query, 0, sizeof(struct v4l2_queryctrl));
2595
2596 query.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE;
2597 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCTRL, &query);
2598 if (!ret)
2599 m_dec_hfr_fps = MIN(query.maximum, m_dec_hfr_fps);
2600
2601 DEBUG_PRINT_HIGH("Updated HFR fps value = %d", m_dec_hfr_fps);
2602 }
2603
2604 #endif
2605 m_state = OMX_StateLoaded;
2606
2607 unsigned long long extradata_mask = DEFAULT_EXTRADATA;
2608 if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc) {
2609 extradata_mask |= OMX_HDR_COLOR_INFO_EXTRADATA | OMX_EXTNUSER_EXTRADATA;
2610 }
2611 enable_extradata(extradata_mask, true, true);
2612
2613 eRet = get_buffer_req(&drv_ctx.ip_buf);
2614 DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size);
2615 get_buffer_req(&drv_ctx.op_buf);
2616 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
2617 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC ||
2618 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
2619 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
2620 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
2621 h264_scratch.nFilledLen = 0;
2622 h264_scratch.nOffset = 0;
2623
2624 if (h264_scratch.pBuffer == NULL) {
2625 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
2626 return OMX_ErrorInsufficientResources;
2627 }
2628 }
2629 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
2630 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
2631 if (m_frame_parser.mutils == NULL) {
2632 m_frame_parser.mutils = new H264_Utils();
2633 if (m_frame_parser.mutils == NULL) {
2634 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
2635 eRet = OMX_ErrorInsufficientResources;
2636 } else {
2637 m_frame_parser.mutils->initialize_frame_checking_environment();
2638 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
2639 }
2640 }
2641
2642 h264_parser = new h264_stream_parser();
2643 if (!h264_parser) {
2644 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
2645 eRet = OMX_ErrorInsufficientResources;
2646 }
2647 }
2648 msg_thread_created = true;
2649 r = pthread_create(&msg_thread_id,0,message_thread_dec,this);
2650
2651 if (r < 0) {
2652 DEBUG_PRINT_ERROR("component_init(): message_thread_dec creation failed");
2653 msg_thread_created = false;
2654 eRet = OMX_ErrorInsufficientResources;
2655 } else if (secure_mode) {
2656 this->post_event(PREFETCH_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_output, OMX_COMPONENT_GENERATE_ION_PREFETCH_PIXEL);
2657 this->post_event(PREFETCH_NON_PIXEL_BUFFER_COUNT, m_dec_secure_prefetch_size_internal, OMX_COMPONENT_GENERATE_ION_PREFETCH_NON_PIXEL);
2658 }
2659 }
2660
2661 {
2662 VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore);
2663 init_vendor_extensions(*extStore);
2664 mVendorExtensionStore.dumpExtensions((const char *)role);
2665 }
2666
2667 if (eRet != OMX_ErrorNone) {
2668 DEBUG_PRINT_ERROR("Component Init Failed");
2669 } else {
2670 DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d",
2671 drv_ctx.video_driver_fd);
2672 }
2673 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
2674
2675 OMX_INIT_STRUCT(&m_sParamLowLatency, QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE);
2676 m_sParamLowLatency.nNumFrames = 0;
2677 m_sParamLowLatency.bEnableLowLatencyMode = OMX_FALSE;
2678
2679 return eRet;
2680 }
2681
2682 /* ======================================================================
2683 FUNCTION
2684 omx_vdec::GetComponentVersion
2685
2686 DESCRIPTION
2687 Returns the component version.
2688
2689 PARAMETERS
2690 TBD.
2691
2692 RETURN VALUE
2693 OMX_ErrorNone.
2694
2695 ========================================================================== */
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)2696 OMX_ERRORTYPE omx_vdec::get_component_version
2697 (
2698 OMX_IN OMX_HANDLETYPE hComp,
2699 OMX_OUT OMX_STRING componentName,
2700 OMX_OUT OMX_VERSIONTYPE* componentVersion,
2701 OMX_OUT OMX_VERSIONTYPE* specVersion,
2702 OMX_OUT OMX_UUIDTYPE* componentUUID
2703 )
2704 {
2705 (void) hComp;
2706 (void) componentName;
2707 (void) componentVersion;
2708 (void) componentUUID;
2709 if (m_state == OMX_StateInvalid) {
2710 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
2711 return OMX_ErrorInvalidState;
2712 }
2713 /* TBD -- Return the proper version */
2714 if (specVersion) {
2715 specVersion->nVersion = OMX_SPEC_VERSION;
2716 }
2717 return OMX_ErrorNone;
2718 }
2719 /* ======================================================================
2720 FUNCTION
2721 omx_vdec::SendCommand
2722
2723 DESCRIPTION
2724 Returns zero if all the buffers released..
2725
2726 PARAMETERS
2727 None.
2728
2729 RETURN VALUE
2730 true/false
2731
2732 ========================================================================== */
send_command(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)2733 OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
2734 OMX_IN OMX_COMMANDTYPE cmd,
2735 OMX_IN OMX_U32 param1,
2736 OMX_IN OMX_PTR cmdData
2737 )
2738 {
2739 (void) hComp;
2740 (void) cmdData;
2741 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
2742 if (m_state == OMX_StateInvalid) {
2743 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
2744 return OMX_ErrorInvalidState;
2745 }
2746 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
2747 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
2748 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
2749 "to invalid port: %u", (unsigned int)param1);
2750 return OMX_ErrorBadPortIndex;
2751 }
2752
2753 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
2754 sem_wait(&m_cmd_lock);
2755 DEBUG_PRINT_LOW("send_command: Command Processed");
2756 return OMX_ErrorNone;
2757 }
2758
2759 /* ======================================================================
2760 FUNCTION
2761 omx_vdec::SendCommand
2762
2763 DESCRIPTION
2764 Returns zero if all the buffers released..
2765
2766 PARAMETERS
2767 None.
2768
2769 RETURN VALUE
2770 true/false
2771
2772 ========================================================================== */
send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)2773 OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
2774 OMX_IN OMX_COMMANDTYPE cmd,
2775 OMX_IN OMX_U32 param1,
2776 OMX_IN OMX_PTR cmdData
2777 )
2778 {
2779 (void) hComp;
2780 (void) cmdData;
2781 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2782 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
2783 int bFlag = 1,sem_posted = 0,ret=0;
2784
2785 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
2786 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
2787 m_state, eState);
2788
2789 if (cmd == OMX_CommandStateSet) {
2790 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
2791 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
2792 /***************************/
2793 /* Current State is Loaded */
2794 /***************************/
2795 if (m_state == OMX_StateLoaded) {
2796 if (eState == OMX_StateIdle) {
2797 //if all buffers are allocated or all ports disabled
2798 if (allocate_done() ||
2799 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
2800 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
2801 } else {
2802 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
2803 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
2804 // Skip the event notification
2805 bFlag = 0;
2806 }
2807 }
2808 /* Requesting transition from Loaded to Loaded */
2809 else if (eState == OMX_StateLoaded) {
2810 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
2811 post_event(OMX_EventError,OMX_ErrorSameState,\
2812 OMX_COMPONENT_GENERATE_EVENT);
2813 eRet = OMX_ErrorSameState;
2814 }
2815 /* Requesting transition from Loaded to WaitForResources */
2816 else if (eState == OMX_StateWaitForResources) {
2817 /* Since error is None , we will post an event
2818 at the end of this function definition */
2819 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
2820 }
2821 /* Requesting transition from Loaded to Executing */
2822 else if (eState == OMX_StateExecuting) {
2823 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
2824 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2825 OMX_COMPONENT_GENERATE_EVENT);
2826 eRet = OMX_ErrorIncorrectStateTransition;
2827 }
2828 /* Requesting transition from Loaded to Pause */
2829 else if (eState == OMX_StatePause) {
2830 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
2831 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2832 OMX_COMPONENT_GENERATE_EVENT);
2833 eRet = OMX_ErrorIncorrectStateTransition;
2834 }
2835 /* Requesting transition from Loaded to Invalid */
2836 else if (eState == OMX_StateInvalid) {
2837 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
2838 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2839 eRet = OMX_ErrorInvalidState;
2840 } else {
2841 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
2842 eState);
2843 eRet = OMX_ErrorBadParameter;
2844 }
2845 }
2846
2847 /***************************/
2848 /* Current State is IDLE */
2849 /***************************/
2850 else if (m_state == OMX_StateIdle) {
2851 if (eState == OMX_StateLoaded) {
2852 if (release_done()) {
2853 /*
2854 * Since error is None , we will post an event at the end
2855 * of this function definition
2856 * Reset buffer requirements here to ensure setting buffer requirement
2857 * when component move to executing state from loaded state via Idle.
2858 */
2859 drv_ctx.op_buf.buffer_size = 0;
2860 drv_ctx.op_buf.actualcount = 0;
2861 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
2862 } else {
2863 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
2864 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2865 // Skip the event notification
2866 bFlag = 0;
2867 }
2868 }
2869 /* Requesting transition from Idle to Executing */
2870 else if (eState == OMX_StateExecuting) {
2871 bFlag = 1;
2872 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
2873 m_state=OMX_StateExecuting;
2874 }
2875 /* Requesting transition from Idle to Idle */
2876 else if (eState == OMX_StateIdle) {
2877 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
2878 post_event(OMX_EventError,OMX_ErrorSameState,\
2879 OMX_COMPONENT_GENERATE_EVENT);
2880 eRet = OMX_ErrorSameState;
2881 }
2882 /* Requesting transition from Idle to WaitForResources */
2883 else if (eState == OMX_StateWaitForResources) {
2884 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
2885 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2886 OMX_COMPONENT_GENERATE_EVENT);
2887 eRet = OMX_ErrorIncorrectStateTransition;
2888 }
2889 /* Requesting transition from Idle to Pause */
2890 else if (eState == OMX_StatePause) {
2891 /*To pause the Video core we need to start the driver*/
2892 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2893 NULL) < */0) {
2894 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
2895 omx_report_error ();
2896 eRet = OMX_ErrorHardware;
2897 } else {
2898 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2899 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
2900 bFlag = 0;
2901 }
2902 }
2903 /* Requesting transition from Idle to Invalid */
2904 else if (eState == OMX_StateInvalid) {
2905 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
2906 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2907 eRet = OMX_ErrorInvalidState;
2908 } else {
2909 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
2910 eRet = OMX_ErrorBadParameter;
2911 }
2912 }
2913
2914 /******************************/
2915 /* Current State is Executing */
2916 /******************************/
2917 else if (m_state == OMX_StateExecuting) {
2918 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
2919 /* Requesting transition from Executing to Idle */
2920 if (eState == OMX_StateIdle) {
2921 /* Since error is None , we will post an event
2922 at the end of this function definition
2923 */
2924 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
2925 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2926 if (!sem_posted) {
2927 sem_posted = 1;
2928 sem_post (&m_cmd_lock);
2929 execute_omx_flush(OMX_ALL);
2930 }
2931 bFlag = 0;
2932 }
2933 /* Requesting transition from Executing to Paused */
2934 else if (eState == OMX_StatePause) {
2935 DEBUG_PRINT_LOW("PAUSE Command Issued");
2936 m_state = OMX_StatePause;
2937 bFlag = 1;
2938 }
2939 /* Requesting transition from Executing to Loaded */
2940 else if (eState == OMX_StateLoaded) {
2941 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
2942 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2943 OMX_COMPONENT_GENERATE_EVENT);
2944 eRet = OMX_ErrorIncorrectStateTransition;
2945 }
2946 /* Requesting transition from Executing to WaitForResources */
2947 else if (eState == OMX_StateWaitForResources) {
2948 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
2949 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2950 OMX_COMPONENT_GENERATE_EVENT);
2951 eRet = OMX_ErrorIncorrectStateTransition;
2952 }
2953 /* Requesting transition from Executing to Executing */
2954 else if (eState == OMX_StateExecuting) {
2955 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
2956 post_event(OMX_EventError,OMX_ErrorSameState,\
2957 OMX_COMPONENT_GENERATE_EVENT);
2958 eRet = OMX_ErrorSameState;
2959 }
2960 /* Requesting transition from Executing to Invalid */
2961 else if (eState == OMX_StateInvalid) {
2962 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
2963 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2964 eRet = OMX_ErrorInvalidState;
2965 } else {
2966 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
2967 eRet = OMX_ErrorBadParameter;
2968 }
2969 }
2970 /***************************/
2971 /* Current State is Pause */
2972 /***************************/
2973 else if (m_state == OMX_StatePause) {
2974 /* Requesting transition from Pause to Executing */
2975 if (eState == OMX_StateExecuting) {
2976 DEBUG_PRINT_LOW("Pause --> Executing");
2977 m_state = OMX_StateExecuting;
2978 bFlag = 1;
2979 }
2980 /* Requesting transition from Pause to Idle */
2981 else if (eState == OMX_StateIdle) {
2982 /* Since error is None , we will post an event
2983 at the end of this function definition */
2984 DEBUG_PRINT_LOW("Pause --> Idle");
2985 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2986 if (!sem_posted) {
2987 sem_posted = 1;
2988 sem_post (&m_cmd_lock);
2989 execute_omx_flush(OMX_ALL);
2990 }
2991 bFlag = 0;
2992 }
2993 /* Requesting transition from Pause to loaded */
2994 else if (eState == OMX_StateLoaded) {
2995 DEBUG_PRINT_ERROR("Pause --> loaded");
2996 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2997 OMX_COMPONENT_GENERATE_EVENT);
2998 eRet = OMX_ErrorIncorrectStateTransition;
2999 }
3000 /* Requesting transition from Pause to WaitForResources */
3001 else if (eState == OMX_StateWaitForResources) {
3002 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
3003 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3004 OMX_COMPONENT_GENERATE_EVENT);
3005 eRet = OMX_ErrorIncorrectStateTransition;
3006 }
3007 /* Requesting transition from Pause to Pause */
3008 else if (eState == OMX_StatePause) {
3009 DEBUG_PRINT_ERROR("Pause --> Pause");
3010 post_event(OMX_EventError,OMX_ErrorSameState,\
3011 OMX_COMPONENT_GENERATE_EVENT);
3012 eRet = OMX_ErrorSameState;
3013 }
3014 /* Requesting transition from Pause to Invalid */
3015 else if (eState == OMX_StateInvalid) {
3016 DEBUG_PRINT_ERROR("Pause --> Invalid");
3017 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
3018 eRet = OMX_ErrorInvalidState;
3019 } else {
3020 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
3021 eRet = OMX_ErrorBadParameter;
3022 }
3023 }
3024 /***************************/
3025 /* Current State is WaitForResources */
3026 /***************************/
3027 else if (m_state == OMX_StateWaitForResources) {
3028 /* Requesting transition from WaitForResources to Loaded */
3029 if (eState == OMX_StateLoaded) {
3030 /* Since error is None , we will post an event
3031 at the end of this function definition */
3032 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
3033 }
3034 /* Requesting transition from WaitForResources to WaitForResources */
3035 else if (eState == OMX_StateWaitForResources) {
3036 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
3037 post_event(OMX_EventError,OMX_ErrorSameState,
3038 OMX_COMPONENT_GENERATE_EVENT);
3039 eRet = OMX_ErrorSameState;
3040 }
3041 /* Requesting transition from WaitForResources to Executing */
3042 else if (eState == OMX_StateExecuting) {
3043 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
3044 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3045 OMX_COMPONENT_GENERATE_EVENT);
3046 eRet = OMX_ErrorIncorrectStateTransition;
3047 }
3048 /* Requesting transition from WaitForResources to Pause */
3049 else if (eState == OMX_StatePause) {
3050 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
3051 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
3052 OMX_COMPONENT_GENERATE_EVENT);
3053 eRet = OMX_ErrorIncorrectStateTransition;
3054 }
3055 /* Requesting transition from WaitForResources to Invalid */
3056 else if (eState == OMX_StateInvalid) {
3057 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
3058 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
3059 eRet = OMX_ErrorInvalidState;
3060 }
3061 /* Requesting transition from WaitForResources to Loaded -
3062 is NOT tested by Khronos TS */
3063
3064 } else {
3065 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
3066 eRet = OMX_ErrorBadParameter;
3067 }
3068 }
3069 /********************************/
3070 /* Current State is Invalid */
3071 /*******************************/
3072 else if (m_state == OMX_StateInvalid) {
3073 /* State Transition from Inavlid to any state */
3074 if ((eState == OMX_StateLoaded) ||
3075 (eState == OMX_StateWaitForResources) ||
3076 (eState == OMX_StateIdle) ||
3077 (eState == OMX_StateExecuting) ||
3078 (eState == OMX_StatePause) ||
3079 (eState == OMX_StateInvalid)
3080 ) {
3081 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
3082 post_event(OMX_EventError,OMX_ErrorInvalidState,\
3083 OMX_COMPONENT_GENERATE_EVENT);
3084 eRet = OMX_ErrorInvalidState;
3085 }
3086 } else if (cmd == OMX_CommandFlush) {
3087 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
3088 "with param1: %u", (unsigned int)param1);
3089 send_codec_config();
3090 if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
3091 param1 == OMX_ALL)) {
3092 if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
3093 struct timespec ts;
3094
3095 clock_gettime(CLOCK_REALTIME, &ts);
3096 ts.tv_sec += 2;
3097 DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
3098 m_queued_codec_config_count);
3099 BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
3100 if (sem_timedwait(&m_safe_flush, &ts)) {
3101 DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
3102 }
3103 BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
3104 }
3105 }
3106
3107 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
3108 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
3109 }
3110 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
3111 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
3112 }
3113 if (!sem_posted) {
3114 sem_posted = 1;
3115 DEBUG_PRINT_LOW("Set the Semaphore");
3116 sem_post (&m_cmd_lock);
3117 execute_omx_flush(param1);
3118 }
3119 bFlag = 0;
3120 } else if ( cmd == OMX_CommandPortEnable) {
3121 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
3122 "with param1: %u", (unsigned int)param1);
3123 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
3124 m_inp_bEnabled = OMX_TRUE;
3125
3126 if ( (m_state == OMX_StateLoaded &&
3127 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3128 || allocate_input_done()) {
3129 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
3130 OMX_COMPONENT_GENERATE_EVENT);
3131 } else {
3132 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
3133 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
3134 // Skip the event notification
3135 bFlag = 0;
3136 }
3137 }
3138 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
3139 DEBUG_PRINT_LOW("Enable output Port command recieved");
3140 m_out_bEnabled = OMX_TRUE;
3141
3142 if ( (m_state == OMX_StateLoaded &&
3143 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3144 || (allocate_output_done())) {
3145 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
3146 OMX_COMPONENT_GENERATE_EVENT);
3147
3148 } else {
3149 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
3150 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
3151 // Skip the event notification
3152 bFlag = 0;
3153 /* enable/disable downscaling if required */
3154 ret = decide_downscalar();
3155 if (ret) {
3156 DEBUG_PRINT_LOW("decide_downscalar failed\n");
3157 }
3158 }
3159 }
3160 } else if (cmd == OMX_CommandPortDisable) {
3161 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
3162 "with param1: %u", (unsigned int)param1);
3163 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
3164 codec_config_flag = false;
3165 m_inp_bEnabled = OMX_FALSE;
3166 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
3167 && release_input_done()) {
3168 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
3169 OMX_COMPONENT_GENERATE_EVENT);
3170 } else {
3171 DEBUG_PRINT_HIGH("Set input port disable pending");
3172 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
3173 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
3174 if (!sem_posted) {
3175 sem_posted = 1;
3176 sem_post (&m_cmd_lock);
3177 }
3178 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
3179 }
3180
3181 // Skip the event notification
3182 bFlag = 0;
3183 }
3184 }
3185 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
3186 m_out_bEnabled = OMX_FALSE;
3187 DEBUG_PRINT_LOW("Disable output Port command recieved");
3188 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
3189 && release_output_done()) {
3190 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
3191 OMX_COMPONENT_GENERATE_EVENT);
3192 } else {
3193 DEBUG_PRINT_HIGH("Set output port disable pending");
3194 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
3195 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
3196 if (!sem_posted) {
3197 sem_posted = 1;
3198 sem_post (&m_cmd_lock);
3199 }
3200 DEBUG_PRINT_HIGH("Set output port flush in disable pending");
3201 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
3202 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
3203 }
3204 // Skip the event notification
3205 bFlag = 0;
3206
3207 }
3208 }
3209 } else {
3210 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
3211 eRet = OMX_ErrorNotImplemented;
3212 }
3213 if (eRet == OMX_ErrorNone && bFlag) {
3214 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
3215 }
3216 if (!sem_posted) {
3217 sem_post(&m_cmd_lock);
3218 }
3219
3220 return eRet;
3221 }
3222
3223 /* ======================================================================
3224 FUNCTION
3225 omx_vdec::ExecuteOmxFlush
3226
3227 DESCRIPTION
3228 Executes the OMX flush.
3229
3230 PARAMETERS
3231 flushtype - input flush(1)/output flush(0)/ both.
3232
3233 RETURN VALUE
3234 true/false
3235
3236 ========================================================================== */
execute_omx_flush(OMX_U32 flushType)3237 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
3238 {
3239 bool bRet = false;
3240 struct v4l2_plane plane;
3241 struct v4l2_buffer v4l2_buf;
3242 struct v4l2_decoder_cmd dec;
3243 DEBUG_PRINT_LOW("in %s, flushing %u", __func__, (unsigned int)flushType);
3244 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
3245 dec.cmd = V4L2_QCOM_CMD_FLUSH;
3246
3247 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
3248
3249 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
3250 output_flush_progress = true;
3251 dec.flags = V4L2_QCOM_CMD_FLUSH_CAPTURE;
3252 } else {
3253 /* XXX: The driver/hardware does not support flushing of individual ports
3254 * in all states. So we pretty much need to flush both ports internally,
3255 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
3256 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
3257 * we automatically omit sending the FLUSH done for the "opposite" port. */
3258 input_flush_progress = true;
3259 output_flush_progress = true;
3260 dec.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
3261 }
3262
3263 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
3264 DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)flushType);
3265 bRet = false;
3266 }
3267
3268 return bRet;
3269 }
3270 /*=========================================================================
3271 FUNCTION : execute_output_flush
3272
3273 DESCRIPTION
3274 Executes the OMX flush at OUTPUT PORT.
3275
3276 PARAMETERS
3277 None.
3278
3279 RETURN VALUE
3280 true/false
3281 ==========================================================================*/
execute_output_flush()3282 bool omx_vdec::execute_output_flush()
3283 {
3284 unsigned long p1 = 0; // Parameter - 1
3285 unsigned long p2 = 0; // Parameter - 2
3286 unsigned long ident = 0;
3287 bool bRet = true;
3288
3289 /*Generate FBD for all Buffers in the FTBq*/
3290 pthread_mutex_lock(&m_lock);
3291 DEBUG_PRINT_LOW("Initiate Output Flush");
3292
3293 //reset last render TS
3294 if(m_last_rendered_TS > 0) {
3295 m_last_rendered_TS = 0;
3296 }
3297
3298 while (m_ftb_q.m_size) {
3299 m_ftb_q.pop_entry(&p1,&p2,&ident);
3300 if (ident == m_fill_output_msg ) {
3301 print_omx_buffer("Flush FBD", (OMX_BUFFERHEADERTYPE *)p2);
3302 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2);
3303 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
3304 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)p1);
3305 }
3306 }
3307 pthread_mutex_unlock(&m_lock);
3308 output_flush_progress = false;
3309
3310 if (arbitrary_bytes) {
3311 prev_ts = LLONG_MAX;
3312 rst_prev_ts = true;
3313 }
3314 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
3315 return bRet;
3316 }
3317 /*=========================================================================
3318 FUNCTION : execute_input_flush
3319
3320 DESCRIPTION
3321 Executes the OMX flush at INPUT PORT.
3322
3323 PARAMETERS
3324 None.
3325
3326 RETURN VALUE
3327 true/false
3328 ==========================================================================*/
execute_input_flush()3329 bool omx_vdec::execute_input_flush()
3330 {
3331 unsigned i =0;
3332 unsigned long p1 = 0; // Parameter - 1
3333 unsigned long p2 = 0; // Parameter - 2
3334 unsigned long ident = 0;
3335 bool bRet = true;
3336
3337 /*Generate EBD for all Buffers in the ETBq*/
3338 DEBUG_PRINT_LOW("Initiate Input Flush");
3339
3340 pthread_mutex_lock(&m_lock);
3341 DEBUG_PRINT_LOW("Check if the Queue is empty");
3342 while (m_etb_q.m_size) {
3343 m_etb_q.pop_entry(&p1,&p2,&ident);
3344
3345 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
3346 print_omx_buffer("Flush ETB_ARBITRARY", (OMX_BUFFERHEADERTYPE *)p2);
3347 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
3348 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
3349 pending_input_buffers++;
3350 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
3351 print_omx_buffer("Flush ETB", (OMX_BUFFERHEADERTYPE *)p2);
3352 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
3353 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
3354 print_omx_buffer("Flush EBD", (OMX_BUFFERHEADERTYPE *)p1);
3355 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
3356 }
3357 }
3358 time_stamp_dts.flush_timestamp();
3359 /*Check if Heap Buffers are to be flushed*/
3360 if (arbitrary_bytes && !(codec_config_flag)) {
3361 DEBUG_PRINT_LOW("Reset all the variables before flusing");
3362 h264_scratch.nFilledLen = 0;
3363 nal_count = 0;
3364 look_ahead_nal = false;
3365 frame_count = 0;
3366 h264_last_au_ts = LLONG_MAX;
3367 h264_last_au_flags = 0;
3368 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
3369 m_demux_entries = 0;
3370 DEBUG_PRINT_LOW("Initialize parser");
3371 if (m_frame_parser.mutils) {
3372 m_frame_parser.mutils->initialize_frame_checking_environment();
3373 }
3374
3375 while (m_input_pending_q.m_size) {
3376 m_input_pending_q.pop_entry(&p1,&p2,&ident);
3377 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
3378 }
3379
3380 if (psource_frame) {
3381 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
3382 psource_frame = NULL;
3383 }
3384
3385 if (pdest_frame) {
3386 pdest_frame->nFilledLen = 0;
3387 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned int)NULL,
3388 (unsigned int)NULL);
3389 pdest_frame = NULL;
3390 }
3391 m_frame_parser.flush();
3392 } else if (codec_config_flag) {
3393 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
3394 "is not sent to the driver yet");
3395 }
3396 pthread_mutex_unlock(&m_lock);
3397 input_flush_progress = false;
3398 if (!arbitrary_bytes) {
3399 prev_ts = LLONG_MAX;
3400 rst_prev_ts = true;
3401 }
3402
3403 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
3404 return bRet;
3405 }
3406
3407 /*=========================================================================
3408 FUNCTION : notify_flush_done
3409
3410 DESCRIPTION
3411 Notifies flush done to the OMX Client.
3412
3413 PARAMETERS
3414 ctxt -- Context information related to the self..
3415
3416 RETURN VALUE
3417 NONE
3418 ==========================================================================*/
notify_flush_done(void * ctxt)3419 void omx_vdec::notify_flush_done(void *ctxt) {
3420
3421 omx_vdec *pThis = (omx_vdec *) ctxt;
3422
3423 if (!pThis->input_flush_progress && !pThis->output_flush_progress) {
3424 if (BITMASK_PRESENT(&pThis->m_flags,
3425 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
3426 DEBUG_PRINT_LOW("Notify Output Flush done");
3427 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
3428 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
3429 OMX_EventCmdComplete,OMX_CommandFlush,
3430 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
3431 }
3432
3433 if (BITMASK_PRESENT(&pThis->m_flags,
3434 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
3435 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
3436 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
3437 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
3438 OMX_EventCmdComplete,OMX_CommandFlush,
3439 OMX_CORE_INPUT_PORT_INDEX,NULL );
3440 }
3441 }
3442 }
3443
3444 /* ======================================================================
3445 FUNCTION
3446 omx_vdec::SendCommandEvent
3447
3448 DESCRIPTION
3449 Send the event to decoder pipe. This is needed to generate the callbacks
3450 in decoder thread context.
3451
3452 PARAMETERS
3453 None.
3454
3455 RETURN VALUE
3456 true/false
3457
3458 ========================================================================== */
post_event(unsigned long p1,unsigned long p2,unsigned long id)3459 bool omx_vdec::post_event(unsigned long p1,
3460 unsigned long p2,
3461 unsigned long id)
3462 {
3463 bool bRet = false;
3464
3465 /* Just drop messages typically generated by hardware (w/o client request),
3466 * if we've reported an error to client. */
3467 if (m_error_propogated) {
3468 switch (id) {
3469 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
3470 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
3471 DEBUG_PRINT_ERROR("Dropping message %lx "
3472 "since client expected to be in error state", id);
3473 return false;
3474 default:
3475 /* whatever */
3476 break;
3477 }
3478 }
3479
3480 pthread_mutex_lock(&m_lock);
3481
3482 if (id == m_fill_output_msg ||
3483 id == OMX_COMPONENT_GENERATE_FBD ||
3484 id == OMX_COMPONENT_GENERATE_PORT_RECONFIG ||
3485 id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH) {
3486 m_ftb_q.insert_entry(p1,p2,id);
3487 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
3488 id == OMX_COMPONENT_GENERATE_EBD ||
3489 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY ||
3490 id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH) {
3491 m_etb_q.insert_entry(p1,p2,id);
3492 } else {
3493 DEBUG_PRINT_HIGH("post_event(%ld, %ld, %ld)", p1, p2, id);
3494 m_cmd_q.insert_entry(p1,p2,id);
3495 }
3496
3497 bRet = true;
3498 post_message(this, id);
3499
3500 pthread_mutex_unlock(&m_lock);
3501
3502 return bRet;
3503 }
3504
vdec_query_cap(struct v4l2_queryctrl & cap)3505 bool inline omx_vdec::vdec_query_cap(struct v4l2_queryctrl &cap) {
3506
3507 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCTRL, &cap)) {
3508 DEBUG_PRINT_ERROR("Query caps for id = %u failed\n", cap.id);
3509 return false;
3510 }
3511 return true;
3512 }
3513
get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE * profileLevelType)3514 OMX_ERRORTYPE omx_vdec::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
3515 {
3516 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3517 struct v4l2_queryctrl profile_cap, level_cap;
3518 int v4l2_profile;
3519 int avc_profiles[5] = { QOMX_VIDEO_AVCProfileConstrainedBaseline,
3520 QOMX_VIDEO_AVCProfileBaseline,
3521 QOMX_VIDEO_AVCProfileMain,
3522 QOMX_VIDEO_AVCProfileConstrainedHigh,
3523 QOMX_VIDEO_AVCProfileHigh };
3524 int hevc_profiles[3] = { OMX_VIDEO_HEVCProfileMain,
3525 OMX_VIDEO_HEVCProfileMain10,
3526 OMX_VIDEO_HEVCProfileMain10HDR10 };
3527 int mpeg2_profiles[2] = { OMX_VIDEO_MPEG2ProfileSimple,
3528 OMX_VIDEO_MPEG2ProfileMain};
3529 int vp9_profiles[3] = { OMX_VIDEO_VP9Profile0,
3530 OMX_VIDEO_VP9Profile2,
3531 OMX_VIDEO_VP9Profile2HDR};
3532
3533 if (!profileLevelType)
3534 return OMX_ErrorBadParameter;
3535
3536 memset(&level_cap, 0, sizeof(struct v4l2_queryctrl));
3537 memset(&profile_cap, 0, sizeof(struct v4l2_queryctrl));
3538
3539 if (output_capability == V4L2_PIX_FMT_H264) {
3540 level_cap.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
3541 profile_cap.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
3542 } else if (output_capability == V4L2_PIX_FMT_VP8) {
3543 level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
3544 } else if (output_capability == V4L2_PIX_FMT_VP9) {
3545 level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL;
3546 profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP9_PROFILE;
3547 } else if (output_capability == V4L2_PIX_FMT_HEVC) {
3548 level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
3549 profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
3550 } else if (output_capability == V4L2_PIX_FMT_MPEG2) {
3551 level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL;
3552 profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE;
3553 } else {
3554 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported Invalid codec");
3555 return OMX_ErrorInvalidComponent;
3556 }
3557
3558 if (profile_cap.id) {
3559 if(!vdec_query_cap(profile_cap)) {
3560 DEBUG_PRINT_ERROR("Getting capabilities for profile failed");
3561 return OMX_ErrorHardware;
3562 }
3563 }
3564
3565 if (level_cap.id) {
3566 if(!vdec_query_cap(level_cap)) {
3567 DEBUG_PRINT_ERROR("Getting capabilities for level failed");
3568 return OMX_ErrorHardware;
3569 }
3570 }
3571
3572 /* Get the corresponding omx level from v4l2 level */
3573 if (!profile_level_converter::convert_v4l2_level_to_omx(output_capability, level_cap.maximum, (int *)&profileLevelType->eLevel)) {
3574 DEBUG_PRINT_ERROR("Invalid level, cannot find corresponding v4l2 level : %d ", level_cap.maximum);
3575 return OMX_ErrorHardware;
3576 }
3577
3578 /* For given profile index get corresponding profile that needs to be supported */
3579 if (profileLevelType->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
3580 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %u", (unsigned int)profileLevelType->nPortIndex);
3581 return OMX_ErrorBadPortIndex;
3582 }
3583
3584 if (output_capability == V4L2_PIX_FMT_H264) {
3585 if (profileLevelType->nProfileIndex < (sizeof(avc_profiles)/sizeof(int))) {
3586 profileLevelType->eProfile = avc_profiles[profileLevelType->nProfileIndex];
3587 } else {
3588 DEBUG_PRINT_LOW("AVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3589 (unsigned int)profileLevelType->nProfileIndex);
3590 return OMX_ErrorNoMore;
3591 }
3592 } else if (output_capability == V4L2_PIX_FMT_VP8) {
3593 if (profileLevelType->nProfileIndex == 0) {
3594 profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
3595 } else {
3596 DEBUG_PRINT_LOW("VP8: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3597 (unsigned int)profileLevelType->nProfileIndex);
3598 return OMX_ErrorNoMore;
3599 }
3600 /* Driver has no notion of VP8 profile. Only one profile is supported. Return this */
3601 return OMX_ErrorNone;
3602 } else if (output_capability == V4L2_PIX_FMT_VP9) {
3603 if (profileLevelType->nProfileIndex < (sizeof(vp9_profiles)/sizeof(int))) {
3604 profileLevelType->eProfile = vp9_profiles[profileLevelType->nProfileIndex];
3605 } else {
3606 DEBUG_PRINT_LOW("VP9: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3607 (unsigned int)profileLevelType->nProfileIndex);
3608 return OMX_ErrorNoMore;
3609 }
3610 } else if (output_capability == V4L2_PIX_FMT_HEVC) {
3611 if (profileLevelType->nProfileIndex < (sizeof(hevc_profiles)/sizeof(int))) {
3612 profileLevelType->eProfile = hevc_profiles[profileLevelType->nProfileIndex];
3613 } else {
3614 DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3615 (unsigned int)profileLevelType->nProfileIndex);
3616 return OMX_ErrorNoMore;
3617 }
3618 } else if (output_capability == V4L2_PIX_FMT_MPEG2) {
3619 if (profileLevelType->nProfileIndex < (sizeof(mpeg2_profiles)/sizeof(int))) {
3620 profileLevelType->eProfile = mpeg2_profiles[profileLevelType->nProfileIndex];
3621 } else {
3622 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
3623 (unsigned int)profileLevelType->nProfileIndex);
3624 return OMX_ErrorNoMore;
3625 }
3626 }
3627
3628 /* Check if the profile is supported by driver or not */
3629 /* During query caps of profile driver sends a mask of */
3630 /* of all v4l2 profiles supported(in the flags field) */
3631 if((output_capability != V4L2_PIX_FMT_HEVC) &&
3632 (output_capability != V4L2_PIX_FMT_VP9)) {
3633 if (!profile_level_converter::convert_omx_profile_to_v4l2(output_capability, profileLevelType->eProfile, &v4l2_profile)) {
3634 DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
3635 return OMX_ErrorHardware;
3636 }
3637 }else if(output_capability == V4L2_PIX_FMT_HEVC) { //convert omx profile to v4l2 profile for HEVC Main10 and Main10HDR10 profiles,seperately
3638 switch (profileLevelType->eProfile) {
3639 case OMX_VIDEO_HEVCProfileMain:
3640 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
3641 break;
3642 case OMX_VIDEO_HEVCProfileMain10:
3643 case OMX_VIDEO_HEVCProfileMain10HDR10:
3644 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
3645 break;
3646 default:
3647 DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
3648 return OMX_ErrorHardware;
3649 }
3650 }else { //convert omx profile to v4l2 profile for VP9 Profile2 and VP9 Profile2HDR profiles,seperately
3651 switch (profileLevelType->eProfile) {
3652 case OMX_VIDEO_VP9Profile0:
3653 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P0;
3654 break;
3655 case OMX_VIDEO_VP9Profile2:
3656 case OMX_VIDEO_VP9Profile2HDR:
3657 v4l2_profile = V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P2_10;
3658 break;
3659 default:
3660 DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
3661 return OMX_ErrorHardware;
3662 }
3663 }
3664 if(!((profile_cap.flags >> v4l2_profile) & 0x1)) {
3665 DEBUG_PRINT_ERROR("%s: Invalid index corresponding profile not supported : %d ",__FUNCTION__, profileLevelType->eProfile);
3666 eRet = OMX_ErrorNoMore;
3667 }
3668
3669 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%u, Level:%u",
3670 (unsigned int)profileLevelType->eProfile, (unsigned int)profileLevelType->eLevel);
3671 return eRet;
3672 }
3673
3674 /* ======================================================================
3675 FUNCTION
3676 omx_vdec::GetParameter
3677
3678 DESCRIPTION
3679 OMX Get Parameter method implementation
3680
3681 PARAMETERS
3682 <TBD>.
3683
3684 RETURN VALUE
3685 Error None if successful.
3686
3687 ========================================================================== */
get_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_INOUT OMX_PTR paramData)3688 OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
3689 OMX_IN OMX_INDEXTYPE paramIndex,
3690 OMX_INOUT OMX_PTR paramData)
3691 {
3692 (void) hComp;
3693 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3694
3695 DEBUG_PRINT_LOW("get_parameter:");
3696 if (m_state == OMX_StateInvalid) {
3697 DEBUG_PRINT_ERROR("Get Param in Invalid State");
3698 return OMX_ErrorInvalidState;
3699 }
3700 if (paramData == NULL) {
3701 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
3702 return OMX_ErrorBadParameter;
3703 }
3704 switch ((unsigned long)paramIndex) {
3705 case OMX_IndexParamPortDefinition: {
3706 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
3707 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
3708 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3709 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
3710
3711 OMX_COLOR_FORMATTYPE drv_color_format;
3712 bool status = false;
3713
3714 if (!client_buffers.is_color_conversion_enabled()) {
3715 status = client_buffers.get_color_format(drv_color_format);
3716 }
3717
3718 if (decide_dpb_buffer_mode()) {
3719 DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed", __func__);
3720 return OMX_ErrorBadParameter;
3721 }
3722
3723 if (status) {
3724 if (!client_buffers.is_color_conversion_enabled()) {
3725 client_buffers.set_client_buffers_disabled(true);
3726 client_buffers.set_color_format(drv_color_format);
3727 }
3728 }
3729
3730 eRet = update_portdef(portDefn);
3731 if (eRet == OMX_ErrorNone)
3732 m_port_def = *portDefn;
3733 break;
3734 }
3735 case OMX_IndexParamVideoInit: {
3736 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
3737 OMX_PORT_PARAM_TYPE *portParamType =
3738 (OMX_PORT_PARAM_TYPE *) paramData;
3739 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
3740
3741 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
3742 portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
3743 portParamType->nPorts = 2;
3744 portParamType->nStartPortNumber = 0;
3745 break;
3746 }
3747 case OMX_IndexParamVideoPortFormat: {
3748 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
3749 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3750 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3751 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
3752
3753 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
3754 portFmt->nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
3755
3756 if (0 == portFmt->nPortIndex) {
3757 if (0 == portFmt->nIndex) {
3758 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
3759 portFmt->eCompressionFormat = eCompressionFormat;
3760 } else {
3761 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
3762 " NoMore compression formats");
3763 eRet = OMX_ErrorNoMore;
3764 }
3765 } else if (1 == portFmt->nPortIndex) {
3766 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
3767
3768 // Distinguish non-surface mode from normal playback use-case based on
3769 // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
3770 // For non-android, use the default list
3771 // Also use default format-list if FLEXIBLE YUV is supported,
3772 // as the client negotiates the standard color-format if it needs to
3773 bool useNonSurfaceMode = false;
3774 #if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED) && !defined(USE_GBM)
3775 useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
3776 #endif
3777 portFmt->eColorFormat = useNonSurfaceMode ?
3778 getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
3779 getPreferredColorFormatDefaultMode(portFmt->nIndex);
3780
3781 if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
3782 eRet = OMX_ErrorNoMore;
3783 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
3784 " NoMore Color formats");
3785 }
3786 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
3787 } else {
3788 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
3789 (int)portFmt->nPortIndex);
3790 eRet = OMX_ErrorBadPortIndex;
3791 }
3792 break;
3793 }
3794 /*Component should support this port definition*/
3795 case OMX_IndexParamAudioInit: {
3796 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
3797 OMX_PORT_PARAM_TYPE *audioPortParamType =
3798 (OMX_PORT_PARAM_TYPE *) paramData;
3799 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
3800 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
3801 audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
3802 audioPortParamType->nPorts = 0;
3803 audioPortParamType->nStartPortNumber = 0;
3804 break;
3805 }
3806 /*Component should support this port definition*/
3807 case OMX_IndexParamImageInit: {
3808 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
3809 OMX_PORT_PARAM_TYPE *imagePortParamType =
3810 (OMX_PORT_PARAM_TYPE *) paramData;
3811 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
3812 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
3813 imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
3814 imagePortParamType->nPorts = 0;
3815 imagePortParamType->nStartPortNumber = 0;
3816 break;
3817
3818 }
3819 /*Component should support this port definition*/
3820 case OMX_IndexParamOtherInit: {
3821 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
3822 paramIndex);
3823 eRet =OMX_ErrorUnsupportedIndex;
3824 break;
3825 }
3826 case OMX_IndexParamStandardComponentRole: {
3827 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
3828 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3829 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3830 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
3831 comp_role->nSize = sizeof(*comp_role);
3832
3833 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
3834 paramIndex);
3835 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
3836 OMX_MAX_STRINGNAME_SIZE);
3837 break;
3838 }
3839 /* Added for parameter test */
3840 case OMX_IndexParamPriorityMgmt: {
3841 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
3842 OMX_PRIORITYMGMTTYPE *priorityMgmType =
3843 (OMX_PRIORITYMGMTTYPE *) paramData;
3844 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
3845 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
3846 priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE);
3847
3848 break;
3849 }
3850 /* Added for parameter test */
3851 case OMX_IndexParamCompBufferSupplier: {
3852 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
3853 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
3854 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3855 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
3856
3857 bufferSupplierType->nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
3858 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
3859 if (0 == bufferSupplierType->nPortIndex)
3860 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
3861 else if (1 == bufferSupplierType->nPortIndex)
3862 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
3863 else
3864 eRet = OMX_ErrorBadPortIndex;
3865
3866
3867 break;
3868 }
3869 case OMX_IndexParamVideoAvc: {
3870 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
3871 paramIndex);
3872 break;
3873 }
3874 case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
3875 DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x",
3876 paramIndex);
3877 break;
3878 }
3879 case OMX_IndexParamVideoMpeg2: {
3880 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
3881 paramIndex);
3882 break;
3883 }
3884 case OMX_IndexParamVideoProfileLevelQuerySupported: {
3885 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
3886 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
3887 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
3888 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
3889 eRet = get_supported_profile_level(profileLevelType);
3890 break;
3891 }
3892 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3893 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
3894 VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams);
3895 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
3896 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
3897 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3898
3899 if (secure_mode && !secure_scaling_to_non_secure_opb) {
3900 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
3901 GRALLOC_USAGE_PRIVATE_UNCACHED);
3902 } else {
3903 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED;
3904 }
3905 } else {
3906 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
3907 eRet = OMX_ErrorBadParameter;
3908 }
3909 }
3910 break;
3911 #endif
3912
3913 #ifdef FLEXYUV_SUPPORTED
3914 case OMX_QcomIndexFlexibleYUVDescription: {
3915 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
3916 VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams);
3917 eRet = describeColorFormat(paramData);
3918 if (eRet == OMX_ErrorUnsupportedSetting) {
3919 DEBUG_PRINT_LOW("The standard OMX linear formats are understood by client. Please ignore this Unsupported Setting (0x80001019).");
3920 }
3921 break;
3922 }
3923 #endif
3924 case OMX_IndexParamVideoProfileLevelCurrent: {
3925 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
3926 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3927 struct v4l2_control profile_control, level_control;
3928
3929 switch (drv_ctx.decoder_format) {
3930 case VDEC_CODECTYPE_H264:
3931 profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
3932 level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
3933 break;
3934 default:
3935 DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264");
3936 eRet = OMX_ErrorNotImplemented;
3937 break;
3938 }
3939
3940 if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) {
3941 switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) {
3942 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
3943 pParam->eProfile = OMX_VIDEO_AVCProfileBaseline;
3944 break;
3945 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
3946 pParam->eProfile = OMX_VIDEO_AVCProfileConstrainedBaseline;
3947 break;
3948 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
3949 pParam->eProfile = OMX_VIDEO_AVCProfileConstrainedHigh;
3950 break;
3951 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
3952 pParam->eProfile = OMX_VIDEO_AVCProfileMain;
3953 break;
3954 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
3955 pParam->eProfile = OMX_VIDEO_AVCProfileExtended;
3956 break;
3957 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
3958 pParam->eProfile = OMX_VIDEO_AVCProfileHigh;
3959 break;
3960 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
3961 pParam->eProfile = OMX_VIDEO_AVCProfileHigh10;
3962 break;
3963 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
3964 pParam->eProfile = OMX_VIDEO_AVCProfileHigh422;
3965 break;
3966 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
3967 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
3968 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
3969 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
3970 case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
3971 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
3972 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
3973 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
3974 case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
3975 case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
3976 eRet = OMX_ErrorUnsupportedIndex;
3977 break;
3978 }
3979 } else {
3980 eRet = OMX_ErrorUnsupportedIndex;
3981 }
3982
3983
3984 if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) {
3985 switch ((enum v4l2_mpeg_video_h264_level)level_control.value) {
3986 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
3987 pParam->eLevel = OMX_VIDEO_AVCLevel1;
3988 break;
3989 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
3990 pParam->eLevel = OMX_VIDEO_AVCLevel1b;
3991 break;
3992 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
3993 pParam->eLevel = OMX_VIDEO_AVCLevel11;
3994 break;
3995 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
3996 pParam->eLevel = OMX_VIDEO_AVCLevel12;
3997 break;
3998 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
3999 pParam->eLevel = OMX_VIDEO_AVCLevel13;
4000 break;
4001 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
4002 pParam->eLevel = OMX_VIDEO_AVCLevel2;
4003 break;
4004 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
4005 pParam->eLevel = OMX_VIDEO_AVCLevel21;
4006 break;
4007 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
4008 pParam->eLevel = OMX_VIDEO_AVCLevel22;
4009 break;
4010 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
4011 pParam->eLevel = OMX_VIDEO_AVCLevel3;
4012 break;
4013 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
4014 pParam->eLevel = OMX_VIDEO_AVCLevel31;
4015 break;
4016 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
4017 pParam->eLevel = OMX_VIDEO_AVCLevel32;
4018 break;
4019 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
4020 pParam->eLevel = OMX_VIDEO_AVCLevel4;
4021 break;
4022 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
4023 pParam->eLevel = OMX_VIDEO_AVCLevel41;
4024 break;
4025 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
4026 pParam->eLevel = OMX_VIDEO_AVCLevel42;
4027 break;
4028 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
4029 pParam->eLevel = OMX_VIDEO_AVCLevel5;
4030 break;
4031 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
4032 pParam->eLevel = OMX_VIDEO_AVCLevel51;
4033 break;
4034 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
4035 pParam->eLevel = OMX_VIDEO_AVCLevel52;
4036 break;
4037 case V4L2_MPEG_VIDEO_H264_LEVEL_6_0:
4038 pParam->eLevel = OMX_VIDEO_AVCLevel6;
4039 break;
4040 case V4L2_MPEG_VIDEO_H264_LEVEL_6_1:
4041 pParam->eLevel = OMX_VIDEO_AVCLevel61;
4042 break;
4043 case V4L2_MPEG_VIDEO_H264_LEVEL_6_2:
4044 pParam->eLevel = OMX_VIDEO_AVCLevel62;
4045 break;
4046 default:
4047 eRet = OMX_ErrorUnsupportedIndex;
4048 break;
4049 }
4050 } else {
4051 eRet = OMX_ErrorUnsupportedIndex;
4052 }
4053
4054 break;
4055
4056 }
4057 case OMX_QTIIndexParamVideoClientExtradata:
4058 {
4059 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
4060 DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVideoClientExtradata");
4061 QOMX_EXTRADATA_ENABLE *pParam =
4062 (QOMX_EXTRADATA_ENABLE *)paramData;
4063 if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
4064 pParam->bEnable = client_extradata ? OMX_TRUE : OMX_FALSE;
4065 eRet = OMX_ErrorNone;
4066 } else {
4067 eRet = OMX_ErrorUnsupportedIndex;
4068 }
4069 break;
4070 }
4071 case OMX_QTIIndexParamDitherControl:
4072 {
4073 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL);
4074 DEBUG_PRINT_LOW("get_parameter: QOMX_VIDEO_DITHER_CONTROL");
4075 QOMX_VIDEO_DITHER_CONTROL *pParam =
4076 (QOMX_VIDEO_DITHER_CONTROL *) paramData;
4077 pParam->eDitherType = (QOMX_VIDEO_DITHERTYPE) m_dither_config;
4078 eRet = OMX_ErrorNone;
4079 break;
4080 }
4081 case OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency:
4082 {
4083 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
4084 DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency");
4085 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pParam =
4086 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) paramData;
4087 pParam->eProfile = mClientSetProfile;
4088 pParam->eLevel = mClientSetLevel;
4089 eRet = OMX_ErrorNone;
4090 break;
4091 }
4092 default: {
4093 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
4094 eRet =OMX_ErrorUnsupportedIndex;
4095 }
4096
4097 }
4098
4099 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
4100 drv_ctx.video_resolution.frame_width,
4101 drv_ctx.video_resolution.frame_height,
4102 drv_ctx.video_resolution.stride,
4103 drv_ctx.video_resolution.scan_lines);
4104
4105 return eRet;
4106 }
4107
4108 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_PTR data)4109 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
4110 {
4111 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
4112 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4113 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
4114
4115 if ((params == NULL) ||
4116 (params->nativeBuffer == NULL) ||
4117 (params->nativeBuffer->handle == NULL) ||
4118 !m_enable_android_native_buffers)
4119 return OMX_ErrorBadParameter;
4120 m_use_android_native_buffers = OMX_TRUE;
4121 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4122 private_handle_t *handle = (private_handle_t *)nBuf->handle;
4123 if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
4124 OMX_U8 *buffer = NULL;
4125 if (!secure_mode) {
4126 buffer = (OMX_U8*)mmap(0, handle->size,
4127 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4128 if (buffer == MAP_FAILED) {
4129 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4130 return OMX_ErrorInsufficientResources;
4131 }
4132 }
4133 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
4134 } else {
4135 eRet = OMX_ErrorBadParameter;
4136 }
4137 return eRet;
4138 }
4139 #endif
4140
enable_smoothstreaming()4141 OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
4142 struct v4l2_control control;
4143 struct v4l2_format fmt;
4144 /*control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
4145 control.value = 1;
4146 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
4147 if (rc < 0) {
4148 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
4149 return OMX_ErrorHardware;
4150 }*/
4151 m_smoothstreaming_mode = true;
4152 return OMX_ErrorNone;
4153 }
4154
4155 /* ======================================================================
4156 FUNCTION
4157 omx_vdec::Setparameter
4158
4159 DESCRIPTION
4160 OMX Set Parameter method implementation.
4161
4162 PARAMETERS
4163 <TBD>.
4164
4165 RETURN VALUE
4166 OMX Error None if successful.
4167
4168 ========================================================================== */
set_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_IN OMX_PTR paramData)4169 OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
4170 OMX_IN OMX_INDEXTYPE paramIndex,
4171 OMX_IN OMX_PTR paramData)
4172 {
4173 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4174 int ret=0;
4175 struct v4l2_format fmt;
4176 #ifdef _ANDROID_
4177 char property_value[PROPERTY_VALUE_MAX] = {0};
4178 #endif
4179 if (m_state == OMX_StateInvalid) {
4180 DEBUG_PRINT_ERROR("Set Param in Invalid State");
4181 return OMX_ErrorInvalidState;
4182 }
4183 if (paramData == NULL) {
4184 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
4185 return OMX_ErrorBadParameter;
4186 }
4187 if ((m_state != OMX_StateLoaded) &&
4188 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
4189 (m_out_bEnabled == OMX_TRUE) &&
4190 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
4191 (m_inp_bEnabled == OMX_TRUE)) {
4192 DEBUG_PRINT_ERROR("Set Param in Invalid State");
4193 return OMX_ErrorIncorrectStateOperation;
4194 }
4195 switch ((unsigned long)paramIndex) {
4196 case OMX_IndexParamPortDefinition: {
4197 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
4198 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
4199 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
4200 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
4201 //been called.
4202 DEBUG_PRINT_LOW(
4203 "set_parameter: OMX_IndexParamPortDefinition: dir %d port %d wxh %dx%d count: min %d actual %d size %d",
4204 (int)portDefn->eDir, (int)portDefn->nPortIndex,
4205 (int)portDefn->format.video.nFrameWidth,
4206 (int)portDefn->format.video.nFrameHeight,
4207 (int)portDefn->nBufferCountMin,
4208 (int)portDefn->nBufferCountActual,
4209 (int)portDefn->nBufferSize);
4210
4211 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
4212 DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d",
4213 portDefn->nBufferCountActual);
4214 eRet = OMX_ErrorBadParameter;
4215 break;
4216 }
4217 if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) {
4218 if (portDefn->nBufferCountActual < MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS ||
4219 portDefn->nBufferSize != m_client_out_extradata_info.getSize()) {
4220 DEBUG_PRINT_ERROR("ERROR: Bad parameeters request for extradata limit %d size - %d",
4221 portDefn->nBufferCountActual, portDefn->nBufferSize);
4222 eRet = OMX_ErrorBadParameter;
4223 break;
4224 }
4225 m_client_out_extradata_info.set_extradata_info(portDefn->nBufferSize,
4226 portDefn->nBufferCountActual);
4227 break;
4228 }
4229
4230 if (OMX_DirOutput == portDefn->eDir) {
4231 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
4232 bool port_format_changed = false;
4233 m_display_id = portDefn->format.video.pNativeWindow;
4234 unsigned int buffer_size;
4235 /* update output port resolution with client supplied dimensions
4236 in case scaling is enabled, else it follows input resolution set
4237 */
4238 if (decide_dpb_buffer_mode()) {
4239 DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed", __func__);
4240 return OMX_ErrorBadParameter;
4241 }
4242 if (is_down_scalar_enabled) {
4243 DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)",
4244 (unsigned int)portDefn->format.video.nFrameWidth,
4245 (unsigned int)portDefn->format.video.nFrameHeight);
4246 if (portDefn->format.video.nFrameHeight != 0x0 &&
4247 portDefn->format.video.nFrameWidth != 0x0) {
4248 memset(&fmt, 0x0, sizeof(struct v4l2_format));
4249 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4250 fmt.fmt.pix_mp.pixelformat = capture_capability;
4251 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
4252 if (ret) {
4253 DEBUG_PRINT_ERROR("Get Resolution failed");
4254 eRet = OMX_ErrorHardware;
4255 break;
4256 }
4257 if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) ||
4258 (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) {
4259 port_format_changed = true;
4260 }
4261
4262 /* set crop info */
4263 rectangle.nLeft = 0;
4264 rectangle.nTop = 0;
4265 rectangle.nWidth = portDefn->format.video.nFrameWidth;
4266 rectangle.nHeight = portDefn->format.video.nFrameHeight;
4267
4268 m_extradata_info.output_crop_rect.nLeft = 0;
4269 m_extradata_info.output_crop_rect.nTop = 0;
4270 m_extradata_info.output_crop_rect.nWidth = rectangle.nWidth;
4271 m_extradata_info.output_crop_rect.nHeight = rectangle.nHeight;
4272
4273 memset(&fmt, 0x0, sizeof(struct v4l2_format));
4274 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4275 fmt.fmt.pix_mp.height = (unsigned int)portDefn->format.video.nFrameHeight;
4276 fmt.fmt.pix_mp.width = (unsigned int)portDefn->format.video.nFrameWidth;
4277 fmt.fmt.pix_mp.pixelformat = capture_capability;
4278 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
4279 fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width);
4280 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4281 if (ret) {
4282 DEBUG_PRINT_ERROR("Set Resolution failed");
4283 eRet = OMX_ErrorUnsupportedSetting;
4284 } else
4285 eRet = get_buffer_req(&drv_ctx.op_buf);
4286 }
4287
4288 if (eRet) {
4289 break;
4290 }
4291 }
4292
4293 if (eRet) {
4294 break;
4295 }
4296
4297 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
4298 DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)",
4299 portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
4300 eRet = OMX_ErrorBadParameter;
4301 } else if (!client_buffers.get_buffer_req(buffer_size)) {
4302 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
4303 eRet = OMX_ErrorBadParameter;
4304 } else if (!port_format_changed) {
4305
4306 // Buffer count can change only when port is unallocated
4307 if (m_out_mem_ptr &&
4308 (portDefn->nBufferCountActual != drv_ctx.op_buf.actualcount ||
4309 portDefn->nBufferSize != drv_ctx.op_buf.buffer_size)) {
4310
4311 DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !");
4312 eRet = OMX_ErrorInvalidState;
4313 break;
4314 }
4315
4316 // route updating of buffer requirements via c2d proxy.
4317 // Based on whether c2d is enabled, requirements will be handed
4318 // to the vidc driver appropriately
4319 eRet = client_buffers.set_buffer_req(portDefn->nBufferSize,
4320 portDefn->nBufferCountActual);
4321 if (eRet == OMX_ErrorNone) {
4322 m_port_def = *portDefn;
4323 } else {
4324 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)",
4325 drv_ctx.op_buf.mincount, (unsigned int)buffer_size,
4326 (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
4327 eRet = OMX_ErrorBadParameter;
4328 }
4329 }
4330 } else if (OMX_DirInput == portDefn->eDir) {
4331 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
4332 bool port_format_changed = false;
4333 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
4334 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
4335 // Frame rate only should be set if this is a "known value" or to
4336 // activate ts prediction logic (arbitrary mode only) sending input
4337 // timestamps with max value (LLONG_MAX).
4338 m_fps_received = portDefn->format.video.xFramerate;
4339 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u",
4340 (unsigned int)portDefn->format.video.xFramerate >> 16);
4341 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
4342 drv_ctx.frame_rate.fps_denominator);
4343 if (!drv_ctx.frame_rate.fps_numerator) {
4344 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
4345 drv_ctx.frame_rate.fps_numerator = 30;
4346 }
4347 if (drv_ctx.frame_rate.fps_denominator)
4348 drv_ctx.frame_rate.fps_numerator = (int)
4349 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
4350 drv_ctx.frame_rate.fps_denominator = 1;
4351 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
4352 drv_ctx.frame_rate.fps_numerator;
4353 DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
4354 (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
4355 (float)drv_ctx.frame_rate.fps_denominator);
4356
4357 struct v4l2_outputparm oparm;
4358 /*XXX: we're providing timing info as seconds per frame rather than frames
4359 * per second.*/
4360 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
4361 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
4362
4363 struct v4l2_streamparm sparm;
4364 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4365 sparm.parm.output = oparm;
4366 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
4367 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
4368 eRet = OMX_ErrorHardware;
4369 break;
4370 }
4371 }
4372
4373 if (drv_ctx.video_resolution.frame_height !=
4374 portDefn->format.video.nFrameHeight ||
4375 drv_ctx.video_resolution.frame_width !=
4376 portDefn->format.video.nFrameWidth) {
4377 DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)",
4378 (unsigned int)portDefn->format.video.nFrameWidth,
4379 (unsigned int)portDefn->format.video.nFrameHeight);
4380 port_format_changed = true;
4381 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
4382 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
4383 if (frameHeight != 0x0 && frameWidth != 0x0) {
4384 if (m_smoothstreaming_mode &&
4385 ((frameWidth * frameHeight) <
4386 (m_smoothstreaming_width * m_smoothstreaming_height))) {
4387 frameWidth = m_smoothstreaming_width;
4388 frameHeight = m_smoothstreaming_height;
4389 DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u "
4390 "for adaptive-playback/smooth-streaming",
4391 (unsigned int)frameWidth, (unsigned int)frameHeight);
4392 }
4393
4394 m_extradata_info.output_crop_rect.nLeft = 0;
4395 m_extradata_info.output_crop_rect.nTop = 0;
4396 m_extradata_info.output_crop_rect.nWidth = frameWidth;
4397 m_extradata_info.output_crop_rect.nHeight = frameHeight;
4398
4399 update_resolution(frameWidth, frameHeight,
4400 frameWidth, frameHeight);
4401 if (is_down_scalar_enabled) {
4402 memset(&fmt, 0x0, sizeof(struct v4l2_format));
4403 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4404 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
4405 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
4406 fmt.fmt.pix_mp.pixelformat = output_capability;
4407 DEBUG_PRINT_LOW("DS Enabled : height = %d , width = %d",
4408 fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
4409 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4410 } else {
4411 memset(&fmt, 0x0, sizeof(struct v4l2_format));
4412 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4413 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
4414 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
4415 fmt.fmt.pix_mp.pixelformat = output_capability;
4416 DEBUG_PRINT_LOW("DS Disabled : height = %d , width = %d",
4417 fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
4418 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4419 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4420 fmt.fmt.pix_mp.pixelformat = capture_capability;
4421 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4422 }
4423 if (ret) {
4424 DEBUG_PRINT_ERROR("Set Resolution failed");
4425 eRet = OMX_ErrorUnsupportedSetting;
4426 } else {
4427 if (!is_down_scalar_enabled)
4428 eRet = get_buffer_req(&drv_ctx.op_buf);
4429 }
4430 if (eRet)
4431 break;
4432 }
4433 }
4434 if (m_custom_buffersize.input_buffersize
4435 && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
4436 DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
4437 m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
4438 eRet = OMX_ErrorBadParameter;
4439 break;
4440 }
4441 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
4442 DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)",
4443 portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
4444 eRet = OMX_ErrorBadParameter;
4445 break;
4446 }
4447 // Buffer count can change only when port is unallocated
4448 if (m_inp_mem_ptr &&
4449 (portDefn->nBufferCountActual != drv_ctx.ip_buf.actualcount ||
4450 portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)) {
4451 DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !");
4452 eRet = OMX_ErrorInvalidState;
4453 break;
4454 }
4455
4456 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
4457 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
4458 port_format_changed = true;
4459 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
4460 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
4461 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
4462 (~(buffer_prop->alignment - 1));
4463 eRet = set_buffer_req(buffer_prop);
4464 }
4465 if (false == port_format_changed) {
4466 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)",
4467 drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size,
4468 (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
4469 eRet = OMX_ErrorBadParameter;
4470 }
4471 } else if (portDefn->eDir == OMX_DirMax) {
4472 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
4473 (int)portDefn->nPortIndex);
4474 eRet = OMX_ErrorBadPortIndex;
4475 }
4476 }
4477 break;
4478 case OMX_IndexParamVideoPortFormat: {
4479 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
4480 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
4481 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
4482 int ret=0;
4483 struct v4l2_format fmt;
4484 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u",
4485 portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex);
4486
4487 memset(&fmt, 0x0, sizeof(struct v4l2_format));
4488 if (1 == portFmt->nPortIndex) {
4489 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4490 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
4491 if (ret < 0) {
4492 DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
4493 return OMX_ErrorBadParameter;
4494 }
4495 enum vdec_output_format op_format;
4496 if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
4497 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
4498 portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
4499 op_format = (enum vdec_output_format)VDEC_YUV_FORMAT_NV12;
4500 fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12;
4501 //check if the required color format is a supported flexible format
4502 is_flexible_format = check_supported_flexible_formats(portFmt->eColorFormat);
4503 } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
4504 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed ||
4505 portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar) {
4506 op_format = (enum vdec_output_format)VDEC_YUV_FORMAT_NV12_UBWC;
4507 fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC;
4508 //check if the required color format is a supported flexible format
4509 is_flexible_format = check_supported_flexible_formats(portFmt->eColorFormat);
4510 } else {
4511 eRet = OMX_ErrorBadParameter;
4512 }
4513
4514 if (eRet == OMX_ErrorNone) {
4515 drv_ctx.output_format = op_format;
4516 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
4517 if (ret) {
4518 DEBUG_PRINT_ERROR("Set output format failed");
4519 eRet = OMX_ErrorUnsupportedSetting;
4520 /*TODO: How to handle this case */
4521 } else {
4522 eRet = get_buffer_req(&drv_ctx.op_buf);
4523 }
4524 }
4525 if (eRet == OMX_ErrorNone) {
4526 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
4527 DEBUG_PRINT_ERROR("Set color format failed");
4528 eRet = OMX_ErrorBadParameter;
4529 }
4530 }
4531 }
4532 }
4533 break;
4534 case OMX_QcomIndexPortDefn: {
4535 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
4536 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
4537 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
4538 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u",
4539 (unsigned int)portFmt->nFramePackingFormat);
4540
4541 /* Input port */
4542 if (portFmt->nPortIndex == 0) {
4543 // arbitrary_bytes mode cannot be changed arbitrarily since this controls how:
4544 // - headers are allocated and
4545 // - headers-indices are derived
4546 // Avoid changing arbitrary_bytes when the port is already allocated
4547 if (m_inp_mem_ptr) {
4548 DEBUG_PRINT_ERROR("Cannot change arbitrary-bytes-mode since input port is not free!");
4549 return OMX_ErrorUnsupportedSetting;
4550 }
4551 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
4552 if (secure_mode || m_input_pass_buffer_fd) {
4553 arbitrary_bytes = false;
4554 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode");
4555 eRet = OMX_ErrorUnsupportedSetting;
4556 } else {
4557 arbitrary_bytes = true;
4558 }
4559 } else if (portFmt->nFramePackingFormat ==
4560 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
4561 arbitrary_bytes = false;
4562 } else {
4563 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u",
4564 (unsigned int)portFmt->nFramePackingFormat);
4565 eRet = OMX_ErrorUnsupportedSetting;
4566 }
4567 //Explicitly disable arb mode for unsupported codecs
4568 bool is_arb_supported = false;
4569 if (arbitrary_bytes) {
4570 switch (drv_ctx.decoder_format) {
4571 case VDEC_CODECTYPE_H264:
4572 is_arb_supported = m_arb_mode_override & VDEC_ARB_CODEC_H264;
4573 break;
4574 case VDEC_CODECTYPE_HEVC:
4575 is_arb_supported = m_arb_mode_override & VDEC_ARB_CODEC_HEVC;
4576 break;
4577 case VDEC_CODECTYPE_MPEG2:
4578 is_arb_supported = m_arb_mode_override & VDEC_ARB_CODEC_MPEG2;
4579 break;
4580 default:
4581 DEBUG_PRINT_HIGH("Arbitrary bytes mode not enabled for this Codec");
4582 break;
4583 }
4584
4585 if (!is_arb_supported) {
4586 DEBUG_PRINT_ERROR("Setparameter: Disabling arbitrary bytes mode explicitly");
4587 arbitrary_bytes = false;
4588 eRet = OMX_ErrorUnsupportedSetting;
4589 }
4590 }
4591 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
4592 DEBUG_PRINT_ERROR("Unsupported at O/P port");
4593 eRet = OMX_ErrorUnsupportedSetting;
4594 }
4595 break;
4596 }
4597 case OMX_QTIIndexParamVideoClientExtradata: {
4598 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
4599 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoClientExtradata");
4600 QOMX_EXTRADATA_ENABLE *pParam =
4601 (QOMX_EXTRADATA_ENABLE *)paramData;
4602
4603 if (m_state != OMX_StateLoaded) {
4604 DEBUG_PRINT_ERROR("Set Parameter called in Invalid state");
4605 return OMX_ErrorIncorrectStateOperation;
4606 }
4607
4608 if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
4609 m_client_out_extradata_info.enable_client_extradata(pParam->bEnable);
4610 } else {
4611 DEBUG_PRINT_ERROR("Incorrect portIndex - %d", pParam->nPortIndex);
4612 eRet = OMX_ErrorUnsupportedIndex;
4613 }
4614 break;
4615 }
4616 case OMX_IndexParamStandardComponentRole: {
4617 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
4618 OMX_PARAM_COMPONENTROLETYPE *comp_role;
4619 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
4620 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
4621 comp_role->cRole);
4622
4623 if ((m_state == OMX_StateLoaded)&&
4624 !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_IDLE_PENDING)) {
4625 DEBUG_PRINT_LOW("Set Parameter called in valid state");
4626 } else {
4627 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
4628 return OMX_ErrorIncorrectStateOperation;
4629 }
4630
4631 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
4632 if (!strncmp((char*)comp_role->cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
4633 strlcpy((char*)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE);
4634 } else {
4635 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4636 eRet =OMX_ErrorUnsupportedSetting;
4637 }
4638 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
4639 if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
4640 strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
4641 } else {
4642 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4643 eRet = OMX_ErrorUnsupportedSetting;
4644 }
4645 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
4646 if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
4647 strlcpy((char*)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE);
4648 } else {
4649 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4650 eRet = OMX_ErrorUnsupportedSetting;
4651 }
4652 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
4653 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
4654 !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
4655 strlcpy((char*)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE);
4656 } else {
4657 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4658 eRet = OMX_ErrorUnsupportedSetting;
4659 }
4660 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
4661 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) ||
4662 !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
4663 strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE);
4664 } else {
4665 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4666 eRet = OMX_ErrorUnsupportedSetting;
4667 }
4668 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
4669 if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
4670 strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
4671 } else {
4672 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
4673 eRet = OMX_ErrorUnsupportedSetting;
4674 }
4675 } else {
4676 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
4677 eRet = OMX_ErrorInvalidComponentName;
4678 }
4679 break;
4680 }
4681
4682 case OMX_IndexParamPriorityMgmt: {
4683 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
4684 if (m_state != OMX_StateLoaded) {
4685 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
4686 return OMX_ErrorIncorrectStateOperation;
4687 }
4688 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
4689 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
4690 (unsigned int)priorityMgmtype->nGroupID);
4691
4692 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
4693 (unsigned int)priorityMgmtype->nGroupPriority);
4694
4695 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
4696 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
4697
4698 break;
4699 }
4700
4701 case OMX_IndexParamCompBufferSupplier: {
4702 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
4703 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
4704 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
4705 bufferSupplierType->eBufferSupplier);
4706 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
4707 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
4708
4709 else
4710
4711 eRet = OMX_ErrorBadPortIndex;
4712
4713 break;
4714
4715 }
4716 case OMX_IndexParamVideoAvc: {
4717 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
4718 paramIndex);
4719 break;
4720 }
4721 case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
4722 DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d",
4723 paramIndex);
4724 break;
4725 }
4726 case OMX_IndexParamVideoMpeg2: {
4727 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
4728 paramIndex);
4729 break;
4730 }
4731 case OMX_QTIIndexParamLowLatencyMode: {
4732 struct v4l2_control control;
4733 int rc = 0;
4734 QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE* pParam =
4735 (QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE*)paramData;
4736 control.id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE;
4737 if (pParam->bEnableLowLatencyMode)
4738 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
4739 else
4740 control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
4741
4742 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4743 if (rc) {
4744 DEBUG_PRINT_ERROR("Set low latency failed");
4745 eRet = OMX_ErrorUnsupportedSetting;
4746 } else {
4747 m_sParamLowLatency.bEnableLowLatencyMode = pParam->bEnableLowLatencyMode;
4748 }
4749 break;
4750 }
4751 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
4752 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER);
4753 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
4754 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
4755 struct v4l2_control control;
4756 int pic_order,rc=0;
4757 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
4758 pictureOrder->eOutputPictureOrder);
4759 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
4760 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
4761 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
4762 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
4763 time_stamp_dts.set_timestamp_reorder_mode(false);
4764 } else
4765 eRet = OMX_ErrorBadParameter;
4766 if (eRet == OMX_ErrorNone) {
4767 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
4768 control.value = pic_order;
4769 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4770 if (rc) {
4771 DEBUG_PRINT_ERROR("Set picture order failed");
4772 eRet = OMX_ErrorUnsupportedSetting;
4773 }
4774 }
4775 m_decode_order_mode =
4776 pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER;
4777 break;
4778 }
4779 case OMX_QcomIndexParamConcealMBMapExtraData:
4780 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4781 eRet = enable_extradata(OMX_MB_ERROR_MAP_EXTRADATA, false,
4782 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4783 break;
4784 case OMX_QcomIndexParamFrameInfoExtraData:
4785 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4786 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
4787 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4788 break;
4789 case OMX_ExtraDataFrameDimension:
4790 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4791 eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false,
4792 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4793 break;
4794 case OMX_QcomIndexParamInterlaceExtraData:
4795 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4796 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
4797 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4798 break;
4799 case OMX_QcomIndexParamOutputCropExtraData:
4800 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4801 eRet = enable_extradata(OMX_OUTPUTCROP_EXTRADATA, false,
4802 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4803 break;
4804 case OMX_QcomIndexParamH264TimeInfo:
4805 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4806 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
4807 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4808 break;
4809 case OMX_QcomIndexParamVideoFramePackingExtradata:
4810 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4811 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
4812 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4813 break;
4814 case OMX_QcomIndexParamVideoQPExtraData:
4815 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4816 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
4817 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4818 break;
4819 case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
4820 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4821 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
4822 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4823 break;
4824 case OMX_QcomIndexEnableExtnUserData:
4825 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4826 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
4827 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4828 break;
4829 case OMX_QTIIndexParamVQZipSEIExtraData:
4830 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
4831 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
4832 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4833 break;
4834 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
4835 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
4836 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
4837 struct v4l2_control control;
4838 int rc;
4839 drv_ctx.idr_only_decoding = 1;
4840 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
4841 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
4842 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4843 if (rc) {
4844 DEBUG_PRINT_ERROR("Set picture order failed");
4845 eRet = OMX_ErrorUnsupportedSetting;
4846 } else {
4847 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
4848 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
4849 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
4850 if (rc) {
4851 DEBUG_PRINT_ERROR("Sync frame setting failed");
4852 eRet = OMX_ErrorUnsupportedSetting;
4853 }
4854 /*Setting sync frame decoding on driver might change buffer
4855 * requirements so update them here*/
4856 if (get_buffer_req(&drv_ctx.ip_buf)) {
4857 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
4858 eRet = OMX_ErrorUnsupportedSetting;
4859 }
4860 if (get_buffer_req(&drv_ctx.op_buf)) {
4861 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
4862 eRet = OMX_ErrorUnsupportedSetting;
4863 }
4864 }
4865 }
4866 break;
4867
4868 case OMX_QcomIndexParamIndexExtraDataType: {
4869 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
4870 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
4871 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
4872 (extradataIndexType->bEnabled == OMX_TRUE) &&
4873 (extradataIndexType->nPortIndex == 1)) {
4874 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
4875 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
4876 } else if ((extradataIndexType->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataOutputCropInfo) &&
4877 (extradataIndexType->bEnabled == OMX_TRUE) &&
4878 (extradataIndexType->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)) {
4879 eRet = enable_extradata(OMX_OUTPUTCROP_EXTRADATA, false,
4880 ((QOMX_ENABLETYPE *)paramData)->bEnable);
4881 }
4882 }
4883 break;
4884 case OMX_QcomIndexParamEnableSmoothStreaming: {
4885 #ifndef SMOOTH_STREAMING_DISABLED
4886 eRet = enable_smoothstreaming();
4887 #else
4888 eRet = OMX_ErrorUnsupportedSetting;
4889 #endif
4890 }
4891 break;
4892 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
4893 /* Need to allow following two set_parameters even in Idle
4894 * state. This is ANDROID architecture which is not in sync
4895 * with openmax standard. */
4896 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
4897 VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams);
4898 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
4899 if (enableNativeBuffers->nPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
4900 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers allowed only on output port!");
4901 eRet = OMX_ErrorUnsupportedSetting;
4902 break;
4903 } else if (m_out_mem_ptr) {
4904 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers is not allowed since Output port is not free !");
4905 eRet = OMX_ErrorInvalidState;
4906 break;
4907 }
4908 if (enableNativeBuffers) {
4909 m_enable_android_native_buffers = enableNativeBuffers->enable;
4910 }
4911 #if !defined(FLEXYUV_SUPPORTED)
4912 if (m_enable_android_native_buffers) {
4913 // Use the most-preferred-native-color-format as surface-mode is hinted here
4914 if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
4915 DEBUG_PRINT_ERROR("Failed to set native color format!");
4916 eRet = OMX_ErrorUnsupportedSetting;
4917 }
4918 }
4919 #endif
4920 }
4921 break;
4922 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
4923 VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams);
4924 eRet = use_android_native_buffer(hComp, paramData);
4925 }
4926 break;
4927 #if ALLOCATE_OUTPUT_NATIVEHANDLE
4928 case OMX_GoogleAndroidIndexAllocateNativeHandle: {
4929
4930 AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
4931 VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams);
4932
4933 if (allocateNativeHandleParams->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
4934 DEBUG_PRINT_LOW("Enable/Disable allocate-native-handle allowed only on input port!. Please ignore this Unsupported Setting (0x80001019).");
4935 eRet = OMX_ErrorUnsupportedSetting;
4936 break;
4937 } else if (m_inp_mem_ptr) {
4938 DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Input port is not free !");
4939 eRet = OMX_ErrorInvalidState;
4940 break;
4941 }
4942
4943 if (allocateNativeHandleParams != NULL) {
4944 allocate_native_handle = allocateNativeHandleParams->enable;
4945 }
4946 }
4947 break;
4948 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE
4949 #endif
4950 case OMX_QcomIndexParamEnableTimeStampReorder: {
4951 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER);
4952 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
4953 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
4954 if (reorder->bEnable == OMX_TRUE) {
4955 frm_int =0;
4956 time_stamp_dts.set_timestamp_reorder_mode(true);
4957 } else
4958 time_stamp_dts.set_timestamp_reorder_mode(false);
4959 } else {
4960 time_stamp_dts.set_timestamp_reorder_mode(false);
4961 if (reorder->bEnable == OMX_TRUE) {
4962 eRet = OMX_ErrorUnsupportedSetting;
4963 }
4964 }
4965 }
4966 break;
4967 case OMX_IndexParamVideoProfileLevelCurrent: {
4968 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
4969 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
4970 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
4971 if (pParam) {
4972 m_profile_lvl.eProfile = pParam->eProfile;
4973 m_profile_lvl.eLevel = pParam->eLevel;
4974 }
4975 break;
4976
4977 }
4978 case OMX_QcomIndexParamVideoMetaBufferMode:
4979 {
4980 VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams);
4981 StoreMetaDataInBuffersParams *metabuffer =
4982 (StoreMetaDataInBuffersParams *)paramData;
4983 if (!metabuffer) {
4984 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
4985 eRet = OMX_ErrorBadParameter;
4986 break;
4987 }
4988 if (m_disable_dynamic_buf_mode) {
4989 DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled");
4990 eRet = OMX_ErrorUnsupportedSetting;
4991 break;
4992 }
4993 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
4994
4995 if (m_out_mem_ptr) {
4996 DEBUG_PRINT_ERROR("Enable/Disable dynamic-buffer-mode is not allowed since Output port is not free !");
4997 eRet = OMX_ErrorInvalidState;
4998 break;
4999 }
5000
5001 dynamic_buf_mode = metabuffer->bStoreMetaData;
5002 DEBUG_PRINT_HIGH("%s buffer mode",
5003 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
5004
5005 } else {
5006 DEBUG_PRINT_ERROR(
5007 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u",
5008 (unsigned int)metabuffer->nPortIndex);
5009 eRet = OMX_ErrorUnsupportedSetting;
5010 }
5011 break;
5012 }
5013 case OMX_QcomIndexParamVideoDownScalar:
5014 {
5015 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR);
5016 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
5017 struct v4l2_control control;
5018 int rc;
5019 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar %d\n", pParam->bEnable);
5020
5021 if (pParam && pParam->bEnable) {
5022 rc = enable_downscalar();
5023 if (rc < 0) {
5024 DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
5025 return OMX_ErrorUnsupportedSetting;
5026 }
5027 m_force_down_scalar = pParam->bEnable;
5028 } else {
5029 rc = disable_downscalar();
5030 if (rc < 0) {
5031 DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
5032 return OMX_ErrorUnsupportedSetting;
5033 }
5034 m_force_down_scalar = pParam->bEnable;
5035 }
5036 break;
5037 }
5038 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
5039 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
5040 {
5041 VALIDATE_OMX_PARAM_DATA(paramData, PrepareForAdaptivePlaybackParams);
5042 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
5043 PrepareForAdaptivePlaybackParams* pParams =
5044 (PrepareForAdaptivePlaybackParams *) paramData;
5045 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
5046 if (!pParams->bEnable) {
5047 return OMX_ErrorNone;
5048 }
5049 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
5050 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
5051 DEBUG_PRINT_ERROR(
5052 "Adaptive playback request exceeds max supported resolution : [%u x %u] vs [%u x %u]",
5053 (unsigned int)pParams->nMaxFrameWidth, (unsigned int)pParams->nMaxFrameHeight,
5054 (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight);
5055 eRet = OMX_ErrorBadParameter;
5056 } else {
5057 eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
5058 }
5059 } else {
5060 DEBUG_PRINT_ERROR(
5061 "Prepare for adaptive playback supported only on output port");
5062 eRet = OMX_ErrorBadParameter;
5063 }
5064 break;
5065 }
5066
5067 case OMX_QTIIndexParamVideoPreferAdaptivePlayback:
5068 {
5069 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
5070 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoPreferAdaptivePlayback");
5071 m_disable_dynamic_buf_mode = ((QOMX_ENABLETYPE *)paramData)->bEnable;
5072 if (m_disable_dynamic_buf_mode) {
5073 DEBUG_PRINT_HIGH("Prefer Adaptive Playback is set");
5074 }
5075 break;
5076 }
5077 #endif
5078 case OMX_QcomIndexParamVideoCustomBufferSize:
5079 {
5080 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CUSTOM_BUFFERSIZE);
5081 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
5082 QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
5083 if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
5084 struct v4l2_control control;
5085 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
5086 control.value = pParam->nBufferSize;
5087 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
5088 DEBUG_PRINT_ERROR("Failed to set input buffer size");
5089 eRet = OMX_ErrorUnsupportedSetting;
5090 } else {
5091 eRet = get_buffer_req(&drv_ctx.ip_buf);
5092 if (eRet == OMX_ErrorNone) {
5093 m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
5094 DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
5095 m_custom_buffersize.input_buffersize);
5096 } else {
5097 DEBUG_PRINT_ERROR("Failed to get buffer requirement");
5098 }
5099 }
5100 } else {
5101 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
5102 eRet = OMX_ErrorBadParameter;
5103 }
5104 break;
5105 }
5106 case OMX_QTIIndexParamVQZIPSEIType:
5107 {
5108 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE);
5109 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVQZIPSEIType");
5110 OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam =
5111 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
5112 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
5113
5114 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
5115 ((QOMX_ENABLETYPE *)paramData)->bEnable);
5116 if (eRet != OMX_ErrorNone) {
5117 DEBUG_PRINT_ERROR("ERROR: Failed to set SEI Extradata");
5118 eRet = OMX_ErrorBadParameter;
5119 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
5120 break;
5121 }
5122 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
5123 ((QOMX_ENABLETYPE *)paramData)->bEnable);
5124 if (eRet != OMX_ErrorNone) {
5125 DEBUG_PRINT_ERROR("ERROR: Failed to set QP Extradata");
5126 eRet = OMX_ErrorBadParameter;
5127 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
5128 client_extradata = client_extradata & ~OMX_QP_EXTRADATA;
5129 break;
5130 }
5131 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
5132 ((QOMX_ENABLETYPE *)paramData)->bEnable);
5133 if (eRet != OMX_ErrorNone) {
5134 DEBUG_PRINT_ERROR("ERROR: Failed to set FrameInfo Extradata");
5135 eRet = OMX_ErrorBadParameter;
5136 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
5137 client_extradata = client_extradata & ~OMX_QP_EXTRADATA;
5138 client_extradata = client_extradata & ~OMX_FRAMEINFO_EXTRADATA;
5139 }
5140 break;
5141 }
5142 case OMX_QTIIndexParamPassInputBufferFd:
5143 {
5144 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
5145 if (arbitrary_bytes) {
5146 DEBUG_PRINT_ERROR("OMX_QTIIndexParamPassInputBufferFd not supported in arbitrary buffer mode");
5147 eRet = OMX_ErrorUnsupportedSetting;
5148 break;
5149 }
5150
5151 m_input_pass_buffer_fd = ((QOMX_ENABLETYPE *)paramData)->bEnable;
5152 if (m_input_pass_buffer_fd)
5153 DEBUG_PRINT_LOW("Enable passing input buffer FD");
5154 break;
5155 }
5156 case OMX_QTIIndexParamForceCompressedForDPB:
5157 {
5158 VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE);
5159 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceCompressedForDPB");
5160 OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *pParam =
5161 (OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *)paramData;
5162 if (m_disable_ubwc_mode) {
5163 DEBUG_PRINT_ERROR("OMX_QTIIndexParamForceCompressedForDPB not supported when ubwc disabled");
5164 eRet = OMX_ErrorUnsupportedSetting;
5165 break;
5166 }
5167 if (!paramData) {
5168 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceCompressedForDPB paramData NULL");
5169 eRet = OMX_ErrorBadParameter;
5170 break;
5171 }
5172
5173 m_force_compressed_for_dpb = pParam->bEnable;
5174 break;
5175 }
5176 case OMX_QTIIndexParamForceUnCompressedForOPB:
5177 {
5178 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB");
5179 OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *pParam =
5180 (OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *)paramData;
5181 if (!paramData) {
5182 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB paramData is NULL");
5183 eRet = OMX_ErrorBadParameter;
5184 break;
5185 }
5186 m_disable_ubwc_mode = pParam->bEnable;
5187 DEBUG_PRINT_LOW("set_parameter: UBWC %s for OPB", pParam->bEnable ? "disabled" : "enabled");
5188 break;
5189 }
5190 case OMX_QTIIndexParamDitherControl:
5191 {
5192 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL);
5193 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamDitherControl");
5194 QOMX_VIDEO_DITHER_CONTROL *pParam = (QOMX_VIDEO_DITHER_CONTROL *)paramData;
5195 DEBUG_PRINT_LOW("set_parameter: Dither Config from client is: %d", pParam->eDitherType);
5196 if (( pParam->eDitherType < QOMX_DITHER_DISABLE ) ||
5197 ( pParam->eDitherType > QOMX_DITHER_ALL_COLORSPACE)) {
5198 DEBUG_PRINT_ERROR("set_parameter: DitherType outside the range");
5199 eRet = OMX_ErrorBadParameter;
5200 break;
5201 }
5202 m_dither_config = is_platform_tp10capture_supported() ? (dither_type)pParam->eDitherType : DITHER_ALL_COLORSPACE;
5203 DEBUG_PRINT_LOW("set_parameter: Final Dither Config is: %d", m_dither_config);
5204 break;
5205 }
5206 case OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency:
5207 {
5208 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
5209 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency");
5210 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
5211
5212 if ((output_capability != V4L2_PIX_FMT_H264) ||
5213 (output_capability != V4L2_PIX_FMT_HEVC)) {
5214 DEBUG_PRINT_ERROR("set_parameter: Unsupported codec for client configured profile and level");
5215 eRet = OMX_ErrorBadParameter;
5216 }
5217
5218 DEBUG_PRINT_LOW("set_parameter: Client set profile is: %d", pParam->eProfile);
5219 DEBUG_PRINT_LOW("set_parameter: Client set level is: %d", pParam->eLevel);
5220 mClientSessionForSufficiency = true;
5221 mClientSetProfile = pParam->eProfile;
5222 mClientSetLevel = pParam->eLevel;
5223 break;
5224 }
5225 default: {
5226 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
5227 eRet = OMX_ErrorUnsupportedIndex;
5228 }
5229 }
5230 if (eRet != OMX_ErrorNone)
5231 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
5232 return eRet;
5233 }
5234
5235 /* ======================================================================
5236 FUNCTION
5237 omx_vdec::GetConfig
5238
5239 DESCRIPTION
5240 OMX Get Config Method implementation.
5241
5242 PARAMETERS
5243 <TBD>.
5244
5245 RETURN VALUE
5246 OMX Error None if successful.
5247
5248 ========================================================================== */
get_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_INOUT OMX_PTR configData)5249 OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
5250 OMX_IN OMX_INDEXTYPE configIndex,
5251 OMX_INOUT OMX_PTR configData)
5252 {
5253 (void) hComp;
5254 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5255
5256 if (m_state == OMX_StateInvalid) {
5257 DEBUG_PRINT_ERROR("Get Config in Invalid State");
5258 return OMX_ErrorInvalidState;
5259 }
5260
5261 switch ((unsigned long)configIndex) {
5262 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
5263 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_QUERY_DECODER_INSTANCES);
5264 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
5265 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
5266 decoderinstances->nNumOfInstances = 16;
5267 /*TODO: How to handle this case */
5268 break;
5269 }
5270 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
5271 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
5272 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_FRAME_PACK_ARRANGEMENT);
5273 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
5274 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
5275 memcpy(configFmt, &m_frame_pack_arrangement,
5276 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
5277 } else {
5278 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
5279 }
5280 break;
5281 }
5282 case OMX_IndexConfigCommonOutputCrop: {
5283 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_RECTTYPE);
5284 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
5285 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
5286 DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
5287 rectangle.nLeft, rectangle.nTop,
5288 rectangle.nWidth, rectangle.nHeight);
5289 break;
5290 }
5291 case OMX_QcomIndexConfigH264EntropyCodingCabac: {
5292 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_H264ENTROPYCODINGTYPE);
5293 QOMX_VIDEO_H264ENTROPYCODINGTYPE *coding = (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)configData;
5294 struct v4l2_control control;
5295
5296 if (drv_ctx.decoder_format != VDEC_CODECTYPE_H264) {
5297 DEBUG_PRINT_ERROR("get_config of OMX_QcomIndexConfigH264EntropyCodingCabac only available for H264");
5298 eRet = OMX_ErrorNotImplemented;
5299 break;
5300 }
5301
5302 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
5303 if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control)) {
5304 coding->bCabac = (OMX_BOOL)
5305 (control.value == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC);
5306 /* We can't query driver at the moment for the cabac mode, so
5307 * just use 0xff...f as a place holder for future improvement */
5308 coding->nCabacInitIdc = ~0;
5309 } else {
5310 eRet = OMX_ErrorUnsupportedIndex;
5311 }
5312
5313 break;
5314 }
5315 case OMX_QTIIndexConfigDescribeColorAspects:
5316 {
5317 VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
5318 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
5319
5320 if (params->bRequestingDataSpace) {
5321 DEBUG_PRINT_LOW("Does not handle dataspace request. Please ignore this Unsupported Setting (0x80001019).");
5322 return OMX_ErrorUnsupportedSetting;
5323 }
5324
5325 print_debug_color_aspects(&(m_client_color_space.sAspects), "GetConfig Client");
5326 print_debug_color_aspects(&(m_internal_color_space.sAspects), "GetConfig Internal");
5327 get_preferred_color_aspects(params->sAspects);
5328 print_debug_color_aspects(&(params->sAspects), "GetConfig");
5329
5330 break;
5331 }
5332 case OMX_QTIIndexConfigDescribeHDRColorInfo:
5333 {
5334 VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams);
5335 DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData;
5336 print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "GetConfig Client HDR");
5337 print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "GetConfig Internal HDR");
5338 get_preferred_hdr_info(params->sInfo);
5339 print_debug_hdr_color_info(&(params->sInfo), "GetConfig HDR");
5340
5341 break;
5342 }
5343 case OMX_IndexConfigAndroidVendorExtension:
5344 {
5345 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
5346
5347 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
5348 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
5349 VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
5350 return get_vendor_extension_config(ext);
5351 }
5352 default:
5353 {
5354 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
5355 eRet = OMX_ErrorBadParameter;
5356 }
5357
5358 }
5359
5360 return eRet;
5361 }
5362
5363 /* ======================================================================
5364 FUNCTION
5365 omx_vdec::SetConfig
5366
5367 DESCRIPTION
5368 OMX Set Config method implementation
5369
5370 PARAMETERS
5371 <TBD>.
5372
5373 RETURN VALUE
5374 OMX Error None if successful.
5375 ========================================================================== */
set_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_IN OMX_PTR configData)5376 OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
5377 OMX_IN OMX_INDEXTYPE configIndex,
5378 OMX_IN OMX_PTR configData)
5379 {
5380 (void) hComp;
5381 if (m_state == OMX_StateInvalid) {
5382 DEBUG_PRINT_ERROR("Get Config in Invalid State");
5383 return OMX_ErrorInvalidState;
5384 }
5385
5386 OMX_ERRORTYPE ret = OMX_ErrorNone;
5387 OMX_VIDEO_CONFIG_NALSIZE *pNal;
5388
5389 DEBUG_PRINT_LOW("Set Config Called");
5390
5391
5392 if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
5393 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
5394 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %u", (unsigned int)config->nFps);
5395
5396 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
5397 if (config->bEnabled) {
5398 if ((config->nFps >> 16) > 0 &&
5399 (config->nFps >> 16) <= MAX_SUPPORTED_FPS) {
5400 m_fps_received = config->nFps;
5401 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %u",
5402 (unsigned int)config->nFps >> 16);
5403 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
5404 drv_ctx.frame_rate.fps_denominator);
5405
5406 if (!drv_ctx.frame_rate.fps_numerator) {
5407 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
5408 drv_ctx.frame_rate.fps_numerator = 30;
5409 }
5410
5411 if (drv_ctx.frame_rate.fps_denominator) {
5412 drv_ctx.frame_rate.fps_numerator = (int)
5413 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
5414 }
5415
5416 drv_ctx.frame_rate.fps_denominator = 1;
5417 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
5418 drv_ctx.frame_rate.fps_numerator;
5419
5420 struct v4l2_outputparm oparm;
5421 /*XXX: we're providing timing info as seconds per frame rather than frames
5422 * per second.*/
5423 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
5424 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
5425
5426 struct v4l2_streamparm sparm;
5427 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5428 sparm.parm.output = oparm;
5429 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
5430 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
5431 performance might be affected");
5432 ret = OMX_ErrorHardware;
5433 }
5434 client_set_fps = true;
5435 } else {
5436 DEBUG_PRINT_ERROR("Frame rate not supported.");
5437 ret = OMX_ErrorUnsupportedSetting;
5438 }
5439 } else {
5440 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
5441 client_set_fps = false;
5442 }
5443 } else {
5444 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
5445 (int)config->nPortIndex);
5446 ret = OMX_ErrorBadPortIndex;
5447 }
5448
5449 return ret;
5450 } else if ((int)configIndex == (int)OMX_QcomIndexConfigPictureTypeDecode) {
5451 OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *config =
5452 (OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *)configData;
5453 struct v4l2_control control;
5454 DEBUG_PRINT_LOW("Set picture type decode: %d", config->eDecodeType);
5455 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE;
5456
5457 switch (config->eDecodeType) {
5458 case OMX_QCOM_PictypeDecode_I:
5459 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_I;
5460 break;
5461 case OMX_QCOM_PictypeDecode_IPB:
5462 default:
5463 control.value = (V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_I|
5464 V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_P|
5465 V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_B);
5466 break;
5467 }
5468
5469 ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
5470 OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
5471 if (ret)
5472 DEBUG_PRINT_ERROR("Failed to set picture type decode");
5473
5474 return ret;
5475 } else if ((int)configIndex == (int)OMX_IndexConfigPriority) {
5476 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
5477 DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
5478
5479 struct v4l2_control control;
5480
5481 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
5482 if (priority->nU32 == 0)
5483 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
5484 else
5485 control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
5486
5487 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
5488 DEBUG_PRINT_ERROR("Failed to set Priority");
5489 ret = OMX_ErrorUnsupportedSetting;
5490 }
5491 return ret;
5492 } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) {
5493 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
5494 DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16);
5495
5496 struct v4l2_control control;
5497
5498 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
5499 control.value = rate->nU32;
5500
5501 if (rate->nU32 == QOMX_VIDEO_HIGH_PERF_OPERATING_MODE) {
5502 DEBUG_PRINT_LOW("Turbo mode requested");
5503 m_client_req_turbo_mode = true;
5504 } else {
5505 operating_frame_rate = rate->nU32 >> 16;
5506 m_client_req_turbo_mode = false;
5507 DEBUG_PRINT_LOW("Operating Rate Set = %d fps", operating_frame_rate);
5508 }
5509
5510 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
5511 ret = errno == -EBUSY ? OMX_ErrorInsufficientResources :
5512 OMX_ErrorUnsupportedSetting;
5513 DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)",
5514 rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno));
5515 }
5516 return ret;
5517
5518 } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeColorAspects) {
5519 VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
5520 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
5521 if (!DEFAULT_EXTRADATA & OMX_DISPLAY_INFO_EXTRADATA) {
5522 enable_extradata(OMX_DISPLAY_INFO_EXTRADATA, false, true);
5523 }
5524
5525 print_debug_color_aspects(&(params->sAspects), "Set Config");
5526 memcpy(&m_client_color_space, params, sizeof(DescribeColorAspectsParams));
5527 return ret;
5528 } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeHDRColorInfo) {
5529 VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams);
5530 DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData;
5531 ret = enable_extradata(OMX_HDR_COLOR_INFO_EXTRADATA, false, true);
5532 if (ret != OMX_ErrorNone) {
5533 DEBUG_PRINT_ERROR("Failed to enable OMX_HDR_COLOR_INFO_EXTRADATA");
5534 return ret;
5535 }
5536
5537 print_debug_hdr_color_info(&(params->sInfo), "Set Config HDR");
5538 memcpy(&m_client_hdr_info, params, sizeof(DescribeHDRStaticInfoParams));
5539 return ret;
5540
5541 } else if ((int)configIndex == (int)OMX_IndexConfigAndroidVendorExtension) {
5542 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
5543
5544 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
5545 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
5546 VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
5547
5548 return set_vendor_extension_config(ext);
5549 }
5550
5551 return OMX_ErrorNotImplemented;
5552 }
5553
5554 #define extn_equals(param, extn) (!strcmp(param, extn))
5555
5556 /* ======================================================================
5557 FUNCTION
5558 omx_vdec::GetExtensionIndex
5559
5560 DESCRIPTION
5561 OMX GetExtensionIndex method implementaion. <TBD>
5562
5563 PARAMETERS
5564 <TBD>.
5565
5566 RETURN VALUE
5567 OMX Error None if everything successful.
5568
5569 ========================================================================== */
get_extension_index(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_STRING paramName,OMX_OUT OMX_INDEXTYPE * indexType)5570 OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
5571 OMX_IN OMX_STRING paramName,
5572 OMX_OUT OMX_INDEXTYPE* indexType)
5573 {
5574 (void) hComp;
5575 if (m_state == OMX_StateInvalid) {
5576 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
5577 return OMX_ErrorInvalidState;
5578 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
5579 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
5580 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
5581 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
5582 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
5583 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
5584 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
5585 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
5586 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
5587 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
5588 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
5589 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
5590 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
5591 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
5592 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNOUTPUTCROP_EXTRADATA)) {
5593 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamOutputCropExtraData;
5594 }
5595 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
5596 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
5597 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
5598 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
5599 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
5600 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
5601 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
5602 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
5603 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
5604 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
5605 }
5606 #if ALLOCATE_OUTPUT_NATIVEHANDLE
5607 else if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) {
5608 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle;
5609 }
5610 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE
5611 #endif
5612 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
5613 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
5614 }
5615 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
5616 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
5617 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
5618 } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK)) {
5619 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoPreferAdaptivePlayback;
5620 }
5621 #endif
5622 #ifdef FLEXYUV_SUPPORTED
5623 else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
5624 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
5625 }
5626 #endif
5627 else if (extn_equals(paramName, "OMX.QCOM.index.param.video.PassInputBufferFd")) {
5628 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamPassInputBufferFd;
5629 } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceCompressedForDPB")) {
5630 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceCompressedForDPB;
5631 } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceUnCompressedForOPB")) {
5632 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceUnCompressedForOPB;
5633 } else if (extn_equals(paramName, "OMX.QTI.index.param.video.LowLatency")) {
5634 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamLowLatencyMode;
5635 } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_CLIENT_EXTRADATA)) {
5636 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoClientExtradata;
5637 } else if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) {
5638 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
5639 } else if (extn_equals(paramName, "OMX.google.android.index.describeHDRStaticInfo")) {
5640 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeHDRColorInfo;
5641 } else if (extn_equals(paramName, "OMX.QTI.index.param.ClientConfiguredProfileLevel")) {
5642 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency;
5643 }else {
5644 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
5645 return OMX_ErrorNotImplemented;
5646 }
5647 return OMX_ErrorNone;
5648 }
5649
5650 /* ======================================================================
5651 FUNCTION
5652 omx_vdec::GetState
5653
5654 DESCRIPTION
5655 Returns the state information back to the caller.<TBD>
5656
5657 PARAMETERS
5658 <TBD>.
5659
5660 RETURN VALUE
5661 Error None if everything is successful.
5662 ========================================================================== */
get_state(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_STATETYPE * state)5663 OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
5664 OMX_OUT OMX_STATETYPE* state)
5665 {
5666 (void) hComp;
5667 *state = m_state;
5668 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
5669 return OMX_ErrorNone;
5670 }
5671
5672 /* ======================================================================
5673 FUNCTION
5674 omx_vdec::ComponentTunnelRequest
5675
5676 DESCRIPTION
5677 OMX Component Tunnel Request method implementation. <TBD>
5678
5679 PARAMETERS
5680 None.
5681
5682 RETURN VALUE
5683 OMX Error None if everything successful.
5684
5685 ========================================================================== */
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)5686 OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
5687 OMX_IN OMX_U32 port,
5688 OMX_IN OMX_HANDLETYPE peerComponent,
5689 OMX_IN OMX_U32 peerPort,
5690 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
5691 {
5692 (void) hComp;
5693 (void) port;
5694 (void) peerComponent;
5695 (void) peerPort;
5696 (void) tunnelSetup;
5697 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
5698 return OMX_ErrorNotImplemented;
5699 }
5700
5701
5702
5703 /* ======================================================================
5704 FUNCTION
5705 omx_vdec::ion_map
5706
5707 DESCRIPTION
5708 Map the memory and run the ioctl SYNC operations
5709 on ION fd with DMA_BUF_IOCTL_SYNC
5710
5711 PARAMETERS
5712 fd : ION fd
5713 len : Lenth of the memory
5714
5715 RETURN VALUE
5716 ERROR: mapped memory pointer
5717
5718 ========================================================================== */
ion_map(int fd,int len)5719 char *omx_vdec::ion_map(int fd, int len)
5720 {
5721 char *bufaddr = (char*)mmap(NULL, len, PROT_READ|PROT_WRITE,
5722 MAP_SHARED, fd, 0);
5723 if (bufaddr != MAP_FAILED) {
5724 #ifdef USE_ION
5725 do_cache_operations(fd);
5726 #endif
5727 }
5728 return bufaddr;
5729 }
5730
5731 /* ======================================================================
5732 FUNCTION
5733 omx_vdec::ion_unmap
5734
5735 DESCRIPTION
5736 Unmap the memory
5737
5738 PARAMETERS
5739 fd : ION fd
5740 bufaddr : buffer address
5741 len : Lenth of the memory
5742
5743 RETURN VALUE
5744 OMX_Error*
5745
5746 ========================================================================== */
ion_unmap(int fd,void * bufaddr,int len)5747 OMX_ERRORTYPE omx_vdec::ion_unmap(int fd, void *bufaddr, int len)
5748 {
5749 #ifdef USE_ION
5750 do_cache_operations(fd);
5751 #else
5752 (void)fd;
5753 #endif
5754 if (-1 == munmap(bufaddr, len)) {
5755 DEBUG_PRINT_ERROR("munmap failed.");
5756 return OMX_ErrorInsufficientResources;
5757 }
5758 return OMX_ErrorNone;
5759 }
5760
5761 /* ======================================================================
5762 FUNCTION
5763 omx_vdec::UseOutputBuffer
5764
5765 DESCRIPTION
5766 Helper function for Use buffer in the input pin
5767
5768 PARAMETERS
5769 None.
5770
5771 RETURN VALUE
5772 true/false
5773
5774 ========================================================================== */
allocate_extradata()5775 OMX_ERRORTYPE omx_vdec::allocate_extradata()
5776 {
5777 #ifdef USE_ION
5778 if (drv_ctx.extradata_info.buffer_size) {
5779 if (drv_ctx.extradata_info.ion.data_fd >= 0) {
5780 free_extradata();
5781 }
5782
5783 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
5784 // Decoder extradata is always uncached as buffer sizes are very small
5785 bool status = alloc_map_ion_memory(
5786 drv_ctx.extradata_info.size, &drv_ctx.extradata_info.ion, 0);
5787 if (status == false) {
5788 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
5789 return OMX_ErrorInsufficientResources;
5790 }
5791 DEBUG_PRINT_HIGH("Allocated extradata size : %d fd: %d",
5792 drv_ctx.extradata_info.size, drv_ctx.extradata_info.ion.data_fd);
5793 drv_ctx.extradata_info.uaddr = ion_map(drv_ctx.extradata_info.ion.data_fd,
5794 drv_ctx.extradata_info.size);
5795 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
5796 DEBUG_PRINT_ERROR("Failed to map extradata memory");
5797 free_ion_memory(&drv_ctx.extradata_info.ion);
5798 return OMX_ErrorInsufficientResources;
5799 }
5800 }
5801 #endif
5802 return OMX_ErrorNone;
5803 }
5804
free_extradata()5805 void omx_vdec::free_extradata()
5806 {
5807 #ifdef USE_ION
5808 if (drv_ctx.extradata_info.uaddr) {
5809 ion_unmap(drv_ctx.extradata_info.ion.data_fd,
5810 (void *)drv_ctx.extradata_info.uaddr,
5811 drv_ctx.extradata_info.ion.alloc_data.len);
5812 free_ion_memory(&drv_ctx.extradata_info.ion);
5813 drv_ctx.extradata_info.uaddr = NULL;
5814 drv_ctx.extradata_info.ion.data_fd = -1;
5815 }
5816 #endif
5817 }
5818
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)5819 OMX_ERRORTYPE omx_vdec::use_output_buffer(
5820 OMX_IN OMX_HANDLETYPE hComp,
5821 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5822 OMX_IN OMX_U32 port,
5823 OMX_IN OMX_PTR appData,
5824 OMX_IN OMX_U32 bytes,
5825 OMX_IN OMX_U8* buffer)
5826 {
5827 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5828 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
5829 unsigned i= 0; // Temporary counter
5830 OMX_PTR privateAppData = NULL;
5831 private_handle_t *handle = NULL;
5832 OMX_U8 *buff = buffer;
5833 bool intermediate = client_buffers.is_color_conversion_enabled();
5834 (void) hComp;
5835 (void) port;
5836
5837 if (!m_out_mem_ptr) {
5838 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers C2D(%d)",
5839 client_buffers.is_color_conversion_enabled());
5840 eRet = allocate_output_headers();
5841 if (eRet == OMX_ErrorNone)
5842 eRet = allocate_extradata();
5843 output_use_buffer = true;
5844 }
5845
5846 OMX_BUFFERHEADERTYPE **omx_base_address =
5847 intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
5848
5849 if (eRet == OMX_ErrorNone) {
5850 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5851 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
5852 break;
5853 }
5854 }
5855 }
5856
5857 if (i >= drv_ctx.op_buf.actualcount) {
5858 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
5859 return OMX_ErrorInsufficientResources;
5860 }
5861
5862 if (intermediate) {
5863 DEBUG_PRINT_HIGH("Use_op_buf:Allocating intermediate output. %d", i);
5864 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
5865 eRet = allocate_output_buffer(hComp, &temp_bufferHdr,
5866 port, appData,
5867 drv_ctx.op_buf.buffer_size,
5868 true, i);
5869 }
5870
5871 if (eRet == OMX_ErrorNone && dynamic_buf_mode) {
5872 *bufferHdr = (m_out_mem_ptr + i );
5873 (*bufferHdr)->pBuffer = NULL;
5874 if (i == (drv_ctx.op_buf.actualcount - 1) && !streaming[CAPTURE_PORT]) {
5875 enum v4l2_buf_type buf_type;
5876 int rr = 0;
5877 DEBUG_PRINT_LOW("USE intermediate bufferSTREAMON(CAPTURE_MPLANE)");
5878 set_buffer_req(&drv_ctx.op_buf);
5879 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5880 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON, &buf_type)) {
5881 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
5882 return OMX_ErrorInsufficientResources;
5883 } else {
5884 streaming[CAPTURE_PORT] = true;
5885 DEBUG_PRINT_LOW("STREAMON Successful");
5886 }
5887 }
5888 BITMASK_SET(&m_out_bm_count,i);
5889 (*bufferHdr)->pAppPrivate = appData;
5890 (*bufferHdr)->pBuffer = buffer;
5891 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
5892 return eRet;
5893 }
5894
5895 if (eRet == OMX_ErrorNone) {
5896 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
5897 if (m_enable_android_native_buffers) {
5898 if (m_use_android_native_buffers) {
5899 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
5900 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
5901 handle = (private_handle_t *)nBuf->handle;
5902 privateAppData = params->pAppPrivate;
5903 } else {
5904 handle = (private_handle_t *)buff;
5905 privateAppData = appData;
5906 }
5907 if (!handle) {
5908 DEBUG_PRINT_ERROR("handle is invalid");
5909 return OMX_ErrorBadParameter;
5910 }
5911
5912 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
5913 if (secure_mode && secure_scaling_to_non_secure_opb) {
5914 DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it",
5915 (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
5916 } else {
5917 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
5918 " expected %u, got %u",
5919 (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
5920 return OMX_ErrorBadParameter;
5921 }
5922 }
5923
5924 drv_ctx.op_buf.buffer_size = handle->size;
5925
5926 if (!m_use_android_native_buffers) {
5927 if (!secure_mode) {
5928 buff = (OMX_U8*)ion_map(handle->fd, handle->size);
5929 if (buff == MAP_FAILED) {
5930 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
5931 return OMX_ErrorInsufficientResources;
5932 }
5933 }
5934 }
5935 #if defined(_ANDROID_ICS_)
5936 native_buffer[i].nativehandle = handle;
5937 native_buffer[i].privatehandle = handle;
5938 #endif
5939 if (!handle) {
5940 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
5941 return OMX_ErrorBadParameter;
5942 }
5943 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
5944 drv_ctx.ptr_outputbuffer[i].offset = 0;
5945 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
5946 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
5947 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
5948 } else
5949 #endif
5950 if (!ouput_egl_buffers && !m_use_output_pmem) {
5951 #ifdef USE_GBM
5952 bool status = alloc_map_gbm_memory(
5953 drv_ctx.video_resolution.frame_width,
5954 drv_ctx.video_resolution.frame_height,
5955 drv_ctx.gbm_device_fd,
5956 &drv_ctx.op_buf_gbm_info[i],
5957 secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
5958 if (status == false) {
5959 DEBUG_PRINT_ERROR("ION device fd is bad %d",
5960 (int) drv_ctx.op_buf_ion_info[i].data_fd);
5961 return OMX_ErrorInsufficientResources;
5962 }
5963 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
5964 drv_ctx.op_buf_gbm_info[i].bo_fd;
5965 if (intermediate)
5966 m_pmem_info[i].pmeta_fd = drv_ctx.op_buf_gbm_info[i].meta_fd;
5967 #elif defined USE_ION
5968 bool status = alloc_map_ion_memory(
5969 drv_ctx.op_buf.buffer_size, &drv_ctx.op_buf_ion_info[i],
5970 secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
5971 if (status == false) {
5972 DEBUG_PRINT_ERROR("ION device fd is bad %d",
5973 (int) drv_ctx.op_buf_ion_info[i].data_fd);
5974 return OMX_ErrorInsufficientResources;
5975 }
5976 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
5977 drv_ctx.op_buf_ion_info[i].data_fd;
5978 #endif
5979 if (!secure_mode) {
5980 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5981 (unsigned char *)ion_map(drv_ctx.ptr_outputbuffer[i].pmem_fd,
5982 drv_ctx.op_buf.buffer_size);
5983 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
5984 #ifdef USE_GBM
5985 free_gbm_memory(&drv_ctx.op_buf_gbm_info[i]);
5986 #elif defined USE_ION
5987 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
5988 #endif
5989 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
5990 return OMX_ErrorInsufficientResources;
5991 }
5992 }
5993 drv_ctx.ptr_outputbuffer[i].offset = 0;
5994 privateAppData = appData;
5995 } else {
5996 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
5997 if (!appData || !bytes ) {
5998 if (!secure_mode && !buffer) {
5999 DEBUG_PRINT_ERROR("Bad parameters for use buffer");
6000 return OMX_ErrorBadParameter;
6001 }
6002 }
6003
6004 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
6005 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
6006 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
6007 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
6008 !pmem_list->nEntries ||
6009 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
6010 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
6011 return OMX_ErrorBadParameter;
6012 }
6013 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6014 pmem_list->entryList->entry;
6015 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
6016 pmem_info->pmem_fd);
6017 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
6018 #ifdef USE_GBM
6019 if (intermediate)
6020 m_pmem_info[i].pmeta_fd = pmem_info->pmeta_fd;
6021 #endif
6022 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
6023 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
6024 drv_ctx.ptr_outputbuffer[i].mmaped_size =
6025 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
6026 privateAppData = appData;
6027 }
6028 if (intermediate) {
6029 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
6030 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
6031 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
6032 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
6033 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
6034 }
6035 *bufferHdr = (m_out_mem_ptr + i );
6036
6037 if (secure_mode)
6038 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
6039
6040 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
6041 enum v4l2_buf_type buf_type;
6042 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6043 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
6044 return OMX_ErrorInsufficientResources;
6045 } else {
6046 streaming[CAPTURE_PORT] = true;
6047 DEBUG_PRINT_LOW("STREAMON Successful");
6048 }
6049 }
6050
6051 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
6052 if (m_enable_android_native_buffers) {
6053 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
6054 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
6055 } else {
6056 (*bufferHdr)->pBuffer = buff;
6057 }
6058 (*bufferHdr)->pAppPrivate = privateAppData;
6059 BITMASK_SET(&m_out_bm_count,i);
6060 }
6061 return eRet;
6062 }
6063
allocate_client_output_extradata_headers()6064 OMX_ERRORTYPE omx_vdec::allocate_client_output_extradata_headers() {
6065 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6066 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
6067 int i = 0;
6068
6069 if (!m_client_output_extradata_mem_ptr) {
6070 int nBufferCount = 0;
6071
6072 nBufferCount = m_client_out_extradata_info.getBufferCount();
6073 DEBUG_PRINT_HIGH("allocate_client_output_extradata_headers buffer_count - %d", nBufferCount);
6074
6075 m_client_output_extradata_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufferCount, sizeof(OMX_BUFFERHEADERTYPE));
6076
6077 if (m_client_output_extradata_mem_ptr) {
6078 bufHdr = m_client_output_extradata_mem_ptr;
6079 for (i=0; i < nBufferCount; i++) {
6080 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
6081 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
6082 // Set the values when we determine the right HxW param
6083 bufHdr->nAllocLen = 0;
6084 bufHdr->nFilledLen = 0;
6085 bufHdr->pAppPrivate = NULL;
6086 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_EXTRADATA_INDEX;
6087 bufHdr->pBuffer = NULL;
6088 bufHdr->pOutputPortPrivate = NULL;
6089 bufHdr++;
6090 }
6091 } else {
6092 DEBUG_PRINT_ERROR("Extradata header buf mem alloc failed[0x%p]",\
6093 m_client_output_extradata_mem_ptr);
6094 eRet = OMX_ErrorInsufficientResources;
6095 }
6096 }
6097 return eRet;
6098 }
use_client_output_extradata_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)6099 OMX_ERRORTYPE omx_vdec::use_client_output_extradata_buffer(
6100 OMX_IN OMX_HANDLETYPE hComp,
6101 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6102 OMX_IN OMX_U32 port,
6103 OMX_IN OMX_PTR appData,
6104 OMX_IN OMX_U32 bytes,
6105 OMX_IN OMX_U8* buffer)
6106 {
6107 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6108 unsigned i = 0; // Temporary counter
6109 unsigned buffer_count = m_client_out_extradata_info.getBufferCount();;
6110 OMX_U32 buffer_size = m_client_out_extradata_info.getSize();
6111 (void) hComp;
6112
6113 if (port != OMX_CORE_OUTPUT_EXTRADATA_INDEX ||
6114 !client_extradata || bytes != buffer_size|| bufferHdr == NULL) {
6115 DEBUG_PRINT_ERROR("Bad Parameters PortIndex is - %d expected is- %d,"
6116 "client_extradata - %d, bytes = %d expected is %d bufferHdr - %p", port,
6117 OMX_CORE_OUTPUT_EXTRADATA_INDEX, client_extradata, bytes, buffer_size, bufferHdr);
6118 eRet = OMX_ErrorBadParameter;
6119 return eRet;
6120 }
6121
6122 if (!m_client_output_extradata_mem_ptr) {
6123 eRet = allocate_client_output_extradata_headers();
6124 }
6125
6126 if (eRet == OMX_ErrorNone) {
6127 for (i = 0; i < buffer_count; i++) {
6128 if (BITMASK_ABSENT(&m_out_extradata_bm_count,i)) {
6129 break;
6130 }
6131 }
6132 }
6133
6134 if (i >= buffer_count) {
6135 DEBUG_PRINT_ERROR("Already using %d Extradata o/p buffers", buffer_count);
6136 eRet = OMX_ErrorInsufficientResources;
6137 }
6138
6139 if (eRet == OMX_ErrorNone) {
6140 BITMASK_SET(&m_out_extradata_bm_count,i);
6141 *bufferHdr = (m_client_output_extradata_mem_ptr + i );
6142 (*bufferHdr)->pAppPrivate = appData;
6143 (*bufferHdr)->pBuffer = buffer;
6144 (*bufferHdr)->nAllocLen = bytes;
6145 }
6146
6147 return eRet;
6148 }
6149 /* ======================================================================
6150 FUNCTION
6151 omx_vdec::use_input_heap_buffers
6152
6153 DESCRIPTION
6154 OMX Use Buffer Heap allocation method implementation.
6155
6156 PARAMETERS
6157 <TBD>.
6158
6159 RETURN VALUE
6160 OMX Error None , if everything successful.
6161
6162 ========================================================================== */
use_input_heap_buffers(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)6163 OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
6164 OMX_IN OMX_HANDLETYPE hComp,
6165 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6166 OMX_IN OMX_U32 port,
6167 OMX_IN OMX_PTR appData,
6168 OMX_IN OMX_U32 bytes,
6169 OMX_IN OMX_U8* buffer)
6170 {
6171 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
6172 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6173
6174 if (secure_mode) {
6175 DEBUG_PRINT_ERROR("use_input_heap_buffers is not allowed in secure mode");
6176 return OMX_ErrorUndefined;
6177 }
6178
6179 if (!m_inp_heap_ptr)
6180 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
6181 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
6182 drv_ctx.ip_buf.actualcount);
6183 if (!m_phdr_pmem_ptr)
6184 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
6185 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
6186 drv_ctx.ip_buf.actualcount);
6187 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
6188 DEBUG_PRINT_ERROR("Insufficent memory");
6189 eRet = OMX_ErrorInsufficientResources;
6190 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
6191 input_use_buffer = true;
6192 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
6193 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
6194 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
6195 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
6196 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
6197 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
6198 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
6199 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
6200 DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
6201 if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[m_in_alloc_cnt],
6202 (unsigned)NULL, (unsigned)NULL)) {
6203 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
6204 return OMX_ErrorInsufficientResources;
6205 }
6206 m_in_alloc_cnt++;
6207 } else {
6208 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
6209 eRet = OMX_ErrorInsufficientResources;
6210 }
6211 return eRet;
6212 }
6213
6214 /* ======================================================================
6215 FUNCTION
6216 omx_vdec::UseBuffer
6217
6218 DESCRIPTION
6219 OMX Use Buffer method implementation.
6220
6221 PARAMETERS
6222 <TBD>.
6223
6224 RETURN VALUE
6225 OMX Error None , if everything successful.
6226
6227 ========================================================================== */
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)6228 OMX_ERRORTYPE omx_vdec::use_buffer(
6229 OMX_IN OMX_HANDLETYPE hComp,
6230 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6231 OMX_IN OMX_U32 port,
6232 OMX_IN OMX_PTR appData,
6233 OMX_IN OMX_U32 bytes,
6234 OMX_IN OMX_U8* buffer)
6235 {
6236 OMX_ERRORTYPE error = OMX_ErrorNone;
6237
6238 if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
6239 DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer);
6240 return OMX_ErrorBadParameter;
6241 }
6242 if (m_state == OMX_StateInvalid) {
6243 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
6244 return OMX_ErrorInvalidState;
6245 }
6246 if (port == OMX_CORE_INPUT_PORT_INDEX) {
6247 // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
6248 // ensure that use-buffer was called for previous allocation.
6249 // Mix-and-match of useBuffer and allocateBuffer is not allowed
6250 if (m_inp_mem_ptr && !input_use_buffer) {
6251 DEBUG_PRINT_ERROR("'Use' Input buffer called after 'Allocate' Input buffer !");
6252 return OMX_ErrorUndefined;
6253 }
6254 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
6255 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
6256 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
6257 } else if (port == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
6258 error = use_client_output_extradata_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
6259 } else {
6260 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
6261 error = OMX_ErrorBadPortIndex;
6262 }
6263 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)port, *bufferHdr, error);
6264 if (error == OMX_ErrorNone) {
6265 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
6266 // Send the callback now
6267 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
6268 post_event(OMX_CommandStateSet,OMX_StateIdle,
6269 OMX_COMPONENT_GENERATE_EVENT);
6270 }
6271 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
6272 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
6273 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
6274 post_event(OMX_CommandPortEnable,
6275 OMX_CORE_INPUT_PORT_INDEX,
6276 OMX_COMPONENT_GENERATE_EVENT);
6277 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
6278 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
6279 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
6280 post_event(OMX_CommandPortEnable,
6281 OMX_CORE_OUTPUT_PORT_INDEX,
6282 OMX_COMPONENT_GENERATE_EVENT);
6283 }
6284 }
6285 return error;
6286 }
6287
free_input_buffer(unsigned int bufferindex,OMX_BUFFERHEADERTYPE * pmem_bufferHdr)6288 OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
6289 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
6290 {
6291 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
6292 if (m_inp_heap_ptr[bufferindex].pBuffer)
6293 free(m_inp_heap_ptr[bufferindex].pBuffer);
6294 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
6295 }
6296 if (pmem_bufferHdr)
6297 free_input_buffer(pmem_bufferHdr);
6298 return OMX_ErrorNone;
6299 }
6300
free_input_buffer(OMX_BUFFERHEADERTYPE * bufferHdr)6301 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
6302 {
6303 unsigned int index = 0;
6304 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
6305 return OMX_ErrorBadParameter;
6306 }
6307 print_omx_buffer("free_input_buffer", bufferHdr);
6308
6309 index = bufferHdr - m_inp_mem_ptr;
6310 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
6311
6312 bufferHdr->pInputPortPrivate = NULL;
6313
6314 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
6315 if (drv_ctx.ptr_inputbuffer[index].pmem_fd >= 0) {
6316 if (!secure_mode) {
6317 ion_unmap(drv_ctx.ptr_inputbuffer[index].pmem_fd,
6318 drv_ctx.ptr_inputbuffer[index].bufferaddr,
6319 drv_ctx.ptr_inputbuffer[index].mmaped_size);
6320 }
6321
6322 if (allocate_native_handle){
6323 native_handle_t *nh = (native_handle_t *)bufferHdr->pBuffer;
6324 native_handle_close(nh);
6325 native_handle_delete(nh);
6326 } else {
6327 #ifndef USE_ION
6328 // Close fd for non-secure and secure non-native-handle case
6329 close(drv_ctx.ptr_inputbuffer[index].pmem_fd);
6330 #endif
6331 }
6332 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
6333
6334 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
6335 free(m_desc_buffer_ptr[index].buf_addr);
6336 m_desc_buffer_ptr[index].buf_addr = NULL;
6337 m_desc_buffer_ptr[index].desc_data_size = 0;
6338 }
6339 #ifdef USE_ION
6340 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
6341 #endif
6342 m_in_alloc_cnt--;
6343 } else {
6344 DEBUG_PRINT_ERROR("Invalid input buffer fd %d", drv_ctx.ptr_inputbuffer[index].pmem_fd);
6345 }
6346 } else {
6347 DEBUG_PRINT_ERROR("Invalid input buffer index %d, drv_ctx.ptr_inputbuffer %p",
6348 index, drv_ctx.ptr_inputbuffer);
6349 }
6350
6351 return OMX_ErrorNone;
6352 }
6353
free_output_buffer(OMX_BUFFERHEADERTYPE * bufferHdr,bool intermediate)6354 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr,
6355 bool intermediate)
6356 {
6357 unsigned int index = 0;
6358
6359 OMX_BUFFERHEADERTYPE *omx_base_address =
6360 intermediate?m_intermediate_out_mem_ptr:m_out_mem_ptr;
6361 vdec_bufferpayload *omx_ptr_outputbuffer =
6362 intermediate?drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
6363 vdec_ion *omx_op_buf_ion_info =
6364 intermediate?drv_ctx.op_intermediate_buf_ion_info:drv_ctx.op_buf_ion_info;
6365 #ifdef USE_GBM
6366 vdec_gbm *omx_op_buf_gbm_info =
6367 intermediate?drv_ctx.op_intermediate_buf_gbm_info:drv_ctx.op_buf_gbm_info;
6368 #endif
6369 if (bufferHdr == NULL || omx_base_address == NULL) {
6370 return OMX_ErrorBadParameter;
6371 }
6372 print_omx_buffer("free_output_buffer", bufferHdr);
6373
6374 index = bufferHdr - omx_base_address;
6375
6376 if (index < drv_ctx.op_buf.actualcount
6377 && omx_ptr_outputbuffer) {
6378 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
6379 omx_ptr_outputbuffer[index].bufferaddr);
6380
6381 if (!dynamic_buf_mode) {
6382 if (streaming[CAPTURE_PORT] &&
6383 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) {
6384 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
6385 DEBUG_PRINT_ERROR("STREAMOFF(CAPTURE_MPLANE) Failed");
6386 } else {
6387 DEBUG_PRINT_LOW("STREAMOFF(CAPTURE_MPLANE) Successful");
6388 }
6389 }
6390 #ifdef _ANDROID_
6391 if (m_enable_android_native_buffers) {
6392 if (!secure_mode) {
6393 if (omx_ptr_outputbuffer[index].pmem_fd > 0) {
6394 ion_unmap(omx_ptr_outputbuffer[index].pmem_fd,
6395 omx_ptr_outputbuffer[index].bufferaddr,
6396 omx_ptr_outputbuffer[index].mmaped_size);
6397 }
6398 }
6399 } else {
6400 #endif
6401 if (omx_ptr_outputbuffer[index].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
6402 if (!secure_mode) {
6403 ion_unmap(omx_ptr_outputbuffer[index].pmem_fd,
6404 omx_ptr_outputbuffer[index].bufferaddr,
6405 omx_ptr_outputbuffer[index].mmaped_size);
6406 omx_ptr_outputbuffer[index].bufferaddr = NULL;
6407 omx_ptr_outputbuffer[index].mmaped_size = 0;
6408 }
6409 #ifdef USE_GBM
6410 free_gbm_memory(&omx_op_buf_gbm_info[index]);
6411 #elif defined USE_ION
6412 free_ion_memory(&omx_op_buf_ion_info[index]);
6413 #endif
6414
6415 omx_ptr_outputbuffer[index].pmem_fd = -1;
6416 }
6417 #ifdef _ANDROID_
6418 }
6419 #endif
6420 } //!dynamic_buf_mode
6421 if (intermediate == false) {
6422 OMX_BUFFERHEADERTYPE *tempBufHdr = m_intermediate_out_mem_ptr + index;
6423 if (client_buffers.is_color_conversion_enabled() &&
6424 free_output_buffer(tempBufHdr, true) != OMX_ErrorNone) {
6425 return OMX_ErrorBadParameter;
6426 }
6427
6428 if (release_output_done()) {
6429 DEBUG_PRINT_HIGH("All output buffers released, free extradata");
6430 free_extradata();
6431 }
6432 }
6433 }
6434
6435 return OMX_ErrorNone;
6436 }
6437
allocate_input_heap_buffer(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)6438 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
6439 OMX_BUFFERHEADERTYPE **bufferHdr,
6440 OMX_U32 port,
6441 OMX_PTR appData,
6442 OMX_U32 bytes)
6443 {
6444 OMX_BUFFERHEADERTYPE *input = NULL;
6445 unsigned char *buf_addr = NULL;
6446 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6447 unsigned i = 0;
6448
6449 /* Sanity Check*/
6450 if (bufferHdr == NULL) {
6451 return OMX_ErrorBadParameter;
6452 }
6453
6454 if (m_inp_heap_ptr == NULL) {
6455 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
6456 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
6457 drv_ctx.ip_buf.actualcount);
6458 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
6459 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
6460 drv_ctx.ip_buf.actualcount);
6461
6462 if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
6463 DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
6464 return OMX_ErrorInsufficientResources;
6465 }
6466 }
6467
6468 /*Find a Free index*/
6469 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
6470 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
6471 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
6472 break;
6473 }
6474 }
6475
6476 if (i < drv_ctx.ip_buf.actualcount) {
6477 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
6478
6479 if (buf_addr == NULL) {
6480 return OMX_ErrorInsufficientResources;
6481 }
6482
6483 *bufferHdr = (m_inp_heap_ptr + i);
6484 input = *bufferHdr;
6485 BITMASK_SET(&m_heap_inp_bm_count,i);
6486
6487 input->pBuffer = (OMX_U8 *)buf_addr;
6488 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
6489 input->nVersion.nVersion = OMX_SPEC_VERSION;
6490 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
6491 input->pAppPrivate = appData;
6492 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
6493 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
6494 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
6495 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
6496 /*Add the Buffers to freeq*/
6497 if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[i],
6498 (unsigned)NULL, (unsigned)NULL)) {
6499 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
6500 return OMX_ErrorInsufficientResources;
6501 }
6502 } else {
6503 return OMX_ErrorBadParameter;
6504 }
6505
6506 return eRet;
6507 }
6508
6509
6510 /* ======================================================================
6511 FUNCTION
6512 omx_vdec::AllocateInputBuffer
6513
6514 DESCRIPTION
6515 Helper function for allocate buffer in the input pin
6516
6517 PARAMETERS
6518 None.
6519
6520 RETURN VALUE
6521 true/false
6522
6523 ========================================================================== */
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)6524 OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
6525 OMX_IN OMX_HANDLETYPE hComp,
6526 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6527 OMX_IN OMX_U32 port,
6528 OMX_IN OMX_PTR appData,
6529 OMX_IN OMX_U32 bytes)
6530 {
6531 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6532 OMX_BUFFERHEADERTYPE *input = NULL;
6533 unsigned i = 0;
6534 unsigned char *buf_addr = NULL;
6535 int pmem_fd = -1, ret = 0;
6536 unsigned int align_size = 0;
6537
6538 (void) hComp;
6539 (void) port;
6540
6541
6542 if (bytes != drv_ctx.ip_buf.buffer_size) {
6543 DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u",
6544 (unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size);
6545 return OMX_ErrorBadParameter;
6546 }
6547
6548 if (!m_inp_mem_ptr) {
6549 /* Currently buffer reqs is being set only in set port defn */
6550 /* Client need not do set port definition if he sees enough buffers in get port defn */
6551 /* In such cases we need to do a set buffer reqs to driver. Doing it here */
6552 struct v4l2_requestbuffers bufreq;
6553
6554 DEBUG_PRINT_HIGH("Calling REQBUFS in %s ",__FUNCTION__);
6555 bufreq.memory = V4L2_MEMORY_USERPTR;
6556 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
6557 bufreq.count = drv_ctx.ip_buf.actualcount;
6558 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
6559 if (ret) {
6560 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
6561 /*TODO: How to handle this case */
6562 eRet = OMX_ErrorInsufficientResources;
6563 } else if (bufreq.count != drv_ctx.ip_buf.actualcount) {
6564 DEBUG_PRINT_ERROR("%s Count(%d) is not expected to change to %d",
6565 __FUNCTION__, drv_ctx.ip_buf.actualcount, bufreq.count);
6566 eRet = OMX_ErrorInsufficientResources;
6567 }
6568
6569 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)",
6570 drv_ctx.ip_buf.actualcount,
6571 (unsigned int)drv_ctx.ip_buf.buffer_size);
6572
6573 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
6574 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
6575
6576 if (m_inp_mem_ptr == NULL) {
6577 return OMX_ErrorInsufficientResources;
6578 }
6579
6580 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
6581 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
6582
6583 if (drv_ctx.ptr_inputbuffer == NULL) {
6584 return OMX_ErrorInsufficientResources;
6585 }
6586 #ifdef USE_ION
6587 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
6588 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
6589
6590 if (drv_ctx.ip_buf_ion_info == NULL) {
6591 return OMX_ErrorInsufficientResources;
6592 }
6593 #endif
6594
6595 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
6596 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
6597 #ifdef USE_ION
6598 drv_ctx.ip_buf_ion_info[i].data_fd = -1;
6599 drv_ctx.ip_buf_ion_info[i].dev_fd = -1;
6600 #endif
6601 }
6602 }
6603
6604 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
6605 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6606 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
6607 break;
6608 }
6609 }
6610
6611 if (i < drv_ctx.ip_buf.actualcount) {
6612 int rc;
6613 DEBUG_PRINT_LOW("Allocate input Buffer");
6614 #ifdef USE_ION
6615 align_size = drv_ctx.ip_buf.buffer_size + 512;
6616 align_size = (align_size + drv_ctx.ip_buf.alignment - 1)&(~(drv_ctx.ip_buf.alignment - 1));
6617 // Input buffers are cached to make parsing faster
6618 bool status = alloc_map_ion_memory(
6619 align_size, &drv_ctx.ip_buf_ion_info[i],
6620 secure_mode ? SECURE_FLAGS_INPUT_BUFFER : ION_FLAG_CACHED);
6621 if (status == false) {
6622 return OMX_ErrorInsufficientResources;
6623 }
6624 pmem_fd = drv_ctx.ip_buf_ion_info[i].data_fd;
6625 #endif
6626 if (!secure_mode) {
6627 buf_addr = (unsigned char *)ion_map(pmem_fd, drv_ctx.ip_buf.buffer_size);
6628 if (buf_addr == MAP_FAILED) {
6629 #ifdef USE_ION
6630 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
6631 #endif
6632 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
6633 return OMX_ErrorInsufficientResources;
6634 }
6635 }
6636 *bufferHdr = (m_inp_mem_ptr + i);
6637 if (secure_mode)
6638 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
6639 else
6640 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
6641 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
6642 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
6643 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
6644 drv_ctx.ptr_inputbuffer [i].offset = 0;
6645
6646 input = *bufferHdr;
6647 BITMASK_SET(&m_inp_bm_count,i);
6648 if (allocate_native_handle) {
6649 native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/);
6650 if (!nh) {
6651 DEBUG_PRINT_ERROR("Native handle create failed");
6652 return OMX_ErrorInsufficientResources;
6653 }
6654 nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd;
6655 input->pBuffer = (OMX_U8 *)nh;
6656 } else if (secure_mode || m_input_pass_buffer_fd) {
6657 /*Legacy method, pass ion fd stashed directly in pBuffer*/
6658 input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer[i].pmem_fd;
6659 } else {
6660 input->pBuffer = (OMX_U8 *)buf_addr;
6661 }
6662 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
6663 input->nVersion.nVersion = OMX_SPEC_VERSION;
6664 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
6665 input->pAppPrivate = appData;
6666 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
6667 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
6668
6669 if (drv_ctx.disable_dmx) {
6670 eRet = allocate_desc_buffer(i);
6671 }
6672 } else {
6673 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
6674 eRet = OMX_ErrorInsufficientResources;
6675 }
6676
6677 if (eRet == OMX_ErrorNone)
6678 DEBUG_PRINT_HIGH("Allocate_input_buffer(%d): Header %p buffer %p allocLen %d offset %d fd = %d",
6679 i, input, input->pBuffer, input->nAllocLen,
6680 input->nOffset, drv_ctx.ptr_inputbuffer[i].pmem_fd);
6681
6682 return eRet;
6683 }
6684
6685
6686 /* ======================================================================
6687 FUNCTION
6688 omx_vdec::AllocateOutputBuffer
6689
6690 DESCRIPTION
6691 Helper fn for AllocateBuffer in the output pin
6692
6693 PARAMETERS
6694 <TBD>.
6695
6696 RETURN VALUE
6697 OMX Error None if everything went well.
6698
6699 ========================================================================== */
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,OMX_IN bool intermediate,OMX_IN int index)6700 OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
6701 OMX_IN OMX_HANDLETYPE hComp,
6702 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6703 OMX_IN OMX_U32 port,
6704 OMX_IN OMX_PTR appData,
6705 OMX_IN OMX_U32 bytes,
6706 OMX_IN bool intermediate,
6707 OMX_IN int index)
6708 {
6709 (void)hComp;
6710 (void)port;
6711
6712 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6713 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
6714 unsigned i= 0; // Temporary counter
6715 #ifdef USE_ION
6716 struct ion_allocation_data ion_alloc_data;
6717 #endif
6718 OMX_BUFFERHEADERTYPE **omx_base_address =
6719 intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
6720
6721 vdec_bufferpayload **omx_ptr_outputbuffer =
6722 intermediate?&drv_ctx.ptr_intermediate_outputbuffer:&drv_ctx.ptr_outputbuffer;
6723 vdec_output_frameinfo **omx_ptr_respbuffer =
6724 intermediate?&drv_ctx.ptr_intermediate_respbuffer:&drv_ctx.ptr_respbuffer;
6725 vdec_ion **omx_op_buf_ion_info =
6726 intermediate?&drv_ctx.op_intermediate_buf_ion_info:&drv_ctx.op_buf_ion_info;
6727 #ifdef USE_GBM
6728 vdec_gbm **omx_op_buf_gbm_info =
6729 intermediate?&drv_ctx.op_intermediate_buf_gbm_info:&drv_ctx.op_buf_gbm_info;
6730 #endif
6731
6732 if (!*omx_base_address) {
6733 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)",
6734 drv_ctx.op_buf.actualcount,
6735 (unsigned int)drv_ctx.op_buf.buffer_size);
6736 int nBufHdrSize = 0;
6737 int nPlatformEntrySize = 0;
6738 int nPlatformListSize = 0;
6739 int nPMEMInfoSize = 0;
6740
6741 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
6742 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
6743 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
6744
6745 nBufHdrSize = drv_ctx.op_buf.actualcount *
6746 sizeof(OMX_BUFFERHEADERTYPE);
6747 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
6748 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
6749 nPlatformListSize = drv_ctx.op_buf.actualcount *
6750 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
6751 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
6752 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
6753
6754 *omx_base_address = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
6755 // Alloc mem for platform specific info
6756 char *pPtr=NULL;
6757 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
6758 nPMEMInfoSize,1);
6759 *omx_ptr_outputbuffer = (struct vdec_bufferpayload *) \
6760 calloc (sizeof(struct vdec_bufferpayload),
6761 drv_ctx.op_buf.actualcount);
6762 *omx_ptr_respbuffer = (struct vdec_output_frameinfo *)\
6763 calloc (sizeof (struct vdec_output_frameinfo),
6764 drv_ctx.op_buf.actualcount);
6765 if (!*omx_ptr_outputbuffer || !*omx_ptr_respbuffer) {
6766 DEBUG_PRINT_ERROR("Failed to alloc outputbuffer or respbuffer ");
6767 free(pPtr);
6768 return OMX_ErrorInsufficientResources;
6769 }
6770
6771 #ifdef USE_GBM
6772 *omx_op_buf_gbm_info = (struct vdec_gbm *)\
6773 calloc (sizeof(struct vdec_gbm),
6774 drv_ctx.op_buf.actualcount);
6775 if (!*omx_op_buf_gbm_info) {
6776 DEBUG_PRINT_ERROR("Failed to alloc op_buf_gbm_info");
6777 return OMX_ErrorInsufficientResources;
6778 }
6779 drv_ctx.gbm_device_fd = open("/dev/dri/renderD128", O_RDWR | O_CLOEXEC);
6780 if (drv_ctx.gbm_device_fd < 0) {
6781 DEBUG_PRINT_ERROR("opening dri device for gbm failed with fd = %d", drv_ctx.gbm_device_fd);
6782 return OMX_ErrorInsufficientResources;
6783 }
6784 #elif defined USE_ION
6785 *omx_op_buf_ion_info = (struct vdec_ion *)\
6786 calloc (sizeof(struct vdec_ion),
6787 drv_ctx.op_buf.actualcount);
6788 if (!*omx_op_buf_ion_info) {
6789 DEBUG_PRINT_ERROR("Failed to alloc op_buf_ion_info");
6790 return OMX_ErrorInsufficientResources;
6791 }
6792 #endif
6793
6794 if (*omx_base_address && pPtr && *omx_ptr_outputbuffer
6795 && *omx_ptr_respbuffer) {
6796 bufHdr = *omx_base_address;
6797 if (m_platform_list) {
6798 free(m_platform_list);
6799 }
6800 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
6801 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
6802 (((char *) m_platform_list) + nPlatformListSize);
6803 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6804 (((char *) m_platform_entry) + nPlatformEntrySize);
6805 pPlatformList = m_platform_list;
6806 pPlatformEntry = m_platform_entry;
6807 pPMEMInfo = m_pmem_info;
6808
6809 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p", *omx_base_address);
6810
6811 // Settting the entire storage nicely
6812 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
6813 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
6814 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
6815 // Set the values when we determine the right HxW param
6816 bufHdr->nAllocLen = bytes;
6817 bufHdr->nFilledLen = 0;
6818 bufHdr->pAppPrivate = appData;
6819 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
6820 // Platform specific PMEM Information
6821 // Initialize the Platform Entry
6822 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
6823 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6824 pPlatformEntry->entry = pPMEMInfo;
6825 // Initialize the Platform List
6826 pPlatformList->nEntries = 1;
6827 pPlatformList->entryList = pPlatformEntry;
6828 // Keep pBuffer NULL till vdec is opened
6829 bufHdr->pBuffer = NULL;
6830 bufHdr->nOffset = 0;
6831 pPMEMInfo->offset = 0;
6832 pPMEMInfo->pmem_fd = -1;
6833 bufHdr->pPlatformPrivate = pPlatformList;
6834 /*Create a mapping between buffers*/
6835 bufHdr->pOutputPortPrivate = &(*omx_ptr_respbuffer)[i];
6836 (*omx_ptr_respbuffer)[i].client_data = (void *) \
6837 &(*omx_ptr_outputbuffer)[i];
6838 // Move the buffer and buffer header pointers
6839 bufHdr++;
6840 pPMEMInfo++;
6841 pPlatformEntry++;
6842 pPlatformList++;
6843 }
6844 } else {
6845 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
6846 *omx_base_address, pPtr);
6847 if (*omx_base_address) {
6848 free(*omx_base_address);
6849 *omx_base_address = NULL;
6850 }
6851 if (pPtr) {
6852 free(pPtr);
6853 pPtr = NULL;
6854 }
6855 if (*omx_ptr_outputbuffer) {
6856 free(*omx_ptr_outputbuffer);
6857 *omx_ptr_outputbuffer = NULL;
6858 }
6859 if (*omx_ptr_respbuffer) {
6860 free(*omx_ptr_respbuffer);
6861 *omx_ptr_respbuffer = NULL;
6862 }
6863 #ifdef USE_GBM
6864 if(drv_ctx.gbm_device_fd >= 0) {
6865 DEBUG_PRINT_LOW("Close gbm device");
6866 close(drv_ctx.gbm_device_fd);
6867 drv_ctx.gbm_device_fd = -1;
6868 }
6869 if (*omx_op_buf_gbm_info) {
6870 DEBUG_PRINT_LOW("Free o/p gbm context");
6871 free(*omx_op_buf_gbm_info);
6872 *omx_op_buf_gbm_info = NULL;
6873 }
6874 #elif defined USE_ION
6875 if (*omx_op_buf_ion_info) {
6876 DEBUG_PRINT_LOW("Free o/p ion context");
6877 free(*omx_op_buf_ion_info);
6878 *omx_op_buf_ion_info = NULL;
6879 }
6880 #endif
6881 eRet = OMX_ErrorInsufficientResources;
6882 }
6883 if (eRet == OMX_ErrorNone)
6884 eRet = allocate_extradata();
6885 }
6886
6887 if (intermediate == true && index != -1) {
6888 i = index;
6889 } else {
6890 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
6891 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
6892 break;
6893 }
6894 }
6895 }
6896
6897 if (eRet == OMX_ErrorNone) {
6898 if (i < drv_ctx.op_buf.actualcount) {
6899 int rc;
6900 int pmem_fd = -1;
6901 int fd = -1;
6902 unsigned char *pmem_baseaddress = NULL;
6903 #ifdef USE_GBM
6904 int pmeta_fd = -1;
6905 // Allocate output buffers as cached to improve performance of software-reading
6906 // of the YUVs. Output buffers are cache-invalidated in driver.
6907 // If color-conversion is involved, Only the C2D output buffers are cached, no
6908 // need to cache the decoder's output buffers
6909 int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
6910 bool status = alloc_map_gbm_memory(
6911 drv_ctx.video_resolution.frame_width,
6912 drv_ctx.video_resolution.frame_height,
6913 drv_ctx.gbm_device_fd,
6914 &(*omx_op_buf_gbm_info)[i],
6915 (secure_mode && !secure_scaling_to_non_secure_opb) ?
6916 SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
6917 if (status == false) {
6918 return OMX_ErrorInsufficientResources;
6919 }
6920 pmem_fd = (*omx_op_buf_gbm_info)[i].bo_fd;
6921 pmeta_fd = (*omx_op_buf_gbm_info)[i].meta_fd;
6922 #elif defined USE_ION
6923 // Allocate output buffers as cached to improve performance of software-reading
6924 // of the YUVs. Output buffers are cache-invalidated in driver.
6925 // If color-conversion is involved, Only the C2D output buffers are cached, no
6926 // need to cache the decoder's output buffers
6927 int cache_flag = ION_FLAG_CACHED;
6928 if (intermediate == true && client_buffers.is_color_conversion_enabled()) {
6929 cache_flag = 0;
6930 }
6931 bool status = alloc_map_ion_memory(drv_ctx.op_buf.buffer_size,
6932 &(*omx_op_buf_ion_info)[i],
6933 (secure_mode && !secure_scaling_to_non_secure_opb) ?
6934 SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
6935 if (status == false) {
6936 return OMX_ErrorInsufficientResources;
6937 }
6938 pmem_fd = (*omx_op_buf_ion_info)[i].data_fd;
6939 #endif
6940 if (!secure_mode) {
6941 pmem_baseaddress = (unsigned char *)ion_map(pmem_fd, drv_ctx.op_buf.buffer_size);
6942 if (pmem_baseaddress == MAP_FAILED) {
6943 DEBUG_PRINT_ERROR("MMAP failed for Size %u",
6944 (unsigned int)drv_ctx.op_buf.buffer_size);
6945 #ifdef USE_GBM
6946 free_gbm_memory(&(*omx_op_buf_gbm_info)[i]);
6947 #elif defined USE_ION
6948 free_ion_memory(&(*omx_op_buf_ion_info)[i]);
6949 #endif
6950 return OMX_ErrorInsufficientResources;
6951 }
6952 }
6953 (*omx_ptr_outputbuffer)[i].pmem_fd = pmem_fd;
6954 #ifdef USE_GBM
6955 m_pmem_info[i].pmeta_fd = pmeta_fd;
6956 #endif
6957 (*omx_ptr_outputbuffer)[i].offset = 0;
6958 (*omx_ptr_outputbuffer)[i].bufferaddr = pmem_baseaddress;
6959 (*omx_ptr_outputbuffer)[i].mmaped_size = drv_ctx.op_buf.buffer_size;
6960 (*omx_ptr_outputbuffer)[i].buffer_len = drv_ctx.op_buf.buffer_size;
6961 m_pmem_info[i].pmem_fd = pmem_fd;
6962 m_pmem_info[i].size = (*omx_ptr_outputbuffer)[i].buffer_len;
6963 m_pmem_info[i].mapped_size = (*omx_ptr_outputbuffer)[i].mmaped_size;
6964 m_pmem_info[i].buffer = (*omx_ptr_outputbuffer)[i].bufferaddr;
6965 m_pmem_info[i].offset = (*omx_ptr_outputbuffer)[i].offset;
6966
6967 *bufferHdr = (*omx_base_address + i );
6968 if (secure_mode) {
6969 #ifdef USE_GBM
6970 (*omx_ptr_outputbuffer)[i].bufferaddr =
6971 (OMX_U8 *)(intptr_t)(*omx_op_buf_gbm_info)[i].bo_fd;
6972 #elif defined USE_ION
6973 (*omx_ptr_outputbuffer)[i].bufferaddr =
6974 (OMX_U8 *)(intptr_t)(*omx_op_buf_ion_info)[i].data_fd;
6975 #endif
6976 }
6977 if (intermediate == false &&
6978 client_buffers.is_color_conversion_enabled()) {
6979 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
6980 eRet = allocate_output_buffer(hComp, &temp_bufferHdr,
6981 port, appData,
6982 drv_ctx.op_buf.buffer_size,
6983 true, i);
6984 }
6985 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
6986 enum v4l2_buf_type buf_type;
6987
6988 set_buffer_req(&drv_ctx.op_buf);
6989 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6990 if (!client_buffers.is_color_conversion_enabled() ||
6991 (client_buffers.is_color_conversion_enabled() && intermediate == true)) {
6992 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
6993 if (rc) {
6994 DEBUG_PRINT_ERROR("STREAMON(CAPTURE_MPLANE) Failed");
6995 return OMX_ErrorInsufficientResources;
6996 } else {
6997 streaming[CAPTURE_PORT] = true;
6998 DEBUG_PRINT_LOW("STREAMON(CAPTURE_MPLANE) Successful");
6999 }
7000 }
7001 }
7002
7003 (*bufferHdr)->pBuffer = (OMX_U8*)(*omx_ptr_outputbuffer)[i].bufferaddr;
7004 (*bufferHdr)->pAppPrivate = appData;
7005 BITMASK_SET(&m_out_bm_count,i);
7006 } else {
7007 DEBUG_PRINT_ERROR("Faile to allocate output buffer (%d) maxcount %d",
7008 i, drv_ctx.op_buf.actualcount);
7009 eRet = OMX_ErrorInsufficientResources;
7010 }
7011 }
7012
7013 if (eRet == OMX_ErrorNone)
7014 DEBUG_PRINT_HIGH("Allocate_output_buffer(%d): Header %p buffer %p allocLen %d offset %d fd = %d intermediate %d",
7015 i, (*bufferHdr), (*bufferHdr)->pBuffer, (*bufferHdr)->nAllocLen,
7016 (*bufferHdr)->nOffset, (*omx_ptr_outputbuffer)[i].pmem_fd,
7017 intermediate);
7018 return eRet;
7019 }
7020
7021
7022 // AllocateBuffer -- API Call
7023 /* ======================================================================
7024 FUNCTION
7025 omx_vdec::AllocateBuffer
7026
7027 DESCRIPTION
7028 Returns zero if all the buffers released..
7029
7030 PARAMETERS
7031 None.
7032
7033 RETURN VALUE
7034 true/false
7035
7036 ========================================================================== */
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)7037 OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
7038 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
7039 OMX_IN OMX_U32 port,
7040 OMX_IN OMX_PTR appData,
7041 OMX_IN OMX_U32 bytes)
7042 {
7043 unsigned i = 0;
7044 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
7045
7046 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
7047 if (m_state == OMX_StateInvalid) {
7048 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
7049 return OMX_ErrorInvalidState;
7050 }
7051
7052 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7053 // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
7054 // ensure that use-buffer was never called.
7055 // Mix-and-match of useBuffer and allocateBuffer is not allowed
7056 if (m_inp_mem_ptr && input_use_buffer) {
7057 DEBUG_PRINT_ERROR("'Allocate' Input buffer called after 'Use' Input buffer !");
7058 return OMX_ErrorUndefined;
7059 }
7060 if (arbitrary_bytes) {
7061 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
7062 } else {
7063 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
7064 }
7065 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7066 if (output_use_buffer) {
7067 DEBUG_PRINT_ERROR("Allocate output buffer not allowed after use buffer");
7068 return OMX_ErrorBadParameter;
7069 }
7070 eRet = allocate_output_buffer(hComp, bufferHdr, port, appData, bytes);
7071 } else {
7072 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
7073 eRet = OMX_ErrorBadPortIndex;
7074 }
7075 if (eRet == OMX_ErrorNone) {
7076 if (allocate_done()) {
7077 DEBUG_PRINT_HIGH("Allocated all buffers on port %d", port);
7078 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
7079 // Send the callback now
7080 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
7081 post_event(OMX_CommandStateSet,OMX_StateIdle,
7082 OMX_COMPONENT_GENERATE_EVENT);
7083 }
7084 }
7085 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
7086 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
7087 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
7088 post_event(OMX_CommandPortEnable,
7089 OMX_CORE_INPUT_PORT_INDEX,
7090 OMX_COMPONENT_GENERATE_EVENT);
7091 }
7092 }
7093 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
7094 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
7095 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
7096 post_event(OMX_CommandPortEnable,
7097 OMX_CORE_OUTPUT_PORT_INDEX,
7098 OMX_COMPONENT_GENERATE_EVENT);
7099 }
7100 }
7101 }
7102 return eRet;
7103 }
7104
7105 // Free Buffer - API call
7106 /* ======================================================================
7107 FUNCTION
7108 omx_vdec::FreeBuffer
7109
7110 DESCRIPTION
7111
7112 PARAMETERS
7113 None.
7114
7115 RETURN VALUE
7116 true/false
7117
7118 ========================================================================== */
free_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_BUFFERHEADERTYPE * buffer)7119 OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
7120 OMX_IN OMX_U32 port,
7121 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7122 {
7123 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7124 unsigned int nPortIndex;
7125 (void) hComp;
7126
7127 auto_lock l(buf_lock);
7128 if (m_state == OMX_StateIdle &&
7129 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
7130 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
7131 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
7132 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
7133 DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
7134 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
7135 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
7136 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
7137 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
7138 DEBUG_PRINT_LOW("Free Buffer while port %u enable pending", (unsigned int)port);
7139 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
7140 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
7141 post_event(OMX_EventError,
7142 OMX_ErrorPortUnpopulated,
7143 OMX_COMPONENT_GENERATE_EVENT);
7144 m_buffer_error = true;
7145 return OMX_ErrorIncorrectStateOperation;
7146 } else if (m_state != OMX_StateInvalid) {
7147 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
7148 post_event(OMX_EventError,
7149 OMX_ErrorPortUnpopulated,
7150 OMX_COMPONENT_GENERATE_EVENT);
7151 }
7152
7153 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7154 /*Check if arbitrary bytes*/
7155 if (!arbitrary_bytes && !input_use_buffer)
7156 nPortIndex = buffer - m_inp_mem_ptr;
7157 else
7158 nPortIndex = buffer - m_inp_heap_ptr;
7159
7160 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
7161 if (nPortIndex < drv_ctx.ip_buf.actualcount &&
7162 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
7163 // Clear the bit associated with it.
7164 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
7165 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
7166 if (input_use_buffer == true) {
7167
7168 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
7169 if (m_phdr_pmem_ptr)
7170 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
7171 } else {
7172 if (arbitrary_bytes) {
7173 if (m_phdr_pmem_ptr)
7174 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
7175 else
7176 free_input_buffer(nPortIndex,NULL);
7177 } else
7178 free_input_buffer(buffer);
7179 }
7180 m_inp_bPopulated = OMX_FALSE;
7181 /*Free the Buffer Header*/
7182 if (release_input_done()) {
7183 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
7184 free_input_buffer_header();
7185 }
7186 } else {
7187 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
7188 eRet = OMX_ErrorBadPortIndex;
7189 }
7190
7191 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
7192 && release_input_done()) {
7193 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
7194 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
7195 post_event(OMX_CommandPortDisable,
7196 OMX_CORE_INPUT_PORT_INDEX,
7197 OMX_COMPONENT_GENERATE_EVENT);
7198 }
7199 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7200 // check if the buffer is valid
7201 OMX_BUFFERHEADERTYPE *omx_base_address =
7202 client_buffers.is_color_conversion_enabled()?
7203 m_intermediate_out_mem_ptr:m_out_mem_ptr;
7204 nPortIndex = buffer - m_out_mem_ptr;
7205 if (nPortIndex < drv_ctx.op_buf.actualcount &&
7206 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
7207 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
7208 // Clear the bit associated with it.
7209 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
7210 m_out_bPopulated = OMX_FALSE;
7211 free_output_buffer (buffer);
7212
7213 if (release_output_done()) {
7214 DEBUG_PRINT_HIGH("All output buffers released.");
7215 free_output_buffer_header();
7216 }
7217 } else {
7218 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
7219 eRet = OMX_ErrorBadPortIndex;
7220 }
7221 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
7222 && release_output_done()) {
7223 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
7224 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
7225 #ifdef _ANDROID_ICS_
7226 if (m_enable_android_native_buffers) {
7227 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
7228 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
7229 }
7230 #endif
7231
7232 post_event(OMX_CommandPortDisable,
7233 OMX_CORE_OUTPUT_PORT_INDEX,
7234 OMX_COMPONENT_GENERATE_EVENT);
7235 }
7236 } else if (port == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
7237 nPortIndex = buffer - m_client_output_extradata_mem_ptr;
7238 DEBUG_PRINT_LOW("free_buffer on extradata output port - Port idx %d", nPortIndex);
7239
7240 BITMASK_CLEAR(&m_out_extradata_bm_count,nPortIndex);
7241
7242 if (release_output_extradata_done()) {
7243 free_output_extradata_buffer_header();
7244 }
7245 } else {
7246 eRet = OMX_ErrorBadPortIndex;
7247 }
7248 if ((eRet == OMX_ErrorNone) &&
7249 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
7250 if (release_done()) {
7251 /*
7252 * Reset buffer requirements here to ensure setting buffer requirement
7253 * when component move to executing state from loaded state via idle.
7254 */
7255 drv_ctx.op_buf.buffer_size = 0;
7256 drv_ctx.op_buf.actualcount = 0;
7257
7258 // Send the callback now
7259 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
7260 post_event(OMX_CommandStateSet, OMX_StateLoaded,
7261 OMX_COMPONENT_GENERATE_EVENT);
7262 m_buffer_error = false;
7263 }
7264 }
7265 return eRet;
7266 }
7267
7268
7269 /* ======================================================================
7270 FUNCTION
7271 omx_vdec::EmptyThisBuffer
7272
7273 DESCRIPTION
7274 This routine is used to push the encoded video frames to
7275 the video decoder.
7276
7277 PARAMETERS
7278 None.
7279
7280 RETURN VALUE
7281 OMX Error None if everything went successful.
7282
7283 ========================================================================== */
empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)7284 OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
7285 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7286 {
7287 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
7288 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
7289
7290 if (m_state != OMX_StateExecuting &&
7291 m_state != OMX_StatePause &&
7292 m_state != OMX_StateIdle) {
7293 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
7294 return OMX_ErrorInvalidState;
7295 }
7296
7297 if (m_error_propogated) {
7298 DEBUG_PRINT_ERROR("Empty this buffer not allowed after error");
7299 return OMX_ErrorHardware;
7300 }
7301
7302 if (buffer == NULL) {
7303 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
7304 return OMX_ErrorBadParameter;
7305 }
7306 print_omx_buffer("EmptyThisBuffer", buffer);
7307
7308 if (!m_inp_bEnabled) {
7309 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
7310 return OMX_ErrorIncorrectStateOperation;
7311 }
7312
7313 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
7314 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex);
7315 return OMX_ErrorBadPortIndex;
7316 }
7317
7318 if (perf_flag) {
7319 if (!latency) {
7320 dec_time.stop();
7321 latency = dec_time.processing_time_us();
7322 dec_time.start();
7323 }
7324 }
7325
7326 if (arbitrary_bytes) {
7327 nBufferIndex = buffer - m_inp_heap_ptr;
7328 } else {
7329 if (input_use_buffer == true) {
7330 nBufferIndex = buffer - m_inp_heap_ptr;
7331 if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
7332 DEBUG_PRINT_ERROR("ERROR: ETB nBufferIndex is invalid in use-buffer mode");
7333 return OMX_ErrorBadParameter;
7334 }
7335 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
7336 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
7337 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
7338 buffer = &m_inp_mem_ptr[nBufferIndex];
7339 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %u",
7340 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen);
7341 } else {
7342 nBufferIndex = buffer - m_inp_mem_ptr;
7343 }
7344 }
7345
7346 if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
7347 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
7348 return OMX_ErrorBadParameter;
7349 }
7350
7351 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
7352 codec_config_flag = true;
7353 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
7354 }
7355
7356 /* The client should not set this when codec is in arbitrary bytes mode */
7357 if (m_input_pass_buffer_fd) {
7358 buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr;
7359 }
7360
7361 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)",
7362 buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
7363 if (arbitrary_bytes) {
7364 post_event ((unsigned long)hComp,(unsigned long)buffer,
7365 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
7366 } else {
7367 post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB);
7368 }
7369 time_stamp_dts.insert_timestamp(buffer);
7370 return OMX_ErrorNone;
7371 }
7372
7373 /* ======================================================================
7374 FUNCTION
7375 omx_vdec::empty_this_buffer_proxy
7376
7377 DESCRIPTION
7378 This routine is used to push the encoded video frames to
7379 the video decoder.
7380
7381 PARAMETERS
7382 None.
7383
7384 RETURN VALUE
7385 OMX Error None if everything went successful.
7386
7387 ========================================================================== */
empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)7388 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
7389 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7390 {
7391 VIDC_TRACE_NAME_HIGH("ETB");
7392 (void) hComp;
7393 int push_cnt = 0,i=0;
7394 unsigned nPortIndex = 0;
7395 OMX_ERRORTYPE ret = OMX_ErrorNone;
7396 struct vdec_bufferpayload *temp_buffer;
7397 bool port_setting_changed = true;
7398
7399 /*Should we generate a Aync error event*/
7400 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
7401 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
7402 return OMX_ErrorBadParameter;
7403 }
7404
7405 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
7406
7407 if (nPortIndex >= drv_ctx.ip_buf.actualcount) {
7408 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
7409 nPortIndex);
7410 return OMX_ErrorBadParameter;
7411 }
7412
7413 pending_input_buffers++;
7414 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
7415
7416 /* return zero length and not an EOS buffer */
7417 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
7418 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
7419 DEBUG_PRINT_HIGH("return zero legth buffer");
7420 post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
7421 OMX_COMPONENT_GENERATE_EBD);
7422 return OMX_ErrorNone;
7423 }
7424
7425 if (input_flush_progress == true) {
7426 DEBUG_PRINT_LOW("Flush in progress return buffer ");
7427 post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
7428 OMX_COMPONENT_GENERATE_EBD);
7429 return OMX_ErrorNone;
7430 }
7431
7432 if (m_error_propogated == true) {
7433 DEBUG_PRINT_LOW("Return buffer in error state");
7434 post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
7435 OMX_COMPONENT_GENERATE_EBD);
7436 return OMX_ErrorNone;
7437 }
7438
7439 auto_lock l(buf_lock);
7440 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
7441
7442 if (!temp_buffer || (temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
7443 return OMX_ErrorBadParameter;
7444 }
7445
7446 if (BITMASK_ABSENT(&m_inp_bm_count, nPortIndex) || m_buffer_error) {
7447 DEBUG_PRINT_ERROR("ETBProxy: ERROR: invalid buffer, nPortIndex %u", nPortIndex);
7448 return OMX_ErrorBadParameter;
7449 }
7450
7451 VIDC_TRACE_INT_LOW("ETB-TS", buffer->nTimeStamp / 1000);
7452 VIDC_TRACE_INT_LOW("ETB-size", buffer->nFilledLen);
7453 /*for use buffer we need to memcpy the data*/
7454 temp_buffer->buffer_len = buffer->nFilledLen;
7455
7456 if (input_use_buffer && temp_buffer->bufferaddr && !secure_mode) {
7457 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
7458 if (arbitrary_bytes) {
7459 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
7460 } else {
7461 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
7462 buffer->nFilledLen);
7463 }
7464 } else {
7465 return OMX_ErrorBadParameter;
7466 }
7467
7468 }
7469
7470 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
7471 DEBUG_PRINT_LOW("ETB: dmx enabled");
7472 if (m_demux_entries == 0) {
7473 extract_demux_addr_offsets(buffer);
7474 }
7475
7476 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%u",(unsigned int)m_demux_entries);
7477 handle_demux_data(buffer);
7478 }
7479
7480 log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len, buffer->nTimeStamp, temp_buffer->pmem_fd);
7481
7482 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
7483 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7484 }
7485
7486 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
7487 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
7488 h264_scratch.nFilledLen = 0;
7489 nal_count = 0;
7490 look_ahead_nal = false;
7491 frame_count = 0;
7492 if (m_frame_parser.mutils)
7493 m_frame_parser.mutils->initialize_frame_checking_environment();
7494 m_frame_parser.flush();
7495 h264_last_au_ts = LLONG_MAX;
7496 h264_last_au_flags = 0;
7497 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
7498 m_demux_entries = 0;
7499 }
7500 struct v4l2_buffer buf;
7501 struct v4l2_plane plane;
7502 memset( (void *)&buf, 0, sizeof(buf));
7503 memset( (void *)&plane, 0, sizeof(plane));
7504 int rc;
7505 unsigned long print_count;
7506 if (temp_buffer->buffer_len == 0 && (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
7507 struct v4l2_decoder_cmd dec;
7508
7509 if (!streaming[OUTPUT_PORT]) {
7510 enum v4l2_buf_type buf_type;
7511 int ret = 0;
7512
7513 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7514 DEBUG_PRINT_HIGH("Calling streamon before issuing stop command for EOS");
7515 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
7516 if (!ret) {
7517 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
7518 streaming[OUTPUT_PORT] = true;
7519 } else {
7520 DEBUG_PRINT_ERROR("Streamon failed before sending stop command");
7521 return OMX_ErrorHardware;
7522 }
7523 }
7524
7525 DEBUG_PRINT_HIGH("Input EOS reached. Converted to STOP command") ;
7526 memset(&dec, 0, sizeof(dec));
7527 dec.cmd = V4L2_DEC_CMD_STOP;
7528 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec);
7529 post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
7530 OMX_COMPONENT_GENERATE_EBD);
7531 if (rc < 0) {
7532 DEBUG_PRINT_ERROR("Decoder CMD failed");
7533 return OMX_ErrorHardware;
7534 }
7535 return OMX_ErrorNone;
7536 }
7537
7538 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
7539 DEBUG_PRINT_HIGH("Input EOS reached") ;
7540 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
7541 }
7542
7543
7544 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7545 buf.index = nPortIndex;
7546 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7547 buf.memory = V4L2_MEMORY_USERPTR;
7548 plane.bytesused = temp_buffer->buffer_len;
7549 plane.length = drv_ctx.ip_buf.buffer_size;
7550 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
7551 (unsigned long)temp_buffer->offset;
7552 plane.reserved[0] = temp_buffer->pmem_fd;
7553 plane.reserved[1] = temp_buffer->offset;
7554 plane.reserved[3] = (unsigned long)buffer->pMarkData;
7555 plane.reserved[4] = (unsigned long)buffer->hMarkTargetComponent;
7556 plane.data_offset = 0;
7557 buf.m.planes = &plane;
7558 buf.length = 1;
7559 //assumption is that timestamp is in milliseconds
7560 buf.timestamp.tv_sec = buffer->nTimeStamp / 1000000;
7561 buf.timestamp.tv_usec = (buffer->nTimeStamp % 1000000);
7562 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
7563 #if NEED_TO_REVISIT
7564 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
7565 #endif
7566
7567 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
7568 DEBUG_PRINT_LOW("Increment codec_config buffer counter");
7569 android_atomic_inc(&m_queued_codec_config_count);
7570 }
7571
7572 print_v4l2_buffer("QBUF-ETB", &buf);
7573 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
7574 if (rc) {
7575 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver, send ETB back to client");
7576 print_v4l2_buffer("QBUF failed", &buf);
7577 print_omx_buffer("EBD on qbuf failed", buffer);
7578 m_cb.EmptyBufferDone(hComp, m_app_data, buffer);
7579 return OMX_ErrorHardware;
7580 }
7581
7582 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
7583 codec_config_flag = false;
7584 }
7585 if (!streaming[OUTPUT_PORT]) {
7586 enum v4l2_buf_type buf_type;
7587 int ret,r;
7588
7589 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7590 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
7591 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
7592 if (!ret) {
7593 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
7594 streaming[OUTPUT_PORT] = true;
7595 } else if (errno == EBUSY) {
7596 DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
7597 post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
7598 OMX_COMPONENT_GENERATE_EBD);
7599 return OMX_ErrorInsufficientResources;
7600 } else {
7601 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
7602 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
7603 post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
7604 OMX_COMPONENT_GENERATE_EBD);
7605 return OMX_ErrorBadParameter;
7606 }
7607 }
7608
7609 return ret;
7610 }
7611
7612 /* ======================================================================
7613 FUNCTION
7614 omx_vdec::FillThisBuffer
7615
7616 DESCRIPTION
7617 IL client uses this method to release the frame buffer
7618 after displaying them.
7619
7620 PARAMETERS
7621 None.
7622
7623 RETURN VALUE
7624 true/false
7625
7626 ========================================================================== */
fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)7627 OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
7628 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
7629 {
7630 if (m_state != OMX_StateExecuting &&
7631 m_state != OMX_StatePause &&
7632 m_state != OMX_StateIdle) {
7633 DEBUG_PRINT_ERROR("FTB in Invalid State");
7634 return OMX_ErrorInvalidState;
7635 }
7636
7637 if (buffer == NULL || buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
7638 DEBUG_PRINT_ERROR("ERROR:FTB invalid buffer %p or PortIndex - %d",
7639 buffer, buffer ? (int)buffer->nOutputPortIndex : -1);
7640 return OMX_ErrorBadPortIndex;
7641 }
7642 print_omx_buffer("FillThisBuffer", buffer);
7643
7644 if (m_error_propogated) {
7645 DEBUG_PRINT_ERROR("Fill this buffer not allowed after error");
7646 return OMX_ErrorHardware;
7647 }
7648
7649 if (!m_out_bEnabled) {
7650 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
7651 return OMX_ErrorIncorrectStateOperation;
7652 }
7653
7654 unsigned nPortIndex = buffer - m_out_mem_ptr;
7655 if (dynamic_buf_mode) {
7656 private_handle_t *handle = NULL;
7657 struct VideoDecoderOutputMetaData *meta = NULL;
7658
7659 if (!buffer || !buffer->pBuffer) {
7660 DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
7661 return OMX_ErrorBadParameter;
7662 }
7663
7664 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
7665 handle = (private_handle_t *)meta->pHandle;
7666
7667 //get the buffer type and fd info
7668 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ",
7669 meta, meta->eType, meta->pHandle);
7670
7671 if (!handle) {
7672 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
7673 return OMX_ErrorBadParameter;
7674 }
7675
7676 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
7677 if (nPortIndex < drv_ctx.op_buf.actualcount &&
7678 nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
7679 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
7680 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
7681
7682 //Store private handle from GraphicBuffer
7683 native_buffer[nPortIndex].privatehandle = handle;
7684 native_buffer[nPortIndex].nativehandle = handle;
7685 } else {
7686 DEBUG_PRINT_ERROR("[FTB]Invalid native_buffer index: %d", nPortIndex);
7687 return OMX_ErrorBadParameter;
7688 }
7689
7690 if (handle->flags & private_handle_t::PRIV_FLAGS_DISP_CONSUMER) {
7691 m_is_display_session = true;
7692 } else {
7693 m_is_display_session = false;
7694 }
7695 buffer->nAllocLen = handle->size;
7696 DEBUG_PRINT_LOW("%s: buffer size = d-%d:b-%d",
7697 __func__, (int)drv_ctx.op_buf.buffer_size, (int)handle->size);
7698
7699 if (!client_buffers.is_color_conversion_enabled()) {
7700 drv_ctx.op_buf.buffer_size = handle->size;
7701 }
7702
7703 DEBUG_PRINT_LOW("%s: m_is_display_session = %d", __func__, m_is_display_session);
7704 }
7705
7706 if (client_buffers.is_color_conversion_enabled()) {
7707 buffer = m_intermediate_out_mem_ptr + nPortIndex;
7708 buffer->nAllocLen = drv_ctx.op_buf.buffer_size;
7709 }
7710
7711 //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
7712 //this with a more sane size so that we don't compensate in rest of code
7713 //We'll restore this size later on, so that it's transparent to client
7714 buffer->nFilledLen = 0;
7715
7716 post_event((unsigned long) hComp, (unsigned long)buffer, m_fill_output_msg);
7717 return OMX_ErrorNone;
7718 }
7719
7720 /* ======================================================================
7721 FUNCTION
7722 omx_vdec::fill_this_buffer_proxy
7723
7724 DESCRIPTION
7725 IL client uses this method to release the frame buffer
7726 after displaying them.
7727
7728 PARAMETERS
7729 None.
7730
7731 RETURN VALUE
7732 true/false
7733
7734 ========================================================================== */
fill_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * bufferAdd)7735 OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
7736 OMX_IN OMX_HANDLETYPE hComp,
7737 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
7738 {
7739 VIDC_TRACE_NAME_HIGH("FTB");
7740 OMX_ERRORTYPE nRet = OMX_ErrorNone;
7741 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
7742 unsigned bufIndex = 0;
7743 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
7744 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
7745
7746 auto_lock l(buf_lock);
7747 OMX_BUFFERHEADERTYPE *omx_base_address =
7748 client_buffers.is_color_conversion_enabled()?
7749 m_intermediate_out_mem_ptr:m_out_mem_ptr;
7750 vdec_bufferpayload *omx_ptr_outputbuffer =
7751 client_buffers.is_color_conversion_enabled()?
7752 drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
7753 bufIndex = buffer-omx_base_address;
7754
7755 if (bufferAdd == NULL || bufIndex >= drv_ctx.op_buf.actualcount) {
7756 DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, bufIndex %u bufCount %u",
7757 bufIndex, drv_ctx.op_buf.actualcount);
7758 return OMX_ErrorBadParameter;
7759 }
7760
7761 if (BITMASK_ABSENT(&m_out_bm_count, bufIndex) || m_buffer_error) {
7762 DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer, bufIndex %u", bufIndex);
7763 return OMX_ErrorBadParameter;
7764 }
7765
7766 /*Return back the output buffer to client*/
7767 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true || in_reconfig) {
7768 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
7769 buffer->nFilledLen = 0;
7770 print_omx_buffer("FBD in FTBProxy", &m_out_mem_ptr[bufIndex]);
7771 m_cb.FillBufferDone (hComp,m_app_data,&m_out_mem_ptr[bufIndex]);
7772 return OMX_ErrorNone;
7773 }
7774 if (m_error_propogated == true) {
7775 DEBUG_PRINT_LOW("Return buffers in error state");
7776 buffer->nFilledLen = 0;
7777 print_omx_buffer("FBD in FTBProxy", &m_out_mem_ptr[bufIndex]);
7778 m_cb.FillBufferDone (hComp,m_app_data,&m_out_mem_ptr[bufIndex]);
7779 return OMX_ErrorNone;
7780 }
7781
7782 if (dynamic_buf_mode) {
7783 omx_ptr_outputbuffer[bufIndex].offset = 0;
7784 omx_ptr_outputbuffer[bufIndex].buffer_len = buffer->nAllocLen;
7785 omx_ptr_outputbuffer[bufIndex].mmaped_size = buffer->nAllocLen;
7786 }
7787
7788 pending_output_buffers++;
7789 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
7790 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
7791 if (ptr_respbuffer) {
7792 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
7793 }
7794
7795 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
7796 DEBUG_PRINT_ERROR("Invalid ptr_respbuffer %p, ptr_outputbuffer %p",
7797 ptr_respbuffer, ptr_outputbuffer);
7798 buffer->nFilledLen = 0;
7799 print_omx_buffer("FBD in error", &m_out_mem_ptr[bufIndex]);
7800 m_cb.FillBufferDone (hComp,m_app_data,&m_out_mem_ptr[bufIndex]);
7801 pending_output_buffers--;
7802 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
7803 return OMX_ErrorBadParameter;
7804 }
7805
7806 int rc = 0;
7807 struct v4l2_buffer buf;
7808 struct v4l2_plane plane[VIDEO_MAX_PLANES];
7809 memset( (void *)&buf, 0, sizeof(buf));
7810 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
7811 unsigned int extra_idx = 0;
7812
7813 buf.index = bufIndex;
7814 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7815 buf.memory = V4L2_MEMORY_USERPTR;
7816 plane[0].bytesused = buffer->nFilledLen;
7817 plane[0].length = buffer->nAllocLen;
7818 plane[0].m.userptr =
7819 (unsigned long)omx_ptr_outputbuffer[bufIndex].bufferaddr -
7820 (unsigned long)omx_ptr_outputbuffer[bufIndex].offset;
7821 plane[0].reserved[0] = omx_ptr_outputbuffer[bufIndex].pmem_fd;
7822 plane[0].reserved[1] = omx_ptr_outputbuffer[bufIndex].offset;
7823 plane[0].data_offset = 0;
7824 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7825 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7826 plane[extra_idx].bytesused = 0;
7827 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
7828 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + bufIndex * drv_ctx.extradata_info.buffer_size);
7829 #ifdef USE_ION
7830 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.data_fd;
7831 #endif
7832 plane[extra_idx].reserved[1] = bufIndex * drv_ctx.extradata_info.buffer_size;
7833 plane[extra_idx].data_offset = 0;
7834 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7835 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
7836 return OMX_ErrorBadParameter;
7837 }
7838 buf.m.planes = plane;
7839 buf.length = drv_ctx.num_planes;
7840 print_v4l2_buffer("QBUF-FTB", &buf);
7841 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
7842 if (rc) {
7843 buffer->nFilledLen = 0;
7844 DEBUG_PRINT_ERROR("Failed to qbuf to driver, error %s", strerror(errno));
7845 print_omx_buffer("FBD in error", &m_out_mem_ptr[bufIndex]);
7846 m_cb.FillBufferDone(hComp, m_app_data, &m_out_mem_ptr[bufIndex]);
7847 return OMX_ErrorHardware;
7848 }
7849
7850 return OMX_ErrorNone;
7851 }
7852
7853 /* ======================================================================
7854 FUNCTION
7855 omx_vdec::SetCallbacks
7856
7857 DESCRIPTION
7858 Set the callbacks.
7859
7860 PARAMETERS
7861 None.
7862
7863 RETURN VALUE
7864 OMX Error None if everything successful.
7865
7866 ========================================================================== */
set_callbacks(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_CALLBACKTYPE * callbacks,OMX_IN OMX_PTR appData)7867 OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
7868 OMX_IN OMX_CALLBACKTYPE* callbacks,
7869 OMX_IN OMX_PTR appData)
7870 {
7871 (void) hComp;
7872
7873 if (!callbacks)
7874 return OMX_ErrorBadParameter;
7875
7876 m_cb = *callbacks;
7877 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
7878 m_cb.EventHandler,m_cb.FillBufferDone);
7879 m_app_data = appData;
7880 return OMX_ErrorNone;
7881 }
7882
7883 /* ======================================================================
7884 FUNCTION
7885 omx_vdec::ComponentDeInit
7886
7887 DESCRIPTION
7888 Destroys the component and release memory allocated to the heap.
7889
7890 PARAMETERS
7891 <TBD>.
7892
7893 RETURN VALUE
7894 OMX Error None if everything successful.
7895
7896 ========================================================================== */
component_deinit(OMX_IN OMX_HANDLETYPE hComp)7897 OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
7898 {
7899 (void) hComp;
7900 OMX_ERRORTYPE nRet = OMX_ErrorNone;
7901 OMX_BUFFERHEADERTYPE *buffer;
7902
7903 unsigned i = 0;
7904 if (OMX_StateLoaded != m_state) {
7905 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
7906 m_state);
7907 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
7908 } else {
7909 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
7910 }
7911
7912 /*Check if the output buffers have to be cleaned up*/
7913 buffer = m_out_mem_ptr;
7914 if (buffer) {
7915 DEBUG_PRINT_LOW("Freeing the Output Memory");
7916 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
7917 if (BITMASK_PRESENT(&m_out_bm_count, i)) {
7918 BITMASK_CLEAR(&m_out_bm_count, i);
7919 nRet = free_output_buffer (buffer+i);
7920 if (OMX_ErrorNone != nRet)
7921 break;
7922 }
7923 if (release_output_done()) {
7924 DEBUG_PRINT_HIGH("All output buffers are released");
7925 break;
7926 }
7927 }
7928 #ifdef _ANDROID_ICS_
7929 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
7930 #endif
7931 }
7932
7933 /*Check if the input buffers have to be cleaned up*/
7934 if (m_inp_mem_ptr || m_inp_heap_ptr) {
7935 DEBUG_PRINT_LOW("Freeing the Input Memory");
7936 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
7937
7938 if (BITMASK_PRESENT(&m_inp_bm_count, i)) {
7939 BITMASK_CLEAR(&m_inp_bm_count, i);
7940 if (m_inp_mem_ptr)
7941 free_input_buffer (i,&m_inp_mem_ptr[i]);
7942 else
7943 free_input_buffer (i,NULL);
7944 }
7945
7946 if (release_input_done()) {
7947 DEBUG_PRINT_HIGH("All input buffers released");
7948 break;
7949 }
7950 }
7951 }
7952 free_input_buffer_header();
7953 free_output_buffer_header();
7954 if (h264_scratch.pBuffer) {
7955 free(h264_scratch.pBuffer);
7956 h264_scratch.pBuffer = NULL;
7957 }
7958
7959 if (h264_parser) {
7960 delete h264_parser;
7961 h264_parser = NULL;
7962 }
7963
7964 if (m_frame_parser.mutils) {
7965 DEBUG_PRINT_LOW("Free utils parser");
7966 delete (m_frame_parser.mutils);
7967 m_frame_parser.mutils = NULL;
7968 }
7969
7970 if (m_platform_list) {
7971 free(m_platform_list);
7972 m_platform_list = NULL;
7973 }
7974 if (m_vendor_config.pData) {
7975 free(m_vendor_config.pData);
7976 m_vendor_config.pData = NULL;
7977 }
7978
7979 // Reset counters in mesg queues
7980 m_ftb_q.m_size=0;
7981 m_cmd_q.m_size=0;
7982 m_etb_q.m_size=0;
7983 m_ftb_q.m_read = m_ftb_q.m_write =0;
7984 m_cmd_q.m_read = m_cmd_q.m_write =0;
7985 m_etb_q.m_read = m_etb_q.m_write =0;
7986
7987 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
7988 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
7989 // NULL);
7990 DEBUG_PRINT_HIGH("Close the driver instance");
7991
7992 if (m_debug.infile) {
7993 fclose(m_debug.infile);
7994 m_debug.infile = NULL;
7995 }
7996 if (m_debug.outfile) {
7997 fclose(m_debug.outfile);
7998 m_debug.outfile = NULL;
7999 }
8000 if (m_debug.ccoutfile) {
8001 fclose(m_debug.ccoutfile);
8002 m_debug.ccoutfile = NULL;
8003 }
8004 if (m_debug.out_ymeta_file) {
8005 fclose(m_debug.out_ymeta_file);
8006 m_debug.out_ymeta_file = NULL;
8007 }
8008 if (m_debug.out_uvmeta_file) {
8009 fclose(m_debug.out_uvmeta_file);
8010 m_debug.out_uvmeta_file = NULL;
8011 }
8012 #ifdef OUTPUT_EXTRADATA_LOG
8013 if (outputExtradataFile)
8014 fclose (outputExtradataFile);
8015 #endif
8016 DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete");
8017 return OMX_ErrorNone;
8018 }
8019
8020 /* ======================================================================
8021 FUNCTION
8022 omx_vdec::UseEGLImage
8023
8024 DESCRIPTION
8025 OMX Use EGL Image method implementation <TBD>.
8026
8027 PARAMETERS
8028 <TBD>.
8029
8030 RETURN VALUE
8031 Not Implemented error.
8032
8033 ========================================================================== */
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)8034 OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
8035 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
8036 OMX_IN OMX_U32 port,
8037 OMX_IN OMX_PTR appData,
8038 OMX_IN void* eglImage)
8039 {
8040 (void) appData;
8041 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
8042 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
8043 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
8044
8045 #ifdef USE_EGL_IMAGE_GPU
8046 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
8047 EGLint fd = -1, offset = 0,pmemPtr = 0;
8048 #else
8049 int fd = -1, offset = 0;
8050 #endif
8051 DEBUG_PRINT_HIGH("use EGL image support for decoder");
8052 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
8053 DEBUG_PRINT_ERROR("Invalid EGL image");
8054 }
8055 #ifdef USE_EGL_IMAGE_GPU
8056 if (m_display_id == NULL) {
8057 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
8058 return OMX_ErrorInsufficientResources;
8059 }
8060 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
8061 eglGetProcAddress("eglQueryImageKHR");
8062 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd);
8063 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &offset);
8064 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR, &pmemPtr);
8065 #else //with OMX test app
8066 struct temp_egl {
8067 int pmem_fd;
8068 int offset;
8069 };
8070 struct temp_egl *temp_egl_id = NULL;
8071 void * pmemPtr = (void *) eglImage;
8072 temp_egl_id = (struct temp_egl *)eglImage;
8073 if (temp_egl_id != NULL) {
8074 fd = temp_egl_id->pmem_fd;
8075 offset = temp_egl_id->offset;
8076 }
8077 #endif
8078 if (fd < 0) {
8079 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
8080 return OMX_ErrorInsufficientResources;
8081 }
8082 pmem_info.pmem_fd = (OMX_U32) fd;
8083 pmem_info.offset = (OMX_U32) offset;
8084 pmem_entry.entry = (void *) &pmem_info;
8085 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8086 pmem_list.entryList = &pmem_entry;
8087 pmem_list.nEntries = 1;
8088 ouput_egl_buffers = true;
8089 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
8090 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
8091 (OMX_U8 *)pmemPtr)) {
8092 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
8093 return OMX_ErrorInsufficientResources;
8094 }
8095 return OMX_ErrorNone;
8096 }
8097
8098 /* ======================================================================
8099 FUNCTION
8100 omx_vdec::ComponentRoleEnum
8101
8102 DESCRIPTION
8103 OMX Component Role Enum method implementation.
8104
8105 PARAMETERS
8106 <TBD>.
8107
8108 RETURN VALUE
8109 OMX Error None if everything is successful.
8110 ========================================================================== */
component_role_enum(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_U8 * role,OMX_IN OMX_U32 index)8111 OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
8112 OMX_OUT OMX_U8* role,
8113 OMX_IN OMX_U32 index)
8114 {
8115 (void) hComp;
8116 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8117
8118 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
8119 if ((0 == index) && role) {
8120 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
8121 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8122 } else {
8123 eRet = OMX_ErrorNoMore;
8124 }
8125 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
8126 if ((0 == index) && role) {
8127 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
8128 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8129 } else {
8130 DEBUG_PRINT_LOW("No more roles");
8131 eRet = OMX_ErrorNoMore;
8132 }
8133 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
8134 if ((0 == index) && role) {
8135 strlcpy((char *)role, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
8136 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8137 } else {
8138 DEBUG_PRINT_LOW("No more roles");
8139 eRet = OMX_ErrorNoMore;
8140 }
8141 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
8142 if ((0 == index) && role) {
8143 strlcpy((char *)role, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
8144 DEBUG_PRINT_LOW("component_role_enum: role %s", role);
8145 } else {
8146 DEBUG_PRINT_LOW("No more roles");
8147 eRet = OMX_ErrorNoMore;
8148 }
8149 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
8150 if ((0 == index) && role) {
8151 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
8152 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8153 } else {
8154 DEBUG_PRINT_LOW("No more roles");
8155 eRet = OMX_ErrorNoMore;
8156 }
8157 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
8158 if ((0 == index) && role) {
8159 strlcpy((char *)role, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
8160 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
8161 } else {
8162 DEBUG_PRINT_LOW("No more roles");
8163 eRet = OMX_ErrorNoMore;
8164 }
8165 } else {
8166 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
8167 eRet = OMX_ErrorInvalidComponentName;
8168 }
8169 return eRet;
8170 }
8171
8172
8173
8174
8175 /* ======================================================================
8176 FUNCTION
8177 omx_vdec::AllocateDone
8178
8179 DESCRIPTION
8180 Checks if entire buffer pool is allocated by IL Client or not.
8181 Need this to move to IDLE state.
8182
8183 PARAMETERS
8184 None.
8185
8186 RETURN VALUE
8187 true/false.
8188
8189 ========================================================================== */
allocate_done(void)8190 bool omx_vdec::allocate_done(void)
8191 {
8192 bool bRet = false;
8193 bool bRet_In = false;
8194 bool bRet_Out = false;
8195 bool bRet_Out_Extra = false;
8196
8197 bRet_In = allocate_input_done();
8198 bRet_Out = allocate_output_done();
8199 bRet_Out_Extra = allocate_output_extradata_done();
8200
8201 if (bRet_In && bRet_Out && bRet_Out_Extra) {
8202 DEBUG_PRINT_HIGH("All ports buffers are allocated");
8203 bRet = true;
8204 }
8205
8206 return bRet;
8207 }
8208 /* ======================================================================
8209 FUNCTION
8210 omx_vdec::AllocateInputDone
8211
8212 DESCRIPTION
8213 Checks if I/P buffer pool is allocated by IL Client or not.
8214
8215 PARAMETERS
8216 None.
8217
8218 RETURN VALUE
8219 true/false.
8220
8221 ========================================================================== */
allocate_input_done(void)8222 bool omx_vdec::allocate_input_done(void)
8223 {
8224 bool bRet = false;
8225 unsigned i=0;
8226
8227 if (m_inp_mem_ptr == NULL) {
8228 return bRet;
8229 }
8230 if (m_inp_mem_ptr ) {
8231 for (; i<drv_ctx.ip_buf.actualcount; i++) {
8232 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
8233 break;
8234 }
8235 }
8236 }
8237 if (i == drv_ctx.ip_buf.actualcount) {
8238 bRet = true;
8239 }
8240 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
8241 m_inp_bPopulated = OMX_TRUE;
8242 }
8243 return bRet;
8244 }
8245 /* ======================================================================
8246 FUNCTION
8247 omx_vdec::AllocateOutputDone
8248
8249 DESCRIPTION
8250 Checks if entire O/P buffer pool is allocated by IL Client or not.
8251
8252 PARAMETERS
8253 None.
8254
8255 RETURN VALUE
8256 true/false.
8257
8258 ========================================================================== */
allocate_output_done(void)8259 bool omx_vdec::allocate_output_done(void)
8260 {
8261 bool bRet = false;
8262 unsigned j=0;
8263
8264 if (m_out_mem_ptr == NULL) {
8265 return bRet;
8266 }
8267
8268 if (m_out_mem_ptr) {
8269 for (; j < drv_ctx.op_buf.actualcount; j++) {
8270 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
8271 break;
8272 }
8273 }
8274 }
8275
8276 if (j == drv_ctx.op_buf.actualcount) {
8277 bRet = true;
8278 if (m_out_bEnabled)
8279 m_out_bPopulated = OMX_TRUE;
8280 }
8281
8282 return bRet;
8283 }
8284
allocate_output_extradata_done(void)8285 bool omx_vdec::allocate_output_extradata_done(void) {
8286 bool bRet = false;
8287 unsigned j=0;
8288 unsigned nBufferCount = 0;
8289
8290 nBufferCount = m_client_out_extradata_info.getBufferCount();
8291
8292 if (!m_client_out_extradata_info.is_client_extradata_enabled()) {
8293 return true;
8294 }
8295
8296 if (m_client_output_extradata_mem_ptr) {
8297 for (; j < nBufferCount; j++) {
8298 if (BITMASK_ABSENT(&m_out_extradata_bm_count,j)) {
8299 break;
8300 }
8301 }
8302
8303 if (j == nBufferCount) {
8304 bRet = true;
8305 DEBUG_PRINT_HIGH("Allocate done for all extradata o/p buffers");
8306 }
8307 }
8308
8309 return bRet;
8310 }
8311 /* ======================================================================
8312 FUNCTION
8313 omx_vdec::ReleaseDone
8314
8315 DESCRIPTION
8316 Checks if IL client has released all the buffers.
8317
8318 PARAMETERS
8319 None.
8320
8321 RETURN VALUE
8322 true/false
8323
8324 ========================================================================== */
release_done(void)8325 bool omx_vdec::release_done(void)
8326 {
8327 bool bRet = false;
8328
8329 if (release_input_done()) {
8330 if (release_output_done()) {
8331 if (release_output_extradata_done()) {
8332 DEBUG_PRINT_HIGH("All ports buffers are released");
8333 bRet = true;
8334 }
8335 }
8336 }
8337 return bRet;
8338 }
8339
8340
8341 /* ======================================================================
8342 FUNCTION
8343 omx_vdec::ReleaseOutputDone
8344
8345 DESCRIPTION
8346 Checks if IL client has released all the buffers.
8347
8348 PARAMETERS
8349 None.
8350
8351 RETURN VALUE
8352 true/false
8353
8354 ========================================================================== */
release_output_done(void)8355 bool omx_vdec::release_output_done(void)
8356 {
8357 bool bRet = false;
8358 unsigned i=0,j=0;
8359
8360 if (m_out_mem_ptr) {
8361 for (; j < drv_ctx.op_buf.actualcount ; j++) {
8362 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
8363 break;
8364 }
8365 }
8366 if (j == drv_ctx.op_buf.actualcount) {
8367 m_out_bm_count = 0;
8368 bRet = true;
8369 }
8370 } else {
8371 m_out_bm_count = 0;
8372 bRet = true;
8373 }
8374 return bRet;
8375 }
8376 /* ======================================================================
8377 FUNCTION
8378 omx_vdec::ReleaseInputDone
8379
8380 DESCRIPTION
8381 Checks if IL client has released all the buffers.
8382
8383 PARAMETERS
8384 None.
8385
8386 RETURN VALUE
8387 true/false
8388
8389 ========================================================================== */
release_input_done(void)8390 bool omx_vdec::release_input_done(void)
8391 {
8392 bool bRet = false;
8393 unsigned i=0,j=0;
8394
8395 if (m_inp_mem_ptr) {
8396 for (; j<drv_ctx.ip_buf.actualcount; j++) {
8397 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
8398 break;
8399 }
8400 }
8401 if (j==drv_ctx.ip_buf.actualcount) {
8402 bRet = true;
8403 }
8404 } else {
8405 bRet = true;
8406 }
8407 return bRet;
8408 }
8409
release_output_extradata_done(void)8410 bool omx_vdec::release_output_extradata_done(void) {
8411 bool bRet = false;
8412 unsigned i=0,j=0, buffer_count=0;
8413
8414 buffer_count = m_client_out_extradata_info.getBufferCount();
8415 DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d",
8416 m_client_output_extradata_mem_ptr, buffer_count);
8417
8418 if (m_client_output_extradata_mem_ptr) {
8419 for (; j<buffer_count; j++) {
8420 if ( BITMASK_PRESENT(&m_out_extradata_bm_count,j)) {
8421 break;
8422 }
8423 }
8424 if (j == buffer_count) {
8425 bRet = true;
8426 }
8427 } else {
8428 bRet = true;
8429 }
8430 return bRet;
8431 }
8432
fill_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)8433 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
8434 OMX_BUFFERHEADERTYPE * buffer)
8435 {
8436 VIDC_TRACE_NAME_HIGH("FBD");
8437 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
8438 OMX_BUFFERHEADERTYPE *omx_base_address =
8439 client_buffers.is_color_conversion_enabled()?
8440 m_intermediate_out_mem_ptr:m_out_mem_ptr;
8441 vdec_bufferpayload *omx_ptr_outputbuffer =
8442 client_buffers.is_color_conversion_enabled()?
8443 drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
8444
8445 if (!buffer || (buffer - omx_base_address) >= (int)drv_ctx.op_buf.actualcount) {
8446 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
8447 return OMX_ErrorBadParameter;
8448 } else if (output_flush_progress) {
8449 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
8450 buffer->nFilledLen = 0;
8451 buffer->nTimeStamp = 0;
8452 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
8453 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
8454 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
8455 }
8456
8457 if (m_debug_extradata) {
8458 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
8459 DEBUG_PRINT_HIGH("***************************************************");
8460 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
8461 DEBUG_PRINT_HIGH("***************************************************");
8462 }
8463
8464 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
8465 DEBUG_PRINT_HIGH("***************************************************");
8466 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8467 DEBUG_PRINT_HIGH("***************************************************");
8468 }
8469 }
8470
8471 pending_output_buffers --;
8472 VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
8473
8474 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
8475 DEBUG_PRINT_HIGH("Output EOS has been reached");
8476 if (!output_flush_progress)
8477 post_event((unsigned)NULL, (unsigned)NULL,
8478 OMX_COMPONENT_GENERATE_EOS_DONE);
8479
8480 if (psource_frame) {
8481 print_omx_buffer("EBD in FBD", psource_frame);
8482 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
8483 psource_frame = NULL;
8484 }
8485 if (pdest_frame) {
8486 pdest_frame->nFilledLen = 0;
8487 m_input_free_q.insert_entry((unsigned long) pdest_frame,(unsigned)NULL,
8488 (unsigned)NULL);
8489 pdest_frame = NULL;
8490 }
8491 }
8492
8493 #ifdef OUTPUT_EXTRADATA_LOG
8494 if (outputExtradataFile) {
8495 int buf_index = buffer - omx_base_address;
8496 OMX_U8 *pBuffer = (OMX_U8 *)(omx_ptr_outputbuffer[buf_index].bufferaddr);
8497
8498 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
8499 p_extra = (OMX_OTHER_EXTRADATATYPE *)
8500 ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3));
8501
8502 while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) {
8503 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x",
8504 p_extra->nSize, p_extra->eType);
8505 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
8506
8507 if (p_extra->eType == OMX_ExtraDataNone) {
8508 break;
8509 }
8510 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8511 }
8512 }
8513 #endif
8514
8515 /* For use buffer we need to copy the data */
8516 if (!output_flush_progress) {
8517 /* This is the error check for non-recoverable errros */
8518 bool is_duplicate_ts_valid = true;
8519 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
8520
8521 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
8522 output_capability == V4L2_PIX_FMT_MPEG2)
8523 is_duplicate_ts_valid = false;
8524
8525 if (buffer->nFilledLen > 0) {
8526 time_stamp_dts.get_next_timestamp(buffer,
8527 is_interlaced && is_duplicate_ts_valid && !is_mbaff);
8528 }
8529 }
8530 VIDC_TRACE_INT_LOW("FBD-TS", buffer->nTimeStamp / 1000);
8531
8532 if (m_cb.FillBufferDone) {
8533 if (buffer->nFilledLen > 0) {
8534 if (arbitrary_bytes)
8535 adjust_timestamp(buffer->nTimeStamp);
8536 else
8537 set_frame_rate(buffer->nTimeStamp);
8538
8539 proc_frms++;
8540 if (perf_flag) {
8541 if (1 == proc_frms) {
8542 dec_time.stop();
8543 latency = dec_time.processing_time_us() - latency;
8544 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
8545 dec_time.start();
8546 fps_metrics.start();
8547 }
8548 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
8549 OMX_U64 proc_time = 0;
8550 fps_metrics.stop();
8551 proc_time = fps_metrics.processing_time_us();
8552 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%u) proc_time(%.2f)S fps(%.2f)",
8553 (unsigned int)proc_frms, (float)proc_time / 1e6,
8554 (float)(1e6 * proc_frms) / proc_time);
8555 }
8556 }
8557 }
8558 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
8559 prev_ts = LLONG_MAX;
8560 rst_prev_ts = true;
8561 proc_frms = 0;
8562 }
8563
8564 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8565 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
8566 buffer->pPlatformPrivate)->entryList->entry;
8567 OMX_BUFFERHEADERTYPE *il_buffer;
8568 il_buffer = client_buffers.get_il_buf_hdr(buffer);
8569 OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator);
8570
8571 if (il_buffer && m_last_rendered_TS >= 0) {
8572 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
8573 // Convert fps into ms value. 1 sec = 1000000 ms.
8574 OMX_U64 target_ts_delta = m_dec_hfr_fps ? 1000000 / m_dec_hfr_fps : ts_delta;
8575
8576 // Current frame can be send for rendering if
8577 // (a) current FPS is <= 60
8578 // (b) is the next frame after the frame with TS 0
8579 // (c) is the first frame after seek
8580 // (d) the delta TS b\w two consecutive frames is > 16 ms
8581 // (e) its TS is equal to previous frame TS
8582 // (f) if marked EOS
8583
8584 if(current_framerate <= (OMX_U32)m_dec_hfr_fps || m_last_rendered_TS == 0 ||
8585 il_buffer->nTimeStamp == 0 || ts_delta >= (OMX_TICKS)target_ts_delta||
8586 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
8587 m_last_rendered_TS = il_buffer->nTimeStamp;
8588 } else {
8589 //mark for droping
8590 buffer->nFilledLen = 0;
8591 }
8592
8593 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)",
8594 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
8595 il_buffer->nTimeStamp,ts_delta);
8596
8597 //above code makes sure that delta b\w two consecutive frames is not
8598 //greater than 16ms, slow-mo feature, so cap fps to max 60
8599 if (current_framerate > (OMX_U32)m_dec_hfr_fps ) {
8600 current_framerate = m_dec_hfr_fps;
8601 }
8602 }
8603
8604 // add current framerate to gralloc meta data
8605 if ((buffer->nFilledLen > 0) && m_enable_android_native_buffers && omx_base_address) {
8606 // If valid fps was received, directly send it to display for the 1st fbd.
8607 // Otherwise, calculate fps using fbd timestamps
8608 float refresh_rate = m_fps_prev;
8609 if (m_fps_received) {
8610 if (1 == proc_frms) {
8611 refresh_rate = m_fps_received / (float)(1<<16);
8612 }
8613 } else {
8614 // calculate and set refresh rate for every frame from second frame onwards
8615 // display will assume the default refresh rate for first frame (which is 60 fps)
8616 if (m_fps_prev) {
8617 if (drv_ctx.frame_rate.fps_denominator) {
8618 refresh_rate = drv_ctx.frame_rate.fps_numerator /
8619 (float) drv_ctx.frame_rate.fps_denominator;
8620 }
8621 }
8622 }
8623 OMX_U32 fps_limit = m_dec_hfr_fps ? (OMX_U32)m_dec_hfr_fps : 60;
8624 if (refresh_rate > fps_limit) {
8625 refresh_rate = fps_limit;
8626 }
8627 DEBUG_PRINT_LOW("frc set refresh_rate %f, frame %d", refresh_rate, proc_frms);
8628 OMX_U32 buf_index = buffer - omx_base_address;
8629 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8630 UPDATE_REFRESH_RATE, (void*)&refresh_rate);
8631 m_fps_prev = refresh_rate;
8632 }
8633
8634 if (buffer->nFilledLen && m_enable_android_native_buffers && omx_base_address) {
8635 OMX_U32 buf_index = buffer - omx_base_address;
8636 DEBUG_PRINT_LOW("stereo_output_mode = %d",stereo_output_mode);
8637 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8638 S3D_FORMAT, (void*)&stereo_output_mode);
8639 }
8640
8641 if (il_buffer) {
8642 log_output_buffers(buffer);
8643 log_cc_output_buffers(il_buffer);
8644 if (dynamic_buf_mode) {
8645 unsigned int nPortIndex = 0;
8646 nPortIndex = buffer-omx_base_address;
8647
8648 // Since we're passing around handles, adjust nFilledLen and nAllocLen
8649 // to size of the handle. Do it _after_ log_output_buffers which
8650 // requires the respective sizes to be accurate.
8651
8652 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
8653 buffer->nFilledLen = buffer->nFilledLen ?
8654 sizeof(struct VideoDecoderOutputMetaData) : 0;
8655
8656 //Clear graphic buffer handles in dynamic mode
8657 if (nPortIndex < drv_ctx.op_buf.actualcount &&
8658 nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
8659 native_buffer[nPortIndex].privatehandle = NULL;
8660 native_buffer[nPortIndex].nativehandle = NULL;
8661 } else {
8662 DEBUG_PRINT_ERROR("[FBD]Invalid native_buffer index: %d", nPortIndex);
8663 return OMX_ErrorBadParameter;
8664 }
8665 }
8666 print_omx_buffer("FillBufferDone", buffer);
8667 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
8668 } else {
8669 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
8670 return OMX_ErrorBadParameter;
8671 }
8672 } else {
8673 DEBUG_PRINT_ERROR("NULL m_cb.FillBufferDone");
8674 return OMX_ErrorBadParameter;
8675 }
8676
8677 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
8678 if (m_smoothstreaming_mode && omx_base_address) {
8679 OMX_U32 buf_index = buffer - omx_base_address;
8680 BufferDim_t dim;
8681 private_handle_t *private_handle = NULL;
8682 dim.sliceWidth = framesize.nWidth;
8683 dim.sliceHeight = framesize.nHeight;
8684 if (buf_index < drv_ctx.op_buf.actualcount &&
8685 buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
8686 native_buffer[buf_index].privatehandle)
8687 private_handle = native_buffer[buf_index].privatehandle;
8688 if (private_handle) {
8689 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
8690 dim.sliceWidth, dim.sliceHeight);
8691 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
8692 }
8693 }
8694 #endif
8695
8696 return OMX_ErrorNone;
8697 }
8698
empty_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)8699 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
8700 OMX_BUFFERHEADERTYPE* buffer)
8701 {
8702 VIDC_TRACE_NAME_HIGH("EBD");
8703 int nBufferIndex = buffer - m_inp_mem_ptr;
8704
8705 if (buffer == NULL || (nBufferIndex >= (int)drv_ctx.ip_buf.actualcount)) {
8706 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
8707 return OMX_ErrorBadParameter;
8708 }
8709
8710 pending_input_buffers--;
8711 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
8712
8713 if (arbitrary_bytes) {
8714 if (pdest_frame == NULL && input_flush_progress == false) {
8715 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
8716 pdest_frame = buffer;
8717 buffer->nFilledLen = 0;
8718 buffer->nTimeStamp = LLONG_MAX;
8719 push_input_buffer (hComp);
8720 } else {
8721 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
8722 buffer->nFilledLen = 0;
8723 if (!m_input_free_q.insert_entry((unsigned long)buffer,
8724 (unsigned)NULL, (unsigned)NULL)) {
8725 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
8726 }
8727 }
8728 } else if (m_cb.EmptyBufferDone) {
8729 buffer->nFilledLen = 0;
8730 if (input_use_buffer == true) {
8731 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
8732 }
8733
8734 /* Restore the FD that we over-wrote in ETB */
8735 if (m_input_pass_buffer_fd) {
8736 buffer->pBuffer = (OMX_U8*)(uintptr_t)drv_ctx.ptr_inputbuffer[nBufferIndex].pmem_fd;
8737 }
8738
8739 print_omx_buffer("EmptyBufferDone", buffer);
8740 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
8741 }
8742 return OMX_ErrorNone;
8743 }
8744
async_message_process(void * context,void * message)8745 int omx_vdec::async_message_process (void *context, void* message)
8746 {
8747 omx_vdec* omx = NULL;
8748 struct vdec_msginfo *vdec_msg = NULL;
8749 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
8750 struct v4l2_buffer *v4l2_buf_ptr = NULL;
8751 struct v4l2_plane *plane = NULL;
8752 struct vdec_output_frameinfo *output_respbuf = NULL;
8753 int rc=1;
8754 bool reconfig_event_sent = false;
8755 if (context == NULL || message == NULL) {
8756 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
8757 return -1;
8758 }
8759 vdec_msg = (struct vdec_msginfo *)message;
8760
8761 omx = reinterpret_cast<omx_vdec*>(context);
8762
8763 switch (vdec_msg->msgcode) {
8764
8765 case VDEC_MSG_EVT_HW_ERROR:
8766 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8767 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
8768 break;
8769
8770 case VDEC_MSG_EVT_HW_OVERLOAD:
8771 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8772 OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
8773 break;
8774
8775 case VDEC_MSG_EVT_HW_UNSUPPORTED:
8776 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8777 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
8778 break;
8779
8780 case VDEC_MSG_RESP_START_DONE:
8781 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8782 OMX_COMPONENT_GENERATE_START_DONE);
8783 break;
8784
8785 case VDEC_MSG_RESP_STOP_DONE:
8786 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8787 OMX_COMPONENT_GENERATE_STOP_DONE);
8788 break;
8789
8790 case VDEC_MSG_RESP_RESUME_DONE:
8791 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8792 OMX_COMPONENT_GENERATE_RESUME_DONE);
8793 break;
8794
8795 case VDEC_MSG_RESP_PAUSE_DONE:
8796 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8797 OMX_COMPONENT_GENERATE_PAUSE_DONE);
8798 break;
8799
8800 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
8801 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8802 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
8803 break;
8804 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
8805 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8806 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
8807 break;
8808 case VDEC_MSG_RESP_INPUT_FLUSHED:
8809 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
8810
8811 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
8812 vdec_msg->msgdata.input_frame_clientdata; */
8813
8814 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
8815 if (omx->m_inp_mem_ptr == NULL || v4l2_buf_ptr == NULL ||
8816 v4l2_buf_ptr->index >= omx->drv_ctx.ip_buf.actualcount) {
8817 omxhdr = NULL;
8818 vdec_msg->status_code = VDEC_S_EFATAL;
8819 break;
8820
8821 }
8822 omxhdr = omx->m_inp_mem_ptr + v4l2_buf_ptr->index;
8823
8824 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
8825 DEBUG_PRINT_HIGH("Unsupported input");
8826 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
8827 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
8828 }
8829 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_DATA_CORRUPT) {
8830 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
8831 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
8832 }
8833 if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
8834
8835 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
8836 android_atomic_dec(&omx->m_queued_codec_config_count);
8837 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
8838 BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
8839 DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
8840 sem_post(&omx->m_safe_flush);
8841 }
8842 }
8843 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
8844 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
8845 }
8846 omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code,
8847 OMX_COMPONENT_GENERATE_EBD);
8848 break;
8849 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
8850 int64_t *timestamp;
8851 timestamp = (int64_t *) malloc(sizeof(int64_t));
8852 if (timestamp) {
8853 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
8854 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code,
8855 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
8856 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
8857 (long long)vdec_msg->msgdata.output_frame.time_stamp);
8858 }
8859 break;
8860 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
8861 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: {
8862 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
8863
8864 OMX_BUFFERHEADERTYPE *omx_base_address = omx->m_out_mem_ptr;
8865 vdec_bufferpayload *omx_ptr_outputbuffer = omx->drv_ctx.ptr_outputbuffer;
8866 vdec_output_frameinfo *omx_ptr_respbuffer = omx->drv_ctx.ptr_respbuffer;
8867
8868 if (omx->client_buffers.is_color_conversion_enabled()) {
8869 omx_base_address = omx->m_intermediate_out_mem_ptr;
8870 omx_ptr_outputbuffer = omx->drv_ctx.ptr_intermediate_outputbuffer;
8871 omx_ptr_respbuffer = omx->drv_ctx.ptr_intermediate_respbuffer;
8872 }
8873
8874 if (v4l2_buf_ptr == NULL || omx_base_address == NULL ||
8875 v4l2_buf_ptr->index >= omx->drv_ctx.op_buf.actualcount) {
8876 omxhdr = NULL;
8877 vdec_msg->status_code = VDEC_S_EFATAL;
8878 break;
8879 }
8880 plane = v4l2_buf_ptr->m.planes;
8881 omxhdr = omx_base_address + v4l2_buf_ptr->index;
8882
8883 if (omxhdr && omxhdr->pOutputPortPrivate &&
8884 ((omxhdr - omx_base_address) < (int)omx->drv_ctx.op_buf.actualcount) &&
8885 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
8886 - omx_ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
8887
8888 omxhdr->pMarkData = (OMX_PTR)(unsigned long)plane[0].reserved[3];
8889 omxhdr->hMarkTargetComponent = (OMX_HANDLETYPE)(unsigned long)plane[0].reserved[4];
8890
8891 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
8892 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
8893 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
8894 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
8895 omxhdr->nFlags = 0;
8896
8897 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
8898 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
8899 //rc = -1;
8900 }
8901 if (omxhdr->nFilledLen) {
8902 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
8903 }
8904 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
8905 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
8906 } else {
8907 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
8908 }
8909 #if NEED_TO_REVISIT
8910 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
8911 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
8912 }
8913 #endif
8914 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
8915 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
8916 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
8917 omx_ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
8918 }
8919
8920 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_DATA_CORRUPT) {
8921 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
8922 }
8923
8924 output_respbuf = (struct vdec_output_frameinfo *)\
8925 omxhdr->pOutputPortPrivate;
8926 if (!output_respbuf) {
8927 DEBUG_PRINT_ERROR("async_message_process: invalid output buf received");
8928 return -1;
8929 }
8930 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
8931 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
8932
8933 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
8934 output_respbuf->pic_type = PICTURE_TYPE_I;
8935 }
8936 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
8937 output_respbuf->pic_type = PICTURE_TYPE_P;
8938 }
8939 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
8940 output_respbuf->pic_type = PICTURE_TYPE_B;
8941 }
8942
8943 if (vdec_msg->msgdata.output_frame.len) {
8944 DEBUG_PRINT_LOW("Processing extradata");
8945 reconfig_event_sent = omx->handle_extradata(omxhdr);
8946
8947 if (omx->m_extradata_info.output_crop_updated) {
8948 DEBUG_PRINT_LOW("Read FBD crop from output extra data");
8949 vdec_msg->msgdata.output_frame.framesize.left = omx->m_extradata_info.output_crop_rect.nLeft;
8950 vdec_msg->msgdata.output_frame.framesize.top = omx->m_extradata_info.output_crop_rect.nTop;
8951 vdec_msg->msgdata.output_frame.framesize.right = omx->m_extradata_info.output_crop_rect.nWidth;
8952 vdec_msg->msgdata.output_frame.framesize.bottom = omx->m_extradata_info.output_crop_rect.nHeight;
8953 vdec_msg->msgdata.output_frame.picsize.frame_width = omx->m_extradata_info.output_width;
8954 vdec_msg->msgdata.output_frame.picsize.frame_height = omx->m_extradata_info.output_height;
8955 memcpy(vdec_msg->msgdata.output_frame.misrinfo,
8956 omx->m_extradata_info.misr_info, sizeof(vdec_misrinfo));
8957 } else {
8958 DEBUG_PRINT_LOW("Read FBD crop from v4l2 reserved fields");
8959 vdec_msg->msgdata.output_frame.framesize.left = plane[0].reserved[2];
8960 vdec_msg->msgdata.output_frame.framesize.top = plane[0].reserved[3];
8961 vdec_msg->msgdata.output_frame.framesize.right = plane[0].reserved[2] + plane[0].reserved[4];
8962 vdec_msg->msgdata.output_frame.framesize.bottom = plane[0].reserved[3] + plane[0].reserved[5];
8963 vdec_msg->msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
8964 vdec_msg->msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
8965
8966 /* Copy these values back to OMX internal variables to make both handlign same*/
8967
8968 omx->m_extradata_info.output_crop_rect.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
8969 omx->m_extradata_info.output_crop_rect.nTop = vdec_msg->msgdata.output_frame.framesize.top;
8970 omx->m_extradata_info.output_crop_rect.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
8971 omx->m_extradata_info.output_crop_rect.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
8972 omx->m_extradata_info.output_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
8973 omx->m_extradata_info.output_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
8974 }
8975 }
8976
8977 vdec_msg->msgdata.output_frame.bufferaddr =
8978 omx_ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
8979
8980 DEBUG_PRINT_LOW("[RespBufDone] Fd(%d) Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x)"
8981 " FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)",
8982 omx_ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
8983 omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp,
8984 vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
8985 (unsigned int)vdec_msg->msgdata.output_frame.len,
8986 vdec_msg->msgdata.output_frame.framesize.left,
8987 vdec_msg->msgdata.output_frame.framesize.top,
8988 vdec_msg->msgdata.output_frame.framesize.right,
8989 vdec_msg->msgdata.output_frame.framesize.bottom);
8990
8991 /* Post event if resolution OR crop changed */
8992 /* filled length will be changed if resolution changed */
8993 /* Crop parameters can be changed even without resolution change */
8994 if (omxhdr->nFilledLen
8995 && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
8996 || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
8997 || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
8998 || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
8999 || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
9000 || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
9001 || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
9002
9003 DEBUG_PRINT_HIGH("Parameters Changed From: Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u --> Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u",
9004 omx->prev_n_filled_len,
9005 omx->drv_ctx.video_resolution.frame_width,
9006 omx->drv_ctx.video_resolution.frame_height,
9007 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
9008 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
9009 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
9010 vdec_msg->msgdata.output_frame.picsize.frame_height,
9011 vdec_msg->msgdata.output_frame.framesize.left,
9012 vdec_msg->msgdata.output_frame.framesize.top,
9013 vdec_msg->msgdata.output_frame.framesize.right,
9014 vdec_msg->msgdata.output_frame.framesize.bottom);
9015
9016 memcpy(&omx->drv_ctx.frame_size,
9017 &vdec_msg->msgdata.output_frame.framesize,
9018 sizeof(struct vdec_framesize));
9019
9020 omx->drv_ctx.video_resolution.frame_width =
9021 vdec_msg->msgdata.output_frame.picsize.frame_width;
9022 omx->drv_ctx.video_resolution.frame_height =
9023 vdec_msg->msgdata.output_frame.picsize.frame_height;
9024 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
9025 omx->drv_ctx.video_resolution.stride =
9026 VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
9027 omx->drv_ctx.video_resolution.scan_lines =
9028 VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
9029 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
9030 omx->drv_ctx.video_resolution.stride =
9031 VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_width);
9032 omx->drv_ctx.video_resolution.scan_lines =
9033 VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_height);
9034 } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
9035 omx->drv_ctx.video_resolution.stride =
9036 VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_width);
9037 omx->drv_ctx.video_resolution.scan_lines =
9038 VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_height);
9039 }
9040 else if(omx->drv_ctx.output_format == VDEC_YUV_FORMAT_P010_VENUS) {
9041 omx->drv_ctx.video_resolution.stride =
9042 VENUS_Y_STRIDE(COLOR_FMT_P010, omx->drv_ctx.video_resolution.frame_width);
9043 omx->drv_ctx.video_resolution.scan_lines =
9044 VENUS_Y_SCANLINES(COLOR_FMT_P010, omx->drv_ctx.video_resolution.frame_height);
9045 }
9046
9047 if(!reconfig_event_sent) {
9048 omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
9049 OMX_IndexConfigCommonOutputCrop,
9050 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
9051 reconfig_event_sent = true;
9052 } else {
9053 /* Update C2D with new resolution */
9054 if (!omx->client_buffers.update_buffer_req()) {
9055 DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
9056 }
9057 }
9058 }
9059
9060 if (omxhdr->nFilledLen)
9061 omx->prev_n_filled_len = omxhdr->nFilledLen;
9062
9063 if (!omx->m_enable_android_native_buffers && omx->output_use_buffer && omxhdr->pBuffer &&
9064 vdec_msg->msgdata.output_frame.bufferaddr)
9065 memcpy ( omxhdr->pBuffer, (void *)
9066 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
9067 (unsigned long)vdec_msg->msgdata.output_frame.offset),
9068 vdec_msg->msgdata.output_frame.len);
9069 } else {
9070 DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
9071 (unsigned int)vdec_msg->msgdata.output_frame.len,
9072 omxhdr->nAllocLen, omx->prev_n_filled_len);
9073 omxhdr->nFilledLen = 0;
9074 }
9075
9076 omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code,
9077 OMX_COMPONENT_GENERATE_FBD);
9078
9079 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
9080 omx->post_event ((unsigned long)NULL, vdec_msg->status_code,
9081 OMX_COMPONENT_GENERATE_EOS_DONE);
9082 } else {
9083 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
9084 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
9085 }
9086 break;
9087 }
9088 case VDEC_MSG_EVT_CONFIG_CHANGED:
9089 DEBUG_PRINT_HIGH("Port settings changed");
9090 omx->m_reconfig_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
9091 omx->m_reconfig_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
9092 omx->isPortReconfigInsufficient = vdec_msg->msgdata.output_frame.flags;
9093 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
9094 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
9095 break;
9096 default:
9097 break;
9098 }
9099 return rc;
9100 }
9101
empty_this_buffer_proxy_arbitrary(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)9102 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
9103 OMX_HANDLETYPE hComp,
9104 OMX_BUFFERHEADERTYPE *buffer
9105 )
9106 {
9107 unsigned address,p2,id;
9108 DEBUG_PRINT_LOW("Empty this arbitrary");
9109
9110 if (buffer == NULL) {
9111 return OMX_ErrorBadParameter;
9112 }
9113 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
9114 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %u, timestamp %lld",
9115 (unsigned int)buffer->nFilledLen, (unsigned int)buffer->nFlags, buffer->nTimeStamp);
9116
9117 /* return zero length and not an EOS buffer */
9118 /* return buffer if input flush in progress */
9119 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
9120 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
9121 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
9122 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
9123 return OMX_ErrorNone;
9124 }
9125
9126 if (psource_frame == NULL) {
9127 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
9128 psource_frame = buffer;
9129 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
9130 push_input_buffer (hComp);
9131 } else {
9132 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
9133 if (!m_input_pending_q.insert_entry((unsigned long)buffer, (unsigned)NULL,
9134 (unsigned)NULL)) {
9135 return OMX_ErrorBadParameter;
9136 }
9137 }
9138
9139 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
9140 codec_config_flag = false;
9141 }
9142 return OMX_ErrorNone;
9143 }
9144
push_input_buffer(OMX_HANDLETYPE hComp)9145 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
9146 {
9147 unsigned long address,p2,id;
9148 OMX_ERRORTYPE ret = OMX_ErrorNone;
9149
9150 if (pdest_frame == NULL || psource_frame == NULL) {
9151 /*Check if we have a destination buffer*/
9152 if (pdest_frame == NULL) {
9153 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
9154 if (m_input_free_q.m_size) {
9155 m_input_free_q.pop_entry(&address,&p2,&id);
9156 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
9157 pdest_frame->nFilledLen = 0;
9158 pdest_frame->nTimeStamp = LLONG_MAX;
9159 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
9160 }
9161 }
9162
9163 /*Check if we have a destination buffer*/
9164 if (psource_frame == NULL) {
9165 DEBUG_PRINT_LOW("Get a source buffer from the queue");
9166 if (m_input_pending_q.m_size) {
9167 m_input_pending_q.pop_entry(&address,&p2,&id);
9168 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
9169 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
9170 psource_frame->nTimeStamp);
9171 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
9172 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
9173
9174 }
9175 }
9176
9177 }
9178
9179 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
9180 switch (codec_type_parse) {
9181 case CODEC_TYPE_MPEG2:
9182 ret = push_input_sc_codec(hComp);
9183 break;
9184 case CODEC_TYPE_H264:
9185 ret = push_input_h264(hComp);
9186 break;
9187 case CODEC_TYPE_HEVC:
9188 ret = push_input_hevc(hComp);
9189 break;
9190 default:
9191 break;
9192 }
9193 if (ret != OMX_ErrorNone) {
9194 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
9195 omx_report_error ();
9196 break;
9197 }
9198 }
9199
9200 return ret;
9201 }
9202
push_input_sc_codec(OMX_HANDLETYPE hComp)9203 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
9204 {
9205 OMX_U32 partial_frame = 1;
9206 OMX_BOOL generate_ebd = OMX_TRUE;
9207 unsigned long address = 0, p2 = 0, id = 0;
9208
9209 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
9210 psource_frame,psource_frame->nTimeStamp);
9211 if (m_frame_parser.parse_sc_frame(psource_frame,
9212 pdest_frame,&partial_frame) == -1) {
9213 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
9214 return OMX_ErrorBadParameter;
9215 }
9216
9217 if (partial_frame == 0) {
9218 DEBUG_PRINT_LOW("Frame size %u source %p frame count %d",
9219 (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count);
9220
9221
9222 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
9223 /*First Parsed buffer will have only header Hence skip*/
9224 if (frame_count == 0) {
9225 frame_count++;
9226 } else {
9227 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
9228 if (pdest_frame->nFilledLen) {
9229 /*Push the frame to the Decoder*/
9230 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9231 return OMX_ErrorBadParameter;
9232 }
9233 frame_count++;
9234 pdest_frame = NULL;
9235
9236 if (m_input_free_q.m_size) {
9237 m_input_free_q.pop_entry(&address,&p2,&id);
9238 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
9239 pdest_frame->nFilledLen = 0;
9240 }
9241 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
9242 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
9243 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL,
9244 (unsigned)NULL);
9245 pdest_frame = NULL;
9246 }
9247 }
9248 } else {
9249 DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen);
9250 /*Check if Destination Buffer is full*/
9251 if (pdest_frame->nAllocLen ==
9252 pdest_frame->nFilledLen + pdest_frame->nOffset) {
9253 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
9254 return OMX_ErrorStreamCorrupt;
9255 }
9256 }
9257
9258 if (psource_frame->nFilledLen == 0) {
9259 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
9260 if (pdest_frame) {
9261 pdest_frame->nFlags |= psource_frame->nFlags;
9262 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
9263 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld",
9264 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
9265 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
9266 (unsigned int)pdest_frame->nFilledLen,frame_count++);
9267 /*Push the frame to the Decoder*/
9268 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9269 return OMX_ErrorBadParameter;
9270 }
9271 frame_count++;
9272 pdest_frame = NULL;
9273 } else {
9274 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
9275 generate_ebd = OMX_FALSE;
9276 }
9277 }
9278 if (generate_ebd) {
9279 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
9280 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
9281 psource_frame = NULL;
9282
9283 if (m_input_pending_q.m_size) {
9284 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
9285 m_input_pending_q.pop_entry(&address,&p2,&id);
9286 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
9287 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
9288 psource_frame->nTimeStamp);
9289 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
9290 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
9291 }
9292 }
9293 }
9294 return OMX_ErrorNone;
9295 }
9296
push_input_h264(OMX_HANDLETYPE hComp)9297 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
9298 {
9299 OMX_U32 partial_frame = 1;
9300 unsigned long address = 0, p2 = 0, id = 0;
9301 OMX_BOOL isNewFrame = OMX_FALSE;
9302 OMX_BOOL generate_ebd = OMX_TRUE;
9303
9304 if (h264_scratch.pBuffer == NULL) {
9305 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
9306 return OMX_ErrorBadParameter;
9307 }
9308 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u "
9309 "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal);
9310 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)pdest_frame->nFilledLen);
9311 if (h264_scratch.nFilledLen && look_ahead_nal) {
9312 look_ahead_nal = false;
9313 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9314 h264_scratch.nFilledLen) {
9315 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9316 h264_scratch.pBuffer,h264_scratch.nFilledLen);
9317 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9318 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
9319 h264_scratch.nFilledLen = 0;
9320 } else {
9321 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
9322 return OMX_ErrorBadParameter;
9323 }
9324 }
9325
9326 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
9327 in EOS flag getting associated with the destination
9328 */
9329 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
9330 pdest_frame->nFilledLen) {
9331 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
9332 generate_ebd = OMX_FALSE;
9333 }
9334
9335 if (nal_length == 0) {
9336 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
9337 if (m_frame_parser.parse_sc_frame(psource_frame,
9338 &h264_scratch,&partial_frame) == -1) {
9339 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
9340 return OMX_ErrorBadParameter;
9341 }
9342 } else {
9343 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
9344 if (m_frame_parser.parse_h264_nallength(psource_frame,
9345 &h264_scratch,&partial_frame) == -1) {
9346 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
9347 return OMX_ErrorBadParameter;
9348 }
9349 }
9350
9351 if (partial_frame == 0) {
9352 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
9353 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
9354 nal_count++;
9355 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
9356 h264_scratch.nFlags = psource_frame->nFlags;
9357 } else {
9358 DEBUG_PRINT_LOW("Parsed New NAL Length = %u",(unsigned int)h264_scratch.nFilledLen);
9359 if (h264_scratch.nFilledLen) {
9360 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
9361 NALU_TYPE_SPS);
9362 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
9363 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
9364 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
9365 h264_scratch.nFilledLen, NALU_TYPE_SEI);
9366 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
9367 // If timeinfo is present frame info from SEI is already processed
9368 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
9369 h264_scratch.nFilledLen, NALU_TYPE_SEI);
9370 #endif
9371 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
9372 nal_count++;
9373 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
9374 pdest_frame->nTimeStamp = h264_last_au_ts;
9375 pdest_frame->nFlags = h264_last_au_flags;
9376 #ifdef PANSCAN_HDLR
9377 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
9378 h264_parser->update_panscan_data(h264_last_au_ts);
9379 #endif
9380 }
9381 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
9382 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
9383 h264_last_au_ts = h264_scratch.nTimeStamp;
9384 h264_last_au_flags = h264_scratch.nFlags;
9385 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
9386 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
9387 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
9388 if (!VALID_TS(h264_last_au_ts))
9389 h264_last_au_ts = ts_in_sei;
9390 }
9391 #endif
9392 } else
9393 h264_last_au_ts = LLONG_MAX;
9394 }
9395
9396 if (!isNewFrame) {
9397 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9398 h264_scratch.nFilledLen) {
9399 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %u",
9400 (unsigned int)h264_scratch.nFilledLen);
9401 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9402 h264_scratch.pBuffer,h264_scratch.nFilledLen);
9403 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9404 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
9405 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
9406 h264_scratch.nFilledLen = 0;
9407 } else {
9408 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
9409 return OMX_ErrorBadParameter;
9410 }
9411 } else if(h264_scratch.nFilledLen) {
9412 look_ahead_nal = true;
9413 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu",
9414 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
9415 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
9416 (unsigned int)pdest_frame->nFilledLen,frame_count++);
9417
9418 if (pdest_frame->nFilledLen == 0) {
9419 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
9420 look_ahead_nal = false;
9421 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9422 h264_scratch.nFilledLen) {
9423 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9424 h264_scratch.pBuffer,h264_scratch.nFilledLen);
9425 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9426 h264_scratch.nFilledLen = 0;
9427 } else {
9428 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
9429 return OMX_ErrorBadParameter;
9430 }
9431 } else {
9432 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
9433 DEBUG_PRINT_LOW("Reset the EOS Flag");
9434 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
9435 }
9436 /*Push the frame to the Decoder*/
9437 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9438 return OMX_ErrorBadParameter;
9439 }
9440 //frame_count++;
9441 pdest_frame = NULL;
9442 if (m_input_free_q.m_size) {
9443 m_input_free_q.pop_entry(&address,&p2,&id);
9444 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
9445 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
9446 pdest_frame->nFilledLen = 0;
9447 pdest_frame->nFlags = 0;
9448 pdest_frame->nTimeStamp = LLONG_MAX;
9449 }
9450 }
9451 }
9452 }
9453 } else {
9454 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %u", (unsigned int)pdest_frame->nFilledLen);
9455 /*Check if Destination Buffer is full*/
9456 if (h264_scratch.nAllocLen ==
9457 h264_scratch.nFilledLen + h264_scratch.nOffset) {
9458 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
9459 return OMX_ErrorStreamCorrupt;
9460 }
9461 }
9462
9463 if (!psource_frame->nFilledLen) {
9464 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
9465
9466 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
9467 if (pdest_frame) {
9468 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
9469 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
9470 h264_scratch.nFilledLen) {
9471 if(pdest_frame->nFilledLen == 0) {
9472 /* No residual frame from before, send whatever
9473 * we have left */
9474 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9475 h264_scratch.pBuffer, h264_scratch.nFilledLen);
9476 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9477 h264_scratch.nFilledLen = 0;
9478 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
9479 } else {
9480 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
9481 if(!isNewFrame) {
9482 /* Have a residual frame, but we know that the
9483 * AU in this frame is belonging to whatever
9484 * frame we had left over. So append it */
9485 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
9486 h264_scratch.pBuffer,h264_scratch.nFilledLen);
9487 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
9488 h264_scratch.nFilledLen = 0;
9489 if (h264_last_au_ts != LLONG_MAX)
9490 pdest_frame->nTimeStamp = h264_last_au_ts;
9491 } else {
9492 /* Completely new frame, let's just push what
9493 * we have now. The resulting EBD would trigger
9494 * another push */
9495 generate_ebd = OMX_FALSE;
9496 pdest_frame->nTimeStamp = h264_last_au_ts;
9497 h264_last_au_ts = h264_scratch.nTimeStamp;
9498 }
9499 }
9500 } else {
9501 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
9502 return OMX_ErrorBadParameter;
9503 }
9504
9505 /* Iff we coalesced two buffers, inherit the flags of both bufs */
9506 if(generate_ebd == OMX_TRUE) {
9507 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
9508 }
9509
9510 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu",
9511 (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
9512 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
9513 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
9514 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
9515 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
9516 if (!VALID_TS(pdest_frame->nTimeStamp))
9517 pdest_frame->nTimeStamp = ts_in_sei;
9518 }
9519 #endif
9520 /*Push the frame to the Decoder*/
9521 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
9522 return OMX_ErrorBadParameter;
9523 }
9524 frame_count++;
9525 pdest_frame = NULL;
9526 } else {
9527 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
9528 pdest_frame, (unsigned int)h264_scratch.nFilledLen);
9529 generate_ebd = OMX_FALSE;
9530 }
9531 }
9532 }
9533 if (generate_ebd && !psource_frame->nFilledLen) {
9534 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
9535 psource_frame = NULL;
9536 if (m_input_pending_q.m_size) {
9537 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
9538 m_input_pending_q.pop_entry(&address,&p2,&id);
9539 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
9540 DEBUG_PRINT_LOW("Next source Buffer flag %u src length %u",
9541 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
9542 }
9543 }
9544 return OMX_ErrorNone;
9545 }
9546
copy_buffer(OMX_BUFFERHEADERTYPE * pDst,OMX_BUFFERHEADERTYPE * pSrc)9547 OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc)
9548 {
9549 OMX_ERRORTYPE rc = OMX_ErrorNone;
9550 if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) {
9551 memcpy((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen);
9552 if (pDst->nTimeStamp == LLONG_MAX) {
9553 pDst->nTimeStamp = pSrc->nTimeStamp;
9554 DEBUG_PRINT_LOW("Assign Dst nTimeStamp = %lld", pDst->nTimeStamp);
9555 }
9556 pDst->nFilledLen += pSrc->nFilledLen;
9557 pSrc->nFilledLen = 0;
9558 } else {
9559 DEBUG_PRINT_ERROR("Error: Destination buffer overflow");
9560 rc = OMX_ErrorBadParameter;
9561 }
9562 return rc;
9563 }
9564
push_input_hevc(OMX_HANDLETYPE hComp)9565 OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp)
9566 {
9567 OMX_U32 partial_frame = 1;
9568 unsigned long address,p2,id;
9569 OMX_BOOL isNewFrame = OMX_FALSE;
9570 OMX_BOOL generate_ebd = OMX_TRUE;
9571 OMX_ERRORTYPE rc = OMX_ErrorNone;
9572 if (h264_scratch.pBuffer == NULL) {
9573 DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated");
9574 return OMX_ErrorBadParameter;
9575 }
9576
9577 DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \
9578 pdest_frame nFilledLen %u nTimeStamp %lld",
9579 (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
9580
9581 if (h264_scratch.nFilledLen && look_ahead_nal) {
9582 look_ahead_nal = false;
9583 rc = copy_buffer(pdest_frame, &h264_scratch);
9584 if (rc != OMX_ErrorNone) {
9585 return rc;
9586 }
9587 }
9588
9589 if (nal_length == 0) {
9590 if (m_frame_parser.parse_sc_frame(psource_frame,
9591 &h264_scratch,&partial_frame) == -1) {
9592 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
9593 return OMX_ErrorBadParameter;
9594 }
9595 } else {
9596 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length);
9597 if (m_frame_parser.parse_h264_nallength(psource_frame,
9598 &h264_scratch,&partial_frame) == -1) {
9599 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
9600 return OMX_ErrorBadParameter;
9601 }
9602 }
9603
9604 if (partial_frame == 0) {
9605 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
9606 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
9607 nal_count++;
9608 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
9609 h264_scratch.nFlags = psource_frame->nFlags;
9610 } else {
9611 DEBUG_PRINT_LOW("Parsed New NAL Length = %u", (unsigned int)h264_scratch.nFilledLen);
9612 if (h264_scratch.nFilledLen) {
9613 m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame);
9614 nal_count++;
9615 }
9616
9617 if (!isNewFrame) {
9618 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \
9619 nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld",
9620 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp,
9621 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
9622 rc = copy_buffer(pdest_frame, &h264_scratch);
9623 if (rc != OMX_ErrorNone) {
9624 return rc;
9625 }
9626 } else {
9627 look_ahead_nal = true;
9628 if (pdest_frame->nFilledLen == 0) {
9629 look_ahead_nal = false;
9630 DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer");
9631 rc = copy_buffer(pdest_frame, &h264_scratch);
9632 if (rc != OMX_ErrorNone) {
9633 return OMX_ErrorBadParameter;
9634 }
9635 } else {
9636 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
9637 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
9638 }
9639 DEBUG_PRINT_LOW("FrameDetected # %d pdest_frame nFilledLen %u \
9640 nTimeStamp %lld, look_ahead_nal in h264_scratch \
9641 nFilledLen %u nTimeStamp %lld",
9642 frame_count++, (unsigned int)pdest_frame->nFilledLen,
9643 pdest_frame->nTimeStamp, (unsigned int)h264_scratch.nFilledLen,
9644 h264_scratch.nTimeStamp);
9645 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
9646 return OMX_ErrorBadParameter;
9647 }
9648 pdest_frame = NULL;
9649 if (m_input_free_q.m_size) {
9650 m_input_free_q.pop_entry(&address, &p2, &id);
9651 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
9652 DEBUG_PRINT_LOW("pop the next pdest_buffer %p", pdest_frame);
9653 pdest_frame->nFilledLen = 0;
9654 pdest_frame->nFlags = 0;
9655 pdest_frame->nTimeStamp = LLONG_MAX;
9656 }
9657 }
9658 }
9659 }
9660 } else {
9661 DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \
9662 pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \
9663 nFilledLen %u nTimeStamp %lld",
9664 (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp,
9665 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp,
9666 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp);
9667
9668 if (h264_scratch.nAllocLen ==
9669 h264_scratch.nFilledLen + h264_scratch.nOffset) {
9670 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
9671 return OMX_ErrorStreamCorrupt;
9672 }
9673 }
9674
9675 if (!psource_frame->nFilledLen) {
9676 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client", psource_frame);
9677 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
9678 if (pdest_frame) {
9679 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
9680 rc = copy_buffer(pdest_frame, &h264_scratch);
9681 if ( rc != OMX_ErrorNone ) {
9682 return rc;
9683 }
9684 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
9685 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
9686 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%u TimeStamp = %lld",
9687 frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
9688 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
9689 return OMX_ErrorBadParameter;
9690 }
9691 frame_count++;
9692 pdest_frame = NULL;
9693 } else {
9694 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
9695 pdest_frame, (unsigned int)h264_scratch.nFilledLen);
9696 generate_ebd = OMX_FALSE;
9697 }
9698 }
9699 }
9700
9701 if (generate_ebd && !psource_frame->nFilledLen) {
9702 m_cb.EmptyBufferDone (hComp, m_app_data, psource_frame);
9703 psource_frame = NULL;
9704 if (m_input_pending_q.m_size) {
9705 m_input_pending_q.pop_entry(&address, &p2, &id);
9706 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
9707 DEBUG_PRINT_LOW("Next source Buffer flag %u nFilledLen %u, nTimeStamp %lld",
9708 (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp);
9709 }
9710 }
9711 return OMX_ErrorNone;
9712 }
9713
9714 #ifdef USE_GBM
alloc_map_gbm_memory(OMX_U32 w,OMX_U32 h,int dev_fd,struct vdec_gbm * op_buf_gbm_info,int flag)9715 bool omx_vdec::alloc_map_gbm_memory(OMX_U32 w,OMX_U32 h,int dev_fd,
9716 struct vdec_gbm *op_buf_gbm_info, int flag)
9717 {
9718
9719 uint32 flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
9720 struct gbm_device *gbm = NULL;
9721 struct gbm_bo *bo = NULL;
9722 int bo_fd = -1, meta_fd = -1;
9723 if (!op_buf_gbm_info || dev_fd < 0 ) {
9724 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
9725 return FALSE;
9726 }
9727
9728 gbm = gbm_create_device(dev_fd);
9729 if (gbm == NULL) {
9730 DEBUG_PRINT_ERROR("create gbm device failed");
9731 return FALSE;
9732 } else {
9733 DEBUG_PRINT_LOW( "Successfully created gbm device");
9734 }
9735 if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC)
9736 flags |= GBM_BO_USAGE_UBWC_ALIGNED_QTI;
9737
9738 DEBUG_PRINT_LOW("create NV12 gbm_bo with width=%d, height=%d", w, h);
9739 bo = gbm_bo_create(gbm, w, h,GBM_FORMAT_NV12,
9740 flags);
9741
9742 if (bo == NULL) {
9743 DEBUG_PRINT_ERROR("Create bo failed");
9744 gbm_device_destroy(gbm);
9745 return FALSE;
9746 }
9747
9748 bo_fd = gbm_bo_get_fd(bo);
9749 if (bo_fd < 0) {
9750 DEBUG_PRINT_ERROR("Get bo fd failed");
9751 gbm_bo_destroy(bo);
9752 gbm_device_destroy(gbm);
9753 return FALSE;
9754 }
9755
9756 gbm_perform(GBM_PERFORM_GET_METADATA_ION_FD, bo, &meta_fd);
9757 if (meta_fd < 0) {
9758 DEBUG_PRINT_ERROR("Get bo meta fd failed");
9759 gbm_bo_destroy(bo);
9760 gbm_device_destroy(gbm);
9761 return FALSE;
9762 }
9763 op_buf_gbm_info->gbm = gbm;
9764 op_buf_gbm_info->bo = bo;
9765 op_buf_gbm_info->bo_fd = bo_fd;
9766 op_buf_gbm_info->meta_fd = meta_fd;
9767
9768 DEBUG_PRINT_LOW("allocate gbm bo fd meta fd %p %d %d",bo,bo_fd,meta_fd);
9769 return TRUE;
9770 }
9771
free_gbm_memory(struct vdec_gbm * buf_gbm_info)9772 void omx_vdec::free_gbm_memory(struct vdec_gbm *buf_gbm_info)
9773 {
9774 if(!buf_gbm_info) {
9775 DEBUG_PRINT_ERROR(" GBM: free called with invalid fd/allocdata");
9776 return;
9777 }
9778 DEBUG_PRINT_LOW("free gbm bo fd meta fd %p %d %d",
9779 buf_gbm_info->bo,buf_gbm_info->bo_fd,buf_gbm_info->meta_fd);
9780
9781 if (buf_gbm_info->bo)
9782 gbm_bo_destroy(buf_gbm_info->bo);
9783 buf_gbm_info->bo = NULL;
9784
9785 if (buf_gbm_info->gbm)
9786 gbm_device_destroy(buf_gbm_info->gbm);
9787 buf_gbm_info->gbm = NULL;
9788
9789 buf_gbm_info->bo_fd = -1;
9790 buf_gbm_info->meta_fd = -1;
9791 }
9792 #endif
9793 #ifndef USE_ION
align_pmem_buffers(int pmem_fd,OMX_U32 buffer_size,OMX_U32 alignment)9794 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
9795 OMX_U32 alignment)
9796 {
9797 struct pmem_allocation allocation;
9798 allocation.size = buffer_size;
9799 allocation.align = clip2(alignment);
9800 if (allocation.align < 4096) {
9801 allocation.align = 4096;
9802 }
9803 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
9804 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
9805 allocation.align, allocation.size);
9806 return false;
9807 }
9808 return true;
9809 }
9810 #endif
9811 #ifdef USE_ION
alloc_map_ion_memory(OMX_U32 buffer_size,vdec_ion * ion_info,int flag)9812 bool omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, vdec_ion *ion_info, int flag)
9813
9814 {
9815 int rc = -EINVAL;
9816 int ion_dev_flag;
9817 struct vdec_ion ion_buf_info;
9818
9819 if (!ion_info || buffer_size <= 0) {
9820 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
9821 return false;
9822 }
9823
9824 ion_info->dev_fd = ion_open();
9825 if (ion_info->dev_fd < 0) {
9826 DEBUG_PRINT_ERROR("opening ion device failed with ion_fd = %d", ion_info->dev_fd);
9827 return false;
9828 }
9829
9830 ion_info->alloc_data.flags = flag;
9831 ion_info->alloc_data.len = buffer_size;
9832
9833 ion_info->alloc_data.heap_id_mask = ION_HEAP(ION_SYSTEM_HEAP_ID);
9834 if (secure_mode && (ion_info->alloc_data.flags & ION_FLAG_SECURE)) {
9835 ion_info->alloc_data.heap_id_mask = ION_HEAP(MEM_HEAP_ID);
9836 }
9837
9838 /* Use secure display cma heap for obvious reasons. */
9839 if (ion_info->alloc_data.flags & ION_FLAG_CP_BITSTREAM) {
9840 ion_info->alloc_data.heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
9841 }
9842
9843 rc = ion_alloc_fd(ion_info->dev_fd, ion_info->alloc_data.len, 0,
9844 ion_info->alloc_data.heap_id_mask, ion_info->alloc_data.flags,
9845 &ion_info->data_fd);
9846
9847 if (rc || ion_info->data_fd < 0) {
9848 DEBUG_PRINT_ERROR("ION ALLOC memory failed");
9849 ion_close(ion_info->dev_fd);
9850 ion_info->data_fd = -1;
9851 ion_info->dev_fd = -1;
9852 return false;
9853 }
9854
9855 DEBUG_PRINT_HIGH("Alloc ion memory: fd (dev:%d data:%d) len %d flags %#x mask %#x",
9856 ion_info->dev_fd, ion_info->data_fd, (unsigned int)ion_info->alloc_data.len,
9857 (unsigned int)ion_info->alloc_data.flags,
9858 (unsigned int)ion_info->alloc_data.heap_id_mask);
9859
9860 return true;
9861 }
9862
free_ion_memory(struct vdec_ion * buf_ion_info)9863 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
9864 {
9865
9866 if (!buf_ion_info) {
9867 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
9868 return;
9869 }
9870 DEBUG_PRINT_HIGH("Free ion memory: mmap fd %d ion_dev fd %d len %d flags %#x mask %#x",
9871 buf_ion_info->data_fd, buf_ion_info->dev_fd,
9872 (unsigned int)buf_ion_info->alloc_data.len,
9873 (unsigned int)buf_ion_info->alloc_data.flags,
9874 (unsigned int)buf_ion_info->alloc_data.heap_id_mask);
9875
9876 if (buf_ion_info->data_fd >= 0) {
9877 close(buf_ion_info->data_fd);
9878 buf_ion_info->data_fd = -1;
9879 }
9880 if (buf_ion_info->dev_fd >= 0) {
9881 ion_close(buf_ion_info->dev_fd);
9882 buf_ion_info->dev_fd = -1;
9883 }
9884 }
9885
do_cache_operations(int fd)9886 void omx_vdec::do_cache_operations(int fd)
9887 {
9888 if (fd < 0)
9889 return;
9890
9891 struct dma_buf_sync dma_buf_sync_data[2];
9892 dma_buf_sync_data[0].flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
9893 dma_buf_sync_data[1].flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
9894
9895 for(unsigned int i=0; i<2; i++) {
9896 int rc = ioctl(fd, DMA_BUF_IOCTL_SYNC, &dma_buf_sync_data[i]);
9897 if (rc < 0) {
9898 DEBUG_PRINT_ERROR("Failed DMA_BUF_IOCTL_SYNC %s fd : %d", i==0?"start":"end", fd);
9899 return;
9900 }
9901 }
9902 }
9903
9904 #endif
free_output_buffer_header(bool intermediate)9905 void omx_vdec::free_output_buffer_header(bool intermediate)
9906 {
9907 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
9908 output_use_buffer = false;
9909 ouput_egl_buffers = false;
9910
9911 OMX_BUFFERHEADERTYPE **omx_base_address =
9912 intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
9913 vdec_bufferpayload **omx_ptr_outputbuffer =
9914 intermediate?&drv_ctx.ptr_intermediate_outputbuffer:&drv_ctx.ptr_outputbuffer;
9915 vdec_output_frameinfo **omx_ptr_respbuffer =
9916 intermediate?&drv_ctx.ptr_intermediate_respbuffer:&drv_ctx.ptr_respbuffer;
9917 vdec_ion **omx_op_buf_ion_info =
9918 intermediate?&drv_ctx.op_intermediate_buf_ion_info:&drv_ctx.op_buf_ion_info;
9919 #ifdef USE_GBM
9920 vdec_gbm **omx_op_buf_gbm_info =
9921 intermediate?&drv_ctx.op_intermediate_buf_gbm_info:&drv_ctx.op_buf_gbm_info;
9922 #endif
9923
9924 if (*omx_base_address) {
9925 free (*omx_base_address);
9926 *omx_base_address = NULL;
9927 }
9928
9929 if (m_platform_list) {
9930 free(m_platform_list);
9931 m_platform_list = NULL;
9932 }
9933
9934 if (*omx_ptr_respbuffer) {
9935 free (*omx_ptr_respbuffer);
9936 *omx_ptr_respbuffer = NULL;
9937 }
9938 if (*omx_ptr_outputbuffer) {
9939 free (*omx_ptr_outputbuffer);
9940 *omx_ptr_outputbuffer = NULL;
9941 }
9942 #ifdef USE_GBM
9943 if (*omx_op_buf_gbm_info) {
9944 DEBUG_PRINT_LOW("Free o/p gbm context");
9945 free(*omx_op_buf_gbm_info);
9946 *omx_op_buf_gbm_info = NULL;
9947 }
9948 if (drv_ctx.gbm_device_fd >= 0) {
9949 DEBUG_PRINT_LOW("Close gbm device");
9950 close(drv_ctx.gbm_device_fd);
9951 drv_ctx.gbm_device_fd = -1;
9952 }
9953
9954 #elif defined USE_ION
9955 if (*omx_op_buf_ion_info) {
9956 DEBUG_PRINT_LOW("Free o/p ion context");
9957 free(*omx_op_buf_ion_info);
9958 *omx_op_buf_ion_info = NULL;
9959 }
9960 #endif
9961 if (intermediate == false && client_buffers.is_color_conversion_enabled()) {
9962 free_output_buffer_header(true);
9963 }
9964 }
9965
free_input_buffer_header()9966 void omx_vdec::free_input_buffer_header()
9967 {
9968 input_use_buffer = false;
9969 if (arbitrary_bytes) {
9970 if (m_inp_heap_ptr) {
9971 DEBUG_PRINT_LOW("Free input Heap Pointer");
9972 free (m_inp_heap_ptr);
9973 m_inp_heap_ptr = NULL;
9974 }
9975
9976 if (m_phdr_pmem_ptr) {
9977 DEBUG_PRINT_LOW("Free input pmem header Pointer");
9978 free (m_phdr_pmem_ptr);
9979 m_phdr_pmem_ptr = NULL;
9980 }
9981 }
9982 if (m_inp_mem_ptr) {
9983 DEBUG_PRINT_LOW("Free input pmem Pointer area");
9984 free (m_inp_mem_ptr);
9985 m_inp_mem_ptr = NULL;
9986 }
9987 /* We just freed all the buffer headers, every thing in m_input_free_q,
9988 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
9989 while (m_input_free_q.m_size) {
9990 unsigned long address, p2, id;
9991 m_input_free_q.pop_entry(&address, &p2, &id);
9992 }
9993 while (m_input_pending_q.m_size) {
9994 unsigned long address, p2, id;
9995 m_input_pending_q.pop_entry(&address, &p2, &id);
9996 }
9997 pdest_frame = NULL;
9998 psource_frame = NULL;
9999 if (drv_ctx.ptr_inputbuffer) {
10000 DEBUG_PRINT_LOW("Free Driver Context pointer");
10001 free (drv_ctx.ptr_inputbuffer);
10002 drv_ctx.ptr_inputbuffer = NULL;
10003 }
10004 #ifdef USE_ION
10005 if (drv_ctx.ip_buf_ion_info) {
10006 DEBUG_PRINT_LOW("Free ion context");
10007 free(drv_ctx.ip_buf_ion_info);
10008 drv_ctx.ip_buf_ion_info = NULL;
10009 }
10010 #endif
10011 }
10012
free_output_extradata_buffer_header()10013 void omx_vdec::free_output_extradata_buffer_header() {
10014 client_extradata = false;
10015 if (m_client_output_extradata_mem_ptr) {
10016 DEBUG_PRINT_LOW("Free extradata pmem Pointer area");
10017 free(m_client_output_extradata_mem_ptr);
10018 m_client_output_extradata_mem_ptr = NULL;
10019 }
10020 }
10021
stream_off(OMX_U32 port)10022 int omx_vdec::stream_off(OMX_U32 port)
10023 {
10024 enum v4l2_buf_type btype;
10025 int rc = 0;
10026 enum v4l2_ports v4l2_port = OUTPUT_PORT;
10027 struct v4l2_requestbuffers bufreq;
10028
10029 if (port == OMX_CORE_INPUT_PORT_INDEX) {
10030 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10031 v4l2_port = OUTPUT_PORT;
10032 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
10033 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10034 v4l2_port = CAPTURE_PORT;
10035 } else if (port == OMX_ALL) {
10036 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
10037 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
10038
10039 if (!rc_input)
10040 return rc_input;
10041 else
10042 return rc_output;
10043 }
10044
10045 if (!streaming[v4l2_port]) {
10046 // already streamed off, warn and move on
10047 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
10048 " which is already streamed off", v4l2_port);
10049 return 0;
10050 }
10051
10052 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
10053
10054 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
10055 if (rc) {
10056 /*TODO: How to handle this case */
10057 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
10058 } else {
10059 streaming[v4l2_port] = false;
10060 }
10061
10062 if (port == OMX_CORE_INPUT_PORT_INDEX) {
10063 bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10064 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
10065 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10066 }
10067
10068 bufreq.memory = V4L2_MEMORY_USERPTR;
10069 bufreq.count = 0;
10070 rc = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
10071 if (rc) {
10072 DEBUG_PRINT_ERROR("Failed to release buffers on %d Port", v4l2_port);
10073 }
10074 return rc;
10075 }
10076
get_buffer_req(vdec_allocatorproperty * buffer_prop)10077 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
10078 {
10079 OMX_ERRORTYPE eRet = OMX_ErrorNone;
10080 struct v4l2_control control;
10081 unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
10082 unsigned int final_extra_data_size = 0;
10083 struct v4l2_format fmt;
10084 int ret = 0;
10085 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
10086 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10087
10088 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
10089 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10090 fmt.fmt.pix_mp.pixelformat = output_capability;
10091 control.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT;
10092 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
10093 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10094 fmt.fmt.pix_mp.pixelformat = capture_capability;
10095 control.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
10096 } else {
10097 eRet = OMX_ErrorBadParameter;
10098 }
10099 if (eRet == OMX_ErrorNone) {
10100 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control);
10101 }
10102 if (ret) {
10103 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
10104 /*TODO: How to handle this case */
10105 eRet = OMX_ErrorInsufficientResources;
10106 return eRet;
10107 }
10108 buffer_prop->actualcount = buffer_prop->mincount = control.value;
10109 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
10110 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10111
10112 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10113
10114 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
10115 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
10116 DEBUG_PRINT_HIGH("Buffer Size = %d, type = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage, fmt.type);
10117
10118 if (ret) {
10119 /*TODO: How to handle this case */
10120 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
10121 eRet = OMX_ErrorInsufficientResources;
10122 } else {
10123 int extra_idx = 0;
10124
10125 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
10126 buf_size = buffer_prop->buffer_size;
10127 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
10128 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
10129 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
10130 } else if (extra_idx >= VIDEO_MAX_PLANES) {
10131 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
10132 return OMX_ErrorBadParameter;
10133 }
10134
10135 default_extra_data_size = VENUS_EXTRADATA_SIZE(
10136 drv_ctx.video_resolution.frame_height,
10137 drv_ctx.video_resolution.frame_width);
10138 final_extra_data_size = extra_data_size > default_extra_data_size ?
10139 extra_data_size : default_extra_data_size;
10140
10141 final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
10142 (~(buffer_prop->alignment - 1));
10143
10144 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
10145 drv_ctx.extradata_info.count = buffer_prop->actualcount;
10146 drv_ctx.extradata_info.buffer_size = final_extra_data_size;
10147 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
10148 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)",
10149 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size);
10150 if (extra_data_size)
10151 DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)",
10152 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
10153
10154 if (in_reconfig) // BufReq will be set to driver when port is disabled
10155 buffer_prop->buffer_size = buf_size;
10156 else if (buf_size != buffer_prop->buffer_size) {
10157 buffer_prop->buffer_size = buf_size;
10158 eRet = set_buffer_req(buffer_prop);
10159 }
10160 }
10161 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)",
10162 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10163 return eRet;
10164 }
10165
set_buffer_req(vdec_allocatorproperty * buffer_prop)10166 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
10167 {
10168 OMX_ERRORTYPE eRet = OMX_ErrorNone;
10169 unsigned buf_size = 0;
10170 struct v4l2_format fmt, c_fmt;
10171 struct v4l2_requestbuffers bufreq;
10172 int ret = 0;
10173 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)",
10174 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
10175 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
10176 if (buf_size != buffer_prop->buffer_size) {
10177 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)",
10178 (unsigned int)buffer_prop->buffer_size, buf_size);
10179 eRet = OMX_ErrorBadParameter;
10180 } else {
10181 memset(&fmt, 0x0, sizeof(struct v4l2_format));
10182 memset(&c_fmt, 0x0, sizeof(struct v4l2_format));
10183 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
10184 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
10185 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
10186
10187 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
10188 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10189 fmt.fmt.pix_mp.pixelformat = output_capability;
10190 DEBUG_PRINT_LOW("S_FMT: type %d wxh %dx%d size %d format %x",
10191 fmt.type, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
10192 fmt.fmt.pix_mp.plane_fmt[0].sizeimage, fmt.fmt.pix_mp.pixelformat);
10193 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
10194 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
10195 c_fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10196 c_fmt.fmt.pix_mp.pixelformat = capture_capability;
10197 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &c_fmt);
10198 c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
10199 DEBUG_PRINT_LOW("S_FMT: type %d wxh %dx%d size %d format %x",
10200 c_fmt.type, c_fmt.fmt.pix_mp.width, c_fmt.fmt.pix_mp.height,
10201 c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage, c_fmt.fmt.pix_mp.pixelformat);
10202 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &c_fmt);
10203 } else {
10204 eRet = OMX_ErrorBadParameter;
10205 }
10206 if (ret) {
10207 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
10208 eRet = OMX_ErrorInsufficientResources;
10209 }
10210
10211 bufreq.memory = V4L2_MEMORY_USERPTR;
10212 bufreq.count = buffer_prop->actualcount;
10213 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
10214 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10215 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
10216 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10217 } else {
10218 eRet = OMX_ErrorBadParameter;
10219 }
10220
10221 if (eRet == OMX_ErrorNone) {
10222 DEBUG_PRINT_LOW("REQBUFS: type %d count %d", bufreq.type, bufreq.count);
10223 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
10224 }
10225
10226 if (ret) {
10227 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
10228 /*TODO: How to handle this case */
10229 eRet = OMX_ErrorInsufficientResources;
10230 } else if (bufreq.count < buffer_prop->actualcount) {
10231 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
10232 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
10233 buffer_prop->actualcount, bufreq.count);
10234 eRet = OMX_ErrorInsufficientResources;
10235 } else {
10236 if (!client_buffers.update_buffer_req()) {
10237 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
10238 eRet = OMX_ErrorInsufficientResources;
10239 }
10240 }
10241 }
10242 return eRet;
10243 }
10244
update_picture_resolution()10245 OMX_ERRORTYPE omx_vdec::update_picture_resolution()
10246 {
10247 OMX_ERRORTYPE eRet = OMX_ErrorNone;
10248 return eRet;
10249 }
10250
update_portdef(OMX_PARAM_PORTDEFINITIONTYPE * portDefn)10251 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
10252 {
10253 OMX_ERRORTYPE eRet = OMX_ErrorNone;
10254 struct v4l2_format fmt;
10255 if (!portDefn) {
10256 DEBUG_PRINT_ERROR("update_portdef: invalid params");
10257 return OMX_ErrorBadParameter;
10258 }
10259 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
10260 portDefn->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
10261 portDefn->eDomain = OMX_PortDomainVideo;
10262 memset(&fmt, 0x0, sizeof(struct v4l2_format));
10263 if (0 == portDefn->nPortIndex) {
10264 if (secure_mode) {
10265 eRet = get_buffer_req(&drv_ctx.ip_buf);
10266 if (eRet) {
10267 DEBUG_PRINT_ERROR("%s:get_buffer_req(ip_buf) failed", __func__);
10268 return eRet;
10269 }
10270 }
10271 portDefn->eDir = OMX_DirInput;
10272 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
10273 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
10274 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
10275 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
10276 portDefn->format.video.eCompressionFormat = eCompressionFormat;
10277 //for input port, always report the fps value set by client,
10278 //to distinguish whether client got valid fps from parser.
10279 portDefn->format.video.xFramerate = m_fps_received;
10280 portDefn->bEnabled = m_inp_bEnabled;
10281 portDefn->bPopulated = m_inp_bPopulated;
10282
10283 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10284 fmt.fmt.pix_mp.pixelformat = output_capability;
10285 ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10286 } else if (1 == portDefn->nPortIndex) {
10287 unsigned int buf_size = 0;
10288 int ret = 0;
10289 if (!is_down_scalar_enabled) {
10290 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10291 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10292 fmt.fmt.pix_mp.pixelformat = capture_capability;
10293 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10294 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
10295 }
10296
10297 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10298 fmt.fmt.pix_mp.pixelformat = capture_capability;
10299 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
10300 if (ret) {
10301 DEBUG_PRINT_ERROR("Get Resolution failed");
10302 return OMX_ErrorHardware;
10303 }
10304 drv_ctx.op_buf.buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
10305 if (!client_buffers.update_buffer_req()) {
10306 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
10307 return OMX_ErrorHardware;
10308 }
10309
10310 if (!client_buffers.get_buffer_req(buf_size)) {
10311 DEBUG_PRINT_ERROR("update buffer requirements");
10312 return OMX_ErrorHardware;
10313 }
10314 portDefn->nBufferSize = buf_size;
10315 portDefn->eDir = OMX_DirOutput;
10316 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
10317 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
10318 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
10319 if (drv_ctx.frame_rate.fps_denominator > 0)
10320 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
10321 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
10322 else {
10323 DEBUG_PRINT_ERROR("Error: Divide by zero");
10324 return OMX_ErrorBadParameter;
10325 }
10326 portDefn->bEnabled = m_out_bEnabled;
10327 portDefn->bPopulated = m_out_bPopulated;
10328 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
10329 DEBUG_PRINT_ERROR("Error in getting color format");
10330 return OMX_ErrorHardware;
10331 }
10332 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
10333 fmt.fmt.pix_mp.pixelformat = capture_capability;
10334 } else if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) {
10335 portDefn->nBufferSize = m_client_out_extradata_info.getSize();
10336 portDefn->nBufferCountMin = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
10337 portDefn->nBufferCountActual = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
10338 portDefn->eDir = OMX_DirOutput;
10339 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
10340 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
10341 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
10342 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
10343 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
10344 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
10345 DEBUG_PRINT_LOW(" get_parameter: Port idx %d nBufSize %u nBufCnt %u",
10346 (int)portDefn->nPortIndex,
10347 (unsigned int)portDefn->nBufferSize,
10348 (unsigned int)portDefn->nBufferCountActual);
10349 return eRet;
10350 } else {
10351 portDefn->eDir = OMX_DirMax;
10352 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
10353 (int)portDefn->nPortIndex);
10354 eRet = OMX_ErrorBadPortIndex;
10355 }
10356 if (in_reconfig) {
10357 m_extradata_info.output_crop_rect.nLeft = 0;
10358 m_extradata_info.output_crop_rect.nTop = 0;
10359 m_extradata_info.output_crop_rect.nWidth = fmt.fmt.pix_mp.width;
10360 m_extradata_info.output_crop_rect.nHeight = fmt.fmt.pix_mp.height;
10361 }
10362 update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
10363 fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
10364
10365 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
10366 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
10367 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
10368 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
10369
10370 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
10371 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
10372 portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16);
10373 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
10374 }
10375 DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d "
10376 "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u",
10377 (unsigned int)portDefn->nPortIndex,
10378 (unsigned int)portDefn->format.video.nFrameWidth,
10379 (unsigned int)portDefn->format.video.nFrameHeight,
10380 (int)portDefn->format.video.nStride,
10381 (unsigned int)portDefn->format.video.nSliceHeight,
10382 (unsigned int)portDefn->format.video.eColorFormat,
10383 (unsigned int)portDefn->nBufferSize,
10384 (unsigned int)portDefn->nBufferCountActual);
10385
10386 return eRet;
10387 }
10388
allocate_output_headers(bool intermediate)10389 OMX_ERRORTYPE omx_vdec::allocate_output_headers(bool intermediate)
10390 {
10391 OMX_ERRORTYPE eRet = OMX_ErrorNone;
10392 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
10393 unsigned i = 0;
10394
10395 OMX_BUFFERHEADERTYPE **omx_base_address =
10396 intermediate?&m_intermediate_out_mem_ptr:&m_out_mem_ptr;
10397 vdec_bufferpayload **omx_ptr_outputbuffer =
10398 intermediate?&drv_ctx.ptr_intermediate_outputbuffer:&drv_ctx.ptr_outputbuffer;
10399 vdec_output_frameinfo **omx_ptr_respbuffer =
10400 intermediate?&drv_ctx.ptr_intermediate_respbuffer:&drv_ctx.ptr_respbuffer;
10401 vdec_ion **omx_op_buf_ion_info =
10402 intermediate?&drv_ctx.op_intermediate_buf_ion_info:&drv_ctx.op_buf_ion_info;
10403
10404 if (!*omx_base_address) {
10405 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation, Cnt %d Sz %d",
10406 drv_ctx.op_buf.actualcount, (unsigned int)drv_ctx.op_buf.buffer_size);
10407 int nBufHdrSize = 0;
10408 int nPlatformEntrySize = 0;
10409 int nPlatformListSize = 0;
10410 int nPMEMInfoSize = 0;
10411 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
10412 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
10413 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
10414
10415 nBufHdrSize = drv_ctx.op_buf.actualcount *
10416 sizeof(OMX_BUFFERHEADERTYPE);
10417 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
10418 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
10419 nPlatformListSize = drv_ctx.op_buf.actualcount *
10420 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
10421 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
10422 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
10423
10424 *omx_base_address = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
10425 // Alloc mem for platform specific info
10426 char *pPtr=NULL;
10427 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
10428 nPMEMInfoSize,1);
10429 *omx_ptr_outputbuffer = (struct vdec_bufferpayload *) \
10430 calloc (sizeof(struct vdec_bufferpayload),
10431 drv_ctx.op_buf.actualcount);
10432 *omx_ptr_respbuffer = (struct vdec_output_frameinfo *) \
10433 calloc (sizeof (struct vdec_output_frameinfo),
10434 drv_ctx.op_buf.actualcount);
10435 if (!pPtr || !*omx_ptr_outputbuffer || !*omx_ptr_respbuffer) {
10436 DEBUG_PRINT_ERROR("allocate_output_headers: allocation failed");
10437 free(pPtr); pPtr = NULL;
10438 free(*omx_ptr_outputbuffer); *omx_ptr_outputbuffer = NULL;
10439 free(*omx_ptr_respbuffer); *omx_ptr_respbuffer = NULL;
10440 return OMX_ErrorInsufficientResources;
10441 }
10442
10443 #ifdef USE_ION
10444 *omx_op_buf_ion_info = (struct vdec_ion * ) \
10445 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
10446 if (!*omx_op_buf_ion_info) {
10447 DEBUG_PRINT_ERROR("Failed to alloc output buffer ion info");
10448 free(pPtr); pPtr = NULL;
10449 free(*omx_ptr_outputbuffer); *omx_ptr_outputbuffer = NULL;
10450 free(*omx_ptr_respbuffer); *omx_ptr_respbuffer = NULL;
10451 return OMX_ErrorInsufficientResources;
10452 }
10453 #endif
10454
10455 if (*omx_base_address && pPtr && *omx_ptr_outputbuffer
10456 && *omx_ptr_respbuffer) {
10457 bufHdr = *omx_base_address;
10458 if (m_platform_list) {
10459 free(m_platform_list);
10460 }
10461 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
10462 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
10463 (((char *) m_platform_list) + nPlatformListSize);
10464 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
10465 (((char *) m_platform_entry) + nPlatformEntrySize);
10466 pPlatformList = m_platform_list;
10467 pPlatformEntry = m_platform_entry;
10468 pPMEMInfo = m_pmem_info;
10469
10470 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p", *omx_base_address);
10471
10472 // Settting the entire storage nicely
10473 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
10474 *omx_base_address,pPlatformEntry);
10475 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
10476 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
10477 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
10478 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
10479 // Set the values when we determine the right HxW param
10480 bufHdr->nAllocLen = 0;
10481 bufHdr->nFilledLen = 0;
10482 bufHdr->pAppPrivate = NULL;
10483 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
10484 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
10485 pPlatformEntry->entry = pPMEMInfo;
10486 // Initialize the Platform List
10487 pPlatformList->nEntries = 1;
10488 pPlatformList->entryList = pPlatformEntry;
10489 // Keep pBuffer NULL till vdec is opened
10490 bufHdr->pBuffer = NULL;
10491 pPMEMInfo->offset = 0;
10492 pPMEMInfo->pmem_fd = -1;
10493 bufHdr->pPlatformPrivate = pPlatformList;
10494 (*omx_ptr_outputbuffer)[i].pmem_fd = -1;
10495 #ifdef USE_ION
10496 (*omx_op_buf_ion_info)[i].data_fd = -1;
10497 (*omx_op_buf_ion_info)[i].dev_fd = -1;
10498 #endif
10499 /*Create a mapping between buffers*/
10500 bufHdr->pOutputPortPrivate = &(*omx_ptr_respbuffer)[i];
10501 (*omx_ptr_respbuffer)[i].client_data = (void *) \
10502 &(*omx_ptr_outputbuffer)[i];
10503 // Move the buffer and buffer header pointers
10504 bufHdr++;
10505 pPMEMInfo++;
10506 pPlatformEntry++;
10507 pPlatformList++;
10508 }
10509 } else {
10510 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
10511 *omx_base_address, pPtr);
10512 if (*omx_base_address) {
10513 free(*omx_base_address);
10514 *omx_base_address = NULL;
10515 }
10516 if (pPtr) {
10517 free(pPtr);
10518 pPtr = NULL;
10519 }
10520 if (*omx_ptr_outputbuffer) {
10521 free(*omx_ptr_outputbuffer);
10522 *omx_ptr_outputbuffer = NULL;
10523 }
10524 if (*omx_ptr_respbuffer) {
10525 free(*omx_ptr_respbuffer);
10526 *omx_ptr_respbuffer = NULL;
10527 }
10528 #ifdef USE_ION
10529 if (*omx_op_buf_ion_info) {
10530 DEBUG_PRINT_LOW("Free o/p ion context");
10531 free(*omx_op_buf_ion_info);
10532 *omx_op_buf_ion_info = NULL;
10533 }
10534 #endif
10535 eRet = OMX_ErrorInsufficientResources;
10536 }
10537 } else {
10538 eRet = OMX_ErrorInsufficientResources;
10539 }
10540
10541 if (intermediate == false &&
10542 eRet == OMX_ErrorNone &&
10543 client_buffers.is_color_conversion_enabled()) {
10544 eRet = allocate_output_headers(true);
10545 }
10546
10547 return eRet;
10548 }
10549
complete_pending_buffer_done_cbs()10550 void omx_vdec::complete_pending_buffer_done_cbs()
10551 {
10552 unsigned long p1, p2, ident;
10553 omx_cmd_queue tmp_q, pending_bd_q;
10554 pthread_mutex_lock(&m_lock);
10555 // pop all pending GENERATE FDB from ftb queue
10556 while (m_ftb_q.m_size) {
10557 m_ftb_q.pop_entry(&p1,&p2,&ident);
10558 if (ident == OMX_COMPONENT_GENERATE_FBD) {
10559 pending_bd_q.insert_entry(p1,p2,ident);
10560 } else {
10561 tmp_q.insert_entry(p1,p2,ident);
10562 }
10563 }
10564 //return all non GENERATE FDB to ftb queue
10565 while (tmp_q.m_size) {
10566 tmp_q.pop_entry(&p1,&p2,&ident);
10567 m_ftb_q.insert_entry(p1,p2,ident);
10568 }
10569 // pop all pending GENERATE EDB from etb queue
10570 while (m_etb_q.m_size) {
10571 m_etb_q.pop_entry(&p1,&p2,&ident);
10572 if (ident == OMX_COMPONENT_GENERATE_EBD) {
10573 pending_bd_q.insert_entry(p1,p2,ident);
10574 } else {
10575 tmp_q.insert_entry(p1,p2,ident);
10576 }
10577 }
10578 //return all non GENERATE FDB to etb queue
10579 while (tmp_q.m_size) {
10580 tmp_q.pop_entry(&p1,&p2,&ident);
10581 m_etb_q.insert_entry(p1,p2,ident);
10582 }
10583 pthread_mutex_unlock(&m_lock);
10584 // process all pending buffer dones
10585 while (pending_bd_q.m_size) {
10586 pending_bd_q.pop_entry(&p1,&p2,&ident);
10587 switch (ident) {
10588 case OMX_COMPONENT_GENERATE_EBD:
10589 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
10590 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
10591 omx_report_error ();
10592 }
10593 break;
10594
10595 case OMX_COMPONENT_GENERATE_FBD:
10596 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
10597 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
10598 omx_report_error ();
10599 }
10600 break;
10601 }
10602 }
10603 }
10604
set_frame_rate(OMX_S64 act_timestamp)10605 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
10606 {
10607 OMX_U32 new_frame_interval = 0;
10608 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
10609 && llabs(act_timestamp - prev_ts) > 2000) {
10610 new_frame_interval = client_set_fps ? frm_int : (act_timestamp - prev_ts) > 0 ?
10611 llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual);
10612 if (new_frame_interval != frm_int || frm_int == 0) {
10613 frm_int = new_frame_interval;
10614 if (frm_int) {
10615 drv_ctx.frame_rate.fps_numerator = 1e6;
10616 drv_ctx.frame_rate.fps_denominator = frm_int;
10617 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
10618 (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
10619 (float)drv_ctx.frame_rate.fps_denominator);
10620 /* We need to report the difference between this FBD and the previous FBD
10621 * back to the driver for clock scaling purposes. */
10622 struct v4l2_outputparm oparm;
10623 /*XXX: we're providing timing info as seconds per frame rather than frames
10624 * per second.*/
10625 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
10626 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
10627
10628 struct v4l2_streamparm sparm;
10629 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
10630 sparm.parm.output = oparm;
10631 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
10632 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
10633 performance might be affected");
10634 }
10635
10636 }
10637 }
10638 }
10639 prev_ts = act_timestamp;
10640 }
10641
adjust_timestamp(OMX_S64 & act_timestamp)10642 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
10643 {
10644 if (rst_prev_ts && VALID_TS(act_timestamp)) {
10645 prev_ts = act_timestamp;
10646 prev_ts_actual = act_timestamp;
10647 rst_prev_ts = false;
10648 } else if (VALID_TS(prev_ts)) {
10649 bool codec_cond = (drv_ctx.timestamp_adjust)?
10650 (!VALID_TS(act_timestamp) || act_timestamp < prev_ts_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) :
10651 (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual);
10652 prev_ts_actual = act_timestamp; //unadjusted previous timestamp
10653 if (frm_int > 0 && codec_cond) {
10654 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
10655 act_timestamp = prev_ts + frm_int;
10656 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
10657 prev_ts = act_timestamp;
10658 } else {
10659 if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
10660 // ensure that timestamps can never step backwards when in display order
10661 act_timestamp = prev_ts;
10662 }
10663 set_frame_rate(act_timestamp);
10664 }
10665 } else if (frm_int > 0) // In this case the frame rate was set along
10666 { // with the port definition, start ts with 0
10667 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
10668 rst_prev_ts = true;
10669 }
10670 }
10671
convert_color_space_info(OMX_U32 primaries,OMX_U32 range,OMX_U32 transfer,OMX_U32 matrix,ColorAspects * aspects)10672 void omx_vdec::convert_color_space_info(OMX_U32 primaries, OMX_U32 range,
10673 OMX_U32 transfer, OMX_U32 matrix, ColorAspects *aspects)
10674 {
10675 switch (primaries) {
10676 case MSM_VIDC_BT709_5:
10677 aspects->mPrimaries = ColorAspects::PrimariesBT709_5;
10678 break;
10679 case MSM_VIDC_BT470_6_M:
10680 aspects->mPrimaries = ColorAspects::PrimariesBT470_6M;
10681 break;
10682 case MSM_VIDC_BT601_6_625:
10683 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
10684 break;
10685 case MSM_VIDC_BT601_6_525:
10686 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
10687 break;
10688 case MSM_VIDC_GENERIC_FILM:
10689 aspects->mPrimaries = ColorAspects::PrimariesGenericFilm;
10690 break;
10691 case MSM_VIDC_BT2020:
10692 aspects->mPrimaries = ColorAspects::PrimariesBT2020;
10693 break;
10694 case MSM_VIDC_UNSPECIFIED:
10695 //Client does not expect ColorAspects::PrimariesUnspecified, but rather the supplied default
10696 default:
10697 //aspects->mPrimaries = ColorAspects::PrimariesOther;
10698 aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
10699 break;
10700 }
10701
10702 aspects->mRange = range ? ColorAspects::RangeFull : ColorAspects::RangeLimited;
10703
10704 switch (transfer) {
10705 case MSM_VIDC_TRANSFER_BT709_5:
10706 case MSM_VIDC_TRANSFER_601_6_525: // case MSM_VIDC_TRANSFER_601_6_625:
10707 aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10708 break;
10709 case MSM_VIDC_TRANSFER_BT_470_6_M:
10710 aspects->mTransfer = ColorAspects::TransferGamma22;
10711 break;
10712 case MSM_VIDC_TRANSFER_BT_470_6_BG:
10713 aspects->mTransfer = ColorAspects::TransferGamma28;
10714 break;
10715 case MSM_VIDC_TRANSFER_SMPTE_240M:
10716 aspects->mTransfer = ColorAspects::TransferSMPTE240M;
10717 break;
10718 case MSM_VIDC_TRANSFER_LINEAR:
10719 aspects->mTransfer = ColorAspects::TransferLinear;
10720 break;
10721 case MSM_VIDC_TRANSFER_IEC_61966:
10722 aspects->mTransfer = ColorAspects::TransferXvYCC;
10723 break;
10724 case MSM_VIDC_TRANSFER_BT_1361:
10725 aspects->mTransfer = ColorAspects::TransferBT1361;
10726 break;
10727 case MSM_VIDC_TRANSFER_SRGB:
10728 aspects->mTransfer = ColorAspects::TransferSRGB;
10729 break;
10730 case MSM_VIDC_TRANSFER_SMPTE_ST2084:
10731 aspects->mTransfer = ColorAspects::TransferST2084;
10732 break;
10733 case MSM_VIDC_TRANSFER_HLG:
10734 aspects->mTransfer = ColorAspects::TransferHLG;
10735 break;
10736 default:
10737 //aspects->mTransfer = ColorAspects::TransferOther;
10738 aspects->mTransfer = m_client_color_space.sAspects.mTransfer;
10739 break;
10740 }
10741
10742 switch (matrix) {
10743 case MSM_VIDC_MATRIX_BT_709_5:
10744 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
10745 break;
10746 case MSM_VIDC_MATRIX_FCC_47:
10747 aspects->mMatrixCoeffs = ColorAspects::MatrixBT470_6M;
10748 break;
10749 case MSM_VIDC_MATRIX_601_6_625:
10750 case MSM_VIDC_MATRIX_601_6_525:
10751 aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10752 break;
10753 case MSM_VIDC_MATRIX_SMPTE_240M:
10754 aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M;
10755 break;
10756 case MSM_VIDC_MATRIX_BT_2020:
10757 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
10758 break;
10759 case MSM_VIDC_MATRIX_BT_2020_CONST:
10760 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020Constant;
10761 break;
10762 default:
10763 //aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
10764 aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
10765 break;
10766 }
10767 }
10768
print_debug_color_aspects(ColorAspects * a,const char * prefix)10769 void omx_vdec::print_debug_color_aspects(ColorAspects *a, const char *prefix) {
10770 DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d(%s) Range = %d(%s) Tx = %d(%s) Matrix = %d(%s)",
10771 prefix, a->mPrimaries, asString(a->mPrimaries), a->mRange, asString(a->mRange),
10772 a->mTransfer, asString(a->mTransfer), a->mMatrixCoeffs, asString(a->mMatrixCoeffs));
10773
10774 }
10775
handle_color_space_info(void * data)10776 bool omx_vdec::handle_color_space_info(void *data)
10777 {
10778 ColorAspects tempAspects;
10779 memset(&tempAspects, 0x0, sizeof(ColorAspects));
10780 ColorAspects *aspects = &tempAspects;
10781
10782 switch(output_capability) {
10783 case V4L2_PIX_FMT_MPEG2:
10784 {
10785 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
10786 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data;
10787
10788 /* Refer MPEG2 Spec @ Rec. ISO/IEC 13818-2, ITU-T Draft Rec. H.262 to
10789 * understand this code */
10790
10791 if (seqdisp_payload && seqdisp_payload->color_descp) {
10792
10793 convert_color_space_info(seqdisp_payload->color_primaries, 0,
10794 seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs,
10795 aspects);
10796 /* MPEG2 seqdisp payload doesn't give range info. Hence assing the value
10797 * set by client */
10798 aspects->mRange = m_client_color_space.sAspects.mRange;
10799 m_disp_hor_size = seqdisp_payload->disp_width;
10800 m_disp_vert_size = seqdisp_payload->disp_height;
10801 }
10802 }
10803 break;
10804 case V4L2_PIX_FMT_H264:
10805 case V4L2_PIX_FMT_HEVC:
10806 {
10807 struct msm_vidc_vui_display_info_payload *display_info_payload;
10808 display_info_payload = (struct msm_vidc_vui_display_info_payload*)data;
10809
10810 /* Refer H264 Spec @ Rec. ITU-T H.264 (02/2014) to understand this code */
10811
10812 if (display_info_payload->video_signal_present_flag &&
10813 display_info_payload->color_description_present_flag) {
10814 convert_color_space_info(display_info_payload->color_primaries,
10815 display_info_payload->video_full_range_flag,
10816 display_info_payload->transfer_characteristics,
10817 display_info_payload->matrix_coefficients,
10818 aspects);
10819 }
10820 }
10821 break;
10822 case V4L2_PIX_FMT_VP8:
10823 {
10824 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
10825 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
10826 /* Refer VP8 Data Format in latest VP8 spec and Decoding Guide November 2011
10827 * to understand this code */
10828
10829 if (vpx_color_space_payload->color_space == 0) {
10830 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
10831 aspects->mRange = ColorAspects::RangeLimited;
10832 aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10833 aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10834 } else {
10835 DEBUG_PRINT_ERROR("Unsupported Color space for VP8");
10836 break;
10837 }
10838 }
10839 break;
10840 case V4L2_PIX_FMT_VP9:
10841 {
10842 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
10843 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
10844 /* Refer VP9 Spec @ VP9 Bitstream & Decoding Process Specification - v0.6 31st March 2016
10845 * to understand this code */
10846
10847 switch(vpx_color_space_payload->color_space) {
10848 case MSM_VIDC_CS_BT_601:
10849 aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10850 aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10851 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
10852 aspects->mRange = m_client_color_space.sAspects.mRange;
10853 break;
10854 case MSM_VIDC_CS_BT_709:
10855 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
10856 aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10857 aspects->mPrimaries = ColorAspects::PrimariesBT709_5;
10858 aspects->mRange = m_client_color_space.sAspects.mRange;
10859 break;
10860 case MSM_VIDC_CS_SMPTE_170:
10861 aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
10862 aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10863 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
10864 aspects->mRange = m_client_color_space.sAspects.mRange;
10865 break;
10866 case MSM_VIDC_CS_SMPTE_240:
10867 aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M;
10868 aspects->mTransfer = ColorAspects::TransferSMPTE240M;
10869 aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
10870 aspects->mRange = m_client_color_space.sAspects.mRange;
10871 break;
10872 case MSM_VIDC_CS_BT_2020:
10873 aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
10874 aspects->mTransfer = ColorAspects:: TransferSMPTE170M;
10875 aspects->mPrimaries = ColorAspects::PrimariesBT2020;
10876 aspects->mRange = m_client_color_space.sAspects.mRange;
10877 break;
10878 case MSM_VIDC_CS_RESERVED:
10879 aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
10880 aspects->mTransfer = ColorAspects::TransferOther;
10881 aspects->mPrimaries = ColorAspects::PrimariesOther;
10882 aspects->mRange = m_client_color_space.sAspects.mRange;
10883 break;
10884 case MSM_VIDC_CS_RGB:
10885 aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
10886 aspects->mTransfer = ColorAspects::TransferSMPTE170M;
10887 aspects->mPrimaries = ColorAspects::PrimariesOther;
10888 aspects->mRange = m_client_color_space.sAspects.mRange;
10889 break;
10890 default:
10891 break;
10892 }
10893 }
10894 break;
10895 default:
10896 break;
10897 }
10898
10899 print_debug_color_aspects(aspects, "Bitstream");
10900
10901 if (m_internal_color_space.sAspects.mPrimaries != aspects->mPrimaries ||
10902 m_internal_color_space.sAspects.mTransfer != aspects->mTransfer ||
10903 m_internal_color_space.sAspects.mMatrixCoeffs != aspects->mMatrixCoeffs ||
10904 m_internal_color_space.sAspects.mRange != aspects->mRange) {
10905 memcpy(&(m_internal_color_space.sAspects), aspects, sizeof(ColorAspects));
10906
10907 DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to Color Aspects Change");
10908 print_debug_color_aspects(&(m_internal_color_space.sAspects), "Internal");
10909 print_debug_color_aspects(&(m_client_color_space.sAspects), "Client");
10910
10911 post_event(OMX_CORE_OUTPUT_PORT_INDEX,
10912 OMX_QTIIndexConfigDescribeColorAspects,
10913 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
10914 return true;
10915 }
10916 return false;
10917 }
10918
print_debug_hdr_color_info(HDRStaticInfo * hdr_info,const char * prefix)10919 void omx_vdec::print_debug_hdr_color_info(HDRStaticInfo *hdr_info, const char *prefix)
10920 {
10921 if (!hdr_info->mID) {
10922 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mR.x = %d mR.y = %d", prefix,
10923 hdr_info->sType1.mR.x, hdr_info->sType1.mR.y);
10924 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mG.x = %d mG.y = %d", prefix,
10925 hdr_info->sType1.mG.x, hdr_info->sType1.mG.y);
10926 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mB.x = %d mB.y = %d", prefix,
10927 hdr_info->sType1.mB.x, hdr_info->sType1.mB.y);
10928 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mW.x = %d mW.y = %d", prefix,
10929 hdr_info->sType1.mW.x, hdr_info->sType1.mW.y);
10930 DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: maxDispLum = %d minDispLum = %d", prefix,
10931 hdr_info->sType1.mMaxDisplayLuminance, hdr_info->sType1.mMinDisplayLuminance);
10932 DEBUG_PRINT_LOW("%s : HDRstaticinfo CLL: CLL = %d FLL = %d", prefix,
10933 hdr_info->sType1.mMaxContentLightLevel, hdr_info->sType1.mMaxFrameAverageLightLevel);
10934 }
10935
10936 }
10937
print_debug_hdr_color_info_mdata(ColorMetaData * color_mdata)10938 void omx_vdec::print_debug_hdr_color_info_mdata(ColorMetaData* color_mdata)
10939 {
10940 DEBUG_PRINT_LOW("setMetaData COLOR_METADATA : color_primaries = %u, range = %u, transfer = %u, matrix = %u",
10941 color_mdata->colorPrimaries, color_mdata->range,
10942 color_mdata->transfer, color_mdata->matrixCoefficients);
10943
10944 for(uint8_t i = 0; i < 3; i++) {
10945 for(uint8_t j = 0; j < 2; j++) {
10946 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : rgbPrimaries[%d][%d] = %d", i, j, color_mdata->masteringDisplayInfo.primaries.rgbPrimaries[i][j]);
10947 }
10948 }
10949
10950 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : whitepoint[0] = %d whitepoint[1] = %d",
10951 color_mdata->masteringDisplayInfo.primaries.whitePoint[0],
10952 color_mdata->masteringDisplayInfo.primaries.whitePoint[1]);
10953
10954 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxDispLum = %d minDispLum = %d",
10955 color_mdata->masteringDisplayInfo.maxDisplayLuminance,
10956 color_mdata->masteringDisplayInfo.minDisplayLuminance);
10957
10958 DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxCLL = %d maxFLL = %d",
10959 color_mdata->contentLightLevel.maxContentLightLevel,
10960 color_mdata->contentLightLevel.minPicAverageLightLevel);
10961
10962
10963 }
10964
handle_content_light_level_info(void * data)10965 bool omx_vdec::handle_content_light_level_info(void* data)
10966 {
10967 struct msm_vidc_content_light_level_sei_payload *light_level_payload =
10968 (msm_vidc_content_light_level_sei_payload*)(data);
10969
10970 if ((m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel != light_level_payload->nMaxContentLight) ||
10971 (m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel != light_level_payload->nMaxPicAverageLight)) {
10972 m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel = light_level_payload->nMaxContentLight;
10973 m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel = light_level_payload->nMaxPicAverageLight;
10974 return true;
10975 }
10976 return false;
10977 }
10978
handle_mastering_display_color_info(void * data)10979 bool omx_vdec::handle_mastering_display_color_info(void* data)
10980 {
10981 struct msm_vidc_mastering_display_colour_sei_payload *mastering_display_payload =
10982 (msm_vidc_mastering_display_colour_sei_payload*)(data);
10983 HDRStaticInfo* hdr_info = &m_internal_hdr_info.sInfo;
10984 bool internal_disp_changed_flag = false;
10985
10986 internal_disp_changed_flag |= (hdr_info->sType1.mR.x != mastering_display_payload->nDisplayPrimariesX[0]) ||
10987 (hdr_info->sType1.mR.y != mastering_display_payload->nDisplayPrimariesY[0]);
10988 internal_disp_changed_flag |= (hdr_info->sType1.mG.x != mastering_display_payload->nDisplayPrimariesX[1]) ||
10989 (hdr_info->sType1.mG.y != mastering_display_payload->nDisplayPrimariesY[1]);
10990 internal_disp_changed_flag |= (hdr_info->sType1.mB.x != mastering_display_payload->nDisplayPrimariesX[2]) ||
10991 (hdr_info->sType1.mB.y != mastering_display_payload->nDisplayPrimariesY[2]);
10992
10993 internal_disp_changed_flag |= (hdr_info->sType1.mW.x != mastering_display_payload->nWhitePointX) ||
10994 (hdr_info->sType1.mW.y != mastering_display_payload->nWhitePointY);
10995
10996 /* Maximum Display Luminance from the bitstream is in 0.0001 cd/m2 while the HDRStaticInfo extension
10997 requires it in cd/m2, so dividing by 10000 and rounding the value after division
10998 */
10999 uint16_t max_display_luminance_cd_m2 =
11000 static_cast<int>((mastering_display_payload->nMaxDisplayMasteringLuminance / LUMINANCE_DIV_FACTOR) + 0.5);
11001 internal_disp_changed_flag |= (hdr_info->sType1.mMaxDisplayLuminance != max_display_luminance_cd_m2) ||
11002 (hdr_info->sType1.mMinDisplayLuminance != mastering_display_payload->nMinDisplayMasteringLuminance);
11003
11004 if (internal_disp_changed_flag) {
11005 hdr_info->sType1.mR.x = mastering_display_payload->nDisplayPrimariesX[0];
11006 hdr_info->sType1.mR.y = mastering_display_payload->nDisplayPrimariesY[0];
11007 hdr_info->sType1.mG.x = mastering_display_payload->nDisplayPrimariesX[1];
11008 hdr_info->sType1.mG.y = mastering_display_payload->nDisplayPrimariesY[1];
11009 hdr_info->sType1.mB.x = mastering_display_payload->nDisplayPrimariesX[2];
11010 hdr_info->sType1.mB.y = mastering_display_payload->nDisplayPrimariesY[2];
11011 hdr_info->sType1.mW.x = mastering_display_payload->nWhitePointX;
11012 hdr_info->sType1.mW.y = mastering_display_payload->nWhitePointY;
11013
11014 hdr_info->sType1.mMaxDisplayLuminance = max_display_luminance_cd_m2;
11015 hdr_info->sType1.mMinDisplayLuminance = mastering_display_payload->nMinDisplayMasteringLuminance;
11016 }
11017
11018 return internal_disp_changed_flag;
11019 }
11020
set_colormetadata_in_handle(ColorMetaData * color_mdata,unsigned int buf_index)11021 void omx_vdec::set_colormetadata_in_handle(ColorMetaData *color_mdata, unsigned int buf_index)
11022 {
11023 private_handle_t *private_handle = NULL;
11024 if (buf_index < drv_ctx.op_buf.actualcount &&
11025 buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
11026 native_buffer[buf_index].privatehandle) {
11027 private_handle = native_buffer[buf_index].privatehandle;
11028 }
11029 if (private_handle) {
11030 setMetaData(private_handle, COLOR_METADATA, (void*)color_mdata);
11031 }
11032 }
11033
convert_color_aspects_to_metadata(ColorAspects & aspects,ColorMetaData & color_mdata)11034 void omx_vdec::convert_color_aspects_to_metadata(ColorAspects& aspects, ColorMetaData &color_mdata)
11035 {
11036 PrimariesMap::const_iterator primary_it = mPrimariesMap.find(aspects.mPrimaries);
11037 TransferMap::const_iterator transfer_it = mTransferMap.find(aspects.mTransfer);
11038 MatrixCoeffMap::const_iterator matrix_it = mMatrixCoeffMap.find(aspects.mMatrixCoeffs);
11039 RangeMap::const_iterator range_it = mColorRangeMap.find(aspects.mRange);
11040
11041 if (primary_it == mPrimariesMap.end()) {
11042 DEBUG_PRINT_LOW("No mapping for %d in PrimariesMap, defaulting to unspecified", aspects.mPrimaries);
11043 color_mdata.colorPrimaries = (ColorPrimaries)2;
11044 } else {
11045 color_mdata.colorPrimaries = primary_it->second;
11046 }
11047
11048 if (transfer_it == mTransferMap.end()) {
11049 DEBUG_PRINT_LOW("No mapping for %d in TransferMap, defaulting to unspecified", aspects.mTransfer);
11050 color_mdata.transfer = (GammaTransfer)2;
11051 } else {
11052 color_mdata.transfer = transfer_it->second;
11053 }
11054
11055 if (matrix_it == mMatrixCoeffMap.end()) {
11056 DEBUG_PRINT_LOW("No mapping for %d in MatrixCoeffMap, defaulting to unspecified", aspects.mMatrixCoeffs);
11057 color_mdata.matrixCoefficients = (MatrixCoEfficients)2;
11058 } else {
11059 color_mdata.matrixCoefficients = matrix_it->second;
11060 }
11061
11062 if (range_it == mColorRangeMap.end()) {
11063 DEBUG_PRINT_LOW("No mapping for %d in ColorRangeMap, defaulting to limited range", aspects.mRange);
11064 color_mdata.range = Range_Limited;
11065 } else {
11066 color_mdata.range = range_it->second;
11067 }
11068 }
11069
convert_hdr_info_to_metadata(HDRStaticInfo & hdr_info,ColorMetaData & color_mdata)11070 void omx_vdec::convert_hdr_info_to_metadata(HDRStaticInfo& hdr_info, ColorMetaData &color_mdata)
11071 {
11072 HDRStaticInfo::Type1 zero_hdr_info;
11073 MasteringDisplay& mastering_display = color_mdata.masteringDisplayInfo;
11074 ContentLightLevel& content_light = color_mdata.contentLightLevel;
11075 bool hdr_info_enabled = false;
11076 memset(&zero_hdr_info, 0, sizeof(HDRStaticInfo::Type1));
11077 hdr_info_enabled = (memcmp(&hdr_info, &zero_hdr_info, sizeof(HDRStaticInfo::Type1))!= 0);
11078
11079 if (hdr_info_enabled) {
11080 mastering_display.colorVolumeSEIEnabled = true;
11081 mastering_display.primaries.rgbPrimaries[0][0] = hdr_info.sType1.mR.x;
11082 mastering_display.primaries.rgbPrimaries[0][1] = hdr_info.sType1.mR.y;
11083 mastering_display.primaries.rgbPrimaries[1][0] = hdr_info.sType1.mG.x;
11084 mastering_display.primaries.rgbPrimaries[1][1] = hdr_info.sType1.mG.y;
11085 mastering_display.primaries.rgbPrimaries[2][0] = hdr_info.sType1.mB.x;
11086 mastering_display.primaries.rgbPrimaries[2][1] = hdr_info.sType1.mB.y;
11087 mastering_display.primaries.whitePoint[0] = hdr_info.sType1.mW.x;
11088 mastering_display.primaries.whitePoint[1] = hdr_info.sType1.mW.y;
11089 mastering_display.maxDisplayLuminance = hdr_info.sType1.mMaxDisplayLuminance * LUMINANCE_DIV_FACTOR;
11090 mastering_display.minDisplayLuminance = hdr_info.sType1.mMinDisplayLuminance;
11091 content_light.lightLevelSEIEnabled = true;
11092 content_light.maxContentLightLevel = hdr_info.sType1.mMaxContentLightLevel;
11093 content_light.minPicAverageLightLevel = hdr_info.sType1.mMaxFrameAverageLightLevel;
11094 }
11095
11096 }
11097
get_preferred_color_aspects(ColorAspects & preferredColorAspects)11098 void omx_vdec::get_preferred_color_aspects(ColorAspects& preferredColorAspects)
11099 {
11100 // For VPX, use client-color if specified.
11101 // For the rest, try to use the stream-color if present
11102 bool preferClientColor = (output_capability == V4L2_PIX_FMT_VP8 ||
11103 output_capability == V4L2_PIX_FMT_VP9);
11104
11105 const ColorAspects &preferredColor = preferClientColor ?
11106 m_client_color_space.sAspects : m_internal_color_space.sAspects;
11107 const ColorAspects &defaultColor = preferClientColor ?
11108 m_internal_color_space.sAspects : m_client_color_space.sAspects;
11109
11110 preferredColorAspects.mPrimaries = preferredColor.mPrimaries != ColorAspects::PrimariesUnspecified ?
11111 preferredColor.mPrimaries : defaultColor.mPrimaries;
11112 preferredColorAspects.mTransfer = preferredColor.mTransfer != ColorAspects::TransferUnspecified ?
11113 preferredColor.mTransfer : defaultColor.mTransfer;
11114 preferredColorAspects.mMatrixCoeffs = preferredColor.mMatrixCoeffs != ColorAspects::MatrixUnspecified ?
11115 preferredColor.mMatrixCoeffs : defaultColor.mMatrixCoeffs;
11116 preferredColorAspects.mRange = preferredColor.mRange != ColorAspects::RangeUnspecified ?
11117 preferredColor.mRange : defaultColor.mRange;
11118
11119 }
11120
get_preferred_hdr_info(HDRStaticInfo & finalHDRInfo)11121 void omx_vdec::get_preferred_hdr_info(HDRStaticInfo& finalHDRInfo)
11122 {
11123 bool preferClientHDR = (output_capability == V4L2_PIX_FMT_VP9);
11124
11125 const HDRStaticInfo &preferredHDRInfo = preferClientHDR ?
11126 m_client_hdr_info.sInfo : m_internal_hdr_info.sInfo;
11127 const HDRStaticInfo &defaultHDRInfo = preferClientHDR ?
11128 m_internal_hdr_info.sInfo : m_client_hdr_info.sInfo;
11129 finalHDRInfo.sType1.mR = ((preferredHDRInfo.sType1.mR.x != 0) && (preferredHDRInfo.sType1.mR.y != 0)) ?
11130 preferredHDRInfo.sType1.mR : defaultHDRInfo.sType1.mR;
11131 finalHDRInfo.sType1.mG = ((preferredHDRInfo.sType1.mG.x != 0) && (preferredHDRInfo.sType1.mG.y != 0)) ?
11132 preferredHDRInfo.sType1.mG : defaultHDRInfo.sType1.mG;
11133 finalHDRInfo.sType1.mB = ((preferredHDRInfo.sType1.mB.x != 0) && (preferredHDRInfo.sType1.mB.y != 0)) ?
11134 preferredHDRInfo.sType1.mB : defaultHDRInfo.sType1.mB;
11135 finalHDRInfo.sType1.mW = ((preferredHDRInfo.sType1.mW.x != 0) && (preferredHDRInfo.sType1.mW.y != 0)) ?
11136 preferredHDRInfo.sType1.mW : defaultHDRInfo.sType1.mW;
11137 finalHDRInfo.sType1.mMaxDisplayLuminance = (preferredHDRInfo.sType1.mMaxDisplayLuminance != 0) ?
11138 preferredHDRInfo.sType1.mMaxDisplayLuminance : defaultHDRInfo.sType1.mMaxDisplayLuminance;
11139 finalHDRInfo.sType1.mMinDisplayLuminance = (preferredHDRInfo.sType1.mMinDisplayLuminance != 0) ?
11140 preferredHDRInfo.sType1.mMinDisplayLuminance : defaultHDRInfo.sType1.mMinDisplayLuminance;
11141 finalHDRInfo.sType1.mMaxContentLightLevel = (preferredHDRInfo.sType1.mMaxContentLightLevel != 0) ?
11142 preferredHDRInfo.sType1.mMaxContentLightLevel : defaultHDRInfo.sType1.mMaxContentLightLevel;
11143 finalHDRInfo.sType1.mMaxFrameAverageLightLevel = (preferredHDRInfo.sType1.mMaxFrameAverageLightLevel != 0) ?
11144 preferredHDRInfo.sType1.mMaxFrameAverageLightLevel : defaultHDRInfo.sType1.mMaxFrameAverageLightLevel;
11145 }
11146
print_debug_hdr10plus_metadata(ColorMetaData & color_mdata)11147 void omx_vdec::print_debug_hdr10plus_metadata(ColorMetaData& color_mdata) {
11148 DEBUG_PRINT_LOW("HDR10+ valid data length: %d", color_mdata.dynamicMetaDataLen);
11149 for (uint32_t i = 0 ; i < color_mdata.dynamicMetaDataLen && i+3 < HDR_DYNAMIC_META_DATA_SZ; i=i+4) {
11150 DEBUG_PRINT_LOW("HDR10+ mdata: %02X %02X %02X %02X", color_mdata.dynamicMetaDataPayload[i],
11151 color_mdata.dynamicMetaDataPayload[i+1],
11152 color_mdata.dynamicMetaDataPayload[i+2],
11153 color_mdata.dynamicMetaDataPayload[i+3]);
11154 }
11155
11156 }
11157
handle_extradata(OMX_BUFFERHEADERTYPE * p_buf_hdr)11158 bool omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
11159 {
11160 OMX_OTHER_EXTRADATATYPE *p_sei = NULL, *p_vui = NULL, *p_client_extra = NULL;
11161 OMX_U32 num_conceal_MB = 0;
11162 OMX_TICKS time_stamp = 0;
11163 OMX_U32 frame_rate = 0;
11164 unsigned long consumed_len = 0;
11165 OMX_U32 num_MB_in_frame;
11166 OMX_U32 recovery_sei_flags = 1;
11167 int enable = OMX_InterlaceFrameProgressive;
11168 bool internal_hdr_info_changed_flag = false;
11169 bool reconfig_event_sent = false;
11170 char *p_extradata = NULL;
11171 OMX_OTHER_EXTRADATATYPE *data = NULL;
11172 ColorMetaData color_mdata;
11173
11174 OMX_BUFFERHEADERTYPE *omx_base_address =
11175 client_buffers.is_color_conversion_enabled()?
11176 m_intermediate_out_mem_ptr:m_out_mem_ptr;
11177 vdec_bufferpayload *omx_ptr_outputbuffer =
11178 client_buffers.is_color_conversion_enabled()?
11179 drv_ctx.ptr_intermediate_outputbuffer:drv_ctx.ptr_outputbuffer;
11180 memset(&color_mdata, 0, sizeof(color_mdata));
11181
11182 int buf_index = p_buf_hdr - omx_base_address;
11183 if (buf_index >= drv_ctx.extradata_info.count) {
11184 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
11185 buf_index, drv_ctx.extradata_info.count);
11186 return reconfig_event_sent;
11187 }
11188 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
11189
11190 if (omx_ptr_outputbuffer[buf_index].bufferaddr == NULL) {
11191 DEBUG_PRINT_ERROR("handle_extradata: Error: Mapped output buffer address is NULL");
11192 return reconfig_event_sent;
11193 }
11194
11195 if (!drv_ctx.extradata_info.uaddr) {
11196 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
11197 return reconfig_event_sent;
11198 }
11199
11200 if (m_client_output_extradata_mem_ptr &&
11201 m_client_out_extradata_info.getSize() >= drv_ctx.extradata_info.buffer_size) {
11202 p_client_extra = (OMX_OTHER_EXTRADATATYPE *)((m_client_output_extradata_mem_ptr + buf_index)->pBuffer);
11203 }
11204
11205 p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
11206
11207 m_extradata_info.output_crop_updated = OMX_FALSE;
11208 data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
11209 if (data) {
11210 while ((((consumed_len + sizeof(struct OMX_OTHER_EXTRADATATYPE)) <
11211 drv_ctx.extradata_info.buffer_size) && ((consumed_len + data->nSize) <
11212 drv_ctx.extradata_info.buffer_size))
11213 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
11214 DEBUG_PRINT_LOW("handle_extradata: eType = 0x%x", data->eType);
11215 switch ((unsigned long)data->eType) {
11216 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO:
11217 struct msm_vidc_interlace_payload *payload;
11218 payload = (struct msm_vidc_interlace_payload *)(void *)data->data;
11219 if (payload) {
11220 DEBUG_PRINT_LOW("Interlace format %#x", payload->format);
11221 enable = OMX_InterlaceFrameProgressive;
11222 is_mbaff = payload->format & MSM_VIDC_INTERLACE_FRAME_MBAFF;
11223 switch (payload->format & 0x1F) {
11224 case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE:
11225 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
11226 break;
11227 case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
11228 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
11229 enable = OMX_InterlaceInterleaveFrameTopFieldFirst;
11230 break;
11231 case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
11232 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
11233 enable = OMX_InterlaceInterleaveFrameBottomFieldFirst;
11234 break;
11235 case MSM_VIDC_INTERLACE_FRAME_TOPFIELDFIRST:
11236 drv_ctx.interlace = VDEC_InterlaceFrameTopFieldFirst;
11237 enable = OMX_InterlaceFrameTopFieldFirst;
11238 break;
11239 case MSM_VIDC_INTERLACE_FRAME_BOTTOMFIELDFIRST:
11240 drv_ctx.interlace = VDEC_InterlaceFrameBottomFieldFirst;
11241 enable = OMX_InterlaceFrameBottomFieldFirst;
11242 break;
11243 default:
11244 DEBUG_PRINT_LOW("default case - set to progressive");
11245 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
11246 }
11247 }
11248
11249 if (m_enable_android_native_buffers) {
11250 DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d enable:%d",
11251 payload->format, enable);
11252
11253 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
11254 PP_PARAM_INTERLACED, (void*)&enable);
11255
11256 }
11257 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
11258 if (p_client_extra) {
11259 append_interlace_extradata(p_client_extra, (payload->format & 0x1F));
11260 p_client_extra = (OMX_OTHER_EXTRADATATYPE *)
11261 (((OMX_U8 *)p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11262 }
11263 }
11264 break;
11265 case MSM_VIDC_EXTRADATA_FRAME_RATE:
11266 struct msm_vidc_framerate_payload *frame_rate_payload;
11267 frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data;
11268 frame_rate = frame_rate_payload->frame_rate;
11269 break;
11270 case MSM_VIDC_EXTRADATA_TIMESTAMP:
11271 struct msm_vidc_ts_payload *time_stamp_payload;
11272 time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data;
11273 time_stamp = time_stamp_payload->timestamp_lo;
11274 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
11275 p_buf_hdr->nTimeStamp = time_stamp;
11276 break;
11277 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB:
11278 struct msm_vidc_concealmb_payload *conceal_mb_payload;
11279 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)data->data;
11280 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
11281 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
11282 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
11283 break;
11284 case MSM_VIDC_EXTRADATA_INDEX:
11285 int *etype;
11286 etype = (int *)(void *)data->data;
11287 if (etype && *etype == MSM_VIDC_EXTRADATA_ASPECT_RATIO) {
11288 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
11289 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
11290 if (aspect_ratio_payload) {
11291 ((struct vdec_output_frameinfo *)
11292 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
11293 ((struct vdec_output_frameinfo *)
11294 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
11295 }
11296 } else if (etype && *etype == MSM_VIDC_EXTRADATA_OUTPUT_CROP) {
11297 struct msm_vidc_output_crop_payload *output_crop_payload;
11298 output_crop_payload = (struct msm_vidc_output_crop_payload *)(++etype);
11299 if (output_crop_payload) {
11300 m_extradata_info.output_crop_rect.nLeft = output_crop_payload->left;
11301 m_extradata_info.output_crop_rect.nTop = output_crop_payload->top;
11302 m_extradata_info.output_crop_rect.nWidth = output_crop_payload->left + output_crop_payload->display_width;
11303 m_extradata_info.output_crop_rect.nHeight = output_crop_payload->top + output_crop_payload->display_height;
11304 m_extradata_info.output_width = output_crop_payload->width;
11305 m_extradata_info.output_height = output_crop_payload->height;
11306 m_extradata_info.output_crop_updated = OMX_TRUE;
11307 for(unsigned int m=0; m<output_crop_payload->misr_info[0].misr_set; m++) {
11308 DEBUG_PRINT_HIGH("MISR0: %x %x %x %x\n",
11309 output_crop_payload->misr_info[0].misr_dpb_luma[m],
11310 output_crop_payload->misr_info[0].misr_dpb_chroma[m],
11311 output_crop_payload->misr_info[0].misr_opb_luma[m],
11312 output_crop_payload->misr_info[0].misr_opb_chroma[m]);
11313 }
11314 for(unsigned int m=0; m< output_crop_payload->misr_info[1].misr_set; m++) {
11315 DEBUG_PRINT_HIGH("MISR1: %x %x %x %x\n",
11316 output_crop_payload->misr_info[1].misr_dpb_luma[m],
11317 output_crop_payload->misr_info[1].misr_dpb_chroma[m],
11318 output_crop_payload->misr_info[1].misr_opb_luma[m],
11319 output_crop_payload->misr_info[1].misr_opb_chroma[m]);
11320 }
11321 memcpy(m_extradata_info.misr_info, output_crop_payload->misr_info, 2 * sizeof(msm_vidc_misr_info));
11322 if (client_extradata & OMX_OUTPUTCROP_EXTRADATA) {
11323 if (p_client_extra) {
11324 append_outputcrop_extradata(p_client_extra, output_crop_payload);
11325 p_client_extra = (OMX_OTHER_EXTRADATATYPE *)(((OMX_U8 *)p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11326 }
11327 }
11328 }
11329 }
11330 break;
11331 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
11332 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
11333 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data;
11334 recovery_sei_flags = recovery_sei_payload->flags;
11335 if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) {
11336 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
11337 DEBUG_PRINT_HIGH("***************************************************");
11338 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
11339 DEBUG_PRINT_HIGH("***************************************************");
11340 }
11341 break;
11342 case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW:
11343 panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data;
11344 if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) {
11345 DEBUG_PRINT_ERROR("Panscan windows are more than supported\n");
11346 DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n",
11347 MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows);
11348 return reconfig_event_sent;
11349 }
11350 break;
11351 case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP:
11352 case MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO:
11353 case MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO:
11354 reconfig_event_sent |= handle_color_space_info((void *)data->data);
11355 break;
11356 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING:
11357 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
11358 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data;
11359 switch (s3d_frame_packing_payload->fpa_type) {
11360 case MSM_VIDC_FRAMEPACK_SIDE_BY_SIDE:
11361 if (s3d_frame_packing_payload->content_interprtation_type == 1)
11362 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_L_R;
11363 else if (s3d_frame_packing_payload->content_interprtation_type == 2)
11364 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_R_L;
11365 else {
11366 DEBUG_PRINT_ERROR("Unsupported side-by-side framepacking type");
11367 stereo_output_mode = HAL_NO_3D;
11368 }
11369 break;
11370 case MSM_VIDC_FRAMEPACK_TOP_BOTTOM:
11371 stereo_output_mode = HAL_3D_TOP_BOTTOM;
11372 break;
11373 default:
11374 DEBUG_PRINT_ERROR("Unsupported framepacking type");
11375 stereo_output_mode = HAL_NO_3D;
11376 }
11377 DEBUG_PRINT_LOW("setMetaData FRAMEPACKING : fpa_type = %u, content_interprtation_type = %u, stereo_output_mode= %d",
11378 s3d_frame_packing_payload->fpa_type, s3d_frame_packing_payload->content_interprtation_type, stereo_output_mode);
11379 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
11380 if (p_client_extra) {
11381 append_framepack_extradata(p_client_extra, s3d_frame_packing_payload);
11382 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11383 }
11384 }
11385 break;
11386 case MSM_VIDC_EXTRADATA_FRAME_QP:
11387 struct msm_vidc_frame_qp_payload *qp_payload;
11388 qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data;
11389 if (client_extradata & OMX_QP_EXTRADATA) {
11390 if (p_client_extra) {
11391 append_qp_extradata(p_client_extra, qp_payload);
11392 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11393 }
11394 }
11395 break;
11396 case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO:
11397 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
11398 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data;
11399 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
11400 if (p_client_extra) {
11401 append_bitsinfo_extradata(p_client_extra, bits_info_payload);
11402 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11403 }
11404 }
11405 break;
11406 case MSM_VIDC_EXTRADATA_UBWC_CR_STAT_INFO:
11407 DEBUG_PRINT_LOW("MSM_VIDC_EXTRADATA_UBWC_CR_STAT_INFO not used. Ignoring.");
11408 break;
11409 case MSM_VIDC_EXTRADATA_STREAM_USERDATA:
11410 if(output_capability == V4L2_PIX_FMT_HEVC) {
11411 struct msm_vidc_stream_userdata_payload* userdata_payload = (struct msm_vidc_stream_userdata_payload*)data->data;
11412 // Remove the size of type from msm_vidc_stream_userdata_payload
11413 uint32_t payload_len = data->nDataSize - sizeof(userdata_payload->type);
11414 if ((data->nDataSize < sizeof(userdata_payload->type)) ||
11415 (payload_len > HDR_DYNAMIC_META_DATA_SZ)) {
11416 DEBUG_PRINT_ERROR("Invalid User extradata size %u for HDR10+", data->nDataSize);
11417 } else {
11418 color_mdata.dynamicMetaDataValid = true;
11419 color_mdata.dynamicMetaDataLen = payload_len;
11420 memcpy(color_mdata.dynamicMetaDataPayload, userdata_payload->data, payload_len);
11421 DEBUG_PRINT_HIGH("Copied %u bytes of HDR10+ extradata", payload_len);
11422 }
11423 }
11424 if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
11425 if (p_client_extra) {
11426 append_user_extradata(p_client_extra, data);
11427 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11428 }
11429 }
11430 break;
11431 case MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI:
11432
11433 internal_hdr_info_changed_flag |= handle_content_light_level_info((void*)data->data);
11434 break;
11435 case MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI:
11436 internal_hdr_info_changed_flag |= handle_mastering_display_color_info((void*)data->data);
11437 break;
11438 default:
11439 DEBUG_PRINT_LOW("Unrecognized extradata");
11440 goto unrecognized_extradata;
11441 }
11442 consumed_len += data->nSize;
11443 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
11444 }
11445 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
11446 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
11447 if (p_client_extra) {
11448 append_frame_info_extradata(p_client_extra,
11449 num_conceal_MB, recovery_sei_flags, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
11450 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
11451 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
11452 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11453 }
11454 }
11455 if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) {
11456 if (p_client_extra) {
11457 append_frame_dimension_extradata(p_client_extra);
11458 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
11459 }
11460 }
11461
11462 if(internal_hdr_info_changed_flag) {
11463 print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "Internal");
11464 print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "Client");
11465 if(!reconfig_event_sent) {
11466 DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to HDR Info Change");
11467 post_event(OMX_CORE_OUTPUT_PORT_INDEX,
11468 OMX_QTIIndexConfigDescribeHDRColorInfo,
11469 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
11470 reconfig_event_sent = true;
11471 }
11472 }
11473
11474 if (m_enable_android_native_buffers) {
11475 ColorAspects final_color_aspects;
11476 HDRStaticInfo final_hdr_info;
11477 memset(&final_color_aspects, 0, sizeof(final_color_aspects));
11478 memset(&final_hdr_info, 0, sizeof(final_hdr_info));
11479 get_preferred_color_aspects(final_color_aspects);
11480
11481 /* For VP8, always set the metadata on gralloc handle to 601-LR */
11482 if (output_capability == V4L2_PIX_FMT_VP8) {
11483 final_color_aspects.mPrimaries = ColorAspects::PrimariesBT601_6_525;
11484 final_color_aspects.mRange = ColorAspects::RangeLimited;
11485 final_color_aspects.mTransfer = ColorAspects::TransferSMPTE170M;
11486 final_color_aspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
11487 }
11488 get_preferred_hdr_info(final_hdr_info);
11489 convert_color_aspects_to_metadata(final_color_aspects, color_mdata);
11490 convert_hdr_info_to_metadata(final_hdr_info, color_mdata);
11491 print_debug_hdr_color_info_mdata(&color_mdata);
11492 print_debug_hdr10plus_metadata(color_mdata);
11493 set_colormetadata_in_handle(&color_mdata, buf_index);
11494 }
11495
11496 }
11497 unrecognized_extradata:
11498 if (client_extradata) {
11499 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
11500 if (p_client_extra) {
11501 append_terminator_extradata(p_client_extra);
11502 }
11503 }
11504 return reconfig_event_sent;
11505 }
11506
enable_extradata(OMX_U64 requested_extradata,bool is_internal,bool enable)11507 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U64 requested_extradata,
11508 bool is_internal, bool enable)
11509 {
11510 OMX_ERRORTYPE ret = OMX_ErrorNone;
11511 struct v4l2_control control;
11512 if (m_state != OMX_StateLoaded) {
11513 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
11514 return OMX_ErrorIncorrectStateOperation;
11515 }
11516 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d",
11517 (unsigned int)client_extradata, (unsigned int)requested_extradata, enable, is_internal);
11518
11519 if (!is_internal) {
11520 if (enable)
11521 client_extradata |= requested_extradata;
11522 else
11523 client_extradata = client_extradata & ~requested_extradata;
11524 }
11525
11526 if (enable) {
11527 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
11528 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11529 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
11530 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11531 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
11532 " Quality of interlaced clips might be impacted.");
11533 }
11534 }
11535 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
11536 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11537 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
11538 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11539 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
11540 }
11541 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11542 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
11543 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11544 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
11545 }
11546 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11547 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
11548 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11549 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
11550 }
11551 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11552 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
11553 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11554 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
11555 }
11556 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11557 control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO;
11558 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11559 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
11560 }
11561 if (output_capability == V4L2_PIX_FMT_MPEG2) {
11562 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11563 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
11564 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11565 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
11566 }
11567 }
11568 }
11569 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
11570 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11571 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
11572 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11573 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
11574 }
11575 }
11576 if (!secure_mode && (requested_extradata & OMX_FRAMEPACK_EXTRADATA)) {
11577 if (output_capability == V4L2_PIX_FMT_H264) {
11578 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
11579 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11580 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
11581 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11582 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
11583 }
11584 } else {
11585 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
11586 }
11587 }
11588 if (requested_extradata & OMX_QP_EXTRADATA) {
11589 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11590 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
11591 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11592 DEBUG_PRINT_HIGH("Failed to set QP extradata");
11593 }
11594 }
11595 if (!secure_mode && (requested_extradata & OMX_EXTNUSER_EXTRADATA)) {
11596 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11597 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
11598 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11599 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
11600 }
11601 }
11602 #if NEED_TO_REVISIT
11603 if (requested_extradata & OMX_QP_EXTRADATA) {
11604 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11605 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
11606 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11607 DEBUG_PRINT_HIGH("Failed to set QP extradata");
11608 }
11609 }
11610 #endif
11611 if (requested_extradata & OMX_OUTPUTCROP_EXTRADATA) {
11612 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11613 control.value = V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP;
11614 DEBUG_PRINT_LOW("Enable output crop extra data");
11615 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11616 DEBUG_PRINT_HIGH("Failed to set output crop extradata");
11617 }
11618 }
11619 if (requested_extradata & OMX_UBWC_CR_STATS_INFO_EXTRADATA) {
11620 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11621 control.value = V4L2_MPEG_VIDC_EXTRADATA_UBWC_CR_STATS_INFO;
11622 DEBUG_PRINT_LOW("Enable UBWC stats extra data");
11623 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11624 DEBUG_PRINT_HIGH("Failed to set output crop extradata");
11625 }
11626 }
11627 if (requested_extradata & OMX_DISPLAY_INFO_EXTRADATA) {
11628 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11629 switch(output_capability) {
11630 case V4L2_PIX_FMT_H264:
11631 case V4L2_PIX_FMT_HEVC:
11632 control.value = V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY;
11633 break;
11634 case V4L2_PIX_FMT_VP8:
11635 case V4L2_PIX_FMT_VP9:
11636 control.value = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE;
11637 break;
11638 case V4L2_PIX_FMT_MPEG2:
11639 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
11640 break;
11641 default:
11642 DEBUG_PRINT_HIGH("Don't support Disp info for this codec : %s", drv_ctx.kind);
11643 return ret;
11644 }
11645
11646 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11647 DEBUG_PRINT_HIGH("Failed to set Display info extradata");
11648 }
11649 }
11650 if (requested_extradata & OMX_HDR_COLOR_INFO_EXTRADATA) {
11651 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
11652 if (output_capability == V4L2_PIX_FMT_HEVC) {
11653 control.value = V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI;
11654 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11655 DEBUG_PRINT_HIGH("Failed to set Display Colour SEI extradata");
11656 }
11657 control.value = V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI;
11658 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
11659 DEBUG_PRINT_HIGH("Failed to set Content Light Level SEI extradata");
11660 }
11661 } else {
11662 DEBUG_PRINT_HIGH("OMX_HDR_COLOR_INFO_EXTRADATA supported for HEVC only");
11663 }
11664 }
11665 }
11666 ret = get_buffer_req(&drv_ctx.op_buf);
11667 return ret;
11668 }
11669
count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE * extra)11670 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
11671 {
11672 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
11673 OMX_U8 *data_ptr = extra->data, data = 0;
11674 while (byte_count < extra->nDataSize) {
11675 data = *data_ptr;
11676 while (data) {
11677 num_MB += (data&0x01);
11678 data >>= 1;
11679 }
11680 data_ptr++;
11681 byte_count++;
11682 }
11683 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
11684 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
11685 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
11686 }
11687
print_debug_extradata(OMX_OTHER_EXTRADATATYPE * extra)11688 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
11689 {
11690 if (!m_debug_extradata || !extra)
11691 return;
11692
11693
11694 DEBUG_PRINT_HIGH(
11695 "============== Extra Data ==============\n"
11696 " Size: %u\n"
11697 " Version: %u\n"
11698 " PortIndex: %u\n"
11699 " Type: %x\n"
11700 " DataSize: %u",
11701 (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion,
11702 (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize);
11703
11704 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
11705 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
11706 DEBUG_PRINT_HIGH(
11707 "------ Interlace Format ------\n"
11708 " Size: %u\n"
11709 " Version: %u\n"
11710 " PortIndex: %u\n"
11711 " Is Interlace Format: %d\n"
11712 " Interlace Formats: %u\n"
11713 "=========== End of Interlace ===========",
11714 (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex,
11715 intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats);
11716 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
11717 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
11718
11719 DEBUG_PRINT_HIGH(
11720 "-------- Frame Format --------\n"
11721 " Picture Type: %d\n"
11722 " Interlace Type: %d\n"
11723 " Pan Scan Total Frame Num: %u\n"
11724 " Concealed Macro Blocks: %u\n"
11725 " Recovery SEI Flag: %u\n"
11726 " frame rate: %u\n"
11727 " Time Stamp: %llu\n"
11728 " Aspect Ratio X: %u\n"
11729 " Aspect Ratio Y: %u",
11730 fminfo->ePicType,
11731 fminfo->interlaceType,
11732 (unsigned int)fminfo->panScan.numWindows,
11733 (unsigned int)fminfo->nConcealedMacroblocks,
11734 (unsigned int)fminfo->nRecoverySeiFlag,
11735 (unsigned int)fminfo->nFrameRate,
11736 fminfo->nTimeStamp,
11737 (unsigned int)fminfo->aspectRatio.aspectRatioX,
11738 (unsigned int)fminfo->aspectRatio.aspectRatioY);
11739
11740 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
11741 DEBUG_PRINT_HIGH(
11742 "------------------------------"
11743 " Pan Scan Frame Num: %u\n"
11744 " Rectangle x: %d\n"
11745 " Rectangle y: %d\n"
11746 " Rectangle dx: %d\n"
11747 " Rectangle dy: %d",
11748 (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y,
11749 (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy);
11750 }
11751
11752 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
11753 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
11754 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
11755 DEBUG_PRINT_HIGH(
11756 "------------------ Framepack Format ----------\n"
11757 " id: %u \n"
11758 " cancel_flag: %u \n"
11759 " type: %u \n"
11760 " quincunx_sampling_flagFormat: %u \n"
11761 " content_interpretation_type: %u \n"
11762 " spatial_flipping_flag: %u \n"
11763 " frame0_flipped_flag: %u \n"
11764 " field_views_flag: %u \n"
11765 " current_frame_is_frame0_flag: %u \n"
11766 " frame0_self_contained_flag: %u \n"
11767 " frame1_self_contained_flag: %u \n"
11768 " frame0_grid_position_x: %u \n"
11769 " frame0_grid_position_y: %u \n"
11770 " frame1_grid_position_x: %u \n"
11771 " frame1_grid_position_y: %u \n"
11772 " reserved_byte: %u \n"
11773 " repetition_period: %u \n"
11774 " extension_flag: %u \n"
11775 "================== End of Framepack ===========",
11776 (unsigned int)framepack->id,
11777 (unsigned int)framepack->cancel_flag,
11778 (unsigned int)framepack->type,
11779 (unsigned int)framepack->quincunx_sampling_flag,
11780 (unsigned int)framepack->content_interpretation_type,
11781 (unsigned int)framepack->spatial_flipping_flag,
11782 (unsigned int)framepack->frame0_flipped_flag,
11783 (unsigned int)framepack->field_views_flag,
11784 (unsigned int)framepack->current_frame_is_frame0_flag,
11785 (unsigned int)framepack->frame0_self_contained_flag,
11786 (unsigned int)framepack->frame1_self_contained_flag,
11787 (unsigned int)framepack->frame0_grid_position_x,
11788 (unsigned int)framepack->frame0_grid_position_y,
11789 (unsigned int)framepack->frame1_grid_position_x,
11790 (unsigned int)framepack->frame1_grid_position_y,
11791 (unsigned int)framepack->reserved_byte,
11792 (unsigned int)framepack->repetition_period,
11793 (unsigned int)framepack->extension_flag);
11794 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
11795 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
11796 DEBUG_PRINT_HIGH(
11797 "---- QP (Frame quantization parameter) ----\n"
11798 " Frame QP: %u \n"
11799 " Sum of Frame QP: %u \n"
11800 " Sum of Skipped QP: %u \n"
11801 " Num Skipped Blocks: %u \n"
11802 " Total Blocks: %u \n"
11803 "================ End of QP ================\n",
11804 (unsigned int)qp->nQP,(unsigned int)qp->nQPSum,
11805 (unsigned int)qp->nSkipQPSum,(unsigned int)qp->nSkipNumBlocks,
11806 (unsigned int)qp->nTotalNumBlocks);
11807 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
11808 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data;
11809 DEBUG_PRINT_HIGH(
11810 "--------- Input bits information --------\n"
11811 " Header bits: %u \n"
11812 " Frame bits: %u \n"
11813 "===== End of Input bits information =====\n",
11814 (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits);
11815 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
11816 OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data;
11817 OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
11818 OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
11819 OMX_U32 i = 0;
11820 DEBUG_PRINT_HIGH(
11821 "-------------- Userdata -------------\n"
11822 " Stream userdata type: %u\n"
11823 " userdata size: %u\n"
11824 " STREAM_USERDATA:",
11825 (unsigned int)userdata->type, (unsigned int)userdata_size);
11826 for (i = 0; i < userdata_size; i+=4) {
11827 DEBUG_PRINT_HIGH(" %x %x %x %x",
11828 data_ptr[i], data_ptr[i+1],
11829 data_ptr[i+2], data_ptr[i+3]);
11830 }
11831 DEBUG_PRINT_HIGH(
11832 "=========== End of Userdata ===========");
11833 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI) {
11834 OMX_QCOM_EXTRADATA_VQZIPSEI *vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
11835 DEBUG_PRINT_HIGH(
11836 "-------------- VQZip -------------\n"
11837 " Size: %u\n",
11838 (unsigned int)vq->nSize);
11839 DEBUG_PRINT_HIGH( "=========== End of VQZip ===========");
11840 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataOutputCropInfo) {
11841 OMX_QCOM_OUTPUT_CROP *outputcrop_info = (OMX_QCOM_OUTPUT_CROP*)(void *)extra->data;
11842 DEBUG_PRINT_HIGH(
11843 "------------------ output crop ----------\n"
11844 " left: %u \n"
11845 " top: %u \n"
11846 " display_width: %u \n"
11847 " display_height: %u \n"
11848 " width: %u \n"
11849 " height: %u \n"
11850 " frame_num: %u \n"
11851 " bit_depth_y: %u \n"
11852 " bit_depth_c: %u \n",
11853 (unsigned int)outputcrop_info->left,
11854 (unsigned int)outputcrop_info->top,
11855 (unsigned int)outputcrop_info->display_width,
11856 (unsigned int)outputcrop_info->display_height,
11857 (unsigned int)outputcrop_info->width,
11858 (unsigned int)outputcrop_info->height,
11859 (unsigned int)outputcrop_info->frame_num,
11860 (unsigned int)outputcrop_info->bit_depth_y,
11861 (unsigned int)outputcrop_info->bit_depth_c);
11862 for(unsigned int m=0; m<outputcrop_info->misr_info[0].misr_set; m++) {
11863 DEBUG_PRINT_HIGH(
11864 " top field: misr_dpb_luma(%d): %u \n"
11865 " top field: misr_dpb_chroma(%d): %u \n"
11866 " top field: misr_opb_luma(%d): %u \n"
11867 " top field: misr_opb_chroma(%d): %u \n",
11868 m, (unsigned int)outputcrop_info->misr_info[0].misr_dpb_luma[m],
11869 m, (unsigned int)outputcrop_info->misr_info[0].misr_dpb_chroma[m],
11870 m, (unsigned int)outputcrop_info->misr_info[0].misr_opb_luma[m],
11871 m, (unsigned int)outputcrop_info->misr_info[0].misr_opb_chroma[m]);
11872 }
11873 for(unsigned int m=0; m<outputcrop_info->misr_info[1].misr_set; m++) {
11874 DEBUG_PRINT_HIGH(
11875 " bottom field: misr_dpb_luma(%d): %u \n"
11876 "bottom field: misr_dpb_chroma(%d): %u \n"
11877 " bottom field: misr_opb_luma(%d): %u \n"
11878 "bottom field: misr_opb_chroma(%d): %u \n",
11879 m, (unsigned int)outputcrop_info->misr_info[1].misr_dpb_luma[m],
11880 m, (unsigned int)outputcrop_info->misr_info[1].misr_dpb_chroma[m],
11881 m, (unsigned int)outputcrop_info->misr_info[1].misr_opb_luma[m],
11882 m, (unsigned int)outputcrop_info->misr_info[1].misr_opb_chroma[m]);
11883 }
11884 DEBUG_PRINT_HIGH("================== End of output crop ===========");
11885 } else if (extra->eType == OMX_ExtraDataNone) {
11886 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
11887 } else {
11888 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
11889 }
11890 }
11891
append_interlace_extradata(OMX_OTHER_EXTRADATATYPE * extra,OMX_U32 interlaced_format_type)11892 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
11893 OMX_U32 interlaced_format_type)
11894 {
11895 OMX_STREAMINTERLACEFORMAT *interlace_format;
11896
11897 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
11898 return;
11899 }
11900 if (!extra) {
11901 DEBUG_PRINT_ERROR("Error: append_interlace_extradata - invalid input");
11902 return;
11903 }
11904 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
11905 extra->nVersion.nVersion = OMX_SPEC_VERSION;
11906 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
11907 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
11908 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
11909 interlace_format = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
11910 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
11911 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
11912 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
11913
11914 if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) {
11915 interlace_format->bInterlaceFormat = OMX_FALSE;
11916 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
11917 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
11918 } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) {
11919 interlace_format->bInterlaceFormat = OMX_TRUE;
11920 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
11921 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
11922 } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) {
11923 interlace_format->bInterlaceFormat = OMX_TRUE;
11924 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
11925 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
11926 } else if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_TOPFIELDFIRST) {
11927 interlace_format->bInterlaceFormat = OMX_TRUE;
11928 interlace_format->nInterlaceFormats = OMX_InterlaceFrameTopFieldFirst;
11929 drv_ctx.interlace = VDEC_InterlaceFrameTopFieldFirst;
11930 } else if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_BOTTOMFIELDFIRST) {
11931 interlace_format->bInterlaceFormat = OMX_TRUE;
11932 interlace_format->nInterlaceFormats = OMX_InterlaceFrameBottomFieldFirst;
11933 drv_ctx.interlace = VDEC_InterlaceFrameBottomFieldFirst;
11934 } else {
11935 //default case - set to progressive
11936 interlace_format->bInterlaceFormat = OMX_FALSE;
11937 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
11938 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
11939 }
11940 print_debug_extradata(extra);
11941 }
11942
append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE * extra)11943 void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra)
11944 {
11945 OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension;
11946 if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) {
11947 return;
11948 }
11949 extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE;
11950 extra->nVersion.nVersion = OMX_SPEC_VERSION;
11951 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
11952 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension;
11953 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION);
11954 frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data;
11955 frame_dimension->nDecWidth = rectangle.nLeft;
11956 frame_dimension->nDecHeight = rectangle.nTop;
11957 frame_dimension->nActualWidth = rectangle.nWidth;
11958 frame_dimension->nActualHeight = rectangle.nHeight;
11959 }
11960
fill_aspect_ratio_info(struct vdec_aspectratioinfo * aspect_ratio_info,OMX_QCOM_EXTRADATA_FRAMEINFO * frame_info)11961 void omx_vdec::fill_aspect_ratio_info(
11962 struct vdec_aspectratioinfo *aspect_ratio_info,
11963 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
11964 {
11965 m_extradata = frame_info;
11966 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
11967 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
11968 DEBUG_PRINT_LOW("aspectRatioX %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX,
11969 (unsigned int)m_extradata->aspectRatio.aspectRatioY);
11970 }
11971
append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE * extra,OMX_U32 num_conceal_mb,OMX_U32 recovery_sei_flag,OMX_U32 picture_type,OMX_U32 frame_rate,OMX_TICKS time_stamp,struct msm_vidc_panscan_window_payload * panscan_payload,struct vdec_aspectratioinfo * aspect_ratio_info)11972 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
11973 OMX_U32 num_conceal_mb, OMX_U32 recovery_sei_flag, OMX_U32 picture_type, OMX_U32 frame_rate,
11974 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
11975 struct vdec_aspectratioinfo *aspect_ratio_info)
11976 {
11977 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
11978 struct msm_vidc_panscan_window *panscan_window;
11979 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
11980 return;
11981 }
11982 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
11983 extra->nVersion.nVersion = OMX_SPEC_VERSION;
11984 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
11985 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
11986 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
11987 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
11988 switch (picture_type) {
11989 case PICTURE_TYPE_I:
11990 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
11991 break;
11992 case PICTURE_TYPE_P:
11993 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
11994 break;
11995 case PICTURE_TYPE_B:
11996 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
11997 break;
11998 default:
11999 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
12000 }
12001 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
12002 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
12003 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
12004 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
12005 else if (drv_ctx.interlace == VDEC_InterlaceFrameTopFieldFirst)
12006 frame_info->interlaceType = OMX_QCOM_InterlaceFrameTopFieldFirst;
12007 else if (drv_ctx.interlace == VDEC_InterlaceFrameBottomFieldFirst)
12008 frame_info->interlaceType = OMX_QCOM_InterlaceFrameBottomFieldFirst;
12009 else
12010 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
12011 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
12012 frame_info->nConcealedMacroblocks = num_conceal_mb;
12013 frame_info->nRecoverySeiFlag = recovery_sei_flag;
12014 frame_info->nFrameRate = frame_rate;
12015 frame_info->nTimeStamp = time_stamp;
12016 frame_info->panScan.numWindows = 0;
12017 if (output_capability == V4L2_PIX_FMT_MPEG2) {
12018 if (m_disp_hor_size && m_disp_vert_size) {
12019 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
12020 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
12021 } else {
12022 frame_info->displayAspectRatio.displayHorizontalSize = 0;
12023 frame_info->displayAspectRatio.displayVerticalSize = 0;
12024 }
12025 }
12026
12027 if (panscan_payload) {
12028 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
12029 panscan_window = &panscan_payload->wnd[0];
12030 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
12031 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
12032 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
12033 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
12034 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
12035 panscan_window++;
12036 }
12037 }
12038 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
12039 print_debug_extradata(extra);
12040 }
12041
append_portdef_extradata(OMX_OTHER_EXTRADATATYPE * extra)12042 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
12043 {
12044 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
12045 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
12046 extra->nVersion.nVersion = OMX_SPEC_VERSION;
12047 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12048 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
12049 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
12050 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)(void *)extra->data;
12051 *portDefn = m_port_def;
12052 DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u "
12053 "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight,
12054 (unsigned int)portDefn->format.video.nFrameWidth,
12055 (unsigned int)portDefn->format.video.nStride,
12056 (unsigned int)portDefn->format.video.nSliceHeight);
12057 }
12058
append_outputcrop_extradata(OMX_OTHER_EXTRADATATYPE * extra,struct msm_vidc_output_crop_payload * output_crop_payload)12059 void omx_vdec::append_outputcrop_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12060 struct msm_vidc_output_crop_payload *output_crop_payload) {
12061 extra->nSize = OMX_OUTPUTCROP_EXTRADATA_SIZE;
12062 extra->nVersion.nVersion = OMX_SPEC_VERSION;
12063 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12064 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataOutputCropInfo;
12065 extra->nDataSize = sizeof(OMX_QCOM_OUTPUT_CROP);
12066 memcpy(extra->data, output_crop_payload, extra->nDataSize);
12067
12068 print_debug_extradata(extra);
12069 }
12070
append_framepack_extradata(OMX_OTHER_EXTRADATATYPE * extra,struct msm_vidc_s3d_frame_packing_payload * s3d_frame_packing_payload)12071 void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12072 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
12073 {
12074 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
12075 if (18 * sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
12076 DEBUG_PRINT_ERROR("frame packing size mismatch");
12077 return;
12078 }
12079 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
12080 extra->nVersion.nVersion = OMX_SPEC_VERSION;
12081 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12082 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
12083 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
12084 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
12085 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
12086 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
12087 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12088 memcpy(&framepack->id, s3d_frame_packing_payload,
12089 sizeof(struct msm_vidc_s3d_frame_packing_payload));
12090 memcpy(&m_frame_pack_arrangement, framepack,
12091 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
12092 print_debug_extradata(extra);
12093 }
12094
append_qp_extradata(OMX_OTHER_EXTRADATATYPE * extra,struct msm_vidc_frame_qp_payload * qp_payload)12095 void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12096 struct msm_vidc_frame_qp_payload *qp_payload)
12097 {
12098 OMX_QCOM_EXTRADATA_QP * qp = NULL;
12099 if (!qp_payload) {
12100 DEBUG_PRINT_ERROR("QP payload is NULL");
12101 return;
12102 }
12103 extra->nSize = OMX_QP_EXTRADATA_SIZE;
12104 extra->nVersion.nVersion = OMX_SPEC_VERSION;
12105 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12106 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
12107 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
12108 qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
12109 qp->nQP = qp_payload->frame_qp;
12110 qp->nQPSum = qp_payload->qp_sum;
12111 qp->nSkipQPSum = qp_payload->skip_qp_sum;
12112 qp->nSkipNumBlocks = qp_payload->skip_num_blocks;
12113 qp->nTotalNumBlocks = qp_payload->total_num_blocks;
12114 print_debug_extradata(extra);
12115 }
12116
append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE * extra,struct msm_vidc_frame_bits_info_payload * bits_payload)12117 void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12118 struct msm_vidc_frame_bits_info_payload *bits_payload)
12119 {
12120 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
12121 if (!bits_payload) {
12122 DEBUG_PRINT_ERROR("bits info payload is NULL");
12123 return;
12124 }
12125 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
12126 extra->nVersion.nVersion = OMX_SPEC_VERSION;
12127 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12128 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
12129 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
12130 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data;
12131 bits->frame_bits = bits_payload->frame_bits;
12132 bits->header_bits = bits_payload->header_bits;
12133 print_debug_extradata(extra);
12134 }
12135
append_user_extradata(OMX_OTHER_EXTRADATATYPE * extra,OMX_OTHER_EXTRADATATYPE * p_user)12136 void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
12137 OMX_OTHER_EXTRADATATYPE *p_user)
12138 {
12139 int userdata_size = 0;
12140 struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
12141 userdata_payload =
12142 (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data;
12143 userdata_size = p_user->nDataSize;
12144 extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size;
12145 extra->nVersion.nVersion = OMX_SPEC_VERSION;
12146 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
12147 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
12148 extra->nDataSize = userdata_size;
12149 if (extra->nDataSize && (p_user->nDataSize >= extra->nDataSize))
12150 memcpy(extra->data, p_user->data, extra->nDataSize);
12151 print_debug_extradata(extra);
12152 }
12153
append_terminator_extradata(OMX_OTHER_EXTRADATATYPE * extra)12154 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
12155 {
12156 if (!client_extradata) {
12157 return;
12158 }
12159 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
12160 extra->nVersion.nVersion = OMX_SPEC_VERSION;
12161 extra->eType = OMX_ExtraDataNone;
12162 extra->nDataSize = 0;
12163 extra->data[0] = 0;
12164
12165 print_debug_extradata(extra);
12166 }
12167
allocate_desc_buffer(OMX_U32 index)12168 OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
12169 {
12170 OMX_ERRORTYPE eRet = OMX_ErrorNone;
12171 if (index >= drv_ctx.ip_buf.actualcount) {
12172 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
12173 return OMX_ErrorInsufficientResources;
12174 }
12175 if (m_desc_buffer_ptr == NULL) {
12176 m_desc_buffer_ptr = (desc_buffer_hdr*) \
12177 calloc( (sizeof(desc_buffer_hdr)),
12178 drv_ctx.ip_buf.actualcount);
12179 if (m_desc_buffer_ptr == NULL) {
12180 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
12181 return OMX_ErrorInsufficientResources;
12182 }
12183 }
12184
12185 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
12186 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
12187 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
12188 return OMX_ErrorInsufficientResources;
12189 }
12190
12191 return eRet;
12192 }
12193
insert_demux_addr_offset(OMX_U32 address_offset)12194 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
12195 {
12196 DEBUG_PRINT_LOW("Inserting address offset (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)m_demux_entries);
12197 if (m_demux_entries < 8192) {
12198 m_demux_offsets[m_demux_entries++] = address_offset;
12199 }
12200 return;
12201 }
12202
extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE * buf_hdr)12203 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
12204 {
12205 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
12206 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
12207 OMX_U32 index = 0;
12208
12209 m_demux_entries = 0;
12210
12211 while (index < bytes_to_parse) {
12212 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
12213 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
12214 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
12215 (buf[index+2] == 0x01)) ) {
12216 //Found start code, insert address offset
12217 insert_demux_addr_offset(index);
12218 if (buf[index+2] == 0x01) // 3 byte start code
12219 index += 3;
12220 else //4 byte start code
12221 index += 4;
12222 } else
12223 index++;
12224 }
12225 DEBUG_PRINT_LOW("Extracted (%u) demux entry offsets", (unsigned int)m_demux_entries);
12226 return;
12227 }
12228
handle_demux_data(OMX_BUFFERHEADERTYPE * p_buf_hdr)12229 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
12230 {
12231 //fix this, handle 3 byte start code, vc1 terminator entry
12232 OMX_U8 *p_demux_data = NULL;
12233 OMX_U32 desc_data = 0;
12234 OMX_U32 start_addr = 0;
12235 OMX_U32 nal_size = 0;
12236 OMX_U32 suffix_byte = 0;
12237 OMX_U32 demux_index = 0;
12238 OMX_U32 buffer_index = 0;
12239
12240 if (m_desc_buffer_ptr == NULL) {
12241 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
12242 return OMX_ErrorBadParameter;
12243 }
12244
12245 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
12246 if (buffer_index > drv_ctx.ip_buf.actualcount) {
12247 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%u)", (unsigned int)buffer_index);
12248 return OMX_ErrorBadParameter;
12249 }
12250
12251 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
12252
12253 if ( ((OMX_U8*)p_demux_data == NULL) ||
12254 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
12255 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
12256 return OMX_ErrorBadParameter;
12257 } else {
12258 for (; demux_index < m_demux_entries; demux_index++) {
12259 desc_data = 0;
12260 start_addr = m_demux_offsets[demux_index];
12261 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
12262 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
12263 } else {
12264 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
12265 }
12266 if (demux_index < (m_demux_entries - 1)) {
12267 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
12268 } else {
12269 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
12270 }
12271 DEBUG_PRINT_LOW("Start_addr(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)",
12272 (unsigned int)start_addr,
12273 (unsigned int)suffix_byte,
12274 (unsigned int)nal_size,
12275 (unsigned int)demux_index);
12276 desc_data = (start_addr >> 3) << 1;
12277 desc_data |= (start_addr & 7) << 21;
12278 desc_data |= suffix_byte << 24;
12279
12280 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
12281 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
12282 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
12283 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
12284
12285 p_demux_data += 16;
12286 }
12287 //Add zero word to indicate end of descriptors
12288 memset(p_demux_data, 0, sizeof(OMX_U32));
12289
12290 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
12291 DEBUG_PRINT_LOW("desc table data size=%u", (unsigned int)m_desc_buffer_ptr[buffer_index].desc_data_size);
12292 }
12293 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
12294 m_demux_entries = 0;
12295 DEBUG_PRINT_LOW("Demux table complete!");
12296 return OMX_ErrorNone;
12297 }
12298
enable_color_conversion(bool enable)12299 void omx_vdec::allocate_color_convert_buf::enable_color_conversion(bool enable) {
12300 if (!omx) {
12301 DEBUG_PRINT_HIGH("Invalid omx_vdec");
12302 return;
12303 }
12304
12305 if (!omx->in_reconfig)
12306 enabled = enable;
12307
12308 omx->c2d_enable_pending = enable;
12309 }
12310
allocate_color_convert_buf()12311 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
12312 {
12313 enabled = false;
12314 client_buffers_disabled = false;
12315 omx = NULL;
12316 init_members();
12317 ColorFormat = OMX_COLOR_FormatMax;
12318 dest_format = YCbCr420P;
12319 m_c2d_width = 0;
12320 m_c2d_height = 0;
12321
12322 mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12][-1] =
12323 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
12324 mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12][VDEC_CODECTYPE_MVC] =
12325 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
12326 mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12_UBWC][-1] =
12327 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
12328 mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_NV12_TP10_UBWC][-1] =
12329 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed;
12330 mMapOutput2DriverColorFormat[VDEC_YUV_FORMAT_P010_VENUS][-1] =
12331 QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus;
12332
12333 mMapOutput2Convert.insert( {
12334 {VDEC_YUV_FORMAT_NV12, NV12_128m},
12335 {VDEC_YUV_FORMAT_NV12_UBWC, NV12_UBWC},
12336 {VDEC_YUV_FORMAT_NV12_TP10_UBWC, TP10_UBWC},
12337 {VDEC_YUV_FORMAT_P010_VENUS, YCbCr420_VENUS_P010},
12338 });
12339 }
12340
set_vdec_client(void * client)12341 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
12342 {
12343 omx = reinterpret_cast<omx_vdec*>(client);
12344 }
12345
init_members()12346 void omx_vdec::allocate_color_convert_buf::init_members()
12347 {
12348 allocated_count = 0;
12349 buffer_size_req = 0;
12350 buffer_alignment_req = 0;
12351 m_c2d_width = m_c2d_height = 0;
12352 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
12353 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
12354 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
12355 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
12356 #ifdef USE_ION
12357 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
12358 #endif
12359 for (int i = 0; i < MAX_COUNT; i++)
12360 pmem_fd[i] = -1;
12361 }
12362
update_buffer_req()12363 bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
12364 {
12365 bool status = true;
12366 unsigned int src_size = 0, destination_size = 0;
12367 unsigned int height, width;
12368 struct v4l2_format fmt;
12369 OMX_COLOR_FORMATTYPE drv_color_format;
12370
12371 if (!omx) {
12372 DEBUG_PRINT_ERROR("Invalid client in color convert");
12373 return false;
12374 }
12375 if (!enabled) {
12376 DEBUG_PRINT_HIGH("No color conversion required");
12377 return true;
12378 }
12379 pthread_mutex_lock(&omx->c_lock);
12380
12381 ColorSubMapping::const_iterator
12382 found = mMapOutput2Convert.find(omx->drv_ctx.output_format);
12383 if (found == mMapOutput2Convert.end()) {
12384 DEBUG_PRINT_HIGH("%s: Could not find the color conversion "
12385 "mapping for %#X. Setting to default NV12",
12386 __func__, omx->drv_ctx.output_format);
12387 src_format = NV12_128m;
12388 } else {
12389 src_format = (ColorConvertFormat) found->second;;
12390 }
12391
12392 memset(&fmt, 0x0, sizeof(struct v4l2_format));
12393 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
12394 fmt.fmt.pix_mp.pixelformat = omx->capture_capability;
12395 ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
12396 width = fmt.fmt.pix_mp.width;
12397 height = fmt.fmt.pix_mp.height;
12398
12399 bool resolution_upgrade = (height > m_c2d_height ||
12400 width > m_c2d_width);
12401 bool is_interlaced = omx->m_progressive != MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
12402 if (resolution_upgrade) {
12403 // resolution upgraded ? ensure we are yet to allocate;
12404 // failing which, c2d buffers will never be reallocated and bad things will happen
12405 if (allocated_count > 0) {
12406 DEBUG_PRINT_ERROR("Cannot change C2D buffer requirements with %d active allocations",
12407 allocated_count);
12408 status = false;
12409 }
12410 }
12411
12412 if (status != false) {
12413 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
12414 (ColorFormat != OMX_COLOR_FormatYUV420Planar &&
12415 ColorFormat != OMX_COLOR_FormatYUV420SemiPlanar &&
12416 ColorFormat != (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)) {
12417 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
12418 status = false;
12419 } else {
12420 ColorSubMapping::const_iterator
12421 found = mMapOutput2Convert.find(
12422 omx->drv_ctx.output_format);
12423 if (found == mMapOutput2Convert.end()) {
12424 src_format = NV12_128m;
12425 } else {
12426 src_format = (ColorConvertFormat) found->second;;
12427 }
12428
12429 DEBUG_PRINT_INFO("C2D: Set Resolution, Interlace(%s) Conversion(%#X -> %#X)"
12430 " src(%dX%d) dest(%dX%d)",
12431 (omx->m_progressive != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) ? "true": "false",
12432 src_format, dest_format, width,
12433 omx->m_progressive !=
12434 MSM_VIDC_PIC_STRUCT_PROGRESSIVE?(height+1)/2 : height,
12435 width, height);
12436 status = c2dcc.setResolution(width,
12437 omx->m_progressive !=
12438 MSM_VIDC_PIC_STRUCT_PROGRESSIVE?
12439 (height+1)/2 : height,
12440 width, height,
12441 src_format, dest_format,
12442 0,0);
12443 if (status) {
12444 src_size = c2dcc.getBuffSize(C2D_INPUT);
12445 destination_size = c2dcc.getBuffSize(C2D_OUTPUT);
12446
12447 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
12448 !destination_size) {
12449 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
12450 "driver size %u destination size %d",
12451 src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size,
12452 destination_size);
12453 buffer_size_req = 0;
12454 // TODO: make this fatal. Driver is not supposed to quote size
12455 // smaller than what C2D needs !!
12456 } else {
12457 buffer_size_req = destination_size;
12458 m_c2d_height = height;
12459 m_c2d_width = width;
12460 }
12461 }
12462 }
12463 }
12464 pthread_mutex_unlock(&omx->c_lock);
12465 return status;
12466 }
12467
set_color_format(OMX_COLOR_FORMATTYPE dest_color_format)12468 bool omx_vdec::allocate_color_convert_buf::set_color_format(
12469 OMX_COLOR_FORMATTYPE dest_color_format)
12470 {
12471 bool status = true, drv_colorformat_c2d_enable = false;
12472 bool dest_color_format_c2d_enable = false;
12473 OMX_COLOR_FORMATTYPE drv_color_format = OMX_COLOR_FormatUnused;
12474 if (!omx) {
12475 DEBUG_PRINT_ERROR("Invalid client in color convert");
12476 return false;
12477 }
12478 pthread_mutex_lock(&omx->c_lock);
12479 status = get_color_format (drv_color_format);
12480
12481 drv_colorformat_c2d_enable = (drv_color_format != dest_color_format) &&
12482 (drv_color_format != (OMX_COLOR_FORMATTYPE)
12483 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView) &&
12484 (drv_color_format != (OMX_COLOR_FORMATTYPE)
12485 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed) &&
12486 (drv_color_format != (OMX_COLOR_FORMATTYPE)
12487 QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus);
12488
12489 dest_color_format_c2d_enable = (dest_color_format != (OMX_COLOR_FORMATTYPE)
12490 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) &&
12491 (dest_color_format != (OMX_COLOR_FORMATTYPE)
12492 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed);
12493
12494 if (status && drv_colorformat_c2d_enable && dest_color_format_c2d_enable) {
12495 DEBUG_PRINT_LOW("Enabling C2D");
12496 if (dest_color_format == OMX_COLOR_FormatYUV420Planar ||
12497 dest_color_format == OMX_COLOR_FormatYUV420SemiPlanar ||
12498 (omx->m_progressive != MSM_VIDC_PIC_STRUCT_PROGRESSIVE &&
12499 dest_color_format == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)) {
12500 ColorFormat = dest_color_format;
12501 if (dest_color_format == OMX_COLOR_FormatYUV420Planar) {
12502 dest_format = YCbCr420P;
12503 } else if( dest_color_format == OMX_COLOR_FormatYUV420SemiPlanar) {
12504 dest_format = YCbCr420SP;
12505 } else {
12506 dest_format = NV12_128m;
12507 }
12508 enable_color_conversion(true);
12509 } else {
12510 DEBUG_PRINT_ERROR("Unsupported output color format for c2d (%d)",
12511 dest_color_format);
12512 status = false;
12513 enable_color_conversion(false);
12514 }
12515 } else {
12516 enable_color_conversion(false);
12517 }
12518 pthread_mutex_unlock(&omx->c_lock);
12519 return status;
12520 }
12521
get_il_buf_hdr(OMX_BUFFERHEADERTYPE * bufadd)12522 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
12523 (OMX_BUFFERHEADERTYPE *bufadd)
12524 {
12525 if (!omx) {
12526 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
12527 return NULL;
12528 }
12529 if (!is_color_conversion_enabled())
12530 return bufadd;
12531
12532 OMX_BUFFERHEADERTYPE *omx_base_address =
12533 is_color_conversion_enabled()?
12534 omx->m_intermediate_out_mem_ptr:omx->m_out_mem_ptr;
12535
12536 unsigned index = 0;
12537 index = bufadd - omx_base_address;
12538 if (index < omx->drv_ctx.op_buf.actualcount) {
12539 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
12540 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
12541
12542 omx->m_out_mem_ptr[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
12543 omx->m_out_mem_ptr[index].nTimeStamp = bufadd->nTimeStamp;
12544 bool status = false;
12545 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
12546 pthread_mutex_lock(&omx->c_lock);
12547 omx->do_cache_operations(omx->drv_ctx.op_intermediate_buf_ion_info[index].data_fd);
12548
12549 DEBUG_PRINT_INFO("C2D: Start color convertion");
12550 status = c2dcc.convertC2D(
12551 omx->drv_ctx.ptr_intermediate_outputbuffer[index].pmem_fd,
12552 bufadd->pBuffer, bufadd->pBuffer,
12553 omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
12554 omx->m_out_mem_ptr[index].pBuffer,
12555 omx->m_out_mem_ptr[index].pBuffer);
12556 omx->do_cache_operations(omx->drv_ctx.op_intermediate_buf_ion_info[index].data_fd);
12557 if (!status) {
12558 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
12559 m_out_mem_ptr_client[index].nFilledLen = 0;
12560 omx->m_out_mem_ptr[index].nFilledLen = 0;
12561 pthread_mutex_unlock(&omx->c_lock);
12562 return &omx->m_out_mem_ptr[index];
12563 } else {
12564 unsigned int filledLen = 0;
12565 c2dcc.getBuffFilledLen(C2D_OUTPUT, filledLen);
12566 m_out_mem_ptr_client[index].nFilledLen = filledLen;
12567 omx->m_out_mem_ptr[index].nFilledLen = filledLen;
12568 }
12569 pthread_mutex_unlock(&omx->c_lock);
12570 } else {
12571 m_out_mem_ptr_client[index].nFilledLen = 0;
12572 omx->m_out_mem_ptr[index].nFilledLen = 0;
12573 }
12574 return &omx->m_out_mem_ptr[index];
12575 }
12576 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
12577 return NULL;
12578 }
12579
get_buffer_req(unsigned int & buffer_size)12580 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
12581 (unsigned int &buffer_size)
12582 {
12583 bool status = true;
12584 pthread_mutex_lock(&omx->c_lock);
12585 /* Whenever port mode is set to kPortModeDynamicANWBuffer, Video Frameworks
12586 always uses VideoNativeMetadata and OMX receives buffer type as
12587 grallocsource via storeMetaDataInBuffers_l API. The buffer_size
12588 will be communicated to frameworks via IndexParamPortdefinition. */
12589 if (!enabled)
12590 buffer_size = omx->dynamic_buf_mode ? sizeof(struct VideoNativeMetadata) :
12591 omx->drv_ctx.op_buf.buffer_size;
12592 else {
12593 buffer_size = c2dcc.getBuffSize(C2D_OUTPUT);
12594 }
12595 pthread_mutex_unlock(&omx->c_lock);
12596 return status;
12597 }
12598
set_buffer_req(OMX_U32 buffer_size,OMX_U32 actual_count)12599 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::set_buffer_req(
12600 OMX_U32 buffer_size, OMX_U32 actual_count)
12601 {
12602 OMX_U32 expectedSize = is_color_conversion_enabled() ? buffer_size_req : omx->dynamic_buf_mode ?
12603 sizeof(struct VideoDecoderOutputMetaData) : omx->drv_ctx.op_buf.buffer_size;
12604 if (buffer_size < expectedSize) {
12605 DEBUG_PRINT_ERROR("OP Requirements: Client size(%u) insufficient v/s requested(%u)",
12606 buffer_size, expectedSize);
12607 return OMX_ErrorBadParameter;
12608 }
12609 if (actual_count < omx->drv_ctx.op_buf.mincount) {
12610 DEBUG_PRINT_ERROR("OP Requirements: Client count(%u) insufficient v/s requested(%u)",
12611 actual_count, omx->drv_ctx.op_buf.mincount);
12612 return OMX_ErrorBadParameter;
12613 }
12614
12615 if (enabled) {
12616 // disallow changing buffer size/count while we have active allocated buffers
12617 if (allocated_count > 0) {
12618 DEBUG_PRINT_ERROR("Cannot change C2D buffer size from %u to %u with %d active allocations",
12619 buffer_size_req, buffer_size, allocated_count);
12620 return OMX_ErrorInvalidState;
12621 }
12622
12623 buffer_size_req = buffer_size;
12624 } else {
12625 if (buffer_size > omx->drv_ctx.op_buf.buffer_size) {
12626 omx->drv_ctx.op_buf.buffer_size = buffer_size;
12627 }
12628 }
12629
12630 omx->drv_ctx.op_buf.actualcount = actual_count;
12631 omx->drv_ctx.extradata_info.count = omx->drv_ctx.op_buf.actualcount;
12632 omx->drv_ctx.extradata_info.size = omx->drv_ctx.extradata_info.count *
12633 omx->drv_ctx.extradata_info.buffer_size;
12634 return omx->set_buffer_req(&(omx->drv_ctx.op_buf));
12635 }
12636
is_component_secure()12637 bool omx_vdec::is_component_secure()
12638 {
12639 return secure_mode;
12640 }
12641
get_color_format(OMX_COLOR_FORMATTYPE & dest_color_format)12642 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
12643 {
12644 bool status = true;
12645 if (!enabled) {
12646 for (auto& x: mMapOutput2DriverColorFormat) {
12647 DecColorMapping::const_iterator
12648 found = mMapOutput2DriverColorFormat.find(omx->drv_ctx.output_format);
12649 if (found == mMapOutput2DriverColorFormat.end()) {
12650 status = false;
12651 } else {
12652 ColorSubMapping::const_iterator
12653 subFound = found->second.find(omx->drv_ctx.decoder_format);
12654 if (subFound == found->second.end()) {
12655 dest_color_format = (OMX_COLOR_FORMATTYPE)
12656 found->second.find(-1)->second;
12657 } else {
12658 dest_color_format = (OMX_COLOR_FORMATTYPE) subFound->second;
12659 }
12660 }
12661 }
12662 } else {
12663 if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
12664 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
12665 ColorFormat == (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
12666 dest_color_format = ColorFormat;
12667 } else {
12668 status = false;
12669 }
12670 }
12671 return status;
12672 }
12673
send_codec_config()12674 void omx_vdec::send_codec_config() {
12675 if (codec_config_flag) {
12676 unsigned long p1 = 0; // Parameter - 1
12677 unsigned long p2 = 0; // Parameter - 2
12678 unsigned long ident = 0;
12679 pthread_mutex_lock(&m_lock);
12680 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
12681 while (m_etb_q.m_size) {
12682 m_etb_q.pop_entry(&p1,&p2,&ident);
12683 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
12684 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
12685 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
12686 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
12687 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
12688 omx_report_error();
12689 }
12690 } else {
12691 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
12692 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
12693 }
12694 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
12695 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
12696 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
12697 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
12698 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
12699 omx_report_error ();
12700 }
12701 } else {
12702 pending_input_buffers++;
12703 VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
12704 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
12705 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
12706 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
12707 }
12708 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
12709 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
12710 (OMX_BUFFERHEADERTYPE *)p1);
12711 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
12712 }
12713 }
12714 pthread_mutex_unlock(&m_lock);
12715 }
12716 }
12717
perf_control()12718 omx_vdec::perf_control::perf_control()
12719 {
12720 m_perf_control_enable = 0;
12721 m_perf_lib = NULL;
12722 m_perf_handle = 0;
12723 m_perf_lock_acquire = NULL;
12724 m_perf_lock_release = NULL;
12725 }
12726
~perf_control()12727 omx_vdec::perf_control::~perf_control()
12728 {
12729 if (!m_perf_control_enable)
12730 return;
12731
12732 if (m_perf_handle && m_perf_lock_release) {
12733 m_perf_lock_release(m_perf_handle);
12734 DEBUG_PRINT_LOW("perflock released");
12735 }
12736 if (m_perf_lib) {
12737 dlclose(m_perf_lib);
12738 }
12739 }
12740
perf_lock_acquire()12741 int omx_vdec::perf_control::perf_lock_acquire()
12742 {
12743 int arg[2];
12744 if (!m_perf_control_enable)
12745 return 0;
12746
12747 if (!m_perf_lib) {
12748 DEBUG_PRINT_ERROR("no perf control library");
12749 return -1;
12750 }
12751 if (!m_perf_lock_acquire) {
12752 DEBUG_PRINT_ERROR("NULL perflock acquire");
12753 return -1;
12754 }
12755 if (m_perf_handle) {
12756 DEBUG_PRINT_LOW("perflock already acquired");
12757 return 0;
12758 }
12759 DEBUG_PRINT_HIGH("perflock acquire");
12760 arg[0] = MPCTLV3_VIDEO_DECODE_PB_HINT;
12761 arg[1] = 1;
12762 m_perf_handle = m_perf_lock_acquire(0, 0, arg, sizeof(arg) / sizeof(int));
12763 if (m_perf_handle < 0) {
12764 DEBUG_PRINT_ERROR("perflock acquire failed with error %d", m_perf_handle);
12765 m_perf_handle = 0;
12766 return -1;
12767 }
12768 return 0;
12769 }
12770
perf_lock_release()12771 void omx_vdec::perf_control::perf_lock_release()
12772 {
12773 if (!m_perf_control_enable)
12774 return;
12775
12776 if (!m_perf_lib) {
12777 DEBUG_PRINT_ERROR("no perf control library");
12778 return;
12779 }
12780 if (!m_perf_lock_release) {
12781 DEBUG_PRINT_ERROR("NULL perflock release");
12782 return;
12783 }
12784 if (!m_perf_handle) {
12785 DEBUG_PRINT_LOW("perflock already released");
12786 return;
12787 }
12788 DEBUG_PRINT_HIGH("perflock release");
12789 m_perf_lock_release(m_perf_handle);
12790 m_perf_handle = 0;
12791 }
12792
load_perf_library()12793 bool omx_vdec::perf_control::load_perf_library()
12794 {
12795 char perf_lib_path[PROPERTY_VALUE_MAX] = {0};
12796
12797 if (!m_perf_control_enable) {
12798 DEBUG_PRINT_HIGH("perf control is not enabled");
12799 return false;
12800 }
12801 if (m_perf_lib) {
12802 DEBUG_PRINT_HIGH("perf lib already opened");
12803 return true;
12804 }
12805
12806 if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) {
12807 DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library");
12808 goto handle_err;
12809 }
12810
12811 if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) {
12812 DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror());
12813 goto handle_err;
12814 } else {
12815 m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq");
12816 if (m_perf_lock_acquire == NULL) {
12817 DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq");
12818 goto handle_err;
12819 }
12820 m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel");
12821 if (m_perf_lock_release == NULL) {
12822 DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel");
12823 goto handle_err;
12824 }
12825 }
12826 return true;
12827
12828 handle_err:
12829 if (m_perf_lib) {
12830 dlclose(m_perf_lib);
12831 }
12832 m_perf_lib = NULL;
12833 m_perf_lock_acquire = NULL;
12834 m_perf_lock_release = NULL;
12835 return false;
12836 }
12837
enable_adaptive_playback(unsigned long nMaxFrameWidth,unsigned long nMaxFrameHeight)12838 OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
12839 unsigned long nMaxFrameHeight)
12840 {
12841
12842 OMX_ERRORTYPE eRet = OMX_ErrorNone;
12843 int ret = 0;
12844 unsigned long min_res_buf_count = 0;
12845
12846 eRet = enable_smoothstreaming();
12847 if (eRet != OMX_ErrorNone) {
12848 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
12849 return eRet;
12850 }
12851
12852 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
12853 nMaxFrameWidth,
12854 nMaxFrameHeight);
12855 m_smoothstreaming_mode = true;
12856 m_smoothstreaming_width = nMaxFrameWidth;
12857 m_smoothstreaming_height = nMaxFrameHeight;
12858
12859 //Get upper limit buffer count for min supported resolution
12860 struct v4l2_format fmt;
12861 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
12862 fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
12863 fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
12864 fmt.fmt.pix_mp.pixelformat = output_capability;
12865
12866 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
12867 if (ret) {
12868 DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
12869 m_decoder_capability.min_height,
12870 m_decoder_capability.min_width);
12871 return OMX_ErrorUnsupportedSetting;
12872 }
12873
12874 eRet = get_buffer_req(&drv_ctx.op_buf);
12875 if (eRet != OMX_ErrorNone) {
12876 DEBUG_PRINT_ERROR("failed to get_buffer_req");
12877 return eRet;
12878 }
12879
12880 min_res_buf_count = drv_ctx.op_buf.mincount;
12881 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
12882 min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
12883
12884 m_extradata_info.output_crop_rect.nLeft = 0;
12885 m_extradata_info.output_crop_rect.nTop = 0;
12886 m_extradata_info.output_crop_rect.nWidth = m_smoothstreaming_width;
12887 m_extradata_info.output_crop_rect.nHeight = m_smoothstreaming_height;
12888
12889 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
12890 m_smoothstreaming_width, m_smoothstreaming_height);
12891
12892 //Get upper limit buffer size for max smooth streaming resolution set
12893 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
12894 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
12895 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
12896 fmt.fmt.pix_mp.pixelformat = output_capability;
12897 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
12898 if (ret) {
12899 DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
12900 return OMX_ErrorUnsupportedSetting;
12901 }
12902
12903 eRet = get_buffer_req(&drv_ctx.op_buf);
12904 if (eRet != OMX_ErrorNone) {
12905 DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
12906 return eRet;
12907 }
12908 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
12909 (unsigned int)drv_ctx.op_buf.buffer_size);
12910
12911 drv_ctx.op_buf.mincount = min_res_buf_count;
12912 drv_ctx.op_buf.actualcount = min_res_buf_count;
12913 drv_ctx.op_buf.buffer_size = drv_ctx.op_buf.buffer_size;
12914 eRet = set_buffer_req(&drv_ctx.op_buf);
12915 if (eRet != OMX_ErrorNone) {
12916 DEBUG_PRINT_ERROR("failed to set_buffer_req");
12917 return eRet;
12918 }
12919
12920 eRet = get_buffer_req(&drv_ctx.op_buf);
12921 if (eRet != OMX_ErrorNone) {
12922 DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
12923 return eRet;
12924 }
12925 DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
12926 drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size);
12927 return eRet;
12928 }
12929
12930 //static
describeColorFormat(OMX_PTR pParam)12931 OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
12932
12933 #ifndef FLEXYUV_SUPPORTED
12934 return OMX_ErrorUndefined;
12935 #else
12936
12937 if (pParam == NULL) {
12938 DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
12939 return OMX_ErrorBadParameter;
12940 }
12941
12942 DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
12943
12944 MediaImage *img = &(params->sMediaImage);
12945 switch(params->eColorFormat) {
12946 case static_cast <OMX_COLOR_FORMATTYPE> (QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m):
12947 {
12948 img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
12949 img->mNumPlanes = 3;
12950 // mWidth and mHeight represent the W x H of the largest plane
12951 // In our case, this happens to be the Stride x Scanlines of Y plane
12952 img->mWidth = params->nFrameWidth;
12953 img->mHeight = params->nFrameHeight;
12954 size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
12955 size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
12956 img->mBitDepth = 8;
12957 //Plane 0 (Y)
12958 img->mPlane[MediaImage::Y].mOffset = 0;
12959 img->mPlane[MediaImage::Y].mColInc = 1;
12960 img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
12961 img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
12962 img->mPlane[MediaImage::Y].mVertSubsampling = 1;
12963 //Plane 1 (U)
12964 img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
12965 img->mPlane[MediaImage::U].mColInc = 2; //interleaved UV
12966 img->mPlane[MediaImage::U].mRowInc =
12967 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
12968 img->mPlane[MediaImage::U].mHorizSubsampling = 2;
12969 img->mPlane[MediaImage::U].mVertSubsampling = 2;
12970 //Plane 2 (V)
12971 img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
12972 img->mPlane[MediaImage::V].mColInc = 2; //interleaved UV
12973 img->mPlane[MediaImage::V].mRowInc =
12974 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
12975 img->mPlane[MediaImage::V].mHorizSubsampling = 2;
12976 img->mPlane[MediaImage::V].mVertSubsampling = 2;
12977 break;
12978 }
12979
12980 case OMX_COLOR_FormatYUV420Planar:
12981 case OMX_COLOR_FormatYUV420SemiPlanar:
12982 // We need not describe the standard OMX linear formats as these are
12983 // understood by client. Fail this deliberately to let client fill-in
12984 return OMX_ErrorUnsupportedSetting;
12985
12986 default:
12987 // Rest all formats which are non-linear cannot be described
12988 DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
12989 img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
12990 return OMX_ErrorNone;
12991 };
12992
12993 DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
12994 DEBUG_PRINT_LOW(" FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
12995 DEBUG_PRINT_LOW(" YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
12996 for (size_t i = 0; i < img->mNumPlanes; ++i) {
12997 DEBUG_PRINT_LOW(" Plane[%zu] : offset=%d / xStep=%d / yStep = %d",
12998 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
12999 }
13000 return OMX_ErrorNone;
13001 #endif //FLEXYUV_SUPPORTED
13002 }
13003
prefetch_buffers(unsigned long prefetch_count,unsigned long prefetch_size,unsigned ioctl_code,unsigned ion_flag)13004 bool omx_vdec::prefetch_buffers(unsigned long prefetch_count,
13005 unsigned long prefetch_size, unsigned ioctl_code, unsigned ion_flag)
13006 {
13007 struct ion_prefetch_data prefetch_data;
13008 struct ion_prefetch_regions regions;
13009 __u64 sizes[prefetch_count];
13010 int rc, ion_fd = ion_open();
13011 if (ion_fd < 0) {
13012 DEBUG_PRINT_ERROR("%s: Ion fd open failed : %d", __func__, ion_fd);
13013 return false;
13014 }
13015
13016 DEBUG_PRINT_HIGH("%s: prefetch_count : %lu, prefetch_size : %lu, ioctl : %u",
13017 __func__, prefetch_count, prefetch_size, ioctl_code);
13018 for (uint32_t i = 0; i < prefetch_count; i++) {
13019 sizes[i] = prefetch_size;
13020 }
13021
13022 regions.nr_sizes = prefetch_count;
13023 #if TARGET_ION_ABI_VERSION >= 2
13024 regions.sizes = (__u64)sizes;
13025 #else
13026 regions.sizes = sizes;
13027 #endif
13028 regions.vmid = ion_flag;
13029
13030 prefetch_data.nr_regions = 1;
13031 #if TARGET_ION_ABI_VERSION >= 2
13032 prefetch_data.regions = (__u64)®ions;
13033 #else
13034 prefetch_data.regions = ®ions;
13035 #endif
13036 prefetch_data.heap_id = ION_HEAP(ION_SECURE_HEAP_ID);
13037
13038 rc = ioctl(ion_fd, ioctl_code, &prefetch_data);
13039 if (rc) {
13040 DEBUG_PRINT_ERROR("%s: Prefetch ioctl failed ioctl : %u, rc : %d, errno : %d",
13041 __func__, ioctl_code, rc, errno);
13042 rc = false;
13043 } else {
13044 rc = true;
13045 }
13046
13047 close(ion_fd);
13048 return rc;
13049 }
13050
13051 // No code beyond this !
13052
13053 // inline import of vendor-extensions implementation
13054 #include "omx_vdec_extensions.hpp"
13055