diff --git a/packager/media/demuxer/demuxer.gyp b/packager/media/demuxer/demuxer.gyp index 788a76ed56..80492e86fd 100644 --- a/packager/media/demuxer/demuxer.gyp +++ b/packager/media/demuxer/demuxer.gyp @@ -20,7 +20,6 @@ '../base/media_base.gyp:media_base', '../formats/mp2t/mp2t.gyp:mp2t', '../formats/mp4/mp4.gyp:mp4', - '../formats/mpeg/mpeg.gyp:mpeg', '../formats/webm/webm.gyp:webm', '../formats/webvtt/webvtt.gyp:webvtt', '../formats/wvm/wvm.gyp:wvm', diff --git a/packager/media/formats/mp2t/ac3_header.cc b/packager/media/formats/mp2t/ac3_header.cc index 757a8da73e..2cf959356e 100644 --- a/packager/media/formats/mp2t/ac3_header.cc +++ b/packager/media/formats/mp2t/ac3_header.cc @@ -43,6 +43,7 @@ const size_t kFrameSizeCodeTable[][3] = { bool Ac3Header::IsSyncWord(const uint8_t* buf) const { DCHECK(buf); + // ATSC Standard A/52:2012 5.4.1 syncinfo: Synchronization Information. return buf[0] == 0x0B && buf[1] == 0x77; } @@ -52,6 +53,13 @@ size_t Ac3Header::GetMinFrameSize() const { return kMinAc3FrameSize; } +size_t Ac3Header::GetSamplesPerFrame() const { + // ATSC Standard A/52:2012 + // Annex A: AC-3 Elementary Streams in the MPEG-2 Multiplex. + const size_t kSamplesPerAc3Frame = 1536; + return kSamplesPerAc3Frame; +} + bool Ac3Header::Parse(const uint8_t* audio_frame, size_t audio_frame_size) { BitReader frame(audio_frame, audio_frame_size); @@ -127,7 +135,7 @@ uint32_t Ac3Header::GetSamplingFrequency() const { uint8_t Ac3Header::GetNumChannels() const { DCHECK_LT(acmod_, arraysize(kAc3NumChannelsTable)); - return kAc3NumChannelsTable[acmod_]; + return kAc3NumChannelsTable[acmod_] + (lfeon_ ? 1 : 0); } } // namespace mp2t diff --git a/packager/media/formats/mp2t/ac3_header.h b/packager/media/formats/mp2t/ac3_header.h index 29debb39cb..773994cb5a 100644 --- a/packager/media/formats/mp2t/ac3_header.h +++ b/packager/media/formats/mp2t/ac3_header.h @@ -28,6 +28,7 @@ class Ac3Header : public AudioHeader { /// @{ bool IsSyncWord(const uint8_t* buf) const override; size_t GetMinFrameSize() const override; + size_t GetSamplesPerFrame() const override; bool Parse(const uint8_t* adts_frame, size_t adts_frame_size) override; size_t GetHeaderSize() const override; size_t GetFrameSize() const override; diff --git a/packager/media/formats/mp2t/ac3_header_unittest.cc b/packager/media/formats/mp2t/ac3_header_unittest.cc index 9eadde2026..ade3c4acc3 100644 --- a/packager/media/formats/mp2t/ac3_header_unittest.cc +++ b/packager/media/formats/mp2t/ac3_header_unittest.cc @@ -25,6 +25,11 @@ const char kValidPartialAc3Frame[] = "000000000000000000001DDDDDDE3C78DB6DB6DB6F9F35AD6B5AD6B5AD6B5AD6B5AD6B5AD6" "9800000000000F1B6DB6DB6DE3C78F1DDD"; +const char kValidPartialAc3FrameSixChannels[] = + "0B77A3B35E40EBF8403EFF9DF0C3F8430FE1FC155755DF3E7CFA33E7CF9F3E7CF9F3E7CF9F" + "3ECDFF3ABE7CF9F3E7CF9F3E7CF9F3E7CF9F3E7CF9F3E7CF9F3E7CF9F3E7CF9F3E7CF9F3E7" + "CF9F3E7CF9F3E7CF9F3E7C31F3E7CF9F3E7C7FCEAF9F3E7CF9F3"; + } // anonymous namespace namespace shaka { @@ -35,10 +40,13 @@ class Ac3HeaderTest : public testing::Test { public: void SetUp() override { ASSERT_TRUE(base::HexStringToBytes(kValidPartialAc3Frame, &ac3_frame_)); + ASSERT_TRUE(base::HexStringToBytes(kValidPartialAc3FrameSixChannels, + &ac3_frame_six_channels_)); } protected: std::vector ac3_frame_; + std::vector ac3_frame_six_channels_; }; TEST_F(Ac3HeaderTest, ParseSuccess) { @@ -65,6 +73,31 @@ TEST_F(Ac3HeaderTest, ParseSuccess) { audio_specific_config); } +TEST_F(Ac3HeaderTest, ParseMultiChannelSuccess) { + const size_t kExpectedFrameSize(1950); + const size_t kExpectedHeaderSize(0); + const uint8_t kExpectedObjectType(0); + const uint32_t kExpectedSamplingFrequency(44100); + const uint8_t kExpectedNumChannels(6); + const uint8_t kExpectedAudioSpecificConfig[] = {0x50, 0x3D, 0xE0}; + + Ac3Header ac3_header; + ASSERT_TRUE(ac3_header.Parse(ac3_frame_six_channels_.data(), + ac3_frame_six_channels_.size())); + EXPECT_EQ(kExpectedFrameSize, ac3_header.GetFrameSize()); + EXPECT_EQ(kExpectedHeaderSize, ac3_header.GetHeaderSize()); + EXPECT_EQ(kExpectedObjectType, ac3_header.GetObjectType()); + EXPECT_EQ(kExpectedSamplingFrequency, ac3_header.GetSamplingFrequency()); + EXPECT_EQ(kExpectedNumChannels, ac3_header.GetNumChannels()); + std::vector audio_specific_config; + ac3_header.GetAudioSpecificConfig(&audio_specific_config); + EXPECT_EQ(arraysize(kExpectedAudioSpecificConfig), + audio_specific_config.size()); + EXPECT_EQ(std::vector(std::begin(kExpectedAudioSpecificConfig), + std::end(kExpectedAudioSpecificConfig)), + audio_specific_config); +} + TEST_F(Ac3HeaderTest, ParseVariousDataSize) { Ac3Header ac3_header; diff --git a/packager/media/formats/mp2t/adts_header.cc b/packager/media/formats/mp2t/adts_header.cc index ef64e0fc1e..07f11cdcc7 100644 --- a/packager/media/formats/mp2t/adts_header.cc +++ b/packager/media/formats/mp2t/adts_header.cc @@ -9,7 +9,22 @@ #include "packager/media/base/bit_reader.h" #include "packager/media/base/bit_writer.h" #include "packager/media/formats/mp2t/mp2t_common.h" -#include "packager/media/formats/mpeg/adts_constants.h" + +namespace { +const size_t kAdtsHeaderMinSize = 7; + +// The following conversion table is extracted from ISO 14496 Part 3 - +// Table 1.16 - Sampling Frequency Index. +const int kAdtsFrequencyTable[] = {96000, 88200, 64000, 48000, 44100, + 32000, 24000, 22050, 16000, 12000, + 11025, 8000, 7350}; +const size_t kAdtsFrequencyTableSize = arraysize(kAdtsFrequencyTable); + +// The following conversion table is extracted from ISO 14496 Part 3 - +// Table 1.17 - Channel Configuration. +const int kAdtsNumChannelsTable[] = {0, 1, 2, 3, 4, 5, 6, 8}; +const size_t kAdtsNumChannelsTableSize = arraysize(kAdtsNumChannelsTable); +} // namespace namespace shaka { namespace media { @@ -23,6 +38,11 @@ size_t AdtsHeader::GetMinFrameSize() const { return kAdtsHeaderMinSize + 1; } +size_t AdtsHeader::GetSamplesPerFrame() const { + const size_t kSamplesPerAacFrame = 1024; + return kSamplesPerAacFrame; +} + bool AdtsHeader::Parse(const uint8_t* adts_frame, size_t adts_frame_size) { CHECK(adts_frame); diff --git a/packager/media/formats/mp2t/adts_header.h b/packager/media/formats/mp2t/adts_header.h index feb8f85706..26a7315e9c 100644 --- a/packager/media/formats/mp2t/adts_header.h +++ b/packager/media/formats/mp2t/adts_header.h @@ -28,6 +28,7 @@ class AdtsHeader : public AudioHeader { /// @{ bool IsSyncWord(const uint8_t* buf) const override; size_t GetMinFrameSize() const override; + size_t GetSamplesPerFrame() const override; bool Parse(const uint8_t* adts_frame, size_t adts_frame_size) override; size_t GetHeaderSize() const override; size_t GetFrameSize() const override; diff --git a/packager/media/formats/mp2t/audio_header.h b/packager/media/formats/mp2t/audio_header.h index 20660162c3..2808e053fa 100644 --- a/packager/media/formats/mp2t/audio_header.h +++ b/packager/media/formats/mp2t/audio_header.h @@ -29,6 +29,9 @@ class AudioHeader { /// @return The minium frame size. virtual size_t GetMinFrameSize() const = 0; + /// @return Number of audio samples per frame. + virtual size_t GetSamplesPerFrame() const = 0; + /// Parse a partial audio frame, extracting the fields within. Only audio /// frame header / metadata is parsed. The audio_frame_size must contain the /// full header / metadata. diff --git a/packager/media/formats/mp2t/es_parser_audio.cc b/packager/media/formats/mp2t/es_parser_audio.cc index 2244a978ef..9599563d73 100644 --- a/packager/media/formats/mp2t/es_parser_audio.cc +++ b/packager/media/formats/mp2t/es_parser_audio.cc @@ -19,7 +19,6 @@ #include "packager/media/formats/mp2t/adts_header.h" #include "packager/media/formats/mp2t/mp2t_common.h" #include "packager/media/formats/mp2t/ts_stream_type.h" -#include "packager/media/formats/mpeg/adts_constants.h" namespace shaka { namespace media { @@ -144,8 +143,8 @@ bool EsParserAudio::Parse(const uint8_t* buf, } int64_t current_pts = audio_timestamp_helper_->GetTimestamp(); - int64_t frame_duration = - audio_timestamp_helper_->GetFrameDuration(kSamplesPerAACFrame); + int64_t frame_duration = audio_timestamp_helper_->GetFrameDuration( + audio_header_->GetSamplesPerFrame()); // Emit an audio frame. bool is_key_frame = true; @@ -160,7 +159,7 @@ bool EsParserAudio::Parse(const uint8_t* buf, emit_sample_cb_.Run(pid(), sample); // Update the PTS of the next frame. - audio_timestamp_helper_->AddFrames(kSamplesPerAACFrame); + audio_timestamp_helper_->AddFrames(audio_header_->GetSamplesPerFrame()); // Skip the current frame. es_position += static_cast(audio_header_->GetFrameSize()); diff --git a/packager/media/formats/mp2t/mp2t.gyp b/packager/media/formats/mp2t/mp2t.gyp index 39a2dd28ba..dc069d9ffc 100644 --- a/packager/media/formats/mp2t/mp2t.gyp +++ b/packager/media/formats/mp2t/mp2t.gyp @@ -83,7 +83,6 @@ '../../codecs/codecs.gyp:codecs', '../../event/media_event.gyp:mock_muxer_listener', '../../test/media_test.gyp:media_test_support', - '../mpeg/mpeg.gyp:mpeg', 'mp2t', ] }, diff --git a/packager/media/formats/mpeg/adts_constants.cc b/packager/media/formats/mpeg/adts_constants.cc deleted file mode 100644 index a5c111fb4e..0000000000 --- a/packager/media/formats/mpeg/adts_constants.cc +++ /dev/null @@ -1,26 +0,0 @@ -// 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 "packager/media/formats/mpeg/adts_constants.h" - -#include "packager/base/macros.h" - -namespace shaka { -namespace media { - -// The following conversion table is extracted from ISO 14496 Part 3 - -// Table 1.16 - Sampling Frequency Index. -const int kAdtsFrequencyTable[] = {96000, 88200, 64000, 48000, 44100, - 32000, 24000, 22050, 16000, 12000, - 11025, 8000, 7350}; -const size_t kAdtsFrequencyTableSize = arraysize(kAdtsFrequencyTable); - -// The following conversion table is extracted from ISO 14496 Part 3 - -// Table 1.17 - Channel Configuration. -const int kAdtsNumChannelsTable[] = { - 0, 1, 2, 3, 4, 5, 6, 8 }; -const size_t kAdtsNumChannelsTableSize = arraysize(kAdtsNumChannelsTable); - -} // namespace media -} // namespace shaka diff --git a/packager/media/formats/mpeg/adts_constants.h b/packager/media/formats/mpeg/adts_constants.h deleted file mode 100644 index a929484bc0..0000000000 --- a/packager/media/formats/mpeg/adts_constants.h +++ /dev/null @@ -1,27 +0,0 @@ -// 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. - -#ifndef MEDIA_FORMATS_MPEG_ADTS_CONSTANTS_H_ -#define MEDIA_FORMATS_MPEG_ADTS_CONSTANTS_H_ - -#include - -namespace shaka { -namespace media { - -enum { - kAdtsHeaderMinSize = 7, - kSamplesPerAACFrame = 1024, -}; - -extern const int kAdtsFrequencyTable[]; -extern const size_t kAdtsFrequencyTableSize; - -extern const int kAdtsNumChannelsTable[]; -extern const size_t kAdtsNumChannelsTableSize; - -} // namespace media -} // namespace shaka - -#endif // MEDIA_FORMATS_MPEG_ADTS_CONSTANTS_H_ diff --git a/packager/media/formats/mpeg/mpeg.gyp b/packager/media/formats/mpeg/mpeg.gyp deleted file mode 100644 index 1a0c996baf..0000000000 --- a/packager/media/formats/mpeg/mpeg.gyp +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2014 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd - -{ - 'includes': [ - '../../../common.gypi', - ], - 'targets': [ - { - 'target_name': 'mpeg', - 'type': '<(component)', - 'sources': [ - 'adts_constants.cc', - 'adts_constants.h', - ], - }, - { - 'target_name': 'mpeg_unittest', - 'type': '<(gtest_target_type)', - 'sources': [ - ], - 'dependencies': [ - '../../../testing/gtest.gyp:gtest', - '../../../testing/gmock.gyp:gmock', - '../../test/media_test.gyp:media_test_support', - 'mpeg', - ] - }, - ], -} diff --git a/packager/media/formats/wvm/wvm.gyp b/packager/media/formats/wvm/wvm.gyp index e6c070071f..530e0ce735 100644 --- a/packager/media/formats/wvm/wvm.gyp +++ b/packager/media/formats/wvm/wvm.gyp @@ -20,7 +20,6 @@ '../../base/media_base.gyp:media_base', '../../codecs/codecs.gyp:codecs', '../../formats/mp2t/mp2t.gyp:mp2t', - '../mpeg/mpeg.gyp:mpeg', ], }, { diff --git a/packager/packager.gyp b/packager/packager.gyp index db1798ba56..8e830b7806 100644 --- a/packager/packager.gyp +++ b/packager/packager.gyp @@ -30,7 +30,6 @@ 'media/event/media_event.gyp:media_event', 'media/formats/mp2t/mp2t.gyp:mp2t', 'media/formats/mp4/mp4.gyp:mp4', - 'media/formats/mpeg/mpeg.gyp:mpeg', 'media/formats/webm/webm.gyp:webm', 'media/formats/webvtt/webvtt.gyp:webvtt', 'media/formats/wvm/wvm.gyp:wvm',