| 556 | } |
| 557 | |
| 558 | static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) |
| 559 | { |
| 560 | CuvidContext *ctx = avctx->priv_data; |
| 561 | AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data; |
| 562 | AVCUDADeviceContext *device_hwctx = device_ctx->hwctx; |
| 563 | CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx; |
| 564 | CuvidParsedFrame parsed_frame; |
| 565 | CUdeviceptr mapped_frame = 0; |
| 566 | int ret = 0, eret = 0; |
| 567 | |
| 568 | av_log(avctx, AV_LOG_TRACE, "cuvid_output_frame\n"); |
| 569 | |
| 570 | if (ctx->decoder_flushing) { |
| 571 | ret = cuvid_decode_packet(avctx, NULL); |
| 572 | if (ret < 0 && ret != AVERROR_EOF) |
| 573 | return ret; |
| 574 | } |
| 575 | |
| 576 | if (!cuvid_is_buffer_full(avctx)) { |
| 577 | AVPacket *const pkt = ctx->pkt; |
| 578 | ret = ff_decode_get_packet(avctx, pkt); |
| 579 | if (ret < 0 && ret != AVERROR_EOF) |
| 580 | return ret; |
| 581 | ret = cuvid_decode_packet(avctx, pkt); |
| 582 | av_packet_unref(pkt); |
| 583 | // cuvid_is_buffer_full() should avoid this. |
| 584 | if (ret == AVERROR(EAGAIN)) |
| 585 | ret = AVERROR_EXTERNAL; |
| 586 | if (ret < 0 && ret != AVERROR_EOF) |
| 587 | return ret; |
| 588 | } |
| 589 | |
| 590 | ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx)); |
| 591 | if (ret < 0) |
| 592 | return ret; |
| 593 | |
| 594 | if (av_fifo_read(ctx->frame_queue, &parsed_frame, 1) >= 0) { |
| 595 | const AVPixFmtDescriptor *pixdesc; |
| 596 | CUVIDPROCPARAMS params; |
| 597 | unsigned int pitch = 0; |
| 598 | int offset = 0; |
| 599 | int i; |
| 600 | |
| 601 | memset(¶ms, 0, sizeof(params)); |
| 602 | params.progressive_frame = parsed_frame.dispinfo.progressive_frame; |
| 603 | params.second_field = parsed_frame.second_field; |
| 604 | params.top_field_first = parsed_frame.dispinfo.top_field_first; |
| 605 | |
| 606 | ret = CHECK_CU(ctx->cvdl->cuvidMapVideoFrame(ctx->cudecoder, parsed_frame.dispinfo.picture_index, &mapped_frame, &pitch, ¶ms)); |
| 607 | if (ret < 0) |
| 608 | goto error; |
| 609 | |
| 610 | if (avctx->pix_fmt == AV_PIX_FMT_CUDA) { |
| 611 | ret = av_hwframe_get_buffer(ctx->hwframe, frame, 0); |
| 612 | if (ret < 0) { |
| 613 | av_log(avctx, AV_LOG_ERROR, "av_hwframe_get_buffer failed\n"); |
| 614 | goto error; |
| 615 | } |
nothing calls this directly
no test coverage detected