1.説明:
i.MX AndroidカメラHALでは、センサーがISPまたはISIに接続されているかどうかに関係なく、YUYVセンサーのみをサポートします。一部のユーザーは、UYVYやRAWなどのセンサー形式をカスタマイズしたい、彼らはこれを行うためのガイドが必要で、このドキュメントは、i.MX8MPのAndroidに生のカメラセンサーを実装し、生データを出力する方法を説明することを意図しています。
注:i.MX 8M plus、Android12_1.0.0に基づいています。
2.カメラHAL
Android のカメラ ハードウェア抽象化レイヤ(HAL)は、android.hardware.camera2 の上位カメラ フレームワーク API を基盤となるカメラ ドライバとハードウェアに接続します。詳細については、AOSP のドキュメントをご覧ください。
https://source.android.google.cn/docs/core/camera/camera3_requests_hal?hl=en
I.MX カメラHALでは、カメラサブシステムはいくつかの部分に分割できます。
hidl_service dlカメラHAL3を開きます。
そのコールスタックは次のようにリストできます。
パイプラインには 2 つのストリームがあり、プレビュー ストリームには 3 つのバッファが必要であり、キャプチャ ストリームには 2 つのバッファが必要です。
CameraDeviceSessionHwlImpl: ConfigurePipeline, stream 0: id 0, type 0, res 2592x1944, format 0x21, usage 0x3, space 0x8c20000, rot 0, is_phy 0, phy_id 0, size 8388608
CameraDeviceSessionHwlImpl: ConfigurePipeline create capture stream
CameraDeviceSessionHwlImpl: ConfigurePipeline, stream 1: id 1, type 0, res 1024x768, format 0x22, usage 0x100, space 0x0, rot 0, is_phy 0, phy_id 0, size 0
CameraDeviceSessionHwlImpl: ConfigurePipeline create preview stream
次のコマンドを使用して、ストリームの入出力をダンプできます。
"setprop vendor.rw.camera.test 1" を使用して Steam 0 をダンプします。
"setprop vendor.rw.camera.test 2" を使用して Steam 1 をダンプします。
コマンドを実装する前に、"su;setenforce 0" を使用して SeLinux を閉じると、データは "/data/x-src.data" としてダンプされます。"/data/x-dst.data"、ここで、"x" はストリーム ID で、"0"、"1"、"2"、...
|
|
プレビューストリーム |
ストリームのキャプチャ |
|
身分証明書 |
1 |
0 |
|
解決 |
1024*768 |
2592*1944 |
|
形式 |
HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED (34) |
HAL_PIXEL_FORMAT_BLOB (33) |
|
使い |
0x900 GRALLOC_USAGE_HW_TEXTURE (0x100) GRALLOC_USAGE_HW_COMPOSER (0x800) |
0x3 GRALLOC_USAGE_SW_READ_OFTEN |
|
データスペース |
0 |
HAL_DATASPACE_V0_JFIF |
プレビューとビデオを区別するために、フレームワークによって次の使用法が追加されますGRALLOC_USAGE_HW_VIDEO_ENCODER
3. Rawサポート
3.1 システムの変更
i.MX 8M Plus EVKのデフォルト画像はbasler + baslerをサポートしており、カメラは画像がフラッシュされて起動した後に動作することができます、それはISPのカメラですが、生を処理するにはISIが必要です。あなたはAndroid_Userのs_Guide.pdfを参照する必要があります、Android12_2.0.0はAndroid12_1.0.0と異なるので、正しいバージョンを見つける必要があります。カメラをデフォルト以外の画像で動作させるには、次の追加コマンドを実行します。
ホスト上の OV5640 (CSI1) のみ:
1920*1080、解凍されたraw12をサポートするOV2775を使用しているため、jsonファイルは次のようになります。
3.2 DTB modification
1.まず、dtbo-imx8mp-ov2775.imgを生成するように BoardConfig.mk を変更します
device\nxp\imx8m\evk_8mp\BoardConfig.mk:
TARGET_BOARD_DTS_CONFIG += imx8mp-ov2775:imx8mp-evk-ov2775.dtb
2. 次に、imx8mp-evk-ov2775.dts を vendor\nxp-opensource\kernel_imx arch\arm64\boot\dts\freescale に追加します。
3. imx8mp-evk-ov2775.dts を変更します。OV2775 を ISI に接続します。
&isi_0 {
status = "okay";
};
&isp_0 {
status = "disabled";
};
&dewarp {
status = "disabled";
};
4. dtboイメージをビルドし、ボードにフラッシュします。
./imx-make.sh dtboimage -j4
fastboot flash dtbo dtbo.img
3.3 センサードライバーの変更
私はOV2775ドライバをISP側から使用していますが、g_frame_intervalやenum_frame_sizeなどのすべての機能を実装する必要があるか、HALが間違ったパラメータを取得してエラーを返すように注意してください。
static struct v4l2_subdev_video_ops ov2775_subdev_video_ops = {
.g_frame_interval = ov2775_g_frame_interval,
.s_frame_interval = ov2775_s_frame_interval,
.s_stream = ov2775_s_stream,
};
static const struct v4l2_subdev_pad_ops ov2775_subdev_pad_ops = {
.enum_mbus_code = ov2775_enum_mbus_code,
.set_fmt = ov2775_set_fmt,
.get_fmt = ov2775_get_fmt,
.enum_frame_size = ov2775_enum_frame_size,
.enum_frame_interval = ov2775_enum_frame_interval,
};
3.4 ISI ドライバの変更
ISIドライバーにRAW形式を追加する必要があります。
}, {
.name = "RAW12 (SBGGR12)",
.fourcc = V4L2_PIX_FMT_SBGGR12,
.depth = { 16 },
.color = MXC_ISI_OUT_FMT_RAW12,
.memplanes = 1,
.colplanes = 1,
.mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
}, {
.name = "RAW10 (SGRBG10)",
.fourcc = V4L2_PIX_FMT_SGRBG10,
.depth = { 16 },
.color = MXC_ISI_OUT_FMT_RAW10,
.memplanes = 1,
.colplanes = 1,
.mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
}
3.5 カメラHALの変更
パイプラインにはプレビューストリームとキャプチャストリームがあります。
GPUはraw形式をサポートしていないため、アプリケーションがraw形式を設定するとエラーログが印刷されます。
02-10 18:49:02.162 436 436 E NxpAllocatorHal: convertToMemDescriptor Unsupported fomat PixelFormat::RAW10
02-10 18:49:02.163 2390 2445 E GraphicBufferAllocator: Failed to allocate (1920 x 1080) layerCount 1 format 37 usage 20303: 7
02-10 18:49:02.163 2390 2445 E BufferQueueProducer: [ImageReader-1920x1080f25m2-2390-0](id:95600000002,api:4,p:2148,c:2390) dequeueBuffer: createGraphicBuffer failed
02-10 18:49:02.163 2390 2405 E BufferQueueProducer: [ImageReader-1920x1080f25m2-2390-0](id:95600000002,api:4,p:2148,c:2390) requestBuffer: slot 0 is not owned by the producer (state = FREE)
02-10 18:49:02.163 2148 2423 E Surface : dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: -22
02-10 18:49:02.163 2390 2445 E BufferQueueProducer: [ImageReader-1920x1080f25m2-2390-0](id:95600000002,api:4,p:2148,c:2390) cancelBuffer: slot 0 is not owned by the producer (state = FREE)
02-10 18:49:02.164 2148 2423 E Camera3-OutputStream: getBufferLockedCommon: Stream 1: Can't dequeue next output buffer: Invalid argument (-22)
GPU コードを変更することはお勧めしません。
プレビューストリームの場合、ピクセル形式はHAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINEDに固定されており、YUYV形式が必要ですが、このパッチでは、raw12をyuyvに変換せず、入力から出力にバッファをコピーするだけなので、プレビューストリームは実際にはraw12です。
ストリームをキャプチャするときは、通常はJPEG形式に使用されるBlob形式を使用します。形式がアプリケーションによって渡される Blob であることが判明すると、カメラ HAL はバッファを入力から出力に直接コピーします。詳細は関数ProcessCapturedBuffer()で確認できます。
4. アプリケーションとツール
4.1 応用
添付ファイル「android-Camera2Basic-master_application.7z」のテストアプリケーション、これは基本的に一般的なカメラアプリケーションであり、キャプチャストリーム形式をblobに設定します。
Size largest = Collections.max(
Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
new CompareSizesByArea());
mImageReader = ImageReader.newInstance(largest.getWidth(),
largest.getHeight(),
ImageFormat.JPEG, /*maxImages*/2);
4.2 ツール
7yuvツールを使用して、適用可能なまたはHALによってダンプされるraw12形式を確認します。右側にパラメータを設定する必要があります。
ImageJツールを使用して、RAW形式を確認することもできます。