shithub: openh264

Download patch

ref: 0fec22683f252edd582d05c6b7ade4562e9d56c3
parent: dcd3618bfc70fe6b409a46fc729d5b5161e02b9d
parent: c5a09faf24190d66fbc9d97f6374dbb4dc203b4c
author: huili2 <[email protected]>
date: Mon Jan 9 07:54:16 EST 2017

Merge pull request #2630 from huili2/sebsetsps_vui_bugfix

fix subsetsps vui hrd parse--not supported

--- a/codec/decoder/core/inc/au_parser.h
+++ b/codec/decoder/core/inc/au_parser.h
@@ -86,7 +86,8 @@
 uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeader, uint8_t* pSrcRbsp,
                          int32_t iSrcRbspLen, uint8_t* pSrcNal, int32_t iSrcNalLen, int32_t* pConsumedBytes);
 
-int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t kiSrcLen, uint8_t* pSrcNal, const int32_t kSrcNalLen);
+int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t kiSrcLen, uint8_t* pSrcNal,
+                        const int32_t kSrcNalLen);
 
 int32_t ParseRefBasePicMarking (PBitStringAux pBs, PRefBasePicMarking pRefBasePicMarking);
 
@@ -113,7 +114,8 @@
  * \note    Call it in case eNalUnitType is SPS.
  *************************************************************************************
  */
-int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicWidth, int32_t* pPicHeight, uint8_t* pSrcNal, const int32_t kSrcNalLen);
+int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicWidth, int32_t* pPicHeight,
+                  uint8_t* pSrcNal, const int32_t kSrcNalLen);
 
 /*!
  *************************************************************************************
@@ -129,7 +131,8 @@
  * \note    Call it in case eNalUnitType is PPS.
  *************************************************************************************
  */
-int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux, uint8_t* pSrcNal, const int32_t kSrcNalLen);
+int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux, uint8_t* pSrcNal,
+                  const int32_t kSrcNalLen);
 
 /*!
 *************************************************************************************
@@ -145,7 +148,7 @@
 * \note    Call it in case the flag "vui_parameters_present_flag" in sps is true.
 *************************************************************************************
 */
-int32_t ParseVui(PWelsDecoderContext pCtx, PSps pSps, PBitStringAux pBsAux);
+int32_t ParseVui (PWelsDecoderContext pCtx, PSps pSps, PBitStringAux pBsAux);
 
 /*!
  *************************************************************************************
@@ -160,8 +163,10 @@
  * \note  Call it in case scaling matrix present at sps or pps
  *************************************************************************************
 */
