Showing the changes to libavcodec (1 of 1 file). Show all
Unified · Split
| @@ -131,7 +131,7 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form · 130 unmodified lines | |||
| 131 | CUVIDDECODECREATEINFO cuinfo; | 131 | CUVIDDECODECREATEINFO cuinfo; |
| 132 | int surface_fmt; | 132 | int surface_fmt; |
| 133 | int chroma_444; | 133 | int chroma_444; |
| 134 | int fifo_size_inc; | 134 | int old_nb_surfaces, fifo_size_inc, fifo_size_mul = 1; |
| 135 | 135 | ||
| 136 | int old_width = avctx->width; | 136 | int old_width = avctx->width; |
| 137 | int old_height = avctx->height; | 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 | return 0; | 349 | return 0; |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | fifo_size_inc = ctx->nb_surfaces; | 352 | if (ctx->deint_mode_current != cudaVideoDeinterlaceMode_Weave && !ctx->drop_second_field) { |
| 353 | ctx->nb_surfaces = FFMAX(ctx->nb_surfaces, format->min_num_decode_surfaces + 3); | 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 | if (avctx->extra_hw_frames > 0) | 359 | if (avctx->extra_hw_frames > 0) |
| 356 | ctx->nb_surfaces += avctx->extra_hw_frames; | 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 | if (fifo_size_inc > 0 && av_fifo_grow2(ctx->frame_queue, fifo_size_inc) < 0) { | 363 | if (fifo_size_inc > 0 && av_fifo_grow2(ctx->frame_queue, fifo_size_inc) < 0) { |
| 360 | av_log(avctx, AV_LOG_ERROR, "Failed to grow frame queue on video sequence callback\n"); | 364 | av_log(avctx, AV_LOG_ERROR, "Failed to grow frame queue on video sequence callback\n"); |
| 361 | ctx->internal_error = AVERROR(ENOMEM); | 365 | ctx->internal_error = AVERROR(ENOMEM); |
| 362 | return 0; | 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 | av_log(avctx, AV_LOG_ERROR, "Failed to grow key frame array on video sequence callback\n"); | 370 | av_log(avctx, AV_LOG_ERROR, "Failed to grow key frame array on video sequence callback\n"); |
| 367 | ctx->internal_error = AVERROR(ENOMEM); | 371 | ctx->internal_error = AVERROR(ENOMEM); |
| 368 | return 0; | 372 | return 0; |
| @@ -374,9 +378,6 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form · 5 unmodified lines | |||
| 374 | cuinfo.bitDepthMinus8 = format->bit_depth_luma_minus8; | 378 | cuinfo.bitDepthMinus8 = format->bit_depth_luma_minus8; |
| 375 | cuinfo.DeinterlaceMode = ctx->deint_mode_current; | 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 | ctx->internal_error = CHECK_CU(ctx->cvdl->cuvidCreateDecoder(&ctx->cudecoder, &cuinfo)); | 381 | ctx->internal_error = CHECK_CU(ctx->cvdl->cuvidCreateDecoder(&ctx->cudecoder, &cuinfo)); |
| 381 | if (ctx->internal_error < 0) | 382 | if (ctx->internal_error < 0) |
| 382 | return 0; | 383 | return 0; |
| @@ -448,11 +449,12 @@ static int cuvid_is_buffer_full(AVCodecContext *avctx) · 65 unmodified lines | |||
| 448 | { | 449 | { |
| 449 | CuvidContext *ctx = avctx->priv_data; | 450 | CuvidContext *ctx = avctx->priv_data; |
| 450 | 451 | ||
| 451 | int delay = ctx->cuparseinfo.ulMaxDisplayDelay; | 452 | int shift = 0; |
| 452 | if (ctx->deint_mode != cudaVideoDeinterlaceMode_Weave && !ctx->drop_second_field) | 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 | static int cuvid_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt) | 460 | static int cuvid_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt) |