| @@ -44,6 +44,7 @@ typedef struct NVDECDecoder { · 43 unmodified lines |
| 44 | CUvideodecoder decoder; | 44 | CUvideodecoder decoder; |
| 45 | | 45 | |
| 46 | AVBufferRef *hw_device_ref; | 46 | AVBufferRef *hw_device_ref; |
| | 47 | AVBufferRef *real_hw_frames_ref; |
| 47 | CUcontext cuda_ctx; | 48 | CUcontext cuda_ctx; |
| 48 | CUstream stream; | 49 | CUstream stream; |
| 49 | | 50 | |
| @@ -163,6 +164,7 @@ static void nvdec_decoder_free(void *opaque, uint8_t *data) · 113 unmodified lines |
| 163 | CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy)); | 164 | CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy)); |
| 164 | } | 165 | } |
| 165 | | 166 | |
| | 167 | av_buffer_unref(&decoder->real_hw_frames_ref); |
| 166 | av_buffer_unref(&decoder->hw_device_ref); | 168 | av_buffer_unref(&decoder->hw_device_ref); |
| 167 | | 169 | |
| 168 | cuvid_free_functions(&decoder->cvdl); | 170 | cuvid_free_functions(&decoder->cvdl); |
| @@ -269,10 +271,61 @@ int ff_nvdec_decode_uninit(AVCodecContext *avctx) · 100 unmodified lines |
| 269 | return 0; | 271 | return 0; |
| 270 | } | 272 | } |
| 271 | | 273 | |
| | 274 | static void nvdec_free_dummy(struct AVHWFramesContext *ctx) |
| | 275 | { |
| | 276 | av_buffer_pool_uninit(&ctx->pool); |
| | 277 | } |
| | 278 | |
| | 279 | static AVBufferRef *nvdec_alloc_dummy(int size) |
| | 280 | { |
| | 281 | return av_buffer_create(NULL, 0, NULL, NULL, 0); |
| | 282 | } |
| | 283 | |
| | 284 | static int nvdec_init_hwframes(AVCodecContext *avctx, AVBufferRef **out_frames_ref, int dummy) |
| | 285 | { |
| | 286 | AVHWFramesContext *frames_ctx; |
| | 287 | int ret; |
| | 288 | |
| | 289 | ret = avcodec_get_hw_frames_parameters(avctx, |
| | 290 | avctx->hw_device_ctx, |
| | 291 | avctx->hwaccel->pix_fmt, |
| | 292 | out_frames_ref); |
| | 293 | if (ret < 0) |
| | 294 | return ret; |
| | 295 | |
| | 296 | frames_ctx = (AVHWFramesContext*)(*out_frames_ref)->data; |
| | 297 | |
| | 298 | if (dummy) { |
| | 299 | // Copied from ff_decode_get_hw_frames_ctx for compatibility |
| | 300 | frames_ctx->initial_pool_size += 3; |
| | 301 | |
| | 302 | frames_ctx->free = nvdec_free_dummy; |
| | 303 | frames_ctx->pool = av_buffer_pool_init(0, nvdec_alloc_dummy); |
| | 304 | |
| | 305 | if (!frames_ctx->pool) { |
| | 306 | av_buffer_unref(out_frames_ref); |
| | 307 | return AVERROR(ENOMEM); |
| | 308 | } |
| | 309 | } else { |
| | 310 | // This is normally not used to actually allocate frames from |
| | 311 | frames_ctx->initial_pool_size = 0; |
| | 312 | } |
| | 313 | |
| | 314 | ret = av_hwframe_ctx_init(*out_frames_ref); |
| | 315 | if (ret < 0) { |
| | 316 | av_buffer_unref(out_frames_ref); |
| | 317 | return ret; |
| | 318 | } |
| | 319 | |
| | 320 | return 0; |
| | 321 | } |
| | 322 | |
| 272 | int ff_nvdec_decode_init(AVCodecContext *avctx) | 323 | int ff_nvdec_decode_init(AVCodecContext *avctx) |
| 273 | { | 324 | { |
| 274 | NVDECContext *ctx = avctx->internal->hwaccel_priv_data; | 325 | NVDECContext *ctx = avctx->internal->hwaccel_priv_data; |
| 275 | | 326 | |
| | 327 | NVDECDecoder *decoder; |
| | 328 | AVBufferRef *real_hw_frames_ref; |
| 276 | NVDECFramePool *pool; | 329 | NVDECFramePool *pool; |
| 277 | AVHWFramesContext *frames_ctx; | 330 | AVHWFramesContext *frames_ctx; |
| 278 | const AVPixFmtDescriptor *sw_desc; | 331 | const AVPixFmtDescriptor *sw_desc; |
| @@ -301,9 +354,17 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) · 22 unmodified lines |
| 301 | chroma_444 = ctx->supports_444 && cuvid_chroma_format == cudaVideoChromaFormat_444; | 354 | chroma_444 = ctx->supports_444 && cuvid_chroma_format == cudaVideoChromaFormat_444; |
| 302 | | 355 | |
| 303 | if (!avctx->hw_frames_ctx) { | 356 | if (!avctx->hw_frames_ctx) { |
| 304 | ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_CUDA); | 357 | ret = nvdec_init_hwframes(avctx, &avctx->hw_frames_ctx, 1); |
| | 358 | if (ret < 0) |
| | 359 | return ret; |
| | 360 | |
| | 361 | ret = nvdec_init_hwframes(avctx, &real_hw_frames_ref, 0); |
| 305 | if (ret < 0) | 362 | if (ret < 0) |
| 306 | return ret; | 363 | return ret; |
| | 364 | } else { |
| | 365 | real_hw_frames_ref = av_buffer_ref(avctx->hw_frames_ctx); |
| | 366 | if (!real_hw_frames_ref) |
| | 367 | return AVERROR(ENOMEM); |
| 307 | } | 368 | } |
| 308 | | 369 | |
| 309 | switch (sw_desc->comp[0].depth) { | 370 | switch (sw_desc->comp[0].depth) { |
| @@ -318,6 +379,7 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) · 8 unmodified lines |
| 318 | break; | 379 | break; |
| 319 | default: | 380 | default: |
| 320 | av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth\n"); | 381 | av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth\n"); |
| | 382 | av_buffer_unref(&real_hw_frames_ref); |
| 321 | return AVERROR(ENOSYS); | 383 | return AVERROR(ENOSYS); |
| 322 | } | 384 | } |
| 323 | | 385 | |
| @@ -342,9 +404,14 @@ int ff_nvdec_decode_init(AVCodecContext *avctx) · 18 unmodified lines |
| 342 | av_log(avctx, AV_LOG_WARNING, "Try lowering the amount of threads. Using %d right now.\n", | 404 | av_log(avctx, AV_LOG_WARNING, "Try lowering the amount of threads. Using %d right now.\n", |
| 343 | avctx->thread_count); | 405 | avctx->thread_count); |
| 344 | } | 406 | } |
| | 407 | av_buffer_unref(&real_hw_frames_ref); |
| 345 | return ret; | 408 | return ret; |
| 346 | } | 409 | } |
| 347 | | 410 | |
| | 411 | decoder = (NVDECDecoder*)ctx->decoder_ref->data; |
| | 412 | decoder->real_hw_frames_ref = real_hw_frames_ref; |
| | 413 | real_hw_frames_ref = NULL; |
| | 414 | |
| 348 | pool = av_mallocz(sizeof(*pool)); | 415 | pool = av_mallocz(sizeof(*pool)); |
| 349 | if (!pool) { | 416 | if (!pool) { |
| 350 | ret = AVERROR(ENOMEM); | 417 | ret = AVERROR(ENOMEM); |
| @@ -447,6 +514,13 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) · 96 unmodified lines |
| 447 | goto copy_fail; | 514 | goto copy_fail; |
| 448 | } | 515 | } |
| 449 | | 516 | |
| | 517 | av_buffer_unref(&frame->hw_frames_ctx); |
| | 518 | frame->hw_frames_ctx = av_buffer_ref(decoder->real_hw_frames_ref); |
| | 519 | if (!frame->hw_frames_ctx) { |
| | 520 | ret = AVERROR(ENOMEM); |
| | 521 | goto copy_fail; |
| | 522 | } |
| | 523 | |
| 450 | unmap_data->idx = cf->idx; | 524 | unmap_data->idx = cf->idx; |
| 451 | unmap_data->idx_ref = av_buffer_ref(cf->idx_ref); | 525 | unmap_data->idx_ref = av_buffer_ref(cf->idx_ref); |
| 452 | unmap_data->decoder_ref = av_buffer_ref(cf->decoder_ref); | 526 | unmap_data->decoder_ref = av_buffer_ref(cf->decoder_ref); |
| @@ -575,16 +649,6 @@ int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, · 122 unmodified lines |
| 575 | return 0; | 649 | return 0; |
| 576 | } | 650 | } |
| 577 | | 651 | |
| 578 | static void nvdec_free_dummy(struct AVHWFramesContext *ctx) | | |
| 579 | { | | |
| 580 | av_buffer_pool_uninit(&ctx->pool); | | |
| 581 | } | | |
| 582 | | | |
| 583 | static AVBufferRef *nvdec_alloc_dummy(int size) | | |
| 584 | { | | |
| 585 | return av_buffer_create(NULL, 0, NULL, NULL, 0); | | |
| 586 | } | | |
| 587 | | | |
| 588 | int ff_nvdec_frame_params(AVCodecContext *avctx, | 652 | int ff_nvdec_frame_params(AVCodecContext *avctx, |
| 589 | AVBufferRef *hw_frames_ctx, | 653 | AVBufferRef *hw_frames_ctx, |
| 590 | int dpb_size, | 654 | int dpb_size, |
| @@ -620,12 +684,6 @@ int ff_nvdec_frame_params(AVCodecContext *avctx, · 29 unmodified lines |
| 620 | */ | 684 | */ |
| 621 | frames_ctx->initial_pool_size = dpb_size + 2; | 685 | frames_ctx->initial_pool_size = dpb_size + 2; |
| 622 | | 686 | |
| 623 | frames_ctx->free = nvdec_free_dummy; | | |
| 624 | frames_ctx->pool = av_buffer_pool_init(0, nvdec_alloc_dummy); | | |
| 625 | | | |
| 626 | if (!frames_ctx->pool) | | |
| 627 | return AVERROR(ENOMEM); | | |
| 628 | | | |
| 629 | switch (sw_desc->comp[0].depth) { | 687 | switch (sw_desc->comp[0].depth) { |
| 630 | case 8: | 688 | case 8: |
| 631 | frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_NV12; | 689 | frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_NV12; |