【映像・音声プログラミング学習】B局RTMPプッシュストリーム「映像トラックパースエラー」問題解決

発生した問題:

Wireshark を使用して、成功した rtmp パケットと失敗した rtmp パケットを分析し、最初に成功した videoData にはデータがあり、最初に失敗した videoData にはデータがないことを確認します。

成功:

ここに画像の説明を挿入

失敗:

ここに画像の説明を挿入

ここに問題はありますか?

調査中は、次のブログを参照してください。

rtmp プロトコルの詳細を手で引き裂く、このシリーズは非常に優れた基本的なものです

rtmp プロトコルは tcp ベースのアプリケーション レイヤ プロトコルであるため、3 ウェイ ハンドシェイクが行われ、tcp が確立された後、rtmp プロトコル レベルのハンドシェイクが実行されます。

ハンドシェイク プロセスは主に 2 つのタスクを完了します。1つは rtmp のバージョンを確認することで、もう 1 つはネットワーク ステータス検出のためにランダム データを送信することです。

Rtmpプロトコルのハンドシェイクが完了した後、データのやり取りを行うことができますが、交換されるデータ形式には組織の標準が必要です.送信者は標準に従ってデータを組み立て、受信者は標準に従ってデータを分解します.通信を完了します。

  • rtmp ヘッダー

  • rtmp本体

最初に createStream メッセージを見てみましょう. RTMP クライアントは、このメッセージをサーバーに送信して、メッセージ通信用の論理チャネルを作成します。オーディオ、ビデオ、およびメタデータはすべて createStream によって作成されたデータ チャネルを介してやり取りされ、 releaseStream は createStream に対応します这个问题也困扰了我,让我一度怀疑是否是这里的问题これは、多くのサービス実装と同様に、最初に停止が実行され、次に開始が実行されます。新しいプロセスを開始するたびに、前のプロセスが正常に完了したかどうか、異常な状況が発生したかどうか、異常な状況が処理されたかどうかなどを確認できないため、初期状態に戻すのと同様の操作を行う必要があります。 、 releaseStream はこの効果です。ここに画像の説明を挿入

上の図のように、多くの rtmp パケットがまとめられており、どれがそこにあるかを確認するにはクリックして開く必要があり、クリックしないと createStream は表示されません。ここに画像の説明を挿入

ここで、ストリームをプッシュするために必要なパブリッシュがあることがわかります.ストリームをプルするプロセスがある場合は、 play があるはずです.

Rtmp のビデオ パッケージの紹介

RTMP ライブ ストリーミング - ショート ブック (jianshu.com)

h264 手動で sps と pps を AVCodecContext->extradata に追加します

H264–4--H264 エンコーディング

ビッグデータ】 FFmepg AV_CODEC_FLAG_GLOBAL_HEADER 問題解説

そこで、これらの記事を検索したところ、この記事RTMP ライブ ストリーミング - Jianshu (jianshu.com)で同じ問題が見つかりました。! !

原来在调用avformat_write_header之前,就要把sps跟pps传入

1 つ目は、sps と pps の導入です。

シーケンス パラメータ セット (SPS) と画像パラメータ セット (PPS)

H264 の場合、SPS はエンコード後の最初のフレームです。読み込まれた H264 ファイルの場合、最初のフレーム区切り文字と 2 番目のフレーム区切り文字の間のデータの長さは 4 です。

PPS はエンコード後の2 フレーム目であり、読み込んだ H264 ファイルの場合、2 フレーム区切りから 3 フレーム区切りまでのデータ長は不定です。

