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