查看: 27038|回复: 2
收起左侧

教你手机摄像头软件调试

[复制链接]
发表于 2013-11-26 09:06:56 | 显示全部楼层 |阅读模式
摄像头主要参数:
1、MCLK  24MHz;
2、PCLK  48~52MHz~;
3、电压 1.8V(1.5V)、2.8V;
4、scl(IIC时钟)100KHz或者400KHz。

一、摄像头驱动
我们以GT2005为例,来讲述一个摄像头驱动的调试过程:
摄像头和主控的关系图,如下:



摄像头驱动比较简单,完成一面三大步就可以:
摄像头的上电、时钟这些基本条件;
IIC保证摄像头的初始化;
摄像头工作后传回数据到主控。

完成这三个步骤就完成了摄像头基本工作的调试。
1、 摄像头的上电、时钟这些基本条件的实现
电源部分,上电时对应规格书,确认上电时序;MCLK摄像头的主时钟是否提供,看下面是和电和规格书中的
(1)、主意摄像头工作要两组电压:1.8V(1.5V)、2.8V还有MCLK


程序中对电源控制:我们在arch\arm\mach-smdkv310.c中,完成上面两个步骤的代码,(这一点不同平台也许有所不同,这里这是一个实例,这部分代码只是针对三星平台的)




  • #ifdef CONFIG_VIDEO_GT2005
  • static void set_cam2005_main_power(int onoff)
  • {
  •     unsigned int gpio;
  •     int err;
  •     if(onoff)
  •     {
  •         err = gpio_request(S5PV210_GPB(2), "GPB");
  •         if (err)
  •             printk(KERN_ERR "#### failed to request GPB2 for CAM\n");
  •             s3c_gpio_cfgpin(S5PV210_GPB(2),S3C_GPIO_OUTPUT);
  •             s3c_gpio_setpull(S5PV210_GPB(2), S3C_GPIO_PULL_UP);
  •             gpio_direction_output(S5PV210_GPB(2), 1);
  •             gpio_free(S5PV210_GPB(2));
  •         //RESET
  •             err = gpio_request(S5PV210_GPE1(4), "GPE1");
  •             if (err)
  •                 printk(KERN_ERR "#### failed to request GPE1_4 for CAM\n");
  •                 s3c_gpio_setpull(S5PV210_GPE1(4), S3C_GPIO_PULL_NONE);
  •                 gpio_direction_output(S5PV210_GPE1(4),0);
  •                 mdelay(100);
  •                 gpio_direction_output(S5PV210_GPE1(4), 1);
  •                 gpio_free(S5PV210_GPE1(4));
  •         //PWDN CAM_back
  •             err = gpio_request(S5PV210_GPB(4), "GPB");
  •             if (err)
  •                 printk(KERN_ERR "#### failed to request GPB4 for CAM\n");
  •                 s3c_gpio_cfgpin(S5PV210_GPB(4),S3C_GPIO_OUTPUT);
  •                 s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP);
  •                 gpio_direction_output(S5PV210_GPB(4), 0);
  •                 mdelay(100);
  •                 gpio_direction_output(S5PV210_GPB(4), 1);
  •                 gpio_free(S5PV210_GPB(4));
  •     }
  •     else
  •     {
  •         ………………
  •     }
  •     return;
  • }
  • #endif

