// Copyright (c) 2009 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/player/movie.h" #include "base/string_util.h" #include "media/base/pipeline_impl.h" #include "media/filters/audio_renderer_impl.h" #include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_demuxer.h" #include "media/filters/ffmpeg_video_decoder.h" #include "media/filters/file_data_source.h" #include "media/filters/null_audio_renderer.h" #include "media/player/wtl_renderer.h" using media::AudioRendererImpl; using media::FFmpegAudioDecoder; using media::FFmpegDemuxer; using media::FFmpegVideoDecoder; using media::FileDataSource; using media::FilterFactoryCollection; using media::PipelineImpl; namespace media { Movie::Movie() : enable_audio_(true), enable_draw_(true), enable_dump_yuv_file_(false), enable_pause_(false), max_threads_(0), play_rate_(1.0f), movie_dib_(NULL), movie_hwnd_(0) { } Movie::~Movie() { } bool Movie::IsOpen() { return pipeline_ != NULL; } void Movie::SetFrameBuffer(HBITMAP hbmp, HWND hwnd) { movie_dib_ = hbmp; movie_hwnd_ = hwnd; } bool Movie::Open(const wchar_t* url, WtlVideoRenderer* video_renderer) { // Close previous movie. if (pipeline_) { Close(); } // Create our filter factories. scoped_refptr factories = new FilterFactoryCollection(); factories->AddFactory(FileDataSource::CreateFactory()); factories->AddFactory(FFmpegAudioDecoder::CreateFactory()); factories->AddFactory(FFmpegDemuxer::CreateFilterFactory()); factories->AddFactory(FFmpegVideoDecoder::CreateFactory()); if (enable_audio_) { factories->AddFactory(AudioRendererImpl::CreateFilterFactory()); } else { factories->AddFactory(media::NullAudioRenderer::CreateFilterFactory()); } factories->AddFactory( new media::InstanceFilterFactory(video_renderer)); thread_.reset(new base::Thread("PipelineThread")); thread_->Start(); pipeline_ = new PipelineImpl(thread_->message_loop()); // Create and start our pipeline. pipeline_->Start(factories, WideToUTF8(std::wstring(url)), NULL); while (true) { PlatformThread::Sleep(100); if (pipeline_->IsInitialized()) break; if (pipeline_->GetError() != media::PIPELINE_OK) return false; } pipeline_->SetPlaybackRate(play_rate_); return true; } void Movie::Play(float rate) { // Begin playback. if (pipeline_) pipeline_->SetPlaybackRate(enable_pause_ ? 0.0f : rate); if (rate > 0.0f) play_rate_ = rate; } // Get playback rate. float Movie::GetPlayRate() { return play_rate_; } // Get movie duration in seconds. float Movie::GetDuration() { float duration = 0.f; if (pipeline_) duration = (pipeline_->GetDuration()).InMicroseconds() / 1000000.0f; return duration; } // Get current movie position in seconds. float Movie::GetPosition() { float position = 0.f; if (pipeline_) position = (pipeline_->GetCurrentTime()).InMicroseconds() / 1000000.0f; return position; } // Set current movie position in seconds. void Movie::SetPosition(float position) { int64 us = static_cast(position * 1000000); base::TimeDelta time = base::TimeDelta::FromMicroseconds(us); if (pipeline_) pipeline_->Seek(time, NULL); } // Set playback pause. void Movie::SetPause(bool pause) { enable_pause_ = pause; Play(play_rate_); } // Get playback pause state. bool Movie::GetPause() { return enable_pause_; } void Movie::SetAudioEnable(bool enable_audio) { enable_audio_ = enable_audio; } bool Movie::GetAudioEnable() { return enable_audio_; } void Movie::SetDrawEnable(bool enable_draw) { enable_draw_ = enable_draw; } bool Movie::GetDrawEnable() { return enable_draw_; } void Movie::SetDumpYuvFileEnable(bool enable_dump_yuv_file) { enable_dump_yuv_file_ = enable_dump_yuv_file; } bool Movie::GetDumpYuvFileEnable() { return enable_dump_yuv_file_; } // Teardown. void Movie::Close() { if (pipeline_) { pipeline_->Stop(NULL); thread_->Stop(); pipeline_ = NULL; thread_.reset(); } } } // namespace media