软解码和软编码时都没问题,换成硬解码之后,程序一直卡在avcodec_receive_frame这里,一直返回-11
std::cout << output <<std::endl;
while (av_read_frame(fmt_ctx, &avpkt) >= 0) {
if (avpkt.stream_index == stream_index) {
// 8 发送等待解码帧
int re = avcodec_send_packet(codeCtx, &avpkt);
if (re < 0) {
continue;
}
std::cout << 1 << std::endl;
// 9 接收解码后frame数据
std::cout << avcodec_receive_frame(codeCtx, frame) << std::endl;
while (avcodec_receive_frame(codeCtx, frame) == 0) {
// 拼接图片路径、名称,测试输出用
snprintf(buf, sizeof(buf), "%s/Demo-%d.jpg", output, frame_count++);
std::cout << 2 << std::endl;
width = frame->width;
height = frame->height;
Encode2Jpg(frame); //保存为jpg图片
}
// 测试从内存读数据到文件里是否正常
FILE *fp = fopen(buf,"wb");
fwrite(bd_out.ptr, sizeof(char), bd_out.size, fp);
fclose(fp);
}
av_packet_unref(&avpkt);
}
这个问题可能是由于在硬解码模式下,解码器需要更多的时间来处理数据,因此在调用avcodec_receive_frame时可能会返回EAGAIN(-11)错误,表示解码器需要更多的输入数据才能产生输出帧。
你可以尝试修改你的代码,当avcodec_receive_frame返回-11时,再次发送数据到解码器,直到avcodec_receive_frame返回0,表示成功接收到解码后的帧。你可以尝试以下修改后的代码:
while (av_read_frame(fmt_ctx, &avpkt) >= 0) {
if (avpkt.stream_index == stream_index) {
// 8 发送等待解码帧
int re = avcodec_send_packet(codeCtx, &avpkt);
if (re < 0) {
continue;
}
std::cout << 1 << std::endl;
// 9 接收解码后frame数据
int ret;
while ((ret = avcodec_receive_frame(codeCtx, frame)) == 0) {
// 拼接图片路径、名称,测试输出用
snprintf(buf, sizeof(buf), "%s/Demo-%d.jpg", output, frame_count++);
std::cout << 2 << std::endl;
width = frame->width;
height = frame->height;
Encode2Jpg(frame); //保存为jpg图片
}
if (ret == AVERROR(EAGAIN)) {
// 解码器需要更多数据,继续发送数据
continue;
} else if (ret < 0) {
// 其他错误
break;
}
// 测试从内存读数据到文件里是否正常
FILE *fp = fopen(buf,"wb");
fwrite(bd_out.ptr, sizeof(char), bd_out.size, fp);
fclose(fp);
}
av_packet_unref(&avpkt);
}
这样修改后,当解码器需要更多的输入数据时,会继续发送数据,直到成功接收到解码后的帧。
avcodec_receive_frame返回-11的错误代码是EAGAIN。这种情况通常表示当前没有可用的输出帧,需要发送更多的输入数据。您可以尝试增加更多的输入数据以及等待更长的时间,以等待解码器输出可用的帧。同时,您也可以检查解码器的设置是否正确,并且可能需要升级您的硬件设备以提高计算能力和内存速度。
这段代码中的问题可能是在接收解码后frame数据时,使用了两次avcodec_receive_frame函数,而且没有检查返回值。您可以尝试修改代码如下:
std::cout << output <<std::endl;
while (av_read_frame(fmt_ctx, &avpkt) >= 0) {
if (avpkt.stream_index == stream_index) {
// 8 发送等待解码帧
int re = avcodec_send_packet(codeCtx, &avpkt);
if (re < 0) {
continue;
}
std::cout << 1 << std::endl;
// 9 接收解码后frame数据
while (true) {
int ret = avcodec_receive_frame(codeCtx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
}
if (ret < 0) {
std::cerr << "Error while receiving a frame from the decoder: " << av_err2str(ret) << std::endl;
exit(1);
}
// 拼接图片路径、名称,测试输出用
snprintf(buf, sizeof(buf), "%s/Demo-%d.jpg", output, frame_count++);
std::cout << 2 << std::endl;
width = frame->width;
height = frame->height;
Encode2Jpg(frame); //保存为jpg图片
// 测试从内存读数据到文件里是否正常
FILE *fp = fopen(buf,"wb");
fwrite(bd_out.ptr, sizeof(char), bd_out.size, fp);
fclose(fp);
}
}
av_packet_unref(&avpkt);
}
这样可以避免多次调用avcodec_receive_frame函数,同时也增加了对函数返回值的检查。
根据参考资料和问题描述,可以初步得出以下结论:
针对这个问题,可能需要对以下方面进行排查和处理:
因为这个问题涉及到具体的硬件设备、FFmpeg版本和代码实现,需要更多的信息和具体的排查过程才能够找到问题的根本原因并提供解决方案。在此无法提供具体的代码实现和解决方案,建议结合具体的场景和资料逐个排查和分析,找到问题后再进行相应的解决方案。