From c4a6ead569116d966bb0318a3b70561536f6a531 Mon Sep 17 00:00:00 2001 From: "FeRD (Frank Dana)" Date: Tue, 20 Aug 2019 04:32:47 -0400 Subject: [PATCH 1/2] FFmpegReader: Detect interlaced video Move interlace detection to UpdateVideoInfo() so it'll be done before we read any frames, and use the field_order member of the codec attributes (an AVFieldOrder enum) as the data source. --- src/FFmpegReader.cpp | 53 +++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index c9e21271..38a1f610 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -729,6 +729,31 @@ void FFmpegReader::UpdateVideoInfo() { info.display_ratio.num = size.num; info.display_ratio.den = size.den; + // Get scan type and order from codec context/params + if (!check_interlace) { + check_interlace = true; + AVFieldOrder field_order = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->field_order; + switch(field_order) { + case AV_FIELD_PROGRESSIVE: + info.interlaced_frame = false; + break; + case AV_FIELD_TT: + case AV_FIELD_TB: + info.interlaced_frame = true; + info.top_field_first = true; + break; + case AV_FIELD_BT: + case AV_FIELD_BB: + info.interlaced_frame = true; + info.top_field_first = false; + break; + case AV_FIELD_UNKNOWN: + // Check again later? + check_interlace = false; + break; + } + } + // Set the video timebase info.video_timebase.num = pStream->time_base.num; info.video_timebase.den = pStream->time_base.den; @@ -1078,14 +1103,14 @@ bool FFmpegReader::GetAVFrame() { ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAVFrame (Packet not sent)"); } else { - AVFrame *next_frame2; - if (hw_de_on && hw_de_supported) { - next_frame2 = AV_ALLOCATE_FRAME(); - } - else - { - next_frame2 = next_frame; - } + AVFrame *next_frame2; + if (hw_de_on && hw_de_supported) { + next_frame2 = AV_ALLOCATE_FRAME(); + } + else + { + next_frame2 = next_frame; + } pFrame = AV_ALLOCATE_FRAME(); while (ret >= 0) { ret = avcodec_receive_frame(pCodecCtx, next_frame2); @@ -1119,11 +1144,6 @@ bool FFmpegReader::GetAVFrame() { av_image_alloc(pFrame->data, pFrame->linesize, info.width, info.height, (AVPixelFormat)(pStream->codecpar->format), 1); av_image_copy(pFrame->data, pFrame->linesize, (const uint8_t**)next_frame->data, next_frame->linesize, (AVPixelFormat)(pStream->codecpar->format), info.width, info.height); - if (!check_interlace) { - check_interlace = true; - info.interlaced_frame = next_frame->interlaced_frame; - info.top_field_first = next_frame->top_field_first; - } } } if (hw_de_on && hw_de_supported) { @@ -1143,13 +1163,6 @@ bool FFmpegReader::GetAVFrame() { avpicture_alloc((AVPicture *) pFrame, pCodecCtx->pix_fmt, info.width, info.height); av_picture_copy((AVPicture *) pFrame, (AVPicture *) next_frame, pCodecCtx->pix_fmt, info.width, info.height); - - // Detect interlaced frame (only once) - if (!check_interlace) { - check_interlace = true; - info.interlaced_frame = next_frame->interlaced_frame; - info.top_field_first = next_frame->top_field_first; - } } #endif } From 9e0d194072a227ffc05283fbcd7c4ad1c44acd20 Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Sun, 22 Sep 2019 01:37:32 -0400 Subject: [PATCH 2/2] Add comment re: updates to interlace params --- src/FFmpegReader.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 38a1f610..7b5230e9 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -752,6 +752,8 @@ void FFmpegReader::UpdateVideoInfo() { check_interlace = false; break; } + // check_interlace will prevent these checks being repeated, + // unless it was cleared because we got an AV_FIELD_UNKNOWN response. } // Set the video timebase