更新:これはこれに関連しているように見えます: Android camera2 API からの画像データが Galaxy S5 でフリップ & スクイッシュされる希望のアスペクト比に到達するために手動でトリミングすると、「サポートされている」出力サイズも使用しない可能性があります。
問題:
- Camera2 API を使用してカメラの特性を取得し、MediaCodec.class に適した出力サイズを抽出します
- 適切なカメラ出力サイズのいずれかで MediaCodec 入力サーフェスを作成します。出力をMediaMuxerなどにフィードして、出力を確認します。
- コーデックの作成されたサーフェスをターゲットとして使用して、カメラ キャプチャ リクエストを開始します。
コーデック出力は正しいサイズです。ただし、結果はデバイスによって異なります。
- Nexus 5/6: Android 5/6 で問題ありません。
- Android 5.1 を搭載した Samsung タブレット: 一部の解像度では、画像が明らかに引き伸ばされており、カメラの出力解像度が表面のサイズと一致していないことを示しています。カメラを回転させ始めると、非常に明白になります。X/Y 軸に沿っていないため、画像がますます歪んでいきます。他のいくつかの解像度では、出力は問題ありません。ここには、サイズまたはアスペクト比に関連するパターンはありません。
問題ありません。おそらく、指定された幅や高さなどでサーフェスが正確に作成されない可能性があります (出力サイズが MediaCodec.class ターゲット用に特別に抽出された場合でも)。
そこで、OpenGL コンテキストを作成し、テクスチャとそのための SurfaceTexture を生成し、デフォルトのバッファ サイズをカメラ出力サイズに設定し、テクスチャを使用して Surface を作成しました。これを TextureView に描画したり、MediaCodec の EGL サーフェスに戻したりする詳細については説明しません。結果は同じです。Camera2 のキャプチャ リクエストは、一部の解像度でのみ歪んだ画像を出力します。より深く掘り下げる: updateTexImage の直後に SurfaceTexture で getTransformMatrix を呼び出す - マトリックスは、予想どおり、常に恒等マトリックスです。
したがって、ここでの本当の問題は、カメラが提供されたターゲット サーフェスのサイズでキャプチャしていないことです。解決策は、カメラがキャプチャしている実際のサイズを取得することであり、残りは正しく描画するための純粋な GL マトリックス変換です。しかし - どうすればそれを手に入れることができますか?
注: 古いカメラ API を使用して、まったく同じ「プレビュー サイズ」とターゲット (MediaCodec またはカスタムのいずれか)と同じサーフェスを使用する - すべて問題ありません! しかし、古いカメラ API は非推奨であり、最大キャプチャ サイズが 1080p のように見えるため、使用できません。一方、Camera2 API はそれを超えており、4k 録画をサポートする必要があります。