Supporters update.
[dcpomatic.git] / src / lib / ffmpeg_decoder.cc
1 /*
2     Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic 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.
10
11     DCP-o-matic 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.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21
22 /** @file  src/ffmpeg_decoder.cc
23  *  @brief A decoder using FFmpeg to decode content.
24  */
25
26
27 #include "audio_buffers.h"
28 #include "audio_content.h"
29 #include "audio_decoder.h"
30 #include "compose.hpp"
31 #include "dcpomatic_log.h"
32 #include "exceptions.h"
33 #include "ffmpeg_audio_stream.h"
34 #include "ffmpeg_content.h"
35 #include "ffmpeg_decoder.h"
36 #include "ffmpeg_subtitle_stream.h"
37 #include "film.h"
38 #include "filter.h"
39 #include "frame_interval_checker.h"
40 #include "image.h"
41 #include "log.h"
42 #include "raw_image_proxy.h"
43 #include "text_content.h"
44 #include "text_decoder.h"
45 #include "util.h"
46 #include "video_decoder.h"
47 #include "video_filter_graph.h"
48 #include <dcp/subtitle_string.h>
49 #include <sub/ssa_reader.h>
50 #include <sub/subtitle.h>
51 #include <sub/collect.h>
52 extern "C" {
53 #include <libavcodec/avcodec.h>
54 #include <libavformat/avformat.h>
55 }
56 #include <boost/algorithm/string.hpp>
57 #include <iomanip>
58 #include <iostream>
59 #include <vector>
60 #include <stdint.h>
61
62 #include "i18n.h"
63
64
65 using std::cout;
66 using std::dynamic_pointer_cast;
67 using std::make_shared;
68 using std::min;
69 using std::shared_ptr;
70 using std::string;
71 using std::vector;
72 using boost::optional;
73 using dcp::Size;
74 using namespace dcpomatic;
75
76
77 FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> film, shared_ptr<const FFmpegContent> c, bool fast)
78         : FFmpeg (c)
79         , Decoder (film)
80         , _filter_graphs(c->filters(), dcp::Fraction(lrint(_ffmpeg_content->video_frame_rate().get_value_or(24) * 1000), 1000))
81 {
82         if (c->video && c->video->use()) {
83                 video = make_shared<VideoDecoder>(this, c);
84                 _pts_offset = pts_offset (c->ffmpeg_audio_streams(), c->first_video(), c->active_video_frame_rate(film));
85                 /* It doesn't matter what size or pixel format this is, it just needs to be black */
86                 _black_image = make_shared<Image>(AV_PIX_FMT_RGB24, dcp::Size (128, 128), Image::Alignment::PADDED);
87                 _black_image->make_black ();
88         } else {
89                 _pts_offset = {};
90         }
91
92         if (c->audio) {
93                 audio = make_shared<AudioDecoder>(this, c->audio, fast);
94         }
95
96         if (c->only_text()) {
97                 text.push_back (make_shared<TextDecoder>(this, c->only_text()));
98                 /* XXX: we should be calling maybe_set_position() on this TextDecoder, but we can't easily find
99                  * the time of the first subtitle at this point.
100                  */
101         }
102
103         for (auto i: c->ffmpeg_audio_streams()) {
104                 _next_time[i] = boost::optional<dcpomatic::ContentTime>();
105         }
106 }
107
108
109 FFmpegDecoder::FlushResult
110 FFmpegDecoder::flush ()
111 {
112         LOG_DEBUG_PLAYER("Flush FFmpeg decoder: current state %1", static_cast<int>(_flush_state));
113
114         switch (_flush_state) {
115         case FlushState::CODECS:
116                 if (flush_codecs() == FlushResult::DONE) {
117                         LOG_DEBUG_PLAYER_NC("Finished flushing codecs");
118                         _flush_state = FlushState::AUDIO_DECODER;
119                 }
120                 break;
121         case FlushState::AUDIO_DECODER:
122                 if (audio) {
123                         audio->flush();
124                 }
125                 LOG_DEBUG_PLAYER_NC("Finished flushing audio decoder");
126                 _flush_state = FlushState::FILL;
127                 break;
128         case FlushState::FILL:
129                 if (flush_fill() == FlushResult::DONE) {
130                         LOG_DEBUG_PLAYER_NC("Finished flushing fills");
131                         return FlushResult::DONE;
132                 }
133                 break;
134         }
135
136         return FlushResult::AGAIN;
137 }
138
139
140 /** @return true if we have finished flushing the codecs */
141 FFmpegDecoder::FlushResult
142 FFmpegDecoder::flush_codecs()
143 {
144         bool did_something = false;
145         if (video) {
146                 if (decode_and_process_video_packet(nullptr)) {
147                         did_something = true;
148                 }
149         }
150
151         for (auto i: ffmpeg_content()->ffmpeg_audio_streams()) {
152                 auto context = _codec_context[i->index(_format_context)];
153                 int r = avcodec_send_packet (context, nullptr);
154                 if (r < 0 && r != AVERROR_EOF) {
155                         /* EOF can happen if we've already sent a flush packet */
156                         throw DecodeError (N_("avcodec_send_packet"), N_("FFmpegDecoder::flush"), r);
157                 }
158                 r = avcodec_receive_frame (context, audio_frame(i));
159                 if (r >= 0) {
160                         process_audio_frame (i);
161                         did_something = true;
162                 }
163         }
164
165         return did_something ? FlushResult::AGAIN : FlushResult::DONE;
166 }
167
168
169 FFmpegDecoder::FlushResult
170 FFmpegDecoder::flush_fill()
171 {
172         /* Make sure all streams are the same length and round up to the next video frame */
173
174         bool did_something = false;
175
176         auto const frc = film()->active_frame_rate_change(_ffmpeg_content->position());
177         ContentTime full_length (_ffmpeg_content->full_length(film()), frc);
178         full_length = full_length.ceil (frc.source);
179         if (video && !video->ignore()) {
180                 double const vfr = _ffmpeg_content->video_frame_rate().get();
181                 auto const f = full_length.frames_round (vfr);
182                 auto const v = video->position(film()).get_value_or(ContentTime()).frames_round(vfr) + 1;
183                 if (v < f) {
184                         video->emit(film(), make_shared<const RawImageProxy>(_black_image), v);
185                         did_something = true;
186                 }
187         }
188
189         if (audio && !audio->ignore()) {
190                 for (auto i: _ffmpeg_content->ffmpeg_audio_streams ()) {
191                         auto const a = audio->stream_position(film(), i);
192                         /* Unfortunately if a is 0 that really means that we don't know the stream position since
193                            there has been no data on it since the last seek.  In this case we'll just do nothing
194                            here.  I'm not sure if that's the right idea.
195                         */
196                         if (a > ContentTime() && a < full_length) {
197                                 LOG_DEBUG_PLAYER("Flush inserts silence at %1", to_string(a));
198                                 auto to_do = min (full_length - a, ContentTime::from_seconds (0.1));
199                                 auto silence = make_shared<AudioBuffers>(i->channels(), to_do.frames_ceil (i->frame_rate()));
200                                 silence->make_silent ();
201                                 audio->emit (film(), i, silence, a, true);
202                                 did_something = true;
203                         }
204                 }
205         }
206
207         return did_something ? FlushResult::AGAIN : FlushResult::DONE;
208 }
209
210
211 bool
212 FFmpegDecoder::pass ()
213 {
214         auto packet = av_packet_alloc();
215         DCPOMATIC_ASSERT (packet);
216
217         int r = av_read_frame (_format_context, packet);
218
219         /* AVERROR_INVALIDDATA can apparently be returned sometimes even when av_read_frame
220            has pretty-much succeeded (and hence generated data which should be processed).
221            Hence it makes sense to continue here in that case.
222         */
223         if (r < 0 && r != AVERROR_INVALIDDATA) {
224                 LOG_DEBUG_PLAYER("FFpmegDecoder::pass flushes because av_read_frame returned %1", r);
225                 if (r != AVERROR_EOF) {
226                         /* Maybe we should fail here, but for now we'll just finish off instead */
227                         char buf[256];
228                         av_strerror (r, buf, sizeof(buf));
229                         LOG_ERROR (N_("error on av_read_frame (%1) (%2)"), &buf[0], r);
230                 }
231
232                 av_packet_free (&packet);
233                 return flush() == FlushResult::DONE;
234         }
235
236         int const si = packet->stream_index;
237         auto fc = _ffmpeg_content;
238
239         if (_video_stream && si == _video_stream.get() && video && !video->ignore()) {
240                 decode_and_process_video_packet (packet);
241         } else if (fc->subtitle_stream() && fc->subtitle_stream()->uses_index(_format_context, si) && !only_text()->ignore()) {
242                 decode_and_process_subtitle_packet (packet);
243         } else {
244                 decode_and_process_audio_packet (packet);
245         }
246
247         av_packet_free (&packet);
248         return false;
249 }
250
251
252 /** @param data pointer to array of pointers to buffers.
253  *  Only the first buffer will be used for non-planar data, otherwise there will be one per channel.
254  */
255 static
256 shared_ptr<AudioBuffers>
257 deinterleave_audio(AVFrame* frame)
258 {
259         auto format = static_cast<AVSampleFormat>(frame->format);
260
261         /* XXX: can't we use swr_convert() to do the format conversion? */
262
263         int const channels = frame->channels;
264         int const frames = frame->nb_samples;
265         int const total_samples = frames * channels;
266         auto audio = make_shared<AudioBuffers>(channels, frames);
267         auto data = audio->data();
268
269         if (frames == 0) {
270                 return audio;
271         }
272
273         switch (format) {
274         case AV_SAMPLE_FMT_U8:
275         {
276                 auto p = reinterpret_cast<uint8_t *> (frame->data[0]);
277                 int sample = 0;
278                 int channel = 0;
279                 for (int i = 0; i < total_samples; ++i) {
280                         data[channel][sample] = float(*p++) / (1 << 23);
281
282                         ++channel;
283                         if (channel == channels) {
284                                 channel = 0;
285                                 ++sample;
286                         }
287                 }
288         }
289         break;
290
291         case AV_SAMPLE_FMT_S16:
292         {
293                 auto p = reinterpret_cast<int16_t *> (frame->data[0]);
294                 int sample = 0;
295                 int channel = 0;
296                 for (int i = 0; i < total_samples; ++i) {
297                         data[channel][sample] = float(*p++) / (1 << 15);
298
299                         ++channel;
300                         if (channel == channels) {
301                                 channel = 0;
302                                 ++sample;
303                         }
304                 }
305         }
306         break;
307
308         case AV_SAMPLE_FMT_S16P:
309         {
310                 auto p = reinterpret_cast<int16_t **> (frame->data);
311                 for (int i = 0; i < channels; ++i) {
312                         for (int j = 0; j < frames; ++j) {
313                                 data[i][j] = static_cast<float>(p[i][j]) / (1 << 15);
314                         }
315                 }
316         }
317         break;
318
319         case AV_SAMPLE_FMT_S32:
320         {
321                 auto p = reinterpret_cast<int32_t *> (frame->data[0]);
322                 int sample = 0;
323                 int channel = 0;
324                 for (int i = 0; i < total_samples; ++i) {
325                         data[channel][sample] = static_cast<float>(*p++) / 2147483648;
326
327                         ++channel;
328                         if (channel == channels) {
329                                 channel = 0;
330                                 ++sample;
331                         }
332                 }
333         }
334         break;
335
336         case AV_SAMPLE_FMT_S32P:
337         {
338                 auto p = reinterpret_cast<int32_t **> (frame->data);
339                 for (int i = 0; i < channels; ++i) {
340                         for (int j = 0; j < frames; ++j) {
341                                 data[i][j] = static_cast<float>(p[i][j]) / 2147483648;
342                         }
343                 }
344         }
345         break;
346
347         case AV_SAMPLE_FMT_FLT:
348         {
349                 auto p = reinterpret_cast<float*> (frame->data[0]);
350                 int sample = 0;
351                 int channel = 0;
352                 for (int i = 0; i < total_samples; ++i) {
353                         data[channel][sample] = *p++;
354
355                         ++channel;
356                         if (channel == channels) {
357                                 channel = 0;
358                                 ++sample;
359                         }
360                 }
361         }
362         break;
363
364         case AV_SAMPLE_FMT_FLTP:
365         {
366                 auto p = reinterpret_cast<float**> (frame->data);
367                 for (int i = 0; i < channels; ++i) {
368                         memcpy (data[i], p[i], frames * sizeof(float));
369                 }
370         }
371         break;
372
373         default:
374                 throw DecodeError (String::compose(_("Unrecognised audio sample format (%1)"), static_cast<int>(format)));
375         }
376
377         return audio;
378 }
379
380
381 AVSampleFormat
382 FFmpegDecoder::audio_sample_format (shared_ptr<FFmpegAudioStream> stream) const
383 {
384         return static_cast<AVSampleFormat>(stream->stream(_format_context)->codecpar->format);
385 }
386
387
388 int
389 FFmpegDecoder::bytes_per_audio_sample (shared_ptr<FFmpegAudioStream> stream) const
390 {
391         return av_get_bytes_per_sample (audio_sample_format (stream));
392 }
393
394
395 void
396 FFmpegDecoder::seek (ContentTime time, bool accurate)
397 {
398         Decoder::seek (time, accurate);
399
400         /* If we are doing an `accurate' seek, we need to use pre-roll, as
401            we don't really know what the seek will give us.
402         */
403
404         auto pre_roll = accurate ? ContentTime::from_seconds (2) : ContentTime (0);
405         time -= pre_roll;
406
407         /* XXX: it seems debatable whether PTS should be used here...
408            http://www.mjbshaw.com/2012/04/seeking-in-ffmpeg-know-your-timestamp.html
409         */
410
411         optional<int> stream;
412
413         if (_video_stream) {
414                 stream = _video_stream;
415         } else {
416                 DCPOMATIC_ASSERT (_ffmpeg_content->audio);
417                 auto s = dynamic_pointer_cast<FFmpegAudioStream>(_ffmpeg_content->audio->stream());
418                 if (s) {
419                         stream = s->index (_format_context);
420                 }
421         }
422
423         DCPOMATIC_ASSERT (stream);
424
425         auto u = time - _pts_offset;
426         if (u < ContentTime ()) {
427                 u = ContentTime ();
428         }
429         av_seek_frame (
430                 _format_context,
431                 stream.get(),
432                 u.seconds() / av_q2d (_format_context->streams[stream.get()]->time_base),
433                 AVSEEK_FLAG_BACKWARD
434                 );
435
436         /* Force re-creation of filter graphs to reset them and hence to make sure
437            they don't have any pre-seek frames knocking about.
438         */
439         _filter_graphs.clear();
440
441         if (video_codec_context ()) {
442                 avcodec_flush_buffers (video_codec_context());
443         }
444
445         for (auto i: ffmpeg_content()->ffmpeg_audio_streams()) {
446                 avcodec_flush_buffers (_codec_context[i->index(_format_context)]);
447         }
448
449         if (subtitle_codec_context ()) {
450                 avcodec_flush_buffers (subtitle_codec_context ());
451         }
452
453         _have_current_subtitle = false;
454
455         for (auto& i: _next_time) {
456                 i.second = boost::optional<dcpomatic::ContentTime>();
457         }
458 }
459
460
461 shared_ptr<FFmpegAudioStream>
462 FFmpegDecoder::audio_stream_from_index (int index) const
463 {
464         /* XXX: inefficient */
465         auto streams = ffmpeg_content()->ffmpeg_audio_streams();
466         auto stream = streams.begin();
467         while (stream != streams.end() && !(*stream)->uses_index(_format_context, index)) {
468                 ++stream;
469         }
470
471         if (stream == streams.end ()) {
472                 return {};
473         }
474
475         return *stream;
476 }
477
478
479 void
480 FFmpegDecoder::process_audio_frame (shared_ptr<FFmpegAudioStream> stream)
481 {
482         auto frame = audio_frame (stream);
483         auto data = deinterleave_audio(frame);
484
485         auto const time_base = stream->stream(_format_context)->time_base;
486
487         ContentTime ct;
488         if (frame->pts == AV_NOPTS_VALUE) {
489                 /* In some streams we see not every frame coming through with a timestamp; for those
490                    that have AV_NOPTS_VALUE we need to work out the timestamp ourselves.  This is
491                    particularly noticeable with TrueHD streams (see #1111).
492                    */
493                 if (_next_time[stream]) {
494                         ct = *_next_time[stream];
495                 }
496         } else {
497                 ct = ContentTime::from_seconds (
498                         frame->best_effort_timestamp *
499                         av_q2d(time_base))
500                         + _pts_offset;
501                 LOG_DEBUG_PLAYER(
502                         "Process audio with timestamp %1 (BET %2, timebase %3/%4, (PTS offset %5)",
503                         to_string(ct),
504                         frame->best_effort_timestamp,
505                         time_base.num,
506                         time_base.den,
507                         to_string(_pts_offset)
508                         );
509         }
510
511         _next_time[stream] = ct + ContentTime::from_frames(data->frames(), stream->frame_rate());
512
513         if (ct < ContentTime()) {
514                 /* Discard audio data that comes before time 0 */
515                 auto const remove = min (int64_t(data->frames()), (-ct).frames_ceil(double(stream->frame_rate())));
516                 data->move (data->frames() - remove, remove, 0);
517                 data->set_frames (data->frames() - remove);
518                 ct += ContentTime::from_frames (remove, stream->frame_rate());
519         }
520
521         if (ct < ContentTime()) {
522                 LOG_WARNING (
523                         "Crazy timestamp %1 for %2 samples in stream %3 (ts=%4 tb=%5, off=%6)",
524                         to_string(ct),
525                         data->frames(),
526                         stream->id(),
527                         frame->best_effort_timestamp,
528                         av_q2d(time_base),
529                         to_string(_pts_offset)
530                         );
531         }
532
533         /* Give this data provided there is some, and its time is sane */
534         if (ct >= ContentTime() && data->frames() > 0) {
535                 audio->emit (film(), stream, data, ct);
536         }
537 }
538
539
540 void
541 FFmpegDecoder::decode_and_process_audio_packet (AVPacket* packet)
542 {
543         auto stream = audio_stream_from_index (packet->stream_index);
544         if (!stream) {
545                 return;
546         }
547
548         auto context = _codec_context[stream->index(_format_context)];
549         auto frame = audio_frame (stream);
550
551         LOG_DEBUG_PLAYER("Send audio packet on stream %1", stream->index(_format_context));
552         int r = avcodec_send_packet (context, packet);
553         if (r < 0) {
554                 LOG_WARNING("avcodec_send_packet returned %1 for an audio packet", r);
555         }
556         while (r >= 0) {
557                 r = avcodec_receive_frame (context, frame);
558                 if (r == AVERROR(EAGAIN)) {
559                         /* More input is required */
560                         LOG_DEBUG_PLAYER_NC("EAGAIN after trying to receive audio frame");
561                         return;
562                 }
563
564                 /* We choose to be relaxed here about other errors; it seems that there may be valid
565                  * data to decode even if an error occurred.  #352 may be related (though this was
566                  * when we were using an old version of the FFmpeg API).
567                  */
568                 process_audio_frame (stream);
569         }
570 }
571
572
573 bool
574 FFmpegDecoder::decode_and_process_video_packet (AVPacket* packet)
575 {
576         DCPOMATIC_ASSERT (_video_stream);
577
578         auto context = video_codec_context();
579
580         bool pending = false;
581         do {
582                 int r = avcodec_send_packet (context, packet);
583                 if (r < 0) {
584                         LOG_WARNING("avcodec_send_packet returned %1 for a video packet", r);
585                 }
586
587                 /* EAGAIN means we should call avcodec_receive_frame and then re-send the same packet */
588                 pending = r == AVERROR(EAGAIN);
589
590                 while (true) {
591                         r = avcodec_receive_frame (context, _video_frame);
592                         if (r == AVERROR(EAGAIN) || r == AVERROR_EOF || (r < 0 && !packet)) {
593                                 /* More input is required, no more frames are coming, or we are flushing and there was
594                                  * some error which we just want to ignore.
595                                  */
596                                 return false;
597                         } else if (r < 0) {
598                                 throw DecodeError (N_("avcodec_receive_frame"), N_("FFmpeg::decode_and_process_video_packet"), r);
599                         }
600
601                         process_video_frame ();
602                 }
603         } while (pending);
604
605         return true;
606 }
607
608
609 void
610 FFmpegDecoder::process_video_frame ()
611 {
612         auto graph = _filter_graphs.get(dcp::Size(_video_frame->width, _video_frame->height), static_cast<AVPixelFormat>(_video_frame->format));
613         auto images = graph->process (_video_frame);
614
615         for (auto const& i: images) {
616
617                 auto image = i.first;
618
619                 if (i.second != AV_NOPTS_VALUE) {
620                         double const pts = i.second * av_q2d(_format_context->streams[_video_stream.get()]->time_base) + _pts_offset.seconds();
621
622                         video->emit (
623                                 film(),
624                                 make_shared<RawImageProxy>(image),
625                                 llrint(pts * _ffmpeg_content->active_video_frame_rate(film()))
626                                 );
627                 } else {
628                         LOG_WARNING_NC ("Dropping frame without PTS");
629                 }
630         }
631 }
632
633
634 void
635 FFmpegDecoder::decode_and_process_subtitle_packet (AVPacket* packet)
636 {
637         auto context = subtitle_codec_context();
638         if (!context) {
639                 return;
640         }
641
642         int got_subtitle;
643         AVSubtitle sub;
644         if (avcodec_decode_subtitle2(context, &sub, &got_subtitle, packet) < 0 || !got_subtitle) {
645                 return;
646         }
647
648         auto sub_period = subtitle_period (packet, ffmpeg_content()->subtitle_stream()->stream(_format_context), sub);
649
650         /* Stop any current subtitle, either at the time it was supposed to stop, or now if now is sooner */
651         if (_have_current_subtitle) {
652                 if (_current_subtitle_to) {
653                         only_text()->emit_stop (min(*_current_subtitle_to, sub_period.from + _pts_offset));
654                 } else {
655                         only_text()->emit_stop (sub_period.from + _pts_offset);
656                 }
657                 _have_current_subtitle = false;
658         }
659
660         if (sub.num_rects <= 0) {
661                 /* Nothing new in this subtitle */
662                 avsubtitle_free (&sub);
663                 return;
664         }
665
666         /* Subtitle PTS (within the source, not taking into account any of the
667            source that we may have chopped off for the DCP).
668         */
669         ContentTime from;
670         from = sub_period.from + _pts_offset;
671         _have_current_subtitle = true;
672         if (sub_period.to) {
673                 _current_subtitle_to = *sub_period.to + _pts_offset;
674         } else {
675                 _current_subtitle_to = optional<ContentTime>();
676         }
677
678         ContentBitmapText bitmap_text(from);
679         for (unsigned int i = 0; i < sub.num_rects; ++i) {
680                 auto const rect = sub.rects[i];
681
682                 switch (rect->type) {
683                 case SUBTITLE_NONE:
684                         break;
685                 case SUBTITLE_BITMAP:
686                         bitmap_text.subs.push_back(process_bitmap_subtitle(rect));
687                         break;
688                 case SUBTITLE_TEXT:
689                         cout << "XXX: SUBTITLE_TEXT " << rect->text << "\n";
690                         break;
691                 case SUBTITLE_ASS:
692                         process_ass_subtitle (rect->ass, from);
693                         break;
694                 }
695         }
696
697         if (!bitmap_text.subs.empty()) {
698                 only_text()->emit_bitmap_start(bitmap_text);
699         }
700
701         if (_current_subtitle_to) {
702                 only_text()->emit_stop (*_current_subtitle_to);
703         }
704
705         avsubtitle_free (&sub);
706 }
707
708
709 BitmapText
710 FFmpegDecoder::process_bitmap_subtitle (AVSubtitleRect const * rect)
711 {
712         /* Note BGRA is expressed little-endian, so the first byte in the word is B, second
713            G, third R, fourth A.
714         */
715         auto image = make_shared<Image>(AV_PIX_FMT_BGRA, dcp::Size (rect->w, rect->h), Image::Alignment::PADDED);
716
717 #ifdef DCPOMATIC_HAVE_AVSUBTITLERECT_PICT
718         /* Start of the first line in the subtitle */
719         auto sub_p = rect->pict.data[0];
720         /* sub_p looks up into a BGRA palette which is at rect->pict.data[1];
721            (i.e. first byte B, second G, third R, fourth A)
722         */
723         auto const* palette = rect->pict.data[1];
724 #else
725         /* Start of the first line in the subtitle */
726         auto sub_p = rect->data[0];
727         /* sub_p looks up into a BGRA palette which is at rect->data[1].
728            (first byte B, second G, third R, fourth A)
729         */
730         auto const* palette = rect->data[1];
731 #endif
732         /* And the stream has a map of those palette colours to colours
733            chosen by the user; created a `mapped' palette from those settings.
734         */
735         auto colour_map = ffmpeg_content()->subtitle_stream()->colours();
736         vector<RGBA> mapped_palette (rect->nb_colors);
737         for (int i = 0; i < rect->nb_colors; ++i) {
738                 RGBA c (palette[2], palette[1], palette[0], palette[3]);
739                 auto j = colour_map.find (c);
740                 if (j != colour_map.end ()) {
741                         mapped_palette[i] = j->second;
742                 } else {
743                         /* This colour was not found in the FFmpegSubtitleStream's colour map; probably because
744                            it is from a project that was created before this stuff was added.  Just use the
745                            colour straight from the original palette.
746                         */
747                         mapped_palette[i] = c;
748                 }
749                 palette += 4;
750         }
751
752         /* Start of the output data */
753         auto out_p = image->data()[0];
754
755         for (int y = 0; y < rect->h; ++y) {
756                 auto sub_line_p = sub_p;
757                 auto out_line_p = out_p;
758                 for (int x = 0; x < rect->w; ++x) {
759                         auto const p = mapped_palette[*sub_line_p++];
760                         *out_line_p++ = p.b;
761                         *out_line_p++ = p.g;
762                         *out_line_p++ = p.r;
763                         *out_line_p++ = p.a;
764                 }
765 #ifdef DCPOMATIC_HAVE_AVSUBTITLERECT_PICT
766                 sub_p += rect->pict.linesize[0];
767 #else
768                 sub_p += rect->linesize[0];
769 #endif
770                 out_p += image->stride()[0];
771         }
772
773         int target_width = subtitle_codec_context()->width;
774         if (target_width == 0 && video_codec_context()) {
775                 /* subtitle_codec_context()->width == 0 has been seen in the wild but I don't
776                    know if it's supposed to mean something from FFmpeg's point of view.
777                 */
778                 target_width = video_codec_context()->width;
779         }
780         int target_height = subtitle_codec_context()->height;
781         if (target_height == 0 && video_codec_context()) {
782                 target_height = video_codec_context()->height;
783         }
784
785         int x_offset = 0;
786         int y_offset = 0;
787         if (_ffmpeg_content->video && _ffmpeg_content->video->use()) {
788                 auto const crop = _ffmpeg_content->video->actual_crop();
789                 target_width -= crop.left + crop.right;
790                 target_height -= crop.top + crop.bottom;
791                 x_offset = -crop.left;
792                 y_offset = -crop.top;
793         }
794
795         DCPOMATIC_ASSERT(target_width > 0);
796         DCPOMATIC_ASSERT(target_height > 0);
797
798         dcpomatic::Rect<double> const scaled_rect (
799                 static_cast<double>(rect->x + x_offset) / target_width,
800                 static_cast<double>(rect->y + y_offset) / target_height,
801                 static_cast<double>(rect->w) / target_width,
802                 static_cast<double>(rect->h) / target_height
803                 );
804
805         return { image, scaled_rect };
806 }
807
808
809 void
810 FFmpegDecoder::process_ass_subtitle (string ass, ContentTime from)
811 {
812         /* We have no styles and no Format: line, so I'm assuming that FFmpeg
813            produces a single format of Dialogue: lines...
814         */
815
816         int commas = 0;
817         string text;
818         for (size_t i = 0; i < ass.length(); ++i) {
819                 if (commas < 9 && ass[i] == ',') {
820                         ++commas;
821                 } else if (commas == 9) {
822                         text += ass[i];
823                 }
824         }
825
826         if (text.empty ()) {
827                 return;
828         }
829
830         sub::RawSubtitle base;
831         auto video_size = _ffmpeg_content->video->size();
832         DCPOMATIC_ASSERT(video_size);
833
834         auto raw = sub::SSAReader::parse_line (
835                 base,
836                 text,
837                 video_size->width,
838                 video_size->height,
839                 sub::Colour(1, 1, 1)
840                 );
841
842         for (auto const& i: sub::collect<vector<sub::Subtitle>>(raw)) {
843                 only_text()->emit_plain_start (from, i);
844         }
845 }