diff options
author | vigneshv@chromium.org <vigneshv@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-01 22:31:45 +0000 |
---|---|---|
committer | vigneshv@chromium.org <vigneshv@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-01 22:31:45 +0000 |
commit | 9e57e37f8a0da50bf9a2b11151d807652b001c82 (patch) | |
tree | ef522c3e22b10499c742638b027619b1ccb4976a /media/filters | |
parent | 735a7cef6b5d317a802f1a46369eb076f9fb2bcf (diff) | |
download | chromium_src-9e57e37f8a0da50bf9a2b11151d807652b001c82.zip chromium_src-9e57e37f8a0da50bf9a2b11151d807652b001c82.tar.gz chromium_src-9e57e37f8a0da50bf9a2b11151d807652b001c82.tar.bz2 |
media: Adding Opus support in WebM for <video> tag
In earlier CLs, support for playing back Opus in WebM container
was added to Media Source. This CL tries to implement the same
spec so that Opus in WebM can be played back in <video> tag too.
Note: This depends on an ffmpeg roll being done first (it's being worked on). This CL should not be committed until that's resolved.
TEST=media_unittests
Review URL: https://codereview.chromium.org/23868037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@232484 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/filters')
-rw-r--r-- | media/filters/ffmpeg_demuxer.cc | 18 | ||||
-rw-r--r-- | media/filters/opus_audio_decoder.cc | 36 | ||||
-rw-r--r-- | media/filters/pipeline_integration_test.cc | 4 |
3 files changed, 37 insertions, 21 deletions
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index 30c8101..2ba0c54 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc @@ -18,6 +18,7 @@ #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "base/sys_byteorder.h" #include "base/task_runner_util.h" #include "base/time/time.h" #include "media/base/audio_decoder_config.h" @@ -131,6 +132,23 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) { buffer = DecoderBuffer::CopyFrom(packet.get()->data, packet.get()->size); } + int skip_samples_size = 0; + uint8* skip_samples = av_packet_get_side_data(packet.get(), + AV_PKT_DATA_SKIP_SAMPLES, + &skip_samples_size); + const int kSkipSamplesValidSize = 10; + const int kSkipSamplesOffset = 4; + if (skip_samples_size >= kSkipSamplesValidSize) { + int discard_padding_samples = base::ByteSwapToLE32( + *(reinterpret_cast<const uint32*>(skip_samples + + kSkipSamplesOffset))); + // TODO(vigneshv): Change decoder buffer to use number of samples so that + // this conversion can be avoided. + buffer->set_discard_padding(base::TimeDelta::FromMicroseconds( + discard_padding_samples * 1000000.0 / + audio_decoder_config().samples_per_second())); + } + if ((type() == DemuxerStream::AUDIO && audio_config_.is_encrypted()) || (type() == DemuxerStream::VIDEO && video_config_.is_encrypted())) { scoped_ptr<DecryptConfig> config(WebMCreateDecryptConfig( diff --git a/media/filters/opus_audio_decoder.cc b/media/filters/opus_audio_decoder.cc index 74ac302..9d26d39 100644 --- a/media/filters/opus_audio_decoder.cc +++ b/media/filters/opus_audio_decoder.cc @@ -477,25 +477,21 @@ bool OpusAudioDecoder::ConfigureDecoder() { &opus_extra_data)) return false; - if (!config.codec_delay().InMicroseconds()) { - // TODO(vigneshv): Replace this with return false once ffmpeg demuxer code - // starts populating the config correctly. Also, timestamp is not being - // offset in this case as this code path will go away in a subsequent CL. - frames_to_discard_ = opus_extra_data.skip_samples; - } else { - // Convert from seconds to samples. - timestamp_offset_ = config.codec_delay(); - frame_delay_at_start_ = TimeDeltaToAudioFrames(config.codec_delay(), - config.samples_per_second()); - if (frame_delay_at_start_ < 0) { - DVLOG(1) << "Invalid file. Incorrect value for codec delay."; - return false; - } - if (frame_delay_at_start_ != opus_extra_data.skip_samples) { - DVLOG(1) << "Invalid file. Codec Delay in container does not match the " - << "value in Opus Extra Data."; - return false; - } + if (!config.codec_delay().InMicroseconds()) + return false; + + // Convert from seconds to samples. + timestamp_offset_ = config.codec_delay(); + frame_delay_at_start_ = TimeDeltaToAudioFrames(config.codec_delay(), + config.samples_per_second()); + if (frame_delay_at_start_ < 0) { + DVLOG(1) << "Invalid file. Incorrect value for codec delay."; + return false; + } + if (frame_delay_at_start_ != opus_extra_data.skip_samples) { + DVLOG(1) << "Invalid file. Codec Delay in container does not match the " + << "value in Opus Extra Data."; + return false; } uint8 channel_mapping[kMaxVorbisChannels]; @@ -579,7 +575,7 @@ bool OpusAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& input, // TODO(vigneshv): This should be checked for start of stream rather than // input timestamp of zero to accomodate streams that don't start at zero. if (input->timestamp() == base::TimeDelta()) - frames_to_discard_ = frame_delay_at_start_; + frames_to_discard_ = frame_delay_at_start_; if (bytes_decoded > 0 && frames_decoded > frames_to_discard_) { // Copy the audio samples into an output buffer. diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc index 6f38923..bdf79fb 100644 --- a/media/filters/pipeline_integration_test.cc +++ b/media/filters/pipeline_integration_test.cc @@ -1050,10 +1050,12 @@ TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) { // Verify that Opus audio in WebM containers can be played back. TEST_F(PipelineIntegrationTest, BasicPlayback_AudioOnly_Opus_WebM) { - ASSERT_TRUE(Start(GetTestDataFilePath("bear-opus.webm"), + ASSERT_TRUE(Start(GetTestDataFilePath("bear-opus-end-trimming.webm"), PIPELINE_OK)); Play(); ASSERT_TRUE(WaitUntilOnEnded()); + EXPECT_EQ(kOpusEndTrimmingWebMFileAudioBytes, + pipeline_->GetStatistics().audio_bytes_decoded); } // Verify that VP9 video in WebM containers can be played back. |