8

現在、Android を Skype エンドポイントとして使用しようとしています。この段階で、ビデオを H.264 にエンコードし (Skype でサポートされている唯一の形式であるため)、ストリーミングを機能させるために RTP でカプセル化する必要があります。

どうやら はMediaRecorder、さまざまな理由からこれにはあまり適していません。1 つは、終了後に MP4 または 3GP ヘッダーを追加するためです。もう 1 つの理由は、レイテンシを最小限に抑えるために、ハードウェア アクセラレーションが役立つ場合があるためです。MediaCodecそのため、フレームワークへの最近の低レベルの追加である being 、MediaExtractorなどを利用したいと思います。

現時点では、以下のような活動を予定しています。カメラはビデオをバッファに書き込みます。MediaCodec はビデオを H264 でエンコードし、結果を別のバッファーに書き込みます。このバッファは、ストリーム データをサーバーに送信する RTP カプセル化装置によって読み取られます。これが私の最初の質問です。この計画は実行可能だと思いますか?

今、私はすでにステップ1で立ち往生しています。カメラの使用に関するインターネット上のすべてのドキュメントは を使用しているMediaRecorderため、エンコードする前に生データをバッファに保存する方法が見つかりません。addCallbackBuffer はこれに適していますか? 誰かが例とのリンクを持っていますか?

次に、MediaCodec に関する多くのドキュメントを見つけることができません (かなり新しいため)。堅実なチュートリアルを持っている人はいますか?

最後に: RTP ライブラリに関する推奨事項はありますか?

よろしくお願いします!

4

3 に答える 3

10

更新
最終的に、h264 フレームから適切な RTP パッケージを作成することができました。覚えておくべきことは次のとおりです(実際には非常に簡単です)。

エンコーダーは、フレームごとに NAL ヘッダーを作成します。ただし、各フレームを h264 bytestreamとして返します。これは、各フレームが 3 つの 0 バイトと 1 つの 1 バイトで始まることを意味します。これらの開始プレフィックスを削除し、フレームを RTP パケットに入れる (または FU-A を使用してそれらを分割する) だけです。

今あなたの質問に:

エンコードする前に生データをバッファに保存する方法が見つかりません。addCallbackBuffer はこれに適していますか?

camera.setPreviewCallback(...) を使用し、各フレームをエンコーダーに追加する必要があります。

MediaCodec に関する多くのドキュメントを見つけることができません (かなり新しいため)。堅実なチュートリアルを持っている人はいますか?

これは、MediaCodec がどのように機能するかについての良い紹介になるはずです。http://dpsm.wordpress.com/2012/07/28/android-mediacodec-decoded/

最後に: RTP ライブラリに関する推奨事項はありますか?

私は仕事を成し遂げるjlibrtpを使用しています。

于 2013-07-26T10:23:41.600 に答える
7

MediaCodec や MediaExtractor についてはまだ何も知りませんが、MediaRecorder にはかなり精通しており、MediaRecorder からの H264/AMRNB 出力をキャプチャする SpyDroid に基づく RTSP サーバーの実装に成功しています。基本的な考え方は、コードがローカル ソケット ペアを作成し、MediaRecorder の setOutputFile を使用して出力をペアのソケットの 1 つに書き込むというものです。次に、プログラムはビデオまたはオーディオ ストリームを他のソケットから読み取り、パケットに解析してから、各パケットを 1 つまたは複数の RTP パケットにラップし、UDP 経由で送信します。

MediaRecorder が終了後に MOOV ヘッダーを追加するのは事実ですが、H264 ビデオを RTP 形式で提供している場合は問題ありません。基本的に、ビデオ ストリームの先頭に「mdat」ヘッダーがあります。ヘッダーの長さは 4 バイトで、その後に 4 バイトの「mdat」が続きます。長さを読み取ってヘッダーの長さを確認し、それが mdat ヘッダーであることを確認してから、残りのヘッダー データをスキップします。そこから、ユニット長が 4 バイトで始まる NAL ユニットのストリームを取得します。小さな NAL ユニットは単一の RTP パケットで送信でき、大きなユニットは FU パケットに分割されます。RTSP の場合、ストリームを記述する SDP ヘッダーも提供する必要があります。SpyDroid は、非常に短いムービーをファイルに書き込むことで、SDP ヘッダーの情報を計算します。次に、このファイルを読み取り、最後から MOOV ヘッダーを抽出します。私のアプリは常に同じサイズ、フォーマット、ビット レートを使用するため、静的な文字列を提供するだけです。

public static final String SDP_STRING =
        "m=video 5006 RTP/AVP 96\n"
                + "b=RR:0\n"
                + "a=rtpmap:96 H264/90000\n"
                + "a=fmtp:96 packetization-mode=1;profile-level-id=428028;sprop-parameter-sets=Z0KAKJWgKA9E,aM48gA==;\n"
                + "a=control:trackID=0\n"
                + "m=audio 5004 RTP/AVP 96\n"
                + "b=AS:128\n"
                + "b=RR:0\n"
                + "a=rtpmap:96 AMR/8000\n"
                + "a=fmtp:96 octet-align=1;\n"
                + "a=control:trackID=1\n";

これは、640x480x10fps、H264 ビデオ、8000/16/1 AMRNB オーディオのヘッダーです。

1 つ注意しておきたいことがあります。MediaRecorder を使用している場合、プレビュー コールバックは呼び出されません。これは、ビデオを録画しているときではなく、カメラ モードでのみ機能します。ビデオの録画中に非圧縮形式のプレビュー画像にアクセスする方法を見つけることができませんでした。

SpyDroid のコードを確認することを強くお勧めします。掘り下げるには少し時間がかかりますが、あなたが望むものはすでにそこにあるに違いありません。

于 2012-12-18T22:13:36.473 に答える