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