MIPI CSI调试之 raw 数据格式

1. 概述

mipi csi规范中为了在mipi 传输中节约带宽采用所谓紧密存储格式,这样的格式虽然在传输中节约了带宽,可是这样的格式若想在调试中显示却未必是好的选择,之所以说未必是因为笔者的工具里是不能直接显示这样的格式,但有没有其它什么工具可以直接显示,笔者不是很清楚,不能显示也无妨,这样的转换并不复杂。

如需显示需要对mipi raw 进行打包, 把mipi raw的字节打包重组成像素。

也许有人会问mipi csi 的数据为何不直接给isp处理而要经过DDR中转,

这个就是如今常说的offline pipeline mode, 直接给ISP处理我们就称之为online pipiline mode,

那为何要采用offline mode, offline mode 明显看起来费点周折。

就是因为大家都想只用一个 ISP core 来同时处理两个以上的 sensor 采集到的图像信息,那多个sensor只能共享一个 isp core, 如何共享?

分时复用嘛,既然是分时复用就一定会出现 isp core在处理某个sensor采集到数据时其它sensor也采集完毕的场景,怎么办? 把其它sensor采集到数据丢掉?显然不合理,尤其在安防行业。那只能先把其它sensor采集到的帧数据缓存下来,待ISP core 处理完当前帧再去处理其它sensor才接到的帧数据, 要缓存这么多的数据,在isp core里加memory显然是不经济的,而且芯片面积也会大大增加。那怎么办?

只有系统memory中为这些暂时还不能得到ISP core帧数据申请空间缓存起来日后处理。好了有点跑题了,还是回到 mipi raw 数据的讨论吧。

下面放我们看看mipi raw究竟是怎么排列的。

2. MIPI RAW排列

先看raw8,因为raw8本来就一字节对齐的,所以没毛病

再看raw10, 5个byte存储4个像素,有一个byte是4个pixel共享的。

 然后raw12, 3个byte存储2个pixel, 有一个byte是两个pixel共享的。

raw14, 7个byte存储4个pixel

 

raw16, raw16也是byte对其的,所以也没毛病,我们这里之提raw10 raw12 raw14这三种格式,网上也有一些文章介绍了 mipi raw如何转 raw ,但不够详细。

笔者前家公司的设计中考虑到了这一点,即在通过DMA写mipi raw 数据到DDR时做了这样的转换,软件同学就不用再自己想办法转了,所以之前没有特别注意过这个问题,现在不行了,必须要搞清楚它了。

以raw10举例

 

3. 转换code

#include <stdio.h>

#include <string.h>

#include <stdlib.h>


char raw_array[3840*2160*2];

short pixel_array[3840*2160*2];


static const char *format_array[5] = {"RAW8", "RAW10", "RAW12", "RAW14", "RAW16"};

static const char *help = "help";


int main(int argc, char *argv[])

