Unified · Split
| @@ -131,7 +131,7 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form · 130 unmodified lines | ||
| 131 | 131 | CUVIDDECODECREATEINFO cuinfo; |
| 132 | 132 | int surface_fmt; |
| 133 | 133 | int chroma_444; |
| 134 | − int fifo_size_inc; | |
| 134 | + int old_nb_surfaces, fifo_size_inc, fifo_size_mul = 1; | |
| 135 | 135 | |
| 136 | 136 | int old_width = avctx->width; |
| 137 | 137 | int old_height = avctx->height; |
| @@ -349,20 +349,24 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form · 211 unmodified lines | ||
| 349 | 349 | return 0; |
| 350 | 350 | } |
| 351 | 351 | |
| 352 | − fifo_size_inc = ctx->nb_surfaces; | |
| 353 | − ctx->nb_surfaces = FFMAX(ctx->nb_surfaces, format->min_num_decode_surfaces + 3); | |
| 352 | + if (ctx->deint_mode_current != cudaVideoDeinterlaceMode_Weave && !ctx->drop_second_field) { | |
| 353 | + avctx->framerate = av_mul_q(avctx->framerate, (AVRational){2, 1}); | |
| 354 | + fifo_size_mul = 2; | |
| 355 | + } | |
| 354 | 356 | |
| 357 | + old_nb_surfaces = ctx->nb_surfaces; | |
| 358 | + ctx->nb_surfaces = FFMAX(ctx->nb_surfaces, format->min_num_decode_surfaces + 3); | |
| 355 | 359 | if (avctx->extra_hw_frames > 0) |
| 356 | 360 | ctx->nb_surfaces += avctx->extra_hw_frames; |
| 357 | 361 | |
| 358 | − fifo_size_inc = ctx->nb_surfaces - fifo_size_inc; | |
| 362 | + fifo_size_inc = ctx->nb_surfaces * fifo_size_mul - av_fifo_can_read(ctx->frame_queue) - av_fifo_can_write(ctx->frame_queue); | |
| 359 | 363 | if (fifo_size_inc > 0 && av_fifo_grow2(ctx->frame_queue, fifo_size_inc) < 0) { |
| 360 | 364 | av_log(avctx, AV_LOG_ERROR, "Failed to grow frame queue on video sequence callback\n"); |
| 361 | 365 | ctx->internal_error = AVERROR(ENOMEM); |
| 362 | 366 | return 0; |
| 363 | 367 | } |
| 364 | 368 | |
| 365 | − if (fifo_size_inc > 0 && av_reallocp_array(&ctx->key_frame, ctx->nb_surfaces, sizeof(int)) < 0) { | |
| 369 | + if (ctx->nb_surfaces > old_nb_surfaces && av_reallocp_array(&ctx->key_frame, ctx->nb_surfaces, sizeof(int)) < 0) { | |
| 366 | 370 | av_log(avctx, AV_LOG_ERROR, "Failed to grow key frame array on video sequence callback\n"); |
| 367 | 371 | ctx->internal_error = AVERROR(ENOMEM); |
| 368 | 372 | return 0; |
| @@ -374,9 +378,6 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form · 5 unmodified lines | ||
| 374 | 378 | cuinfo.bitDepthMinus8 = format->bit_depth_luma_minus8; |
| 375 | 379 | cuinfo.DeinterlaceMode = ctx->deint_mode_current; |
| 376 | 380 | |
| 377 | − if (ctx->deint_mode_current != cudaVideoDeinterlaceMode_Weave && !ctx->drop_second_field) | |
| 378 | − avctx->framerate = av_mul_q(avctx->framerate, (AVRational){2, 1}); | |
| 379 | − | |
| 380 | 381 | ctx->internal_error = CHECK_CU(ctx->cvdl->cuvidCreateDecoder(&ctx->cudecoder, &cuinfo)); |
| 381 | 382 | if (ctx->internal_error < 0) |
| 382 | 383 | return 0; |
| @@ -448,11 +449,12 @@ static int cuvid_is_buffer_full(AVCodecContext *avctx) · 65 unmodified lines | ||
| 448 | 449 | { |
| 449 | 450 | CuvidContext *ctx = avctx->priv_data; |
| 450 | 451 | |
| 451 | − int delay = ctx->cuparseinfo.ulMaxDisplayDelay; | |
| 452 | + int shift = 0; | |
| 452 | 453 | if (ctx->deint_mode != cudaVideoDeinterlaceMode_Weave && !ctx->drop_second_field) |
| 453 | − delay *= 2; | |
| 454 | + shift = 1; | |
| 454 | 455 | |
| 455 | − return av_fifo_can_read(ctx->frame_queue) + delay >= ctx->nb_surfaces; | |
| 456 | + // shift/divide frame count to ensure the buffer is still signalled full if one half-frame has already been returned when deinterlacing. | |
| 457 | + return ((av_fifo_can_read(ctx->frame_queue) + shift) >> shift) + ctx->cuparseinfo.ulMaxDisplayDelay >= ctx->nb_surfaces; | |
| 456 | 458 | } |
| 457 | 459 | |
| 458 | 460 | static int cuvid_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt) |