Merge branch '1.0' of ssh://carlh.dnsalias.org/home/carl/git/dvdomatic into 1.0
[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         Time time = content->start() + (frame * TIME_HZ / _film->audio_frame_rate()) + (content->audio_delay() * TIME_HZ / 1000);
299
300         /* We must cut off anything that comes before the start of all time */
301         if (time < 0) {
302                 int const frames = - time * _film->audio_frame_rate() / TIME_HZ;
303                 if (frames >= audio->frames ()) {
304                         return;
305                 }
306
307                 shared_ptr<AudioBuffers> trimmed (new AudioBuffers (audio->channels(), audio->frames() - frames));
308                 trimmed->copy_from (audio.get(), audio->frames() - frames, frames, 0);
309
310                 audio = trimmed;
311                 time = 0;
312         }
313
314         /* The time of this audio may indicate that some of our buffered audio is not going to
315            be added to any more, so it can be emitted.
316         */
317
318         if (time > _audio_position) {
319                 /* We can emit some audio from our buffers */
320                 OutputAudioFrame const N = _film->time_to_audio_frames (time - _audio_position);
321                 if (N > _audio_buffers.frames()) {
322                         /* We need some extra silence before whatever is in the buffers */
323                         _audio_buffers.ensure_size (N);
324                         _audio_buffers.move (0, N - _audio_buffers.frames(), _audio_buffers.frames ());
325                         _audio_buffers.make_silent (0, _audio_buffers.frames());
326                         _audio_buffers.set_frames (N);
327                 }
328                 assert (N <= _audio_buffers.frames());
329                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
330                 emit->copy_from (&_audio_buffers, N, 0, 0);
331                 Audio (emit, _audio_position);
332                 _audio_position = piece->audio_position = time + _film->audio_frames_to_time (N);
333
334                 /* And remove it from our buffers */
335                 if (_audio_buffers.frames() > N) {
336                         _audio_buffers.move (N, 0, _audio_buffers.frames() - N);
337                 }
338                 _audio_buffers.set_frames (_audio_buffers.frames() - N);
339         }
340
341         /* Now accumulate the new audio into our buffers */
342         _audio_buffers.ensure_size (_audio_buffers.frames() + audio->frames());
343         _audio_buffers.accumulate_frames (audio.get(), 0, 0, audio->frames ());
344         _audio_buffers.set_frames (_audio_buffers.frames() + audio->frames());
345 }
346
347 void
348 Player::flush ()
349 {
350         if (_audio_buffers.frames() > 0) {
351                 shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), _audio_buffers.frames()));
352                 emit->copy_from (&_audio_buffers, _audio_buffers.frames(), 0, 0);
353                 Audio (emit, _audio_position);
354                 _audio_position += _film->audio_frames_to_time (_audio_buffers.frames ());
355                 _audio_buffers.set_frames (0);
356         }
357
358         while (_video_position < _audio_position) {
359                 emit_black ();
360         }
361
362         while (_audio_position < _video_position) {
363                 emit_silence (_film->time_to_audio_frames (_video_position - _audio_position));
364         }
365         
366 }
367
368 /** Seek so that the next pass() will yield (approximately) the requested frame.
369  *  Pass accurate = true to try harder to get close to the request.
370  *  @return true on error
371  */
372 void
373 Player::seek (Time t, bool accurate)
374 {
375         if (!_have_valid_pieces) {
376                 setup_pieces ();
377                 _have_valid_pieces = true;
378         }
379
380         if (_pieces.empty ()) {
381                 return;
382         }
383
384         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
385                 shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> ((*i)->content);
386                 if (!vc) {
387                         continue;
388                 }
389                 
390                 Time s = t - vc->start ();
391                 s = max (static_cast<Time> (0), s);
392                 s = min (vc->length(), s);
393
394                 (*i)->video_position = (*i)->audio_position = vc->start() + s;
395
396                 FrameRateConversion frc (vc->video_frame_rate(), _film->video_frame_rate());
397                 /* Here we are converting from time (in the DCP) to a frame number in the content.
398                    Hence we need to use the DCP's frame rate and the double/skip correction, not
399                    the source's rate.
400                 */
401                 VideoContent::Frame f = s * _film->video_frame_rate() / (frc.factor() * TIME_HZ);
402                 dynamic_pointer_cast<VideoDecoder>((*i)->decoder)->seek (f, accurate);
403         }
404
405         _video_position = _audio_position = t;
406         
407         /* XXX: don't seek audio because we don't need to... */
408 }
409
410 void
411 Player::setup_pieces ()
412 {
413         list<shared_ptr<Piece> > old_pieces = _pieces;
414
415         _pieces.clear ();
416
417         ContentList content = _playlist->content ();
418         sort (content.begin(), content.end(), ContentSorter ());
419
420         for (ContentList::iterator i = content.begin(); i != content.end(); ++i) {
421
422                 shared_ptr<Piece> piece (new Piece (*i));
423
424                 /* XXX: into content? */
425
426                 shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
427                 if (fc) {
428                         shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio));
429                         
430                         fd->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3, _4));
431                         fd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2));
432                         fd->Subtitle.connect (bind (&Player::process_subtitle, this, piece, _1, _2, _3, _4));
433
434                         piece->decoder = fd;
435                 }
436                 
437                 shared_ptr<const StillImageContent> ic = dynamic_pointer_cast<const StillImageContent> (*i);
438                 if (ic) {
439                         shared_ptr<StillImageDecoder> id;
440                         
441                         /* See if we can re-use an old StillImageDecoder */
442                         for (list<shared_ptr<Piece> >::const_iterator j = old_pieces.begin(); j != old_pieces.end(); ++j) {
443                                 shared_ptr<StillImageDecoder> imd = dynamic_pointer_cast<StillImageDecoder> ((*j)->decoder);
444                                 if (imd && imd->content() == ic) {
445                                         id = imd;
446                                 }
447                         }
448
449                         if (!id) {
450                                 id.reset (new StillImageDecoder (_film, ic));
451                                 id->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3, _4));
452                         }
453
454                         piece->decoder = id;
455                 }
456
457                 shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
458                 if (sc) {
459                         shared_ptr<AudioDecoder> sd (new SndfileDecoder (_film, sc));
460                         sd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2));
461
462                         piece->decoder = sd;
463                 }
464
465                 _pieces.push_back (piece);
466         }
467
468 #ifdef DEBUG_PLAYER
469         cout << "=== Player setup:\n";
470         for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
471                 cout << *(i->get()) << "\n";
472         }
473 #endif  
474 }
475
476 void
477 Player::content_changed (weak_ptr<Content> w, int property, bool frequent)
478 {
479         shared_ptr<Content> c = w.lock ();
480         if (!c) {
481                 return;
482         }
483
484         if (
485                 property == ContentProperty::START || property == ContentProperty::LENGTH ||
486                 property == VideoContentProperty::VIDEO_CROP || property == VideoContentProperty::VIDEO_RATIO
487                 ) {
488                 
489                 _have_valid_pieces = false;
490                 Changed (frequent);
491
492         } else if (property == SubtitleContentProperty::SUBTITLE_OFFSET || property == SubtitleContentProperty::SUBTITLE_SCALE) {
493                 update_subtitle ();
494                 Changed (frequent);
495         } else if (property == VideoContentProperty::VIDEO_FRAME_TYPE) {
496                 Changed (frequent);
497         }
498 }
499
500 void
501 Player::playlist_changed ()
502 {
503         _have_valid_pieces = false;
504         Changed (false);
505 }
506
507 void
508 Player::set_video_container_size (libdcp::Size s)
509 {
510         _video_container_size = s;
511         _black_frame.reset (new Image (PIX_FMT_RGB24, _video_container_size, true));
512         _black_frame->make_black ();
513 }
514
515 shared_ptr<Resampler>
516 Player::resampler (shared_ptr<AudioContent> c, bool create)
517 {
518         map<shared_ptr<AudioContent>, shared_ptr<Resampler> >::iterator i = _resamplers.find (c);
519         if (i != _resamplers.end ()) {
520                 return i->second;
521         }
522
523         if (!create) {
524                 return shared_ptr<Resampler> ();
525         }
526         
527         shared_ptr<Resampler> r (new Resampler (c->content_audio_frame_rate(), c->output_audio_frame_rate(), c->audio_channels()));
528         _resamplers[c] = r;
529         return r;
530 }
531
532 void
533 Player::emit_black ()
534 {
535 #ifdef DCPOMATIC_DEBUG
536         _last_video.reset ();
537 #endif
538         
539         /* XXX: use same here */
540         Video (_black_frame, EYES_BOTH, false, _video_position);
541         _video_position += _film->video_frames_to_time (1);
542 }
543
544 void
545 Player::emit_silence (OutputAudioFrame most)
546 {
547         OutputAudioFrame N = min (most, _film->audio_frame_rate() / 2);
548         shared_ptr<AudioBuffers> silence (new AudioBuffers (_film->audio_channels(), N));
549         silence->make_silent ();
550         Audio (silence, _audio_position);
551         _audio_position += _film->audio_frames_to_time (N);
552 }
553
554 void
555 Player::film_changed (Film::Property p)
556 {
557         /* Here we should notice Film properties that affect our output, and
558            alert listeners that our output now would be different to how it was
559            last time we were run.
560         */
561
562         if (p == Film::SCALER || p == Film::WITH_SUBTITLES || p == Film::CONTAINER) {
563                 Changed (false);
564         }
565 }
566
567 void
568 Player::process_subtitle (weak_ptr<Piece> weak_piece, shared_ptr<Image> image, dcpomatic::Rect<double> rect, Time from, Time to)
569 {
570         _in_subtitle.piece = weak_piece;
571         _in_subtitle.image = image;
572         _in_subtitle.rect = rect;
573         _in_subtitle.from = from;
574         _in_subtitle.to = to;
575
576         update_subtitle ();
577 }
578
579 void
580 Player::update_subtitle ()
581 {
582         shared_ptr<Piece> piece = _in_subtitle.piece.lock ();
583         if (!piece) {
584                 return;
585         }
586
587         if (!_in_subtitle.image) {
588                 _out_subtitle.image.reset ();
589                 return;
590         }
591
592         shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (piece->content);
593         assert (sc);
594
595         dcpomatic::Rect<double> in_rect = _in_subtitle.rect;
596         libdcp::Size scaled_size;
597
598         in_rect.y += sc->subtitle_offset ();
599
600         /* We will scale the subtitle up to fit _video_container_size, and also by the additional subtitle_scale */
601         scaled_size.width = in_rect.width * _video_container_size.width * sc->subtitle_scale ();
602         scaled_size.height = in_rect.height * _video_container_size.height * sc->subtitle_scale ();
603
604         /* Then we need a corrective translation, consisting of two parts:
605          *
606          * 1.  that which is the result of the scaling of the subtitle by _video_container_size; this will be
607          *     rect.x * _video_container_size.width and rect.y * _video_container_size.height.
608          *
609          * 2.  that to shift the origin of the scale by subtitle_scale to the centre of the subtitle; this will be
610          *     (width_before_subtitle_scale * (1 - subtitle_scale) / 2) and
611          *     (height_before_subtitle_scale * (1 - subtitle_scale) / 2).
612          *
613          * Combining these two translations gives these expressions.
614          */
615         
616         _out_subtitle.position.x = rint (_video_container_size.width * (in_rect.x + (in_rect.width * (1 - sc->subtitle_scale ()) / 2)));
617         _out_subtitle.position.y = rint (_video_container_size.height * (in_rect.y + (in_rect.height * (1 - sc->subtitle_scale ()) / 2)));
618         
619         _out_subtitle.image = _in_subtitle.image->scale (libdcp::Size (scaled_size.width, scaled_size.height), Scaler::from_id ("bicubic"), true);
620         _out_subtitle.from = _in_subtitle.from + piece->content->start ();
621         _out_subtitle.to = _in_subtitle.to + piece->content->start ();
622 }