Skip to content

Commit

Permalink
Fix hw decode
Browse files Browse the repository at this point in the history
  • Loading branch information
floppyhammer committed Dec 10, 2024
1 parent 9c4a80d commit 3692af8
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 19 deletions.
41 changes: 23 additions & 18 deletions src/player/ffmpegDecode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -32,9 +32,9 @@ bool FFmpegDecoder::OpenInput(string &inputFile) {
// 超时机制
static const int timeout = 10;
auto startTime = std::make_shared<uint64_t>();
*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();
Expand All @@ -45,7 +45,7 @@ bool FFmpegDecoder::OpenInput(string &inputFile) {
}

// 分析超时,退出,可能格式不正确
if (QDateTime::currentDateTime().toSecsSinceEpoch() - *startTime > timeout) {
if (QDateTime::currentSecsSinceEpoch() - *startTime > timeout) {
CloseInput();
return false;
}
Expand Down Expand Up @@ -182,7 +182,6 @@ shared_ptr<AVFrame> FFmpegDecoder::GetNextFrame() {
}

bool FFmpegDecoder::hwDecoderInit(AVCodecContext *ctx, const enum AVHWDeviceType type) {

if (av_hwdevice_ctx_create(&hwDeviceCtx, type, nullptr, nullptr, 0) < 0) {
return false;
}
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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) {
Expand All @@ -247,25 +246,28 @@ bool FFmpegDecoder::OpenVideo() {
return res;
}

bool FFmpegDecoder::DecodeVideo(const AVPacket *avpkt, shared_ptr<AVFrame> &pOutFrame) {
bool FFmpegDecoder::DecodeVideo(const AVPacket *av_pkt, shared_ptr<AVFrame> &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<AVFrame>(av_frame_alloc(), &freeFrame);
}

if (isHwDecoderEnable) {
// Initialize the hardware frame.
if (!hwFrame) {
hwFrame = shared_ptr<AVFrame>(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;
Expand All @@ -277,17 +279,20 @@ bool FFmpegDecoder::DecodeVideo(const AVPacket *avpkt, shared_ptr<AVFrame> &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));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/player/ffmpegDecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class FFmpegDecoder {
enum AVPixelFormat hwPixFmt;
AVBufferRef *hwDeviceCtx = nullptr;
volatile bool dropCurrentVideoFrame = false;
// 初始化硬件解码frame
// Hardware frame
shared_ptr<AVFrame> hwFrame;
};

Expand Down

0 comments on commit 3692af8

Please sign in to comment.