3

MediaExtractor/MediaCodec を使用してビデオをデコードし、TextureView にレンダリングしています。テンプレートとして、 https ://github.com/vecio/MediaCodecDemo/blob/master/src/io/vec/demo/mediacodec/DecodeActivity.java のコードを使用しました。

動画を2倍速で再生したいです。幸いなことに、メディアのエンコード/デコードは十分に高速であるため、MediaCodec ですべてのフレームをデコードし、1 つおきのフレームのみを画面にレンダリングすることでこれを実現できます。ただし、特に任意の値で再生を増やしたい場合は、これは優れた解決策とは思えません。たとえば、10x の速度では、コーデックは 30 fps で 10 フレームごとに再生するのに十分な速さでフレームをデコードできません。

代わりに、MediaExtractor.advance() を複数回呼び出して再生を制御し、デコードする必要のないフレームをスキップしたいと思います。例えば:

        ...
        mDecoder.queueInputBuffer(inIndex, 0, sampleSize, mExtractor.getSampleTime(), 0);
        for (i = 0; i < playbackSpeedIncrease; i++) {
               mExtractor.advance();
        }
        ...

このコードでは、理論上、エクストラクタはn 番目のフレームごとにのみ抽出する必要があります。ここで、nは変数「playbackSpeedIncrease」によって定義されます。たとえば、n = 5 の場合、これはフレーム 1 ~ 4 を過ぎて進み、フレーム 5 のみを抽出する必要があります。

ただし、これは実際には機能しません。このコードを実行すると、画面にレンダリングされた画像が歪んでいます。ここに画像の説明を入力

これがなぜなのか誰か知っていますか?任意の速度でビデオを再生するためのより良い方法について何か提案はありますか?

4

1 に答える 1

6

通常、AVC ビデオではこれを行うことはできません。

エンコードされたビデオには、完全なイメージを保持する「キー」(または「同期」または「I」) フレームがありますが、キー フレーム間のフレームには、前のフレームからの「差分」が保持されます。ウィキペディアで、ビデオのエンコード方法に関する記事をいくつか見つけることができます。キー フレームをスキップし、間違った画像に対して差分が計算されているため、不快なビデオが表示されます。

TiVo などでビデオの早送りはスムーズに行われるが早戻しはぎこちないのを見たことがある場合は、これが理由です。希望のレートを得るために。「より速い」順方向/逆方向では、デバイスが I フレームを再生しているだけなので、均等になります。SAMPLE_FLAG_SYNCMediaExtractor から取得したフレームのフラグを監視することで、同様のことができます。

一般に、デバイスがデコードできる速度でビデオを再生するか、キー フレームのみを再生するかのいずれかに制限されます。(特定のエンコーディングでの特定のビデオのレイアウトについて十分に知っている場合は、より適切に実行できる場合があります。たとえば、I と P を再生し、B を再生しないようにできますが、AVC でそれが可能かどうかはわかりません。)

I フレームの頻度は、ビデオ エンコーダーによって決定されます。1 秒あたり 1 つまたは 2 つの傾向がありますが、さまざまなソースからビデオを取得する場合、GOP サイズ (画像のグループ、つまり I フレーム間にあるフレームの数) が異なることが予想されます。

于 2015-05-18T16:21:34.010 に答える