1

MediaCodecAPI を使用したエンコード/デコードの以下の例を見ました。https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java

推測されたプレゼンテーション時間と、デコードされた情報から受け取ったプレゼンテーション時間の比較があります。

assertEquals("Wrong time stamp", computePresentationTime(checkIndex),
    info.presentationTimeUs);

デコーダーはエンコードされたバッファー内のデータをデコードするだけなので、このエンコーダーの出力 H.264 ストリームで解析できるタイムスタンプ情報があると思います。

( )MediaCodecを使用して mp4 コンテナーにエンコードされた H264 ストリーム (.h264) を多重化する Android アプリケーションを作成しています。高すぎるバージョン 4.3 が必要なため、使用したくありません。ffmpeglibavformatMediaMuxer

ただし、ffmpegによってエンコードされたパケットのプレゼンテーション タイムスタンプを認識しないようMediaCodecです。そのため、ストリームからフレームを読み取ろうとすると、常に NO_PTS 値が取得されます。

この状況で正しいプレゼンテーションのタイムスタンプを取得する方法を知っている人はいますか?

4

1 に答える 1

3

MediaCodecエンコーダーからタイムスタンプを送信ffmpegするには、次のように変換する必要があります。

jint Java_com_classclass_WriteVideoFrame(JNIEnv * env, jobject this, jbyteArray data, jint datasize, jlong timestamp) {

    ....

AVPacket pkt;
av_init_packet(&pkt);

AVCodecContext *c = m_pVideoStream->codec;

pkt.pts = (long)((double)timestamp * (double)c->time_base.den / 1000.0);
pkt.stream_index    = m_pVideoStream->index;
pkt.data            = rawjBytes;
pkt.size            = datasize;

time_baseフレームレートに依存する場所

パイプラインでのタイムスタンプ フローの更新: デコーダーもエンコーダーもタイムスタンプを独自に認識しません。タイムスタンプはこれらのコンポーネントに設定されます

decoder.queueInputBuffer(inputBufIndex, 0, info.size, info.presentationTimeUs, info.flags);

また

encoder.queueInputBuffer(inputBufIndex, 0, 0, ptsUsec, info.flags);

これらのタイムスタンプは、extractor、カメラ、またはアプリによって生成されたものから取得できますが、decoder\encoder はこれらのタイムスタンプを変更せずに通過するだけです。その結果、タイムスタンプはソースからシンク (マルチプレクサー) まで変更されません。

確かにいくつかの例外があります: フレーム周波数が変更された場合 - フレームレート変換など。または、エンコーダーが B フレームでエンコードを行い、並べ替えが発生した場合。またはエンコーダーはタイムスタンプをエンコーダー フレーム ヘッダーに追加できます - オプションであり、標準では必須ではありません。これはすべて、現在の Android バージョン、コーデック、または使用シナリオには当てはまらないと思います。

于 2014-05-20T10:03:27.837 に答える