1 /*--------------------------------------------------------------------------
2 Copyright (c) 2017-2019, 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 
init_vendor_extensions(VendorExtensionStore & store)30 void omx_video::init_vendor_extensions(VendorExtensionStore &store) {
31 
32     //TODO: add extensions based on Codec, m_platform and/or other capability queries
33 
34     ADD_EXTENSION("qti-ext-enc-preprocess-rotate", OMX_IndexConfigCommonRotate, OMX_DirOutput)
35     ADD_PARAM_END("angle", OMX_AndroidVendorValueInt32)
36 
37     ADD_EXTENSION("qti-ext-enc-preprocess-mirror", OMX_IndexConfigCommonMirror, OMX_DirOutput)
38     ADD_PARAM_END("flip", OMX_AndroidVendorValueInt32)
39 
40     ADD_EXTENSION("qti-ext-enc-avc-intra-period", QOMX_IndexConfigVideoIntraperiod, OMX_DirOutput)
41     ADD_PARAM    ("n-pframes",    OMX_AndroidVendorValueInt32)
42     ADD_PARAM_END("n-idr-period", OMX_AndroidVendorValueInt32)
43 
44     ADD_EXTENSION("qti-ext-enc-intra-period", QOMX_IndexConfigVideoIntraperiod, OMX_DirOutput)
45     ADD_PARAM    ("n-pframes",    OMX_AndroidVendorValueInt32)
46     ADD_PARAM    ("n-bframes",    OMX_AndroidVendorValueInt32)
47     ADD_PARAM_END("n-idr-period", OMX_AndroidVendorValueInt32)
48 
49     ADD_EXTENSION("qti-ext-enc-error-correction", OMX_QcomIndexParamVideoSliceSpacing, OMX_DirOutput)
50     ADD_PARAM_END("resync-marker-spacing-bits", OMX_AndroidVendorValueInt32)
51 
52     ADD_EXTENSION("qti-ext-enc-slice", OMX_QcomIndexParamVideoSliceSpacing, OMX_DirOutput)
53     ADD_PARAM_END("spacing", OMX_AndroidVendorValueInt32)
54 
55     ADD_EXTENSION("qti-ext-enc-custom-profile-level", OMX_IndexParamVideoProfileLevelCurrent, OMX_DirOutput)
56     ADD_PARAM    ("profile", OMX_AndroidVendorValueInt32)
57     ADD_PARAM_END("level",   OMX_AndroidVendorValueInt32)
58 
59     ADD_EXTENSION("qti-ext-enc-timestamp-source-avtimer", OMX_QTIIndexParamEnableAVTimerTimestamps, OMX_DirInput)
60     ADD_PARAM_END("enable", OMX_AndroidVendorValueInt32)
61 
62     ADD_EXTENSION("qti-ext-enc-frame-qp", OMX_QcomIndexConfigQp, OMX_DirOutput)
63     ADD_PARAM_END("value", OMX_AndroidVendorValueInt32)
64 
65     ADD_EXTENSION("qti-ext-down-scalar", OMX_QcomIndexParamVideoDownScalar, OMX_DirOutput)
66     ADD_PARAM    ("output-width", OMX_AndroidVendorValueInt32)
67     ADD_PARAM_END("output-height", OMX_AndroidVendorValueInt32)
68 
69     ADD_EXTENSION("qti-ext-enc-app-input-control", OMX_QcomIndexParamVencControlInputQueue, OMX_DirInput)
70     ADD_PARAM_END("enable", OMX_AndroidVendorValueInt32)
71 
72     ADD_EXTENSION("qti-ext-enc-input-trigger", OMX_IndexConfigTimePosition, OMX_DirInput)
73     ADD_PARAM_END("timestamp", OMX_AndroidVendorValueInt64)
74 
75     ADD_EXTENSION("qti-ext-enc-low-latency", OMX_QTIIndexParamLowLatencyMode, OMX_DirInput)
76     ADD_PARAM_END("enable", OMX_AndroidVendorValueInt32)
77 
78     ADD_EXTENSION("qti-ext-enc-base-layer-pid", OMX_QcomIndexConfigBaseLayerId, OMX_DirInput)
79     ADD_PARAM_END("value", OMX_AndroidVendorValueInt32)
80 
81     ADD_EXTENSION("qti-ext-enc-ltr-count", OMX_QcomIndexParamVideoLTRCount, OMX_DirOutput)
82     ADD_PARAM_END("num-ltr-frames", OMX_AndroidVendorValueInt32)
83 
84     ADD_EXTENSION("qti-ext-enc-ltr", OMX_QcomIndexConfigVideoLTRUse, OMX_DirInput)
85     ADD_PARAM_END("use-frame", OMX_AndroidVendorValueInt32)
86 
87     ADD_EXTENSION("qti-ext-enc-ltr", OMX_QcomIndexConfigVideoLTRMark, OMX_DirInput)
88     ADD_PARAM_END("mark-frame", OMX_AndroidVendorValueInt32)
89 
90     ADD_EXTENSION("qti-ext-enc-dynamic-frame-rate", OMX_IndexConfigVideoFramerate, OMX_DirOutput)
91     ADD_PARAM_END("frame-rate", OMX_AndroidVendorValueInt32)
92 
93     ADD_EXTENSION("qti-ext-extradata-enable", OMX_QcomIndexParamIndexExtraDataType, OMX_DirOutput)
94     ADD_PARAM_END("types", OMX_AndroidVendorValueString)
95 
96     ADD_EXTENSION("qti-ext-enc-caps-vt-driver-version", OMX_QTIIndexParamCapabilitiesVTDriverVersion, OMX_DirOutput)
97     ADD_PARAM_END("number", OMX_AndroidVendorValueInt32)
98 
99     ADD_EXTENSION("qti-ext-enc-caps-preprocess", OMX_QTIIndexParamCapabilitiesMaxDownScaleRatio, OMX_DirOutput)
100     ADD_PARAM_END("max-downscale-factor", OMX_AndroidVendorValueInt32)
101 
102     ADD_EXTENSION("qti-ext-enc-caps-preprocess", OMX_QTIIndexParamCapabilitiesRotationSupport, OMX_DirOutput)
103     ADD_PARAM_END("rotation", OMX_AndroidVendorValueInt32)
104 
105     ADD_EXTENSION("qti-ext-enc-blur-support", OMX_QTIIndexParamCapabilitiesBlurSupport, OMX_DirInput)
106     ADD_PARAM_END ("blur-support", OMX_AndroidVendorValueInt32)
107 
108     ADD_EXTENSION("qti-ext-enc-color-conversion-support", OMX_QTIIndexParamCapabilitiesColorSpaceConversionSupport, OMX_DirInput)
109     ADD_PARAM_END ("color-conversion-support", OMX_AndroidVendorValueInt32)
110 
111     ADD_EXTENSION("qti-ext-enc-caps-ltr", OMX_QTIIndexParamCapabilitiesMaxLTR, OMX_DirOutput)
112     ADD_PARAM_END("max-count", OMX_AndroidVendorValueInt32)
113 
114     ADD_EXTENSION("qti-ext-enc-caps-temporal-layers", OMX_QTIIndexParamCapabilitiesMaxTemporalLayers, OMX_DirInput)
115     ADD_PARAM    ("max-p-count", OMX_AndroidVendorValueInt32)
116     ADD_PARAM_END("max-b-count", OMX_AndroidVendorValueInt32)
117 
118     ADD_EXTENSION("qti-ext-enc-colorspace-conversion", OMX_QTIIndexParamColorSpaceConversion, OMX_DirInput)
119     ADD_PARAM_END("enable", OMX_AndroidVendorValueInt32)
120 
121     ADD_EXTENSION("qti-ext-enc-initial-qp", QOMX_IndexParamVideoInitialQp, OMX_DirOutput)
122     ADD_PARAM    ("qp-i", OMX_AndroidVendorValueInt32)
123     ADD_PARAM    ("qp-i-enable", OMX_AndroidVendorValueInt32)
124     ADD_PARAM    ("qp-p", OMX_AndroidVendorValueInt32)
125     ADD_PARAM    ("qp-p-enable", OMX_AndroidVendorValueInt32)
126     ADD_PARAM    ("qp-b", OMX_AndroidVendorValueInt32)
127     ADD_PARAM_END("qp-b-enable", OMX_AndroidVendorValueInt32)
128 
129     ADD_EXTENSION("qti-ext-enc-blurinfo", OMX_QTIIndexParamVideoEnableBlur, OMX_DirInput)
130     ADD_PARAM_END("info", OMX_AndroidVendorValueInt32)
131     ADD_EXTENSION("qti-ext-enc-blurfilter", OMX_QTIIndexConfigVideoBlurResolution, OMX_DirInput)
132     ADD_PARAM_END("strength", OMX_AndroidVendorValueInt32)
133 
134     ADD_EXTENSION("qti-ext-enc-qp-range", OMX_QcomIndexParamVideoIPBQPRange, OMX_DirOutput)
135     ADD_PARAM    ("qp-i-min", OMX_AndroidVendorValueInt32)
136     ADD_PARAM    ("qp-i-max", OMX_AndroidVendorValueInt32)
137     ADD_PARAM    ("qp-p-min", OMX_AndroidVendorValueInt32)
138     ADD_PARAM    ("qp-p-max", OMX_AndroidVendorValueInt32)
139     ADD_PARAM    ("qp-b-min", OMX_AndroidVendorValueInt32)
140     ADD_PARAM_END("qp-b-max", OMX_AndroidVendorValueInt32)
141 
142     ADD_EXTENSION("qti-ext-enc-bitrate-mode", OMX_IndexParamVideoBitrate, OMX_DirOutput)
143     ADD_PARAM_END("value", OMX_AndroidVendorValueInt32)
144 
145     ADD_EXTENSION("qti-ext-enc-linear-color-format", OMX_QTIIndexParamEnableLinearColorFormat, OMX_DirInput)
146     ADD_PARAM_END("value", OMX_AndroidVendorValueInt32)
147 
148     ADD_EXTENSION("qti-ext-enc-roiinfo", OMX_QTIIndexConfigVideoRoiRectRegionInfo, OMX_DirInput)
149     ADD_PARAM    ("timestamp", OMX_AndroidVendorValueInt64)
150     ADD_PARAM    ("type", OMX_AndroidVendorValueString)
151     ADD_PARAM    ("rect-payload", OMX_AndroidVendorValueString)
152     ADD_PARAM_END("rect-payload-ext", OMX_AndroidVendorValueString)
153 
154     ADD_EXTENSION("qti-ext-enc-roiinfo-rect-mode", OMX_QTIIndexConfigVideoRoiRectRegionInfo, OMX_DirOutput)
155     ADD_PARAM_END("enable", OMX_AndroidVendorValueInt32)
156 }
157 
get_vendor_extension_config(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE * ext)158 OMX_ERRORTYPE omx_video::get_vendor_extension_config(
159                 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) {
160     if (ext->nIndex >= mVendorExtensionStore.size()) {
161         return OMX_ErrorNoMore;
162     }
163 
164     const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex];
165     DEBUG_PRINT_LOW("VendorExt: getConfig: index=%u (%s)", ext->nIndex, vExt.name());
166 
167     vExt.copyInfoTo(ext);
168     if (ext->nParamSizeUsed < vExt.paramCount()) {
169         // this happens during initial getConfig to query only extension-name and param-count
170         return OMX_ErrorNone;
171     }
172 
173     // We now have sufficient params allocated in extension data passed.
174     // Following code is to set the extension-specific data
175 
176     bool setStatus = true;
177 
178     switch ((OMX_U32)vExt.extensionIndex()) {
179         case OMX_IndexConfigCommonRotate:
180         {
181             setStatus &= vExt.setParamInt32(ext, "angle", m_sConfigFrameRotation.nRotation);
182             break;
183         }
184         case OMX_IndexConfigCommonMirror:
185         {
186             setStatus &= vExt.setParamInt32(ext, "flip", m_sConfigFrameMirror.eMirror);
187             break;
188         }
189         case QOMX_IndexConfigVideoIntraperiod:
190         {
191             if (vExt.isConfigKey(ext, "qti-ext-enc-avc-intra-period")) {
192                 setStatus &= vExt.setParamInt32(ext, "n-pframes", m_sIntraperiod.nPFrames);
193                 setStatus &= vExt.setParamInt32(ext, "n-idr-period", m_sIntraperiod.nIDRPeriod);
194             } else if (vExt.isConfigKey(ext, "qti-ext-enc-intra-period")) {
195                 setStatus &= vExt.setParamInt32(ext, "n-pframes", m_sIntraperiod.nPFrames);
196                 setStatus &= vExt.setParamInt32(ext, "n-bframes",  m_sIntraperiod.nBFrames);
197                 setStatus &= vExt.setParamInt32(ext, "n-idr-period", m_sIntraperiod.nIDRPeriod);
198             }
199             break;
200         }
201         case OMX_QcomIndexParamVideoSliceSpacing:
202         {
203             if (vExt.isConfigKey(ext, "qti-ext-enc-error-correction")) {
204                 setStatus &= vExt.setParamInt32(ext,
205                         "resync-marker-spacing-bits", m_sSliceSpacing.nSliceSize);
206             } else if (vExt.isConfigKey(ext, "qti-ext-enc-slice")) {
207                 setStatus &= vExt.setParamInt32(ext, "spacing", m_sSliceSpacing.nSliceSize);
208             }
209             break;
210         }
211         case OMX_IndexParamVideoProfileLevelCurrent:
212         {
213             setStatus &= vExt.setParamInt32(ext, "profile", m_sParamProfileLevel.eProfile);
214             setStatus &= vExt.setParamInt32(ext, "level", m_sParamProfileLevel.eLevel);
215 
216             break;
217         }
218         case OMX_QTIIndexParamEnableAVTimerTimestamps:
219         {
220             setStatus &= vExt.setParamInt32(ext, "enable", m_sParamAVTimerTimestampMode.bEnable);
221             break;
222         }
223         case OMX_QcomIndexConfigQp:
224         {
225             setStatus &= vExt.setParamInt32(ext, "value", m_sConfigQP.nQP);
226             break;
227         }
228         case OMX_QcomIndexParamVideoDownScalar:
229         {
230             setStatus &= vExt.setParamInt32(ext, "output-width", m_sParamDownScalar.nOutputWidth);
231             setStatus &= vExt.setParamInt32(ext, "output-height", m_sParamDownScalar.nOutputHeight);
232             break;
233         }
234         case OMX_QcomIndexParamVencControlInputQueue:
235         {
236             setStatus &= vExt.setParamInt32(ext, "enable", m_sParamControlInputQueue.bEnable);
237             break;
238         }
239         case OMX_IndexConfigTimePosition:
240         {
241             setStatus &= vExt.setParamInt64(ext, "timestamp", m_sConfigInputTrigTS.nTimestamp);
242             break;
243         }
244         case OMX_QTIIndexParamLowLatencyMode:
245         {
246             setStatus &= vExt.setParamInt32(ext, "enable", m_sParamLowLatency.bEnableLowLatencyMode);
247             break;
248         }
249         case OMX_QcomIndexConfigBaseLayerId:
250         {
251             setStatus &= vExt.setParamInt32(ext, "value", m_sBaseLayerID.nPID);
252             break;
253         }
254         case OMX_QcomIndexParamVideoLTRCount:
255         {
256             setStatus &= vExt.setParamInt32(ext, "num-ltr-frames", m_sParamLTRCount.nCount);
257             break;
258         }
259         case OMX_QcomIndexConfigVideoLTRUse:
260         {
261             setStatus &= vExt.setParamInt32(ext, "use-frame", m_sConfigLTRUse.nID);
262             break;
263         }
264         case OMX_QcomIndexConfigVideoLTRMark:
265         {
266             setStatus &= vExt.setParamInt32(ext, "mark-frame", m_sConfigLTRMark.nID);
267             break;
268         }
269         case OMX_IndexConfigVideoFramerate:
270         {
271             setStatus &= vExt.setParamInt32(ext, "frame-rate", m_sConfigFramerate.xEncodeFramerate);
272             break;
273         }
274         case  OMX_QcomIndexParamIndexExtraDataType:
275         {
276             char exType[OMX_MAX_STRINGVALUE_SIZE+1];
277             memset (exType,0, (sizeof(char)*OMX_MAX_STRINGVALUE_SIZE));
278             if ((OMX_BOOL)(m_sExtraData & VENC_EXTRADATA_LTRINFO)){
279                 const char *extraDataVideoLTRInfo = getStringForExtradataType(OMX_ExtraDataVideoLTRInfo);
280                 if(extraDataVideoLTRInfo != NULL &&
281                         (strlcat(exType, extraDataVideoLTRInfo,
282                                    OMX_MAX_STRINGVALUE_SIZE)) >= OMX_MAX_STRINGVALUE_SIZE) {
283                     DEBUG_PRINT_LOW("extradata string size exceeds size %d",OMX_MAX_STRINGVALUE_SIZE );
284                 }
285             }
286             if ((OMX_BOOL)(m_sExtraData & VENC_EXTRADATA_MBINFO)) {
287                 if (exType[0]!=0) {
288                     strlcat(exType,"|", OMX_MAX_STRINGVALUE_SIZE);
289                 }
290                 const char *extraDataVideoEncoderMBInfo = getStringForExtradataType(OMX_ExtraDataVideoEncoderMBInfo);
291                 if(extraDataVideoEncoderMBInfo != NULL &&
292                         (strlcat(exType, extraDataVideoEncoderMBInfo,
293                                  OMX_MAX_STRINGVALUE_SIZE)) >= OMX_MAX_STRINGVALUE_SIZE) {
294                     DEBUG_PRINT_LOW("extradata string size exceeds size %d",OMX_MAX_STRINGVALUE_SIZE );
295                 }
296             }
297             if ((OMX_BOOL)(m_sExtraData & VENC_EXTRADATA_ROI)) {
298                 if (exType[0]!=0) {
299                     strlcat(exType,"|", OMX_MAX_STRINGVALUE_SIZE);
300                 }
301                 const char *extraDataVideoEncoderROIInfo = getStringForExtradataType(OMX_ExtraDataInputROIInfo);
302                 if(extraDataVideoEncoderROIInfo != NULL &&
303                         (strlcat(exType, extraDataVideoEncoderROIInfo,
304                                  OMX_MAX_STRINGVALUE_SIZE)) >= OMX_MAX_STRINGVALUE_SIZE) {
305                     DEBUG_PRINT_LOW("extradata string size exceeds size %d",OMX_MAX_STRINGVALUE_SIZE );
306                 }
307             }
308             setStatus &= vExt.setParamString(ext, "types", exType);
309             DEBUG_PRINT_LOW("VendorExt: getparam: Extradata %s",exType);
310             break;
311         }
312         case OMX_QTIIndexParamCapabilitiesVTDriverVersion:
313         {
314             setStatus &= vExt.setParamInt32(ext, "number", VT_DRIVER_VERSION);
315             break;
316         }
317         case OMX_QTIIndexParamCapabilitiesMaxLTR:
318         {
319             setStatus &= vExt.setParamInt32(ext, "max-count", 3);
320             break;
321         }
322         case OMX_QTIIndexParamCapabilitiesMaxDownScaleRatio:
323         {
324             setStatus &= vExt.setParamInt32(ext, "max-downscale-factor", 8);
325             break;
326         }
327         case OMX_QTIIndexParamCapabilitiesRotationSupport:
328         {
329             struct v4l2_queryctrl query_ctrl;
330             memset(&query_ctrl, 0, sizeof(struct v4l2_queryctrl));
331             query_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_CAPS;
332             if (dev_query_cap(query_ctrl) && (query_ctrl.maximum > 0)) {
333                 setStatus &= vExt.setParamInt32(ext, "rotation",OMX_TRUE);
334             }
335             else {
336                 setStatus &= vExt.setParamInt32(ext, "rotation",OMX_FALSE);
337             }
338             break;
339         }
340         case OMX_QTIIndexParamCapabilitiesBlurSupport:
341         {
342             struct v4l2_queryctrl query_ctrl;
343             memset(&query_ctrl, 0, sizeof(struct v4l2_queryctrl));
344             query_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_BLUR_WIDTH;
345             if (dev_query_cap(query_ctrl) && (query_ctrl.maximum > 0)) {
346                 setStatus &= vExt.setParamInt32(ext, "blur-support",OMX_TRUE);
347             }
348             else {
349                 setStatus &= vExt.setParamInt32(ext, "blur-support",OMX_FALSE);
350             }
351             break;
352         }
353         case OMX_QTIIndexParamCapabilitiesColorSpaceConversionSupport:
354         {
355             struct v4l2_queryctrl query_ctrl;
356             memset(&query_ctrl, 0, sizeof(struct v4l2_queryctrl));
357             query_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE_CAPS;
358             if (dev_query_cap(query_ctrl) && (query_ctrl.maximum > 0)) {
359                 setStatus &= vExt.setParamInt32(ext, "color-conversion-support",OMX_TRUE);
360             }
361             else {
362                 setStatus &= vExt.setParamInt32(ext, "color-conversion-support",OMX_FALSE);
363             }
364             break;
365         }
366         case OMX_QTIIndexParamCapabilitiesMaxTemporalLayers:
367         {
368             OMX_U32 nPLayerCountMax , nBLayerCountMax;
369             OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE SupportedPattern;
370             if (!dev_get_temporal_layer_caps(&nPLayerCountMax,
371                         &nBLayerCountMax, &SupportedPattern)) {
372                 DEBUG_PRINT_ERROR("Failed to get temporal layer capabilities");
373                 break;
374             }
375             setStatus &= vExt.setParamInt32(ext, "max-p-count",nPLayerCountMax);
376             setStatus &= vExt.setParamInt32(ext, "max-b-count",nBLayerCountMax);
377             break;
378         }
379         case OMX_QTIIndexParamColorSpaceConversion:
380         {
381             setStatus &= vExt.setParamInt32(ext, "enable", m_sParamColorSpaceConversion.bEnable);
382             break;
383         }
384         case QOMX_IndexParamVideoInitialQp:
385         {
386             setStatus &= vExt.setParamInt32(ext, "qp-i", m_sSessionQuantization.nQpI);
387             setStatus &= vExt.setParamInt32(ext, "qp-p", m_sSessionQuantization.nQpP);
388             setStatus &= vExt.setParamInt32(ext, "qp-b", m_sSessionQuantization.nQpB);
389             setStatus &= vExt.setParamInt32(ext, "qp-i-enable", (m_QPSet & 0x1));
390             setStatus &= vExt.setParamInt32(ext, "qp-p-enable", ((m_QPSet >> 0x1) & 0x1));
391             setStatus &= vExt.setParamInt32(ext, "qp-b-enable", ((m_QPSet >> 0x2) & 0x1));
392             break;
393         }
394         case OMX_QTIIndexParamVideoEnableBlur:
395         case OMX_QTIIndexConfigVideoBlurResolution:
396         {
397             break;
398         }
399         case OMX_QcomIndexParamVideoIPBQPRange:
400         {
401             setStatus &= vExt.setParamInt32(ext, "qp-i-min", m_sSessionQPRange.minIQP);
402             setStatus &= vExt.setParamInt32(ext, "qp-i-max", m_sSessionQPRange.maxIQP);
403             setStatus &= vExt.setParamInt32(ext, "qp-p-min", m_sSessionQPRange.minPQP);
404             setStatus &= vExt.setParamInt32(ext, "qp-p-max", m_sSessionQPRange.maxPQP);
405             setStatus &= vExt.setParamInt32(ext, "qp-b-min", m_sSessionQPRange.minBQP);
406             setStatus &= vExt.setParamInt32(ext, "qp-b-max", m_sSessionQPRange.maxBQP);
407             break;
408         }
409         case OMX_IndexParamVideoBitrate:
410         {
411             setStatus &= vExt.setParamInt32(ext, "value", m_sParamBitrate.eControlRate);
412             break;
413         }
414         case OMX_QTIIndexParamEnableLinearColorFormat:
415         {
416             setStatus &= vExt.setParamInt32(ext, "value", m_sParamLinearColorFormat.bEnable);
417             break;
418         }
419         case OMX_QTIIndexConfigVideoRoiRectRegionInfo:
420         {
421             if (vExt.paramCount() == 1) {
422                 setStatus &= vExt.setParamInt32(ext, "enable", 1);
423             } else {
424                 setStatus &= vExt.setParamInt64(ext, "timestamp", 0);
425                 setStatus &= vExt.setParamString(ext, "type", "rect");
426                 setStatus &= vExt.setParamString(ext, "rect-payload", "");
427                 setStatus &= vExt.setParamString(ext, "rect-payload-ext", "");
428             }
429             break;
430         }
431         default:
432         {
433             return OMX_ErrorNotImplemented;
434         }
435     }
436     return setStatus ? OMX_ErrorNone : OMX_ErrorUndefined;
437 }
438 
set_vendor_extension_config(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE * ext)439 OMX_ERRORTYPE omx_video::set_vendor_extension_config(
440                 OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) {
441 
442     DEBUG_PRINT_LOW("set_vendor_extension_config");
443     if (ext->nIndex >= mVendorExtensionStore.size()) {
444         DEBUG_PRINT_ERROR("unrecognized vendor extension index (%u) max(%u)",
445                 ext->nIndex, mVendorExtensionStore.size());
446         return OMX_ErrorBadParameter;
447     }
448 
449     const VendorExtension& vExt = mVendorExtensionStore[ext->nIndex];
450     DEBUG_PRINT_LOW("VendorExt: setConfig: index=%u (%s)", ext->nIndex, vExt.name());
451 
452     OMX_ERRORTYPE err = OMX_ErrorNone;
453     err = vExt.isConfigValid(ext);
454     if (err != OMX_ErrorNone) {
455         return err;
456     }
457 
458     // mark this as set, regardless of set_config succeeding/failing.
459     // App will know by inconsistent values in output-format
460     vExt.set();
461 
462     bool valueSet = false;
463     switch ((OMX_U32)vExt.extensionIndex()) {
464         case OMX_IndexConfigCommonRotate:
465         {
466             OMX_CONFIG_ROTATIONTYPE rotationParam;
467             memcpy(&rotationParam, &m_sConfigFrameRotation, sizeof(OMX_CONFIG_ROTATIONTYPE));
468             valueSet |= vExt.readParamInt32(ext, "angle", &rotationParam.nRotation);
469             if (!valueSet) {
470                 break;
471             }
472 
473             DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: OMX_IndexConfigCommonRotate : %d",
474                     rotationParam.nRotation);
475 
476             err = set_config(
477                     NULL, OMX_IndexConfigCommonRotate, &rotationParam);
478             if (err != OMX_ErrorNone) {
479                 DEBUG_PRINT_ERROR("set_config: OMX_IndexConfigCommonRotate failed !");
480             }
481             break;
482         }
483         case OMX_IndexConfigCommonMirror:
484         {
485             OMX_CONFIG_MIRRORTYPE mirrorParam;
486             memcpy(&mirrorParam, &m_sConfigFrameMirror, sizeof(OMX_CONFIG_MIRRORTYPE));
487             valueSet |= vExt.readParamInt32(ext, "flip", (OMX_S32*)&mirrorParam.eMirror);
488             if (!valueSet) {
489                 break;
490             }
491 
492             DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: OMX_IndexConfigCommonMirror : %d",
493                              mirrorParam.eMirror);
494 
495             err = set_config(
496                     NULL, OMX_IndexConfigCommonMirror, &mirrorParam);
497             if (err != OMX_ErrorNone) {
498                 DEBUG_PRINT_ERROR("set_config: OMX_IndexConfigCommonMirror failed !");
499             }
500             break;
501         }
502         case QOMX_IndexConfigVideoIntraperiod:
503         {
504             QOMX_VIDEO_INTRAPERIODTYPE intraPeriodConfig;
505             memcpy(&intraPeriodConfig, &m_sIntraperiod, sizeof(QOMX_VIDEO_INTRAPERIODTYPE));
506 
507             if (vExt.isConfigKey(ext, "qti-ext-enc-avc-intra-period")) {
508                 valueSet |= vExt.readParamInt32(ext, "n-pframes", (OMX_S32 *)&(intraPeriodConfig.nPFrames));
509                 valueSet |= vExt.readParamInt32(ext, "n-idr-period", (OMX_S32 *)&(intraPeriodConfig.nIDRPeriod));
510 
511                 DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: AVC-intra-period : nP=%d, nIDR=%d",
512                     intraPeriodConfig.nPFrames, intraPeriodConfig.nIDRPeriod);
513             } else if (vExt.isConfigKey(ext, "qti-ext-enc-intra-period")) {
514                 valueSet |= vExt.readParamInt32(ext, "n-bframes", (OMX_S32 *)&(intraPeriodConfig.nBFrames));
515                 valueSet |= vExt.readParamInt32(ext, "n-pframes", (OMX_S32 *)&(intraPeriodConfig.nPFrames));
516                 valueSet |= vExt.readParamInt32(ext, "n-idr-period", (OMX_S32 *)&(intraPeriodConfig.nIDRPeriod));
517 
518                 DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: intra-period : nIDR=%d, nP=%d, nB=%d",
519                 intraPeriodConfig.nIDRPeriod, intraPeriodConfig.nPFrames, intraPeriodConfig.nBFrames);
520             }
521             if (!valueSet) {
522                 break;
523             }
524 
525             err = set_config(
526                     NULL, (OMX_INDEXTYPE)QOMX_IndexConfigVideoIntraperiod, &intraPeriodConfig);
527             if (err != OMX_ErrorNone) {
528                 DEBUG_PRINT_ERROR("set_config: QOMX_IndexConfigVideoIntraperiod failed !");
529             }
530             break;
531         }
532         case OMX_QcomIndexParamVideoSliceSpacing:
533         {
534             QOMX_VIDEO_PARAM_SLICE_SPACING_TYPE sliceSpacing;
535             memcpy(&sliceSpacing, &m_sSliceSpacing, sizeof(QOMX_VIDEO_PARAM_SLICE_SPACING_TYPE));
536 
537             if (vExt.isConfigKey(ext, "qti-ext-enc-error-correction")) {
538                 sliceSpacing.eSliceMode = QOMX_SLICEMODE_BYTE_COUNT;
539                 valueSet |= vExt.readParamInt32(ext,
540                     "resync-marker-spacing-bits", (OMX_S32 *)&(sliceSpacing.nSliceSize));
541                 sliceSpacing.nSliceSize = ALIGN(sliceSpacing.nSliceSize, 8) >> 3;
542             } else if (vExt.isConfigKey(ext, "qti-ext-enc-slice")) {
543                 sliceSpacing.eSliceMode = QOMX_SLICEMODE_MB_COUNT;
544                 valueSet |= vExt.readParamInt32(ext,
545                     "spacing", (OMX_S32 *)&(sliceSpacing.nSliceSize));
546             } else {
547               DEBUG_PRINT_ERROR("VENDOR-EXT: set_config: Slice Spacing : Incorrect Mode !");
548               break;
549             }
550 
551             if (!valueSet) {
552                 break;
553             }
554 
555             DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: slice spacing : mode %d size %d",
556                     sliceSpacing.eSliceMode, sliceSpacing.nSliceSize);
557 
558             err = set_parameter(
559                     NULL, (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSliceSpacing, &sliceSpacing);
560             if (err != OMX_ErrorNone) {
561                 DEBUG_PRINT_ERROR("set_config: OMX_QcomIndexParamVideoSliceSpacing failed !");
562             }
563             break;
564         }
565         case OMX_IndexParamVideoProfileLevelCurrent:
566         {
567             OMX_VIDEO_PARAM_PROFILELEVELTYPE profileParam;
568             memcpy(&profileParam, &m_sParamProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
569             valueSet |= vExt.readParamInt32(ext, "profile", (OMX_S32 *)&(profileParam.eProfile));
570             valueSet |= vExt.readParamInt32(ext, "level", (OMX_S32 *)&(profileParam.eLevel));
571             if (!valueSet) {
572                 break;
573             }
574 
575             DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: custom-profile/level : profile=%u level=%u",
576                     (OMX_U32)profileParam.eProfile, (OMX_U32)profileParam.eLevel);
577 
578             err = set_parameter(
579                     NULL, OMX_IndexParamVideoProfileLevelCurrent, &profileParam);
580             if (err != OMX_ErrorNone) {
581                 DEBUG_PRINT_ERROR("set_config: OMX_IndexParamVideoProfileLevelCurrent failed !");
582             }
583 
584             break;
585         }
586         case OMX_QTIIndexParamEnableAVTimerTimestamps:
587         {
588             QOMX_ENABLETYPE avTimerEnableParam;
589             memcpy(&avTimerEnableParam, &m_sParamAVTimerTimestampMode, sizeof(QOMX_ENABLETYPE));
590             valueSet |= vExt.readParamInt32(ext, "enable", (OMX_S32 *)&(avTimerEnableParam.bEnable));
591             if (!valueSet) {
592                 break;
593             }
594 
595             DEBUG_PRINT_HIGH("VENDOR-EXT: AV-timer timestamp mode enable=%u", avTimerEnableParam.bEnable);
596 
597             err = set_parameter(
598                     NULL, (OMX_INDEXTYPE)OMX_QTIIndexParamEnableAVTimerTimestamps, &avTimerEnableParam);
599             if (err != OMX_ErrorNone) {
600                 DEBUG_PRINT_ERROR("set_param: OMX_QTIIndexParamEnableAVTimerTimestamps failed !");
601             }
602 
603             break;
604         }
605         case OMX_QcomIndexConfigQp:
606         {
607             OMX_QCOM_VIDEO_CONFIG_QP qpConfig;
608             memcpy(&qpConfig, &m_sConfigQP, sizeof(OMX_QCOM_VIDEO_CONFIG_QP));
609             valueSet |= vExt.readParamInt32(ext, "value", (OMX_S32 *)&(qpConfig.nQP));
610             if (!valueSet) {
611                 break;
612             }
613 
614             DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: nQP =%u", qpConfig.nQP);
615 
616             err = set_config(
617                     NULL, (OMX_INDEXTYPE)OMX_QcomIndexConfigQp, &qpConfig);
618             if (err != OMX_ErrorNone) {
619                 DEBUG_PRINT_ERROR("set_config: OMX_QcomIndexConfigQp failed !");
620             }
621 
622             break;
623         }
624         case OMX_QcomIndexParamVideoDownScalar:
625         {
626             QOMX_INDEXDOWNSCALAR downScalarParam;
627             memcpy(&downScalarParam, &m_sParamDownScalar, sizeof(QOMX_INDEXDOWNSCALAR));
628             downScalarParam.bEnable = OMX_TRUE;
629             valueSet |= vExt.readParamInt32(ext, "output-width", (OMX_S32 *)&(downScalarParam.nOutputWidth));
630             valueSet |= vExt.readParamInt32(ext, "output-height", (OMX_S32 *)&(downScalarParam.nOutputHeight));
631             if(!valueSet) {
632                 break;
633             }
634 
635             DEBUG_PRINT_HIGH("VENDOR-EXT: Downscalar Enable = %u Output Width = %u Output Height = %u",
636                              downScalarParam.bEnable, downScalarParam.nOutputWidth, downScalarParam.nOutputHeight);
637 
638             err = set_parameter(NULL, (OMX_INDEXTYPE)OMX_QcomIndexParamVideoDownScalar, &downScalarParam);
639             if (err != OMX_ErrorNone) {
640                 DEBUG_PRINT_ERROR("set_param: OMX_QcomIndexParamVideoDownScalar failed !");
641             }
642             break;
643         }
644         case OMX_QcomIndexParamVencControlInputQueue:
645         {
646             QOMX_ENABLETYPE controlInputQueueParam;
647             memcpy(&controlInputQueueParam, &m_sParamControlInputQueue, sizeof(QOMX_ENABLETYPE));
648             valueSet |= vExt.readParamInt32(ext, "enable", (OMX_S32 *)&(controlInputQueueParam.bEnable));
649             if (!valueSet) {
650                 break;
651             }
652 
653             DEBUG_PRINT_HIGH("VENDOR-EXT: set_param: control input queue enable=%u", controlInputQueueParam.bEnable);
654 
655             err = set_parameter(
656                     NULL, (OMX_INDEXTYPE)OMX_QcomIndexParamVencControlInputQueue, &controlInputQueueParam);
657             if (err != OMX_ErrorNone) {
658                 DEBUG_PRINT_ERROR("set_param: OMX_QcomIndexParamVencControlInputQueue failed !");
659             }
660 
661             break;
662         }
663         case OMX_IndexConfigTimePosition:
664         {
665             OMX_TIME_CONFIG_TIMESTAMPTYPE triggerTimeStamp;
666             memcpy(&triggerTimeStamp, &m_sConfigInputTrigTS, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
667             valueSet |= vExt.readParamInt64(ext, "timestamp", (OMX_S64 *)&(triggerTimeStamp.nTimestamp));
668             if (!valueSet) {
669                 break;
670             }
671 
672             DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: trigger timestamp =%lld", triggerTimeStamp.nTimestamp);
673 
674             err = set_config(
675                     NULL, (OMX_INDEXTYPE)OMX_IndexConfigTimePosition, &triggerTimeStamp);
676             if (err != OMX_ErrorNone) {
677                 DEBUG_PRINT_ERROR("set_config: OMX_IndexConfigTimePosition failed !");
678             }
679 
680             break;
681         }
682         case OMX_QTIIndexParamLowLatencyMode:
683         {
684             QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE lowLatency;
685             memcpy(&lowLatency, &m_sParamLowLatency, sizeof(QOMX_EXTNINDEX_VIDEO_LOW_LATENCY_MODE));
686             valueSet |= vExt.readParamInt32(ext, "enable", (OMX_S32 *)&(lowLatency.bEnableLowLatencyMode));
687             if (!valueSet) {
688                 break;
689             }
690 
691             DEBUG_PRINT_HIGH("VENDOR-EXT: set_param: low latency mode =%u", lowLatency.bEnableLowLatencyMode);
692 
693             err = set_parameter(
694                     NULL, (OMX_INDEXTYPE)OMX_QTIIndexParamLowLatencyMode, &lowLatency);
695             if (err != OMX_ErrorNone) {
696                 DEBUG_PRINT_ERROR("set_param: OMX_QTIIndexParamLowLatencyMode failed !");
697             }
698 
699             break;
700         }
701         case OMX_QcomIndexConfigBaseLayerId:
702         {
703             OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID baselayerPID;
704             memcpy(&baselayerPID, &m_sBaseLayerID, sizeof(OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID));
705             valueSet |= vExt.readParamInt32(ext, "value", (OMX_S32 *)&(baselayerPID.nPID));
706             if (!valueSet) {
707                 break;
708             }
709 
710             DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: base layer pid =%u", baselayerPID.nPID);
711 
712             err = set_config(
713                     NULL, (OMX_INDEXTYPE)OMX_QcomIndexConfigBaseLayerId, &baselayerPID);
714             if (err != OMX_ErrorNone) {
715                 DEBUG_PRINT_ERROR("set_config: OMX_QcomIndexConfigBaseLayerId failed !");
716             }
717 
718             break;
719         }
720         case OMX_QcomIndexParamVideoLTRCount:
721         {
722            QOMX_VIDEO_PARAM_LTRCOUNT_TYPE ltrCount;
723            memcpy(&ltrCount, &m_sParamLTRCount, sizeof(QOMX_VIDEO_PARAM_LTRCOUNT_TYPE));
724            valueSet |= vExt.readParamInt32(ext, "num-ltr-frames", (OMX_S32 *)&(ltrCount.nCount));
725            if (!valueSet) {
726                 break;
727             }
728 
729             DEBUG_PRINT_HIGH("VENDOR-EXT: set_parameter: ltr count  =%u", ltrCount.nCount);
730 
731             err = set_parameter(
732                     NULL, (OMX_INDEXTYPE)QOMX_IndexParamVideoLTRCount, &ltrCount);
733             if (err != OMX_ErrorNone) {
734                 DEBUG_PRINT_ERROR("set_parameter: OMX_QcomIndexParamVideoLTRCount failed !");
735             }
736 
737             break;
738         }
739         case OMX_QcomIndexConfigVideoLTRUse:
740         {
741            QOMX_VIDEO_CONFIG_LTRUSE_TYPE ltrUse;
742            memcpy(&ltrUse, &m_sConfigLTRUse, sizeof(QOMX_VIDEO_CONFIG_LTRUSE_TYPE));
743            valueSet |= vExt.readParamInt32(ext, "use-frame", (OMX_S32 *)&(ltrUse.nID));
744            if (!valueSet) {
745                 break;
746             }
747 
748             DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: ltr use  =%u", ltrUse.nID);
749 
750             err = set_config(
751                     NULL, (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRUse, &ltrUse);
752             if (err != OMX_ErrorNone) {
753                 DEBUG_PRINT_ERROR("set_config: OMX_QcomIndexConfigVideoLTRUse failed !");
754             }
755 
756             break;
757         }
758         case OMX_QcomIndexConfigVideoLTRMark:
759         {
760            QOMX_VIDEO_CONFIG_LTRMARK_TYPE ltrMark;
761            memcpy(&ltrMark, &m_sConfigLTRMark, sizeof(QOMX_VIDEO_CONFIG_LTRMARK_TYPE));
762            valueSet |= vExt.readParamInt32(ext, "mark-frame", (OMX_S32 *)&(ltrMark.nID));
763            if (!valueSet) {
764                 break;
765             }
766 
767             DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: ltr mark  =%u", ltrMark.nID);
768 
769             err = set_config(
770                     NULL, (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRMark, &ltrMark);
771             if (err != OMX_ErrorNone) {
772                 DEBUG_PRINT_ERROR("set_config: OMX_QcomIndexConfigVideoLTRMark failed !");
773             }
774 
775             break;
776         }
777         case OMX_IndexConfigVideoFramerate:
778         {
779             OMX_CONFIG_FRAMERATETYPE rateParam;
780             memcpy(&rateParam, &m_sConfigFramerate, sizeof(OMX_CONFIG_FRAMERATETYPE));
781             valueSet |= vExt.readParamInt32(ext, "frame-rate", (OMX_S32 *)&rateParam.xEncodeFramerate);
782             if (!valueSet) {
783                 break;
784             }
785             DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: OMX_IndexConfigVideoFramerate : %d",
786                     rateParam.xEncodeFramerate);
787 
788             err = set_config(
789                     NULL, OMX_IndexConfigVideoFramerate, &rateParam);
790             if (err != OMX_ErrorNone) {
791                 DEBUG_PRINT_ERROR("set_config: OMX_IndexConfigVideoFramerate failed !");
792             }
793             break;
794         }
795         case  OMX_QcomIndexParamIndexExtraDataType:
796         {
797             QOMX_INDEXEXTRADATATYPE extraDataParam;
798             char exType[OMX_MAX_STRINGVALUE_SIZE];
799             OMX_INIT_STRUCT(&extraDataParam, QOMX_INDEXEXTRADATATYPE);
800             valueSet |= vExt.readParamString(ext, "types", exType);
801             if (!valueSet) {
802                 break;
803             }
804             char *rest = exType;
805             char *token = strtok_r(exType, "|", &rest);
806             do {
807                 extraDataParam.bEnabled = OMX_TRUE;
808                 extraDataParam.nIndex = (OMX_INDEXTYPE)getIndexForExtradataType(token);
809                 if (extraDataParam.nIndex < 0) {
810                     DEBUG_PRINT_HIGH(" extradata %s not supported ",token);
811                     continue;
812                 }
813                 if (extraDataParam.nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo ||
814                     extraDataParam.nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderMBInfo) {
815                     extraDataParam.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
816                 } else if (extraDataParam.nIndex == (OMX_INDEXTYPE)OMX_ExtraDataInputROIInfo) {
817                     extraDataParam.nPortIndex = (OMX_U32)PORT_INDEX_IN;
818                 }
819                 DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: extradata: enable for index = %d",
820                                   extraDataParam.nIndex);
821                 err = set_parameter(
822                        NULL, (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType, &extraDataParam);
823                 if (err != OMX_ErrorNone) {
824                     DEBUG_PRINT_ERROR("set_config: OMX_QcomIndexParamIndexExtraDataType failed !");
825                 }
826             } while ((token = strtok_r(NULL, "|", &rest)));
827             break;
828         }
829         case OMX_QTIIndexParamColorSpaceConversion:
830         {
831             QOMX_ENABLETYPE colorspaceConversionParam;
832             memcpy(&colorspaceConversionParam, &m_sParamColorSpaceConversion, sizeof(QOMX_ENABLETYPE));
833             valueSet |= vExt.readParamInt32(ext, "enable", (OMX_S32 *)&(colorspaceConversionParam.bEnable));
834             if (!valueSet) {
835                 break;
836             }
837 
838             DEBUG_PRINT_HIGH("VENDOR-EXT: set_param: color space conversion enable=%u", colorspaceConversionParam.bEnable);
839 
840             err = set_parameter(
841                    NULL, (OMX_INDEXTYPE)OMX_QTIIndexParamColorSpaceConversion, &colorspaceConversionParam);
842             if (err != OMX_ErrorNone) {
843                 DEBUG_PRINT_ERROR("set_param: OMX_QTIIndexParamColorSpaceConversion failed !");
844             }
845 
846             break;
847         }
848         case OMX_QTIIndexParamCapabilitiesVTDriverVersion:
849         case OMX_QTIIndexParamCapabilitiesMaxLTR:
850         case OMX_QTIIndexParamCapabilitiesMaxDownScaleRatio:
851         case OMX_QTIIndexParamCapabilitiesRotationSupport:
852         case OMX_QTIIndexParamCapabilitiesMaxTemporalLayers:
853         case OMX_QTIIndexParamCapabilitiesBlurSupport:
854         case OMX_QTIIndexParamCapabilitiesColorSpaceConversionSupport:
855         {
856             break;
857         }
858         case QOMX_IndexParamVideoInitialQp:
859         {
860             QOMX_EXTNINDEX_VIDEO_INITIALQP initQP;
861             OMX_INIT_STRUCT(&initQP, QOMX_EXTNINDEX_VIDEO_INITIALQP);
862             initQP.nPortIndex = (OMX_U32)PORT_INDEX_OUT;
863             OMX_S32 enableIQp = (m_QPSet & 0x1);
864             OMX_S32 enablePQp = ((m_QPSet >> 0x1) & 0x1);
865             OMX_S32 enableBQp = ((m_QPSet >> 0x2) & 0x1);
866             initQP.nQpI = m_sSessionQuantization.nQpI;
867             initQP.nQpP = m_sSessionQuantization.nQpP;
868             initQP.nQpB = m_sSessionQuantization.nQpB;
869             initQP.bEnableInitQp = m_QPSet;
870             valueSet |= vExt.readParamInt32(ext, "qp-i", (OMX_S32 *)&(initQP.nQpI));
871             valueSet |= vExt.readParamInt32(ext, "qp-b", (OMX_S32 *)&(initQP.nQpB));
872             valueSet |= vExt.readParamInt32(ext, "qp-p", (OMX_S32 *)&(initQP.nQpP));
873             valueSet |= vExt.readParamInt32(ext, "qp-i-enable", (OMX_S32 *)&enableIQp);
874             valueSet |= vExt.readParamInt32(ext, "qp-p-enable", (OMX_S32 *)&enablePQp);
875             valueSet |= vExt.readParamInt32(ext, "qp-b-enable", (OMX_S32 *)&enableBQp);
876             initQP.bEnableInitQp = (((enableIQp == 0x1) << 0x0 ) | ((enablePQp == 0x1) << 0x1 ) | ((enableBQp == 0x1) << 0x2 ));
877             if (!valueSet) {
878                 break;
879             }
880 
881             DEBUG_PRINT_HIGH("VENDOR-EXT: set_param: QOMX_IndexParamVideoInitialQp I/B/P value: %d %d %d",
882                 initQP.nQpI,initQP.nQpB,initQP.nQpP);
883 
884             err = set_parameter(
885                     NULL, (OMX_INDEXTYPE)QOMX_IndexParamVideoInitialQp, &initQP);
886             if (err != OMX_ErrorNone) {
887                 DEBUG_PRINT_ERROR("set_param: QOMX_IndexParamVideoInitialQp failed !");
888             }
889             break;
890         }
891         case OMX_QTIIndexParamVideoEnableBlur:
892         {
893             OMX_QTI_VIDEO_CONFIG_BLURINFO blurInfo;
894 
895             memcpy(&blurInfo, &m_blurInfo, sizeof(OMX_QTI_VIDEO_CONFIG_BLURINFO));
896 
897             valueSet |= vExt.readParamInt32(ext, "info", (OMX_S32 *)&(blurInfo.nBlurInfo));
898             if (!valueSet) {
899                 break;
900             }
901 
902             DEBUG_PRINT_HIGH("VENDOR-EXT: set_param: OMX_QTIIndexParamVideoEnableBlur : %u",
903                              blurInfo.nBlurInfo);
904 
905             err = set_parameter(
906                     NULL, (OMX_INDEXTYPE)OMX_QTIIndexParamVideoEnableBlur, &blurInfo);
907             if (err != OMX_ErrorNone) {
908                 DEBUG_PRINT_ERROR("set_param: OMX_QTIIndexParamVideoEnableBlur failed !");
909             }
910             break;
911         }
912         case OMX_QTIIndexConfigVideoBlurResolution:
913         {
914             OMX_QTI_VIDEO_CONFIG_BLURINFO blurInfo;
915 
916             memcpy(&blurInfo, &m_blurInfo, sizeof(OMX_QTI_VIDEO_CONFIG_BLURINFO));
917 
918             valueSet |= vExt.readParamInt32(ext, "strength", (OMX_S32 *)&(blurInfo.nBlurInfo));
919             if (!valueSet) {
920                 break;
921             }
922 
923             DEBUG_PRINT_HIGH("VENDOR-EXT: set_config: OMX_QTIIndexConfigVideoBlurResolution : %u",
924                              blurInfo.nBlurInfo);
925 
926             err = set_config(
927                     NULL, (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoBlurResolution, &blurInfo);
928             if (err != OMX_ErrorNone) {
929                 DEBUG_PRINT_ERROR("set_config: OMX_QTIIndexConfigVideoBlurResolution failed !");
930             }
931             break;
932         }
933         case OMX_QcomIndexParamVideoIPBQPRange:
934         {
935             OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE qpRange;
936             memcpy(&qpRange, &m_sSessionQPRange, sizeof(OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE));
937             valueSet |= vExt.readParamInt32(ext, "qp-i-min", (OMX_S32 *)&(qpRange.minIQP));
938             valueSet |= vExt.readParamInt32(ext, "qp-i-max", (OMX_S32 *)&(qpRange.maxIQP));
939             valueSet |= vExt.readParamInt32(ext, "qp-p-min", (OMX_S32 *)&(qpRange.minPQP));
940             valueSet |= vExt.readParamInt32(ext, "qp-p-max", (OMX_S32 *)&(qpRange.maxPQP));
941             valueSet |= vExt.readParamInt32(ext, "qp-b-min", (OMX_S32 *)&(qpRange.minBQP));
942             valueSet |= vExt.readParamInt32(ext, "qp-b-max", (OMX_S32 *)&(qpRange.maxBQP));
943             if (!valueSet) {
944                 break;
945             }
946 
947             DEBUG_PRINT_HIGH("VENDOR-EXT: set_param: OMX_QcomIndexParamVideoIPBQPRange for min/max value for I/P/B: %d-%d / %d-%d / %d-%d"
948                 ,qpRange.minIQP,qpRange.maxIQP,qpRange.minPQP,qpRange.maxPQP,qpRange.minBQP,qpRange.maxBQP);
949 
950             err = set_parameter(
951                     NULL, (OMX_INDEXTYPE)OMX_QcomIndexParamVideoIPBQPRange, &qpRange);
952             if (err != OMX_ErrorNone) {
953                 DEBUG_PRINT_ERROR("set_param: OMX_QcomIndexParamVideoIPBQPRange failed !");
954             }
955             break;
956         }
957         case OMX_IndexParamVideoBitrate:
958         {
959             OMX_VIDEO_PARAM_BITRATETYPE bitRateParam;
960             memcpy(&bitRateParam, &m_sParamBitrate, sizeof(OMX_VIDEO_PARAM_BITRATETYPE));
961             valueSet |= vExt.readParamInt32(ext, "value", (OMX_S32 *)&(bitRateParam.eControlRate));
962             if (!valueSet) {
963                 break;
964             }
965             DEBUG_PRINT_HIGH("VENDOR-EXT: set_param: ControlRate = %d",
966                                 bitRateParam.eControlRate);
967 
968             err = set_parameter(
969                    NULL, (OMX_INDEXTYPE)OMX_IndexParamVideoBitrate, &bitRateParam);
970             if (err != OMX_ErrorNone) {
971                 DEBUG_PRINT_ERROR("set_param: OMX_IndexParamVideoBitrate failed !");
972             }
973 
974             break;
975         }
976         case OMX_QTIIndexParamEnableLinearColorFormat:
977         {
978             QOMX_ENABLETYPE linearColor;
979             memcpy(&linearColor, &m_sParamLinearColorFormat, sizeof(QOMX_ENABLETYPE));
980             valueSet |= vExt.readParamInt32(ext, "value", (OMX_S32 *)&(linearColor.bEnable));
981             if (!valueSet) {
982                 break;
983             }
984 
985             DEBUG_PRINT_HIGH("VENDOR-EXT: set_param: OMX_QTIIndexParamEnableLinearColorFormat : %d",
986                                 linearColor.bEnable);
987 
988             err = set_parameter(
989                    NULL, (OMX_INDEXTYPE)OMX_QTIIndexParamEnableLinearColorFormat, &linearColor);
990             if (err != OMX_ErrorNone) {
991                 DEBUG_PRINT_ERROR("set_param: OMX_QTIIndexParamEnableLinearColorFormat failed !");
992             }
993             break;
994         }
995         case OMX_QTIIndexConfigVideoRoiRectRegionInfo:
996         {
997             if (vExt.paramCount() == 1) {
998                 break;
999             }
1000             uint32_t format = m_sOutPortDef.format.video.eCompressionFormat;
1001             if (format != OMX_VIDEO_CodingHEVC && format != OMX_VIDEO_CodingAVC) {
1002                 DEBUG_PRINT_ERROR("ROI-Ext: only support avc or hevc");
1003                 break;
1004             }
1005             char type[OMX_MAX_STRINGVALUE_SIZE];
1006             valueSet = vExt.readParamString(ext, "type", type);
1007             if (!valueSet || strncmp(type, "rect", 4)) {
1008                 DEBUG_PRINT_ERROR("ROI-Ext: type is invalid");
1009                 break;
1010             }
1011             int64_t timestamp;
1012             valueSet = vExt.readParamInt64(ext, "timestamp", (OMX_S64 *)&timestamp);
1013             if (!valueSet) {
1014                 DEBUG_PRINT_ERROR("ROI-Ext: timestamp is invalid");
1015                 break;
1016             }
1017             char rawData[OMX_MAX_STRINGVALUE_SIZE * 2] = {0};
1018             valueSet = vExt.readParamString(ext, "rect-payload", rawData);
1019             if (!valueSet) {
1020                 DEBUG_PRINT_ERROR("ROI-Ext: payload is invalid");
1021                 break;
1022             }
1023             uint32_t size = strlen(rawData);
1024             if (size == 0 || size > (OMX_MAX_STRINGVALUE_SIZE -1)) {
1025                 DEBUG_PRINT_ERROR("ROI-Ext: payload size is invalid : %u", size);
1026                 break;
1027             }
1028             // "payload-ext" is optional, if it's set by the client, joint this string
1029             // with the "payload" string and seperate them with ';'
1030             if (vExt.readParamString(ext, "rect-payload-ext", rawData + size + 1)) {
1031                 rawData[size] = ';';
1032                 size = strlen(rawData);
1033             }
1034             uint32_t width = m_sOutPortDef.format.video.nFrameWidth;
1035             uint32_t height = m_sOutPortDef.format.video.nFrameHeight;
1036             DEBUG_PRINT_LOW("ROI-Ext: clip(%ux%u), ts(%lld), payload(%u):%s",
1037                     width, height, (long long)timestamp, size, rawData);
1038 
1039             OMX_QTI_VIDEO_CONFIG_ROI_RECT_REGION_INFO roiInfo;
1040             OMX_INIT_STRUCT(&roiInfo, OMX_QTI_VIDEO_CONFIG_ROI_RECT_REGION_INFO);
1041             roiInfo.nTimeStamp = timestamp;
1042             roiInfo.nPortIndex = PORT_INDEX_IN;
1043 
1044             // The pattern to parse the String: "top,left-bottom,right=deltaQp;"
1045             // each rectangle region string is seperated by ";"
1046             // For example, the rectangle region is: top: 128, left:96, bottom:336, right:272
1047             // and delta QP is -9, the string is "128,96-336,272=-9;".
1048             uint32_t index = 0;
1049             int top, left, bottom, right, deltaQp;
1050             char *save = rawData;
1051             char *rect = strtok_r(rawData, ";", &save);
1052             const char* patternString = "%d,%d-%d,%d=%d";
1053             while (rect != NULL) {
1054                 int tags = sscanf(rect, patternString, &top, &left, &bottom, &right, &deltaQp);
1055                 if (tags == 5) {
1056                     // sanity check
1057                     if (top > bottom || left > right || top < 0 || left < 0
1058                             || bottom >= (int32_t)height || right >= (int32_t)width
1059                             || index == MAX_RECT_ROI_NUM) {
1060                         DEBUG_PRINT_ERROR("ROI-Ext: invalid roi info with deltaQp");
1061                     } else {
1062                         // delta QP range is (-32, 31)
1063                         if (deltaQp < -31) {
1064                             deltaQp = -31;
1065                         }
1066                         if (deltaQp > 30) {
1067                             deltaQp = 30;
1068                         }
1069                         roiInfo.nRegions[index].nLeft = (uint32_t)left;
1070                         roiInfo.nRegions[index].nTop = (uint32_t)top;
1071                         roiInfo.nRegions[index].nRight = (uint32_t)right;
1072                         roiInfo.nRegions[index].nBottom = (uint32_t)bottom;
1073                         roiInfo.nRegions[index].nDeltaQP = (int8_t)deltaQp;
1074                         DEBUG_PRINT_LOW("ROI-Ext: region(%u): t%d-l%d-b%d-r%d: qp:%d",
1075                                 index, top, left, bottom, right, deltaQp);
1076                         index++;
1077                     }
1078                 } else {
1079                     DEBUG_PRINT_LOW("error rect : %s", rect);
1080                 }
1081                 rect = strtok_r(NULL, ";", &save);
1082             }
1083             if (index > 0) {
1084                 roiInfo.nRegionNum = index;
1085                 err = set_config(NULL, (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoRoiRectRegionInfo,
1086                         &roiInfo);
1087                 if (err != OMX_ErrorNone) {
1088                     DEBUG_PRINT_ERROR("ROI-Ext: failed to set roi region info");
1089                 } else {
1090                     DEBUG_PRINT_LOW("ROI-Ext: set %u number of roi region info", index);
1091                 }
1092             } else {
1093                 DEBUG_PRINT_LOW("ROI-Ext: none valid roi region info");
1094             }
1095             break;
1096         }
1097         default:
1098         {
1099             return OMX_ErrorNotImplemented;
1100         }
1101     }
1102     return err;
1103 }
1104