diff --git a/src/player/ffmpegDecode.cpp b/src/player/ffmpegDecode.cpp index 6e4cc58..e0f57f2 100644 --- a/src/player/ffmpegDecode.cpp +++ b/src/player/ffmpegDecode.cpp @@ -9,7 +9,7 @@ bool FFmpegDecoder::OpenInput(string &inputFile) { CloseInput(); - if (isHwDecoderEnable) { + if (!isHwDecoderEnable) { hwDecoderType = av_hwdevice_find_type_by_name("d3d11va"); if (hwDecoderType != AV_HWDEVICE_TYPE_NONE) { isHwDecoderEnable = true; @@ -32,9 +32,9 @@ bool FFmpegDecoder::OpenInput(string &inputFile) { // 超时机制 static const int timeout = 10; auto startTime = std::make_shared(); - *startTime = QDateTime::currentDateTime().toSecsSinceEpoch(); + *startTime = QDateTime::currentSecsSinceEpoch(); pFormatCtx->interrupt_callback.callback = [](void *ctx) -> int { - uint64_t now = QDateTime::currentDateTime().toSecsSinceEpoch(); + uint64_t now = QDateTime::currentSecsSinceEpoch(); return now - *(uint64_t *)ctx > timeout; }; pFormatCtx->interrupt_callback.opaque = startTime.get(); @@ -45,7 +45,7 @@ bool FFmpegDecoder::OpenInput(string &inputFile) { } // 分析超时,退出,可能格式不正确 - if (QDateTime::currentDateTime().toSecsSinceEpoch() - *startTime > timeout) { + if (QDateTime::currentSecsSinceEpoch() - *startTime > timeout) { CloseInput(); return false; } @@ -182,7 +182,6 @@ shared_ptr FFmpegDecoder::GetNextFrame() { } bool FFmpegDecoder::hwDecoderInit(AVCodecContext *ctx, const enum AVHWDeviceType type) { - if (av_hwdevice_ctx_create(&hwDeviceCtx, type, nullptr, nullptr, 0) < 0) { return false; } @@ -213,7 +212,6 @@ bool FFmpegDecoder::OpenVideo() { if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && config->device_type == hwDecoderType) { hwPixFmt = config->pix_fmt; - isHwDecoderEnable = true; break; } } @@ -225,6 +223,7 @@ bool FFmpegDecoder::OpenVideo() { if (isHwDecoderEnable) { isHwDecoderEnable = hwDecoderInit(pVideoCodecCtx, hwDecoderType); } + if (avcodec_parameters_to_context(pVideoCodecCtx, pFormatCtx->streams[i]->codecpar) >= 0) { res = !(avcodec_open2(pVideoCodecCtx, codec, nullptr) < 0); if (res) { @@ -247,25 +246,28 @@ bool FFmpegDecoder::OpenVideo() { return res; } -bool FFmpegDecoder::DecodeVideo(const AVPacket *avpkt, shared_ptr &pOutFrame) { +bool FFmpegDecoder::DecodeVideo(const AVPacket *av_pkt, shared_ptr &pOutFrame) { bool res = false; - if (pVideoCodecCtx && avpkt && pOutFrame) { - int ret = avcodec_send_packet(pVideoCodecCtx, avpkt); + if (pVideoCodecCtx && av_pkt && pOutFrame) { + int ret = avcodec_send_packet(pVideoCodecCtx, av_pkt); if (ret < 0) { char errStr[AV_ERROR_MAX_STRING_SIZE]; av_strerror(ret, errStr, AV_ERROR_MAX_STRING_SIZE); throw runtime_error("发送视频包出错 " + string(errStr)); } - if (isHwDecoderEnable && !hwFrame) { - hwFrame = shared_ptr(av_frame_alloc(), &freeFrame); - } if (isHwDecoderEnable) { + // Initialize the hardware frame. + if (!hwFrame) { + hwFrame = shared_ptr(av_frame_alloc(), &freeFrame); + } + ret = avcodec_receive_frame(pVideoCodecCtx, hwFrame.get()); } else { ret = avcodec_receive_frame(pVideoCodecCtx, pOutFrame.get()); } + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { // No output available right now or end of stream res = false; @@ -277,17 +279,20 @@ bool FFmpegDecoder::DecodeVideo(const AVPacket *avpkt, shared_ptr &pOut // Successfully decoded a frame res = true; } + if (isHwDecoderEnable) { if (dropCurrentVideoFrame) { pOutFrame.reset(); return false; } - if ((ret = av_hwframe_transfer_data(pOutFrame.get(), hwFrame.get(), 0)) < 0) { - if (ret < 0) { - char errStr[AV_ERROR_MAX_STRING_SIZE]; - av_strerror(ret, errStr, AV_ERROR_MAX_STRING_SIZE); - throw runtime_error("Decode video frame error. " + string(errStr)); - } + + // Copy data from the hw surface to the out frame. + ret = av_hwframe_transfer_data(pOutFrame.get(), hwFrame.get(), 0); + + if (ret < 0) { + char errStr[AV_ERROR_MAX_STRING_SIZE]; + av_strerror(ret, errStr, AV_ERROR_MAX_STRING_SIZE); + throw runtime_error("Decode video frame error. " + string(errStr)); } } } diff --git a/src/player/ffmpegDecode.h b/src/player/ffmpegDecode.h index a6f46a0..1ffcfe8 100644 --- a/src/player/ffmpegDecode.h +++ b/src/player/ffmpegDecode.h @@ -172,7 +172,7 @@ class FFmpegDecoder { enum AVPixelFormat hwPixFmt; AVBufferRef *hwDeviceCtx = nullptr; volatile bool dropCurrentVideoFrame = false; - // 初始化硬件解码frame + // Hardware frame shared_ptr hwFrame; };