Tag Parser: avc/avcinfo.cpp Source File

Tag Parser 12.5.3 C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags

Loading...
Searching...
No Matches
avcinfo.cpp
Go to the documentation of this file.
1#include "./avcinfo.h"
2
3#include "../exceptions.h"
4
5#include <c++utilities/io/binaryreader.h>
6#include <c++utilities/io/bitreader.h>
7
8#include <memory>
9#include <unordered_map>
10
11using namespace std;
12using namespace CppUtilities;
13
14namespace TagParser {
15
20
24 void SpsInfo::parse(BinaryReader &reader, std::uint32_t maxSize)
25{
26 // read (and check) size
27 if ((maxSize < minSize) || (size = reader.readUInt16BE()) > (maxSize - minSize)) {
28 throw TruncatedDataException();
29 }
30
31 // buffer data for reading with BitReader
32 auto buffer = make_unique<char[]>(size);
33 reader.read(buffer.get(), size);
34 BitReader bitReader(buffer.get(), size);
35
36 try {
37 // read general values
38 bitReader.skipBits(3);
39 if (bitReader.readBits<std::uint8_t>(5) != 7) {
40 throw InvalidDataException();
41 }
42 profileIndication = bitReader.readBits<std::uint8_t>(8);
43 profileConstraints = bitReader.readBits<std::uint8_t>(8);
44 levelIndication = bitReader.readBits<std::uint8_t>(8);
45 id = bitReader.readUnsignedExpGolombCodedBits<ugolomb>();
46
47 // read chroma profile specific values
48 switch (profileIndication) {
49 case 44:
50 case 83:
51 case 86:
52 case 100:
53 case 110:
54 case 118:
55 case 122:
56 case 128:
57 case 244:
58 // high-level profile
59 if ((chromaFormatIndication = bitReader.readUnsignedExpGolombCodedBits<ugolomb>()) == 3) {
60 bitReader.skipBits(1); // separate color plane flag
61 }
62 bitReader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // bit depth luma minus8
63 bitReader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // bit depth chroma minus8
64 bitReader.skipBits(1); // qpprime y zero transform bypass flag
65 if (bitReader.readBit()) { // sequence scaling matrix present flag
66 for (std::uint8_t i = 0; i < 8; ++i) {
67 // TODO: store values
68 if (bitReader.readBit()) { // sequence scaling list present
69 if (i < 6) {
70 bitReader.skipBits(16); // scalingList4x4[i]
71 } else {
72 bitReader.skipBits(64); // scalingList8x8[i - 6]
73 }
74 }
75 }
76 }
77 break;
78 default:
79 chromaFormatIndication = 1; // assume YUV 4:2:0
80 }
81
82 // read misc values
83 log2MaxFrameNum = bitReader.readUnsignedExpGolombCodedBits<ugolomb>() + 4;
84 switch (pictureOrderCountType = bitReader.readUnsignedExpGolombCodedBits<ugolomb>()) {
85 case 0:
86 log2MaxPictureOrderCountLsb = bitReader.readUnsignedExpGolombCodedBits<ugolomb>() + 4;
87 break;
88 case 1:
89 deltaPicOrderAlwaysZeroFlag = bitReader.readBit();
90 offsetForNonRefPic = bitReader.readSignedExpGolombCodedBits<sgolomb>();
91 offsetForTopToBottomField = bitReader.readSignedExpGolombCodedBits<sgolomb>();
92 numRefFramesInPicOrderCntCycle = bitReader.readUnsignedExpGolombCodedBits<ugolomb>();
93 for (std::uint8_t i = 0; i < numRefFramesInPicOrderCntCycle; ++i) {
94 bitReader.readUnsignedExpGolombCodedBits<ugolomb>(); // offset for ref frames
95 }
96 break;
97 case 2:
98 break;
99 default:
100 throw InvalidDataException();
101 }
102 bitReader.readUnsignedExpGolombCodedBits<ugolomb>(); // ref frames num
103 bitReader.skipBits(1); // gaps in frame num value allowed flag
104
105 // read picture size related values
106 Size mbSize;
107 mbSize.setWidth(bitReader.readUnsignedExpGolombCodedBits<std::uint32_t>() + 1);
108 mbSize.setHeight(bitReader.readUnsignedExpGolombCodedBits<std::uint32_t>() + 1);
109 if (!(frameMbsOnly = bitReader.readBit())) { // frame mbs only flag
110 bitReader.readBit(); // mb adaptive frame field flag
111 }
112 bitReader.skipBits(1); // distinct 8x8 inference flag
113
114 // read cropping values
115 if (bitReader.readBit()) { // frame cropping flag
116 cropping.setLeft(bitReader.readUnsignedExpGolombCodedBits<std::uint32_t>());
117 cropping.setRight(bitReader.readUnsignedExpGolombCodedBits<std::uint32_t>());
118 cropping.setTop(bitReader.readUnsignedExpGolombCodedBits<std::uint32_t>());
119 cropping.setBottom(bitReader.readUnsignedExpGolombCodedBits<std::uint32_t>());
120 }
121
122 // calculate actual picture size
123 if (!cropping.isNull()) {
124 // determine cropping scale
125 ugolomb croppingScaleX, croppingScaleY;
126 switch (chromaFormatIndication) {
127 case 1: // 4:2:0
128 croppingScaleX = 2;
129 croppingScaleY = frameMbsOnly ? 2 : 4;
130 break;
131 case 2: // 4:2:2
132 croppingScaleX = 2;
133 croppingScaleY = 2 - frameMbsOnly;
134 break;
135 default: // case 0: monochrome, case 3: 4:4:4
136 croppingScaleX = 1;
137 croppingScaleY = 2 - frameMbsOnly;
138 break;
139 }
140 pictureSize.setWidth(mbSize.width() * 16 - croppingScaleX * (cropping.left() + cropping.right()));
141 pictureSize.setHeight((2 - frameMbsOnly) * mbSize.height() * 16 - croppingScaleY * (cropping.top() + cropping.bottom()));
142 } else {
143 pictureSize.setWidth(mbSize.width() * 16);
144 pictureSize.setHeight((2 - frameMbsOnly) * mbSize.height() * 16);
145 }
146
147 // read VUI (video usability information)
148 if ((vuiPresent = bitReader.readBit())) {
149 if ((bitReader.readBit())) { // PAR present flag
150 pixelAspectRatio = AspectRatio(bitReader.readBits<std::uint8_t>(8));
151 if (pixelAspectRatio.isExtended()) {
152 // read extended SAR
153 pixelAspectRatio.numerator = bitReader.readBits<std::uint16_t>(16);
154 pixelAspectRatio.denominator = bitReader.readBits<std::uint16_t>(16);
155 }
156 }
157
158 // read/skip misc values
159 if (bitReader.readBit()) { // overscan info present
160 bitReader.skipBits(1); // overscan appropriate
161 }
162 if (bitReader.readBit()) { // video signal type present
163 bitReader.skipBits(4); // video format and video full range
164 if (bitReader.readBit()) { // color description present
165 bitReader.skipBits(24); // color primaries, transfer characteristics, matrix coefficients
166 }
167 }
168 if (bitReader.readBit()) { // chroma loc info present
169 bitReader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // chroma sample loc type top field
170 bitReader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // chroma sample loc type bottom field
171 }
172
173 // read timing info
174 if ((timingInfo.isPresent = bitReader.readBit())) {
175 timingInfo.unitsInTick = bitReader.readBits<std::uint32_t>(32);
176 timingInfo.timeScale = bitReader.readBits<std::uint32_t>(32);
177 timingInfo.fixedFrameRate = bitReader.readBit();
178 }
179
180 // skip hrd parameters
181 hrdParametersPresent = 0;
182 if (bitReader.readBit()) { // nal hrd parameters present
183 nalHrdParameters.parse(bitReader);
184 hrdParametersPresent = 1;
185 }
186 if (bitReader.readBit()) { // vcl hrd parameters present
187 vclHrdParameters.parse(bitReader);
188 hrdParametersPresent = 1;
189 }
190 if (hrdParametersPresent) {
191 bitReader.skipBits(1); // low delay hrd flag
192 }
193
194 pictureStructPresent = bitReader.readBit();
195
196 // TODO: investigate error (truncated data) when parsing mtx-test-data/mkv/attachment-without-fileuid.mkv
197 if (bitReader.readBit()) { // bitstream restriction flag
198 bitReader.skipBits(1); // motion vectors over pic boundaries flag
199 bitReader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // max bytes per pic denom
200 bitReader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // max bytes per mb denom
201 bitReader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // log2 max mv length horizontal
202 bitReader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // log2 max mv length vertical
203 bitReader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // reorder frames num
204 bitReader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // max decoder frame buffering
205 }
206 }
207
208 } catch (const std::ios_base::failure &) {
209 throw TruncatedDataException();
210 }
211}
212
217
221 void PpsInfo::parse(BinaryReader &reader, std::uint32_t maxSize)
222{
223 // read (and check) size
224 if ((maxSize < minSize) || (size = reader.readUInt16BE()) > (maxSize - minSize)) {
225 throw TruncatedDataException();
226 }
227
228 // buffer data for reading with BitReader
229 auto buffer = make_unique<char[]>(size);
230 reader.read(buffer.get(), size);
231 BitReader bitReader(buffer.get(), size);
232
233 try {
234 // read general values
235 bitReader.skipBits(1); // zero bit
236 if (bitReader.readBits<std::uint8_t>(5) != 8) { // nal unit type
237 throw NotImplementedException();
238 }
239 id = bitReader.readUnsignedExpGolombCodedBits<ugolomb>();
240 spsId = bitReader.readUnsignedExpGolombCodedBits<ugolomb>();
241 bitReader.skipBits(1); // entropy coding mode flag
242 picOrderPresent = bitReader.readBit();
243 } catch (const std::ios_base::failure &) {
244 throw TruncatedDataException();
245 }
246}
247
253
257 void HrdParameters::parse(CppUtilities::BitReader &reader)
258{
259 cpbCount = reader.readUnsignedExpGolombCodedBits<ugolomb>() + 1;
260 bitRateScale = reader.readBits<std::uint8_t>(4);
261 cpbSizeScale = reader.readBits<std::uint8_t>(4);
262 for (ugolomb i = 0; i < cpbCount; ++i) {
263 // just skip those values
264 reader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // bit rate value minus 1
265 reader.readUnsignedExpGolombCodedBits<std::uint8_t>(); // cpb size value minus 1
266 reader.skipBits(1); // cbr flag
267 }
268 initialCpbRemovalDelayLength = reader.readBits<std::uint8_t>(5) + 1;
269 cpbRemovalDelayLength = reader.readBits<std::uint8_t>(5) + 1;
270 cpbOutputDelayLength = reader.readBits<std::uint8_t>(5) + 1;
271 timeOffsetLength = reader.readBits<std::uint8_t>(5);
272}
273
278
284
290
291} // namespace TagParser
avcinfo.h
TagParser::InvalidDataException
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
Definition exceptions.h:25
TagParser::NotImplementedException
This exception is thrown when the an operation is invoked that has not been implemented yet.
Definition exceptions.h:60
TagParser::Size
The Size class defines the size of a two-dimensional object using integer point precision.
Definition size.h:17
TagParser::Size::height
constexpr std::uint32_t height() const
Returns the height.
Definition size.h:68
TagParser::Size::setWidth
void setWidth(std::uint32_t value)
Sets the width.
Definition size.h:76
TagParser::Size::width
constexpr std::uint32_t width() const
Returns the width.
Definition size.h:60
TagParser::Size::setHeight
void setHeight(std::uint32_t value)
Sets the height.
Definition size.h:84
TagParser::TruncatedDataException
The exception that is thrown when the data to be parsed is truncated and therefore can not be parsed ...
Definition exceptions.h:39
exceptions.h
CppUtilities
Definition abstractcontainer.h:16
TagParser
Contains all classes and functions of the TagInfo library.
Definition aaccodebook.h:10
TagParser::ugolomb
std::uint32_t ugolomb
Type used to store unsigned integer values using golomb coding.
Definition avcinfo.h:18
TagParser::sgolomb
std::int32_t sgolomb
Type used to store signed integer values using golomb coding.
Definition avcinfo.h:23
TagParser::AspectRatio
The AspectRatio struct defines an aspect ratio.
Definition aspectratio.h:13
TagParser::HrdParameters::initialCpbRemovalDelayLength
std::uint8_t initialCpbRemovalDelayLength
Definition avcinfo.h:52
TagParser::HrdParameters::bitRateScale
std::uint8_t bitRateScale
Definition avcinfo.h:50
TagParser::HrdParameters::parse
void parse(CppUtilities::BitReader &reader)
Parses HRD parameters.
Definition avcinfo.cpp:257
TagParser::HrdParameters::cpbRemovalDelayLength
std::uint8_t cpbRemovalDelayLength
Definition avcinfo.h:53
TagParser::HrdParameters::timeOffsetLength
std::uint8_t timeOffsetLength
Definition avcinfo.h:55
TagParser::HrdParameters::cpbOutputDelayLength
std::uint8_t cpbOutputDelayLength
Definition avcinfo.h:54
TagParser::HrdParameters::cpbSizeScale
std::uint8_t cpbSizeScale
Definition avcinfo.h:51
TagParser::HrdParameters::cpbCount
ugolomb cpbCount
Definition avcinfo.h:49
TagParser::PpsInfo::picOrderPresent
std::uint8_t picOrderPresent
Definition avcinfo.h:126
TagParser::PpsInfo::spsId
ugolomb spsId
Definition avcinfo.h:125
TagParser::PpsInfo::parse
void parse(CppUtilities::BinaryReader &reader, std::uint32_t maxSize)
Parses the PPS info.
Definition avcinfo.cpp:221
TagParser::PpsInfo::minSize
static constexpr std::uint16_t minSize
Definition avcinfo.h:128
TagParser::PpsInfo::size
std::uint16_t size
Definition avcinfo.h:127
TagParser::SpsInfo::deltaPicOrderAlwaysZeroFlag
std::uint8_t deltaPicOrderAlwaysZeroFlag
Definition avcinfo.h:84
TagParser::SpsInfo::pictureOrderCountType
ugolomb pictureOrderCountType
Definition avcinfo.h:78
TagParser::SpsInfo::parse
void parse(CppUtilities::BinaryReader &reader, std::uint32_t maxSize)
Parses the SPS info.
Definition avcinfo.cpp:24
TagParser::SpsInfo::pixelAspectRatio
AspectRatio pixelAspectRatio
Definition avcinfo.h:87
TagParser::SpsInfo::vclHrdParameters
HrdParameters vclHrdParameters
Definition avcinfo.h:93
TagParser::SpsInfo::nalHrdParameters
HrdParameters nalHrdParameters
Definition avcinfo.h:92
TagParser::SpsInfo::timingInfo
TimingInfo timingInfo
Definition avcinfo.h:88
TagParser::SpsInfo::cropping
Margin cropping
Definition avcinfo.h:89
TagParser::SpsInfo::frameMbsOnly
std::uint8_t frameMbsOnly
Definition avcinfo.h:85
TagParser::SpsInfo::hrdParametersPresent
std::uint8_t hrdParametersPresent
Definition avcinfo.h:91
TagParser::SpsInfo::vuiPresent
std::uint8_t vuiPresent
Definition avcinfo.h:86
TagParser::SpsInfo::minSize
static constexpr std::uint16_t minSize
Definition avcinfo.h:96
TagParser::SpsInfo::log2MaxPictureOrderCountLsb
ugolomb log2MaxPictureOrderCountLsb
Definition avcinfo.h:80
TagParser::SpsInfo::offsetForTopToBottomField
sgolomb offsetForTopToBottomField
Definition avcinfo.h:82
TagParser::SpsInfo::log2MaxFrameNum
ugolomb log2MaxFrameNum
Definition avcinfo.h:79
TagParser::SpsInfo::profileConstraints
std::uint8_t profileConstraints
Definition avcinfo.h:75
TagParser::SpsInfo::numRefFramesInPicOrderCntCycle
ugolomb numRefFramesInPicOrderCntCycle
Definition avcinfo.h:83
TagParser::SpsInfo::pictureSize
Size pictureSize
Definition avcinfo.h:90
TagParser::SpsInfo::profileIndication
std::uint8_t profileIndication
Definition avcinfo.h:74
TagParser::SpsInfo::levelIndication
std::uint8_t levelIndication
Definition avcinfo.h:76
TagParser::SpsInfo::size
std::uint16_t size
Definition avcinfo.h:95
TagParser::SpsInfo::offsetForNonRefPic
sgolomb offsetForNonRefPic
Definition avcinfo.h:81
TagParser::SpsInfo::pictureStructPresent
std::uint8_t pictureStructPresent
Definition avcinfo.h:94
TagParser::SpsInfo::chromaFormatIndication
ugolomb chromaFormatIndication
Definition avcinfo.h:77