#ifdef CONFIG_VIDEO_GT2005static void set_cam2005_main_power(int onoff){        unsigned int gpio;        int err;                if(onoff)        {                err = gpio_request(S5PV210_GPB(2), "GPB");                if (err)                        printk(KERN_ERR "#### failed to request GPB2 for CAM\n");                        s3c_gpio_cfgpin(S5PV210_GPB(2),S3C_GPIO_OUTPUT);                        s3c_gpio_setpull(S5PV210_GPB(2), S3C_GPIO_PULL_UP);                        gpio_direction_output(S5PV210_GPB(2), 1);                        gpio_free(S5PV210_GPB(2));                //RESET                        err = gpio_request(S5PV210_GPE1(4), "GPE1");                        if (err)                                printk(KERN_ERR "#### failed to request GPE1_4 for CAM\n");                                s3c_gpio_setpull(S5PV210_GPE1(4), S3C_GPIO_PULL_NONE);                                gpio_direction_output(S5PV210_GPE1(4),0);                                mdelay(100);                                gpio_direction_output(S5PV210_GPE1(4), 1);                                gpio_free(S5PV210_GPE1(4));                //PWDN CAM_back                        err = gpio_request(S5PV210_GPB(4), "GPB");                        if (err)                                printk(KERN_ERR "#### failed to request GPB4 for CAM\n");                                s3c_gpio_cfgpin(S5PV210_GPB(4),S3C_GPIO_OUTPUT);                                s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP);                                gpio_direction_output(S5PV210_GPB(4), 0);                                mdelay(100);                                gpio_direction_output(S5PV210_GPB(4), 1);                                gpio_free(S5PV210_GPB(4));        }        else                {                        ………………        }        return;}#endif
提供MCLK代码如下:



  • static int smdkv210_cam_clk_init(void)
  • {
  •     unsigned int tempvalue=0;
  •         tempvalue = readl(S5P_CLK_DIV1);
  •     tempvalue = (tempvalue &0xffff0fff);
  •     writel(tempvalue,S5P_CLK_DIV1);
  •     tempvalue = readl(S5P_CLK_SRC1);
  •     tempvalue = (tempvalue &0xffff0fff)|0x00001000;
  •     writel(tempvalue,S5P_CLK_SRC1);
  •     return 0;
  • }

static int smdkv210_cam_clk_init(void){        unsigned int tempvalue=0;              tempvalue = readl(S5P_CLK_DIV1);                tempvalue = (tempvalue &0xffff0fff);                writel(tempvalue,S5P_CLK_DIV1);                tempvalue = readl(S5P_CLK_SRC1);                tempvalue = (tempvalue &0xffff0fff)|0x00001000;                writel(tempvalue,S5P_CLK_SRC1);                return 0;}这时拿示波器抓到上电时的波形和MCLK24MHZ的时钟,信号就说明我们完成了这一步,其实在实际工作中,我们一般出问题的时候才会测这些数据,确认问题点。
上电时序:

(1)、上电时序;
(2)、MCLK如下所示。



2、 IIC和一些参数的配置




  • #ifdef CONFIG_VIDEO_GT2005
  • static struct GT2005_platform_data GT2005_plat = {
  •     .default_width = 640,
  •     .default_height = 480,
  •     .pixelformat = V4L2_PIX_FMT_UYVY,   //  .freq = 24000000,
  •     .is_mipi = 0,
  • };
  • static struct i2c_board_info GT2005_i2c_info = {
  •     I2C_BOARD_INFO("GT2005", 0x78 >> 1), //1、IIC地址
  •     .platform_data = >2005_plat,
  • };
  • static struct s3c_platform_camera GT2005 = {
  • #ifdef CAM_ITU_CH_A
  •     .id     = CAMERA_PAR_A,
  • #else
  •     .id     = CAMERA_PAR_B,
  • #endif
  •     .type       = CAM_TYPE_ITU,   //2、数据接口选择(ITU\MIPI等)
  •     .fmt        = ITU_601_YCBCR422_8BIT,
  •     .order422   = CAM_ORDER422_8BIT_CBYCRY, //3、图像数据格式
  •     .i2c_busnum = 1,
  •     .info       = >2005_i2c_info,
  •     .pixelformat    = V4L2_PIX_FMT_UYVY,
  •     .srclk_name = "mout_mpll",              //4、这部分关系到时钟
  •     .clk_name   = "sclk_cam1",
  •     .clk_rate   = 24000000,             /* 24MHz */
  •     .line_length    = 640,              /* 640*480 */
  •     /* default resol for preview kind of thing */
  •     .width      = 640,
  •     .height     = 480,
  •     .window     = {
  •         .left   = 16,
  •         .top    = 0,
  •         .width  = (640 - 16),
  •         .height = 480,
  •     },
  •     /* Polarity */                            //5、信号的极性,    .inv_pclk   = 0,
  •     .inv_vsync  = 1,
  •     .inv_href   = 0,
  •     .inv_hsync  = 1,
  •     .initialized    = 0,
  •     .cam_power=set_cam2005_main_power
  • };
  • #endif

