diff --git a/media/mp4/aac.cc b/media/mp4/aac_audio_specific_config.cc similarity index 88% rename from media/mp4/aac.cc rename to media/mp4/aac_audio_specific_config.cc index 81eb89512c..d386e88c71 100644 --- a/media/mp4/aac.cc +++ b/media/mp4/aac_audio_specific_config.cc @@ -2,7 +2,7 @@ // 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 "media/mp4/aac_audio_specific_config.h" #include @@ -27,16 +27,18 @@ namespace media { namespace mp4 { -AAC::AAC() - : audio_object_type_(0), frequency_index_(0), channel_config_(0), - ps_present_(false), frequency_(0), extension_frequency_(0), - num_channels_(0) { -} +AACAudioSpecificConfig::AACAudioSpecificConfig() + : audio_object_type_(0), + frequency_index_(0), + channel_config_(0), + ps_present_(false), + frequency_(0), + extension_frequency_(0), + num_channels_(0) {} -AAC::~AAC() { -} +AACAudioSpecificConfig::~AACAudioSpecificConfig() {} -bool AAC::Parse(const std::vector& data) { +bool AACAudioSpecificConfig::Parse(const std::vector& data) { if (data.empty()) return false; @@ -125,7 +127,8 @@ bool AAC::Parse(const std::vector& data) { channel_config_ <= 7; } -uint32 AAC::GetOutputSamplesPerSecond(bool sbr_in_mimetype) const { +uint32 AACAudioSpecificConfig::GetOutputSamplesPerSecond(bool sbr_in_mimetype) + const { if (extension_frequency_ > 0) return extension_frequency_; @@ -140,7 +143,7 @@ uint32 AAC::GetOutputSamplesPerSecond(bool sbr_in_mimetype) const { return std::min(2 * frequency_, 48000u); } -uint8 AAC::GetNumChannels(bool sbr_in_mimetype) const { +uint8 AACAudioSpecificConfig::GetNumChannels(bool sbr_in_mimetype) const { // Check for implicit signalling of HE-AAC and indicate stereo output // if the mono channel configuration is signalled. // See ISO-14496-3 Section 1.6.6.1.2 for details about this special casing. @@ -154,7 +157,7 @@ uint8 AAC::GetNumChannels(bool sbr_in_mimetype) const { return num_channels_; } -bool AAC::ConvertToADTS(std::vector* buffer) const { +bool AACAudioSpecificConfig::ConvertToADTS(std::vector* buffer) const { size_t size = buffer->size() + kADTSHeaderSize; DCHECK(audio_object_type_ >= 1 && audio_object_type_ <= 4 && @@ -181,7 +184,7 @@ bool AAC::ConvertToADTS(std::vector* buffer) const { // 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 { +bool AACAudioSpecificConfig::SkipDecoderGASpecificConfig(BitReader* bit_reader) const { switch (audio_object_type_) { case 1: case 2: @@ -203,7 +206,7 @@ bool AAC::SkipDecoderGASpecificConfig(BitReader* bit_reader) const { return false; } -bool AAC::SkipErrorSpecificConfig() const { +bool AACAudioSpecificConfig::SkipErrorSpecificConfig() const { switch (audio_object_type_) { case 17: case 19: @@ -225,7 +228,7 @@ bool AAC::SkipErrorSpecificConfig() const { // The following code is written according to ISO 14496 part 3 Table 4.1 - // GASpecificConfig. -bool AAC::SkipGASpecificConfig(BitReader* bit_reader) const { +bool AACAudioSpecificConfig::SkipGASpecificConfig(BitReader* bit_reader) const { uint8 extension_flag = 0; uint8 depends_on_core_coder; uint16 dummy; diff --git a/media/mp4/aac.h b/media/mp4/aac_audio_specific_config.h similarity index 88% rename from media/mp4/aac.h rename to media/mp4/aac_audio_specific_config.h index 9d829274b5..9a4f41cce7 100644 --- a/media/mp4/aac.h +++ b/media/mp4/aac_audio_specific_config.h @@ -2,8 +2,8 @@ // 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_ +#ifndef MEDIA_MP4_AAC_AUDIO_SPECIFIC_CONFIG_H_ +#define MEDIA_MP4_AAC_AUDIO_SPECIFIC_CONFIG_H_ #include @@ -19,12 +19,10 @@ namespace mp4 { // 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. -// TODO(kqyang): the class name is not appropriate, it should be -// AACAudioSpecificConfig instead. -class AAC { +class AACAudioSpecificConfig { public: - AAC(); - ~AAC(); + AACAudioSpecificConfig(); + ~AACAudioSpecificConfig(); // Parse the AAC config from the raw binary data embedded in esds box. // The function will parse the data and get the ElementaryStreamDescriptor, @@ -32,12 +30,12 @@ class AAC { // configurations. bool Parse(const std::vector& data); - // Gets the output sample rate for the AAC stream. + // Get the output sample rate for the AAC stream. // |sbr_in_mimetype| should be set to true if the SBR mode is // signalled in the mimetype. (ie mp4a.40.5 in the codecs parameter). uint32 GetOutputSamplesPerSecond(bool sbr_in_mimetype) const; - // Gets number of channels for the AAC stream. + // Get number of channels for the AAC stream. // |sbr_in_mimetype| should be set to true if the SBR mode is // signalled in the mimetype. (ie mp4a.40.5 in the codecs parameter). uint8 GetNumChannels(bool sbr_in_mimetype) const; @@ -85,7 +83,6 @@ class AAC { }; } // namespace mp4 - } // namespace media -#endif // MEDIA_MP4_AAC_H_ +#endif // MEDIA_MP4_AAC_AUDIO_SPECIFIC_CONFIG_H_ diff --git a/media/mp4/aac_audio_specific_config_unittest.cc b/media/mp4/aac_audio_specific_config_unittest.cc new file mode 100644 index 0000000000..2da1c486b0 --- /dev/null +++ b/media/mp4/aac_audio_specific_config_unittest.cc @@ -0,0 +1,144 @@ +// 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_audio_specific_config.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace media { +namespace mp4 { + +TEST(AACAudioSpecificConfigTest, BasicProfileTest) { + AACAudioSpecificConfig aac_audio_specific_config; + uint8 buffer[] = {0x12, 0x10}; + std::vector data; + + data.assign(buffer, buffer + sizeof(buffer)); + + EXPECT_TRUE(aac_audio_specific_config.Parse(data)); + EXPECT_EQ(aac_audio_specific_config.GetOutputSamplesPerSecond(false), 44100); + EXPECT_EQ(aac_audio_specific_config.GetNumChannels(false), 2); +} + +TEST(AACAudioSpecificConfigTest, ExtensionTest) { + AACAudioSpecificConfig aac_audio_specific_config; + uint8 buffer[] = {0x13, 0x08, 0x56, 0xe5, 0x9d, 0x48, 0x80}; + std::vector data; + + data.assign(buffer, buffer + sizeof(buffer)); + + EXPECT_TRUE(aac_audio_specific_config.Parse(data)); + EXPECT_EQ(aac_audio_specific_config.GetOutputSamplesPerSecond(false), 48000); + EXPECT_EQ(aac_audio_specific_config.GetOutputSamplesPerSecond(true), 48000); + EXPECT_EQ(aac_audio_specific_config.GetNumChannels(false), 2); +} + +// Test implicit SBR with mono channel config. +// Mono channel layout should only be reported if SBR is not +// specified. Otherwise stereo should be reported. +// See ISO-14496-3 Section 1.6.6.1.2 for details about this special casing. +TEST(AACAudioSpecificConfigTest, ImplicitSBR_ChannelConfig0) { + AACAudioSpecificConfig aac_audio_specific_config; + uint8 buffer[] = {0x13, 0x08}; + std::vector data; + + data.assign(buffer, buffer + sizeof(buffer)); + + EXPECT_TRUE(aac_audio_specific_config.Parse(data)); + + // Test w/o implict SBR. + EXPECT_EQ(aac_audio_specific_config.GetOutputSamplesPerSecond(false), 24000); + EXPECT_EQ(aac_audio_specific_config.GetNumChannels(false), 1); + + // Test implicit SBR. + EXPECT_EQ(aac_audio_specific_config.GetOutputSamplesPerSecond(true), 48000); + EXPECT_EQ(aac_audio_specific_config.GetNumChannels(true), 2); +} + +// Tests implicit SBR with a stereo channel config. +TEST(AACAudioSpecificConfigTest, ImplicitSBR_ChannelConfig1) { + AACAudioSpecificConfig aac_audio_specific_config; + uint8 buffer[] = {0x13, 0x10}; + std::vector data; + + data.assign(buffer, buffer + sizeof(buffer)); + + EXPECT_TRUE(aac_audio_specific_config.Parse(data)); + + // Test w/o implict SBR. + EXPECT_EQ(aac_audio_specific_config.GetOutputSamplesPerSecond(false), 24000); + EXPECT_EQ(aac_audio_specific_config.GetNumChannels(false), 2); + + // Test implicit SBR. + EXPECT_EQ(aac_audio_specific_config.GetOutputSamplesPerSecond(true), 48000); + EXPECT_EQ(aac_audio_specific_config.GetNumChannels(true), 2); +} + +TEST(AACAudioSpecificConfigTest, SixChannelTest) { + AACAudioSpecificConfig aac_audio_specific_config; + uint8 buffer[] = {0x11, 0xb0}; + std::vector data; + + data.assign(buffer, buffer + sizeof(buffer)); + + EXPECT_TRUE(aac_audio_specific_config.Parse(data)); + EXPECT_EQ(aac_audio_specific_config.GetOutputSamplesPerSecond(false), 48000); + EXPECT_EQ(aac_audio_specific_config.GetNumChannels(false), 6); +} + +TEST(AACAudioSpecificConfigTest, DataTooShortTest) { + AACAudioSpecificConfig aac_audio_specific_config; + std::vector data; + + EXPECT_FALSE(aac_audio_specific_config.Parse(data)); + + data.push_back(0x12); + EXPECT_FALSE(aac_audio_specific_config.Parse(data)); +} + +TEST(AACAudioSpecificConfigTest, IncorrectProfileTest) { + AACAudioSpecificConfig aac_audio_specific_config; + uint8 buffer[] = {0x0, 0x08}; + std::vector data; + + data.assign(buffer, buffer + sizeof(buffer)); + + EXPECT_FALSE(aac_audio_specific_config.Parse(data)); + + data[0] = 0x08; + EXPECT_TRUE(aac_audio_specific_config.Parse(data)); + + data[0] = 0x28; + EXPECT_FALSE(aac_audio_specific_config.Parse(data)); +} + +TEST(AACAudioSpecificConfigTest, IncorrectFrequencyTest) { + AACAudioSpecificConfig aac_audio_specific_config; + uint8 buffer[] = {0x0f, 0x88}; + std::vector data; + + data.assign(buffer, buffer + sizeof(buffer)); + + EXPECT_FALSE(aac_audio_specific_config.Parse(data)); + + data[0] = 0x0e; + data[1] = 0x08; + EXPECT_TRUE(aac_audio_specific_config.Parse(data)); +} + +TEST(AACAudioSpecificConfigTest, IncorrectChannelTest) { + AACAudioSpecificConfig aac_audio_specific_config; + uint8 buffer[] = {0x0e, 0x00}; + std::vector data; + + data.assign(buffer, buffer + sizeof(buffer)); + + EXPECT_FALSE(aac_audio_specific_config.Parse(data)); + + data[1] = 0x08; + EXPECT_TRUE(aac_audio_specific_config.Parse(data)); +} + +} // namespace mp4 +} // namespace media diff --git a/media/mp4/aac_unittest.cc b/media/mp4/aac_unittest.cc deleted file mode 100644 index 58d0c53cbf..0000000000 --- a/media/mp4/aac_unittest.cc +++ /dev/null @@ -1,146 +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 data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_TRUE(aac.Parse(data)); - EXPECT_EQ(aac.GetOutputSamplesPerSecond(false), 44100); - EXPECT_EQ(aac.GetNumChannels(false), 2); -} - -TEST(AACTest, ExtensionTest) { - AAC aac; - uint8 buffer[] = {0x13, 0x08, 0x56, 0xe5, 0x9d, 0x48, 0x80}; - std::vector data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_TRUE(aac.Parse(data)); - EXPECT_EQ(aac.GetOutputSamplesPerSecond(false), 48000); - EXPECT_EQ(aac.GetOutputSamplesPerSecond(true), 48000); - EXPECT_EQ(aac.GetNumChannels(false), 2); -} - -// Test implicit SBR with mono channel config. -// Mono channel layout should only be reported if SBR is not -// specified. Otherwise stereo should be reported. -// See ISO-14496-3 Section 1.6.6.1.2 for details about this special casing. -TEST(AACTest, ImplicitSBR_ChannelConfig0) { - AAC aac; - uint8 buffer[] = {0x13, 0x08}; - std::vector data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_TRUE(aac.Parse(data)); - - // Test w/o implict SBR. - EXPECT_EQ(aac.GetOutputSamplesPerSecond(false), 24000); - EXPECT_EQ(aac.GetNumChannels(false), 1); - - // Test implicit SBR. - EXPECT_EQ(aac.GetOutputSamplesPerSecond(true), 48000); - EXPECT_EQ(aac.GetNumChannels(true), 2); -} - -// Tests implicit SBR with a stereo channel config. -TEST(AACTest, ImplicitSBR_ChannelConfig1) { - AAC aac; - uint8 buffer[] = {0x13, 0x10}; - std::vector data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_TRUE(aac.Parse(data)); - - // Test w/o implict SBR. - EXPECT_EQ(aac.GetOutputSamplesPerSecond(false), 24000); - EXPECT_EQ(aac.GetNumChannels(false), 2); - - // Test implicit SBR. - EXPECT_EQ(aac.GetOutputSamplesPerSecond(true), 48000); - EXPECT_EQ(aac.GetNumChannels(true), 2); -} - -TEST(AACTest, SixChannelTest) { - AAC aac; - uint8 buffer[] = {0x11, 0xb0}; - std::vector data; - - data.assign(buffer, buffer + sizeof(buffer)); - - EXPECT_TRUE(aac.Parse(data)); - EXPECT_EQ(aac.GetOutputSamplesPerSecond(false), 48000); - EXPECT_EQ(aac.GetNumChannels(false), 6); -} - -TEST(AACTest, DataTooShortTest) { - AAC aac; - std::vector 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 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 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 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/box_definitions.cc b/media/mp4/box_definitions.cc index 9339786704..d4644bc17a 100644 --- a/media/mp4/box_definitions.cc +++ b/media/mp4/box_definitions.cc @@ -983,8 +983,10 @@ bool ElementaryStreamDescriptor::ReadWrite(BoxBuffer* buffer) { std::vector data; RCHECK(buffer->ReadWriteVector(&data, buffer->Size() - buffer->Pos())); RCHECK(es_descriptor.Parse(data)); - if (es_descriptor.IsAAC()) - RCHECK(aac.Parse(es_descriptor.decoder_specific_info())); + if (es_descriptor.IsAAC()) { + RCHECK(aac_audio_specific_config.Parse( + es_descriptor.decoder_specific_info())); + } } else { DCHECK(buffer->writer()); es_descriptor.Write(buffer->writer()); diff --git a/media/mp4/box_definitions.h b/media/mp4/box_definitions.h index 6ce0047bce..a56388e2cb 100644 --- a/media/mp4/box_definitions.h +++ b/media/mp4/box_definitions.h @@ -8,7 +8,7 @@ #include #include -#include "media/mp4/aac.h" +#include "media/mp4/aac_audio_specific_config.h" #include "media/mp4/box.h" #include "media/mp4/es_descriptor.h" #include "media/mp4/fourccs.h" @@ -210,7 +210,7 @@ struct VideoSampleEntry : Box { struct ElementaryStreamDescriptor : FullBox { DECLARE_BOX_METHODS(ElementaryStreamDescriptor); - AAC aac; + AACAudioSpecificConfig aac_audio_specific_config; ESDescriptor es_descriptor; }; diff --git a/media/mp4/mp4_media_parser.cc b/media/mp4/mp4_media_parser.cc index 8f58172714..96ce30b36b 100644 --- a/media/mp4/mp4_media_parser.cc +++ b/media/mp4/mp4_media_parser.cc @@ -227,10 +227,11 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) { // supported MPEG2 AAC variants. if (entry.esds.es_descriptor.IsAAC()) { codec = kCodecAAC; - const AAC& aac = entry.esds.aac; - num_channels = aac.num_channels(); - sampling_frequency = aac.frequency(); - audio_object_type = aac.audio_object_type(); + const AACAudioSpecificConfig& aac_audio_specific_config = + entry.esds.aac_audio_specific_config; + num_channels = aac_audio_specific_config.num_channels(); + sampling_frequency = aac_audio_specific_config.frequency(); + audio_object_type = aac_audio_specific_config.audio_object_type(); extra_data = entry.esds.es_descriptor.decoder_specific_info(); } else if (audio_type == kEAC3) { codec = kCodecEAC3; diff --git a/packager.gyp b/packager.gyp index 2631adcc97..1710b50a2b 100644 --- a/packager.gyp +++ b/packager.gyp @@ -98,8 +98,8 @@ 'target_name': 'mp4', 'type': 'static_library', 'sources': [ - 'media/mp4/aac.cc', - 'media/mp4/aac.h', + 'media/mp4/aac_audio_specific_config.cc', + 'media/mp4/aac_audio_specific_config.h', 'media/mp4/box.cc', 'media/mp4/box.h', 'media/mp4/box_buffer_interface.h', @@ -147,7 +147,7 @@ 'target_name': 'mp4_unittest', 'type': 'executable', 'sources': [ - 'media/mp4/aac_unittest.cc', + 'media/mp4/aac_audio_specific_config_unittest.cc', 'media/mp4/box_definitions_unittest.cc', 'media/mp4/box_reader_unittest.cc', 'media/mp4/chunk_info_iterator_unittest.cc',