diff options
author | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-17 00:08:40 +0000 |
---|---|---|
committer | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-17 00:08:40 +0000 |
commit | 7ae09bee4a843369b1a5b8a459ddb2b556ae24fd (patch) | |
tree | 7726f5e5f1fdfee15ae98817e7c255b5254943f9 /media/mp4 | |
parent | 17bcc311f6e378e7c47389a073de53a4d798c7e8 (diff) | |
download | chromium_src-7ae09bee4a843369b1a5b8a459ddb2b556ae24fd.zip chromium_src-7ae09bee4a843369b1a5b8a459ddb2b556ae24fd.tar.gz chromium_src-7ae09bee4a843369b1a5b8a459ddb2b556ae24fd.tar.bz2 |
Revert 145769 (broke test stream, removed needed HasMoreRBSPData, added extra ops) - Add HE AAC support to ISO BMFF.
Also abstract common code in H264BitReader into BitReader for reusing.
Was: https://chromiumcodereview.appspot.com/10710002/
In the submitted patch of the last issue, the media.gyp included a non-existing file. This error hadn't been caught by try but later got caught by the build process and reverted the commit. So I create this issue to submit the fixed patch.
BUG=134445
TEST=BitReaderTest, AACTest
Review URL: https://chromiumcodereview.appspot.com/10753005
TBR=xiaomings@google.com
Review URL: https://chromiumcodereview.appspot.com/10779025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146927 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/mp4')
-rw-r--r-- | media/mp4/aac.cc | 252 | ||||
-rw-r--r-- | media/mp4/aac.h | 67 | ||||
-rw-r--r-- | media/mp4/aac_unittest.cc | 104 | ||||
-rw-r--r-- | media/mp4/avc.cc | 22 | ||||
-rw-r--r-- | media/mp4/avc.h | 4 | ||||
-rw-r--r-- | media/mp4/box_definitions.cc | 28 | ||||
-rw-r--r-- | media/mp4/box_definitions.h | 9 | ||||
-rw-r--r-- | media/mp4/es_descriptor.cc | 112 | ||||
-rw-r--r-- | media/mp4/es_descriptor.h | 57 | ||||
-rw-r--r-- | media/mp4/es_descriptor_unittest.cc | 92 | ||||
-rw-r--r-- | media/mp4/mp4_stream_parser.cc | 16 | ||||
-rw-r--r-- | media/mp4/mp4_stream_parser.h | 4 |
12 files changed, 33 insertions, 734 deletions
diff --git a/media/mp4/aac.cc b/media/mp4/aac.cc deleted file mode 100644 index e79e927..0000000 --- a/media/mp4/aac.cc +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (c) 2012 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/mp4/aac.h" - -#include "base/logging.h" -#include "media/base/bit_reader.h" -#include "media/mp4/rcheck.h" - -// The following conversion table is extracted from ISO 14496 Part 3 - -// Table 1.16 - Sampling Frequency Index. -static const uint32 kFrequencyMap[] = { - 96000, 88200, 64000, 48000, 44100, 32000, 24000, - 22050, 16000, 12000, 11025, 8000, 7350 -}; - -static ChannelLayout GetChannelLayout(uint8 channel_config) { - switch (channel_config) { - case 1: - return CHANNEL_LAYOUT_MONO; - case 2: - return CHANNEL_LAYOUT_STEREO; - case 3: - return CHANNEL_LAYOUT_SURROUND; - case 4: - return CHANNEL_LAYOUT_4_0; - case 5: - return CHANNEL_LAYOUT_5_0; - case 6: - return CHANNEL_LAYOUT_5_1; - case 8: - return CHANNEL_LAYOUT_7_1; - default: - break; - } - - return CHANNEL_LAYOUT_UNSUPPORTED; -} - -namespace media { - -namespace mp4 { - -AAC::AAC() - : profile_(0), frequency_index_(0), channel_config_(0), frequency_(0), - channel_layout_(CHANNEL_LAYOUT_UNSUPPORTED) { -} - -AAC::~AAC() { -} - -bool AAC::Parse(const std::vector<uint8>& data) { - BitReader reader; - uint8 extension_type = 0; - bool ps_present = false; - uint8 extension_frequency_index; - - profile_ = 0; - frequency_index_ = 0; - frequency_ = 0; - channel_config_ = 0; - - reader.Initialize(&data[0], data.size()); - - // The following code is written according to ISO 14496 Part 3 Table 1.13 - - // Syntax of AudioSpecificConfig. - - // Read base configuration - RCHECK(reader.ReadBits(5, &profile_)); - RCHECK(reader.ReadBits(4, &frequency_index_)); - if (frequency_index_ == 0xf) - RCHECK(reader.ReadBits(24, &frequency_)); - RCHECK(reader.ReadBits(4, &channel_config_)); - - extension_frequency_index = frequency_index_; - - // Read extension configuration - if (profile_ == 5 || profile_ == 29) { - ps_present = (profile_ == 29); - extension_type = 5; - RCHECK(reader.ReadBits(4, &extension_frequency_index)); - if (extension_frequency_index == 0xf) - RCHECK(reader.ReadBits(24, &frequency_)); - RCHECK(reader.ReadBits(5, &profile_)); - } - - RCHECK(SkipDecoderGASpecificConfig(&reader)); - RCHECK(SkipErrorSpecificConfig()); - - // Read extension configuration again - if (extension_type != 5 && reader.NumBitsLeft() >= 16) { - uint16 sync_extension_type; - uint8 sbr_present_flag; - uint8 ps_present_flag; - - RCHECK(reader.ReadBits(11, &sync_extension_type)); - - if (sync_extension_type == 0x2b7) { - RCHECK(reader.ReadBits(5, &extension_type)); - - if (extension_type == 5) { - RCHECK(reader.ReadBits(1, &sbr_present_flag)); - - if (sbr_present_flag) { - RCHECK(reader.ReadBits(4, &extension_frequency_index)); - - if (extension_frequency_index == 0xf) - RCHECK(reader.ReadBits(24, &frequency_)); - - RCHECK(reader.ReadBits(11, &sync_extension_type)); - - if (sync_extension_type == 0x548) { - RCHECK(reader.ReadBits(1, &ps_present_flag)); - ps_present = ps_present_flag != 0; - } - } - } - } - } - - if (frequency_ == 0) { - RCHECK(extension_frequency_index < arraysize(kFrequencyMap)); - frequency_ = kFrequencyMap[extension_frequency_index]; - } - - // When Parametric Stereo is on, mono will be played as stereo. - if (ps_present && channel_config_ == 1) - channel_layout_ = GetChannelLayout(channel_config_ + 1); - else - channel_layout_ = GetChannelLayout(channel_config_); - - return frequency_ != 0 && channel_layout_ != CHANNEL_LAYOUT_UNSUPPORTED && - profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf && - channel_config_ <= 7; -} - -uint32 AAC::frequency() const { - return frequency_; -} - -ChannelLayout AAC::channel_layout() const { - return channel_layout_; -} - -bool AAC::ConvertEsdsToADTS(std::vector<uint8>* buffer) const { - size_t size = buffer->size() + 7; - - DCHECK(profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf && - channel_config_ <= 7); - - // ADTS header uses 13 bits for packet size. - if (size > (1 << 13) - 1) - return false; - - std::vector<uint8>& adts = *buffer; - - adts.insert(buffer->begin(), 7, 0); - adts[0] = 0xff; - adts[1] = 0xf1; - adts[2] = ((profile_ - 1) << 6) + (frequency_index_ << 2) + - (channel_config_ >> 2); - adts[3] = ((channel_config_ & 0x3) << 6) + (size >> 11); - adts[4] = (size & 0x7ff) >> 3; - adts[5] = ((size & 7) << 5) + 0x1f; - adts[6] = 0xfc; - - return true; -} - -// Currently this function only support GASpecificConfig defined in -// ISO 14496 Part 3 Table 4.1 - Syntax of GASpecificConfig() -bool AAC::SkipDecoderGASpecificConfig(BitReader* bit_reader) const { - switch (profile_) { - case 1: - case 2: - case 3: - case 4: - case 6: - case 7: - case 17: - case 19: - case 20: - case 21: - case 22: - case 23: - return SkipGASpecificConfig(bit_reader); - default: - break; - } - - return false; -} - -bool AAC::SkipErrorSpecificConfig() const { - switch (profile_) { - case 17: - case 19: - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - case 26: - case 27: - return false; - default: - break; - } - - return true; -} - -// The following code is written according to ISO 14496 part 3 Table 4.1 - -// GASpecificConfig. -bool AAC::SkipGASpecificConfig(BitReader* bit_reader) const { - uint8 extension_flag = 0; - uint8 depends_on_core_coder; - - RCHECK(bit_reader->SkipBits(1)); // frameLengthFlag - RCHECK(bit_reader->ReadBits(1, &depends_on_core_coder)); - if (depends_on_core_coder == 1) - RCHECK(bit_reader->SkipBits(14)); // coreCoderDelay - - RCHECK(bit_reader->ReadBits(1, &extension_flag)); - RCHECK(channel_config_ != 0); - - if (profile_ == 6 || profile_ == 20) - RCHECK(bit_reader->SkipBits(3)); - - if (extension_flag) { - if (profile_ == 22) { - RCHECK(bit_reader->SkipBits(5)); - RCHECK(bit_reader->SkipBits(11)); - } - - if (profile_ == 17 || profile_ == 19 || profile_ == 20 || profile_ == 23) { - RCHECK(bit_reader->SkipBits(1)); - RCHECK(bit_reader->SkipBits(1)); - RCHECK(bit_reader->SkipBits(1)); - } - - RCHECK(bit_reader->SkipBits(1)); - } - - return true; -} - -} // namespace mp4 - -} // namespace media diff --git a/media/mp4/aac.h b/media/mp4/aac.h deleted file mode 100644 index 7a2a3f8..0000000 --- a/media/mp4/aac.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef MEDIA_MP4_AAC_H_ -#define MEDIA_MP4_AAC_H_ - -#include <vector> - -#include "base/basictypes.h" -#include "media/base/channel_layout.h" -#include "media/base/media_export.h" - -namespace media { - -class BitReader; - -namespace mp4 { - -// This class parses the AAC information from decoder specific information -// embedded in the esds box in an ISO BMFF file. -// Please refer to ISO 14496 Part 3 Table 1.13 - Syntax of AudioSpecificConfig -// for more details. -class MEDIA_EXPORT AAC { - public: - AAC(); - ~AAC(); - - // Parse the AAC config from the raw binary data embedded in esds box. - // The function will parse the data and get the ElementaryStreamDescriptor, - // then it will parse the ElementaryStreamDescriptor to get audio stream - // configurations. - bool Parse(const std::vector<uint8>& data); - - uint32 frequency() const; - ChannelLayout channel_layout() const; - - // This function converts a raw AAC frame into an AAC frame with an ADTS - // header. On success, the function returns true and stores the converted data - // in the buffer. The function returns false on failure and leaves the buffer - // unchanged. - bool ConvertEsdsToADTS(std::vector<uint8>* buffer) const; - - private: - bool SkipDecoderGASpecificConfig(BitReader* bit_reader) const; - bool SkipErrorSpecificConfig() const; - bool SkipGASpecificConfig(BitReader* bit_reader) const; - - // The following variables store the AAC specific configuration information - // that are used to generate the ADTS header. - uint8 profile_; - uint8 frequency_index_; - uint8 channel_config_; - - // The following variables store audio configuration information that - // can be used by Chromium. They are based on the AAC specific - // configuration but can be overridden by extensions in elementary - // stream descriptor. - uint32 frequency_; - ChannelLayout channel_layout_; -}; - -} // namespace mp4 - -} // namespace media - -#endif // MEDIA_MP4_AAC_H_ diff --git a/media/mp4/aac_unittest.cc b/media/mp4/aac_unittest.cc deleted file mode 100644 index 2f61de5..0000000 --- a/media/mp4/aac_unittest.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2012 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/mp4/aac.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace media { - -namespace mp4 { - -TEST(AACTest, BasicProfileTest) { - AAC aac; - uint8 buffer[] = {0x12, 0x10}; - std::vector<uint8> data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_TRUE(aac.Parse(data)); - EXPECT_EQ(aac.frequency(), 44100u); - EXPECT_EQ(aac.channel_layout(), CHANNEL_LAYOUT_STEREO); -} - -TEST(AACTest, ExtensionTest) { - AAC aac; - uint8 buffer[] = {0x13, 0x08, 0x56, 0xe5, 0x9d, 0x48, 0x80}; - std::vector<uint8> data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_TRUE(aac.Parse(data)); - EXPECT_EQ(aac.frequency(), 48000u); - EXPECT_EQ(aac.channel_layout(), CHANNEL_LAYOUT_STEREO); -} - -TEST(AACTest, SixChannelTest) { - AAC aac; - uint8 buffer[] = {0x11, 0xb0}; - std::vector<uint8> data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_TRUE(aac.Parse(data)); - EXPECT_EQ(aac.frequency(), 48000u); - EXPECT_EQ(aac.channel_layout(), CHANNEL_LAYOUT_5_1); -} - -TEST(AACTest, DataTooShortTest) { - AAC aac; - std::vector<uint8> data; - - EXPECT_FALSE(aac.Parse(data)); - - data.push_back(0x12); - EXPECT_FALSE(aac.Parse(data)); -} - -TEST(AACTest, IncorrectProfileTest) { - AAC aac; - uint8 buffer[] = {0x0, 0x08}; - std::vector<uint8> data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_FALSE(aac.Parse(data)); - - data[0] = 0x08; - EXPECT_TRUE(aac.Parse(data)); - - data[0] = 0x28; - EXPECT_FALSE(aac.Parse(data)); -} - -TEST(AACTest, IncorrectFrequencyTest) { - AAC aac; - uint8 buffer[] = {0x0f, 0x88}; - std::vector<uint8> data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_FALSE(aac.Parse(data)); - - data[0] = 0x0e; - data[1] = 0x08; - EXPECT_TRUE(aac.Parse(data)); -} - -TEST(AACTest, IncorrectChannelTest) { - AAC aac; - uint8 buffer[] = {0x0e, 0x00}; - std::vector<uint8> data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_FALSE(aac.Parse(data)); - - data[1] = 0x08; - EXPECT_TRUE(aac.Parse(data)); -} - -} // namespace mp4 - -} // namespace media diff --git a/media/mp4/avc.cc b/media/mp4/avc.cc index 2999466..faf9939 100644 --- a/media/mp4/avc.cc +++ b/media/mp4/avc.cc @@ -88,5 +88,27 @@ bool AVC::InsertParameterSets(const AVCDecoderConfigurationRecord& avc_config, return true; } +// static +ChannelLayout AVC::ConvertAACChannelCountToChannelLayout(int count) { + switch (count) { + case 1: + return CHANNEL_LAYOUT_MONO; + case 2: + return CHANNEL_LAYOUT_STEREO; + case 3: + return CHANNEL_LAYOUT_SURROUND; + case 4: + return CHANNEL_LAYOUT_4_0; + case 5: + return CHANNEL_LAYOUT_5_0; + case 6: + return CHANNEL_LAYOUT_5_1; + case 8: + return CHANNEL_LAYOUT_7_1; + default: + return CHANNEL_LAYOUT_UNSUPPORTED; + } +} + } // namespace mp4 } // namespace media diff --git a/media/mp4/avc.h b/media/mp4/avc.h index 8e826b0..2767c14 100644 --- a/media/mp4/avc.h +++ b/media/mp4/avc.h @@ -8,6 +8,7 @@ #include <vector> #include "base/basictypes.h" +#include "media/base/channel_layout.h" #include "media/base/media_export.h" namespace media { @@ -22,8 +23,11 @@ class MEDIA_EXPORT AVC { static bool InsertParameterSets( const AVCDecoderConfigurationRecord& avc_config, std::vector<uint8>* buffer); + + static ChannelLayout ConvertAACChannelCountToChannelLayout(int count); }; + } // namespace mp4 } // namespace media diff --git a/media/mp4/box_definitions.cc b/media/mp4/box_definitions.cc index eb43530..ff86372 100644 --- a/media/mp4/box_definitions.cc +++ b/media/mp4/box_definitions.cc @@ -5,7 +5,8 @@ #include "media/mp4/box_definitions.h" #include "base/logging.h" -#include "media/mp4/es_descriptor.h" +#include "media/mp4/box_reader.h" +#include "media/mp4/fourccs.h" #include "media/mp4/rcheck.h" namespace media { @@ -388,29 +389,6 @@ bool VideoSampleEntry::Parse(BoxReader* reader) { return true; } -ElementaryStreamDescriptor::ElementaryStreamDescriptor() {} - -ElementaryStreamDescriptor::~ElementaryStreamDescriptor() {} - -FourCC ElementaryStreamDescriptor::BoxType() const { - return FOURCC_ESDS; -} - -bool ElementaryStreamDescriptor::Parse(BoxReader* reader) { - std::vector<uint8> data; - ESDescriptor es_desc; - - RCHECK(reader->ReadFullBoxHeader()); - RCHECK(reader->ReadVec(&data, reader->size() - reader->pos())); - RCHECK(es_desc.Parse(data)); - - object_type = es_desc.object_type(); - - RCHECK(aac.Parse(es_desc.decoder_specific_info())); - - return true; -} - AudioSampleEntry::AudioSampleEntry() : format(FOURCC_NULL), data_reference_index(0), @@ -419,7 +397,6 @@ AudioSampleEntry::AudioSampleEntry() samplerate(0) {} AudioSampleEntry::~AudioSampleEntry() {} - FourCC AudioSampleEntry::BoxType() const { DCHECK(false) << "AudioSampleEntry should be parsed according to the " << "handler type recovered in its Media ancestor."; @@ -442,7 +419,6 @@ bool AudioSampleEntry::Parse(BoxReader* reader) { if (format == FOURCC_ENCA) { RCHECK(reader->ReadChild(&sinf)); } - RCHECK(reader->ReadChild(&esds)); return true; } diff --git a/media/mp4/box_definitions.h b/media/mp4/box_definitions.h index 0b7e771..52a0e86 100644 --- a/media/mp4/box_definitions.h +++ b/media/mp4/box_definitions.h @@ -11,7 +11,6 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "media/base/media_export.h" -#include "media/mp4/aac.h" #include "media/mp4/avc.h" #include "media/mp4/box_reader.h" #include "media/mp4/fourccs.h" @@ -185,13 +184,6 @@ struct VideoSampleEntry : Box { AVCDecoderConfigurationRecord avcc; }; -struct ElementaryStreamDescriptor : Box { - DECLARE_BOX_METHODS(ElementaryStreamDescriptor); - - uint8 object_type; - AAC aac; -}; - struct AudioSampleEntry : Box { DECLARE_BOX_METHODS(AudioSampleEntry); @@ -202,7 +194,6 @@ struct AudioSampleEntry : Box { uint32 samplerate; ProtectionSchemeInfo sinf; - ElementaryStreamDescriptor esds; }; struct SampleDescription : Box { diff --git a/media/mp4/es_descriptor.cc b/media/mp4/es_descriptor.cc deleted file mode 100644 index 1cb4c65..0000000 --- a/media/mp4/es_descriptor.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2012 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/mp4/es_descriptor.h" - -#include "media/base/bit_reader.h" -#include "media/mp4/rcheck.h" - -// The elementary stream size is specific by up to 4 bytes. -// The MSB of a byte indicates if there are more bytes for the size. -static bool ReadESSize(media::BitReader* reader, uint32* size) { - uint8 msb; - uint8 byte; - - *size = 0; - - for (size_t i = 0; i < 4; ++i) { - RCHECK(reader->ReadBits(1, &msb)); - RCHECK(reader->ReadBits(7, &byte)); - *size = (*size << 7) + byte; - - if (msb == 0) - break; - } - - return true; -} - -namespace media { - -namespace mp4 { - -ESDescriptor::ESDescriptor() - : object_type_(kForbidden) { -} - -ESDescriptor::~ESDescriptor() {} - -bool ESDescriptor::Parse(const std::vector<uint8>& data) { - BitReader reader(&data[0], data.size()); - uint8 tag; - uint32 size; - uint8 stream_dependency_flag; - uint8 url_flag; - uint8 ocr_stream_flag; - - RCHECK(reader.ReadBits(8, &tag)); - RCHECK(tag == kESDescrTag); - RCHECK(ReadESSize(&reader, &size)); - RCHECK(static_cast<off_t>(size * CHAR_BIT) <= reader.NumBitsLeft()); - - RCHECK(reader.SkipBits(16)); // ES_ID - RCHECK(reader.ReadBits(1, &stream_dependency_flag)); - RCHECK(reader.ReadBits(1, &url_flag)); - RCHECK(reader.ReadBits(1, &ocr_stream_flag)); - RCHECK(reader.SkipBits(5)); // streamPriority - - if (stream_dependency_flag) - reader.SkipBits(16); // dependsOn_ES_ID; - RCHECK(!url_flag); // We don't support url flag - if (ocr_stream_flag) - reader.SkipBits(16); // OCR_ES_Id - - RCHECK(ParseDecoderConfigDescriptor(&reader)); - - return true; -} - -uint8 ESDescriptor::object_type() const { - return object_type_; -} - -const std::vector<uint8>& ESDescriptor::decoder_specific_info() const { - return decoder_specific_info_; -} - -bool ESDescriptor::ParseDecoderConfigDescriptor(BitReader* reader) { - uint8 tag; - uint32 size; - - RCHECK(reader->ReadBits(8, &tag)); - RCHECK(tag == kDecoderConfigDescrTag); - RCHECK(ReadESSize(reader, &size)); - RCHECK(static_cast<off_t>(size * CHAR_BIT) <= reader->NumBitsLeft()); - - RCHECK(reader->ReadBits(8, &object_type_)); - RCHECK(reader->SkipBits(96)); - RCHECK(ParseDecoderSpecificInfo(reader)); - - return true; -} - -bool ESDescriptor::ParseDecoderSpecificInfo(BitReader* reader) { - uint8 tag; - uint32 size; - - RCHECK(reader->ReadBits(8, &tag)); - RCHECK(tag == kDecoderSpecificInfoTag); - RCHECK(ReadESSize(reader, &size)); - RCHECK(static_cast<off_t>(size * CHAR_BIT) <= reader->NumBitsLeft()); - - decoder_specific_info_.resize(size); - for (uint32 i = 0; i < size; ++i) - RCHECK(reader->ReadBits(8, &decoder_specific_info_[i])); - - return true; -} - -} // namespace mp4 - -} // namespace media diff --git a/media/mp4/es_descriptor.h b/media/mp4/es_descriptor.h deleted file mode 100644 index daddbc0..0000000 --- a/media/mp4/es_descriptor.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef MEDIA_MP4_ES_DESCRIPTOR_H_ -#define MEDIA_MP4_ES_DESCRIPTOR_H_ - -#include <vector> - -#include "base/basictypes.h" -#include "media/base/media_export.h" - -namespace media { - -class BitReader; - -namespace mp4 { - -// The following values are extracted from ISO 14496 Part 1 Table 5 - -// objectTypeIndication Values. Only values currently in use are included. -enum ObjectType { - kForbidden = 0, - kISO_14496_3 = 0x40 // MPEG4 AAC -}; - -// This class parse object type and decoder specific information from an -// elementary stream descriptor, which is usually contained in an esds box. -// Please refer to ISO 14496 Part 1 7.2.6.5 for more details. -class MEDIA_EXPORT ESDescriptor { - public: - ESDescriptor(); - ~ESDescriptor(); - - bool Parse(const std::vector<uint8>& data); - - uint8 object_type() const; - const std::vector<uint8>& decoder_specific_info() const; - - private: - enum Tag { - kESDescrTag = 0x03, - kDecoderConfigDescrTag = 0x04, - kDecoderSpecificInfoTag = 0x05 - }; - - bool ParseDecoderConfigDescriptor(BitReader* reader); - bool ParseDecoderSpecificInfo(BitReader* reader); - - uint8 object_type_; - std::vector<uint8> decoder_specific_info_; -}; - -} // namespace mp4 - -} // namespace media - -#endif // MEDIA_MP4_ES_DESCRIPTOR_H_ diff --git a/media/mp4/es_descriptor_unittest.cc b/media/mp4/es_descriptor_unittest.cc deleted file mode 100644 index c3a39fb..0000000 --- a/media/mp4/es_descriptor_unittest.cc +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2012 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/mp4/es_descriptor.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace media { - -namespace mp4 { - -TEST(ESDescriptorTest, SingleByteLengthTest) { - ESDescriptor es_desc; - uint8 buffer[] = { - 0x03, 0x19, 0x00, 0x01, 0x00, 0x04, 0x11, 0x40, - 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x02, 0x12, 0x10, - 0x06, 0x01, 0x02 - }; - std::vector<uint8> data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_EQ(es_desc.object_type(), kForbidden); - EXPECT_TRUE(es_desc.Parse(data)); - EXPECT_EQ(es_desc.object_type(), kISO_14496_3); - EXPECT_EQ(es_desc.decoder_specific_info().size(), 2u); - EXPECT_EQ(es_desc.decoder_specific_info()[0], 0x12); - EXPECT_EQ(es_desc.decoder_specific_info()[1], 0x10); -} - -TEST(ESDescriptorTest, NonAACTest) { - ESDescriptor es_desc; - uint8 buffer[] = { - 0x03, 0x19, 0x00, 0x01, 0x00, 0x04, 0x11, 0x66, - 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x02, 0x12, 0x10, - 0x06, 0x01, 0x02 - }; - std::vector<uint8> data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_TRUE(es_desc.Parse(data)); - EXPECT_NE(es_desc.object_type(), kISO_14496_3); - EXPECT_EQ(es_desc.decoder_specific_info().size(), 2u); - EXPECT_EQ(es_desc.decoder_specific_info()[0], 0x12); - EXPECT_EQ(es_desc.decoder_specific_info()[1], 0x10); -} - -TEST(ESDescriptorTest, MultiByteLengthTest) { - ESDescriptor es_desc; - uint8 buffer[] = { - 0x03, 0x80, 0x19, 0x00, 0x01, 0x00, 0x04, 0x80, - 0x80, 0x11, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, - 0x80, 0x80, 0x80, 0x02, 0x12, 0x10, 0x06, 0x01, - 0x02 - }; - std::vector<uint8> data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_TRUE(es_desc.Parse(data)); - EXPECT_EQ(es_desc.object_type(), kISO_14496_3); - EXPECT_EQ(es_desc.decoder_specific_info().size(), 2u); - EXPECT_EQ(es_desc.decoder_specific_info()[0], 0x12); - EXPECT_EQ(es_desc.decoder_specific_info()[1], 0x10); -} - -TEST(ESDescriptorTest, FiveByteLengthTest) { - ESDescriptor es_desc; - uint8 buffer[] = { - 0x03, 0x80, 0x19, 0x00, 0x01, 0x00, 0x04, 0x80, - 0x80, 0x11, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, - 0x80, 0x80, 0x80, 0x80, 0x02, 0x12, 0x10, 0x06, - 0x01, 0x02 - }; - std::vector<uint8> data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_TRUE(es_desc.Parse(data)); - EXPECT_EQ(es_desc.object_type(), kISO_14496_3); - EXPECT_EQ(es_desc.decoder_specific_info().size(), 0u); -} - -} // namespace mp4 - -} // namespace media diff --git a/media/mp4/mp4_stream_parser.cc b/media/mp4/mp4_stream_parser.cc index ebaa2a2..bb2a95c 100644 --- a/media/mp4/mp4_stream_parser.cc +++ b/media/mp4/mp4_stream_parser.cc @@ -13,7 +13,6 @@ #include "media/base/video_decoder_config.h" #include "media/mp4/box_definitions.h" #include "media/mp4/box_reader.h" -#include "media/mp4/es_descriptor.h" #include "media/mp4/rcheck.h" namespace media { @@ -163,13 +162,10 @@ bool MP4StreamParser::ParseMoov(BoxReader* reader) { // (entry.format == FOURCC_ENCA && // entry.sinf.format.format == FOURCC_MP4A)); - // Check if it is MPEG4 AAC defined in ISO 14496 Part 3. - RCHECK(entry.esds.object_type == kISO_14496_3); - aac_ = entry.esds.aac; - audio_config.Initialize(kCodecAAC, entry.samplesize, - aac_.channel_layout(), aac_.frequency(), - NULL, 0, false); - + const ChannelLayout layout = + AVC::ConvertAACChannelCountToChannelLayout(entry.channelcount); + audio_config.Initialize(kCodecAAC, entry.samplesize, layout, + entry.samplerate, NULL, 0, false); has_audio_ = true; audio_track_id_ = track->header.track_id; } @@ -295,10 +291,6 @@ bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, } } - if (audio) { - aac_.ConvertEsdsToADTS(&frame_buf); - } - scoped_refptr<StreamParserBuffer> stream_buf = StreamParserBuffer::CopyFrom(&frame_buf[0], frame_buf.size(), runs_.is_keyframe()); diff --git a/media/mp4/mp4_stream_parser.h b/media/mp4/mp4_stream_parser.h index 706aa65..7d9be27 100644 --- a/media/mp4/mp4_stream_parser.h +++ b/media/mp4/mp4_stream_parser.h @@ -11,7 +11,6 @@ #include "base/memory/scoped_ptr.h" #include "media/base/media_export.h" #include "media/base/stream_parser.h" -#include "media/mp4/aac.h" #include "media/mp4/offset_byte_queue.h" #include "media/mp4/track_run_iterator.h" @@ -86,9 +85,8 @@ class MEDIA_EXPORT MP4StreamParser : public StreamParser { uint32 audio_track_id_; uint32 video_track_id_; - // We keep them around to avoid having to go digging through the moov with + // We keep this around to avoid having to go digging through the moov with // every frame. - AAC aac_; uint8 size_of_nalu_length_; DISALLOW_COPY_AND_ASSIGN(MP4StreamParser); |