Tag Parser 12.1.0
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
24void SpsInfo::parse(BinaryReader &reader, std::uint32_t maxSize)
25{
26 // read (and check) size
27 if ((maxSize < minSize) || (size = reader.readUInt16BE()) > (maxSize - minSize)) {
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) {
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));
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
182 if (bitReader.readBit()) { // nal hrd parameters present
183 nalHrdParameters.parse(bitReader);
185 }
186 if (bitReader.readBit()) { // vcl hrd parameters present
187 vclHrdParameters.parse(bitReader);
189 }
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 &) {
210 }
211}
212
221void PpsInfo::parse(BinaryReader &reader, std::uint32_t maxSize)
222{
223 // read (and check) size
224 if ((maxSize < minSize) || (size = reader.readUInt16BE()) > (maxSize - minSize)) {
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
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 &) {
245 }
246}
247
257void 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
291} // namespace TagParser
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
Definition exceptions.h:25
constexpr bool isNull() const
Returns true if all margins are is 0; otherwise returns false;.
Definition margin.h:115
constexpr std::uint32_t right() const
Returns the right margin.
Definition margin.h:99
constexpr std::uint32_t left() const
Returns the left margin.
Definition margin.h:67
void setRight(std::uint32_t right)
Sets the right margin to right.
Definition margin.h:107
constexpr std::uint32_t top() const
Returns the top margin.
Definition margin.h:51
constexpr std::uint32_t bottom() const
Returns the bottom margin.
Definition margin.h:83
void setLeft(std::uint32_t left)
Sets the left margin to left.
Definition margin.h:75
void setTop(std::uint32_t top)
Sets the top margin to top.
Definition margin.h:59
void setBottom(std::uint32_t bottom)
Sets the bottom margin to bottom.
Definition margin.h:91
This exception is thrown when the an operation is invoked that has not been implemented yet.
Definition exceptions.h:60
The Size class defines the size of a two-dimensional object using integer point precision.
Definition size.h:17
constexpr std::uint32_t height() const
Returns the height.
Definition size.h:68
void setWidth(std::uint32_t value)
Sets the width.
Definition size.h:76
constexpr std::uint32_t width() const
Returns the width.
Definition size.h:60
void setHeight(std::uint32_t value)
Sets the height.
Definition size.h:84
The exception that is thrown when the data to be parsed is truncated and therefore can not be parsed ...
Definition exceptions.h:39
Contains all classes and functions of the TagInfo library.
Definition aaccodebook.h:10
std::int32_t sgolomb
Type used to store signed integer values using golomb coding.
Definition avcinfo.h:23
std::uint32_t ugolomb
Type used to store unsigned integer values using golomb coding.
Definition avcinfo.h:18
The AspectRatio struct defines an aspect ratio.
Definition aspectratio.h:13
std::uint16_t numerator
Definition aspectratio.h:22
std::uint16_t denominator
Definition aspectratio.h:23
constexpr bool isExtended() const
Returns whether numerator and denominator must be read from extended SAR header.
Definition aspectratio.h:58
std::uint8_t initialCpbRemovalDelayLength
Definition avcinfo.h:52
std::uint8_t bitRateScale
Definition avcinfo.h:50
void parse(CppUtilities::BitReader &reader)
Parses HRD parameters.
Definition avcinfo.cpp:257
std::uint8_t cpbRemovalDelayLength
Definition avcinfo.h:53
std::uint8_t timeOffsetLength
Definition avcinfo.h:55
std::uint8_t cpbOutputDelayLength
Definition avcinfo.h:54
std::uint8_t cpbSizeScale
Definition avcinfo.h:51
std::uint8_t picOrderPresent
Definition avcinfo.h:126
void parse(CppUtilities::BinaryReader &reader, std::uint32_t maxSize)
Parses the PPS info.
Definition avcinfo.cpp:221
static constexpr std::uint16_t minSize
Definition avcinfo.h:128
std::uint16_t size
Definition avcinfo.h:127
std::uint8_t deltaPicOrderAlwaysZeroFlag
Definition avcinfo.h:84
ugolomb pictureOrderCountType
Definition avcinfo.h:78
void parse(CppUtilities::BinaryReader &reader, std::uint32_t maxSize)
Parses the SPS info.
Definition avcinfo.cpp:24
AspectRatio pixelAspectRatio
Definition avcinfo.h:87
HrdParameters vclHrdParameters
Definition avcinfo.h:93
HrdParameters nalHrdParameters
Definition avcinfo.h:92
TimingInfo timingInfo
Definition avcinfo.h:88
std::uint8_t frameMbsOnly
Definition avcinfo.h:85
std::uint8_t hrdParametersPresent
Definition avcinfo.h:91
std::uint8_t vuiPresent
Definition avcinfo.h:86
static constexpr std::uint16_t minSize
Definition avcinfo.h:96
ugolomb log2MaxPictureOrderCountLsb
Definition avcinfo.h:80
sgolomb offsetForTopToBottomField
Definition avcinfo.h:82
ugolomb log2MaxFrameNum
Definition avcinfo.h:79
std::uint8_t profileConstraints
Definition avcinfo.h:75
ugolomb numRefFramesInPicOrderCntCycle
Definition avcinfo.h:83
std::uint8_t profileIndication
Definition avcinfo.h:74
std::uint8_t levelIndication
Definition avcinfo.h:76
std::uint16_t size
Definition avcinfo.h:95
sgolomb offsetForNonRefPic
Definition avcinfo.h:81
std::uint8_t pictureStructPresent
Definition avcinfo.h:94
ugolomb chromaFormatIndication
Definition avcinfo.h:77
std::uint8_t isPresent
Definition avcinfo.h:29
std::uint8_t fixedFrameRate
Definition avcinfo.h:30
std::uint32_t unitsInTick
Definition avcinfo.h:27
std::uint32_t timeScale
Definition avcinfo.h:28