Change how video timing is done.
[dcpomatic.git] / src / lib / ffmpeg_decoder.cc
index 477dcda1988371b271eb2bcaa1c943c1d630eb27..c1633c8bb442041516a7b5ee332ad8e394be4172 100644 (file)
@@ -178,9 +178,8 @@ FFmpegDecoder::flush_fill()
        full_length = full_length.ceil (frc.source);
        if (video && !video->ignore()) {
                double const vfr = _ffmpeg_content->video_frame_rate().get();
-               auto const f = full_length.frames_round (vfr);
-               auto const v = video->position(film()).get_value_or(ContentTime()).frames_round(vfr) + 1;
-               if (v < f) {
+               auto const v = video->position(film()).get_value_or(ContentTime()) + ContentTime::from_frames(1, vfr);
+               if (v < full_length) {
                        video->emit(film(), make_shared<const RawImageProxy>(_black_image), v);
                        did_something = true;
                }
@@ -254,18 +253,22 @@ FFmpegDecoder::pass ()
  */
 static
 shared_ptr<AudioBuffers>
-deinterleave_audio(shared_ptr<FFmpegAudioStream> stream, AVFrame* frame)
+deinterleave_audio(AVFrame* frame)
 {
        auto format = static_cast<AVSampleFormat>(frame->format);
 
        /* XXX: can't we use swr_convert() to do the format conversion? */
 
-       int const channels = frame->channels;
+       int const channels = frame->ch_layout.nb_channels;
        int const frames = frame->nb_samples;
        int const total_samples = frames * channels;
        auto audio = make_shared<AudioBuffers>(channels, frames);
        auto data = audio->data();
 
+       if (frames == 0) {
+               return audio;
+       }
+
        switch (format) {
        case AV_SAMPLE_FMT_U8:
        {
@@ -476,7 +479,7 @@ void
 FFmpegDecoder::process_audio_frame (shared_ptr<FFmpegAudioStream> stream)
 {
        auto frame = audio_frame (stream);
-       auto data = deinterleave_audio(stream, frame);
+       auto data = deinterleave_audio(frame);
 
        auto const time_base = stream->stream(_format_context)->time_base;
 
@@ -618,7 +621,7 @@ FFmpegDecoder::process_video_frame ()
                        video->emit (
                                film(),
                                make_shared<RawImageProxy>(image),
-                               llrint(pts * _ffmpeg_content->active_video_frame_rate(film()))
+                               ContentTime::from_seconds(pts)
                                );
                } else {
                        LOG_WARNING_NC ("Dropping frame without PTS");
@@ -630,9 +633,14 @@ FFmpegDecoder::process_video_frame ()
 void
 FFmpegDecoder::decode_and_process_subtitle_packet (AVPacket* packet)
 {
+       auto context = subtitle_codec_context();
+       if (!context) {
+               return;
+       }
+
        int got_subtitle;
        AVSubtitle sub;
-       if (avcodec_decode_subtitle2 (subtitle_codec_context(), &sub, &got_subtitle, packet) < 0 || !got_subtitle) {
+       if (avcodec_decode_subtitle2(context, &sub, &got_subtitle, packet) < 0 || !got_subtitle) {
                return;
        }