nalu のヘッダーでは、67 の後には sps、68 の後には pps が続くと規定されています. 高さと幅の具体的な値についてはこれ以上述べません. インターネットで関連するコンテンツを見つけることができます.あなたはこれについてもっと知っています、あなたはできます直接手書き sps_pps 配列(強くお勧めしません

AMF エンコーディング形式は、Adobe のエンコーディング形式です。

次に、問題の症状があります。

ステーション b のプレーヤー ログでは、最初に video track parse error が表示され、その後に firstFrame timeout が表示されていることから、最初の videoData に問題があると判断でき、プレーヤー情報に情報はありません。 、プレーヤーが必要なビデオ データを取得していないことを示します。

[外部リンクの画像転送に失敗しました。ソース サイトには盗難防止リンク メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします。ここに画像の説明を挿入

Douyu と Huya を比較した結果、プレイできない現象はプレイヤーにも関係していることがわかりました. Douyu のプレイヤーのように選択しないプレイヤーもいます. 最初のプレイヤーが sps と pps の情報を持っているかどうかは問題ではありません.奇妙で、さらに奇妙なのは Huya です。Huya はストリームを受信し、ネットワークでデータを要求し続けます。ステーション b とは異なり、解放することはできません。プレイヤーがエラーを解析すると、プレイヤーはリクエストとクロスドメイン リクエストを繰り返します。

ここに画像の説明を挿入

ビッグデータ] FFmepg AV_CODEC_FLAG_GLOBAL_HEADER 問題の説明、この記事では、デフォルトで、AVCodecContext エクストラデータは、
コード ストリーム (avformat_find_stream_info) を検出すると、SPS と PPS をエクストラデータ文字列に自動的に入力し、avcodec_parameters_to_context 関数を介して codecpar コンテンツを AVCodecContext に渡します。アプローチにもなりますが、私たちのシナリオには当てはまりません。

(119 メッセージ) AVC シーケンス ヘッダー & AAC シーケンス ヘッダー_You Yu Yu You-CSDN ブログ

上記の記事から、AVC シーケンス ヘッダーである最初のビデオ フレームが非常に重要であり、クライアント側のデコードに必要な部分であることもわかります。

これが、ステーション b のプレーヤーがデコードできない理由です。

https://blog.csdn.net/ai2000ai/article/details/85114110

上記の記事では、extradata は side_data を介して更新できると述べており、AVCodecContext の変更と更新も試みましたが成功しませんでした。試みることができます

上面这个方案不行,修改side_data是修改的packet的数据,我们这个是在pollAVPacket之前进行的操作,是AVFormat_write_header的操作,这个方法适用于中途修改sps和pps设置。

sps_pps 情報を stream->codecpar->extraData に書き込もう:

avFormat_write_header の前に sps_pps 情報を extraData に書き込むことはまだできません. videoData の本体にはデータがありますが、いくつかの情報が欠落しており、sps_pps を手書きすることは非現実的であり、移植性がなくテストにのみ使用できます.

不足している情報:

ここに画像の説明を挿入

この記事でもAVCと書いてありますが、その後のデータ形式は | AVCPacketType(8) | CompostionTime(24) | Data |
AVCPacketTypeは00、データ型はAVCSequence Header、
AVCPacketTypeは01、データ型はAVC NALU
したがって、17 の後の 4 つの 00 は AVCPacketType と CompostionTime であることがわかり、ffmpeg のソース コードから残りのバイトの説明も見つかります。

リンク: https://www.jianshu.com/p/e90184fe94f9

AVFormat_write_header の前と rtmp パケットを送信する前に sps と pps の情報を入力する必要があるため、次の試みが行われました。

  • 最初にストリームのディスカバリーを変更してもflags |= AV_CODEC_FLAG_GLOBAL_HEADER;意味がありません。
  • 上記のように、sps と pps の前にいくつかの情報があるため、sps_pps を手動で記述することは良い方法ではありません。
  • 最後に、エンコーダーの初期化時に ctx をエンコーダーに追加することでflags |= AV_CODEC_FLAG_GLOBAL_HEADER;、エンコーダーにデータが入力されていないとき (つまり、初期化後) にエンコーダーの sps_pps 情報を取得できます

ただし、このパラメーターを設定すると、後続のデータに影響します。つまり、後続の I フレームには sps および pps 情報がなくなります。これは、flv 形式が最初のビデオ タグの sps および pps 情報のみを使用して生成する必要があるためです。 AVCC (AVCDecoderConfigurationRecord)なので、次の I フレームには sps がなく、pps の影響はなく、問題は解決しています。

要約:

問題を分析するには, 基本から始める必要があります, 特に基礎となる知識や通信関連の知識については.プロトコルや仕様に関する公式文書を読むことができます. 次に,それらを分析するいくつかのブログや記事を読むこともできます.プロセスを分析することによって問題を見つけるために並べ替えます。これは配置の問題です。

この問題を解決するには、最初の videoData に sps と pps のデータを持たせ、正しいデータを自動的最初は、AVCodecContext にフラグを設定する必要があることを学びましたが、プロセスに慣れていないと、設定する適切な場所を見つけることができない場合があります.

おすすめ

転載: blog.csdn.net/Daibvly/article/details/122296989