#ifdef CONFIG_VIDEO_GT2005static struct GT2005_platform_data GT2005_plat = {        .default_width = 640,        .default_height = 480,        .pixelformat = V4L2_PIX_FMT_UYVY,   //        .freq = 24000000,        .is_mipi = 0,};static struct i2c_board_info GT2005_i2c_info = {        I2C_BOARD_INFO("GT2005", 0x78 >> 1), //1、IIC地址        .platform_data = >2005_plat,};static struct s3c_platform_camera GT2005 = {#ifdef CAM_ITU_CH_A        .id                = CAMERA_PAR_A,   #else        .id                = CAMERA_PAR_B,#endif        .type                = CAM_TYPE_ITU,   //2、数据接口选择(ITU\MIPI等)        .fmt                = ITU_601_YCBCR422_8BIT,        .order422        = CAM_ORDER422_8BIT_CBYCRY, //3、图像数据格式         .i2c_busnum        = 1,        .info                = >2005_i2c_info,        .pixelformat        = V4L2_PIX_FMT_UYVY,                .srclk_name        = "mout_mpll",              //4、这部分关系到时钟        .clk_name        = "sclk_cam1",        .clk_rate        = 24000000,             /* 24MHz */         .line_length        = 640,              /* 640*480 */        /* default resol for preview kind of thing */        .width                = 640,        .height                = 480,        .window                = {                .left   = 16,                .top    = 0,                .width  = (640 - 16),                .height = 480,        },        /* Polarity */                            //5、信号的极性,        .inv_pclk        = 0,        .inv_vsync        = 1,        .inv_href        = 0,        .inv_hsync        = 1,        .initialized        = 0,        .cam_power=set_cam2005_main_power};#endif注意下面几个参数:
(1)、IIC地址
(2)、数据接口选择(ITU\MIPI等),这几个数据接口我们在前面提到过;
(3)、图像数据格式 ,这就是我们前面提到的YVU\UVY之类不同的数据顺序;
(4)、这部分关系到时钟;
(5)、输出信号的极性,就是我们PCLK、VSYNC、HSVNC这些信号的极性,不正确时会没有图像之类现象,这个也要注意了。
完成这一步确认IIC通信是否正常,如下图所抓到波形:


3、 完成上面两步,摄像头基本配置完成,我们确认下输出端PCLK、VHSN、SVSN、D1-D7


二、摄像头调试过程中常遇到的问题
1、录相在预览时正常,播放录像时花屏(程序解释为三星s5pv210/s5pv310是的,其它的可以参考,找相应代码)

原因分析:
(1)录相用fimc2,

在android/device/samsung/proprietary/libcamera/SecCamera.cpp中
int SecCamera::startRecord(void)




  • m_cam_fd_rec = open(CAMERA_DEV_NAME2, O_RDWR);
  • vendor\sec\sec_proprietary\smdkc110\libcamera\SecCamera.h
  • #define CAMERA_DEV_NAME2      "/dev/video2"

m_cam_fd_rec = open(CAMERA_DEV_NAME2, O_RDWR);vendor\sec\sec_proprietary\smdkc110\libcamera\SecCamera.h#define CAMERA_DEV_NAME2      "/dev/video2"(2)所用的视频格式,在
android/device/samsung/proprietary/libcamera/SecCameraHWInterface.cpp中
void CameraHardwareSec::m_initDefaultParameters(int camera_id)



  • int default_preview_pixel_format = mSecCamera->getPreviewDefaultPixelFormat();
  •     switch (default_preview_pixel_format) {
  •     default:
  •     case V4L2_PIX_FMT_NV21:
  •         p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
  •         break;
  •     case V4L2_PIX_FMT_NV12T:
  •         p.setPreviewFormat("yuv420sp_tiled");
  •         break;
  •     }
  • 其中mSecCamera->getPreviewDefaultPixelFormat()在
  • vendor\sec\sec_proprietary\smdkc110\libcamera\SecCamera.cpp中实现,
  • int SecCamera::getPreviewDefaultPixelFormat(void)
  • {
  •     return DEFAULT_PREVIEW_PIXEL_FORMAT;
  • }
  • 在android/device/samsung/proprietary/libcamera/SecCamera.h中设定初始值。我们这里设的是
  • #ifdef DUAL_PORT_RECORDING
  •     #define DEFAULT_PREVIEW_PIXEL_FORMAT  (V4L2_PIX_FMT_NV21)
  • #else
  •     #define DEFAULT_PREVIEW_PIXEL_FORMAT  (V4L2_PIX_FMT_NV12T)
  • #endif

