8cc1849e865f0909001a55374954bca5fbe48247
[dcpomatic.git] / src / lib / player.cc
1 /*
2     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
3
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.
8
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.
13
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.
17
18 */
19
20 #include <stdint.h>
21 #include "player.h"
22 #include "film.h"
23 #include "ffmpeg_decoder.h"
24 #include "ffmpeg_content.h"
25 #include "still_image_decoder.h"
26 #include "still_image_content.h"
27 #include "sndfile_decoder.h"
28 #include "sndfile_content.h"
29 #include "subtitle_content.h"
30 #include "playlist.h"
31 #include "job.h"
32 #include "image.h"
33 #include "ratio.h"
34 #include "resampler.h"
35 #include "log.h"
36 #include "scaler.h"
37
38 using std::list;
39 using std::cout;
40 using std::min;
41 using std::max;
42 using std::vector;
43 using std::pair;
44 using std::map;
45 using boost::shared_ptr;
46 using boost::weak_ptr;
47 using boost::dynamic_pointer_cast;
48
49 //#define DEBUG_PLAYER 1
50
51 class Piece
52 {
53 public:
54         Piece (shared_ptr<Content> c)
55                 : content (c)
56                 , video_position (c->start ())
57                 , audio_position (c->start ())
58         {}
59         
60         Piece (shared_ptr<Content> c, shared_ptr<Decoder> d)
61                 : content (c)
62                 , decoder (d)
63                 , video_position (c->start ())
64                 , audio_position (c->start ())
65         {}
66         
67         shared_ptr<Content> content;
68         shared_ptr<Decoder> decoder;
69         Time video_position;
70         Time audio_position;
71 };
72
73 #ifdef DEBUG_PLAYER
74 std::ostream& operator<<(std::ostream& s, Piece const & p)
75 {
76         if (dynamic_pointer_cast<FFmpegContent> (p.content)) {
77                 s << "\tffmpeg     ";
78         } else if (dynamic_pointer_cast<StillImageContent> (p.content)) {
79                 s << "\tstill image";
80         } else if (dynamic_pointer_cast<SndfileContent> (p.content)) {
81                 s << "\tsndfile    ";
82         }
83         
84         s << " at " << p.content->start() << " until " << p.content->end();
85         
86         return s;
87 }
88 #endif  
89
90 Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p)
91         : _film (f)
92         , _playlist (p)
93         , _video (true)
94         , _audio (true)
95         , _have_valid_pieces (false)
96         , _video_position (0)
97         , _audio_position (0)
98         , _audio_buffers (f->audio_channels(), 0)
99 {
100         _playlist->Changed.connect (bind (&Player::playlist_changed, this));
101         _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2, _3));
102         _film->Changed.connect (bind (&Player::film_changed, this, _1));
103         set_video_container_size (_film->container()->size (_film->full_frame ()));
104 }
105
106 void
107 Player::disable_video ()
108 {
109         _video = false;
110 }
111
112 void
113 Player::disable_audio ()
114 {
115         _audio = false;
116 }
117
118 bool
119 Player::pass ()
120 {
121         if (!_have_valid_pieces) {
122                 setup_pieces ();
123                 _have_valid_pieces = true;
124         }
125
126 #ifdef DEBUG_PLAYER
127         cout << "= PASS\n";
128 #endif  
129
130         Time earliest_t = TIME_MAX;
131         shared_ptr<Piece> earliest;
132         enum {
133                 VIDEO,
134                 AUDIO
135         } type = VIDEO;
136
137         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
138                 if ((*i)->decoder->done ()) {
139                         continue;
140                 }
141
142                 if (_video && dynamic_pointer_cast<VideoDecoder> ((*i)->decoder)) {
143                         if ((*i)->video_position < earliest_t) {
144                                 earliest_t = (*i)->video_position;
145                                 earliest = *i;
146                                 type = VIDEO;
147                         }
148                 }
149
150                 if (_audio && dynamic_pointer_cast<AudioDecoder> ((*i)->decoder)) {
151                         if ((*i)->audio_position < earliest_t) {
152                                 earliest_t = (*i)->audio_position;
153                                 earliest = *i;
154                                 type = AUDIO;
155                         }
156                 }
157         }
158
159         if (!earliest) {
160 #ifdef DEBUG_PLAYER
161                 cout << "no earliest piece.\n";
162 #endif          
163                 
164                 flush ();
165                 return true;
166         }
167
168         switch (type) {
169         case VIDEO:
170                 if (earliest_t > _video_position) {
171 #ifdef DEBUG_PLAYER
172                         cout << "no video here; emitting black frame (earliest=" << earliest_t << ", video_position=" << _video_position << ").\n";
173 #endif
174                         emit_black ();
175                 } else {
176 #ifdef DEBUG_PLAYER
177                         cout << "Pass " << *earliest << "\n";
178 #endif                  
179                         earliest->decoder->pass ();
180                 }
181                 break;
182
183         case AUDIO:
184                 if (earliest_t > _audio_position) {
185 #ifdef DEBUG_PLAYER
186                         cout << "no audio here; emitting silence.\n";
187 #endif
188                         emit_silence (_film->time_to_audio_frames (earliest_t - _audio_position));
189                 } else {
190 #ifdef DEBUG_PLAYER
191                         cout << "Pass " << *earliest << "\n";
192 #endif                  
193                         earliest->decoder->pass ();
194                         
195                         if (earliest->decoder->done()) {
196                                 shared_ptr<AudioContent> ac = dynamic_pointer_cast<AudioContent> (earliest->content);
197                                 assert (ac);
198                                 shared_ptr<Resampler> re = resampler (ac, false);
199                                 if (re) {
200                                         shared_ptr<const AudioBuffers> b = re->flush ();
201                                         if (b->frames ()) {
202                                                 process_audio (earliest, b, ac->audio_length ());
203                                         }
204                                 }
205                         }
206                 }
207                 break;
208         }
209
210 #ifdef DEBUG_PLAYER
211         cout << "\tpost pass " << _video_position << " " << _audio_position << "\n";
212 #endif  
213
214         return false;
215 }
216
217 void
218 Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image, Eyes eyes, bool same, VideoContent::Frame frame)
219 {
220         shared_ptr<Piece> piece = weak_piece.lock ();
221         if (!piece) {
222                 return;
223         }
224
225         shared_ptr<VideoContent> content = dynamic_pointer_cast<VideoContent> (piece->content);
226         assert (content);
227
228         FrameRateConversion frc (content->video_frame_rate(), _film->video_frame_rate());
229         if (frc.skip && (frame % 2) == 1) {
230                 return;
231         }
232
233         shared_ptr<Image> work_image = image->crop (content->crop(), true);
234
235         libdcp::Size const image_size = content->ratio()->size (_video_container_size);
236         
237         work_image = work_image->scale_and_convert_to_rgb (image_size, _film->scaler(), true);
238
239         Time time = content->start() + (frame * frc.factor() * TIME_HZ / _film->video_frame_rate());
240         
241         if (_film->with_subtitles () && _out_subtitle.image && time >= _out_subtitle.from && time <= _out_subtitle.to) {
242                 work_image->alpha_blend (_out_subtitle.image, _out_subtitle.position);
243         }
244
245         if (image_size != _video_container_size) {
246                 assert (image_size.width <= _video_container_size.width);
247                 assert (image_size.height <= _video_container_size.height);
248                 shared_ptr<Image> im (new Image (PIX_FMT_RGB24, _video_container_size, true));
249                 im->make_black ();
250                 im->copy (work_image, Position<int> ((_video_container_size.width - image_size.width) / 2, (_video_container_size.height - image_size.height) / 2));
251                 work_image = im;
252         }
253
254 #ifdef DCPOMATIC_DEBUG
255         _last_video = piece->content;
256 #endif
257
258         Video (work_image, eyes, same, time);
259         time += TIME_HZ / _film->video_frame_rate();
260
261         if (frc.repeat) {
262                 Video (work_image, eyes, true, time);
263                 time += TIME_HZ / _film->video_frame_rate();
264         }
265
266         _video_position = piece->video_position = time;
267 }
268
269 void
270 Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers> audio, AudioContent::Frame frame)
271 {
272         shared_ptr<Piece> piece = weak_piece.lock ();
273         if (!piece) {
274                 return;
275         }
276
277         shared_ptr<AudioContent> content = dynamic_pointer_cast<AudioContent> (piece->content);
278         assert (content);
279
280         /* Resample */
281         if (content->content_audio_frame_rate() != content->output_audio_frame_rate()) {
282                 shared_ptr<Resampler> r = resampler (content, true);
283                 audio = r->run (audio);
284         }
285
286         /* Remap channels */
287         shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->audio_channels(), audio->frames()));
288         dcp_mapped->make_silent ();
289         list<pair<int, libdcp::Channel> > map = content->audio_mapping().content_to_dcp ();
290         for (list<pair<int, libdcp::Channel> >::iterator i = map.begin(); i != map.end(); ++i) {
291                 if (i->first < audio->channels() && i->second < dcp_mapped->channels()) {
292                         dcp_mapped->accumulate_channel (audio.get(), i->first, i->second);
293                 }
294         }
295
296         audio = dcp_mapped;
297
298         /* Convert frame to time.  After resampling, the frame time (in the DCP rate) will be T_D where
299            T_D = frame * DCP_rate / original_rate.  Hence the time in seconds is T_D / DCP_rate.
300         */
301         Time time = content->start() + (frame * TIME_HZ / _film->audio_frame_rate()) + (content->audio_delay() * TIME_HZ / 1000);
302
303         /* We must cut off anything that comes before the start of all time */
304         if (time < 0) {
305                 int const frames = - time * _film->audio_frame_rate() / TIME_HZ;
306                 if (frames >= audio->frames ()) {
307                         return;
308                 }
309
310                 shared_ptr<AudioBuffers> trimmed (new AudioBuffers (audio->channels(), audio->frames() - frames));
311                 trimmed->copy_from (audio.get(), audio->frames() - frames, frames, 0);
312
313                 audio = trimmed;
314                 time = 0;
315         }
316
317         /* The time of this audio may indicate that some of our buffered audio is not going to
318            be added to any more, so it can be emitted.
319         */
320
321         if (time > _audio_position) {
322                 /* We can emit some audio from our buffers */
323                 OutputAudioFrame const N = _film->time_to_audio_frames (time - _audio_position);
324                 if (N > _audio_buffers.frames()) {
325                         /* We need some extra silence before whatever is in the buffers */
326                         _audio_buffers.ensure_size (N);
327                         _audio_buffers.move (0, N - _audio_buffers.frames(), _audio_buffers.frames ());
328                         _audio_buffers.make_silent (0, _audio_buffers.frames());
329                         _audio_buffers.set_frames (N);
330                 }
331                 assert (N <= _audio_buffers.frames());
332                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
333                 emit->copy_from (&_audio_buffers, N, 0, 0);
334                 Audio (emit, _audio_position);
335                 _audio_position = piece->audio_position = time + _film->audio_frames_to_time (N);
336
337                 /* And remove it from our buffers */
338                 if (_audio_buffers.frames() > N) {
339                         _audio_buffers.move (N, 0, _audio_buffers.frames() - N);
340                 }
341                 _audio_buffers.set_frames (_audio_buffers.frames() - N);
342         }
343
344         /* Now accumulate the new audio into our buffers */
345         _audio_buffers.ensure_size (_audio_buffers.frames() + audio->frames());
346         _audio_buffers.accumulate_frames (audio.get(), 0, 0, audio->frames ());
347         _audio_buffers.set_frames (_audio_buffers.frames() + audio->frames());
348 }
349
350 void
351 Player::flush ()
352 {
353         if (_audio_buffers.frames() > 0) {
354                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), _audio_buffers.frames()));
355                 emit->copy_from (&_audio_buffers, _audio_buffers.frames(), 0, 0);
356                 Audio (emit, _audio_position);
357                 _audio_position += _film->audio_frames_to_time (_audio_buffers.frames ());
358                 _audio_buffers.set_frames (0);
359         }
360
361         while (_video_position < _audio_position) {
362                 emit_black ();
363         }
364
365         while (_audio_position < _video_position) {
366                 emit_silence (_film->time_to_audio_frames (_video_position - _audio_position));
367         }
368         
369 }
370
371 /** Seek so that the next pass() will yield (approximately) the requested frame.
372  *  Pass accurate = true to try harder to get close to the request.
373  *  @return true on error
374  */
375 void
376 Player::seek (Time t, bool accurate)
377 {
378         if (!_have_valid_pieces) {
379                 setup_pieces ();
380                 _have_valid_pieces = true;
381         }
382
383         if (_pieces.empty ()) {
384                 return;
385         }
386
387         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
388                 shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> ((*i)->content);
389                 if (!vc) {
390                         continue;
391                 }
392                 
393                 Time s = t - vc->start ();
394                 s = max (static_cast<Time> (0), s);
395                 s = min (vc->length(), s);
396
397                 (*i)->video_position = (*i)->audio_position = vc->start() + s;
398
399                 FrameRateConversion frc (vc->video_frame_rate(), _film->video_frame_rate());
400                 /* Here we are converting from time (in the DCP) to a frame number in the content.
401                    Hence we need to use the DCP's frame rate and the double/skip correction, not
402                    the source's rate.
403                 */
404                 VideoContent::Frame f = s * _film->video_frame_rate() / (frc.factor() * TIME_HZ);
405                 dynamic_pointer_cast<VideoDecoder>((*i)->decoder)->seek (f, accurate);
406         }
407
408         _video_position = _audio_position = t;
409         
410         /* XXX: don't seek audio because we don't need to... */
411 }
412
413 void
414 Player::setup_pieces ()
415 {
416         list<shared_ptr<Piece> > old_pieces = _pieces;
417
418         _pieces.clear ();
419
420         ContentList content = _playlist->content ();
421         sort (content.begin(), content.end(), ContentSorter ());
422
423         for (ContentList::iterator i = content.begin(); i != content.end(); ++i) {
424
425                 shared_ptr<Piece> piece (new Piece (*i));
426
427                 /* XXX: into content? */
428
429                 shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
430                 if (fc) {
431                         shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio));
432                         
433                         fd->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3, _4));
434                         fd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2));
435                         fd->Subtitle.connect (bind (&Player::process_subtitle, this, piece, _1, _2, _3, _4));
436
437                         piece->decoder = fd;
438                 }
439                 
440                 shared_ptr<const StillImageContent> ic = dynamic_pointer_cast<const StillImageContent> (*i);
441                 if (ic) {
442                         shared_ptr<StillImageDecoder> id;
443                         
444                         /* See if we can re-use an old StillImageDecoder */
445                         for (list<shared_ptr<Piece> >::const_iterator j = old_pieces.begin(); j != old_pieces.end(); ++j) {
446                                 shared_ptr<StillImageDecoder> imd = dynamic_pointer_cast<StillImageDecoder> ((*j)->decoder);
447                                 if (imd && imd->content() == ic) {
448                                         id = imd;
449                                 }
450                         }
451
452                         if (!id) {
453                                 id.reset (new StillImageDecoder (_film, ic));
454                                 id->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3, _4));
455                         }
456
457                         piece->decoder = id;
458                 }
459
460                 shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
461                 if (sc) {
462                         shared_ptr<AudioDecoder> sd (new SndfileDecoder (_film, sc));
463                         sd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2));
464
465                         piece->decoder = sd;
466                 }
467
468                 _pieces.push_back (piece);
469         }
470
471 #ifdef DEBUG_PLAYER
472         cout << "=== Player setup:\n";
473         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
474                 cout << *(i->get()) << "\n";
475         }
476 #endif  
477 }
478
479 void
480 Player::content_changed (weak_ptr<Content> w, int property, bool frequent)
481 {
482         shared_ptr<Content> c = w.lock ();
483         if (!c) {
484                 return;
485         }
486
487         if (
488                 property == ContentProperty::START || property == ContentProperty::LENGTH ||
489                 property == VideoContentProperty::VIDEO_CROP || property == VideoContentProperty::VIDEO_RATIO
490                 ) {
491                 
492                 _have_valid_pieces = false;
493                 Changed (frequent);
494
495         } else if (property == SubtitleContentProperty::SUBTITLE_OFFSET || property == SubtitleContentProperty::SUBTITLE_SCALE) {
496                 update_subtitle ();
497                 Changed (frequent);
498         } else if (property == VideoContentProperty::VIDEO_FRAME_TYPE) {
499                 Changed (frequent);
500         }
501 }
502
503 void
504 Player::playlist_changed ()
505 {
506         _have_valid_pieces = false;
507         Changed (false);
508 }
509
510 void
511 Player::set_video_container_size (libdcp::Size s)
512 {
513         _video_container_size = s;
514         _black_frame.reset (new Image (PIX_FMT_RGB24, _video_container_size, true));
515         _black_frame->make_black ();
516 }
517
518 shared_ptr<Resampler>
519 Player::resampler (shared_ptr<AudioContent> c, bool create)
520 {
521         map<shared_ptr<AudioContent>, shared_ptr<Resampler> >::iterator i = _resamplers.find (c);
522         if (i != _resamplers.end ()) {
523                 return i->second;
524         }
525
526         if (!create) {
527                 return shared_ptr<Resampler> ();
528         }
529         
530         shared_ptr<Resampler> r (new Resampler (c->content_audio_frame_rate(), c->output_audio_frame_rate(), c->audio_channels()));
531         _resamplers[c] = r;
532         return r;
533 }
534
535 void
536 Player::emit_black ()
537 {
538 #ifdef DCPOMATIC_DEBUG
539         _last_video.reset ();
540 #endif
541         
542         /* XXX: use same here */
543         Video (_black_frame, EYES_BOTH, false, _video_position);
544         _video_position += _film->video_frames_to_time (1);
545 }
546
547 void
548 Player::emit_silence (OutputAudioFrame most)
549 {
550         OutputAudioFrame N = min (most, _film->audio_frame_rate() / 2);
551         shared_ptr<AudioBuffers> silence (new AudioBuffers (_film->audio_channels(), N));
552         silence->make_silent ();
553         Audio (silence, _audio_position);
554         _audio_position += _film->audio_frames_to_time (N);
555 }
556
557 void
558 Player::film_changed (Film::Property p)
559 {
560         /* Here we should notice Film properties that affect our output, and
561            alert listeners that our output now would be different to how it was
562            last time we were run.
563         */
564
565         if (p == Film::SCALER || p == Film::WITH_SUBTITLES || p == Film::CONTAINER) {
566                 Changed (false);
567         }
568 }
569
570 void
571 Player::process_subtitle (weak_ptr<Piece> weak_piece, shared_ptr<Image> image, dcpomatic::Rect<double> rect, Time from, Time to)
572 {
573         _in_subtitle.piece = weak_piece;
574         _in_subtitle.image = image;
575         _in_subtitle.rect = rect;
576         _in_subtitle.from = from;
577         _in_subtitle.to = to;
578
579         update_subtitle ();
580 }
581
582 void
583 Player::update_subtitle ()
584 {
585         shared_ptr<Piece> piece = _in_subtitle.piece.lock ();
586         if (!piece) {
587                 return;
588         }
589
590         if (!_in_subtitle.image) {
591                 _out_subtitle.image.reset ();
592                 return;
593         }
594
595         shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (piece->content);
596         assert (sc);
597
598         dcpomatic::Rect<double> in_rect = _in_subtitle.rect;
599         libdcp::Size scaled_size;
600
601         in_rect.y += sc->subtitle_offset ();
602
603         /* We will scale the subtitle up to fit _video_container_size, and also by the additional subtitle_scale */
604         scaled_size.width = in_rect.width * _video_container_size.width * sc->subtitle_scale ();
605         scaled_size.height = in_rect.height * _video_container_size.height * sc->subtitle_scale ();
606
607         /* Then we need a corrective translation, consisting of two parts:
608          *
609          * 1.  that which is the result of the scaling of the subtitle by _video_container_size; this will be
610          *     rect.x * _video_container_size.width and rect.y * _video_container_size.height.
611          *
612          * 2.  that to shift the origin of the scale by subtitle_scale to the centre of the subtitle; this will be
613          *     (width_before_subtitle_scale * (1 - subtitle_scale) / 2) and
614          *     (height_before_subtitle_scale * (1 - subtitle_scale) / 2).
615          *
616          * Combining these two translations gives these expressions.
617          */
618         
619         _out_subtitle.position.x = rint (_video_container_size.width * (in_rect.x + (in_rect.width * (1 - sc->subtitle_scale ()) / 2)));
620         _out_subtitle.position.y = rint (_video_container_size.height * (in_rect.y + (in_rect.height * (1 - sc->subtitle_scale ()) / 2)));
621         
622         _out_subtitle.image = _in_subtitle.image->scale (libdcp::Size (scaled_size.width, scaled_size.height), Scaler::from_id ("bicubic"), true);
623         _out_subtitle.from = _in_subtitle.from + piece->content->start ();
624         _out_subtitle.to = _in_subtitle.to + piece->content->start ();
625 }