- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 C++ 源代码,使用 libavcodec 解码 h264 rtsp 流帧。此源代码是使用 ffmpeg 1.1 编写的。现在,当我升级到 ffmpeg 3.3 时,除了解码帧不起作用之外,一切似乎都正常工作。在旧版本中,我使用的是 avcodec_decode_video2。升级后,avcodec_decode_video2 始终将 got_picture 设置为 0,返回值等于输入数据包的大小(这意味着使用了所有数据)。并且永远不会解码帧。我还删除了 avcodec_decode_video2 并使用 avcodec_send_packet 和 avcodec_receive_frame 完成解码,但 avcodec_send_packet 始终返回 0,而 avcodec_receive_frame 始终返回 -11 (EAGAIN)。
这是我用来解码的代码:
#include "stdafx.h"
#include <stdlib.h>
#include <string>
#include <iostream>
using namespace std;
extern "C"{
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
#include "libavutil/pixfmt.h"
}
int extraDataSize;
static const int MaxExtraDataSize = 1024;
uint8_t extraDataBuffer[MaxExtraDataSize];
void AddExtraData(uint8_t* data, int size)
{
auto newSize = extraDataSize + size;
if (newSize > MaxExtraDataSize){
throw "extradata exceeds size limit";
}
memcpy(extraDataBuffer + extraDataSize, data, size);
extraDataSize = newSize;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::string strFramesPath("g:\\frames\\");
AVCodec* avCodec;
AVCodecContext* avCodecContext;
AVFrame* avFrame;
AVCodecID codecId = AV_CODEC_ID_H264;
unsigned char sprops_part_1[9] = { 0x27, 0x42, 0x80, 0x1f, 0xda, 0x02, 0xd0, 0x49, 0x10 };
unsigned char sprops_part_2[4] = { 0x28, 0xce, 0x3c, 0x80 };
av_register_all();
avcodec_register_all();
avCodec = avcodec_find_decoder(codecId);
avCodecContext = avcodec_alloc_context3(avCodec);
if (!avCodecContext)
{
cout << "avcodec_alloc_context3 failed." << endl;
return 0;
}
uint8_t startCode[] = { 0x00, 0x00, 0x01 };
// sprops
{
// sprops 1
AddExtraData(startCode, sizeof(startCode));
AddExtraData(sprops_part_1, 9);
// sprops 2
AddExtraData(startCode, sizeof(startCode));
AddExtraData(sprops_part_2, 4);
avCodecContext->extradata = extraDataBuffer;
avCodecContext->extradata_size = extraDataSize;
}
AddExtraData(startCode, sizeof(startCode));
avCodecContext->flags = 0;
if (avcodec_open2(avCodecContext, avCodec, NULL) < 0)
{
cout << "failed to open codec" << endl;
return 0;
}
avFrame = av_frame_alloc();
if (!avFrame)
{
cout << "failed to alloc frame" << endl;
return 0;
}
void *buffer = malloc(100 * 1024); // 100 KB buffer - all frames fit in this buffer
for (int nFrameIndex = 0; nFrameIndex < 257; nFrameIndex++)
{
std::string strFilename = std::string("g:\\frames\\" + std::to_string(nFrameIndex));
FILE* f = fopen(strFilename.c_str(), "rb");
fseek(f, 0, SEEK_END);
long nFileSize = ftell(f);
fseek(f, 0, SEEK_SET);
size_t nReadSize = fread(buffer, 1, nFileSize, f);
// cout << strFilename << endl;
if (nReadSize != nFileSize)
{
cout << "Error reading file data" << endl;
continue;
}
AVPacket avpkt;
avpkt.data = (uint8_t*)buffer;
avpkt.size = nReadSize;
while (avpkt.size > 0)
{
int got_frame = 0;
auto len = avcodec_decode_video2(avCodecContext, avFrame, &got_frame, &avpkt);
if (len < 0) {
//TODO: log error
cout << "Error decoding - error code: " << len << endl;
break;
}
if (got_frame)
{
cout << "* Got 1 Decoded Frame" << endl;
}
avpkt.size -= len;
avpkt.data += len;
}
}
getchar();
return 0;
}
测试帧数据可以从这个链接下载: Frames.zip (~3.7MB)
我使用了来自 Builds - Zeranoe FFmpeg 的 Windows 版本如果将此代码复制粘贴到 IDE 中,代码将成功编译。使用 libavcodec 新版本,没有帧被解码。使用旧版本的 libavcodec (20141216-git-92a596f),在输入帧 2 时开始解码。
有什么想法吗?
最佳答案
FFmpeg/libAV 的描述相当复杂,就可理解性而言可能不是最好的(如果不是说它很糟糕的话)。你应该仔细阅读它。
但是,您缺少的是使用 av_init_packet
初始化 AVPacket
。或者使用 av_packet_alloc()
来创建将初始化数据包的数据包(并且更好地复制它以进行编码)。
// code ...
AVPacket avpkt;
av_init_packet(&avpkt); // initialize packet
avpkt.data = (uint8_t*)buffer;
avpkt.size = nReadSize;
// code ...
或
// code ...
AVPacket* avpkt = av_packet_alloc();
avpkt->data = (uint8_t*)buffer;
avpkt->size = nReadSize;
// use ...
auto len = avcodec_decode_video2(avCodecContext, avFrame, &got_frame, avpkt);
使用 av_packet_alloc()
在代码中也更加一致,因为您还使用 AVFrame
作为指针。
记得把packets/frames/pictures也一起free,不然会内存泄露。
还有 here是一个(或多或少)好的/“最新”的 ffmpeg 教程。
关于c++ - 从 ffmpeg 1.1 升级到 3.3 后没有帧解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50113717/
我几乎不敢在这里问这个问题,因为它似乎应该很容易通过谷歌或 ravendb.net 获得。但是,我一直很难找到将我的 RavenDB 升级到新版本的正确方法。我目前正在运行 573 版并希望升级到 6
这周我需要升级当前版本的 DNN。我目前使用的是 2.1.1。我不想每件事都做两次,所以,我有几个问题。 是否有升级工具或某些脚本可以帮助我进行升级。 我最好安装 4.9 还是 5.0。这是生产。 如
将 Sugarcrm 从 6.2 升级到 6.3 版本时遇到问题。当我升级本地 Sugarcrm 安装时,它可以工作,但是当我开始升级我的 Sugarcrm 6.2 站点并上传升级包时,它不会上传。
有没有办法绕过 Meteor 的自动更新功能?我坚持 Downloading meteor-tool@1.3.0_3... \ 当我尝试运行现有项目,或创建一个新项目或只是运行“
我已将应用内集成到我的 Andorid 应用程序中,用于单个产品 productone。 为此,我在我的 Google Play 控制台中创建了不同的产品 ID,如下所示: 1。 productone
我在将 TeamCity 版本 2017.1.1 升级到 2017.1.2 时遇到问题。这个问题涉及 TeamCity 和 PostgreSQL 的工作。我的工作: 停止 teamcity 进程 /e
我寻找了这个问题的具体答案,但找不到——即使是在 WAMPSERVER 网站上也是如此。我确定我忽略了它。 我有 Wampserver 2.0、MySQL 5.0.51b、PHP 5.2.6 和 Ap
我使用 Ubuntu 软件中心默认的 Eclipse 3.7。 我想将 Eclipse 升级到 kepler 版本,所以我添加了 repository 我收到以下错误消息: Cannot comple
你好 我只想安装 mercurial,但对于它需要 python 2.6 的所有版本,我尝试使用 .rpm 文件,但我唯一得到的是很多充满错误的行,它告诉我:需要安装在 2.6 之前和 2.5 之后的
我完全知道 Gradle 网站上有一些页面说明了如何升级,但仅限于 4.x 及更高版本。 我正在尝试关注 tutorial制作一个简单的“我的第一个”Minecraft 模组。在其中,您被告知安装 f
我们想升级 Kerberos(服务器和客户端) 当前:1.6.3-133.27.1 目标:1.6.3-133.49.97.1 问题是如果我们用包管理器升级它,下面会发生什么? KDC 数据库 所有主要
背景 原计划 2019 年发布的 Vue3,又经过一年的再次打磨,终于于去年 9 月正式发布。随后,不少 UI 组件库都积极参与适配,去年 12 月,Element-plus(
我有一个版本为 2.3.4 的 grails 项目,我需要尽可能升级到最新版本。查看文档我意识到从 2.x 到 3.x 有巨大的变化。 问题是:从 2 到 3、从 3 到 4、从 4 到 5 逐步升级
我正在将 API 项目从 .net5 升级到 .net6 它以前工作,现在它崩溃 内部异常消息“抛出了‘Unity.Exceptions.InvalidRegistrationException’类型
我将我的项目从 expo 44 升级到 expo 45,现在我有无数这样的错误: The module 'MaterialIcons' can't be used as JSX component.
我已经升级了掌 Helm 模板(手动) 以前的片段depoloyment.yaml : apiVersion: apps/v1beta2 kind: Deployment metadata: na
我正在尝试将我的 Scala Play Framework 应用程序升级到 2.8,这涉及将 SBT 升级到 1.x。 在我的 build.propeties 我有 sbt.version=1.3.5
我想在我的 Windows 服务器上安装 PHPUnit 3.7。我遵循了各种说明 here并以 PHPUnit 3.4.1 结束。当我尝试使用以下方法再次安装它时: pear update chan
Microsoft.Net 4.5 即将推出,我想在 MS 发布最终版本时升级我的 clickonce 应用程序。 我的问题是:已经安装了 clickonce 应用程序(使用 .net 4.0)的用户
为了将 Angular 8 更新到 9,我正在按照官方文档升级。 这建议首先更新到最新版本的 angular 8,例如: ng update @angular/core@8 @angular/cli@
我是一名优秀的程序员,十分优秀!