1 /*
2 * Copyright (c) 2017-2018, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 
23 //! \file     mhw_vdbox_mfx_interface.cpp
24 //! \brief    MHW interface for constructing MFX commands for the Vdbox engine
25 //! \details  Defines the interfaces for constructing MHW Vdbox MFX commands across all platforms
26 //!
27 
28 #include "mhw_vdbox_mfx_interface.h"
29 
30 const uint8_t MhwVdboxMfxInterface::m_mpeg2QuantMatrixScan[64] =
31 {
32     // Inverse Zig-Zag scan pattern
33     0, 1, 5, 6, 14, 15, 27, 28,
34     2, 4, 7, 13, 16, 26, 29, 42,
35     3, 8, 12, 17, 25, 30, 41, 43,
36     9, 11, 18, 24, 31, 40, 44, 53,
37     10, 19, 23, 32, 39, 45, 52, 54,
38     20, 22, 33, 38, 46, 51, 55, 60,
39     21, 34, 37, 47, 50, 56, 59, 61,
40     35, 36, 48, 49, 57, 58, 62, 63
41 };
42 
43 const uint16_t MhwVdboxMfxInterface::m_mpeg2DefaultIntraQuantizerMatrix[64] =
44 {
45     8, 16, 19, 22, 26, 27, 29, 34,
46     16, 16, 22, 24, 27, 29, 34, 37,
47     19, 22, 26, 27, 29, 34, 34, 38,
48     22, 22, 26, 27, 29, 34, 37, 40,
49     22, 26, 27, 29, 32, 35, 40, 48,
50     26, 27, 29, 32, 35, 40, 48, 58,
51     26, 27, 29, 34, 38, 46, 56, 69,
52     27, 29, 35, 38, 46, 56, 69, 83
53 };
54 
55 const uint16_t MhwVdboxMfxInterface::m_mpeg2DefaultNonIntraQuantizerMatrix[64] =
56 {
57     16, 16, 16, 16, 16, 16, 16, 16,
58     16, 16, 16, 16, 16, 16, 16, 16,
59     16, 16, 16, 16, 16, 16, 16, 16,
60     16, 16, 16, 16, 16, 16, 16, 16,
61     16, 16, 16, 16, 16, 16, 16, 16,
62     16, 16, 16, 16, 16, 16, 16, 16,
63     16, 16, 16, 16, 16, 16, 16, 16,
64     16, 16, 16, 16, 16, 16, 16, 16
65 };
66 
67 const uint32_t MhwVdboxMfxInterface::m_mpeg2SliceDeltaQPMax[4] =
68 {
69     0x02040608, 0x01020304, 0x01020304, 0x01010202
70 };
71 
72 const uint32_t MhwVdboxMfxInterface::m_mpeg2InitSliceDeltaQPMin[4] =
73 {
74     0x81828384, 0x81828384, 0x81828384, 0x81828384
75 };
76 
77 const uint32_t MhwVdboxMfxInterface::m_mpeg2FrameBitrateMinMax[4] =
78 {
79     0x00010000, 0x00010000, 0x00010000, 0x00010000
80 };
81 
82 const uint32_t MhwVdboxMfxInterface::m_mpeg2FrameBitrateMinMaxDelta[4] =
83 {
84     0x00010000, 0x00010000, 0x00010000, 0x00010000
85 };
86 
87 const uint8_t MhwVdboxMfxInterface::m_columnScan4x4[16] =
88 {
89     0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15
90 };
91 
92 const uint8_t MhwVdboxMfxInterface::m_columnScan8x8[64] =
93 {
94     0, 8, 16, 24, 32, 40, 48, 56, 1, 9, 17, 25, 33, 41, 49, 57,
95     2, 10, 18, 26, 34, 42, 50, 58, 3, 11, 19, 27, 35, 43, 51, 59,
96     4, 12, 20, 28, 36, 44, 52, 60, 5, 13, 21, 29, 37, 45, 53, 61,
97     6, 14, 22, 30, 38, 46, 54, 62, 7, 15, 23, 31, 39, 47, 55, 63
98 };
99 
100 const MhwVdboxMfxInterface::AvcSliceType MhwVdboxMfxInterface::m_AvcBsdSliceType[10] =
101 {
102     MhwVdboxMfxInterface::avcSliceP,
103     MhwVdboxMfxInterface::avcSliceB,
104     MhwVdboxMfxInterface::avcSliceI,
105     MhwVdboxMfxInterface::avcSliceP,
106     MhwVdboxMfxInterface::avcSliceI,
107     MhwVdboxMfxInterface::avcSliceP,
108     MhwVdboxMfxInterface::avcSliceB,
109     MhwVdboxMfxInterface::avcSliceI,
110     MhwVdboxMfxInterface::avcSliceP,
111     MhwVdboxMfxInterface::avcSliceI
112 };
113 
MhwVdboxMfxInterface(PMOS_INTERFACE osInterface,MhwMiInterface * miInterface,MhwCpInterface * cpInterface,bool decodeInUse)114 MhwVdboxMfxInterface::MhwVdboxMfxInterface(
115     PMOS_INTERFACE osInterface,
116     MhwMiInterface *miInterface,
117     MhwCpInterface *cpInterface,
118     bool decodeInUse)
119 {
120     MHW_FUNCTION_ENTER;
121 
122     m_osInterface = osInterface;
123     m_MiInterface = miInterface;
124     m_cpInterface = cpInterface;
125     m_decodeInUse = decodeInUse;
126 
127     MHW_ASSERT(m_osInterface);
128     MHW_ASSERT(m_MiInterface);
129     MHW_ASSERT(m_cpInterface);
130 
131     m_waTable = osInterface->pfnGetWaTable(osInterface);
132     m_skuTable = osInterface->pfnGetSkuTable(osInterface);
133     m_osInterface->pfnGetPlatform(m_osInterface, &m_platform);
134     m_maxVdboxIndex = MEDIA_IS_SKU(m_skuTable, FtrVcs2) ? MHW_VDBOX_NODE_2 : MHW_VDBOX_NODE_1;
135 
136     if (m_osInterface->bUsesGfxAddress)
137     {
138         AddResourceToCmd = Mhw_AddResourceToCmd_GfxAddress;
139     }
140     else // bUsesPatchList
141     {
142         AddResourceToCmd = Mhw_AddResourceToCmd_PatchList;
143     }
144 
145     MEDIA_ENGINE_INFO mediaSysInfo;
146     MOS_ZeroMemory(&mediaSysInfo, sizeof(MEDIA_ENGINE_INFO));
147     MOS_STATUS     eStatus      = osInterface->pfnGetMediaEngineInfo(osInterface, mediaSysInfo);
148     if (eStatus == MOS_STATUS_SUCCESS && (!MEDIA_IS_SKU(m_skuTable, FtrWithSlimVdbox) || m_decodeInUse))
149     {
150         m_numVdbox = (uint8_t)(mediaSysInfo.VDBoxInfo.NumberOfVDBoxEnabled);
151     }
152     else
153     {
154         m_numVdbox = 1;
155     }
156 }
157 
CalcAvcImgStateMinMaxBitrate(MHW_VDBOX_AVC_IMG_BITRATE_PARAMS & params)158 void MhwVdboxMfxInterface::CalcAvcImgStateMinMaxBitrate(
159     MHW_VDBOX_AVC_IMG_BITRATE_PARAMS& params)
160 {
161     // Set this to New mode (= 1) - FrameBitRateMaxUnit and FrameBitRateMinUnit are in new mode (32byte/4Kb)
162     params.frameBitRateMaxUnitMode = params.frameBitRateMinUnitMode = 1;
163 
164     // Set this to Kilo Byte (= 1) - FrameBitRateMax and FrameBitRateMin are in units of 4KBytes when FrameBitrateMaxUnitMode and FrameBitRateMinUnitMode are set to 1
165     params.frameBitRateMaxUnit = params.frameBitRateMinUnit = 1;
166 
167     // We have 14 bits available when FrameBitRateMaxUnitMode is set to 1, so set it to max value
168     params.frameBitRateMax = (1 << 14) - 1;
169 
170     // Set this to min available value
171     params.frameBitRateMin = 0;
172 
173     // Set frame bitrate max and min delta to 0
174     params.frameBitRateMaxDelta = params.frameBitRateMinDelta = 0;
175 
176     return;
177 }
178 
GetViewOrder(PMHW_VDBOX_AVC_DPB_PARAMS params,uint32_t currIdx,uint32_t list)179 uint32_t MhwVdboxMfxInterface::GetViewOrder(
180     PMHW_VDBOX_AVC_DPB_PARAMS params,
181     uint32_t currIdx,
182     uint32_t list)
183 {
184     MHW_CHK_NULL_RETURN(params);
185 
186     auto avcPicParams = params->pAvcPicParams;
187     auto mvcExtPicParams = params->pMvcExtPicParams;
188     auto avcRefList = params->ppAvcRefList;
189 
190     // No need to check if bottom field since only progressive is supported
191     int32_t  currPOC = avcPicParams->CurrFieldOrderCnt[0];
192     uint32_t numRefs = (list == LIST_0) ? mvcExtPicParams->NumInterViewRefsL0 : mvcExtPicParams->NumInterViewRefsL1;
193     uint32_t viewOrder = 0xF;
194     uint32_t currRef = params->pAvcPicIdx[currIdx].ucPicIdx;
195 
196     if (params->pAvcPicIdx[currIdx].bValid &&
197         avcRefList[currRef]->bUsedAsInterViewRef &&
198         (currPOC == avcRefList[currRef]->iFieldOrderCnt[0]))
199     {
200         for (uint32_t i = 0; i < numRefs; i++)
201         {
202             if (mvcExtPicParams->ViewIDList[currIdx] == mvcExtPicParams->InterViewRefList[list][i])
203             {
204                 viewOrder = mvcExtPicParams->ViewIDList[currIdx];
205                 break;
206             }
207         }
208     }
209 
210     return viewOrder;
211 }
212 
IsVc1IPicture(const CODEC_PICTURE & picture,bool isFirstField,uint16_t picType)213 bool MhwVdboxMfxInterface::IsVc1IPicture(
214     const CODEC_PICTURE& picture,
215     bool isFirstField,
216     uint16_t picType)
217 {
218     bool isI = false;
219 
220     if (CodecHal_PictureIsField(picture))
221     {
222         if (picType == vc1IIField)
223         {
224             // I/I frame
225             isI = true;
226         }
227         else if (picType == vc1IPField)
228         {
229             // I/P frame
230             isI = isFirstField;
231         }
232         else if (picType == vc1PIField)
233         {
234             // P/I frame
235             isI = (!isFirstField);
236         }
237     }
238     else
239     {
240         isI = (picType == vc1IFrame);
241     }
242 
243     return isI;
244 }
245 
IsVc1PPicture(const CODEC_PICTURE & picture,bool isFirstField,uint16_t picType)246 bool MhwVdboxMfxInterface::IsVc1PPicture(
247     const CODEC_PICTURE& picture,
248     bool isFirstField,
249     uint16_t picType)
250 {
251     bool isP = false;
252 
253     if (CodecHal_PictureIsField(picture))
254     {
255         if (picType == vc1PPField)
256         {
257             // P/P frame
258             isP = true;
259         }
260         else if (picType == vc1IPField)
261         {
262             // I/P frame
263             isP = (!isFirstField);
264         }
265         else if (picType == vc1PIField)
266         {
267             // P/I frame
268             isP = isFirstField;
269         }
270     }
271     else
272     {
273         isP = (picType == vc1PFrame);
274     }
275 
276     return isP;
277 }
278 
IsVc1BPicture(const CODEC_PICTURE & picture,bool isFirstField,uint16_t picType)279 bool MhwVdboxMfxInterface::IsVc1BPicture(
280     const CODEC_PICTURE& picture,
281     bool isFirstField,
282     uint16_t picType)
283 {
284     bool isB = false;
285 
286     if (CodecHal_PictureIsField(picture))
287     {
288         if (picType == vc1BBIField)
289         {
290             // B/BI frame
291             isB = isFirstField;
292         }
293         else if (picType == vc1BIBField)
294         {
295             // BI/B frame
296             isB = (!isFirstField);
297         }
298         else if (picType == vc1BBField)
299         {
300             // BI/BI frame
301             isB = true;
302         }
303     }
304     else
305     {
306         isB = (picType == vc1BFrame);
307     }
308 
309     return isB;
310 }
311 
IsVc1BIPicture(const CODEC_PICTURE & picture,bool isFirstField,uint16_t picType)312 bool MhwVdboxMfxInterface::IsVc1BIPicture(
313     const CODEC_PICTURE& picture,
314     bool isFirstField,
315     uint16_t picType)
316 {
317     bool isBI = false;
318 
319     if (CodecHal_PictureIsField(picture))
320     {
321         if (picType == vc1BBIField)
322         {
323             // B/BI frame
324             isBI = (!isFirstField);
325         }
326         else if (picType == vc1BIBField)
327         {
328             // BI/B frame
329             isBI = isFirstField;
330         }
331         else if (picType == vc1BIBIField)
332         {
333             // BI/BI frame
334             isBI = true;
335         }
336     }
337     else
338     {
339         isBI = (picType == vc1BIFrame);
340     }
341 
342     return isBI;
343 }
344 
AddMfxAvcImgCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_IMG_PARAMS params)345 MOS_STATUS MhwVdboxMfxInterface::AddMfxAvcImgCmd(
346     PMOS_COMMAND_BUFFER cmdBuffer,
347     PMHW_BATCH_BUFFER batchBuffer,
348     PMHW_VDBOX_AVC_IMG_PARAMS params)
349 {
350     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
351 
352     MHW_FUNCTION_ENTER;
353 
354     if (m_decodeInUse)
355     {
356         MHW_MI_CHK_STATUS(AddMfxDecodeAvcImgCmd(cmdBuffer, batchBuffer, params));
357     }
358     else
359     {
360         MHW_MI_CHK_STATUS(AddMfxEncodeAvcImgCmd(cmdBuffer, batchBuffer, params));
361     }
362 
363     return eStatus;
364 }
365 
AddMfxAvcWeightOffset(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS params)366 MOS_STATUS MhwVdboxMfxInterface::AddMfxAvcWeightOffset(
367     PMOS_COMMAND_BUFFER cmdBuffer,
368     PMHW_BATCH_BUFFER batchBuffer,
369     PMHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS params)
370 {
371     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
372 
373     MHW_FUNCTION_ENTER;
374 
375     if (m_decodeInUse)
376     {
377         MHW_MI_CHK_STATUS(AddMfxDecodeAvcWeightOffset(cmdBuffer, batchBuffer, params));
378     }
379     else
380     {
381         MHW_MI_CHK_STATUS(AddMfxEncodeAvcWeightOffset(cmdBuffer, batchBuffer, params));
382     }
383 
384     return eStatus;
385 }
386 
AddMfxAvcSlice(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_SLICE_STATE avcSliceState)387 MOS_STATUS MhwVdboxMfxInterface::AddMfxAvcSlice(
388     PMOS_COMMAND_BUFFER cmdBuffer,
389     PMHW_BATCH_BUFFER batchBuffer,
390     PMHW_VDBOX_AVC_SLICE_STATE avcSliceState)
391 {
392     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
393 
394     MHW_FUNCTION_ENTER;
395 
396     if (m_decodeInUse)
397     {
398         MHW_MI_CHK_STATUS(AddMfxDecodeAvcSlice(cmdBuffer, batchBuffer, avcSliceState));
399     }
400     else
401     {
402         MHW_MI_CHK_STATUS(AddMfxEncodeAvcSlice(cmdBuffer, batchBuffer, avcSliceState));
403     }
404 
405     return eStatus;
406 }
407 
AddMfxMpeg2PicCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_MPEG2_PIC_STATE params)408 MOS_STATUS MhwVdboxMfxInterface::AddMfxMpeg2PicCmd(
409     PMOS_COMMAND_BUFFER cmdBuffer,
410     PMHW_VDBOX_MPEG2_PIC_STATE params)
411 {
412     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
413 
414     MHW_FUNCTION_ENTER;
415 
416     if (m_decodeInUse)
417     {
418         MHW_MI_CHK_STATUS(AddMfxDecodeMpeg2PicCmd(cmdBuffer, params));
419     }
420     else
421     {
422         MHW_MI_CHK_STATUS(AddMfxEncodeMpeg2PicCmd(cmdBuffer, params));
423     }
424 
425     return eStatus;
426 }
427 
AddMfxVp8PicCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_VP8_PIC_STATE params)428 MOS_STATUS MhwVdboxMfxInterface::AddMfxVp8PicCmd(
429     PMOS_COMMAND_BUFFER cmdBuffer,
430     PMHW_VDBOX_VP8_PIC_STATE params)
431 {
432     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
433 
434     MHW_FUNCTION_ENTER;
435 
436     if (m_decodeInUse)
437     {
438         MHW_MI_CHK_STATUS(AddMfxDecodeVp8PicCmd(cmdBuffer, params));
439     }
440     else
441     {
442         MHW_MI_CHK_STATUS(AddMfxEncodeVp8PicCmd(cmdBuffer, params));
443     }
444 
445     return eStatus;
446 }
447 
GetJpegDecodeFormat(MOS_FORMAT format)448 MHW_VDBOX_DECODE_JPEG_FORMAT_CODE MhwVdboxMfxInterface::GetJpegDecodeFormat(MOS_FORMAT format)
449 {
450     switch (format)
451     {
452     case Format_NV12:
453         return MHW_VDBOX_DECODE_JPEG_FORMAT_NV12;
454     case Format_UYVY:
455         return MHW_VDBOX_DECODE_JPEG_FORMAT_UYVY;
456     case Format_YUY2:
457         return MHW_VDBOX_DECODE_JPEG_FORMAT_YUY2;
458     default:
459         return MHW_VDBOX_DECODE_JPEG_FORMAT_SEPARATE_PLANE;
460     }
461 
462     return MHW_VDBOX_DECODE_JPEG_FORMAT_SEPARATE_PLANE;
463 }
464 
IsVPlanePresent(MOS_FORMAT format)465 bool MhwVdboxMfxInterface::IsVPlanePresent(MOS_FORMAT format)
466 {
467     switch (format)
468     {
469     case Format_NV12:
470     case Format_NV11:
471     case Format_P208:
472     case Format_IMC1:
473     case Format_IMC3:
474     case Format_YUY2:
475     case Format_YUYV:
476     case Format_YVYU:
477     case Format_UYVY:
478     case Format_VYUY:
479     case Format_422H:
480     case Format_422V:
481         // Adding RGB formats because RGB is treated like YUV for JPEG encode and decode
482     case Format_RGBP:
483     case Format_BGRP:
484     case Format_A8R8G8B8:
485     case Format_X8R8G8B8:
486     case Format_A8B8G8R8:
487     case Format_411P:
488     case Format_411R:
489     case Format_444P:
490     case Format_IMC2:
491     case Format_IMC4:
492         return true;
493     default:
494         return false;
495     }
496 }
497 
MosToMediaStateFormat(MOS_FORMAT format)498 uint32_t MhwVdboxMfxInterface::MosToMediaStateFormat(MOS_FORMAT format)
499 {
500     switch (format)
501     {
502     case Format_A8R8G8B8:
503     case Format_X8R8G8B8:
504     case Format_A8B8G8R8:
505         return MHW_MEDIASTATE_SURFACEFORMAT_R8G8B8A8_UNORM;
506     case Format_422H:
507     case Format_422V:
508         return MHW_MEDIASTATE_SURFACEFORMAT_PLANAR_422_8;
509     case Format_AYUV:
510     case Format_AUYV:
511         return MHW_MEDIASTATE_SURFACEFORMAT_A8Y8U8V8_UNORM;
512     case Format_NV12:
513     case Format_NV11:
514     case Format_P208:
515     case Format_IMC1:
516     case Format_IMC3:
517         return MHW_MEDIASTATE_SURFACEFORMAT_PLANAR_420_8;
518     case Format_400P:
519     case Format_P8:
520         return MHW_MEDIASTATE_SURFACEFORMAT_Y8_UNORM;
521     case Format_411P:
522     case Format_411R:
523         return MHW_MEDIASTATE_SURFACEFORMAT_PLANAR_411_8;
524     case Format_UYVY:
525         return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_SWAPY;
526     case Format_YVYU:
527         return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_SWAPUV;
528     case Format_VYUY:
529         return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_SWAPUVY;
530     case Format_YUY2:
531     case Format_YUYV:
532     case Format_444P:
533     case Format_IMC2:
534     case Format_IMC4:
535     default:
536         return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_NORMAL;
537     }
538 
539     return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_NORMAL;
540 }
541 
GetJpegHorizontalSamplingFactorForY(CodecEncodeJpegInputSurfaceFormat format)542 uint32_t MhwVdboxMfxInterface::GetJpegHorizontalSamplingFactorForY(
543     CodecEncodeJpegInputSurfaceFormat format)
544 {
545     uint32_t horizontalSamplingFactor = 1;
546 
547     if (format == codechalJpegY8)
548     {
549         horizontalSamplingFactor = 1;
550     }
551     else if (format == codechalJpegNV12)
552     {
553         horizontalSamplingFactor = 2;
554     }
555     else if (format == codechalJpegUYVY || format == codechalJpegYUY2)
556     {
557         horizontalSamplingFactor = 2;
558     }
559     else if (format == codechalJpegRGB)
560     {
561         horizontalSamplingFactor = 1;
562     }
563 
564     return horizontalSamplingFactor;
565 }
566 
GetJpegVerticalSamplingFactorForY(CodecEncodeJpegInputSurfaceFormat format)567 uint32_t MhwVdboxMfxInterface::GetJpegVerticalSamplingFactorForY(
568     CodecEncodeJpegInputSurfaceFormat format)
569 {
570     uint32_t verticalSamplingFactor = 1;
571 
572     if (format == codechalJpegY8)
573     {
574         verticalSamplingFactor = 1;
575     }
576     else if (format == codechalJpegNV12)
577     {
578         verticalSamplingFactor = 2;
579     }
580     else if (format == codechalJpegRGB ||
581         format == codechalJpegUYVY ||
582         format == codechalJpegYUY2)
583     {
584         verticalSamplingFactor = 1;
585     }
586 
587     return verticalSamplingFactor;
588 }
589