12 virtual void parseNal(
const std::vector<std::uint8_t>& bs,
unsigned int start, std::vector<SliceType>& out) = 0;
13 std::vector<SliceType>
parseBytestream(
const std::vector<std::uint8_t>& bs,
bool breakOnFirst);
16 static std::vector<SliceType>
getTypes(
const std::vector<std::uint8_t>& bs,
bool breakOnFirst);
21 void parseNal(
const std::vector<std::uint8_t>& bs,
unsigned int start, std::vector<SliceType>& out);
35 void parseNal(
const std::vector<std::uint8_t>& bs,
unsigned int start, std::vector<SliceType>& out);
40 typedef const std::vector<std::uint8_t>
buf;
81 if(bs.size() - pos > code.size()) {
82 for(
uint i = 0; i < code.size(); ++i) {
83 if(bs[pos + i] != code[i])
return false;
91 buf codeLong = {0, 0, 0, 1};
92 buf codeShort = {0, 0, 1};
98 }
else if(
scodeEq(bs, i, codeShort)) {
107 buf end1 = {0, 0, 0};
108 buf end2 = {0, 0, 1};
122 for(
ulong i = start; i < end; ++i) {
123 uint bit = (bs[(
uint)(i / 8)] & (1 << (7 - i % 8))) > 0;
124 ret += bit * (1 << (end - i - 1));
133 std::uint8_t bit = bs[(
uint)(pos / 8)] & (char)(1 << (7 - pos % 8));
142 ulong end = pos + count;
143 if(end >
size) exit(30);
144 return std::make_tuple(
readUint(bs, start, end) - 1, end);
147 template <
typename T>
150 return p.parseBytestream(
buffer, breakOnFirst);
153 template <
typename T>
157 std::vector<SliceType> ret;
161 if(start >= end)
break;
162 parseNal(bs, start, ret);
164 if(breakOnFirst && ret.size() > 0)
break;
171 uint nalUnitType = bs[pos++] & 31;
172 uint nalUnitHeaderBytes = 1;
173 if(nalUnitType == 14 || nalUnitType == 20 || nalUnitType == 21) {
174 uint avc3dExtensionFlag = 0;
175 if(nalUnitType == 21) avc3dExtensionFlag =
readUint(bs, pos * 8, pos * 8 + 1);
176 if(avc3dExtensionFlag)
177 nalUnitHeaderBytes += 2;
179 nalUnitHeaderBytes += 3;
181 pos = start + nalUnitHeaderBytes;
182 if(nalUnitType == 1 || nalUnitType == 5) {
183 const auto bpos1 = std::get<1>(
readGE(bs, pos * 8));
186 std::tie(tyNum, bpos2) =
readGE(bs, bpos1);
187 pos = (
uint)(bpos2 / 8) + (bpos2 % 8 > 0);
194 uint pos = start + 2;
197 uint spsMaxSubLayersMinus1 = (bs[pos] & 14) >> 1;
199 const auto bpos1 = std::get<1>(
readGE(bs, pos * 8));
202 std::tie(chr, bpos2) =
readGE(bs, bpos1);
207 std::tie(pw, bpos3) =
readGE(bs, bpos2);
210 std::tie(ph, bpos4) =
readGE(bs, bpos3);
213 uint conformanceWindowFlag =
readUint(bs, bpos4, bpos4 + 1);
214 ulong bpos8 = ++bpos4;
215 if(conformanceWindowFlag) {
217 auto bpos5 = std::get<1>(
readGE(bs, bpos4));
218 auto bpos6 = std::get<1>(
readGE(bs, bpos5));
219 auto bpos7 = std::get<1>(
readGE(bs, bpos6));
220 auto tbpos8 = std::get<1>(
readGE(bs, bpos7));
223 auto bpos9 = std::get<1>(
readGE(bs, bpos8));
224 auto bpos10 = std::get<1>(
readGE(bs, bpos9));
225 auto bpos11 = std::get<1>(
readGE(bs, bpos10));
226 uint spsSubLayerOrderingInfoPresentFlag =
readUint(bs, bpos11, bpos11 + 1);
227 ulong bpos12 = ++bpos11;
228 for(
uint i = spsSubLayerOrderingInfoPresentFlag ? 0 : spsMaxSubLayersMinus1; i <= spsMaxSubLayersMinus1; ++i) {
229 auto tbpos1 = std::get<1>(
readGE(bs, bpos12));
230 auto tbpos2 = std::get<1>(
readGE(bs, tbpos1));
231 auto tbpos3 = std::get<1>(
readGE(bs, tbpos2));
235 ulong bpos13, bpos14;
236 std::tie(lm, bpos13) =
readGE(bs, bpos12);
237 std::tie(ldm, bpos14) =
readGE(bs, bpos13);
240 pos = (
uint)(bpos14 / 8) + (bpos14 % 8 > 0);
243 auto bpos1 = std::get<1>(
readGE(bs, pos * 8));
244 auto bpos2 = std::get<1>(
readGE(bs, bpos1));
249 pos = (
uint)(bpos2 / 8) + (bpos2 % 8 > 0);
252 ulong bpos1 = pos * 8;
253 uint firstSliceSegmentInPicFlag =
readUint(bs, bpos1, bpos1 + 1);
256 auto bpos2 = std::get<1>(
readGE(bs, bpos1));
257 uint dependentSliceSegmentFlag = 0;
258 if(!firstSliceSegmentInPicFlag) {
260 dependentSliceSegmentFlag =
readUint(bs, bpos2, bpos2 + 1);
264 uint ctbSizeY = 1 << ctbLog2SizeY;
267 uint picSizeInCtbsY = picWidthInCtbsY * picHeightInCtbsY;
268 uint vlen = ceil(log2(picSizeInCtbsY));
272 if(!dependentSliceSegmentFlag) {
276 std::tie(tyNum, tbpos3) =
readGE(bs, bpos2);
280 pos = (
uint)(bpos3 / 8) + (bpos3 % 8 > 0);