Tag Parser 12.3.1
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
Loading...
Searching...
No Matches
mpegaudioframestream.cpp
Go to the documentation of this file.
2
3#include "../exceptions.h"
4#include "../mediaformat.h"
5
6#include <c++utilities/conversion/stringbuilder.h>
7
8#include <sstream>
9
10using namespace std;
11using namespace CppUtilities;
12
13namespace TagParser {
14
24{
25 track.m_version = frame.mpegVersion();
26 track.m_format = MediaFormat(GeneralMediaFormat::Mpeg1Audio, static_cast<unsigned char>(frame.layer()));
28 track.m_channelConfig = static_cast<std::uint8_t>(frame.channelMode());
30}
31
33{
34 CPP_UTILITIES_UNUSED(progress)
35
36 static const string context("parsing MPEG audio frame header");
37 if (!m_istream) {
39 }
40 // parse frames until the first valid, non-empty frame is reached
41 m_istream->seekg(static_cast<std::streamoff>(m_startOffset), ios_base::beg);
42 for (size_t invalidByteskipped = 0; m_frames.size() < 200 && invalidByteskipped <= 0x600u;) {
43 MpegAudioFrame &frame = invalidByteskipped > 0 ? m_frames.back() : m_frames.emplace_back();
44 try {
45 frame.parseHeader(m_reader, diag);
46 } catch (const InvalidDataException &) {
47 if (++invalidByteskipped > 1) {
48 diag.pop_back();
49 }
50 m_istream->seekg(-3, ios_base::cur);
51 continue;
52 }
53 if (invalidByteskipped > 1) {
54 diag.emplace_back(DiagLevel::Critical, argsToString("The next ", invalidByteskipped, " bytes are junk as well."), context);
55 }
56 if (!frame.size()) {
57 continue; // likely just junk, check further frames
58 }
59 invalidByteskipped = 0;
60 if (frame.isProtectedByCrc()) {
61 m_istream->seekg(2, ios_base::cur);
62 }
63 break;
64 }
65 if (!m_frames.back().isValid()) {
66 return;
67 }
68 const MpegAudioFrame &frame = m_frames.back();
69 addInfo(frame, *this);
70 if (frame.isXingBytesfieldPresent()) {
71 const auto xingSize = frame.xingBytesfield();
72 if (!m_size) {
73 m_size = xingSize;
74 } else if (xingSize != m_size) {
75 diag.emplace_back(DiagLevel::Warning,
76 argsToString("Real size of MPEG audio frames (", m_size, " byte) is not in accordance with value provided by Xing header (", xingSize,
77 " byte). The real size will be used."),
78 context);
79 }
80 }
81 if (frame.isXingFramefieldPresent()) {
82 const auto duration = static_cast<double>(frame.xingFrameCount() * frame.sampleCount()) / static_cast<double>(frame.samplingFrequency());
83 m_bitrate = static_cast<double>(m_size) / duration / 125.0;
84 m_duration = TimeSpan::fromSeconds(duration);
85 } else {
86 m_bitrate = frame.bitrate();
87 m_duration = TimeSpan::fromSeconds(static_cast<double>(m_size) / (m_bytesPerSecond = static_cast<std::uint32_t>(m_bitrate * 125)));
88 }
89}
90
91} // namespace TagParser
The AbortableProgressFeedback class provides feedback about an ongoing operation via callbacks.
The AbstractTrack class parses and stores technical information about video, audio and other kinds of...
std::uint32_t m_bytesPerSecond
CppUtilities::TimeSpan m_duration
CppUtilities::BinaryReader m_reader
const CppUtilities::TimeSpan & duration() const
Returns the duration if known; otherwise returns a TimeSpan of zero ticks.
std::uint32_t m_samplingFrequency
The Diagnostics class is a container for DiagMessage.
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
The MediaFormat class specifies the format of media data.
static void addInfo(const MpegAudioFrame &frame, AbstractTrack &track)
Adds the information from the specified frame to the specified track.
void internalParseHeader(Diagnostics &diag, AbortableProgressFeedback &progress) override
This method is internally called to parse header information.
The MpegAudioFrame class is used to parse MPEG audio frames.
std::uint32_t size() const
Returns the size if known; otherwise returns 0.
std::uint32_t samplingFrequency() const
Returns the sampeling frequency of the frame if known; otherwise returns 0.
MpegChannelMode channelMode() const
Returns the channel mode if known; otherwise returns MpegChannelMode::Unspecifed.
constexpr bool isProtectedByCrc() const
Returns an indication whether the frame is protected by CRC.
std::uint32_t sampleCount() const
Returns the sample count if known; otherwise returns 0.
int layer() const
Returns the MPEG layer if known (1, 2, or 3); otherwise returns 0.
std::uint16_t bitrate() const
Returns the bitrate of the frame if known; otherwise returns 0.
constexpr std::uint32_t xingFrameCount() const
Returns an indication whether the Xing frame count is present.
constexpr bool isXingBytesfieldPresent() const
Returns an indication whether the Xing bytes field is present.
void parseHeader(CppUtilities::BinaryReader &reader, Diagnostics &diag)
Parses the header read using the specified reader.
double mpegVersion() const
Returns the MPEG version if known (1.0, 2.0 or 2.5); otherwise returns 0.
constexpr bool isXingFramefieldPresent() const
Returns an indication whether the Xing frame field is present.
constexpr std::uint32_t xingBytesfield() const
Returns the Xing bytes field if known; otherwise returns 0.
The exception that is thrown when the data to be parsed holds no parsable information (e....
Contains all classes and functions of the TagInfo library.
Definition aaccodebook.h:10