2017-07-18 88 views
0

を無視しているように見える次のように私は、H264のエンコードを実装し、MediaCodecを設定する必要がアンドロイドMediaCodecが指定KEY_BIT_RATE値に

MediaCodec codec = MediaCodec.createEncoderByType("video/avc"); 
    MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", resolution.getWidth(), resolution.getHeight()); 

    mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); 
    mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 1000000); 
    mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE,30); 
    codec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); 

ビットレートは1000000に設定され、これはネットワークの制限によって定義された要件です。私がサムスンギャラクシーJ7でテストすると、予想どおり1000 kbpsの出力が見えます。しかし、Samsung Galaxy Grand 2 Duos(アンドロイド4.4)やHuawei Nexus 6P(アンドロイド7.1.2)のような特定のデバイスで同じコードをテストすると、エンコーダが最大5メガバイト/秒の出力を生成することがわかります。指定された値1000000ビット/秒はコーデックによって完全に無視されます。どうしたの?エンコーダにこの指定された値を使用させる方法はありますか?

答えて

0

この動作の真の理由は、プッシュされたフレームが入ったときにエンコーダに転送されたタイムスタンプにありました。単純化のため、開発段階でSystem.nanoTime()の値をタイムスタンプとして使用しました。このタイムスタンプはナノ秒単位で表され、エンコーダはタイムスタンプとしてマイクロ秒を必要とします。

ほとんどのコーデック実装では、実際の受信fpsを測定するために独自のタイマーが使用されるため、実際のタイムスタンプ値には依存せず、無視します。 Nexus 6Pはおそらくスマートなものですが、このエンコーダはタイムスタンプを使用してfps値を測定します。タイムスタンプはナノ秒単位で与えられ、コーデック時間の流れの観点からは1000倍遅く、測定されたfpsは33秒あたり1000/30〜1フレームであったため、要求されたすべてのメガビットを1つの出力フレームにプッシュしようとしました。

0

私はこの問題にも遭遇しましたが、それは1つのデバイス(7のMoto E Plus、6のMoto Eはうまくいきましたが、他のデバイスは7でした)でも発生しました。指定されたbpsの代わりに割り当てられたビットレートをKbpsとして使用します。
あまりにも多くのデータを出力しているように見える場合、残念なことに、このミスを犯すアンドロイドの実装を検出する唯一の "解決策"は、メディアコーデックの出力を監視してビットレート/ 1000でリセットすることです。

+0

私は、エンコーダにナノ秒のタイムスタンプを供給していると思います。それはあなたの問題の本当の理由です。ナノ秒のタイムスタンプは、フレームレートの測定単位を1キロ秒あたりのフレームに変更します。つまり、測定の正確さと正しい動作を維持するために、ビットレートの測定単位をキロビット/秒に変更する必要があります。とにかくありがとう、あなたの答えは正しいアイデアに私を押し込んだ。 –

+1

私はコーデックのマイクロ秒を渡していることを確認したので、同様の症状の2つの異なる問題を見ていたと思います。私は何か間違ったことを排除するつもりはない - なぜ私は私のタイムスタンプを二重にチェックしたのか - しかし、今のところ私は自分の問題についてOEMを責めている。あなたの問題が分かりやすくなってうれしいです。 –

+0

私はmoto c plusと同じ問題に遭遇しました。私は、ナノ秒の代わりにマイクロ秒が入ると確信しています。テストした他のデバイス(15種類)でこの問題に直面していません。 –

関連する問題