0

生の H.264 フレーム データを QUdpSocket データグラムから FFMPEG に渡すカスタム I/O レイヤーを作成しようとしています。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 呼び出しがありませんか? 誰かが私が間違っているかもしれない何かを見ることができますか?

4

1 に答える 1

0

これは単なる推測ですが、TCP ではなく UDP を使用しているために問題が発生する可能性があります。問題は、UDP の信頼性が低く、パケットが失われたり、重複したり、順不同で到着したりする可能性があることです。また、パケットがフレームに対応していない場合があります。そのため、フレームの断片や文字化けした情報を取得する可能性があります。私はffmpegがそれをうまく処理するとは思わない。

ウィキペディアから:

UDP は、信頼性、順序付け、またはデータの整合性を提供するために、暗黙的なハンドシェーク ダイアログを使用しない単純な伝送モデルを使用します。したがって、UDP は信頼性の低いサービスを提供し、データグラムが順不同で到着したり、重複しているように見えたり、通知なしに失われたりする可能性があります。UDP は、エラーのチェックと修正が不要であるか、アプリケーションで実行されると想定し、ネットワーク インターフェイス レベルでのそのような処理のオーバーヘッドを回避します。

そのため、代わりに TCP を使用してみて、それが機能するかどうかを確認してください。TCP は、送信したものを正確に受信することを保証する必要があるため、出力をローカルで ffmpeg にパイプすることと変わらないはずです。

于 2012-04-19T20:24:07.350 に答える