diff options
author | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-29 15:13:13 +0000 |
---|---|---|
committer | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-29 15:13:13 +0000 |
commit | 57c9ae399f80f00b533aa92c9eafeee748aa3b1c (patch) | |
tree | db5b26fc3e9090edda0c370dfdcb6790058611f3 | |
parent | 8238dd6190819daade7ee98f669e23a5a56ee4fa (diff) | |
download | chromium_src-57c9ae399f80f00b533aa92c9eafeee748aa3b1c.zip chromium_src-57c9ae399f80f00b533aa92c9eafeee748aa3b1c.tar.gz chromium_src-57c9ae399f80f00b533aa92c9eafeee748aa3b1c.tar.bz2 |
Remove AdaptiveDemuxer since it's been replaced with ChunkingDemuxer.
BUG=none
TEST=trybots
Review URL: http://codereview.chromium.org/8065023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103279 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/browser/renderer_host/browser_render_process_host.cc | 1 | ||||
-rw-r--r-- | media/base/media_switches.cc | 3 | ||||
-rw-r--r-- | media/base/media_switches.h | 1 | ||||
-rw-r--r-- | media/filters/adaptive_demuxer.cc | 1044 | ||||
-rw-r--r-- | media/filters/adaptive_demuxer.h | 270 | ||||
-rw-r--r-- | media/filters/adaptive_demuxer_unittest.cc | 70 | ||||
-rw-r--r-- | media/media.gyp | 6 | ||||
-rw-r--r-- | media/tools/player_wtl/movie.cc | 6 | ||||
-rw-r--r-- | webkit/glue/webmediaplayer_impl.cc | 24 |
9 files changed, 4 insertions, 1421 deletions
diff --git a/content/browser/renderer_host/browser_render_process_host.cc b/content/browser/renderer_host/browser_render_process_host.cc index 4d21e2e..b5d5d5b 100644 --- a/content/browser/renderer_host/browser_render_process_host.cc +++ b/content/browser/renderer_host/browser_render_process_host.cc @@ -563,7 +563,6 @@ void BrowserRenderProcessHost::PropagateBrowserCommandLineToRenderer( switches::kDisableWebAudio, switches::kDisableWebSockets, switches::kEnableAccessibilityLogging, - switches::kEnableAdaptive, switches::kEnableDCHECK, switches::kEnableGPUServiceLogging, switches::kEnableGPUClientLogging, diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index c779cc4..eb57065 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc @@ -13,9 +13,6 @@ const char kAlsaOutputDevice[] = "alsa-output-device"; const char kAlsaInputDevice[] = "alsa-input-device"; #endif -// Enable x-adaptive URL scheme. -const char kEnableAdaptive[] = "enable-adaptive"; - // Use PulseAudio instead of ALSA on Linux. const char kUsePulseAudio[] = "use-pulseaudio"; diff --git a/media/base/media_switches.h b/media/base/media_switches.h index d4bc9a3..410277e 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h @@ -17,7 +17,6 @@ extern const char kAlsaOutputDevice[]; extern const char kAlsaInputDevice[]; #endif -MEDIA_EXPORT extern const char kEnableAdaptive[]; MEDIA_EXPORT extern const char kUsePulseAudio[]; MEDIA_EXPORT extern const char kVideoThreads[]; diff --git a/media/filters/adaptive_demuxer.cc b/media/filters/adaptive_demuxer.cc deleted file mode 100644 index de980f9..0000000 --- a/media/filters/adaptive_demuxer.cc +++ /dev/null @@ -1,1044 +0,0 @@ -// Copyright (c) 2011 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 "base/bind.h" -#include "base/logging.h" -#include "base/message_loop.h" -#include "base/string_number_conversions.h" -#include "base/string_split.h" -#include "base/string_util.h" -#include "base/timer.h" -#include "media/ffmpeg/ffmpeg_common.h" -#include "media/filters/adaptive_demuxer.h" - -namespace media { - -static const int64 kSwitchTimerPeriod = 5000; // In milliseconds. - -// Object that decides when to switch streams. -class StreamSwitchManager - : public base::RefCountedThreadSafe<StreamSwitchManager> { - public: - typedef std::vector<int> StreamIdVector; - - StreamSwitchManager(AdaptiveDemuxer* demuxer, - const StreamIdVector& video_ids); - virtual ~StreamSwitchManager(); - - // Playback events. These methods are called when playback starts, pauses, or - // stops. - void Play(); - void Pause(); - void Stop(); - - private: - // Method called periodically to determine if we should switch - // streams. - void OnSwitchTimer(); - - // Called when the demuxer completes a stream switch. - void OnSwitchDone(PipelineStatus status); - - // The demuxer that owns this object. - AdaptiveDemuxer* demuxer_; - - // Message loop this object runs on. - MessageLoop* message_loop_; - - // Is clip playing or not? - bool playing_; - - // Is a stream switch in progress? - bool switch_pending_; - - // Periodic timer that calls OnSwitchTimer(). - base::RepeatingTimer<StreamSwitchManager> timer_; - - // The stream IDs for the video streams. - StreamIdVector video_ids_; - - // An index into |video_ids_| for the current video stream. - int current_id_index_; - - DISALLOW_COPY_AND_ASSIGN(StreamSwitchManager); -}; - -StreamSwitchManager::StreamSwitchManager( - AdaptiveDemuxer* demuxer, - const StreamIdVector& video_ids) - : demuxer_(demuxer), - playing_(false), - switch_pending_(false), - video_ids_(video_ids), - current_id_index_(-1) { - DCHECK(demuxer); - message_loop_ = MessageLoop::current(); - demuxer_ = demuxer; - current_id_index_ = -1; - - if (video_ids_.size() > 0) { - // Find the index in video_ids_ for the current video ID. - int current_id = demuxer->GetCurrentVideoId(); - current_id_index_ = 0; - for (size_t i = 0; i < video_ids_.size(); i++) { - if (current_id == video_ids_[i]) { - current_id_index_ = i; - break; - } - } - } -} - -StreamSwitchManager::~StreamSwitchManager() {} - -void StreamSwitchManager::Play() { - DCHECK_EQ(MessageLoop::current(), message_loop_); - DCHECK(!playing_); - playing_ = true; - - if (video_ids_.size() > 1) { - timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(kSwitchTimerPeriod), - this, &StreamSwitchManager::OnSwitchTimer); - } -} - -void StreamSwitchManager::Pause() { - DCHECK_EQ(MessageLoop::current(), message_loop_); - DCHECK(playing_); - playing_ = false; - timer_.Stop(); -} - -void StreamSwitchManager::Stop() { - DCHECK_EQ(MessageLoop::current(), message_loop_); - DCHECK(!playing_); - demuxer_ = NULL; -} - -void StreamSwitchManager::OnSwitchTimer() { - DCHECK_EQ(MessageLoop::current(), message_loop_); - - if (!playing_ || !demuxer_ || (video_ids_.size() < 2) || switch_pending_) - return; - - // Select the stream to switch to. For now we are just rotating - // through the available streams. - int new_id_index = (current_id_index_ + 1) % video_ids_.size(); - - current_id_index_ = new_id_index; - switch_pending_ = true; - demuxer_->ChangeVideoStream(video_ids_[new_id_index], - base::Bind(&StreamSwitchManager::OnSwitchDone, - this)); -} - -void StreamSwitchManager::OnSwitchDone(PipelineStatus status) { - if (MessageLoop::current() != message_loop_) { - message_loop_->PostTask( - FROM_HERE, - NewRunnableMethod(this, &StreamSwitchManager::OnSwitchDone, status)); - return; - } - - switch_pending_ = false; -} - -// -// AdaptiveDemuxerStream -// -AdaptiveDemuxerStream::AdaptiveDemuxerStream( - StreamVector const& streams, int initial_stream) - : streams_(streams), current_stream_index_(initial_stream), - bitstream_converter_enabled_(false), - pending_reads_(0), - switch_index_(-1), - last_buffer_timestamp_(kNoTimestamp) { - DCheckSanity(); -} - -void AdaptiveDemuxerStream::DCheckSanity() { - // We only carry out sanity checks in debug mode. - if (!logging::DEBUG_MODE) - return; - DCHECK(streams_[current_stream_index_].get()); - - bool non_null_stream_seen = false; - Type type = DemuxerStream::UNKNOWN; - for (size_t i = 0; i < streams_.size(); ++i) { - if (!streams_[i]) - continue; - - if (!non_null_stream_seen) { - non_null_stream_seen = true; - type = streams_[i]->type(); - } else { - DCHECK_EQ(streams_[i]->type(), type); - } - } -} - -AdaptiveDemuxerStream::~AdaptiveDemuxerStream() { - base::AutoLock auto_lock(lock_); - current_stream_index_ = -1; - streams_.clear(); -} - -DemuxerStream* AdaptiveDemuxerStream::current_stream() { - base::AutoLock auto_lock(lock_); - return streams_[current_stream_index_]; -} - -void AdaptiveDemuxerStream::Read(const ReadCallback& read_callback) { - DemuxerStream* stream = NULL; - - { - base::AutoLock auto_lock(lock_); - - read_cb_queue_.push_back(read_callback); - - // Check to make sure we aren't doing a stream switch. We only want to - // make calls on |streams_[current_stream_index_]| when we aren't - // in the middle of a stream switch. Since the callback is stored in - // |read_cb_queue_| we will issue the Read() on the new stream once - // the switch has completed. - if (!IsSwitchPending_Locked()) { - stream = streams_[current_stream_index_]; - pending_reads_++; - } - } - - if (stream) - stream->Read(base::Bind(&AdaptiveDemuxerStream::OnReadDone, this)); -} - -AVStream* AdaptiveDemuxerStream::GetAVStream() { - return current_stream()->GetAVStream(); -} - -const AudioDecoderConfig& AdaptiveDemuxerStream::audio_decoder_config() { - return current_stream()->audio_decoder_config(); -} - -DemuxerStream::Type AdaptiveDemuxerStream::type() { - return current_stream()->type(); -} - -void AdaptiveDemuxerStream::EnableBitstreamConverter() { - { - base::AutoLock auto_lock(lock_); - bitstream_converter_enabled_ = true; - } - current_stream()->EnableBitstreamConverter(); -} - -void AdaptiveDemuxerStream::OnAdaptiveDemuxerSeek(base::TimeDelta seek_time) { - base::AutoLock auto_lock(lock_); - - last_buffer_timestamp_ = seek_time; - - // TODO(acolwell): Figure out what to do if this happens during a stream - // switch. -} - -// This method initiates a stream switch. The diagram below shows the steps -// involved. -// -// +-----------------------+ -// ChangeCurrentStream() -> | Store stream switch | -// | index, seek_function, | -// | and switch_cb. | -// +-----------------------+ -// | -// V -// +-------------------+ Yes -// | Are there pending | -----> (Wait for OnReadDone()) -// | Read()s on the | | -// | current stream? | <-----+ V -// +-------------------+ +--- OnReadDone() -// | No -// V -// StartSwitch() -// | -// V -// +------------------------+ No -// | Have buffer timestamp? |-----+ -// +------------------------+ | -// | Yes | -// V | -// +-----------------------------+ | -// | Seek stream to timestamp | | -// | using switch_seek_function_ | | -// +-----------------------------+ | -// | | -// V | -// OnSwitchSeekDone() <-----+ -// | -// V -// +------------------+ No -// | Seek successful? |----------+ -// +------------------+ | -// | Yes | -// V | -// +------------------------------+ | -// | Update current_stream_index_ | | -// +------------------------------+ | -// | | -// V | -// +---------------------------+ | -// | Call Read() on new stream |<---+ -// | for deferred reads. | -// +---------------------------+ -// | -// V -// switch_cb(OK | ERROR) -// -// NOTE: Any AdaptiveDemuxerStream::Read() calls that occur during the stream -// switch will be deferred until the switch has completed. The callbacks -// will be queued on |read_cb_queue_|, but no Read() will be issued on the -// current stream. -void AdaptiveDemuxerStream::ChangeCurrentStream( - int index, - const SeekFunction& seek_function, - const PipelineStatusCB& switch_cb) { - DCHECK_GE(index, 0); - - bool start_switch = false; - - { - base::AutoLock auto_lock(lock_); - - DCHECK_LE(index, (int)streams_.size()); - DCHECK(streams_[index].get()); - DCHECK_NE(index, current_stream_index_); - DCHECK(!IsSwitchPending_Locked()); - - // TODO(acolwell): Still need to handle the case where the stream has ended. - - switch_cb_ = switch_cb; - switch_index_ = index; - switch_seek_function_ = seek_function; - - start_switch = CanStartSwitch_Locked(); - } - - if (start_switch) - StartSwitch(); -} - -void AdaptiveDemuxerStream::OnReadDone(Buffer* buffer) { - ReadCallback read_cb; - bool start_switch = false; - - { - base::AutoLock auto_lock(lock_); - - pending_reads_--; - - DCHECK_GE(pending_reads_, 0); - DCHECK_GE(read_cb_queue_.size(), 0u); - - read_cb = read_cb_queue_.front(); - read_cb_queue_.pop_front(); - - if (buffer && !buffer->IsEndOfStream()) - last_buffer_timestamp_ = buffer->GetTimestamp(); - - start_switch = IsSwitchPending_Locked() && CanStartSwitch_Locked(); - } - - if (!read_cb.is_null()) - read_cb.Run(buffer); - - if (start_switch) - StartSwitch(); -} - -bool AdaptiveDemuxerStream::IsSwitchPending_Locked() const { - lock_.AssertAcquired(); - return !switch_cb_.is_null(); -} - -bool AdaptiveDemuxerStream::CanStartSwitch_Locked() const { - lock_.AssertAcquired(); - - if (pending_reads_ == 0) { - DCHECK(IsSwitchPending_Locked()); - return true; - } - return false; -} - -void AdaptiveDemuxerStream::StartSwitch() { - SeekFunction seek_function; - base::TimeDelta seek_point; - - { - base::AutoLock auto_lock(lock_); - DCHECK(IsSwitchPending_Locked()); - DCHECK_EQ(pending_reads_, 0); - DCHECK_GE(switch_index_, 0); - - seek_point = last_buffer_timestamp_; - seek_function = switch_seek_function_; - - // TODO(acolwell): add code to call switch_cb_ if we are at the end of the - // stream now. - } - - if (seek_point == kNoTimestamp) { - // We haven't seen a buffer so there is no need to seek. Just move on to - // the next stage in the switch process. - OnSwitchSeekDone(kNoTimestamp, PIPELINE_OK); - return; - } - - DCHECK(!seek_function.is_null()); - seek_function.Run(seek_point, - base::Bind(&AdaptiveDemuxerStream::OnSwitchSeekDone, this)); -} - -void AdaptiveDemuxerStream::OnSwitchSeekDone(base::TimeDelta seek_time, - PipelineStatus status) { - DemuxerStream* stream = NULL; - PipelineStatusCB switch_cb; - int reads_to_request = 0; - bool needs_bitstream_converter_enabled = false; - - { - base::AutoLock auto_lock(lock_); - - if (status == PIPELINE_OK) { - DCHECK(streams_[switch_index_]); - - current_stream_index_ = switch_index_; - needs_bitstream_converter_enabled = bitstream_converter_enabled_; - } - - // Clear stream switch state. - std::swap(switch_cb, switch_cb_); - switch_index_ = -1; - switch_seek_function_.Reset(); - - // Get the number of outstanding Read()s on this object. - reads_to_request = read_cb_queue_.size(); - - DCHECK_EQ(pending_reads_, 0); - pending_reads_ = reads_to_request; - - stream = streams_[current_stream_index_]; - } - - if (needs_bitstream_converter_enabled) - EnableBitstreamConverter(); - - DCHECK(stream); - DCHECK(!switch_cb.is_null()); - - // Make the Read() calls that were deferred during the stream switch. - for (;reads_to_request > 0; --reads_to_request) - stream->Read(base::Bind(&AdaptiveDemuxerStream::OnReadDone, this)); - - // Signal that the stream switch has completed. - switch_cb.Run(status); -} - -// -// AdaptiveDemuxer -// - -AdaptiveDemuxer::AdaptiveDemuxer(DemuxerVector const& demuxers, - int initial_audio_demuxer_index, - int initial_video_demuxer_index) - : demuxers_(demuxers), - current_audio_demuxer_index_(initial_audio_demuxer_index), - current_video_demuxer_index_(initial_video_demuxer_index), - playback_rate_(0), - switch_pending_(false), - start_time_(kNoTimestamp) { - DCHECK(!demuxers_.empty()); - DCHECK_GE(current_audio_demuxer_index_, -1); - DCHECK_GE(current_video_demuxer_index_, -1); - DCHECK_LT(current_audio_demuxer_index_, static_cast<int>(demuxers_.size())); - DCHECK_LT(current_video_demuxer_index_, static_cast<int>(demuxers_.size())); - DCHECK(current_audio_demuxer_index_ != -1 || - current_video_demuxer_index_ != -1); - AdaptiveDemuxerStream::StreamVector audio_streams, video_streams; - StreamSwitchManager::StreamIdVector video_ids; - for (size_t i = 0; i < demuxers_.size(); ++i) { - DemuxerStream* video = demuxers_[i]->GetStream(DemuxerStream::VIDEO); - audio_streams.push_back(demuxers_[i]->GetStream(DemuxerStream::AUDIO)); - video_streams.push_back(video); - if (video) - video_ids.push_back(i); - if (start_time_ == kNoTimestamp || - demuxers_[i]->GetStartTime() < start_time_) { - start_time_ = demuxers_[i]->GetStartTime(); - } - } - DCHECK(start_time_ != kNoTimestamp); - // TODO(fgalligan): Add a check to make sure |demuxers_| start time are - // within an acceptable range, once the range is defined. - if (current_audio_demuxer_index_ >= 0) { - audio_stream_ = new AdaptiveDemuxerStream( - audio_streams, current_audio_demuxer_index_); - } - if (current_video_demuxer_index_ >= 0) { - video_stream_ = new AdaptiveDemuxerStream( - video_streams, current_video_demuxer_index_); - } - - stream_switch_manager_ = new StreamSwitchManager(this, video_ids); - // TODO(fischman): any streams in the underlying demuxers that aren't being - // consumed currently need to be sent to /dev/null or else FFmpegDemuxer will - // hold data for them in memory, waiting for them to get drained by a - // non-existent decoder. -} - -AdaptiveDemuxer::~AdaptiveDemuxer() {} - -// Switches the current video stream. The diagram below describes the switch -// process. -// +-------------------------------+ -// ChangeVideoStream() ---> | video_index | -// | == | Yes. -// | current_video_demuxer_index_? |--> done_cb(OK) -// +-------------------------------+ -// | No. -// V -// Call video_stream_->ChangeCurrentStream() -// | -// V -// (Wait for ChangeVideoStreamDone()) -// | -// V -// ChangeVideoStreamDone() -// | -// V -// +------------------------+ No -// | Was switch successful? |---> done_cb(ERROR) -// +------------------------+ -// | -// V -// Update current_video_demuxer_index_ -// & SetPlaybackRate() on new stream. -// | -// V -// done_cb(OK). -// -void AdaptiveDemuxer::ChangeVideoStream(int video_index, - const PipelineStatusCB& done_cb) { - // TODO(fischman): this is currently broken because when a new Demuxer is to - // be used we need to set_host(host()) it, and we need to set_host(NULL) the - // current Demuxer if it's no longer being used. - bool switching_to_current_stream = false; - AdaptiveDemuxerStream::SeekFunction seek_function; - - { - base::AutoLock auto_lock(lock_); - - DCHECK(video_stream_); - DCHECK(!switch_pending_); - if (current_video_demuxer_index_ == video_index) { - switching_to_current_stream = true; - } else { - switch_pending_ = true; - seek_function = base::Bind(&AdaptiveDemuxer::StartStreamSwitchSeek, - this, - DemuxerStream::VIDEO, - video_index); - } - } - - if (switching_to_current_stream) { - done_cb.Run(PIPELINE_OK); - return; - } - - video_stream_->ChangeCurrentStream( - video_index, seek_function, - base::Bind(&AdaptiveDemuxer::ChangeVideoStreamDone, this, video_index, - done_cb)); -} - -int AdaptiveDemuxer::GetCurrentVideoId() const { - base::AutoLock auto_lock(lock_); - return current_video_demuxer_index_; -} - -void AdaptiveDemuxer::ChangeVideoStreamDone(int new_stream_index, - const PipelineStatusCB& done_cb, - PipelineStatus status) { - { - base::AutoLock auto_lock(lock_); - - switch_pending_ = false; - - if (status == PIPELINE_OK) { - demuxers_[current_video_demuxer_index_]->SetPlaybackRate(0); - current_video_demuxer_index_ = new_stream_index; - demuxers_[current_video_demuxer_index_]->SetPlaybackRate(playback_rate_); - } - } - - done_cb.Run(status); -} - -Demuxer* AdaptiveDemuxer::current_demuxer(DemuxerStream::Type type) { - base::AutoLock auto_lock(lock_); - switch (type) { - case DemuxerStream::AUDIO: - return (current_audio_demuxer_index_ < 0) ? NULL : - demuxers_[current_audio_demuxer_index_]; - case DemuxerStream::VIDEO: - return (current_video_demuxer_index_ < 0) ? NULL : - demuxers_[current_video_demuxer_index_]; - default: - LOG(DFATAL) << "Unexpected type: " << type; - return NULL; - } -} - -// Helper class that wraps a FilterCallback and expects to get called a set -// number of times, after which the wrapped callback is fired (and deleted). -// -// TODO(acolwell): Remove this class once Stop() is converted to base::Closure. -class CountingCallback { - public: - CountingCallback(int count, FilterCallback* orig_cb) - : remaining_count_(count), orig_cb_(orig_cb) { - DCHECK_GT(remaining_count_, 0); - DCHECK(orig_cb); - } - - FilterCallback* GetACallback() { - return NewCallback(this, &CountingCallback::OnChildCallbackDone); - } - - private: - void OnChildCallbackDone() { - bool fire_orig_cb = false; - { - base::AutoLock auto_lock(lock_); - if (--remaining_count_ == 0) - fire_orig_cb = true; - } - if (fire_orig_cb) { - orig_cb_->Run(); - delete this; - } - } - - base::Lock lock_; - int remaining_count_; - scoped_ptr<FilterCallback> orig_cb_; -}; - -// Helper class that wraps PipelineStatusCB and expects to get called a set -// number of times, after which the wrapped callback is fired. If an error -// is reported in any of the callbacks, only the first error code is passed -// to the wrapped callback. -class CountingStatusCB : public base::RefCountedThreadSafe<CountingStatusCB> { - public: - CountingStatusCB(int count, const PipelineStatusCB& orig_cb) - : remaining_count_(count), orig_cb_(orig_cb), - overall_status_(PIPELINE_OK) { - DCHECK_GT(remaining_count_, 0); - DCHECK(!orig_cb.is_null()); - } - - PipelineStatusCB GetACallback() { - return base::Bind(&CountingStatusCB::OnChildCallbackDone, this); - } - - private: - void OnChildCallbackDone(PipelineStatus status) { - bool fire_orig_cb = false; - PipelineStatus overall_status = PIPELINE_OK; - - { - base::AutoLock auto_lock(lock_); - - if (overall_status_ == PIPELINE_OK && status != PIPELINE_OK) - overall_status_ = status; - - if (--remaining_count_ == 0) { - fire_orig_cb = true; - overall_status = overall_status_; - } - } - - if (fire_orig_cb) - orig_cb_.Run(overall_status); - } - - base::Lock lock_; - int remaining_count_; - PipelineStatusCB orig_cb_; - PipelineStatus overall_status_; - - DISALLOW_COPY_AND_ASSIGN(CountingStatusCB); -}; - -void AdaptiveDemuxer::Stop(FilterCallback* callback) { - stream_switch_manager_->Stop(); - - // Stop() must be called on all of the demuxers even though only one demuxer - // is actively delivering audio and another one is delivering video. This - // just satisfies the contract that all demuxers must have Stop() called on - // them before they are destroyed. - // - // TODO(acolwell): Remove CountingCallback once Stop() is converted to - // base::Closure. - CountingCallback* wrapper = new CountingCallback(demuxers_.size(), callback); - for (size_t i = 0; i < demuxers_.size(); ++i) - demuxers_[i]->Stop(wrapper->GetACallback()); -} - -void AdaptiveDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { - if (audio_stream_) - audio_stream_->OnAdaptiveDemuxerSeek(time); - - if (video_stream_) - video_stream_->OnAdaptiveDemuxerSeek(time); - - Demuxer* audio = current_demuxer(DemuxerStream::AUDIO); - Demuxer* video = current_demuxer(DemuxerStream::VIDEO); - int count = (audio ? 1 : 0) + (video && audio != video ? 1 : 0); - CountingStatusCB* wrapper = new CountingStatusCB(count, cb); - if (audio) - audio->Seek(time, wrapper->GetACallback()); - if (video && audio != video) - video->Seek(time, wrapper->GetACallback()); -} - -void AdaptiveDemuxer::OnAudioRendererDisabled() { - for (size_t i = 0; i < demuxers_.size(); ++i) - demuxers_[i]->OnAudioRendererDisabled(); -} - -void AdaptiveDemuxer::set_host(FilterHost* filter_host) { - Demuxer* audio = current_demuxer(DemuxerStream::AUDIO); - Demuxer* video = current_demuxer(DemuxerStream::VIDEO); - if (audio) audio->set_host(filter_host); - if (video && audio != video) video->set_host(filter_host); -} - -void AdaptiveDemuxer::SetPlaybackRate(float playback_rate) { - { - base::AutoLock auto_lock(lock_); - if (playback_rate_ == 0 && playback_rate > 0) { - stream_switch_manager_->Play(); - } else if (playback_rate_ > 0 && playback_rate == 0) { - stream_switch_manager_->Pause(); - } - - playback_rate_ = playback_rate; - } - - Demuxer* audio = current_demuxer(DemuxerStream::AUDIO); - Demuxer* video = current_demuxer(DemuxerStream::VIDEO); - if (audio) audio->SetPlaybackRate(playback_rate); - if (video && audio != video) video->SetPlaybackRate(playback_rate); -} - -void AdaptiveDemuxer::SetPreload(Preload preload) { - for (size_t i = 0; i < demuxers_.size(); ++i) - demuxers_[i]->SetPreload(preload); -} - -scoped_refptr<DemuxerStream> AdaptiveDemuxer::GetStream( - DemuxerStream::Type type) { - switch (type) { - case DemuxerStream::AUDIO: - return audio_stream_; - case DemuxerStream::VIDEO: - return video_stream_; - default: - LOG(DFATAL) << "Unexpected type " << type; - return NULL; - } -} - -base::TimeDelta AdaptiveDemuxer::GetStartTime() const { - return start_time_; -} - -void AdaptiveDemuxer::StartStreamSwitchSeek( - DemuxerStream::Type type, - int stream_index, - base::TimeDelta seek_time, - const AdaptiveDemuxerStream::SeekFunctionCB& seek_cb) { - DCHECK_GE(stream_index, 0); - DCHECK(!seek_cb.is_null()); - - Demuxer* demuxer = NULL; - base::TimeDelta seek_point; - PipelineStatusCB filter_cb; - - { - base::AutoLock auto_lock(lock_); - - demuxer = demuxers_[stream_index]; - - if (GetSeekTimeAfter(demuxer->GetStream(type)->GetAVStream(), seek_time, - &seek_point)) { - // We found a seek point. - filter_cb = base::Bind(&AdaptiveDemuxer::OnStreamSeekDone, - seek_cb, seek_point); - } else { - // We didn't find a seek point. Assume we don't have index data for it - // yet. Seek to the specified time to force index data to be loaded. - seek_point = seek_time; - filter_cb = base::Bind(&AdaptiveDemuxer::OnIndexSeekDone, this, - type, stream_index, seek_time, seek_cb); - } - } - - DCHECK(demuxer); - demuxer->Seek(seek_point, filter_cb); -} - -void AdaptiveDemuxer::OnIndexSeekDone( - DemuxerStream::Type type, - int stream_index, - base::TimeDelta seek_time, - const AdaptiveDemuxerStream::SeekFunctionCB& seek_cb, - PipelineStatus status) { - base::TimeDelta seek_point; - PipelineStatusCB filter_cb; - - Demuxer* demuxer = NULL; - - if (status != PIPELINE_OK) { - seek_cb.Run(base::TimeDelta(), status); - return; - } - - { - base::AutoLock auto_lock(lock_); - - demuxer = demuxers_[stream_index]; - DCHECK(demuxer); - - // Look for a seek point now that we have index data. - if (GetSeekTimeAfter(demuxer->GetStream(type)->GetAVStream(), seek_time, - &seek_point)) { - filter_cb = base::Bind(&AdaptiveDemuxer::OnStreamSeekDone, - seek_cb, seek_point); - } else { - // Failed again to find a seek point. Clear the demuxer so that - // a seek error will be reported. - demuxer = NULL; - } - } - - if (!demuxer) { - seek_cb.Run(base::TimeDelta(), PIPELINE_ERROR_INITIALIZATION_FAILED); - return; - } - - demuxer->Seek(seek_point, filter_cb); -} - -// static -void AdaptiveDemuxer::OnStreamSeekDone( - const AdaptiveDemuxerStream::SeekFunctionCB& seek_cb, - base::TimeDelta seek_point, - PipelineStatus status) { - seek_cb.Run(seek_point, status); -} - -// -// AdaptiveDemuxerFactory -// - -AdaptiveDemuxerFactory::AdaptiveDemuxerFactory( - DemuxerFactory* delegate_factory) - : delegate_factory_(delegate_factory) { - DCHECK(delegate_factory); -} - -AdaptiveDemuxerFactory::~AdaptiveDemuxerFactory() {} - -DemuxerFactory* AdaptiveDemuxerFactory::Clone() const { - return new AdaptiveDemuxerFactory(delegate_factory_->Clone()); -} - -// See AdaptiveDemuxerFactory's class-level comment for |url|'s format. -bool ParseAdaptiveUrl( - const std::string& url, int* audio_index, int* video_index, - std::vector<std::string>* urls) { - urls->clear(); - - if (url.empty()) - return false; - if (!StartsWithASCII(url, "x-adaptive:", false)) { - return ParseAdaptiveUrl( - "x-adaptive:0:0:" + url, audio_index, video_index, urls); - } - - std::vector<std::string> parts; - base::SplitStringDontTrim(url, ':', &parts); - if (parts.size() < 4 || - parts[0] != "x-adaptive" || - !base::StringToInt(parts[1], audio_index) || - !base::StringToInt(parts[2], video_index) || - *audio_index < -1 || *video_index < -1) { - return false; - } - - std::string::size_type first_url_pos = - parts[0].size() + 1 + parts[1].size() + 1 + parts[2].size() + 1; - std::string urls_str = url.substr(first_url_pos); - if (urls_str.empty()) - return false; - base::SplitStringDontTrim(urls_str, '^', urls); - if (urls->empty() || - *audio_index >= static_cast<int>(urls->size()) || - *video_index >= static_cast<int>(urls->size())) { - return false; - } - - return true; -} - -// Wrapper for a BuildCallback which accumulates the Demuxer's returned by a -// number of DemuxerFactory::Build() calls and eventually constructs an -// AdaptiveDemuxer and returns it to the |orig_cb| (or errors out if any -// individual Demuxer fails construction). -class DemuxerAccumulator { - public: - // Takes ownership of |orig_cb|. - DemuxerAccumulator(int audio_index, int video_index, - int count, DemuxerFactory::BuildCallback* orig_cb) - : audio_index_(audio_index), video_index_(video_index), - remaining_count_(count), orig_cb_(orig_cb), - demuxers_(count, static_cast<Demuxer*>(NULL)), - statuses_(count, PIPELINE_OK) { - DCHECK_GT(remaining_count_, 0); - DCHECK(orig_cb_.get()); - } - - DemuxerFactory::BuildCallback* GetNthCallback(int n) { - return new IndividualCallback(this, n); - } - - private: - // Wrapper for a BuildCallback that can carry one extra piece of data: the - // index of this callback in the original list of outstanding requests. - struct IndividualCallback : public DemuxerFactory::BuildCallback { - IndividualCallback(DemuxerAccumulator* accumulator, int index) - : accumulator_(accumulator), index_(index) {} - - virtual void RunWithParams(const Tuple2<PipelineStatus, Demuxer*>& params) { - accumulator_->Run(index_, params.a, params.b); - } - DemuxerAccumulator* accumulator_; - int index_; - }; - - // When an individual callback is fired, it calls this method. - void Run(int index, PipelineStatus status, Demuxer* demuxer) { - bool fire_orig_cb = false; - { - base::AutoLock auto_lock(lock_); - DCHECK(!demuxers_[index]); - demuxers_[index] = demuxer; - statuses_[index] = status; - if (--remaining_count_ == 0) - fire_orig_cb = true; - } - if (fire_orig_cb) - DoneAccumulating(); - } - - // Called when all of the demuxers have been built. - void DoneAccumulating() { - PipelineStatus overall_status = GetOverallStatus(); - if (overall_status == PIPELINE_OK) { - CallOriginalCallback(PIPELINE_OK, - new AdaptiveDemuxer(demuxers_, audio_index_, - video_index_)); - return; - } - - // An error occurred. Call Stop() on all of the demuxers that were - // successfully built. - AdaptiveDemuxer::DemuxerVector demuxers_to_stop; - - for (size_t i = 0; i < demuxers_.size(); ++i) { - if (demuxers_[i].get()) - demuxers_to_stop.push_back(demuxers_[i]); - } - - if (demuxers_to_stop.empty()) { - CallOriginalCallback(overall_status, NULL); - return; - } - - CountingCallback* wrapper = new CountingCallback( - demuxers_to_stop.size(), - NewCallback(this, &DemuxerAccumulator::StopOnErrorDone)); - for (size_t i = 0; i < demuxers_to_stop.size(); ++i) - demuxers_to_stop[i]->Stop(wrapper->GetACallback()); - } - - // Called after Stop() has been called on all of the demuxers that were - // successfully built. - void StopOnErrorDone() { - CallOriginalCallback(GetOverallStatus(), NULL); - } - - void CallOriginalCallback(PipelineStatus status, Demuxer* demuxer) { - orig_cb_->Run(status, demuxer); - - delete this; - } - - // Gets the overall status of the demuxer factory builds. If all build - // operations are successful then this will return PIPELINE_OK. If there - // are any errors then this function will return the first error that - // it encounters. Multiple builds may have failed, but we only care about - // the first error since only one error can be reported to the higher level - // code. - PipelineStatus GetOverallStatus() const { - for (size_t i = 0; i < statuses_.size(); ++i) { - if (statuses_[i] != PIPELINE_OK) - return statuses_[i]; - } - - return PIPELINE_OK; - } - - // Self-delete in CallOriginalCallback() only. - ~DemuxerAccumulator() {} - - int audio_index_; - int video_index_; - int remaining_count_; - scoped_ptr<DemuxerFactory::BuildCallback> orig_cb_; - base::Lock lock_; // Guards vectors of results below. - AdaptiveDemuxer::DemuxerVector demuxers_; - std::vector<PipelineStatus> statuses_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(DemuxerAccumulator); -}; - -void AdaptiveDemuxerFactory::Build(const std::string& url, BuildCallback* cb) { - std::vector<std::string> urls; - int audio_index, video_index; - if (!ParseAdaptiveUrl(url, &audio_index, &video_index, &urls)) { - cb->Run(Tuple2<PipelineStatus, Demuxer*>( - DEMUXER_ERROR_COULD_NOT_OPEN, NULL)); - delete cb; - return; - } - DemuxerAccumulator* accumulator = new DemuxerAccumulator( - audio_index, video_index, urls.size(), cb); - for (size_t i = 0; i < urls.size(); ++i) - delegate_factory_->Build(urls[i], accumulator->GetNthCallback(i)); -} - -} // namespace media diff --git a/media/filters/adaptive_demuxer.h b/media/filters/adaptive_demuxer.h deleted file mode 100644 index 4fd7e27..0000000 --- a/media/filters/adaptive_demuxer.h +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright (c) 2011 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. - -// 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. - -#ifndef MEDIA_FILTERS_ADAPTIVE_DEMUXER_H_ -#define MEDIA_FILTERS_ADAPTIVE_DEMUXER_H_ - -#include <deque> -#include <vector> - -#include "base/callback.h" -#include "base/synchronization/lock.h" -#include "media/base/buffers.h" -#include "media/base/filter_factories.h" -#include "media/base/demuxer.h" -#include "media/base/pipeline.h" - -namespace media { - -class AdaptiveDemuxer; -class StreamSwitchManager; - -class AdaptiveDemuxerStream : public DemuxerStream { - public: - typedef std::vector<scoped_refptr<DemuxerStream> > StreamVector; - typedef std::deque<ReadCallback> ReadCBQueue; - - // Typedefs used by the stream switching code to seek a stream to a desired - // location. The AdaptiveDemuxer constructs a SeekFunction for the stream - // being switched to and passes this function to - // AdaptiveDemuxerStream::ChangeCurrentStream(). For more information about - // how the SeekFunction is implemented, look at the comments for - // AdaptiveDemuxer::StartStreamSwitchSeek() below. - // - // Callback for SeekFunction. The PipelineStatus parameter indicates whether - // the seek was successful or not. The base::TimeDelta parameter indicates the - // time we actually seeked to. If the seek was successful this should be >= - // than the requested time. - typedef base::Callback<void(base::TimeDelta, PipelineStatus)> SeekFunctionCB; - - // Wraps a function that performs a seek on a specified stream. The - // base::TimeDelta parameter indicates what time to seek to. The - // SeekFunctionCBparameter specifies the callback we want called when the seek - // completes. - typedef base::Callback<void(base::TimeDelta, SeekFunctionCB)> SeekFunction; - - // Keeps references to the passed-in streams. |streams| must be non-empty and - // all the streams in it must agree on type. - // - // |initial_stream| must be a valid index into |streams| and specifies the - // current stream on construction. - AdaptiveDemuxerStream(StreamVector const& streams, int initial_stream); - virtual ~AdaptiveDemuxerStream(); - - // Notifies this stream that a Seek() was requested on the demuxer. - void OnAdaptiveDemuxerSeek(base::TimeDelta seek_time); - - // Change the stream to satisfy subsequent Read() requests from. The - // referenced pointer must not be NULL. The SeekFunction parameter - // provides a way to seek |streams_[index]| to a specific time. - void ChangeCurrentStream(int index, const SeekFunction& seek_function, - const PipelineStatusCB& cb); - - // DemuxerStream methods. - virtual void Read(const ReadCallback& read_callback); - virtual Type type(); - virtual void EnableBitstreamConverter(); - virtual AVStream* GetAVStream(); - virtual const AudioDecoderConfig& audio_decoder_config(); - - private: - // Returns a pointer to the current stream. - DemuxerStream* current_stream(); - - // DEBUG_MODE-only CHECK that the data members are in a reasonable state. - void DCheckSanity(); - - void OnReadDone(Buffer* buffer); - - bool IsSwitchPending_Locked() const; - bool CanStartSwitch_Locked() const; - - // Starts the stream switch. This method expects that no Read()s are - // outstanding on |streams_[current_stream_index_]|. - void StartSwitch(); - - // Called by the SeekFunction when it has completed the seek on - // |streams_[switch_index_]|. - void OnSwitchSeekDone(base::TimeDelta seek_time, PipelineStatus status); - - StreamVector streams_; - // Guards the members below. Only held for simple variable reads/writes, not - // during async operation. - base::Lock lock_; - int current_stream_index_; - bool bitstream_converter_enabled_; - - // The number of outstanding Read()'s on |streams_[current_stream_index_]|. - int pending_reads_; - - // A queue of callback objects passed to Read(). - ReadCBQueue read_cb_queue_; - - // Callback passed to ChangeCurrentStream(). This is called & reset when the - // stream switch has completed. Callback object is null when a stream switch - // is not in progress. - PipelineStatusCB switch_cb_; - - // The index of the stream we are switching to. During a stream switch - // 0 <= |switch_index_| < |streams_.size()| and - // |streams_[switch_index]| MUST NOT be null. |switch_index_| is set to -1 if - // a stream switch is not in progress. - int switch_index_; - - // Function used to seek |streams_[switch_index_]| to a specific time. The - // callback is null if a switch is not pending. - SeekFunction switch_seek_function_; - - // The timestamp of the last buffer returned via a Read() callback. - base::TimeDelta last_buffer_timestamp_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveDemuxerStream); -}; - -class AdaptiveDemuxer : public Demuxer { - public: - typedef std::vector<scoped_refptr<Demuxer> > DemuxerVector; - - // |demuxers| must be non-empty, and the index arguments must be valid indexes - // into |demuxers|, or -1 to indicate no demuxer is serving that type. - AdaptiveDemuxer(DemuxerVector const& demuxers, - int initial_audio_demuxer_index, - int initial_video_demuxer_index); - virtual ~AdaptiveDemuxer(); - - // Change to a different video stream. - void ChangeVideoStream(int video_id, const PipelineStatusCB& done_cb); - - // Get the ID of the current video stream. - int GetCurrentVideoId() const; - - // Demuxer implementation. - virtual void Stop(FilterCallback* callback) OVERRIDE; - virtual void Seek(base::TimeDelta time, const PipelineStatusCB& cb) OVERRIDE; - virtual void OnAudioRendererDisabled() OVERRIDE; - virtual void set_host(FilterHost* filter_host) OVERRIDE; - virtual void SetPlaybackRate(float playback_rate) OVERRIDE; - virtual void SetPreload(Preload preload) OVERRIDE; - virtual scoped_refptr<DemuxerStream> GetStream( - DemuxerStream::Type type) OVERRIDE; - virtual base::TimeDelta GetStartTime() const OVERRIDE; - - private: - // Returns a pointer to the currently active demuxer of the given type. - Demuxer* current_demuxer(DemuxerStream::Type type); - - // Called when the AdaptiveDemuxerStream completes a stream switch. - void ChangeVideoStreamDone(int new_stream_index, - const PipelineStatusCB& done_cb, - PipelineStatus status); - - // Methods for SeekFunction. - // - // Seeking on a stream follows the flow below. - // - // SeekFunction.Run() -> StartStreamSwitchSeek() - // | - // V - // +--------------+ - // | Found Switch | - // | Point in | No (Seeking to get more index data.) - // | Index Data? |---> |demuxers_[stream_index]->Seek()| - // +--------------+ | - // |Yes V - // | OnIndexSeekDone() - // | | - // V V - // (Seeking stream to switch point.) Yes +--------------+ - // |demuxers_[stream_index]->Seek()| <------| Found Switch | - // | | Point in | - // | | Index Data? | - // | +--------------+ - // | | No - // V V - // OnStreamSeekDone() seek_cb(ERROR) - // | - // V - // seek_cb(OK | ERROR) - // - // When AdaptiveDemuxer creates a SeekFunction object it points to this - // method. - void StartStreamSwitchSeek( - DemuxerStream::Type type, - int stream_index, - base::TimeDelta seek_time, - const AdaptiveDemuxerStream::SeekFunctionCB& seek_cb); - - // Called when the seek for index data initiated by StartStreamSwitchSeek() - // completes. - void OnIndexSeekDone(DemuxerStream::Type type, - int stream_index, - base::TimeDelta seek_time, - const AdaptiveDemuxerStream::SeekFunctionCB& seek_cb, - PipelineStatus status); - - // Called when the stream seek initiated by StartStreamSwitchSeek() or - // OnIndexSeekDone() completes. - static void OnStreamSeekDone( - const AdaptiveDemuxerStream::SeekFunctionCB& seek_cb, - base::TimeDelta seek_point, - PipelineStatus status); - - DemuxerVector demuxers_; - scoped_refptr<AdaptiveDemuxerStream> audio_stream_; - scoped_refptr<AdaptiveDemuxerStream> video_stream_; - // Guards the members below. Only held for simple variable reads/writes, not - // during async operation. - mutable base::Lock lock_; - int current_audio_demuxer_index_; - int current_video_demuxer_index_; - float playback_rate_; - bool switch_pending_; - scoped_refptr<StreamSwitchManager> stream_switch_manager_; - - // This is used to set the starting clock value to match the lowest - // timestamp of all |demuxers_|. - base::TimeDelta start_time_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveDemuxer); -}; - -// AdaptiveDemuxerFactory wraps an underlying DemuxerFactory that knows how to -// build demuxers for a single URL, and implements a primitive (for now) version -// of multi-file manifests. The manifest is encoded in the |url| parameter to -// Build() as: -// x-adaptive:<initial_audio_index>:<initial_video_index>:<URL>[^<URL>]* where -// <URL>'s are "real" media URLs which are passed to the underlying -// DemuxerFactory's Build() method individually. For backward-compatibility, -// the manifest URL may also simply be a regular URL in which case an implicit -// "x-adaptive:0:0:" is prepended. -class MEDIA_EXPORT AdaptiveDemuxerFactory : public DemuxerFactory { - public: - // Takes a reference to |demuxer_factory|. - AdaptiveDemuxerFactory(DemuxerFactory* delegate_factory); - virtual ~AdaptiveDemuxerFactory(); - - // DemuxerFactory methods. - // If any of the underlying Demuxers encounter construction errors, only the - // first one (in manifest order) will get reported back in |cb|. - virtual void Build(const std::string& url, BuildCallback* cb); - virtual DemuxerFactory* Clone() const; - - private: - scoped_ptr<DemuxerFactory> delegate_factory_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveDemuxerFactory); -}; - -// See AdaptiveDemuxerFactory's class-level comment for |url|'s format. -MEDIA_EXPORT bool ParseAdaptiveUrl( - const std::string& url, int* audio_index, int* video_index, - std::vector<std::string>* urls); - -} // namespace media - -#endif // MEDIA_FILTERS_ADAPTIVE_DEMUXER_H_ diff --git a/media/filters/adaptive_demuxer_unittest.cc b/media/filters/adaptive_demuxer_unittest.cc deleted file mode 100644 index a6fcf79..0000000 --- a/media/filters/adaptive_demuxer_unittest.cc +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2011 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 "base/string_number_conversions.h" -#include "media/filters/adaptive_demuxer.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace media { - -TEST(ParseAdaptiveUrlTest, BackwardsCompatible) { - std::string manifest = "http://youtube.com/video.webm"; - int audio_index; - int video_index; - std::vector<std::string> urls; - ASSERT_TRUE(ParseAdaptiveUrl(manifest, &audio_index, &video_index, &urls)); - EXPECT_EQ(audio_index, 0); - EXPECT_EQ(video_index, 0); - ASSERT_EQ(urls.size(), 1u); - EXPECT_EQ(urls[0], manifest); -} - -TEST(ParseAdaptiveUrlTest, CombinedManifest) { - std::string video1 = "http://youtube.com/video1.webm"; - std::string video2 = "http://youtube.com/video2.webm"; - for (int a = 0; a <= 1; ++a) { - for (int v = 0; v <= 1; ++v) { - std::string manifest = "x-adaptive:" + - base::IntToString(a) + ":" + base::IntToString(v) + ":" + - video1 + "^" + video2; - int audio_index; - int video_index; - std::vector<std::string> urls; - ASSERT_TRUE(ParseAdaptiveUrl( - manifest, &audio_index, &video_index, &urls)); - EXPECT_EQ(audio_index, a); - EXPECT_EQ(video_index, v); - ASSERT_EQ(urls.size(), 2u); - EXPECT_EQ(urls[0], video1); - EXPECT_EQ(urls[1], video2); - } - } -} - -TEST(ParseAdaptiveUrlTest, Errors) { - int audio_index; - int video_index; - std::vector<std::string> urls; - // Indexes are required on x-adaptive URLs. - EXPECT_FALSE(ParseAdaptiveUrl( - "x-adaptive:file.webm", &audio_index, &video_index, &urls)); - // Empty URL list is not allowed. - EXPECT_FALSE(ParseAdaptiveUrl( - "x-adaptive:0:0:", &audio_index, &video_index, &urls)); - EXPECT_FALSE(ParseAdaptiveUrl( - "x-adaptive:0:0", &audio_index, &video_index, &urls)); - // Empty URL is not allowed. - EXPECT_FALSE(ParseAdaptiveUrl( - "", &audio_index, &video_index, &urls)); - // Malformed indexes parameter. - EXPECT_FALSE(ParseAdaptiveUrl( - "x-adaptive:0:file.webm", &audio_index, &video_index, &urls)); - EXPECT_FALSE(ParseAdaptiveUrl( - "x-adaptive::0:file.webm", &audio_index, &video_index, &urls)); - // Invalid index for URL list. - EXPECT_FALSE(ParseAdaptiveUrl( - "x-adaptive:1:0:file.webm", &audio_index, &video_index, &urls)); -} - -} // namespace media diff --git a/media/media.gyp b/media/media.gyp index 1e402eb..4844727 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -151,8 +151,6 @@ 'ffmpeg/ffmpeg_common.h', 'ffmpeg/file_protocol.cc', 'ffmpeg/file_protocol.h', - 'filters/adaptive_demuxer.cc', - 'filters/adaptive_demuxer.h', 'filters/audio_file_reader.cc', 'filters/audio_file_reader.h', 'filters/audio_renderer_algorithm_base.cc', @@ -257,8 +255,6 @@ 'ffmpeg/ffmpeg_common.h', 'ffmpeg/file_protocol.cc', 'ffmpeg/file_protocol.h', - 'filters/adaptive_demuxer.cc', - 'filters/adaptive_demuxer.h', 'filters/audio_file_reader.cc', 'filters/audio_file_reader.h', 'filters/bitstream_converter.cc', @@ -575,7 +571,6 @@ 'base/video_util_unittest.cc', 'base/yuv_convert_unittest.cc', 'ffmpeg/ffmpeg_common_unittest.cc', - 'filters/adaptive_demuxer_unittest.cc', 'filters/audio_renderer_algorithm_ola_unittest.cc', 'filters/audio_renderer_base_unittest.cc', 'filters/bitstream_converter_unittest.cc', @@ -609,7 +604,6 @@ 'sources!': [ 'ffmpeg/ffmpeg_common_unittest.cc', 'filters/ffmpeg_audio_decoder_unittest.cc', - 'filters/adaptive_demuxer_unittest.cc', 'filters/bitstream_converter_unittest.cc', 'filters/chunk_demuxer_unittest.cc', 'filters/ffmpeg_demuxer_unittest.cc', diff --git a/media/tools/player_wtl/movie.cc b/media/tools/player_wtl/movie.cc index 58b6f0b..ad6c704 100644 --- a/media/tools/player_wtl/movie.cc +++ b/media/tools/player_wtl/movie.cc @@ -11,7 +11,6 @@ #include "media/base/media_log.h" #include "media/base/message_loop_factory_impl.h" #include "media/base/pipeline_impl.h" -#include "media/filters/adaptive_demuxer.h" #include "media/filters/audio_renderer_impl.h" #include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_demuxer_factory.h" @@ -20,7 +19,6 @@ #include "media/filters/null_audio_renderer.h" #include "media/tools/player_wtl/wtl_renderer.h" -using media::AdaptiveDemuxerFactory; using media::AudioRendererImpl; using media::FFmpegAudioDecoder; using media::FFmpegDemuxerFactory; @@ -72,8 +70,8 @@ bool Movie::Open(const wchar_t* url, WtlVideoRenderer* video_renderer) { // Create filter collection. scoped_ptr<FilterCollection> collection(new FilterCollection()); - collection->SetDemuxerFactory(new AdaptiveDemuxerFactory( - new FFmpegDemuxerFactory(new FileDataSourceFactory(), pipeline_loop))); + collection->SetDemuxerFactory(new FFmpegDemuxerFactory( + new FileDataSourceFactory(), pipeline_loop)); collection->AddAudioDecoder(new FFmpegAudioDecoder( message_loop_factory_->GetMessageLoop("AudioDecoderThread"))); collection->AddVideoDecoder(new FFmpegVideoDecoder( diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc index 0c6c9ba..c504235 100644 --- a/webkit/glue/webmediaplayer_impl.cc +++ b/webkit/glue/webmediaplayer_impl.cc @@ -17,7 +17,6 @@ #include "media/base/media_switches.h" #include "media/base/pipeline_impl.h" #include "media/base/video_frame.h" -#include "media/filters/adaptive_demuxer.h" #include "media/filters/chunk_demuxer_factory.h" #include "media/filters/dummy_demuxer_factory.h" #include "media/filters/ffmpeg_audio_decoder.h" @@ -190,27 +189,8 @@ bool WebMediaPlayerImpl::Initialize( data_source_factory->AddFactory(simple_data_source_factory.release()); } - scoped_ptr<media::DemuxerFactory> demuxer_factory( - new media::FFmpegDemuxerFactory(data_source_factory.release(), - pipeline_message_loop)); - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAdaptive)) { - demuxer_factory.reset(new media::AdaptiveDemuxerFactory( - demuxer_factory.release())); - - std::string sourceUrl; - - // TODO(acolwell): Uncomment once WebKit changes are checked in. - // https://bugs.webkit.org/show_bug.cgi?id=64731 - //sourceUrl = GetClient()->sourceURL().spec(); - - if (!sourceUrl.empty()) { - demuxer_factory.reset( - new media::ChunkDemuxerFactory(sourceUrl, - demuxer_factory.release(), - proxy_)); - } - } - filter_collection_->SetDemuxerFactory(demuxer_factory.release()); + filter_collection_->SetDemuxerFactory(new media::FFmpegDemuxerFactory( + data_source_factory.release(), pipeline_message_loop)); // Add in the default filter factories. filter_collection_->AddAudioDecoder(new media::FFmpegAudioDecoder( |