X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Flib%2Fffmpeg_decoder.cc;h=a51b521d0fe22918010a6976c5ae754dd9d8e051;hb=7e690d21278df14b113f3602cbbd43f6214fd614;hp=851c64606b705af1974c1c953fa1d14863c6af89;hpb=816b3c2dda2c5e33900f5d90a001284045040b5f;p=dcpomatic.git diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 851c64606..a51b521d0 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Carl Hetherington + Copyright (C) 2012-2014 Carl Hetherington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,7 +27,6 @@ #include #include #include -#include #include extern "C" { #include @@ -43,9 +42,14 @@ extern "C" { #include "filter_graph.h" #include "audio_buffers.h" #include "ffmpeg_content.h" +#include "image_proxy.h" #include "i18n.h" +#define LOG_GENERAL(...) film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_GENERAL); +#define LOG_ERROR(...) film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_ERROR); +#define LOG_WARNING(...) film->log()->log (__VA_ARGS__, Log::TYPE_WARNING); + using std::cout; using std::string; using std::vector; @@ -142,7 +146,7 @@ FFmpegDecoder::flush () } /* Stop us being asked for any more data */ - _video_position = _ffmpeg_content->video_length (); + _video_position = _ffmpeg_content->video_length_after_3d_combine (); _audio_position = _ffmpeg_content->audio_length (); } @@ -158,7 +162,7 @@ FFmpegDecoder::pass () av_strerror (r, buf, sizeof(buf)); shared_ptr film = _film.lock (); assert (film); - film->log()->log (String::compose (N_("error on av_read_frame (%1) (%2)"), buf, r)); + LOG_ERROR (N_("error on av_read_frame (%1) (%2)"), buf, r); } flush (); @@ -382,6 +386,11 @@ FFmpegDecoder::seek (VideoContent::Frame frame, bool accurate) av_free_packet (&_packet); } + + /* _video_position should be the next thing to be emitted, which will the one after the thing + we just saw. + */ + _video_position++; } void @@ -400,7 +409,7 @@ FFmpegDecoder::decode_audio_packet () if (decode_result < 0) { shared_ptr film = _film.lock (); assert (film); - film->log()->log (String::compose ("avcodec_decode_audio4 failed (%1)", decode_result)); + LOG_ERROR ("avcodec_decode_audio4 failed (%1)", decode_result); return; } @@ -413,15 +422,18 @@ FFmpegDecoder::decode_audio_packet () if (pts > 0) { /* Emit some silence */ - shared_ptr silence ( - new AudioBuffers ( - _ffmpeg_content->audio_channels(), - pts * _ffmpeg_content->content_audio_frame_rate() - ) - ); + int64_t frames = pts * _ffmpeg_content->content_audio_frame_rate (); + while (frames > 0) { + int64_t const this_time = min (frames, (int64_t) _ffmpeg_content->content_audio_frame_rate() / 2); + + shared_ptr silence ( + new AudioBuffers (_ffmpeg_content->audio_channels(), this_time) + ); - silence->make_silent (); - audio (silence, _audio_position); + silence->make_silent (); + audio (silence, _audio_position); + frames -= this_time; + } } } @@ -461,13 +473,16 @@ FFmpegDecoder::decode_video_packet () graph.reset (new FilterGraph (_ffmpeg_content, libdcp::Size (_frame->width, _frame->height), (AVPixelFormat) _frame->format)); _filter_graphs.push_back (graph); - film->log()->log (String::compose (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format)); + LOG_GENERAL (N_("New graph for %1x%2, pixel format %3"), _frame->width, _frame->height, _frame->format); } else { graph = *i; } list, int64_t> > images = graph->process (_frame); + shared_ptr film = _film.lock (); + assert (film); + for (list, int64_t> >::iterator i = images.begin(); i != images.end(); ++i) { shared_ptr image = i->first; @@ -502,20 +517,21 @@ FFmpegDecoder::decode_video_packet () ) ); + shared_ptr film = _film.lock (); + assert (film); + black->make_black (); - video (image, false, _video_position); + video (shared_ptr (new RawImageProxy (image, film->log())), false, _video_position); delta -= one_frame; } if (delta > -one_frame) { /* This PTS is within a frame of being right; emit this (otherwise it will be dropped) */ - video (image, false, _video_position); + video (shared_ptr (new RawImageProxy (image, film->log())), false, _video_position); } } else { - shared_ptr film = _film.lock (); - assert (film); - film->log()->log ("Dropping frame without PTS"); + LOG_WARNING ("Dropping frame without PTS"); } }