1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/tools/player_wtl/movie.h"
8 #include "base/memory/singleton.h"
9 #include "base/threading/platform_thread.h"
10 #include "base/utf_string_conversions.h"
11 #include "media/audio/audio_manager.h"
12 #include "media/base/filter_collection.h"
13 #include "media/base/media_log.h"
14 #include "media/base/message_loop_factory.h"
15 #include "media/base/pipeline.h"
16 #include "media/filters/ffmpeg_audio_decoder.h"
17 #include "media/filters/ffmpeg_demuxer.h"
18 #include "media/filters/ffmpeg_video_decoder.h"
19 #include "media/filters/file_data_source.h"
20 #include "media/filters/null_audio_renderer.h"
21 #include "media/filters/video_renderer_base.h"
26 : audio_manager_(AudioManager::Create()),
29 enable_dump_yuv_file_(false),
40 Movie
* Movie::GetInstance() {
41 return Singleton
<Movie
>::get();
44 bool Movie::IsOpen() {
45 return pipeline_
!= NULL
;
48 void Movie::SetFrameBuffer(HBITMAP hbmp
, HWND hwnd
) {
53 bool Movie::Open(const wchar_t* url
, VideoRendererBase
* video_renderer
) {
54 // Close previous movie.
59 message_loop_factory_
.reset(new media::MessageLoopFactory());
61 MessageLoop
* pipeline_loop
=
62 message_loop_factory_
->GetMessageLoop("PipelineThread");
63 pipeline_
= new Pipeline(pipeline_loop
, new media::MediaLog());
66 std::string url_utf8
= WideToUTF8(string16(url
));
67 scoped_refptr
<FileDataSource
> data_source
= new FileDataSource();
68 if (data_source
->Initialize(url_utf8
) != PIPELINE_OK
) {
72 // Create filter collection.
73 scoped_ptr
<FilterCollection
> collection(new FilterCollection());
74 collection
->SetDemuxer(new FFmpegDemuxer(
75 pipeline_loop
, data_source
, true));
76 collection
->AddAudioDecoder(new FFmpegAudioDecoder(
77 base::Bind(&MessageLoopFactory::GetMessageLoop
,
78 base::Unretained(message_loop_factory_
.get()),
79 "AudioDecoderThread")));
80 collection
->AddVideoDecoder(new FFmpegVideoDecoder(
81 base::Bind(&MessageLoopFactory::GetMessageLoop
,
82 base::Unretained(message_loop_factory_
.get()),
83 "VideoDecoderThread")));
85 // TODO(vrk): Re-enabled audio. (crbug.com/112159)
86 collection
->AddAudioRenderer(new media::NullAudioRenderer());
87 collection
->AddVideoRenderer(video_renderer
);
89 // Create and start our pipeline.
90 media::PipelineStatusNotification note
;
93 media::PipelineStatusCB(),
94 media::PipelineStatusCB(),
95 media::NetworkEventCB(),
98 // Wait until the pipeline is fully initialized.
100 if (note
.status() != PIPELINE_OK
)
102 pipeline_
->SetPlaybackRate(play_rate_
);
106 void Movie::Play(float rate
) {
109 pipeline_
->SetPlaybackRate(enable_pause_
? 0.0f
: rate
);
114 // Get playback rate.
115 float Movie::GetPlayRate() {
119 // Get movie duration in seconds.
120 float Movie::GetDuration() {
121 float duration
= 0.f
;
123 duration
= (pipeline_
->GetMediaDuration()).InMicroseconds() / 1000000.0f
;
127 // Get current movie position in seconds.
128 float Movie::GetPosition() {
129 float position
= 0.f
;
131 position
= (pipeline_
->GetCurrentTime()).InMicroseconds() / 1000000.0f
;
135 // Set current movie position in seconds.
136 void Movie::SetPosition(float position
) {
137 int64 us
= static_cast<int64
>(position
* 1000000);
138 base::TimeDelta time
= base::TimeDelta::FromMicroseconds(us
);
140 pipeline_
->Seek(time
, media::PipelineStatusCB());
144 // Set playback pause.
145 void Movie::SetPause(bool pause
) {
146 enable_pause_
= pause
;
150 // Get playback pause state.
151 bool Movie::GetPause() {
152 return enable_pause_
;
155 void Movie::SetAudioEnable(bool enable_audio
) {
158 bool Movie::GetAudioEnable() {
159 return enable_audio_
;
162 void Movie::SetDrawEnable(bool enable_draw
) {
163 enable_draw_
= enable_draw
;
166 bool Movie::GetDrawEnable() {
170 void Movie::SetDumpYuvFileEnable(bool enable_dump_yuv_file
) {
171 enable_dump_yuv_file_
= enable_dump_yuv_file
;
174 bool Movie::GetDumpYuvFileEnable() {
175 return enable_dump_yuv_file_
;
179 void Movie::Close() {
181 pipeline_
->Stop(base::Closure());
185 message_loop_factory_
.reset();