Commit 703583db authored by Sergey Svechnikov's avatar Sergey Svechnikov Committed by Timo Rothenpieler

avcodec/cuviddec: improve progressive frame detection

There are 2 types of problems when using adaptive deinterlace with cuvid:

1. Sometimes, in the middle of transcoding, cuvid outputs frames with visible horizontal lines (as though weave deinterlace method was chosen);
2. Occasionally, on scene changes, cuvid outputs a wrong frame, which should have been shown several seconds before (as if the frame was assigned some wrong PTS value).

The reason is that sometimes CUVIDPARSERDISPINFO has property progressive_frame equal to 1 with interlaced videos.
In order to fix the problem we should check if the video is interlaced or progressive in the beginning of a video sequence (cuvid_handle_video_sequence).
And then we just use this information instead of the property progressive_frame in CUVIDPARSERDISPINFO (which is unreliable).
Signed-off-by: 's avatarTimo Rothenpieler <timo@rothenpieler.org>
parent a0877648
...@@ -77,6 +77,7 @@ typedef struct CuvidContext ...@@ -77,6 +77,7 @@ typedef struct CuvidContext
int deint_mode; int deint_mode;
int deint_mode_current; int deint_mode_current;
int64_t prev_pts; int64_t prev_pts;
int progressive_sequence;
int internal_error; int internal_error;
int decoder_flushing; int decoder_flushing;
...@@ -216,6 +217,8 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form ...@@ -216,6 +217,8 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form
? cudaVideoDeinterlaceMode_Weave ? cudaVideoDeinterlaceMode_Weave
: ctx->deint_mode; : ctx->deint_mode;
ctx->progressive_sequence = format->progressive_sequence;
if (!format->progressive_sequence && ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave) if (!format->progressive_sequence && ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave)
avctx->flags |= AV_CODEC_FLAG_INTERLACED_DCT; avctx->flags |= AV_CODEC_FLAG_INTERLACED_DCT;
else else
...@@ -349,6 +352,9 @@ static int CUDAAPI cuvid_handle_picture_display(void *opaque, CUVIDPARSERDISPINF ...@@ -349,6 +352,9 @@ static int CUDAAPI cuvid_handle_picture_display(void *opaque, CUVIDPARSERDISPINF
parsed_frame.dispinfo = *dispinfo; parsed_frame.dispinfo = *dispinfo;
ctx->internal_error = 0; ctx->internal_error = 0;
// For some reason, dispinfo->progressive_frame is sometimes wrong.
parsed_frame.dispinfo.progressive_frame = ctx->progressive_sequence;
if (ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave) { if (ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave) {
av_fifo_generic_write(ctx->frame_queue, &parsed_frame, sizeof(CuvidParsedFrame), NULL); av_fifo_generic_write(ctx->frame_queue, &parsed_frame, sizeof(CuvidParsedFrame), NULL);
} else { } else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment