2 Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "ffmpeg_decoder.h"
23 #include "ffmpeg_content.h"
24 #include "imagemagick_decoder.h"
25 #include "imagemagick_content.h"
26 #include "sndfile_decoder.h"
27 #include "sndfile_content.h"
36 using boost::shared_ptr;
37 using boost::weak_ptr;
38 using boost::dynamic_pointer_cast;
40 Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p)
46 , _have_valid_decoders (false)
48 , _audio_buffers (MAX_AUDIO_CHANNELS, 0)
50 , _last_was_black (false)
53 _playlist->Changed.connect (bind (&Player::playlist_changed, this));
54 _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2));
58 Player::disable_video ()
64 Player::disable_audio ()
70 Player::disable_subtitles ()
78 if (!_have_valid_decoders) {
80 _have_valid_decoders = true;
83 cout << "-> Player::pass\n";
85 /* Here we are just finding the active decoder with the earliest last emission time, then
86 calling pass on it. If there is no decoder, we skip our position on until there is.
87 Hence this method will cause video and audio to be emitted, and it is up to the
88 process_{video,audio} methods to tidy it up.
91 Time earliest_pos = TIME_MAX;
92 shared_ptr<RegionDecoder> earliest;
93 Time next_wait = TIME_MAX;
95 for (list<shared_ptr<RegionDecoder> >::iterator i = _decoders.begin(); i != _decoders.end(); ++i) {
96 Time const ts = (*i)->region.time;
97 Time const te = (*i)->region.time + (*i)->region.content->length (_film);
98 if (ts <= _position && te > _position) {
99 Time const pos = ts + (*i)->last;
100 if (pos < earliest_pos) {
106 if (ts > _position) {
107 next_wait = min (next_wait, ts - _position);
112 earliest->decoder->pass ();
113 _position = earliest->last;
114 } else if (next_wait < TIME_MAX) {
115 _position += next_wait;
117 cout << "<- Player::pass\n";
121 cout << "<- Player::pass\n";
126 Player::process_video (shared_ptr<RegionDecoder> rd, shared_ptr<const Image> image, bool same, shared_ptr<Subtitle> sub, Time time)
128 shared_ptr<VideoDecoder> vd = dynamic_pointer_cast<VideoDecoder> (rd->decoder);
130 Time const global_time = rd->region.time + time;
131 while ((global_time - _last_video) > 1) {
132 /* Fill in with black */
136 Video (image, same, sub, global_time);
138 _last_video = global_time;
139 _last_was_black = false;
143 Player::process_audio (shared_ptr<RegionDecoder> rd, shared_ptr<const AudioBuffers> audio, Time time)
147 /* The time of this audio may indicate that some of our buffered audio is not going to
148 be added to any more, so it can be emitted.
151 if (time > _last_audio) {
152 /* We can emit some audio from our buffers */
153 OutputAudioFrame const N = min (_film->time_to_audio_frames (time - _last_audio), static_cast<OutputAudioFrame> (_audio_buffers.frames()));
154 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
155 emit->copy_from (&_audio_buffers, N, 0, 0);
156 Audio (emit, _last_audio);
157 _last_audio += _film->audio_frames_to_time (N);
159 /* And remove it from our buffers */
160 if (_audio_buffers.frames() > N) {
161 _audio_buffers.move (N, 0, _audio_buffers.frames() - N);
163 _audio_buffers.set_frames (_audio_buffers.frames() - N);
166 /* Now accumulate the new audio into our buffers */
168 if (_audio_buffers.frames() == 0) {
169 /* We have no remaining data. Emit silence up to the start of this new data */
170 if ((time - _last_audio) > 0) {
171 emit_silence (time - _last_audio);
175 _audio_buffers.ensure_size (time - _last_audio + audio->frames());
176 _audio_buffers.accumulate (audio.get(), 0, _film->time_to_audio_frames (time - _last_audio));
177 rd->last = time + _film->audio_frames_to_time (audio->frames ());
180 /** @return true on error */
182 Player::seek (Time t)
184 if (!_have_valid_decoders) {
186 _have_valid_decoders = true;
189 if (_decoders.empty ()) {
195 /* XXX: don't seek audio because we don't need to... */
208 Player::seek_forward ()
215 Player::setup_decoders ()
217 list<shared_ptr<RegionDecoder> > old_decoders = _decoders;
221 Playlist::RegionList regions = _playlist->regions ();
222 for (Playlist::RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
224 shared_ptr<RegionDecoder> rd (new RegionDecoder);
227 /* XXX: into content? */
229 shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (i->content);
231 shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio, _subtitles));
233 fd->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4));
234 fd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2));
239 shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (i->content);
241 shared_ptr<ImageMagickDecoder> id;
243 /* See if we can re-use an old ImageMagickDecoder */
244 for (list<shared_ptr<RegionDecoder> >::const_iterator i = old_decoders.begin(); i != old_decoders.end(); ++i) {
245 shared_ptr<ImageMagickDecoder> imd = dynamic_pointer_cast<ImageMagickDecoder> ((*i)->decoder);
246 if (imd && imd->content() == ic) {
252 id.reset (new ImageMagickDecoder (_film, ic));
253 id->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4));
259 shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (i->content);
261 shared_ptr<AudioDecoder> sd (new SndfileDecoder (_film, sc));
262 sd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2));
267 _decoders.push_back (rd);
274 Player::content_changed (weak_ptr<Content> w, int p)
276 shared_ptr<Content> c = w.lock ();
281 if (p == VideoContentProperty::VIDEO_LENGTH) {
282 _have_valid_decoders = false;
287 Player::playlist_changed ()
289 _have_valid_decoders = false;
293 Player::emit_black_frame ()
295 shared_ptr<SimpleImage> image (new SimpleImage (AV_PIX_FMT_RGB24, libdcp::Size (128, 128), true));
296 Video (image, _last_was_black, shared_ptr<Subtitle> (), _last_video);
297 _last_video += _film->video_frames_to_time (1);
301 Player::emit_silence (Time t)
303 OutputAudioFrame frames = _film->time_to_audio_frames (t);
305 /* Do this in half-second chunks so we don't overwhelm anybody */
306 OutputAudioFrame this_time = min (_film->dcp_audio_frame_rate() / 2, frames);
307 shared_ptr<AudioBuffers> silence (new AudioBuffers (MAX_AUDIO_CHANNELS, this_time));
308 silence->make_silent ();
309 Audio (silence, _last_audio);
310 _last_audio += _film->audio_frames_to_time (this_time);