c++ - 使用 ffmpeg 的 avcodec_receive_frame() 以及为什么有时会在解码图像中得到这些垂直线
问题描述
我正在使用现代 ffmpeg API,它指示我使用avcodec_send_packet
和avcodec_receive_frame
. github中几乎没有使用示例,因此我无法与其他代码进行比较。
我的代码有点工作,但有时,不到一两秒,视频就会像这样解码:
我认为这是一个缓冲区大小问题,所以我从
const size_t bufferSize = 408304;
至
const size_t bufferSize = 10408304;
只是看看,但问题仍然存在。
(视频尺寸为 1920x1080,即使屏幕几乎没有运动也会发生这种情况)
这是我的解码器类,它将解码后的数据在线发送到 OpenGL
this->frameUpdater->updateData(avFrame->data, avFrame->width, avFrame->height);
void FfmpegDecoder::decodeFrame(uint8_t* frameBuffer, int frameLength)
{
if (frameLength <= 0) return;
int frameFinished = 0;
AVPacket* avPacket = av_packet_alloc();
if (!avPacket) std::cout << "av packet error" << std::endl;
avPacket->size = frameLength;
avPacket->data = frameBuffer;
//Disable ffmpeg annoying output
av_log_set_level(AV_LOG_QUIET);
int sendPacketResult = avcodec_send_packet(avCodecContext, avPacket);
if (!sendPacketResult) {
int receiveFrameResult = avcodec_receive_frame(avCodecContext, avFrame);
if (!receiveFrameResult) {
this->frameUpdater->updateData(avFrame->data, avFrame->width, avFrame->height);
} else if ((receiveFrameResult < 0) && (receiveFrameResult != AVERROR(EAGAIN)) && (receiveFrameResult != AVERROR_EOF)) {
std::cout << "avcodec_receive_frame returned error " << receiveFrameResult /*<< *av_err2str(result).c_str()*/ << std::endl;
} else {
switch (receiveFrameResult) {
//Not exactly an error, we just have to wait for more data
case AVERROR(EAGAIN):
break;
//To be done: what does this error mean? I think it's literally the end of an mp4 file
case AVERROR_EOF:
std::cout << "avcodec_receive_frame AVERROR_EOF" << std::endl;
break;
//To be done: describe what error is this in std cout before stopping
default:
std::cout << "avcodec_receive_frame returned error, stopping..." << receiveFrameResult /*<< av_err2str(result).c_str()*/ << std::endl;
break;
//Error happened, should break anyway
break;
}
}
} else {
switch (sendPacketResult) {
case AVERROR(EAGAIN):
std::cout << "avcodec_send_packet EAGAIN" << std::endl;
break;
case AVERROR_EOF:
std::cout << "avcodec_send_packet AVERROR_EOF" << std::endl;
break;
default:
break;
}
}
}
我认为知道解码如何工作的人可能会立即知道为什么图像会这样解码。知道为什么会很有帮助。谢谢!
解决方案
推荐阅读
- javascript - React 对象作为 React 子对象无效
- java - SpringBatch 在步骤之间共享大量数据
- r - 应用函数从其他列表的元素中提取随机样本
- google-apps-script - 通过应用程序脚本从 Google 文档中删除文本不起作用
- vba - 使用 VBA 创建过程宏
- c# - 是否可以使用 Appium C# 测试跨平台移动应用程序?
- laravel - orwhereNotIn() 雄辩
- php - laravel 护照在 laravel 5.8 中不起作用
- bash - 从 Bash 的读取命令中检查空字符
- google-sheets - 在谷歌表格的两个标签中识别相同的单词