Tag Parser  10.0.1
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
avcconfiguration.cpp
Go to the documentation of this file.
1 #include "./avcconfiguration.h"
2 
3 #include "../diagnostics.h"
4 #include "../exceptions.h"
5 #include "../mediaformat.h"
6 
7 #include <c++utilities/io/binaryreader.h>
8 
9 #include <limits>
10 
11 using namespace std;
12 using namespace CppUtilities;
13 
14 namespace TagParser {
15 
25 void AvcConfiguration::parse(BinaryReader &reader, std::uint64_t maxSize, Diagnostics &diag)
26 {
27  if (maxSize < 7) {
28  throw TruncatedDataException();
29  }
30  maxSize -= 7;
31 
32  reader.stream()->seekg(1, ios_base::cur); // always 1
33  profileIndication = reader.readByte();
34  profileCompat = reader.readByte();
35  levelIndication = reader.readByte();
36  naluSizeLength = (reader.readByte() & 0x03) + 1;
37 
38  // read SPS info entries
39  std::uint8_t spsEntryCount = reader.readByte() & 0x0f;
40  std::uint8_t ignoredSpsEntries = 0;
41  spsInfos.reserve(spsEntryCount);
42  for (; spsEntryCount; --spsEntryCount) {
43  if (maxSize < SpsInfo::minSize) {
44  throw TruncatedDataException();
45  }
46  auto error = false;
47  try {
48  spsInfos.emplace_back().parse(
49  reader, maxSize > numeric_limits<std::uint32_t>::max() ? numeric_limits<std::uint32_t>::max() : static_cast<std::uint32_t>(maxSize));
50  } catch (const TruncatedDataException &) {
51  if (spsInfos.back().size > (maxSize - SpsInfo::minSize)) {
52  throw; // sps info looks bigger than bytes to read
53  }
54  error = true; // sps info exceeds denoted size
55  } catch (const Failure &) {
56  error = true;
57  }
58  maxSize -= spsInfos.back().size;
59  if (error) {
60  spsInfos.pop_back();
61  ++ignoredSpsEntries;
62  }
63  }
64 
65  // read PPS info entries
66  std::uint8_t ppsEntryCount = reader.readByte();
67  std::uint8_t ignoredPpsEntries = 0;
68  ppsInfos.reserve(ppsEntryCount);
69  for (; ppsEntryCount; --ppsEntryCount) {
70  if (maxSize < PpsInfo::minSize) {
71  throw TruncatedDataException();
72  }
73  auto error = false;
74  try {
75  ppsInfos.emplace_back().parse(
76  reader, maxSize > numeric_limits<std::uint32_t>::max() ? numeric_limits<std::uint32_t>::max() : static_cast<std::uint32_t>(maxSize));
77  } catch (const TruncatedDataException &) {
78  if (ppsInfos.back().size > (maxSize - PpsInfo::minSize)) {
79  throw; // pps info looks bigger than bytes to read
80  }
81  error = true; // pps info exceeds denoted size
82  } catch (const Failure &) {
83  error = true;
84  }
85  maxSize -= ppsInfos.back().size;
86  if (error) {
87  ppsInfos.pop_back();
88  ++ignoredPpsEntries;
89  }
90  }
91 
92  // log parsing errors
93  if (ignoredSpsEntries || ignoredPpsEntries) {
94  diag.emplace_back(DiagLevel::Debug,
95  argsToString(
96  "Ignored ", ignoredSpsEntries, " SPS entries and ", ignoredPpsEntries, " PPS entries. This AVC config is likely just not supported."),
97  "parsing AVC config");
98  }
99 
100  // ignore remaining data
101 }
102 
103 } // namespace TagParser
The Diagnostics class is a container for DiagMessage.
Definition: diagnostics.h:156
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
Definition: exceptions.h:11
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