summaryrefslogtreecommitdiffstats
path: root/chromium/media/formats/mpeg/adts_stream_parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/formats/mpeg/adts_stream_parser.cc')
-rw-r--r--chromium/media/formats/mpeg/adts_stream_parser.cc99
1 files changed, 99 insertions, 0 deletions
diff --git a/chromium/media/formats/mpeg/adts_stream_parser.cc b/chromium/media/formats/mpeg/adts_stream_parser.cc
new file mode 100644
index 00000000000..beb94350c9c
--- /dev/null
+++ b/chromium/media/formats/mpeg/adts_stream_parser.cc
@@ -0,0 +1,99 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/formats/mpeg/adts_stream_parser.h"
+
+#include "media/formats/mpeg/adts_constants.h"
+
+namespace media {
+
+static const uint32 kADTSStartCodeMask = 0xfff00000;
+
+ADTSStreamParser::ADTSStreamParser()
+ : MPEGAudioStreamParserBase(kADTSStartCodeMask, kCodecAAC, 0) {}
+
+ADTSStreamParser::~ADTSStreamParser() {}
+
+int ADTSStreamParser::ParseFrameHeader(const uint8* data,
+ int size,
+ int* frame_size,
+ int* sample_rate,
+ ChannelLayout* channel_layout,
+ int* sample_count,
+ bool* metadata_frame) const {
+ DCHECK(data);
+ DCHECK_GE(size, 0);
+ DCHECK(frame_size);
+
+ if (size < 8)
+ return 0;
+
+ BitReader reader(data, size);
+ int sync;
+ int version;
+ int layer;
+ int protection_absent;
+ int profile;
+ size_t sample_rate_index;
+ size_t channel_layout_index;
+ int frame_length;
+ size_t num_data_blocks;
+ int unused;
+
+ if (!reader.ReadBits(12, &sync) ||
+ !reader.ReadBits(1, &version) ||
+ !reader.ReadBits(2, &layer) ||
+ !reader.ReadBits(1, &protection_absent) ||
+ !reader.ReadBits(2, &profile) ||
+ !reader.ReadBits(4, &sample_rate_index) ||
+ !reader.ReadBits(1, &unused) ||
+ !reader.ReadBits(3, &channel_layout_index) ||
+ !reader.ReadBits(4, &unused) ||
+ !reader.ReadBits(13, &frame_length) ||
+ !reader.ReadBits(11, &unused) ||
+ !reader.ReadBits(2, &num_data_blocks) ||
+ (!protection_absent && !reader.ReadBits(16, &unused))) {
+ return -1;
+ }
+
+ DVLOG(2) << "Header data :" << std::hex
+ << " sync 0x" << sync
+ << " version 0x" << version
+ << " layer 0x" << layer
+ << " profile 0x" << profile
+ << " sample_rate_index 0x" << sample_rate_index
+ << " channel_layout_index 0x" << channel_layout_index;
+
+ const int bytes_read = reader.bits_read() / 8;
+ if (sync != 0xfff || layer != 0 || frame_length < bytes_read ||
+ sample_rate_index >= kADTSFrequencyTableSize ||
+ channel_layout_index >= kADTSChannelLayoutTableSize) {
+ MEDIA_LOG(log_cb()) << "Invalid header data :" << std::hex
+ << " sync 0x" << sync
+ << " version 0x" << version
+ << " layer 0x" << layer
+ << " sample_rate_index 0x" << sample_rate_index
+ << " channel_layout_index 0x" << channel_layout_index;
+ return -1;
+ }
+
+ if (sample_rate)
+ *sample_rate = kADTSFrequencyTable[sample_rate_index];
+
+ if (frame_size)
+ *frame_size = frame_length;
+
+ if (sample_count)
+ *sample_count = (num_data_blocks + 1) * kSamplesPerAACFrame;
+
+ if (channel_layout)
+ *channel_layout = kADTSChannelLayoutTable[channel_layout_index];
+
+ if (metadata_frame)
+ *metadata_frame = false;
+
+ return bytes_read;
+}
+
+} // namespace media