From c851cd6fb95e44c4208e0db3cc86822ce8b09144 Mon Sep 17 00:00:00 2001 From: "acolwell@chromium.org" Date: Tue, 10 Jan 2012 23:26:07 +0000 Subject: Move WebM specific code from ChunkDemuxer to WebMStreamParser. BUG=108329 TEST=Existing ChunkDemuxer unittests TBR=acolwell@chromium.org Review URL: http://codereview.chromium.org/9170002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@117113 0039d316-1c4b-4281-b951-d872f2087c98 --- media/filters/chunk_demuxer.cc | 402 +++++++------------------ media/filters/chunk_demuxer.h | 61 +--- media/filters/ffmpeg_audio_decoder_unittest.cc | 5 +- media/filters/ffmpeg_video_decoder_unittest.cc | 4 +- 4 files changed, 128 insertions(+), 344 deletions(-) (limited to 'media/filters') diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc index 79f6178..ba3224b 100644 --- a/media/filters/chunk_demuxer.cc +++ b/media/filters/chunk_demuxer.cc @@ -2,10 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Implements a Demuxer that can switch among different data sources mid-stream. -// Uses FFmpegDemuxer under the covers, so see the caveats at the top of -// ffmpeg_demuxer.h. - #include "media/filters/chunk_demuxer.h" #include "base/bind.h" @@ -14,47 +10,11 @@ #include "media/base/audio_decoder_config.h" #include "media/base/data_buffer.h" #include "media/base/video_decoder_config.h" -#include "media/ffmpeg/ffmpeg_common.h" #include "media/filters/chunk_demuxer_client.h" -#include "media/filters/ffmpeg_glue.h" -#include "media/filters/in_memory_url_protocol.h" -#include "media/webm/webm_cluster_parser.h" -#include "media/webm/webm_constants.h" -#include "media/webm/webm_info_parser.h" -#include "media/webm/webm_tracks_parser.h" +#include "media/webm/webm_stream_parser.h" namespace media { -// WebM File Header. This is prepended to the INFO & TRACKS -// data passed to Init() before handing it to FFmpeg. Essentially -// we are making the INFO & TRACKS data look like a small WebM -// file so we can use FFmpeg to initialize the AVFormatContext. -// -// TODO(acolwell): Remove this when we construct AudioDecoderConfig and -// VideoDecoderConfig without requiring an AVStream object. -static const uint8 kWebMHeader[] = { - 0x1A, 0x45, 0xDF, 0xA3, 0x9F, // EBML (size = 0x1f) - 0x42, 0x86, 0x81, 0x01, // EBMLVersion = 1 - 0x42, 0xF7, 0x81, 0x01, // EBMLReadVersion = 1 - 0x42, 0xF2, 0x81, 0x04, // EBMLMaxIDLength = 4 - 0x42, 0xF3, 0x81, 0x08, // EBMLMaxSizeLength = 8 - 0x42, 0x82, 0x84, 0x77, 0x65, 0x62, 0x6D, // DocType = "webm" - 0x42, 0x87, 0x81, 0x02, // DocTypeVersion = 2 - 0x42, 0x85, 0x81, 0x02, // DocTypeReadVersion = 2 - // EBML end - 0x18, 0x53, 0x80, 0x67, // Segment - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // segment(size = 0) - // INFO goes here. -}; - -// Offset of the segment size field in kWebMHeader. Used to update -// the segment size field before handing the buffer to FFmpeg. -static const int kSegmentSizeOffset = sizeof(kWebMHeader) - 8; - -static const uint8 kEmptyCluster[] = { - 0x1F, 0x43, 0xB6, 0x75, 0x80 // CLUSTER (size = 0) -}; - // Create an "end of stream" buffer. static Buffer* CreateEOSBuffer() { return new DataBuffer(0); @@ -65,7 +25,8 @@ class ChunkDemuxerStream : public DemuxerStream { typedef std::deque > BufferQueue; typedef std::deque ReadCBQueue; - ChunkDemuxerStream(Type type, AVStream* stream); + explicit ChunkDemuxerStream(const AudioDecoderConfig& audio_config); + explicit ChunkDemuxerStream(const VideoDecoderConfig& video_config); virtual ~ChunkDemuxerStream(); void Flush(); @@ -87,7 +48,6 @@ class ChunkDemuxerStream : public DemuxerStream { private: Type type_; - AVStream* av_stream_; AudioDecoderConfig audio_config_; VideoDecoderConfig video_config_; @@ -105,23 +65,27 @@ class ChunkDemuxerStream : public DemuxerStream { DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); }; -ChunkDemuxerStream::ChunkDemuxerStream(Type type, AVStream* stream) - : type_(type), - av_stream_(stream), +ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config) + : type_(AUDIO), shutdown_called_(false), received_end_of_stream_(false), last_buffer_timestamp_(kNoTimestamp) { - if (type_ == AUDIO) { - AVCodecContextToAudioDecoderConfig(stream->codec, &audio_config_); - } else if (type_ == VIDEO) { - AVStreamToVideoDecoderConfig(stream, &video_config_); - } + audio_config_.CopyFrom(audio_config); +} + + +ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config) + : type_(VIDEO), + shutdown_called_(false), + received_end_of_stream_(false), + last_buffer_timestamp_(kNoTimestamp) { + video_config_.CopyFrom(video_config); } ChunkDemuxerStream::~ChunkDemuxerStream() {} void ChunkDemuxerStream::Flush() { - VLOG(1) << "Flush()"; + DVLOG(1) << "Flush()"; base::AutoLock auto_lock(lock_); buffers_.clear(); received_end_of_stream_ = false; @@ -289,7 +253,6 @@ const VideoDecoderConfig& ChunkDemuxerStream::video_decoder_config() { ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) : state_(WAITING_FOR_INIT), client_(client), - format_context_(NULL), buffered_bytes_(0), seek_waits_for_data_(true) { DCHECK(client); @@ -297,28 +260,21 @@ ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) ChunkDemuxer::~ChunkDemuxer() { DCHECK_NE(state_, INITIALIZED); - - if (!format_context_) - return; - - DestroyAVFormatContext(format_context_); - format_context_ = NULL; - - if (url_protocol_.get()) { - FFmpegGlue::GetInstance()->RemoveProtocol(url_protocol_.get()); - url_protocol_.reset(); - url_protocol_buffer_.reset(); - } } void ChunkDemuxer::Init(const PipelineStatusCB& cb) { - VLOG(1) << "Init()"; + DVLOG(1) << "Init()"; { base::AutoLock auto_lock(lock_); DCHECK_EQ(state_, WAITING_FOR_INIT); ChangeState_Locked(INITIALIZING); init_cb_ = cb; + stream_parser_.reset(new WebMStreamParser()); + + stream_parser_->Init( + base::Bind(&ChunkDemuxer::OnStreamParserInitDone, this), + this); } client_->DemuxerOpened(this); @@ -332,13 +288,13 @@ void ChunkDemuxer::set_host(DemuxerHost* host) { } void ChunkDemuxer::Stop(const base::Closure& callback) { - VLOG(1) << "Stop()"; + DVLOG(1) << "Stop()"; Shutdown(); callback.Run(); } void ChunkDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { - VLOG(1) << "Seek(" << time.InSecondsF() << ")"; + DVLOG(1) << "Seek(" << time.InSecondsF() << ")"; PipelineStatus status = PIPELINE_ERROR_INVALID_STATE; { @@ -346,7 +302,7 @@ void ChunkDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { if (state_ == INITIALIZED || state_ == ENDED) { if (seek_waits_for_data_) { - VLOG(1) << "Seek() : waiting for more data to arrive."; + DVLOG(1) << "Seek() : waiting for more data to arrive."; seek_cb_ = cb; return; } @@ -393,13 +349,13 @@ scoped_refptr ChunkDemuxer::GetStream( } base::TimeDelta ChunkDemuxer::GetStartTime() const { - VLOG(1) << "GetStartTime()"; + DVLOG(1) << "GetStartTime()"; // TODO(acolwell) : Fix this so it uses the time on the first packet. return base::TimeDelta(); } void ChunkDemuxer::FlushData() { - VLOG(1) << "FlushData()"; + DVLOG(1) << "FlushData()"; base::AutoLock auto_lock(lock_); DCHECK(state_ == INITIALIZED || state_ == ENDED || state_ == SHUTDOWN); @@ -413,14 +369,14 @@ void ChunkDemuxer::FlushData() { video_->Flush(); byte_queue_.Reset(); - cluster_parser_->Reset(); + stream_parser_->Flush(); seek_waits_for_data_ = true; ChangeState_Locked(INITIALIZED); } bool ChunkDemuxer::AppendData(const uint8* data, size_t length) { - VLOG(1) << "AppendData(" << length << ")"; + DVLOG(1) << "AppendData(" << length << ")"; if (!data || length == 0u) return false; @@ -438,40 +394,37 @@ bool ChunkDemuxer::AppendData(const uint8* data, size_t length) { int cur_size = 0; int bytes_parsed = 0; int result = -1; - bool can_complete_seek = false; + + // Capture |seek_waits_for_data_| state before we start parsing. + // Its state can be changed by OnAudioBuffers() or OnVideoBuffers() + // calls during the parse. + bool old_seek_waits_for_data = seek_waits_for_data_; byte_queue_.Peek(&cur, &cur_size); do { switch(state_) { case INITIALIZING: - result = ParseInfoAndTracks_Locked(cur, cur_size); + result = stream_parser_->Parse(cur, cur_size); if (result < 0) { - VLOG(1) << "AppendData(): parsing info & tracks failed"; ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); return true; } break; case INITIALIZED: { - bool buffers_added = false; - result = ParseCluster_Locked(cur, cur_size, &buffers_added); + result = stream_parser_->Parse(cur, cur_size); if (result < 0) { - VLOG(1) << "AppendData(): parsing data failed"; ReportError_Locked(PIPELINE_ERROR_DECODE); return true; } - - // We can complete the seek if we have successfully parsed - // some data and buffers were added to one of the DemuxerStreams. - can_complete_seek |= (result > 0 && buffers_added); } break; case WAITING_FOR_INIT: case ENDED: case PARSE_ERROR: case SHUTDOWN: - VLOG(1) << "AppendData(): called in unexpected state " << state_; + DVLOG(1) << "AppendData(): called in unexpected state " << state_; return false; } @@ -484,11 +437,11 @@ bool ChunkDemuxer::AppendData(const uint8* data, size_t length) { byte_queue_.Pop(bytes_parsed); - if (can_complete_seek && seek_waits_for_data_) { - seek_waits_for_data_ = false; - - if (!seek_cb_.is_null()) - std::swap(cb, seek_cb_); + // Check to see if parsing triggered seek_waits_for_data_ to go from true to + // false. This indicates we have parsed enough data to complete the seek. + if (old_seek_waits_for_data && !seek_waits_for_data_ && + !seek_cb_.is_null()) { + std::swap(cb, seek_cb_); } base::TimeDelta tmp; @@ -523,7 +476,7 @@ bool ChunkDemuxer::AppendData(const uint8* data, size_t length) { } void ChunkDemuxer::EndOfStream(PipelineStatus status) { - VLOG(1) << "EndOfStream(" << status << ")"; + DVLOG(1) << "EndOfStream(" << status << ")"; base::AutoLock auto_lock(lock_); DCHECK_NE(state_, WAITING_FOR_INIT); DCHECK_NE(state_, ENDED); @@ -560,7 +513,7 @@ bool ChunkDemuxer::HasEnded() { } void ChunkDemuxer::Shutdown() { - VLOG(1) << "Shutdown()"; + DVLOG(1) << "Shutdown()"; PipelineStatusCB cb; { base::AutoLock auto_lock(lock_); @@ -576,6 +529,8 @@ void ChunkDemuxer::Shutdown() { if (video_.get()) video_->Shutdown(); + stream_parser_.reset(); + ChangeState_Locked(SHUTDOWN); } @@ -590,207 +545,6 @@ void ChunkDemuxer::ChangeState_Locked(State new_state) { state_ = new_state; } -int ChunkDemuxer::ParseInfoAndTracks_Locked(const uint8* data, int size) { - lock_.AssertAcquired(); - DCHECK(data); - DCHECK_GT(size, 0); - - DCHECK_EQ(state_, INITIALIZING); - - const uint8* cur = data; - int cur_size = size; - int bytes_parsed = 0; - - int id; - int64 element_size; - int result = WebMParseElementHeader(cur, cur_size, &id, &element_size); - - if (result <= 0) - return result; - - switch (id) { - case kWebMIdEBML : - case kWebMIdSeekHead : - case kWebMIdVoid : - case kWebMIdCRC32 : - case kWebMIdCues : - if (cur_size < (result + element_size)) { - // We don't have the whole element yet. Signal we need more data. - return 0; - } - // Skip the element. - return result + element_size; - break; - case kWebMIdSegment : - // Just consume the segment header. - return result; - break; - case kWebMIdInfo : - // We've found the element we are looking for. - break; - default: - VLOG(1) << "Unexpected ID 0x" << std::hex << id; - return -1; - } - - WebMInfoParser info_parser; - result = info_parser.Parse(cur, cur_size); - - if (result <= 0) - return result; - - cur += result; - cur_size -= result; - bytes_parsed += result; - - WebMTracksParser tracks_parser(info_parser.timecode_scale()); - result = tracks_parser.Parse(cur, cur_size); - - if (result <= 0) - return result; - - bytes_parsed += result; - - double mult = info_parser.timecode_scale() / 1000.0; - duration_ = base::TimeDelta::FromMicroseconds(info_parser.duration() * mult); - - cluster_parser_.reset(new WebMClusterParser( - info_parser.timecode_scale(), - tracks_parser.audio_track_num(), - tracks_parser.audio_default_duration(), - tracks_parser.video_track_num(), - tracks_parser.video_default_duration())); - - format_context_ = CreateFormatContext(data, bytes_parsed); - if (!format_context_ || !SetupStreams()) - return -1; - - ChangeState_Locked(INITIALIZED); - init_cb_.Run(PIPELINE_OK); - init_cb_.Reset(); - return bytes_parsed; -} - -AVFormatContext* ChunkDemuxer::CreateFormatContext(const uint8* data, - int size) { - DCHECK(!url_protocol_.get()); - DCHECK(!url_protocol_buffer_.get()); - - int segment_size = size + sizeof(kEmptyCluster); - int buf_size = sizeof(kWebMHeader) + segment_size; - url_protocol_buffer_.reset(new uint8[buf_size]); - uint8* buf = url_protocol_buffer_.get(); - memcpy(buf, kWebMHeader, sizeof(kWebMHeader)); - memcpy(buf + sizeof(kWebMHeader), data, size); - memcpy(buf + sizeof(kWebMHeader) + size, kEmptyCluster, - sizeof(kEmptyCluster)); - - // Update the segment size in the buffer. - int64 tmp = (segment_size & GG_LONGLONG(0x00FFFFFFFFFFFFFF)) | - GG_LONGLONG(0x0100000000000000); - for (int i = 0; i < 8; i++) { - buf[kSegmentSizeOffset + i] = (tmp >> (8 * (7 - i))) & 0xff; - } - - url_protocol_.reset(new InMemoryUrlProtocol(buf, buf_size, true)); - std::string key = FFmpegGlue::GetInstance()->AddProtocol(url_protocol_.get()); - - // Open FFmpeg AVFormatContext. - AVFormatContext* context = NULL; - int result = av_open_input_file(&context, key.c_str(), NULL, 0, NULL); - - if (result < 0) - return NULL; - - return context; -} - -bool ChunkDemuxer::SetupStreams() { - int result = av_find_stream_info(format_context_); - - if (result < 0) - return false; - - bool no_supported_streams = true; - for (size_t i = 0; i < format_context_->nb_streams; ++i) { - AVStream* stream = format_context_->streams[i]; - AVCodecContext* codec_context = stream->codec; - AVMediaType codec_type = codec_context->codec_type; - - if (codec_type == AVMEDIA_TYPE_AUDIO && - stream->codec->codec_id == CODEC_ID_VORBIS && - !audio_.get()) { - audio_ = new ChunkDemuxerStream(DemuxerStream::AUDIO, stream); - no_supported_streams = false; - continue; - } - - if (codec_type == AVMEDIA_TYPE_VIDEO && - stream->codec->codec_id == CODEC_ID_VP8 && - !video_.get()) { - video_ = new ChunkDemuxerStream(DemuxerStream::VIDEO, stream); - no_supported_streams = false; - continue; - } - } - - return !no_supported_streams; -} - -int ChunkDemuxer::ParseCluster_Locked(const uint8* data, int size, - bool* buffers_added) { - lock_.AssertAcquired(); - if (!cluster_parser_.get()) - return -1; - - int id; - int64 element_size; - int result = WebMParseElementHeader(data, size, &id, &element_size); - - if (result <= 0) - return result; - - if (id == kWebMIdCues) { - if (size < (result + element_size)) { - // We don't have the whole element yet. Signal we need more data. - return 0; - } - // Skip the element. - return result + element_size; - } - - int bytes_parsed = cluster_parser_->Parse(data, size); - - if (bytes_parsed <= 0) - return bytes_parsed; - - if (!cluster_parser_->audio_buffers().empty() || - !cluster_parser_->video_buffers().empty()) { - // Make sure we can add the buffers to both streams before we actually - // add them. This allows us to accept all of the data or none of it. - if ((audio_.get() && - !audio_->CanAddBuffers(cluster_parser_->audio_buffers())) || - (video_.get() && - !video_->CanAddBuffers(cluster_parser_->video_buffers()))) { - return -1; - } - - if (audio_.get()) - audio_->AddBuffers(cluster_parser_->audio_buffers()); - - if (video_.get()) - video_->AddBuffers(cluster_parser_->video_buffers()); - - *buffers_added = true; - } - - // TODO(acolwell) : make this more representative of what is actually - // buffered. - buffered_bytes_ += bytes_parsed; - - return bytes_parsed; -} - void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { lock_.AssertAcquired(); DCHECK_NE(error, PIPELINE_OK); @@ -822,4 +576,68 @@ void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { } } +void ChunkDemuxer::OnStreamParserInitDone(bool success, + base::TimeDelta duration) { + lock_.AssertAcquired(); + DCHECK_EQ(state_, INITIALIZING); + if (!success || (!audio_.get() && !video_.get())) { + ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); + return; + } + + duration_ = duration; + + ChangeState_Locked(INITIALIZED); + PipelineStatusCB cb; + std::swap(cb, init_cb_); + cb.Run(PIPELINE_OK); +} + +bool ChunkDemuxer::OnNewAudioConfig(const AudioDecoderConfig& config) { + lock_.AssertAcquired(); + // Only allow a single audio config for now. + if (audio_.get()) + return false; + + audio_ = new ChunkDemuxerStream(config); + return true; +} + +bool ChunkDemuxer::OnNewVideoConfig(const VideoDecoderConfig& config) { + lock_.AssertAcquired(); + // Only allow a single video config for now. + if (video_.get()) + return false; + + video_ = new ChunkDemuxerStream(config); + return true; +} + + +bool ChunkDemuxer::OnAudioBuffers(const BufferQueue& buffers) { + if (!audio_.get()) + return false; + + if (!audio_->CanAddBuffers(buffers)) + return false; + + audio_->AddBuffers(buffers); + seek_waits_for_data_ = false; + + return true; +} + +bool ChunkDemuxer::OnVideoBuffers(const BufferQueue& buffers) { + if (!video_.get()) + return false; + + if (!video_->CanAddBuffers(buffers)) + return false; + + video_->AddBuffers(buffers); + seek_waits_for_data_ = false; + + return true; +} + } // namespace media diff --git a/media/filters/chunk_demuxer.h b/media/filters/chunk_demuxer.h index 3313c11..9ce5845 100644 --- a/media/filters/chunk_demuxer.h +++ b/media/filters/chunk_demuxer.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -10,9 +10,7 @@ #include "base/synchronization/lock.h" #include "media/base/byte_queue.h" #include "media/base/demuxer.h" -#include "media/webm/webm_cluster_parser.h" - -struct AVFormatContext; +#include "media/base/stream_parser.h" namespace media { @@ -20,9 +18,9 @@ class ChunkDemuxerClient; class ChunkDemuxerStream; class FFmpegURLProtocol; -// Demuxer implementation that allows chunks of WebM media data to be passed +// Demuxer implementation that allows chunks of media data to be passed // from JavaScript to the media stack. -class MEDIA_EXPORT ChunkDemuxer : public Demuxer { +class MEDIA_EXPORT ChunkDemuxer : public Demuxer, public StreamParserHost { public: explicit ChunkDemuxer(ChunkDemuxerClient* client); virtual ~ChunkDemuxer(); @@ -64,40 +62,18 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { void ChangeState_Locked(State new_state); - // Parses a buffer that contains an INFO & TRACKS element. This method handles - // calling & clearing |init_cb_| before it returns. - // - // Returns -1 if the parse fails. - // Returns 0 if more data is needed. - // Returns the number of bytes parsed on success. - int ParseInfoAndTracks_Locked(const uint8* data, int size); - - // Generates an AVFormatContext for the INFO & TRACKS elements contained - // in |data|. Returns NULL if parsing |data| fails. - AVFormatContext* CreateFormatContext(const uint8* data, int size); - - // Sets up |audio_| & |video_| DemuxerStreams based on the data in - // |format_context_|. Returns false if no valid audio or video stream were - // found. - bool SetupStreams(); - - // Parse a cluster and add the buffers to the appropriate DemuxerStream. This - // method also skips over CUES elements if it happens to encounter them. - // - // |data| is expected to point to the beginning of an element. - // - // |buffers_added| - Indicates whether Buffers were added to DemuxerStreams - // during the call. This is only valid if the return value > 0. - // - // Returns -1 if the parse fails. - // Returns 0 if more data is needed. - // Returns the number of bytes parsed on success. - int ParseCluster_Locked(const uint8* data, int size, bool* buffers_added); - // Reports an error and puts the demuxer in a state where it won't accept more // data. void ReportError_Locked(PipelineStatus error); + void OnStreamParserInitDone(bool success, base::TimeDelta duration); + + // StreamParserHost implementation. + virtual bool OnNewAudioConfig(const AudioDecoderConfig& config) OVERRIDE; + virtual bool OnNewVideoConfig(const VideoDecoderConfig& config) OVERRIDE; + virtual bool OnAudioBuffers(const BufferQueue& buffer) OVERRIDE; + virtual bool OnVideoBuffers(const BufferQueue& buffer) OVERRIDE; + base::Lock lock_; State state_; @@ -108,22 +84,11 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { scoped_refptr audio_; scoped_refptr video_; - // Backing buffer for |url_protocol_|. - scoped_array url_protocol_buffer_; - - // Protocol used by |format_context_|. It must outlive the context object. - scoped_ptr url_protocol_; - - // FFmpeg format context for this demuxer. It is created by - // av_open_input_file() during demuxer initialization and cleaned up with - // DestroyAVFormatContext() in the destructor. - AVFormatContext* format_context_; - int64 buffered_bytes_; base::TimeDelta duration_; - scoped_ptr cluster_parser_; + scoped_ptr stream_parser_; // Should a Seek() call wait for more data before calling the // callback. diff --git a/media/filters/ffmpeg_audio_decoder_unittest.cc b/media/filters/ffmpeg_audio_decoder_unittest.cc index f8ba102..12e2ce6 100644 --- a/media/filters/ffmpeg_audio_decoder_unittest.cc +++ b/media/filters/ffmpeg_audio_decoder_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -59,7 +59,8 @@ class FFmpegAudioDecoderTest : public testing::Test { CHANNEL_LAYOUT_STEREO, 44100, vorbis_extradata_.get(), - vorbis_extradata_size_); + vorbis_extradata_size_, + true); } virtual ~FFmpegAudioDecoderTest() {} diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc index b072993..d9c1fd4 100644 --- a/media/filters/ffmpeg_video_decoder_unittest.cc +++ b/media/filters/ffmpeg_video_decoder_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -62,7 +62,7 @@ class FFmpegVideoDecoderTest : public testing::Test { kVideoFormat, kCodedSize, kVisibleRect, kFrameRate.num, kFrameRate.den, kAspectRatio.num, kAspectRatio.den, - NULL, 0); + NULL, 0, true); } virtual ~FFmpegVideoDecoderTest() {} -- cgit v1.1