-int32_t SetScalingListValue (uint8_t *pScalingList,int iScalingListNum,bool* bUseDefaultScalingMatrixFlag,PBitStringAux pBsAux);
-int32_t ParseScalingList(PSps pSps,PBitStringAux pBs,bool bPPS,bool *bScalingListPresentFlag,uint8_t(*iScalingList4x4)[16],uint8_t(*iScalingList8x8)[64]);
+int32_t SetScalingListValue (uint8_t* pScalingList, int iScalingListNum, bool* bUseDefaultScalingMatrixFlag,
+                             PBitStringAux pBsAux);
+int32_t ParseScalingList (PSps pSps, PBitStringAux pBs, bool bPPS, const bool kbTrans8x8ModeFlag,
+                          bool* bScalingListPresentFlag, uint8_t (*iScalingList4x4)[16], uint8_t (*iScalingList8x8)[64]);
 /*!
  *************************************************************************************
  * \brief   to parse SEI message payload
--- a/codec/decoder/core/inc/dec_golomb.h
+++ b/codec/decoder/core/inc/dec_golomb.h
@@ -338,8 +338,7 @@
 #define MAX_MB_SIZE 36864
 // for aspect_ratio_idc
 #define EXTENDED_SAR 255
-// for chroma_sample_loc_type_top_field & chroma_sample_loc_type_bottom_field
-#define VUI_MAX_CHROMA_LOG_TYPE_TOP_BOTTOM_FIELD 5
+
 } // namespace WelsDec
 
 #endif//WELS_EXPONENTIAL_GOLOMB_ENTROPY_CODING_H__
--- a/codec/decoder/core/inc/error_code.h
+++ b/codec/decoder/core/inc/error_code.h
@@ -106,6 +106,7 @@
 ERR_INFO_REF_COUNT_OVERFLOW,
 ERR_INFO_CROPPING_NO_SUPPORTED,
 ERR_INFO_INVALID_CROPPING_DATA,
+ERR_INFO_UNSUPPORTED_VUI_HRD,
 ERR_INFO_INVALID_SLICEGROUP,
 ERR_INFO_INVALID_SLICEGROUP_MAP_TYPE,
 ERR_INFO_INVALID_FRAME_NUM,
--- a/codec/decoder/core/inc/parameter_sets.h
+++ b/codec/decoder/core/inc/parameter_sets.h
@@ -61,6 +61,16 @@
     uint32_t uiTimeScale;
     bool bFixedFrameRateFlag;
     bool bNalHrdParamPresentFlag;
+    bool bVclHrdParamPresentFlag;
+    bool bPicStructPresentFlag;
+    bool bBitstreamRestrictionFlag;
+    bool bMotionVectorsOverPicBoundariesFlag;
+    uint32_t uiMaxBytesPerPicDenom;
+    uint32_t uiMaxBitsPerMbDenom;
+    uint32_t uiLog2MaxMvLengthHorizontal;
+    uint32_t uiLog2MaxMvLengthVertical;
+    uint32_t uiMaxNumReorderFrames;
+    uint32_t uiMaxDecFrameBuffering;
   } SVui, *PVui;
 
 /* Sequence Parameter Set, refer to Page 57 in JVT X201wcm */
--- a/codec/decoder/core/src/au_parser.cpp
+++ b/codec/decoder/core/src/au_parser.cpp
@@ -1005,7 +1005,7 @@
     pSps->bSeqScalingMatrixPresentFlag = !!uiCode;
 
     if (pSps->bSeqScalingMatrixPresentFlag) {
-      WELS_READ_VERIFY (ParseScalingList (pSps, pBs, 0, pSps->bSeqScalingListPresentFlag, pSps->iScalingList4x4,
+      WELS_READ_VERIFY (ParseScalingList (pSps, pBs, 0, 0, pSps->bSeqScalingListPresentFlag, pSps->iScalingList4x4,
                                           pSps->iScalingList8x8));
     }
   }
@@ -1134,9 +1134,18 @@
   }
   WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //vui_parameters_present_flag
   pSps->bVuiParamPresentFlag = !!uiCode;
-  if (pSps->bVuiParamPresentFlag && !kbUseSubsetFlag) { //parse Part of Vui Parameters in avc sps only
-    WELS_READ_VERIFY (ParseVui (pCtx, pSps, pBsAux));
+  if (pSps->bVuiParamPresentFlag) {
+    int iRetVui = ParseVui (pCtx, pSps, pBsAux);
+    if (iRetVui == GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_VUI_HRD)) {
+      if (kbUseSubsetFlag) { //Currently do no support VUI with HRD enable in subsetSPS
+        WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "hrd parse in vui of subsetSPS is not supported!");
+        return iRetVui;
+      }
+    } else {
+      WELS_READ_VERIFY (iRetVui);
+    }
   }
