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: Timo Rothenpieler <timo@rothenpieler.org>
This commit is contained in:
		
							parent
							
								
									a087764847
								
							
						
					
					
						commit
						703583dbb1
					
				@ -77,6 +77,7 @@ typedef struct CuvidContext
 | 
			
		||||
    int deint_mode;
 | 
			
		||||
    int deint_mode_current;
 | 
			
		||||
    int64_t prev_pts;
 | 
			
		||||
    int progressive_sequence;
 | 
			
		||||
 | 
			
		||||
    int internal_error;
 | 
			
		||||
    int decoder_flushing;
 | 
			
		||||
@ -216,6 +217,8 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form
 | 
			
		||||
                              ? cudaVideoDeinterlaceMode_Weave
 | 
			
		||||
                              : ctx->deint_mode;
 | 
			
		||||
 | 
			
		||||
    ctx->progressive_sequence = format->progressive_sequence;
 | 
			
		||||
 | 
			
		||||
    if (!format->progressive_sequence && ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave)
 | 
			
		||||
        avctx->flags |= AV_CODEC_FLAG_INTERLACED_DCT;
 | 
			
		||||
    else
 | 
			
		||||
@ -349,6 +352,9 @@ static int CUDAAPI cuvid_handle_picture_display(void *opaque, CUVIDPARSERDISPINF
 | 
			
		||||
    parsed_frame.dispinfo = *dispinfo;
 | 
			
		||||
    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) {
 | 
			
		||||
        av_fifo_generic_write(ctx->frame_queue, &parsed_frame, sizeof(CuvidParsedFrame), NULL);
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user