int default_preview_pixel_format = mSecCamera->getPreviewDefaultPixelFormat();    switch (default_preview_pixel_format) {    default:    case V4L2_PIX_FMT_NV21:        p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);        break;    case V4L2_PIX_FMT_NV12T:        p.setPreviewFormat("yuv420sp_tiled");        break;    }其中mSecCamera->getPreviewDefaultPixelFormat()在vendor\sec\sec_proprietary\smdkc110\libcamera\SecCamera.cpp中实现,int SecCamera::getPreviewDefaultPixelFormat(void){    return DEFAULT_PREVIEW_PIXEL_FORMAT;}在android/device/samsung/proprietary/libcamera/SecCamera.h中设定初始值。我们这里设的是#ifdef DUAL_PORT_RECORDING    #define DEFAULT_PREVIEW_PIXEL_FORMAT  (V4L2_PIX_FMT_NV21)#else    #define DEFAULT_PREVIEW_PIXEL_FORMAT  (V4L2_PIX_FMT_NV12T)#endif以上得出视频格式为V4L2_PIX_FMT_NV21
2、图像干扰问题,如下图所示

原因可能是:
(1)、摄像头模组有问题,换一个摄像头试一下;
(2)、数据线驱动能力不足,这个可以在摄像头寄存器里面改,问下摄像头模组FAE,看改那些地方;
3)、两个摄像头共用数据线时,不工作的摄像头会把工作的数据信号减弱;

(4)、PCB 走线太长,也会有干扰,不过我觉得这个可能性小,调试好就一款这样的的,模组厂FAE说的,不过他们模组本身也有问题,两方面因素都有吧:PCB(线过长)、模组打样也有问题。

3、YUV顺序不对:
yuv顺序不对时,出现如下现象。

看下摄像头规格书,把相应寄存器的值改一下就可以了。如下以红框里是不同yuv顺序,找到改为相应的。


4、 预览方向不对(摄像头寄存器只能改以 180度为基数的,90度的就要在FIMC中改)
想知道和比较明确说明翻转角度,最常用的就是写一个“F”,然后看预览里的是怎么转的。


上面有90度的翻转,因为这是FIMC中的寄存器,一般不会改这一部分的值。要不就在模组寄存器中改,要不就在上层。上面只是说明如何去确认图像翻转。
看下GT2005关于翻转的寄存器吧:



5、 杂光,鬼影:
其行业的专业术语统称为Flare,是指在拍摄光源或者强光物体时,边缘出现光影或出现一个完整物体的影子,而且这种现象只能减轻不能完全消失,原因是由于镜片的材质导致光线不但存在折射还存在反射,整机由于镜头面到保护镜片距离很大会更明显!





6、 常见问题相关






摄像头效果评测都有哪些?





以上以gt2005为例,说了一下摄像头驱动,和驱动中常见到的问题,如果上面的问题解决,摄像头点亮,说明在平台是运行是没问题的,小的问题和细节,要找模组厂的FAE过来协助解决,不过你想多研究一下的话,也可以,如果项目允许,就多看看,做到调试一个驱动,所有问题都了解,这样对工作经验、积累很重要的,希望对大家有用。
 楼主| 发表于 2013-11-26 09:09:02 | 显示全部楼层
25楼 ryj_wyy1983 2013-09-09 16:43发表  你好!我现在在做4412 的 ov5640驱动,我按照三星提供的S5KECG提供的驱动修改的,可以预览,也快以录像,但当拍照时,读寄存器CISTUS2(0x0068)为0,好像没用帧送到out_dma中,但我用示波器测了我的摄像头有信号输出,为什没有帧送出呢?
我的qq:67200288

22楼 Brady的博客 2013-07-24 17:58发表  你好,帮忙将YUV和RAW的sensor的区别,帮忙仔细将一下呗。这个工作时候常用,我一直没弄清楚。

21楼 happy08god 2013-06-20 17:08发表 博主实在是太厉害了,对触摸屏,摄像头等都这么精通。另外,写的文章也深入浅出,十分精彩!!

