1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010 - 2020, 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
6 met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 --------------------------------------------------------------------------*/
29
30 /*============================================================================
31 O p e n M A X w r a p p e r s
32 O p e n M A X C o r e
33
34 This module contains the implementation of the OpenMAX core & component.
35
36 *//*========================================================================*/
37
38 //////////////////////////////////////////////////////////////////////////////
39 // Include Files
40 //////////////////////////////////////////////////////////////////////////////
41
42 #include "omx_vdec.h"
43
44 #define BUFFER_LOG_LOC "/data/vendor/media"
45
46 #ifdef _ANDROID_
47 extern "C" {
48 #include<utils/Log.h>
49 }
50 #endif//_ANDROID_
51
52 using namespace android;
53
54 /* ======================================================================
55 FUNCTION
56 omx_vdec::GetParameter
57
58 DESCRIPTION
59 OMX Get Parameter method implementation
60
61 PARAMETERS
62 <TBD>.
63
64 RETURN VALUE
65 Error None if successful.
66
67 ========================================================================== */
get_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_INOUT OMX_PTR paramData)68 OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
69 OMX_IN OMX_INDEXTYPE paramIndex,
70 OMX_INOUT OMX_PTR paramData)
71 {
72 (void) hComp;
73 OMX_ERRORTYPE eRet = OMX_ErrorNone;
74
75 DEBUG_PRINT_LOW("get_parameter:");
76 if (m_state == OMX_StateInvalid) {
77 DEBUG_PRINT_ERROR("Get Param in Invalid State");
78 return OMX_ErrorInvalidState;
79 }
80 if (paramData == NULL) {
81 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
82 return OMX_ErrorBadParameter;
83 }
84 switch ((unsigned long)paramIndex) {
85 case OMX_IndexParamPortDefinition: {
86 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
87 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
88 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
89 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
90
91 OMX_COLOR_FORMATTYPE drv_color_format;
92 bool status = false;
93
94 if (!client_buffers.is_color_conversion_enabled()) {
95 status = client_buffers.get_color_format(drv_color_format);
96 }
97
98 fix_drv_output_format();
99
100 if (status) {
101 if (!client_buffers.is_color_conversion_enabled()) {
102 client_buffers.set_client_buffers_disabled(true);
103 client_buffers.set_color_format(drv_color_format);
104 }
105 }
106
107 eRet = update_portdef(portDefn);
108 if (eRet == OMX_ErrorNone)
109 m_port_def = *portDefn;
110 break;
111 }
112 case OMX_IndexParamVideoInit: {
113 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
114 OMX_PORT_PARAM_TYPE *portParamType =
115 (OMX_PORT_PARAM_TYPE *) paramData;
116 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
117
118 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
119 portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
120 portParamType->nPorts = 2;
121 portParamType->nStartPortNumber = 0;
122 break;
123 }
124 case OMX_IndexParamVideoPortFormat: {
125 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
126 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
127 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
128 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
129
130 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
131 portFmt->nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
132
133 if (0 == portFmt->nPortIndex) {
134 if (0 == portFmt->nIndex) {
135 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
136 portFmt->eCompressionFormat = eCompressionFormat;
137 } else {
138 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
139 " NoMore compression formats");
140 eRet = OMX_ErrorNoMore;
141 }
142 } else if (1 == portFmt->nPortIndex) {
143 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
144
145 // Distinguish non-surface mode from normal playback use-case based on
146 // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
147 // For non-android, use the default list
148 // Also use default format-list if FLEXIBLE YUV is supported,
149 // as the client negotiates the standard color-format if it needs to
150 bool useNonSurfaceMode = false;
151 #if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED) && !defined(USE_GBM)
152 useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
153 #endif
154 portFmt->eColorFormat = useNonSurfaceMode ?
155 getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
156 getPreferredColorFormatDefaultMode(portFmt->nIndex);
157
158 if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
159 eRet = OMX_ErrorNoMore;
160 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
161 " NoMore Color formats");
162 }
163 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
164 } else {
165 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
166 (int)portFmt->nPortIndex);
167 eRet = OMX_ErrorBadPortIndex;
168 }
169 break;
170 }
171 /*Component should support this port definition*/
172 case OMX_IndexParamAudioInit: {
173 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
174 OMX_PORT_PARAM_TYPE *audioPortParamType =
175 (OMX_PORT_PARAM_TYPE *) paramData;
176 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
177 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
178 audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
179 audioPortParamType->nPorts = 0;
180 audioPortParamType->nStartPortNumber = 0;
181 break;
182 }
183 /*Component should support this port definition*/
184 case OMX_IndexParamImageInit: {
185 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
186 OMX_PORT_PARAM_TYPE *imagePortParamType =
187 (OMX_PORT_PARAM_TYPE *) paramData;
188 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
189 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
190 imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
191 imagePortParamType->nPorts = 0;
192 imagePortParamType->nStartPortNumber = 0;
193 break;
194
195 }
196 /*Component should support this port definition*/
197 case OMX_IndexParamOtherInit: {
198 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
199 paramIndex);
200 eRet =OMX_ErrorUnsupportedIndex;
201 break;
202 }
203 case OMX_IndexParamStandardComponentRole: {
204 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
205 OMX_PARAM_COMPONENTROLETYPE *comp_role;
206 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
207 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
208 comp_role->nSize = sizeof(*comp_role);
209
210 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
211 paramIndex);
212 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
213 OMX_MAX_STRINGNAME_SIZE);
214 break;
215 }
216 /* Added for parameter test */
217 case OMX_IndexParamPriorityMgmt: {
218 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
219 OMX_PRIORITYMGMTTYPE *priorityMgmType =
220 (OMX_PRIORITYMGMTTYPE *) paramData;
221 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
222 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
223 priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE);
224
225 break;
226 }
227 /* Added for parameter test */
228 case OMX_IndexParamCompBufferSupplier: {
229 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
230 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
231 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
232 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
233
234 bufferSupplierType->nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
235 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
236 if (0 == bufferSupplierType->nPortIndex)
237 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
238 else if (1 == bufferSupplierType->nPortIndex)
239 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
240 else
241 eRet = OMX_ErrorBadPortIndex;
242
243
244 break;
245 }
246 case OMX_IndexParamVideoAvc: {
247 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
248 paramIndex);
249 break;
250 }
251 case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
252 DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x",
253 paramIndex);
254 break;
255 }
256 case OMX_IndexParamVideoMpeg2: {
257 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
258 paramIndex);
259 break;
260 }
261 case OMX_IndexParamVideoProfileLevelQuerySupported: {
262 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
263 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
264 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
265 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
266 eRet = get_supported_profile_level(profileLevelType);
267 break;
268 }
269 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
270 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
271 VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams);
272 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
273 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
274 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
275
276 if (secure_mode) {
277 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
278 GRALLOC_USAGE_PRIVATE_UNCACHED);
279 } else {
280 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED;
281 }
282 } else {
283 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
284 eRet = OMX_ErrorBadParameter;
285 }
286 }
287 break;
288 #endif
289
290 #ifdef FLEXYUV_SUPPORTED
291 case OMX_QcomIndexFlexibleYUVDescription: {
292 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
293 VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams);
294 eRet = describeColorFormat(paramData);
295 if (eRet == OMX_ErrorUnsupportedSetting) {
296 DEBUG_PRINT_LOW("The standard OMX linear formats are understood by client. Please ignore this Unsupported Setting (0x80001019).");
297 }
298 break;
299 }
300 #endif
301 case OMX_IndexParamVideoProfileLevelCurrent: {
302 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
303 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
304 struct v4l2_control profile_control, level_control;
305
306 switch (drv_ctx.decoder_format) {
307 case VDEC_CODECTYPE_H264:
308 profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
309 level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
310 break;
311 default:
312 DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264");
313 eRet = OMX_ErrorNotImplemented;
314 break;
315 }
316
317 if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) {
318 switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) {
319 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
320 pParam->eProfile = OMX_VIDEO_AVCProfileBaseline;
321 break;
322 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
323 pParam->eProfile = OMX_VIDEO_AVCProfileConstrainedBaseline;
324 break;
325 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
326 pParam->eProfile = OMX_VIDEO_AVCProfileConstrainedHigh;
327 break;
328 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
329 pParam->eProfile = OMX_VIDEO_AVCProfileMain;
330 break;
331 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
332 pParam->eProfile = OMX_VIDEO_AVCProfileExtended;
333 break;
334 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
335 pParam->eProfile = OMX_VIDEO_AVCProfileHigh;
336 break;
337 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
338 pParam->eProfile = OMX_VIDEO_AVCProfileHigh10;
339 break;
340 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
341 pParam->eProfile = OMX_VIDEO_AVCProfileHigh422;
342 break;
343 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
344 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
345 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
346 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
347 case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
348 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
349 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
350 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
351 case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
352 case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
353 eRet = OMX_ErrorUnsupportedIndex;
354 break;
355 }
356 } else {
357 eRet = OMX_ErrorUnsupportedIndex;
358 }
359
360
361 if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) {
362 switch ((enum v4l2_mpeg_video_h264_level)level_control.value) {
363 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
364 pParam->eLevel = OMX_VIDEO_AVCLevel1;
365 break;
366 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
367 pParam->eLevel = OMX_VIDEO_AVCLevel1b;
368 break;
369 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
370 pParam->eLevel = OMX_VIDEO_AVCLevel11;
371 break;
372 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
373 pParam->eLevel = OMX_VIDEO_AVCLevel12;
374 break;
375 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
376 pParam->eLevel = OMX_VIDEO_AVCLevel13;
377 break;
378 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
379 pParam->eLevel = OMX_VIDEO_AVCLevel2;
380 break;
381 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
382 pParam->eLevel = OMX_VIDEO_AVCLevel21;
383 break;
384 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
385 pParam->eLevel = OMX_VIDEO_AVCLevel22;
386 break;
387 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
388 pParam->eLevel = OMX_VIDEO_AVCLevel3;
389 break;
390 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
391 pParam->eLevel = OMX_VIDEO_AVCLevel31;
392 break;
393 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
394 pParam->eLevel = OMX_VIDEO_AVCLevel32;
395 break;
396 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
397 pParam->eLevel = OMX_VIDEO_AVCLevel4;
398 break;
399 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
400 pParam->eLevel = OMX_VIDEO_AVCLevel41;
401 break;
402 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
403 pParam->eLevel = OMX_VIDEO_AVCLevel42;
404 break;
405 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
406 pParam->eLevel = OMX_VIDEO_AVCLevel5;
407 break;
408 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
409 pParam->eLevel = OMX_VIDEO_AVCLevel51;
410 break;
411 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
412 pParam->eLevel = OMX_VIDEO_AVCLevel52;
413 break;
414 case V4L2_MPEG_VIDEO_H264_LEVEL_6_0:
415 pParam->eLevel = OMX_VIDEO_AVCLevel6;
416 break;
417 case V4L2_MPEG_VIDEO_H264_LEVEL_6_1:
418 pParam->eLevel = OMX_VIDEO_AVCLevel61;
419 break;
420 case V4L2_MPEG_VIDEO_H264_LEVEL_6_2:
421 pParam->eLevel = OMX_VIDEO_AVCLevel62;
422 break;
423 default:
424 eRet = OMX_ErrorUnsupportedIndex;
425 break;
426 }
427 } else {
428 eRet = OMX_ErrorUnsupportedIndex;
429 }
430
431 break;
432
433 }
434 case OMX_QTIIndexParamVideoClientExtradata:
435 {
436 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
437 DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVideoClientExtradata");
438 QOMX_EXTRADATA_ENABLE *pParam =
439 (QOMX_EXTRADATA_ENABLE *)paramData;
440 if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
441 pParam->bEnable = m_client_extradata ? OMX_TRUE : OMX_FALSE;
442 eRet = OMX_ErrorNone;
443 } else {
444 eRet = OMX_ErrorUnsupportedIndex;
445 }
446 break;
447 }
448 default: {
449 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
450 eRet =OMX_ErrorUnsupportedIndex;
451 }
452
453 }
454
455 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
456 drv_ctx.video_resolution.frame_width,
457 drv_ctx.video_resolution.frame_height,
458 drv_ctx.video_resolution.stride,
459 drv_ctx.video_resolution.scan_lines);
460
461 return eRet;
462 }
463
464 /* ======================================================================
465 FUNCTION
466 omx_vdec::Setparameter
467
468 DESCRIPTION
469 OMX Set Parameter method implementation.
470
471 PARAMETERS
472 <TBD>.
473
474 RETURN VALUE
475 OMX Error None if successful.
476
477 ========================================================================== */
set_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_IN OMX_PTR paramData)478 OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
479 OMX_IN OMX_INDEXTYPE paramIndex,
480 OMX_IN OMX_PTR paramData)
481 {
482 OMX_ERRORTYPE eRet = OMX_ErrorNone;
483 int ret=0;
484 struct v4l2_format fmt;
485 #ifdef _ANDROID_
486 char property_value[PROPERTY_VALUE_MAX] = {0};
487 #endif
488 if (m_state == OMX_StateInvalid) {
489 DEBUG_PRINT_ERROR("Set Param in Invalid State");
490 return OMX_ErrorInvalidState;
491 }
492 if (paramData == NULL) {
493 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
494 return OMX_ErrorBadParameter;
495 }
496 if ((m_state != OMX_StateLoaded) &&
497 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
498 (m_out_bEnabled == OMX_TRUE) &&
499 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
500 (m_inp_bEnabled == OMX_TRUE)) {
501 DEBUG_PRINT_ERROR("Set Param in Invalid State");
502 return OMX_ErrorIncorrectStateOperation;
503 }
504 switch ((unsigned long)paramIndex) {
505 case OMX_IndexParamPortDefinition: {
506 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
507 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
508 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
509 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
510 //been called.
511 DEBUG_PRINT_LOW(
512 "set_parameter: OMX_IndexParamPortDefinition: dir %d port %d wxh %dx%d count: min %d actual %d size %d",
513 (int)portDefn->eDir, (int)portDefn->nPortIndex,
514 (int)portDefn->format.video.nFrameWidth,
515 (int)portDefn->format.video.nFrameHeight,
516 (int)portDefn->nBufferCountMin,
517 (int)portDefn->nBufferCountActual,
518 (int)portDefn->nBufferSize);
519
520 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
521 DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d",
522 portDefn->nBufferCountActual);
523 eRet = OMX_ErrorBadParameter;
524 break;
525 }
526 if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) {
527 if (portDefn->nBufferCountActual < MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS ||
528 portDefn->nBufferSize != m_client_out_extradata_info.getSize()) {
529 DEBUG_PRINT_ERROR("ERROR: Bad parameeters request for extradata limit %d size - %d",
530 portDefn->nBufferCountActual, portDefn->nBufferSize);
531 eRet = OMX_ErrorBadParameter;
532 break;
533 }
534 m_client_out_extradata_info.set_extradata_info(portDefn->nBufferSize,
535 portDefn->nBufferCountActual);
536 break;
537 }
538
539 if (OMX_DirOutput == portDefn->eDir) {
540 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
541 bool port_format_changed = false;
542 m_display_id = portDefn->format.video.pNativeWindow;
543 unsigned int buffer_size;
544
545 fix_drv_output_format();
546
547 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
548 DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)",
549 portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
550 eRet = OMX_ErrorBadParameter;
551 } else if (!client_buffers.get_buffer_req(buffer_size)) {
552 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
553 eRet = OMX_ErrorBadParameter;
554 } else if (!port_format_changed) {
555
556 // Buffer count can change only when port is unallocated
557 if (m_out_mem_ptr &&
558 (portDefn->nBufferCountActual != drv_ctx.op_buf.actualcount ||
559 portDefn->nBufferSize != drv_ctx.op_buf.buffer_size)) {
560
561 DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !");
562 eRet = OMX_ErrorInvalidState;
563 break;
564 }
565
566 // route updating of buffer requirements via c2d proxy.
567 // Based on whether c2d is enabled, requirements will be handed
568 // to the vidc driver appropriately
569 eRet = client_buffers.set_buffer_req(portDefn->nBufferSize,
570 portDefn->nBufferCountActual);
571 if (eRet == OMX_ErrorNone) {
572 m_port_def = *portDefn;
573 } else {
574 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)",
575 drv_ctx.op_buf.mincount, (unsigned int)buffer_size,
576 (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
577 eRet = OMX_ErrorBadParameter;
578 }
579 }
580 } else if (OMX_DirInput == portDefn->eDir) {
581 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
582 bool port_format_changed = false;
583 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
584 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
585 // Frame rate only should be set if this is a "known value" or to
586 // activate ts prediction logic (arbitrary mode only) sending input
587 // timestamps with max value (LLONG_MAX).
588 m_fps_received = portDefn->format.video.xFramerate;
589 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u",
590 (unsigned int)portDefn->format.video.xFramerate >> 16);
591 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
592 drv_ctx.frame_rate.fps_denominator);
593 if (!drv_ctx.frame_rate.fps_numerator) {
594 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
595 drv_ctx.frame_rate.fps_numerator = 30;
596 }
597 if (drv_ctx.frame_rate.fps_denominator)
598 drv_ctx.frame_rate.fps_numerator = (int)
599 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
600 drv_ctx.frame_rate.fps_denominator = 1;
601 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
602 drv_ctx.frame_rate.fps_numerator;
603 DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
604 (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
605 (float)drv_ctx.frame_rate.fps_denominator);
606
607 struct v4l2_control control;
608
609 control.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE;
610 control.value = drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
611 control.value <<= 16;
612 control.value |= (0x0000FFFF & (drv_ctx.frame_rate.fps_numerator % drv_ctx.frame_rate.fps_denominator));
613 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
614 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
615 if (ret) {
616 DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
617 return OMX_ErrorHardware;
618 }
619 }
620
621 if (drv_ctx.video_resolution.frame_height !=
622 portDefn->format.video.nFrameHeight ||
623 drv_ctx.video_resolution.frame_width !=
624 portDefn->format.video.nFrameWidth) {
625 DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)",
626 (unsigned int)portDefn->format.video.nFrameWidth,
627 (unsigned int)portDefn->format.video.nFrameHeight);
628 port_format_changed = true;
629 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
630 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
631 if (frameHeight != 0x0 && frameWidth != 0x0) {
632 m_extradata_misr.output_crop_rect.nLeft = 0;
633 m_extradata_misr.output_crop_rect.nTop = 0;
634 m_extradata_misr.output_crop_rect.nWidth = frameWidth;
635 m_extradata_misr.output_crop_rect.nHeight = frameHeight;
636
637 update_resolution(frameWidth, frameHeight,
638 frameWidth, frameHeight);
639
640 memset(&fmt, 0x0, sizeof(struct v4l2_format));
641 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
642 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
643 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
644 fmt.fmt.pix_mp.pixelformat = output_capability;
645 DEBUG_PRINT_LOW("DS Disabled : height = %d , width = %d",
646 fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
647 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
648 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
649 fmt.fmt.pix_mp.pixelformat = capture_capability;
650 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
651
652 if (ret) {
653 DEBUG_PRINT_ERROR("Set Resolution failed");
654 eRet = errno == EBUSY ? OMX_ErrorInsufficientResources : OMX_ErrorUnsupportedSetting;
655 } else {
656 eRet = get_buffer_req(&drv_ctx.op_buf);
657 }
658 if (eRet)
659 break;
660 }
661 }
662 if (m_custom_buffersize.input_buffersize
663 && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
664 DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
665 m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
666 eRet = OMX_ErrorBadParameter;
667 break;
668 }
669 if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
670 DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)",
671 portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
672 eRet = OMX_ErrorBadParameter;
673 break;
674 }
675 // Buffer count can change only when port is unallocated
676 if (m_inp_mem_ptr &&
677 (portDefn->nBufferCountActual != drv_ctx.ip_buf.actualcount ||
678 portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)) {
679 DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !");
680 eRet = OMX_ErrorInvalidState;
681 break;
682 }
683
684 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
685 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
686 port_format_changed = true;
687 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
688 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
689 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
690 (~(buffer_prop->alignment - 1));
691 eRet = set_buffer_req(buffer_prop);
692 }
693 if (false == port_format_changed) {
694 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)",
695 drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size,
696 (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
697 eRet = OMX_ErrorBadParameter;
698 }
699 } else if (portDefn->eDir == OMX_DirMax) {
700 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
701 (int)portDefn->nPortIndex);
702 eRet = OMX_ErrorBadPortIndex;
703 }
704 }
705 break;
706 case OMX_IndexParamVideoPortFormat: {
707 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
708 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
709 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
710 int ret=0;
711 struct v4l2_format fmt;
712 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u",
713 portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex);
714
715 memset(&fmt, 0x0, sizeof(struct v4l2_format));
716 if (1 == portFmt->nPortIndex) {
717 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
718 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
719 if (ret < 0) {
720 DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
721 return OMX_ErrorBadParameter;
722 }
723 enum vdec_output_format op_format;
724 if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
725 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
726 op_format = (enum vdec_output_format)VDEC_YUV_FORMAT_NV12;
727 fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12;
728 //check if the required color format is a supported flexible format
729 is_flexible_format = check_supported_flexible_formats(portFmt->eColorFormat);
730 } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
731 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed ||
732 portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
733 portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
734 portFmt->eColorFormat == OMX_COLOR_Format16bitRGB565) {
735 if (!m_disable_ubwc_mode) {
736 op_format = (enum vdec_output_format)VDEC_YUV_FORMAT_NV12_UBWC;
737 fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC;
738 } else {
739 op_format = (enum vdec_output_format)VDEC_YUV_FORMAT_NV12;
740 fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12;
741 }
742 //check if the required color format is a supported flexible format
743 is_flexible_format = check_supported_flexible_formats(portFmt->eColorFormat);
744 } else {
745 eRet = OMX_ErrorBadParameter;
746 }
747
748 if (eRet == OMX_ErrorNone) {
749 drv_ctx.output_format = op_format;
750 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
751 if (ret) {
752 DEBUG_PRINT_ERROR("Set output format failed");
753 eRet = OMX_ErrorUnsupportedSetting;
754 /*TODO: How to handle this case */
755 } else {
756 eRet = get_buffer_req(&drv_ctx.op_buf);
757 }
758 }
759 if (eRet == OMX_ErrorNone) {
760 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
761 DEBUG_PRINT_ERROR("Set color format failed");
762 eRet = OMX_ErrorBadParameter;
763 }
764 }
765 }
766 }
767 break;
768 case OMX_QTIIndexParamVideoClientExtradata: {
769 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
770 QOMX_EXTRADATA_ENABLE *pParam = (QOMX_EXTRADATA_ENABLE *)paramData;
771 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoClientExtradata %d", pParam->bEnable);
772
773 if (m_state != OMX_StateLoaded) {
774 DEBUG_PRINT_ERROR("Set Parameter called in Invalid state");
775 return OMX_ErrorIncorrectStateOperation;
776 }
777
778 if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
779 m_client_out_extradata_info.enable_client_extradata(pParam->bEnable);
780 } else {
781 DEBUG_PRINT_ERROR("Incorrect portIndex - %d", pParam->nPortIndex);
782 eRet = OMX_ErrorUnsupportedIndex;
783 }
784 break;
785 }
786 case OMX_IndexParamStandardComponentRole: {
787 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
788 OMX_PARAM_COMPONENTROLETYPE *comp_role;
789 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
790 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
791 comp_role->cRole);
792
793 if ((m_state == OMX_StateLoaded)&&
794 !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_IDLE_PENDING)) {
795 DEBUG_PRINT_LOW("Set Parameter called in valid state");
796 } else {
797 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
798 return OMX_ErrorIncorrectStateOperation;
799 }
800
801 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
802 if (!strncmp((char*)comp_role->cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
803 strlcpy((char*)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE);
804 } else {
805 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
806 eRet =OMX_ErrorUnsupportedSetting;
807 }
808 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
809 if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
810 strlcpy((char*)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE);
811 } else {
812 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
813 eRet = OMX_ErrorUnsupportedSetting;
814 }
815 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
816 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
817 !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
818 strlcpy((char*)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE);
819 } else {
820 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
821 eRet = OMX_ErrorUnsupportedSetting;
822 }
823 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
824 if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) ||
825 !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
826 strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE);
827 } else {
828 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
829 eRet = OMX_ErrorUnsupportedSetting;
830 }
831 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
832 if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
833 strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
834 } else {
835 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
836 eRet = OMX_ErrorUnsupportedSetting;
837 }
838 } else {
839 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
840 eRet = OMX_ErrorInvalidComponentName;
841 }
842 break;
843 }
844
845 case OMX_IndexParamPriorityMgmt: {
846 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
847 if (m_state != OMX_StateLoaded) {
848 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
849 return OMX_ErrorIncorrectStateOperation;
850 }
851 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
852 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
853 (unsigned int)priorityMgmtype->nGroupID);
854
855 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
856 (unsigned int)priorityMgmtype->nGroupPriority);
857
858 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
859 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
860
861 break;
862 }
863
864 case OMX_IndexParamCompBufferSupplier: {
865 VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
866 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
867 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
868 bufferSupplierType->eBufferSupplier);
869 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
870 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
871
872 else
873
874 eRet = OMX_ErrorBadPortIndex;
875
876 break;
877
878 }
879 case OMX_IndexParamVideoAvc: {
880 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
881 paramIndex);
882 break;
883 }
884 case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
885 DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d",
886 paramIndex);
887 break;
888 }
889 case OMX_IndexParamVideoMpeg2: {
890 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
891 paramIndex);
892 break;
893 }
894 case OMX_QTIIndexParamLowLatencyMode: {
895 struct v4l2_control control;
896 int rc = 0;
897 QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE* pParam =
898 (QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE*)paramData;
899 control.id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE;
900 if (pParam->bEnableLowLatencyMode)
901 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
902 else
903 control.value = V4L2_MPEG_MSM_VIDC_DISABLE;
904
905 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
906 if (rc) {
907 DEBUG_PRINT_ERROR("Set low latency failed");
908 eRet = OMX_ErrorUnsupportedSetting;
909 } else {
910 m_sParamLowLatency.bEnableLowLatencyMode = pParam->bEnableLowLatencyMode;
911 }
912 break;
913 }
914 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
915 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER);
916 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
917 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
918 struct v4l2_control control;
919 int pic_order,rc=0;
920 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
921 pictureOrder->eOutputPictureOrder);
922 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
923 pic_order = V4L2_MPEG_MSM_VIDC_DISABLE;
924 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
925 pic_order = V4L2_MPEG_MSM_VIDC_ENABLE;
926 time_stamp_dts.set_timestamp_reorder_mode(false);
927 } else
928 eRet = OMX_ErrorBadParameter;
929 if (eRet == OMX_ErrorNone) {
930 control.id = V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER;
931 control.value = pic_order;
932 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
933 if (rc) {
934 DEBUG_PRINT_ERROR("Set picture order failed");
935 eRet = OMX_ErrorUnsupportedSetting;
936 }
937 }
938 m_decode_order_mode =
939 pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER;
940 break;
941 }
942 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
943 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
944 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
945 struct v4l2_control control;
946 int rc;
947 drv_ctx.idr_only_decoding = 1;
948 control.id = V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER;
949 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
950 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
951 if (rc) {
952 DEBUG_PRINT_ERROR("Set picture order failed");
953 eRet = OMX_ErrorUnsupportedSetting;
954 } else {
955 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
956 control.value = V4L2_MPEG_MSM_VIDC_ENABLE;
957 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
958 if (rc) {
959 DEBUG_PRINT_ERROR("Sync frame setting failed");
960 eRet = OMX_ErrorUnsupportedSetting;
961 }
962 /*Setting sync frame decoding on driver might change buffer
963 * requirements so update them here*/
964 if (get_buffer_req(&drv_ctx.ip_buf)) {
965 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
966 eRet = OMX_ErrorUnsupportedSetting;
967 }
968 if (get_buffer_req(&drv_ctx.op_buf)) {
969 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
970 eRet = OMX_ErrorUnsupportedSetting;
971 }
972 }
973 }
974 break;
975 case OMX_QcomIndexParamIndexExtraDataType: {
976 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
977 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
978 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamIndexExtraDataType %d", extradataIndexType->nIndex);
979 if (extradataIndexType->nIndex == (OMX_INDEXTYPE)OMX_QTI_ExtraDataCategory_Basic) {
980 m_client_extradata |= EXTRADATA_DEFAULT;
981 } else if (extradataIndexType->nIndex == (OMX_INDEXTYPE)OMX_QTI_ExtraDataCategory_Advanced) {
982 m_client_extradata |= EXTRADATA_ADVANCED;
983 }
984 if (m_client_extradata) {
985 eRet = enable_extradata(m_client_extradata);
986 }
987 break;
988 }
989 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
990 /* Need to allow following two set_parameters even in Idle
991 * state. This is ANDROID architecture which is not in sync
992 * with openmax standard. */
993 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
994 VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams);
995 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
996 if (enableNativeBuffers->nPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
997 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers allowed only on output port!");
998 eRet = OMX_ErrorUnsupportedSetting;
999 break;
1000 } else if (m_out_mem_ptr) {
1001 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers is not allowed since Output port is not free !");
1002 eRet = OMX_ErrorInvalidState;
1003 break;
1004 }
1005 if (enableNativeBuffers) {
1006 m_enable_android_native_buffers = enableNativeBuffers->enable;
1007 }
1008 #if !defined(FLEXYUV_SUPPORTED)
1009 if (m_enable_android_native_buffers) {
1010 // Use the most-preferred-native-color-format as surface-mode is hinted here
1011 if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
1012 DEBUG_PRINT_ERROR("Failed to set native color format!");
1013 eRet = OMX_ErrorUnsupportedSetting;
1014 }
1015 }
1016 #endif
1017 }
1018 break;
1019 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
1020 VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams);
1021 eRet = use_android_native_buffer(hComp, paramData);
1022 }
1023 break;
1024 #if ALLOCATE_OUTPUT_NATIVEHANDLE
1025 case OMX_GoogleAndroidIndexAllocateNativeHandle: {
1026
1027 AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
1028 VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams);
1029
1030 if (allocateNativeHandleParams->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
1031 DEBUG_PRINT_LOW("Enable/Disable allocate-native-handle allowed only on input port!. Please ignore this Unsupported Setting (0x80001019).");
1032 eRet = OMX_ErrorUnsupportedSetting;
1033 break;
1034 } else if (m_inp_mem_ptr) {
1035 DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Input port is not free !");
1036 eRet = OMX_ErrorInvalidState;
1037 break;
1038 }
1039
1040 if (allocateNativeHandleParams != NULL) {
1041 allocate_native_handle = allocateNativeHandleParams->enable;
1042 }
1043 }
1044 break;
1045 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE
1046 #endif
1047 case OMX_QcomIndexParamEnableTimeStampReorder: {
1048 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER);
1049 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
1050 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
1051 if (reorder->bEnable == OMX_TRUE) {
1052 frm_int =0;
1053 time_stamp_dts.set_timestamp_reorder_mode(true);
1054 } else
1055 time_stamp_dts.set_timestamp_reorder_mode(false);
1056 } else {
1057 time_stamp_dts.set_timestamp_reorder_mode(false);
1058 if (reorder->bEnable == OMX_TRUE) {
1059 eRet = OMX_ErrorUnsupportedSetting;
1060 }
1061 }
1062 }
1063 break;
1064 case OMX_IndexParamVideoProfileLevelCurrent: {
1065 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
1066 OMX_VIDEO_PARAM_PROFILELEVELTYPE *pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
1067
1068 DEBUG_PRINT_LOW("set_parameter: Client set profile is: %d", pParam->eProfile);
1069 DEBUG_PRINT_LOW("set_parameter: Client set level is: %d", pParam->eLevel);
1070 clientSet_profile_level.eProfile = pParam->eProfile;
1071 clientSet_profile_level.eLevel = pParam->eLevel;
1072 break;
1073 }
1074 case OMX_QTIIndexParamVideoDecoderOutputFrameRate:
1075 {
1076 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_OUTPUT_FRAME_RATE);
1077 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoDecoderOutputFrameRate");
1078 QOMX_VIDEO_OUTPUT_FRAME_RATE *pParam = (QOMX_VIDEO_OUTPUT_FRAME_RATE*)paramData;
1079 DEBUG_PRINT_LOW("set_parameter: decoder output-frame-rate %d", pParam->fps);
1080 m_dec_hfr_fps=pParam->fps;
1081 if (m_dec_hfr_fps > m_dec_output_rate)
1082 m_dec_hfr_fps = m_dec_output_rate;
1083
1084 DEBUG_PRINT_HIGH("output-frame-rate value = %d", m_dec_hfr_fps);
1085 break;
1086 }
1087 case OMX_QcomIndexParamVideoMetaBufferMode:
1088 {
1089 VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams);
1090 StoreMetaDataInBuffersParams *metabuffer =
1091 (StoreMetaDataInBuffersParams *)paramData;
1092 if (!metabuffer) {
1093 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
1094 eRet = OMX_ErrorBadParameter;
1095 break;
1096 }
1097 if (m_disable_dynamic_buf_mode) {
1098 DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled");
1099 eRet = OMX_ErrorUnsupportedSetting;
1100 break;
1101 }
1102 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
1103
1104 if (m_out_mem_ptr) {
1105 DEBUG_PRINT_ERROR("Enable/Disable dynamic-buffer-mode is not allowed since Output port is not free !");
1106 eRet = OMX_ErrorInvalidState;
1107 break;
1108 }
1109
1110 dynamic_buf_mode = metabuffer->bStoreMetaData;
1111 DEBUG_PRINT_HIGH("%s buffer mode",
1112 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
1113
1114 } else {
1115 DEBUG_PRINT_ERROR(
1116 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u",
1117 (unsigned int)metabuffer->nPortIndex);
1118 eRet = OMX_ErrorUnsupportedSetting;
1119 }
1120 break;
1121 }
1122 case OMX_QcomIndexParamVideoCustomBufferSize:
1123 {
1124 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CUSTOM_BUFFERSIZE);
1125 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
1126 QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
1127 if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
1128 struct v4l2_control control;
1129 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
1130 control.value = pParam->nBufferSize;
1131 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
1132 DEBUG_PRINT_ERROR("Failed to set input buffer size");
1133 eRet = OMX_ErrorUnsupportedSetting;
1134 } else {
1135 eRet = get_buffer_req(&drv_ctx.ip_buf);
1136 if (eRet == OMX_ErrorNone) {
1137 m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
1138 DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
1139 m_custom_buffersize.input_buffersize);
1140 } else {
1141 DEBUG_PRINT_ERROR("Failed to get buffer requirement");
1142 }
1143 }
1144 } else {
1145 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
1146 eRet = OMX_ErrorBadParameter;
1147 }
1148 break;
1149 }
1150 case OMX_QTIIndexParamPassInputBufferFd:
1151 {
1152 VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
1153 m_input_pass_buffer_fd = ((QOMX_ENABLETYPE *)paramData)->bEnable;
1154 if (m_input_pass_buffer_fd)
1155 DEBUG_PRINT_LOW("Enable passing input buffer FD");
1156 break;
1157 }
1158 case OMX_QTIIndexParamForceUnCompressedForOPB:
1159 {
1160 DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB");
1161 OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *pParam =
1162 (OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *)paramData;
1163 if (!paramData) {
1164 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB paramData is NULL");
1165 eRet = OMX_ErrorBadParameter;
1166 break;
1167 }
1168 m_disable_ubwc_mode = pParam->bEnable;
1169 DEBUG_PRINT_LOW("set_parameter: UBWC %s for OPB", pParam->bEnable ? "disabled" : "enabled");
1170 break;
1171 }
1172 default: {
1173 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
1174 eRet = OMX_ErrorUnsupportedIndex;
1175 }
1176 }
1177 if (eRet != OMX_ErrorNone)
1178 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
1179 return eRet;
1180 }
1181
1182