使用QUdpSocket进行自定义FFMPEG I / O(原始H.264)

时间:2012-04-19 04:05:21

标签: c++ qt ffmpeg udp h.264

我正在尝试创建一个自定义I / O层,以便将原始H.264帧数据从QUdpSocket数据报传递到FFMPEG。 H.264帧没有任何类型的容器,只是从帧抓取设备流式传输。出现问题,因为出于某种原因,当我调用avcodec_decode_video2()时,FFMPEG认为访问单元的大小为1:

[h264 @ 0x1030dd000] missing picture in access unit with size 1
[h264 @ 0x1030dd000] no frame!

我的第一步是探测AVInputFormat的第一帧:

socket->readDatagram(datagram.data(), datagram.size());

AVProbeData probeData;
probeData.filename = udpUrl.toStdString().c_str();
probeData.buf_size = datagram.size() + AVPROBE_PADDING_SIZE;
probeData.buf = (unsigned char *)malloc(datagram.size() + AVPROBE_PADDING_SIZE);
memcpy(&probeData.buf[AVPROBE_PADDING_SIZE], datagram.data(), datagram.size());

inputFormat = av_probe_input_format(&probeData, 1);

接下来我分配一个AVIOContext:

buffer = (unsigned char *)malloc(bufferSize);
ioContext = avio_alloc_context(buffer, bufferSize, 0, socket, &readFrame, NULL, NULL);

之后我调用avformat_open_input_stream():

if (av_open_input_stream(&formatContext, ioContext, "", inputFormat, NULL) != 0)

这似乎成功回归。但是,视频流缺少重要信息,如宽度,高度和像素格式,这会导致av_find_stream_info()失败。我可以手动设置这些参数,但它不会导致成功解码,这让我想知道我还缺少什么。

据我所知,NAL单位完好无损:

First Frame
00:00:00:01:27:64:00:28:ad:84:09:26:6e:23:34:90:81:24:cd:c4:66:92:10:24:99:b8:8c:d2:42:04:93:37:11:9a:48:40:92:66:e2:33:49:08:12:4c:dc:46:69:21:05:5a:eb:d7:d7:e4:fe:bf:27:d7:ae:b5:50:82:ad:75:eb:eb:f2:7f:5f:93:eb:d7:5a:ab:40:50:1e:c8:
00:00:00:01:28:ee:3c:b0:
00:00:00:01:25:88:84:27:...

Second Frame
00:00:00:01:21:9a:59:15:...

我错过了API调用吗?任何人都可以看到我可能做错的事情吗?

1 个答案:

答案 0 :(得分:0)

这只是猜测,但问题可能是因为您使用的是UDP而不是TCP。问题是UDP不可靠,数据包可能丢失,重复或无序到达。数据包可能与帧不对应。所以你可能会得到一些零碎的帧和乱码信息。我不认为ffmpeg会处理得那么好。

来自维基百科:

  

UDP使用简单的传输模型,没有隐式握手   用于提供可靠性,排序或数据完整性的对话。   因此,UDP提供不可靠的服务,并且数据报可能会到达   订单,出现重复或丢失,恕不另行通知。 UDP假定   错误检查和纠正是不必要的或   在应用程序中执行,避免了这种处理的开销   在网络接口级别

所以也许你应该尝试使用TCP,看看它是否有效。 TCP应确保您收到您发送的内容,因此它不应与将输出本地传输到ffmpeg不同。