+
   if (pCtx->pParam->bParseOnly) {
     if (kSrcNalLen >= SPS_PPS_BS_SIZE - 4) { //sps bs exceeds!
       pCtx->iErrorCode |= dsOutOfMemory;
@@ -1408,12 +1417,12 @@
     pPps->bPicScalingMatrixPresentFlag = !!uiCode;
     if (pPps->bPicScalingMatrixPresentFlag) {
       if (pCtx->bSpsAvailFlags[pPps->iSpsId]) {
-        WELS_READ_VERIFY (ParseScalingList (&pCtx->sSpsBuffer[pPps->iSpsId], pBsAux, 1, pPps->bPicScalingListPresentFlag,
-                                            pPps->iScalingList4x4, pPps->iScalingList8x8));
+        WELS_READ_VERIFY (ParseScalingList (&pCtx->sSpsBuffer[pPps->iSpsId], pBsAux, 1, pPps->bTransform8x8ModeFlag,
+                                            pPps->bPicScalingListPresentFlag, pPps->iScalingList4x4, pPps->iScalingList8x8));
       } else {
         pCtx->bSpsLatePps = true;
-        WELS_READ_VERIFY (ParseScalingList (NULL, pBsAux, 1, pPps->bPicScalingListPresentFlag, pPps->iScalingList4x4,
-                                            pPps->iScalingList8x8));
+        WELS_READ_VERIFY (ParseScalingList (NULL, pBsAux, 1, pPps->bTransform8x8ModeFlag, pPps->bPicScalingListPresentFlag,
+                                            pPps->iScalingList4x4, pPps->iScalingList8x8));
       }
     }
     WELS_READ_VERIFY (BsGetSe (pBsAux, &iCode)); //second_chroma_qp_index_offset
@@ -1459,6 +1468,15 @@
   }
   return ERR_NONE;
 }
