1

(これは、使用するサーバー ソフトウェアの制限によるものです。変更できる場合は変更します)。

ソケットを介して、一連の 720x480 JPEG ファイル (サイズ約 6kb) を受信して​​います。ネットワークのベンチマークを行ったところ、これらの JPEG を 60FPS でスムーズに受信できることがわかりました。

私の現在の描画操作は、2560x1600 の Nexus 10 ディスプレイで行われています。ソケットからバイト配列を受け取ったら、これが私のデコード方法です。

public static void decode(byte[] tmp, Long time) {
    try {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferQualityOverSpeed = false;
        options.inDither = false;
        Bitmap bitmap = BitmapFactory.decodeByteArray(tmp, 0, tmp.length, options);
        Bitmap background = Bitmap.createScaledBitmap
                (bitmap, MainActivity.screenwidth, MainActivity.screenheight, false);
        background.setHasAlpha(false);
            Canvas canvas = MainActivity.surface.getHolder().lockCanvas();
            canvas.drawColor(Color.BLACK);
            canvas.drawBitmap(background, 0, 0, new Paint());
            MainActivity.surface.getHolder().unlockCanvasAndPost(canvas);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

ご覧のとおり、SurfaceView からキャンバスをクリアしてから、ビットマップを SurfaceView に描画しています。私の問題は、それが非常に、非常に、遅いということです。

ロック操作の前後に System.currentTimeMillis() を追加することに基づく一部のテストでは、キャンバスの取得、ビットマップの描画、キャンバスの押し戻しの間に約 30 ミリ秒の差が生じます。表示される SurfaceView は非常にラグがあり、時々ジャンプしたり、フレーム レートがひどいです。

このように描くための参照方法はありますか?繰り返しますが、サーバーから取得したものを変更することはできませんが、可能であればビットマップを 60FPS で表示したいと考えています。

(ImageView の内容を設定しようとしましたが、同様の結果が得られています)。これに影響を与える可能性のある SurfaceView のコードは他にありません。ホルダーを RGBA_8888 形式に設定しました。

    getHolder().setFormat(PixelFormat.RGBA_8888);

このビットマップのストリームを VideoView に変換することは可能ですか? その方が速いでしょうか?

ありがとう。

4

1 に答える 1

3

パフォーマンスの問題が発生した場合はいつでも、Traceviewを使用して、問題がどこにあるかを正確に把握してください。使用System.currentTimeMillis()は、ハンマーでステーキをトリミングしようとするようなものです。

一番大事なことは、メイン アプリケーション スレッドからビットマップ デコードを取得することです。バックグラウンドスレッドでそれを行います。メイン アプリケーション スレッドは、ビットマップを描画し、そのバックグラウンド スレッドによって設定されたキューから引き離す必要がありますAndroid には、Android 4.1 の時点で 60 fps ベースでレンダリングするように設定されたメイン アプリケーション スレッドがあります (別名、"Project Butter") Bitmap。キューが現在の場合、60fps の結果が得られるはずです。

また、一貫したサイズの画像がある場合は、常にinBitmapAndroid 3.0 以降で withBitmapFactory.Optionsを使用してください。これは、GC が CPU 時間を盗むことが問題の一部になるためです。ローテーションするオブジェクトのプールをBitmap処理して、ガベージの生成を減らし、ヒープの断片化をあまり行わないようにします。

Android はレンダリングにハードウェア グラフィックス アクセラレーションを利用できるため、イメージをスケーリングするよりも (またはキャンバスImageViewに描画するだけで) Android にイメージをスケーリングさせる方がよいと思います。ここでも、Traceview はあなたの友達です。ViewBitmapFactoryBitmapFactory

に関して:

これらの JPEG を 60FPS でスムーズに受信できることがわかりました。

それは時々真実になるでしょう。モバイル デバイスはモバイルである傾向があります。「6kb」が 6KB (6 キロバイト) を意味すると仮定すると、~3Mbps (毎秒 3 メガビット) の接続を想定していることになりますが、それは確かではありません。

に関して:

このビットマップのストリームを VideoView に変換することは可能ですか?

VideoViewは動画を再生するウィジェットで、動画はありません。

プッシュが押し寄せてくると、NDK にドロップダウンしてネイティブ コードでこれを行う必要があるかもしれませんが、そうしないことを願っています。

于 2013-07-18T22:11:10.140 に答える