1 /* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
4 Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "ffmpeg_decoder.h"
25 #include "ffmpeg_content.h"
26 #include "imagemagick_decoder.h"
27 #include "imagemagick_content.h"
28 #include "sndfile_decoder.h"
29 #include "sndfile_content.h"
38 using boost::shared_ptr;
39 using boost::weak_ptr;
40 using boost::dynamic_pointer_cast;
42 Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p)
48 , _have_valid_decoders (false)
50 , _audio_buffers (MAX_AUDIO_CHANNELS, 0)
52 , _last_was_black (false)
55 _playlist->Changed.connect (bind (&Player::playlist_changed, this));
56 _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2));
60 Player::disable_video ()
66 Player::disable_audio ()
72 Player::disable_subtitles ()
80 if (!_have_valid_decoders) {
82 _have_valid_decoders = true;
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;
124 Player::process_video (shared_ptr<RegionDecoder> rd, shared_ptr<const Image> image, bool same, shared_ptr<Subtitle> sub, Time time)
126 shared_ptr<VideoDecoder> vd = dynamic_pointer_cast<VideoDecoder> (rd->decoder);
128 Time const global_time = rd->region->time + time;
129 while ((global_time - _last_video) > 1) {
130 /* Fill in with black */
134 Video (image, same, sub, global_time);
136 _last_video = global_time;
137 _last_was_black = false;
141 Player::process_audio (shared_ptr<RegionDecoder> rd, shared_ptr<const AudioBuffers> audio, Time time)
145 /* The time of this audio may indicate that some of our buffered audio is not going to
146 be added to any more, so it can be emitted.
149 if (time > _last_audio) {
150 /* We can emit some audio from our buffers */
151 OutputAudioFrame const N = min (_film->time_to_audio_frames (time - _last_audio), static_cast<OutputAudioFrame> (_audio_buffers.frames()));
152 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
153 emit->copy_from (&_audio_buffers, N, 0, 0);
154 Audio (emit, _last_audio);
155 _last_audio += _film->audio_frames_to_time (N);
157 /* And remove it from our buffers */
158 if (_audio_buffers.frames() > N) {
159 _audio_buffers.move (N, 0, _audio_buffers.frames() - N);
161 _audio_buffers.set_frames (_audio_buffers.frames() - N);
164 /* Now accumulate the new audio into our buffers */
166 if (_audio_buffers.frames() == 0) {
167 /* We have no remaining data. Emit silence up to the start of this new data */
168 if ((time - _last_audio) > 0) {
169 emit_silence (time - _last_audio);
173 _audio_buffers.ensure_size (time - _last_audio + audio->frames());
174 _audio_buffers.accumulate (audio.get(), 0, _film->time_to_audio_frames (time - _last_audio));
175 rd->last = time + _film->audio_frames_to_time (audio->frames ());
178 /** @return true on error */
180 Player::seek (Time t)
182 if (!_have_valid_decoders) {
184 _have_valid_decoders = true;
187 if (_decoders.empty ()) {
193 /* XXX: don't seek audio because we don't need to... */
206 Player::seek_forward ()
213 Player::setup_decoders ()
215 list<shared_ptr<RegionDecoder> > old_decoders = _decoders;
219 Playlist::RegionList regions = _playlist->regions ();
220 for (Playlist::RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
222 shared_ptr<RegionDecoder> rd (new RegionDecoder);
225 /* XXX: into content? */
227 shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> ((*i)->content);
229 shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio, _subtitles));
231 fd->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4));
232 fd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2));
237 shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> ((*i)->content);
239 shared_ptr<ImageMagickDecoder> id;
241 /* See if we can re-use an old ImageMagickDecoder */
242 for (list<shared_ptr<RegionDecoder> >::const_iterator i = old_decoders.begin(); i != old_decoders.end(); ++i) {
243 shared_ptr<ImageMagickDecoder> imd = dynamic_pointer_cast<ImageMagickDecoder> ((*i)->decoder);
244 if (imd && imd->content() == ic) {
250 id.reset (new ImageMagickDecoder (_film, ic));
251 id->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4));
257 shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> ((*i)->content);
259 shared_ptr<AudioDecoder> sd (new SndfileDecoder (_film, sc));
260 sd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2));
265 _decoders.push_back (rd);
272 Player::content_changed (weak_ptr<Content> w, int p)
274 shared_ptr<Content> c = w.lock ();
279 if (p == VideoContentProperty::VIDEO_LENGTH) {
280 _have_valid_decoders = false;
285 Player::playlist_changed ()
287 _have_valid_decoders = false;
291 Player::emit_black_frame ()
293 shared_ptr<SimpleImage> image (new SimpleImage (AV_PIX_FMT_RGB24, libdcp::Size (128, 128), true));
294 Video (image, _last_was_black, shared_ptr<Subtitle> (), _last_video);
295 _last_video += _film->video_frames_to_time (1);
299 Player::emit_silence (Time t)
301 OutputAudioFrame frames = _film->time_to_audio_frames (t);
303 /* Do this in half-second chunks so we don't overwhelm anybody */
304 OutputAudioFrame this_time = min (_film->dcp_audio_frame_rate() / 2, frames);
305 shared_ptr<AudioBuffers> silence (new AudioBuffers (MAX_AUDIO_CHANNELS, this_time));
306 silence->make_silent ();
307 Audio (silence, _last_audio);
308 _last_audio += _film->audio_frames_to_time (this_time);