20楼 lxizj 2013-06-08 18:21发表 上电时序的图,与实际GT2005的不符,PWDN应该是高电平正常工作。程序和示波器抓到的波形倒是一致的。
xubin341719 2013-06-19 10:27发表 回复lxizj:上电这块,一般摄像头要求不是太严格,我就没仔细对规格书,按照经验点亮就没仔细看了。谢谢您的提醒,最好还是按规格书的要求来做。

17楼 ad3600 2013-04-18 17:31发表
博主,好文章啊~!
想请问一下,关于预览翻转,在fimc改的部分,具体是在fimc的哪个文件(ictol?reg?)里面改?具体又是哪个函数?希望不吝赐教。 方便的话加我QQ:879616923,我搞平板的,多谢!

16楼 kevinxYangQi 2013-04-09 09:18发表   博主你好!我用你提供的gc0308驱动在三星s5pv210上面调试,能读取到gc0308 Read out the reg 0x0 is 0x9b 打开摄像头没有图像,不知道是什么原因?初始化没有设置好还是其它的问题?请教下博主,QQ:452969479,方便加一下。多谢啦!

15楼 nanihaikeyi 2013-03-28 23:49发表 双摄像头单点正常,前后摄像头切换时候报错,请问是哪里出了问题。
xubin341719 2013-03-29 09:51发表 回复nanihaikeyi:1、检查摄像头端口设定,比如A、B;
                                                                   2、检查HAL层代码,logcat查看下,HAL错误出在哪里;
                                                                  我之前遇到的是这两种情况:端口不对、HAL代码参数有问题(samsung平台)

14楼 suheng007 2013-03-27 09:11发表 我想请问一下camera软件插值到底是怎么一回事?软件插值就是数码变焦吗?是软件改变图片大小还是?是不是通过设定图片大小后从camera读出来的就已经是插值好了的还是要将读出来的数据加工处理在驱动或者hal层实现插值?
xubin341719 2013-03-29 09:52发表 回复suheng007:插值这块我没有接触过, 不好意思!

13楼 skycityxx 2013-03-26 00:26发表  楼主的文章写得太好了。能不能发下三星的内核程序包给我,谢谢。602005399@qq.com

12楼 Brendontsai 2013-03-22 20:47发表  非常感谢楼主~ 想请教楼主一个问题 camera收集的视频不是会有编码一步么,请问楼主了解编码部分是在哪一层么 谢谢~


9楼 Hugo_lucky 2012-09-13 17:31发表 非常有帮助,现在我在做三星4412平台的OV5640 MIPI接口摄像头驱动,我想问下博主,MIPI接口在配置上有什么区别,相关的MIPI寄存器是不是三星都配好了,我只需配置相关的接口就行了?Re: xubin341719 2012-09-13 17:52发表 [回复] [引用] [举报]回复wu_zh9011:你好!我没有调试过MIPI的接口,感觉只用把mach中的配置选项设为MIPI就可以了:
可以参考:
static struct s5k4ea_platform_data s5k4ea_plat = {
………………
.is_mipi = 1,
};
…………
static struct s3c_platform_camera s5k4ea = {
…………

.type = CAM_TYPE_MIPI,
.fmt = MIPI_CSI_YCBCR422_8BIT,
.order422 = CAM_ORDER422_8BIT_YCBYCR,
………………

.mipi_lanes = 2,
.mipi_settle = 12,
.mipi_align = 32,
…………
};
参考别的mipi 接口应可以

Hugo_lucky 2012-09-14 10:56发表
回复xubin341719: 谢谢,我目前正在试验中。还有个问题想请教下博主,我看了下你的代码,preview和capture是在什么地方实现的呢,没有找到相关系统调用。第一次调三星平台的驱动,不是太熟,希望博主能帮忙解答下。
xubin341719 2012-09-14 11:32发表回复wu_zh9011:android/device/samsung/exynos4/libcamera跟hal层相关
Hugo_lucky 2012-09-15 11:24发表 回复xubin341719: 你好博主,你说的是硬件抽象层,驱动应该也会有系统调用响应,以及sensor的寄存器设置。这些是在哪实现的,请博主指点下。
xubin341719 2012-09-15 12:14发表 回复wu_zh9011:你们用MIPI接口的的,驱动里面有一个:V4L2_CID_CAMERA_CAPTURE,这个case对应的函数调用实现拍照功能,返回一个V4L2_PIX_FMT_JPEG格式的数据。
preview和capture相关寄存器,你可以在sensor规格书上找到哦,或者问题下sensor的供应上FAE,
1471770894你加我QQ,我们都在做4412,可以互相沟通下