+
+#define VUI_MAX_CHROMA_LOG_TYPE_TOP_BOTTOM_FIELD_MAX 5
+#define VUI_NUM_UNITS_IN_TICK_MIN 1
+#define VUI_TIME_SCALE_MIN 1
+#define VUI_MAX_BYTES_PER_PIC_DENOM_MAX 16
+#define VUI_MAX_BITS_PER_MB_DENOM_MAX 16
+#define VUI_LOG2_MAX_MV_LENGTH_HOR_MAX 16
+#define VUI_LOG2_MAX_MV_LENGTH_VER_MAX 16
+#define VUI_MAX_DEC_FRAME_BUFFERING_MAX 16
 int32_t ParseVui (PWelsDecoderContext pCtx, PSps pSps, PBitStringAux pBsAux) {
   uint32_t uiCode;
   PVui pVui = &pSps->sVui;
@@ -1506,11 +1524,11 @@
   if (pVui->bChromaLocInfoPresentFlag) {
     WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //chroma_sample_loc_type_top_field
     pVui->uiChromaSampleLocTypeTopField = uiCode;
-    WELS_CHECK_SE_UPPER_WARNING (pVui->uiChromaSampleLocTypeTopField, VUI_MAX_CHROMA_LOG_TYPE_TOP_BOTTOM_FIELD,
+    WELS_CHECK_SE_UPPER_WARNING (pVui->uiChromaSampleLocTypeTopField, VUI_MAX_CHROMA_LOG_TYPE_TOP_BOTTOM_FIELD_MAX,
                                  "chroma_sample_loc_type_top_field");
     WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //chroma_sample_loc_type_bottom_field
     pVui->uiChromaSampleLocTypeBottomField = uiCode;
-    WELS_CHECK_SE_UPPER_WARNING (pVui->uiChromaSampleLocTypeBottomField, VUI_MAX_CHROMA_LOG_TYPE_TOP_BOTTOM_FIELD,
+    WELS_CHECK_SE_UPPER_WARNING (pVui->uiChromaSampleLocTypeBottomField, VUI_MAX_CHROMA_LOG_TYPE_TOP_BOTTOM_FIELD_MAX,
                                  "chroma_sample_loc_type_bottom_field");
   }
   WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //timing_info_present_flag
@@ -1522,17 +1540,60 @@
     WELS_READ_VERIFY (BsGetBits (pBsAux, 16, &uiCode)); //num_units_in_tick
     uiTmp |= uiCode;
     pVui->uiNumUnitsInTick = uiTmp;
-    WELS_CHECK_SE_LOWER_WARNING (pVui->uiNumUnitsInTick, 1, "num_units_in_tick");
+    WELS_CHECK_SE_LOWER_WARNING (pVui->uiNumUnitsInTick, VUI_NUM_UNITS_IN_TICK_MIN, "num_units_in_tick");
     WELS_READ_VERIFY (BsGetBits (pBsAux, 16, &uiCode)); //time_scale
     uiTmp = (uiCode << 16);
     WELS_READ_VERIFY (BsGetBits (pBsAux, 16, &uiCode)); //time_scale
     uiTmp |= uiCode;
     pVui->uiTimeScale = uiTmp;
+    WELS_CHECK_SE_LOWER_WARNING (pVui->uiNumUnitsInTick, VUI_TIME_SCALE_MIN, "time_scale");
     WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //fixed_frame_rate_flag
     pVui->bFixedFrameRateFlag = !!uiCode;
   }
-  //following HRD related parameters, omitted
-
+  WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //nal_hrd_parameters_present_flag
+  pVui->bNalHrdParamPresentFlag = !!uiCode;
+  if (pVui->bNalHrdParamPresentFlag) { //HRD parse not supported
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "nal_hrd_parameters_present_flag = 1 not supported.");
+    return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_VUI_HRD);
+  }
+  WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //vcl_hrd_parameters_present_flag
+  pVui->bVclHrdParamPresentFlag = !!uiCode;
+  if (pVui->bVclHrdParamPresentFlag) { //HRD parse not supported
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "vcl_hrd_parameters_present_flag = 1 not supported.");
+    return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_VUI_HRD);
+  }
+  WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //pic_struct_present_flag
+  pVui->bPicStructPresentFlag = !!uiCode;
+  WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //bitstream_restriction_flag
+  pVui->bBitstreamRestrictionFlag = !!uiCode;
+  if (pVui->bBitstreamRestrictionFlag) {
+    WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //motion_vectors_over_pic_boundaries_flag
+    pVui->bMotionVectorsOverPicBoundariesFlag = !!uiCode;
+    WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //max_bytes_per_pic_denom
+    pVui->uiMaxBytesPerPicDenom = uiCode;
+    WELS_CHECK_SE_UPPER_WARNING (pVui->uiMaxBytesPerPicDenom, VUI_MAX_BYTES_PER_PIC_DENOM_MAX,
+                                 "max_bytes_per_pic_denom");
+    WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //max_bits_per_mb_denom
+    pVui->uiMaxBitsPerMbDenom = uiCode;
+    WELS_CHECK_SE_UPPER_WARNING (pVui->uiMaxBitsPerMbDenom, VUI_MAX_BITS_PER_MB_DENOM_MAX,
+                                 "max_bits_per_mb_denom");
+    WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //log2_max_mv_length_horizontal
+    pVui->uiLog2MaxMvLengthHorizontal = uiCode;
+    WELS_CHECK_SE_UPPER_WARNING (pVui->uiLog2MaxMvLengthHorizontal, VUI_LOG2_MAX_MV_LENGTH_HOR_MAX,
+                                 "log2_max_mv_length_horizontal");
+    WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //log2_max_mv_length_vertical
+    pVui->uiLog2MaxMvLengthVertical = uiCode;
+    WELS_CHECK_SE_UPPER_WARNING (pVui->uiLog2MaxMvLengthVertical, VUI_LOG2_MAX_MV_LENGTH_VER_MAX,
+                                 "log2_max_mv_length_vertical");
+    WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //max_num_reorder_frames
+    pVui->uiMaxNumReorderFrames = uiCode;
+    WELS_CHECK_SE_UPPER_WARNING (pVui->uiMaxNumReorderFrames, VUI_MAX_DEC_FRAME_BUFFERING_MAX,
+                                 "max_num_reorder_frames");
+    WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //max_dec_frame_buffering
+    pVui->uiMaxDecFrameBuffering = uiCode;
+    WELS_CHECK_SE_UPPER_WARNING (pVui->uiMaxDecFrameBuffering, VUI_MAX_DEC_FRAME_BUFFERING_MAX,
+                                 "max_num_reorder_frames");
+  }
   return ERR_NONE;
 }
 /*!
@@ -1593,8 +1654,8 @@
   return ERR_NONE;
 }
 
-int32_t ParseScalingList (PSps pSps, PBitStringAux pBs, bool bPPS, bool* pScalingListPresentFlag,
-                          uint8_t (*iScalingList4x4)[16], uint8_t (*iScalingList8x8)[64]) {
+int32_t ParseScalingList (PSps pSps, PBitStringAux pBs, bool bPPS, const bool kbTrans8x8ModeFlag,
+                          bool* pScalingListPresentFlag, uint8_t (*iScalingList4x4)[16], uint8_t (*iScalingList8x8)[64]) {
   uint32_t uiScalingListNum;
   uint32_t uiCode;
 
@@ -1603,11 +1664,15 @@
   bool bInit = false;
   const uint8_t* defaultScaling[4];
 
-  if (pSps != NULL) {
-    uiScalingListNum = (pSps->uiChromaFormatIdc != 3) ? 8 : 12;
-    bInit = bPPS && pSps->bSeqScalingMatrixPresentFlag;
-  } else
-    uiScalingListNum = 12;
+  if (!bPPS) { //sps scaling_list
+    if (pSps != NULL) {
+      uiScalingListNum = (pSps->uiChromaFormatIdc != 3) ? 8 : 12;
+      bInit = bPPS && pSps->bSeqScalingMatrixPresentFlag;
+    } else
+      uiScalingListNum = 12;
+  } else { //pps scaling_list
+    uiScalingListNum = 6 + (int32_t) kbTrans8x8ModeFlag * ((pSps->uiChromaFormatIdc != 3) ? 2 : 6);
+  }
 
 //Init default_scaling_list value for sps or pps
   defaultScaling[0] = bInit ? pSps->iScalingList4x4[0] : g_kuiDequantScaling4x4Default[0];
binary files /dev/null b/res/sps_subsetsps_bothVUI.264 differ
--- a/test/api/decoder_test.cpp
+++ b/test/api/decoder_test.cpp
@@ -88,9 +88,7 @@
   }
 }
 static const FileParam kFileParamArray[] = {
-  {"res/test_vd_1d.264", "5827d2338b79ff82cd091c707823e466197281d3"},
-  {"res/test_vd_rc.264", "eea02e97bfec89d0418593a8abaaf55d02eaa1ca"},
-  {"res/Static.264", "91dd4a7a796805b2cd015cae8fd630d96c663f42"},
+  {"res/Adobe_PDF_sample_a_1024x768_50Frms.264", "9aa9a4d9598eb3e1093311826844f37c43e4c521"},
   {"res/BA1_FT_C.264", "418d152fb85709b6f172799dcb239038df437cfa"},
   {"res/BA1_Sony_D.jsv", "d94b5ceed5686a03ea682b53d415dee999d27eb6"},
   {"res/BAMQ1_JVC_C.264", "613cf662c23e5d9e1d7da7fe880a3c427411d171"},
@@ -113,6 +111,7 @@
   {"res/NLMQ1_JVC_C.264", "f3265c6ddf8db1b2bf604d8a2954f75532e28cda"},
   {"res/NLMQ2_JVC_C.264", "350ae86ef9ba09390d63a09b7f9ff54184109ca8"},
   {"res/NRF_MW_E.264", "20732198c04cd2591350a361e4510892f6eed3f0"},
+  {"res/QCIF_2P_I_allIPCM.264", "8724c0866ebdba7ebb7209a0c0c3ae3ae38a0240"},
   {"res/SVA_BA1_B.264", "c4543b24823b16c424c673616c36c7f537089b2d"},
   {"res/SVA_BA2_D.264", "98ff2d67860462d8d8bcc9352097c06cc401d97e"},
   {"res/SVA_Base_B.264", "91f514d81cd33de9f6fbf5dbefdb189cc2e7ecf4"},
@@ -120,11 +119,17 @@
   {"res/SVA_FM1_E.264", "fad08c4ff7cf2307b6579853d0f4652fc26645d3"},
   {"res/SVA_NL1_B.264", "6d63f72a0c0d833b1db0ba438afff3b4180fb3e6"},
   {"res/SVA_NL2_E.264", "70453ef8097c94dd190d6d2d1d5cb83c67e66238"},
+  {"res/SarVui.264", "98ff2d67860462d8d8bcc9352097c06cc401d97e"},
+  {"res/Static.264", "91dd4a7a796805b2cd015cae8fd630d96c663f42"},
+  {"res/Zhling_1280x720.264", "ad99f5eaa2d73ae3840e7da67313de8cfc866ce6"},
+  {"res/sps_subsetsps_bothVUI.264", "d3a47032eb5dcc1963343a68e9bea12435bf1e4c"},
   {"res/test_cif_I_CABAC_PCM.264", "95fdf21470d3bbcf95505abb2164042063a79d98"},
   {"res/test_cif_I_CABAC_slice.264", "19121bc67f2b13fb8f030504fc0827e1ac6d0fdb"},
   {"res/test_cif_P_CABAC_slice.264", "521bbd0ba2422369b724c7054545cf107a56f959"},
   {"res/test_qcif_cabac.264", "587d1d05943f3cd416bf69469975fdee05361e69"},
-  {"res/QCIF_2P_I_allIPCM.264", "8724c0866ebdba7ebb7209a0c0c3ae3ae38a0240"}
+  {"res/test_scalinglist_jm.264", "f690a3af2896a53360215fb5d35016bfd41499b3"},
+  {"res/test_vd_1d.264", "5827d2338b79ff82cd091c707823e466197281d3"},
+  {"res/test_vd_rc.264", "eea02e97bfec89d0418593a8abaaf55d02eaa1ca"},
 };
 
 INSTANTIATE_TEST_CASE_P (DecodeFile, DecoderOutputTest,
--- a/test/decoder/DecUT_DecExt.cpp
+++ b/test/decoder/DecUT_DecExt.cpp
@@ -65,6 +65,8 @@
   void TestGetDecStatistics();
   //DECODER_OPTION_GET_SAR_INFO
   void TestGetDecSarInfo();
+  //Additional test on correctness of vui in subset sps
+  void TestVuiInSubsetSps();
   //Do whole tests here
   void DecoderInterfaceAll();
 
@@ -636,6 +638,28 @@
   Uninit();
 }
 
+//DECODER_OPTION_GET_SAR_INFO, test Vui in subset sps
+void DecoderInterfaceTest::TestVuiInSubsetSps() {
+  int32_t iRet;
+  SVuiSarInfo sVuiSarInfo;
+
+  iRet = ValidInit();
+  ASSERT_EQ (iRet, ERR_NONE);
+
+  //GetOption before decoding
+  m_pDec->GetOption (DECODER_OPTION_GET_SAR_INFO, &sVuiSarInfo);
+  EXPECT_EQ (0u, sVuiSarInfo.uiSarWidth);
+  EXPECT_EQ (0u, sVuiSarInfo.uiSarHeight);
+  EXPECT_EQ (sVuiSarInfo.bOverscanAppropriateFlag, false);
+
+  DecoderBs ("res/sps_subsetsps_bothVUI.264");
+  m_pDec->GetOption (DECODER_OPTION_GET_SAR_INFO, &sVuiSarInfo);
+  EXPECT_EQ (1u, sVuiSarInfo.uiSarWidth); //DO NOT MODIFY the data value
+  EXPECT_EQ (1u, sVuiSarInfo.uiSarHeight); //DO NOT MODIFY the data value
+  EXPECT_EQ (sVuiSarInfo.bOverscanAppropriateFlag, false); //DO NOT MODIFY the data value
+  Uninit();
+}
+
 //TEST here for whole tests
 TEST_F (DecoderInterfaceTest, DecoderInterfaceAll) {
 
@@ -667,6 +691,8 @@
   TestGetDecStatistics();
   //DECODER_OPTION_GET_SAR_INFO
   TestGetDecSarInfo();
+  //DECODER_OPTION_GET_SAR_INFO with vui in subsetsps
+  TestVuiInSubsetSps();
 }
 
 
--- a/test/decoder/DecUT_ParseSyntax.cpp
+++ b/test/decoder/DecUT_ParseSyntax.cpp
@@ -259,8 +259,16 @@
     {10, 14, 20, 24, 14, 20, 24, 27, 20, 24, 27, 30, 24, 27, 30, 34 },
     { 9, 13, 18, 21, 13, 18, 21, 24, 18, 21, 24, 27, 21, 24, 27, 27 }
   };
-  uint8_t iScalingListPPS[6][16];
-  memset (iScalingListPPS, 0, 6 * 16 * sizeof (uint8_t));
+  uint8_t iScalingListPPS[6][16] = {
+    { 17, 17, 16, 16, 17, 16, 15, 15, 16, 15, 15, 15, 16, 15, 15, 15 },
+    { 6, 12, 19, 26, 12, 19, 26, 31, 19, 26, 31, 35, 26, 31, 35, 39 },
+    { 6, 12, 19, 26, 12, 19, 26, 31, 19, 26, 31, 35, 26, 31, 35, 40 },
+    { 17, 17, 16, 16, 17, 16, 15, 15, 16, 15, 15, 15, 16, 15, 15, 14 },
+    { 10, 14, 20, 24, 14, 20, 24, 27, 20, 24, 27, 30, 24, 27, 30, 34 },
+    { 9, 13, 18, 21, 13, 18, 21, 24, 18, 21, 24, 27, 21, 24, 27, 27 }
+  };
+  uint8_t iScalingListZero[6][16];
+  memset (iScalingListZero, 0, 6 * 16 * sizeof (uint8_t));
   //Scalinglist matrix not written into sps or pps
   int32_t iRet = ERR_NONE;
   iRet = Init();
@@ -267,9 +275,9 @@
   ASSERT_EQ (iRet, ERR_NONE);
   DecodeBs ("res/BA_MW_D.264");
   ASSERT_TRUE (m_pCtx->sSpsBuffer[0].bSeqScalingMatrixPresentFlag == false);
-  EXPECT_EQ (0, memcmp (iScalingListPPS, m_pCtx->sSpsBuffer[0].iScalingList4x4, 6 * 16 * sizeof (uint8_t)));
+  EXPECT_EQ (0, memcmp (iScalingListZero, m_pCtx->sSpsBuffer[0].iScalingList4x4, 6 * 16 * sizeof (uint8_t)));
   ASSERT_TRUE (m_pCtx->sPpsBuffer[0].bPicScalingMatrixPresentFlag == false);
-  EXPECT_EQ (0, memcmp (iScalingListPPS, m_pCtx->sPpsBuffer[0].iScalingList4x4, 6 * 16 * sizeof (uint8_t)));
+  EXPECT_EQ (0, memcmp (iScalingListZero, m_pCtx->sPpsBuffer[0].iScalingList4x4, 6 * 16 * sizeof (uint8_t)));
   Uninit();
   //Scalinglist value just written into sps and pps
   iRet = Init();
@@ -280,8 +288,10 @@
     EXPECT_EQ (0, memcmp (iScalingList[i], m_pCtx->sSpsBuffer[0].iScalingList4x4[i], 16 * sizeof (uint8_t)));
   }
 
-  ASSERT_TRUE (m_pCtx->sPpsBuffer[0].bPicScalingMatrixPresentFlag == false);
-  EXPECT_EQ (0, memcmp (iScalingListPPS, m_pCtx->sPpsBuffer[0].iScalingList4x4, 6 * 16 * sizeof (uint8_t)));
+  ASSERT_TRUE (m_pCtx->sPpsBuffer[0].bPicScalingMatrixPresentFlag == true);
+  for (int i = 0; i < 6; i++) {
+    EXPECT_EQ (0, memcmp (iScalingListPPS[i], m_pCtx->sPpsBuffer[0].iScalingList4x4[i], 16 * sizeof (uint8_t)));
+  }
   Uninit();
 }