{

char *file_name = argv[1];

char *format = argv[2];

int width = atoi(argv[3]);

int height = atoi(argv[4]);

char out_file[256];

int format_index;


int byte_index = 0;

int pixel_index = 0;

int in_size = 0;

int out_size = 0;


printf("Usage: <filename> <format: RAW8/RAW10/RAW12/RAW14/RAW16> <width> <height>\r\n");


printf("file name: %s \r\n", file_name);

printf("format: %s \r\n", format);

printf("width: %d \r\n", width);

printf("height: %d \r\n", height);


FILE *raw_fb = fopen(file_name, "rb" );

if(!raw_fb)

{

printf("open input file faile \r\n");

return -1;

}


sprintf(out_file, "out_%s_%s", format, file_name);


printf("open input file name: %s\r\n", out_file);


FILE *pixel_fb = fopen(out_file, "wb");

if(!pixel_fb)

{

printf("open output file faile \r\n");

return -1;

}


for(int i=0; i<5; i++)

{

if(0 == strcmp(format_array[i], format))

{

format_index = i;

break;

}


format_index = 5;

}


printf("start convertion format_index: %d \r\n", format_index);


switch(format_index)

{

case 0:

in_size = width*height;

out_size = width*height;

break;

case 1:

in_size = width*height*10/8;

out_size = width*height*2;

break;

case 2:

in_size = width*height*12/8;

out_size = width*height*2;

break;

case 3:

in_size = width*height*14/8;

out_size = width*height*2;

break;

case 4:

in_size = width*height*2;

out_size = width*height*2;

break;

default:

printf("format is unsupport !!! \r\n");

break;

}


fread(raw_array, 1, in_size, raw_fb);


switch(format_index)

{

case 0:

// RAW8 don't need convert

break;

case 1:

// RAW10

for(byte_index=0, pixel_index=0; byte_index < (in_size-5); )

{

pixel_array[pixel_index+0] = (((short)(raw_array[byte_index+0]))<<2) & 0x03FC;

pixel_array[pixel_index+0] = pixel_array[pixel_index+0] | (short)((raw_array[byte_index+4]>>0) & 0x0003);


pixel_array[pixel_index+1] = (((short)(raw_array[byte_index+1]))<<2) & 0x03FC;

pixel_array[pixel_index+1] = pixel_array[pixel_index+1] | (short)((raw_array[byte_index+4]>>2) & 0x0003);


pixel_array[pixel_index+2] = (((short)(raw_array[byte_index+2]))<<2) & 0x03FC;

pixel_array[pixel_index+2] = pixel_array[pixel_index+2] | (short)((raw_array[byte_index+4]>>4) & 0x0003);


pixel_array[pixel_index+3] = (((short)(raw_array[byte_index+3]))<<2) & 0x03FC;

pixel_array[pixel_index+3] = pixel_array[pixel_index+3] | (short)((raw_array[byte_index+4]>>6) & 0x0003);


byte_index = byte_index + 5;

pixel_index = pixel_index + 4;

}

break;


case 2:

// RAW12

for(byte_index=0, pixel_index=0; byte_index < (in_size-3); )

{

pixel_array[pixel_index+0] = (((short)(raw_array[byte_index+0]))<<4) & 0x0FF0;

pixel_array[pixel_index+0] = pixel_array[pixel_index+0] | (short)((raw_array[byte_index+2]>>0) & 0x000F);


pixel_array[pixel_index+1] = (((short)(raw_array[byte_index+1]))<<4) & 0x0FF0;

pixel_array[pixel_index+1] = pixel_array[pixel_index+1] | (short)((raw_array[byte_index+2]>>4) & 0x000F);


byte_index = byte_index + 3;

pixel_index = pixel_index + 2;

}

break;

case 3:

//RAW14

for(byte_index=0, pixel_index=0; byte_index < (in_size-7); )

{

pixel_array[pixel_index+0] = (((short)(raw_array[byte_index+0]))<<6) & 0x3FC0;

pixel_array[pixel_index+0] = pixel_array[pixel_index+0] | (short)((raw_array[byte_index+4]>>0) & 0x003F);


pixel_array[pixel_index+1] = (((short)(raw_array[byte_index+1]))<<6) & 0x3FC0;

pixel_array[pixel_index+1] = pixel_array[pixel_index+1] | (short)((raw_array[byte_index+4]>>6) & 0x0003);

pixel_array[pixel_index+1] = pixel_array[pixel_index+1] | (short)((raw_array[byte_index+5]>>0) & 0x000F);


pixel_array[pixel_index+2] = (((short)(raw_array[byte_index+2]))<<6) & 0x3FC0;

pixel_array[pixel_index+2] = pixel_array[pixel_index+2] | (short)((raw_array[byte_index+5]>>4) & 0x000F);

pixel_array[pixel_index+2] = pixel_array[pixel_index+2] | (short)((raw_array[byte_index+6]>>0) & 0x0003);


pixel_array[pixel_index+3] = (((short)(raw_array[byte_index+3]))<<6) & 0x3FC0;

pixel_array[pixel_index+3] = pixel_array[pixel_index+3] | (short)((raw_array[byte_index+6]>>2) & 0x003F);


byte_index = byte_index + 7;

pixel_index = pixel_index + 4;

}

break;

case 4:

// RAW16 don't need convert

break;

default:

printf("formt is unsupport !!! \r\n");

break;

}


fwrite(pixel_array, 1, out_size, pixel_fb);



fclose(raw_fb);

fclose(pixel_fb);


printf("convert finished !!! \r\n");


return 0;


}

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: MIPI CSI是手机或其他可穿戴设备中使用的一种标准化传输接口,用于连接摄像头和处理器。RAW12像素格式是指每个像素由12位数据组成,CSI接口中的字节是指数据的存储方式。在这个特定的配置中,CIS接口具有两条通道,可以实现高带宽数据传输。具体来说,这意味着在每个时钟周期内,接口可以传输两个字节,并组合成一个12位的像素值。 MIPI CSI RAW12字节2通道配置提供了高质量图像传输和处理的优化,因为它能够处理更大和更多的数据,确保了更高的图像质量和增强的图像分辨率。 ### 回答2: MIPI CSI是一种高速串行接口协议,用于图像或视频传输。Raw12表示像素的编码方式,即每个像素由12位二进制数表示。Byte 2 Lane表示每个传输位通过两个物理线路进行传输,其中每个字节(8位)由两个lanes(物理线路)传输,一共使用了16个物理线路。MIPI CSI Raw12 Byte 2 Lane可以有效地提高图像或视频数据的传输速度和精度,适用于高清图像或视频传输。该技术被广泛应用于移动设备、数字相机、安防监控等领域。 MIPI CSI Raw12 Byte 2 Lane技术能够显著提升图像或视频传输的速度和质量,为用户带来更流畅的观赏体验。同时,这一技术的应用还能够支持更广泛的图像或视频格式和分辨率,带来更多的应用场景和商业机会,对于未来的视觉技术发展具有重要意义。 ### 回答3: MIPI CSI-2是一种用于传输视频和图像数据的协议,它使用双差分对差分串行总线进行通信,具有高速、低功耗等特点。其中CSI代表Camera Serial Interface。 RAW12是一种像素数据格式,表示每个像素占用12位,即使用12个二进制位表示一个像素点的颜色信息,它可以更好地保留图像的细节和清晰度,但相比于RAW10或RAW8等格式需要更大的储存空间和带宽来传输数据。 Byte 2 lane表示数据总线使用2条差分对线路,每条差分对线路的传输速率为1 byte/时钟周期。因为MIPI CSI-2可以支持从1到4条数据总线,所以使用2 lane表示数据总线只使用了其中的两条。这种设置可以兼顾数据传输的带宽和高速度的传输需求,同时也能保证发送端和接收端的兼容性和稳定性。 总之,mipi csi raw12 byte 2 lane是一种高速、稳定的像素数据传输方式,可以更好地保留图像的细节和清晰度,同时也具有较小的功耗和储存空间需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bingdund

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值