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