gpt4 book ai didi

c# - 无法使用 FFmpeg 解码 H.264 流(附件 B)

转载 作者:行者123 更新时间:2023-11-30 18:30:46 33 4
gpt4 key购买 nike

最近我在写一个提供H.264流的网络摄像机的客户端。我现在正在使用 FFmpeg 2.1.1 来解码相机提供的流。

这是应用程序的一些代码:

初始化:

    private unsafe void InitFFmpeg()
{
FFmpeg.avcodec_register_all();
var codec = FFmpeg.avcodec_find_decoder(AVCodecID.AV_CODEC_ID_H264);
avcodec = (IntPtr)codec;

var ctx=FFmpeg.avcodec_alloc_context3(avcodec);
avcontext = (IntPtr)ctx;

ctx->codec = avcodec;
ctx->pix_fmt = AVPixelFormat.PIX_FMT_YUV420P;
ctx->flags2 |= 0x00008000;//CODEC_FLAG2_CHUNKS

var options = IntPtr.Zero;
int result = FFmpeg.avcodec_open2(avcontext, avcodec, ref options);
avframe = FFmpeg.av_frame_alloc();
avparser = FFmpeg.av_parser_init(AVCodecID.AV_CODEC_ID_H264);
FFmpeg.av_init_packet(ref avpacket);
inBuffer = Marshal.AllocHGlobal(300 * 1024);
}

解码:

    private void Decode(byte[] data, int size)
{
IntPtr pOut = IntPtr.Zero;
int outLen = 0;

Marshal.Copy(data, 0, inBuffer, size);

int gotPicture = 0;

var rs = FFmpeg.av_parser_parse2(avparser, avcontext, ref pOut, ref outLen, inBuffer, size, 0, 0, 0);
if (outLen <= 0 || pOut.ToInt32() <= 0)
{
//no enough data to construct a frame, return and receive next NAL unit.
return;
}
avpacket.data = pOut;
avpacket.size = outLen;
avpacket.flags |= PacketFlags.Key;
var len = FFmpeg.avcodec_decode_video2(avcontext, avframe, ref gotPicture, ref avpacket);
Console.WriteLine("avcodec_decode_video2 returned " + len);
if (gotPicture != 0)
{
//some YUV to RGB stuff
}
}

使用上面的代码,我可以获得如下输出:

NAL unit 1: resolution=1280x720, key-frame=True, size=26.
NAL unit 2: resolution=1280x720, key-frame=False, size=8.
NAL unit 3: resolution=1280x720, key-frame=False, size=97222.
NAL unit 4: resolution=1280x720, key-frame=False, size=14129.
avcodec_decode_video2 returned 1
NAL unit 5: resolution=1280x720, key-frame=False, size=12522.
NAL unit 6: resolution=1280x720, key-frame=False, size=12352.
avcodec_decode_video2 returned 1
NAL unit 7: resolution=1280x720, key-frame=False, size=12291.
NAL unit 8: resolution=1280x720, key-frame=False, size=12182.

从输出中我可以看到解析器可以识别相机发送的 NAL 单元并可以从中构建帧。

NAL单元1到4是包含SPS/PPS的关键帧的分片,后面的2个NAL单元组成一个普通帧。

而 avcodec_decode_video2 函数不会产生任何错误,只是一直返回 1 并且 gotPicture 始终为 0。

如果我清除 AVCodecContext.flags2,它会开始提示我提供的数据包不包含帧:

NAL unit 100: resolution=1280x720, frame-rate=0, key-frame=True, size=26.
NAL unit 101: resolution=1280x720, frame-rate=0, key-frame=False, size=8.
NAL unit 102: resolution=1280x720, frame-rate=0, key-frame=False, size=96927.
NAL unit 103: resolution=1280x720, frame-rate=0, key-frame=False, size=17149.
[h264 @ 01423440] no frame!
avcodec_decode_video2 returned -1094995529
NAL unit 104: resolution=1280x720, frame-rate=0, key-frame=False, size=12636.
NAL unit 105: resolution=1280x720, frame-rate=0, key-frame=False, size=12338.
[h264 @ 01423440] no frame!

如果我将原始流写入文件,我可以使用 FFmpeg 将流复用到 mp4 容器,并且可以用任何播放器播放 mp4 文件。

我收到的原始数据是这样的:

00 00 00 01 67 42 00 28 E9 00 A0 0B 75 C4 80 03 6E E8 00 CD FE 60 0D 88 10 94
00 00 00 01 68 CE 31 52
00 00 00 01 65 88 81 00 06 66 36 25 11 21 2C 04 3B 81 E1 80 00 85 4B 23 9F 71...
...

最佳答案

我创建了 libavcodec 的调试版本并进行了一些调试。我发现我使用的是早期版本的 AVPacket 结构,因此传递给解码器的数据格式不正确。我根据头文件编写了一个新版本的 AVPacket,现在它运行起来非常棒。

关于c# - 无法使用 FFmpeg 解码 H.264 流(附件 B),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21136913/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com