Merge branch 'master' of ssh://git.carlh.net/home/carl/git/dcpomatic
[dcpomatic.git] / src / lib / ffmpeg_decoder.cc
index e2c200d7713224ae0c978ca5e8477f8ed4c318df..b6b6e594d9f41055843220706c960dcb6f5756fd 100644 (file)
@@ -98,6 +98,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log>
                        new SubtitleDecoder (
                                this,
                                c->subtitle,
+                               log,
                                bind (&FFmpegDecoder::image_subtitles_during, this, _1, _2),
                                bind (&FFmpegDecoder::text_subtitles_during, this, _1, _2)
                                )
@@ -422,11 +423,9 @@ FFmpegDecoder::decode_audio_packet ()
                        }
 
                        if (ct < ContentTime()) {
-                               LOG_WARNING ("Crazy timestamp %s", to_string (ct));
+                               LOG_WARNING ("Crazy timestamp %1", to_string (ct));
                        }
 
-                       update_position (ct);
-
                        /* Give this data provided there is some, and its time is sane */
                        if (ct >= ContentTime() && data->frames() > 0) {
                                audio->give (*stream, data, ct);
@@ -478,7 +477,6 @@ FFmpegDecoder::decode_video_packet ()
                                shared_ptr<ImageProxy> (new RawImageProxy (image)),
                                llrint (pts * _ffmpeg_content->active_video_frame_rate ())
                                );
-                       update_position (ContentTime::from_seconds (pts));
                } else {
                        LOG_WARNING_NC ("Dropping frame without PTS");
                }
@@ -509,14 +507,11 @@ FFmpegDecoder::decode_subtitle_packet ()
        FFmpegSubtitlePeriod sub_period = subtitle_period (sub);
        ContentTimePeriod period;
        period.from = sub_period.from + _pts_offset;
-       update_position (period.from);
-       if (sub_period.to) {
-               /* We already know the subtitle period `to' time */
-               period.to = sub_period.to.get() + _pts_offset;
-       } else {
-               /* We have to look up the `to' time in the stream's records */
-               period.to = ffmpeg_content()->subtitle_stream()->find_subtitle_to (subtitle_id (sub));
-       }
+       /* We can't trust the `to' time from sub_period as there are some decoders which
+          give a sub_period time for `to' which is subsequently overridden by a `stop' subtitle;
+          see also FFmpegExaminer.
+       */
+       period.to = ffmpeg_content()->subtitle_stream()->find_subtitle_to (subtitle_id (sub));
 
        for (unsigned int i = 0; i < sub.num_rects; ++i) {
                AVSubtitleRect const * rect = sub.rects[i];
@@ -612,12 +607,13 @@ FFmpegDecoder::decode_bitmap_subtitle (AVSubtitleRect const * rect, ContentTimeP
                out_p += image->stride()[0] / sizeof (uint32_t);
        }
 
-       dcp::Size const vs = _ffmpeg_content->video->size ();
+       int const target_width = subtitle_codec_context()->width;
+       int const target_height = subtitle_codec_context()->height;
        dcpomatic::Rect<double> const scaled_rect (
-               static_cast<double> (rect->x) / vs.width,
-               static_cast<double> (rect->y) / vs.height,
-               static_cast<double> (rect->w) / vs.width,
-               static_cast<double> (rect->h) / vs.height
+               static_cast<double> (rect->x) / target_width,
+               static_cast<double> (rect->y) / target_height,
+               static_cast<double> (rect->w) / target_width,
+               static_cast<double> (rect->h) / target_height
                );
 
        subtitle->give_image (period, image, scaled_rect);
@@ -643,16 +639,3 @@ FFmpegDecoder::decode_ass_subtitle (string ass, ContentTimePeriod period)
                subtitle->give_text (period, i);
        }
 }
-
-void
-FFmpegDecoder::update_position (ContentTime p)
-{
-       /* _position should err on the side of being too big, as then there is less
-          chance that we will erroneously decide not to seek when _position > request.
-       */
-       if (!_position) {
-               _position = p;
-       } else {
-               _position = max (*_position, p);
-       }
-}