8楼 lr1988 2012-09-10 16:48发表 您好:这个系列的文章感觉写的很好很详细,不过我是菜鸟还是有点看不懂。比如具体sensor接受的图像格式到frambuff这之间是如何处理。另外,能不能发下gc0308的驱动给我,1275075684@qq.com谢谢!
[游客] 2012-09-10 18:02发表回复lr1988:这篇开头有下载链接,常见的驱动都有,你可以下载看下。图像数据到frambuff这中间要通过FIMC驱动去处理.

7楼 songfengruer 2012-09-08 15:23发表 写的很好,新人一个,看了你写的文章,觉得自己也应该写写博文缕清思路,积累知识,也算是个在学习的好途径。同时想求三星的内核包学习一下。我的邮箱401729990@qq.com,谢谢
xubin341719 2012-09-10 11:29发表 回复songfengruer:发了一个三星平台比较原始的内核源码给你

6楼 san12655874 2012-09-06 13:50发表 博主的这个系列写的非常棒哦!
xubin341719 2012-09-06 14:04发表 回复san12655874:嘿嘿,希望对大家有用!!

5楼 hrbeu06 2012-08-22 13:09发表 你好,我是在linux写的应用程序,只是先简单的在液晶上显示,OV3640是300万的,可以正常显示。我刚才打印了一下获取到的GC0308数据,全是0,你方便留下邮箱吗,我把应用程序给你发过去,还有就是GC0308的电压有什么注意的吗
xubin341719 2012-08-22 13:13发表 回复hrbeu06:1471770894@qq.com

4楼 hrbeu06 2012-08-22 10:15发表 您好:我在调试s5pv210+gc0308用的是您提供的那个程序,现在摄像头工作了,用示波器能看到时钟,也能读取到每帧数据,但是液晶上什么画面也不显示。而OV3640用同样的接口却可以显示,GC0308也是好的,在其他平台上可以正常工作。请教一下知道大概是什么原因吗。
回复hrbeu06:你好,我的调试也出现相同的问题,请问解决了吗?452969479@qq.comRe: xubin341719 2012-08-22 11:41
回复hrbeu06:应该是HAL层的问题确认下:libcamera中用的是SecCamera.cpp这一组,还是SecCamera_zoom.cpp这一组,
回复hrbeu06:看下中间层的。OV那颗是多少像素的?
#logcat
看下libcamera里面那些文件报什么错误。

2楼 ADC0809608 2012-07-17 17:31 好的,谢谢博主,我的邮箱是542170852@qq.com,现在在做210的项目,博主方便的话加一下我的qq,呵呵

1楼 ADC0809608 2012-07-16 19:50 非常好的资料,学习了!我有个疑问想请教一下博主,就是我们看www.kernel.org上发行的内核里面,我看了很多个内核版本都是没有/driver/media/video/samsung/fimc这个目录的,我们要获取这个目录里面的代码是在哪里获取呢?
   
   回复ADC0809608:你好!我现在在做4412 的 ov5640驱动,我按照三星提供的S5KECG提供的驱动修改的,可以预览,也快以录像,但当拍照时,读寄存器CISTUS2(0x0068)为0,好像没用帧送到out_dma中,但我用示波器测了我的摄像头有信号输出,为什没有帧送出呢?
   回复ADC0809608:fimc是三星芯片 定制的这部分,像三星的s5pc110\s5pv210\s5pv310这些芯片的BSP程序包中,所以在linux官网下的内核里面没有,如果你有家个需要的話,发个邮箱,我可以发一个三星的内核程序包給你。
发表于 2015-10-15 00:26:19 | 显示全部楼层
不错,我不会呢
高级模式
B Color Image Link Quote Code Smilies @朋友

本版积分规则

在线客服

客服电话

欢迎来电咨询

188-9985 8350

微信关注

手机APP程序:
扫码下载访问

微信公众平台:
摄像头之家公众号

微信小程序:
摄像头小程序

返回顶部

QQ|站点统计|小黑屋|手机版|Archiver|摄像头模组论坛网-摄像头方案网CCM99 ( 粤ICP备18155214号 )

Powered by Discuz! X3.4 Licensed© 2001-2013 Comsenz Inc.