From eb5cdb32b1c7df6504b3339a83fcbd7849983096 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Fri, 2 Sep 2016 14:43:33 +0200 Subject: [PATCH] Added more H264 SPS decoding --- lib/h264.cpp | 61 ++++++++++++++++++++++++++++++++++++---------------- lib/h264.h | 7 ++++++ 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/lib/h264.cpp b/lib/h264.cpp index 79101e05..97bd6320 100644 --- a/lib/h264.cpp +++ b/lib/h264.cpp @@ -88,15 +88,27 @@ namespace h264 { dataLen = Bit::btohs(dtscInit.data() + 6); } + void skipScalingList(Utils::bitstream & bs, size_t listSize){ + size_t lastScale = 8; + size_t nextScale = 8; + for (size_t i = 0; i < listSize; i++){ + if (nextScale){ + uint64_t deltaScale = bs.getExpGolomb(); + nextScale = (lastScale + deltaScale + 256) % 256; + } + lastScale = (nextScale ? nextScale : lastScale); + } + } + SPSMeta sequenceParameterSet::getCharacteristics() const { SPSMeta result; + result.sep_col_plane = false; //For calculating width unsigned int widthInMbs = 0; unsigned int cropHorizontal = 0; //For calculating height - bool mbsOnlyFlag = 0; unsigned int heightInMapUnits = 0; unsigned int cropVertical = 0; @@ -121,33 +133,44 @@ namespace h264 { bs.getUExpGolomb(); if (profileIdc == 100 || profileIdc == 110 || profileIdc == 122 || profileIdc == 244 || profileIdc == 44 || profileIdc == 83 || profileIdc == 86 || profileIdc == 118 || profileIdc == 128) { //chroma format idc - if (bs.getUExpGolomb() == 3) { - bs.skip(1); + char chromaFormatIdc = bs.getUExpGolomb(); + if (chromaFormatIdc == 3) { + result.sep_col_plane = (bs.get(1) == 1); } - bs.getUExpGolomb(); - bs.getUExpGolomb(); - bs.skip(1); - if (bs.get(1)) { - DEBUG_MSG(DLVL_DEVEL, "Scaling matrix not implemented yet"); + bs.getUExpGolomb();//luma + bs.getUExpGolomb();//chroma + bs.skip(1);//transform bypass + if (bs.get(1)) {//Scaling matrix is present + char listSize = (chromaFormatIdc == 3 ? 12 : 8); + for (size_t i = 0; i < listSize; i++){ + bool thisListPresent = bs.get(1); + if (thisListPresent){ + if (i < 6){ + skipScalingList(bs, 16); + }else{ + skipScalingList(bs, 64); + } + } + } } } - bs.getUExpGolomb(); - unsigned int pic_order_cnt_type = bs.getUExpGolomb(); - if (!pic_order_cnt_type) { - bs.getUExpGolomb(); - } else if (pic_order_cnt_type == 1) { + result.log2_max_frame_num = bs.getUExpGolomb() + 4; + result.cnt_type = bs.getUExpGolomb(); + if (!result.cnt_type) { + result.log2_max_order_cnt = bs.getUExpGolomb() + 4; + } else if (result.cnt_type == 1) { DEBUG_MSG(DLVL_DEVEL, "This part of the implementation is incomplete(2), to be continued. If this message is shown, contact developers immediately."); } - bs.getUExpGolomb(); - bs.skip(1); - //Stop skipping data and start doing usefull stuff + result.max_ref_frames = bs.getUExpGolomb();//max_num_ref_frames + result.gaps = (bs.get(1) == 1);//gaps in frame num allowed + //Stop skipping data and start doing useful stuff widthInMbs = bs.getUExpGolomb() + 1; heightInMapUnits = bs.getUExpGolomb() + 1; - mbsOnlyFlag = bs.get(1);//Gets used in height calculation - if (!mbsOnlyFlag) { + result.mbs_only = (bs.get(1) == 1);//Gets used in height calculation + if (!result.mbs_only) { bs.skip(1); } bs.skip(1); @@ -191,7 +214,7 @@ namespace h264 { } result.width = (widthInMbs * 16) - (cropHorizontal * 2); - result.height = ((mbsOnlyFlag ? 1 : 2) * heightInMapUnits * 16) - (cropVertical * 2); + result.height = ((result.mbs_only ? 1 : 2) * heightInMapUnits * 16) - (cropVertical * 2); return result; } diff --git a/lib/h264.h b/lib/h264.h index 48fcfcc9..0afd0540 100644 --- a/lib/h264.h +++ b/lib/h264.h @@ -14,6 +14,13 @@ namespace h264 { double fps; uint8_t profile; uint8_t level; + bool sep_col_plane; + uint8_t cnt_type; + bool gaps;///< Gaps in frame num allowed flag + bool mbs_only;///