blob: b1d957a8630b6d8914b56c4ea891ede08d543e70 [file] [log] [blame]
// 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/tools/player_wtl/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/tools/player_wtl/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<FilterFactoryCollection> 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<WtlVideoRenderer>(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<int64>(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