X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fffmpeg_examiner.cc;h=fdcacb465602693fba0bf668cc82d7bd9b82ddd6;hb=1a721b82d4094c00ee89574e17c58c23c0de8cdd;hp=a793c7b985d09bfcd91114abe76c6723327dc252;hpb=6f832724ef942f133f6f8d0a06d7377beea8f7a6;p=dcpomatic.git diff --git a/src/lib/ffmpeg_examiner.cc b/src/lib/ffmpeg_examiner.cc index a793c7b98..fdcacb465 100644 --- a/src/lib/ffmpeg_examiner.cc +++ b/src/lib/ffmpeg_examiner.cc @@ -26,17 +26,18 @@ #include "ffmpeg_audio_stream.h" #include "ffmpeg_subtitle_stream.h" #include "util.h" -#include "warnings.h" -DCPOMATIC_DISABLE_WARNINGS +#include +LIBDCP_DISABLE_WARNINGS extern "C" { #include #include #include #include -#include +#include #include +#include } -DCPOMATIC_ENABLE_WARNINGS +LIBDCP_ENABLE_WARNINGS #include #include "i18n.h" @@ -69,7 +70,7 @@ FFmpegExaminer::FFmpegExaminer (shared_ptr c, shared_ptrnb_streams; ++i) { auto s = _format_context->streams[i]; - auto codec = _codec_context[i]->codec; + auto codec = _codec_context[i] ? _codec_context[i]->codec : nullptr; if (s->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && codec) { /* This is a hack; sometimes it seems that _audio_codec_context->channel_layout isn't set up, @@ -220,34 +221,38 @@ FFmpegExaminer::video_packet (AVCodecContext* context, string& temporal_referenc return false; } - int r = avcodec_send_packet (context, packet); - if (r < 0 && !(r == AVERROR_EOF && !packet)) { - /* We could cope with AVERROR(EAGAIN) and re-send the packet but I think it should never happen. - * AVERROR_EOF can happen during flush if we've already sent a flush packet. - */ - throw DecodeError (N_("avcodec_send_packet"), N_("FFmpegExaminer::video_packet"), r); - } + bool pending = false; + do { + int r = avcodec_send_packet (context, packet); + if (r < 0) { + LOG_WARNING("avcodec_send_packet returned %1 for a video packet", r); + } - r = avcodec_receive_frame (context, _frame); - if (r == AVERROR(EAGAIN)) { - /* More input is required */ - return true; - } else if (r == AVERROR_EOF) { - /* No more output is coming */ - return false; - } + /* EAGAIN means we should call avcodec_receive_frame and then re-send the same packet */ + pending = r == AVERROR(EAGAIN); + + r = avcodec_receive_frame (context, _video_frame); + if (r == AVERROR(EAGAIN)) { + /* More input is required */ + return true; + } else if (r == AVERROR_EOF) { + /* No more output is coming */ + return false; + } + } while (pending); if (!_first_video) { - _first_video = frame_time (_format_context->streams[_video_stream.get()]); + _first_video = frame_time (_video_frame, _format_context->streams[_video_stream.get()]); } if (_need_video_length) { _video_length = frame_time ( + _video_frame, _format_context->streams[_video_stream.get()] ).get_value_or (ContentTime ()).frames_round (video_frame_rate().get ()); } if (temporal_reference.size() < (PULLDOWN_CHECK_FRAMES * 2)) { - temporal_reference += (_frame->top_field_first ? "T" : "B"); - temporal_reference += (_frame->repeat_pict ? "3" : "2"); + temporal_reference += (_video_frame->top_field_first ? "T" : "B"); + temporal_reference += (_video_frame->repeat_pict ? "3" : "2"); } return true; @@ -262,30 +267,29 @@ FFmpegExaminer::audio_packet (AVCodecContext* context, shared_ptrfirst_audio = frame_time (stream->stream(_format_context)); + stream->first_audio = frame_time (frame, stream->stream(_format_context)); } optional -FFmpegExaminer::frame_time (AVStream* s) const +FFmpegExaminer::frame_time (AVFrame* frame, AVStream* stream) const { optional t; - int64_t const bet = _frame->best_effort_timestamp; + int64_t const bet = frame->best_effort_timestamp; if (bet != AV_NOPTS_VALUE) { - t = ContentTime::from_seconds (bet * av_q2d (s->time_base)); + t = ContentTime::from_seconds (bet * av_q2d(stream->time_base)); } return t; @@ -479,3 +483,13 @@ FFmpegExaminer::range () const return VideoRange::FULL; } } + + +PixelQuanta +FFmpegExaminer::pixel_quanta () const +{ + auto const desc = av_pix_fmt_desc_get(video_codec_context()->pix_fmt); + DCPOMATIC_ASSERT (desc); + return { 1 << desc->log2_chroma_w, 1 << desc->log2_chroma_h }; +} +