基于CX3的UVC摄像头应用学习笔记-七(添加其他分辨率)
在本篇 blog 中,我们学习如何在固件中已有的分辨率基础上,添加新的分辨率。本篇 blog ,我们在上一篇 blog 的固件的基础上进行修改,所以用的硬件还是CX3 Denebola RDK。原固件中只定义了 1080P@30fps,此处我们增加 720P@60fps。
- 首先我们需要在描述符文件中添加相应的 frame descriptor。
/* Class specific Uncompressed VS frame descriptor 2 - 720p@ 60fps*/
0x1E, /* Descriptor size */
CX3_CS_INTRFC_DESCR, /* Descriptor type*/
0x05, /* Subtype: Uncompressed frame interface*/
0x02, /* Frame Descriptor Index: 2 */
0x00, /* No Still image capture supported */
0x00, 0x05, /* Width in pixel: 1280 */
0xD0, 0x02, /* Height in pixel: 720 */
0x00, 0x00, 0x57, 0x30, /* Min bit rate @55fps (bits/s): 720 x 1280 x 2 x 55 x 8 = 811008000 */
0x00, 0x00, 0xBC, 0x34, /* Max bit rate @60fps (bits/s). 720 x 1280 x 2 x 60 x 8 = 884736000 */
0x00, 0x20, 0x1C, 0x00, /* Maximum video frame size in bytes(Deprecated): 1280 x 720 x 2 */
0x0A, 0x8B, 0x02, 0x00, /* Default frame interval (in 100ns units): (1/60)x10^7 */
0x01, /* Frame interval type : No of discrete intervals */
0x0A, 0x8B, 0x02, 0x00, /* Frame interval 3: Same as Default frame interval */
可以看到,此处定义720P@60fps 的frame index 为2.
2. 修改 VS format descriptor 中的 frame descriptor 的个数。
0x02, /* Number of Frame Descriptors that follow this descriptor: 2 */
3. 修改 Class-specific Video Streaming Input Header Descriptor 中的 Total size of Class specific VS descr.
/* Class-specific Video Streaming Input Header Descriptor */
0x0E, /* Descriptor size */
CX3_CS_INTRFC_DESCR, /* Class-specific VS I/f Type */
0x01, /* Descriptor Subtype: Input Header */
0x01, /* 1 format desciptor follows */
#ifdef Two_frame_rate
// 0x56,0x00, /* Total size of Class specific VS descr */
0x74,0x00, /* Total size of Class specific VS descr */
#else
0x52,0x00, /* Total size of Class specific VS descr */
#endif
CX3_EP_BULK_VIDEO, /* EP address for BULK video data: EP 3 IN */
0x00, /* No dynamic format change supported */
0x04, /* Output terminal ID : 4 */
0x02, /* > Still image capture method supported */
0x00, /* Hardware trigger NOT supported */
0x00, /* Hardware to initiate still image capture not supported */
0x01, /* Size of controls field : 1 byte */
0x00, /* D2 : Compression quality supported - No compression*/
4. 修改 configuration descriptor 的总长度
/* Configuration Descriptor*/
0x09, /* Descriptor Size */
CY_U3P_USB_CONFIG_DESCR, /* Configuration Descriptor Type */
#ifdef Two_frame_rate
// 0xe9,0x00, /* Length of this descriptor and all sub descriptors */
0x07,0x01, /* Length of this descriptor and all sub descriptors */
#else
0xe5,0x00, /* Length of this descriptor and all sub descriptors */
#endif
0x02, /* Number of interfaces */
0x01, /* Configuration number */
0x03, /* Configuration string index */
0xC0, /* Config characteristics - Self Powered */
0x0C, /* Max power consumption of device (in 8mA unit) : 96mA */
5. 添加 Probe structure
/* UVC Probe Control Setting - 720p@60fps*/
uint8_t const gl720pProbeCtrl[CX3_APP_MAX_PROBE_SETTING] = {
0x00, 0x00, /* bmHint : No fixed parameters */
0x01, /* Use 1st Video format index */
0x02, /* Use 2nd Video frame index */
0x0A, 0x8B, 0x02, 0x00, /* Desired frame interval in 100ns = (1/60)x10^7*/
0x00, 0x00, /* Key frame rate in key frame/video frame units */
0x00, 0x00, /* PFrame rate in PFrame / key frame units */
0x00, 0x00, /* Compression quality control */
0x00, 0x00, /* Window size for average bit rate */
0x00, 0x00, /* Internal video streaming i/f latency in ms */
0x00, 0x20, 0x1C, 0x00, /* Max video frame size in bytes: 720 x 1280 x 2*/
#ifdef CX3_UVC_1_0_SUPPORT
0x00, 0x90, 0x00, 0x00 /* No. of bytes device can rx in single payload: 36KB */
#else
/* UVC 1.1 Probe Control has additional fields from UVC 1.0 */
0x00, 0x90, 0x00, 0x00, /* No. of bytes device can rx in single payload: 36KB */
0x00, 0x60, 0xE3, 0x16, /* Device Clock */
0x00, /* Framing Information - Ignored for uncompressed format*/
0x00, /* Preferred payload format version */
0x00, /* Minimum payload format version */
0x00 /* Maximum payload format version */
#endif
};
6. 在添加 if 分支 以向主机返回相应的 Probe structure
/*Returns the pointer to the Probe Control structure for the corresponding frame index.*/
uint8_t *
CyCx3UvcAppGetProbeControlData (
CyU3PUSBSpeed_t usbConType,
uint8_t frameIndex,
uint32_t glCurrentFrameInterval
)
{
uint32_t frame_fps = 10000000 / glCurrentFrameInterval;
if (usbConType == CY_U3P_SUPER_SPEED)
{
if (frameIndex == 1)
{
if(frame_fps == 30)
{
/* 1920 x 1080 @30.0 fps */
CyU3PDebugPrint(4,"\n Line:%d: Return 30 fps structure",__LINE__);
return ((uint8_t *) gl1080pProbeCtrl_30fps);
}
else if(frame_fps == 60)
{ /* 1920 x 1080 @60.0 fps */
CyU3PDebugPrint(4,"\n Line:%d Return 60 fps structure",__LINE__);
return ((uint8_t *) gl1080pProbeCtrl_60fps);
}
}
else if (frameIndex == 2)
{
return ((uint8_t *) gl720pProbeCtrl);
}
}
else if (usbConType == CY_U3P_HIGH_SPEED)
{
}
else
{
}
return NULL;
}
7. 添加 720P 对应的 MIPI CSI 初始化参数 结构体,此处我们直接添加 SDK 目录下的 Cx3UVCOV5640 例子中的参数。用户在使用其他sensor以及添加其他分辨率的支持时,需要首先确认 sensor 的配置参数,将参数输入到 MIPI configuration tool 里面进行计算,从而找到一组合适 的 MIPI CSI的初始化参数。需要注意的是,同样一组sensor 的 配置参数,与之对应的MIPI CSI 初始化参数不止一组,找到一组可用值即可。用户在MIPI configuration tool里面也可以看到, 很多参数都是有一个允许的取值范围,而不是唯一值。
/* Configuration parameters for 720p @60FPS for the OV5640 sensor */
CyU3PMipicsiCfg_t cfgUvc720p60NoMclk = {
CY_U3P_CSI_DF_YUV422_8_2, /* dataFormat */
2, /* numDataLanes */
1, /* pllPrd */
62, /* pllFbd */
CY_U3P_CSI_PLL_FRS_250_500M, /* pllFrs */
CY_U3P_CSI_PLL_CLK_DIV_4, /* csiRxClkDiv */
CY_U3P_CSI_PLL_CLK_DIV_4, /* parClkDiv */
0x00, /* mclkCtl */
CY_U3P_CSI_PLL_CLK_DIV_8, /* mClkRefDiv */
1280, /* hResolution */
0x01 /* fifoDelay */
};
8. 在 SetVideoResolution 中添加720P对应分支。
static void
CyCx3UvcAppImageSensorSetVideoResolution(
uint8_t resolution_index,
uint32_t frame_Interval
)
{
CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
uint32_t frameRate= 10000000/frame_Interval;
switch (CyU3PUsbGetSpeed ())
{
case CY_U3P_SUPER_SPEED:
switch (resolution_index)
{
case 0x01:
{
if(frameRate == 30)
{
CyU3PDebugPrint(4,"\r\n Line:%d: Set 30 fps",__LINE__);
/* Write 1080pSettings */
#ifndef FX3_STREAMING
status = CyU3PMipicsiSetIntfParams (&OV5640_YUY2_1080p, CyFalse);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\n\rUSBStpCB:SetIntfParams SS1 Err = 0x%x", status);
}
#endif
CyCx3_ImageSensor_Set_1080p ();
}
else if (frameRate == 60)
{
CyU3PDebugPrint(4,"\r\n Line:%d: Set 60 fps",__LINE__);
/* Write 1080pSettings */
#ifndef FX3_STREAMING
status = CyU3PMipicsiSetIntfParams (&OV5640_YUY2_1080p, CyFalse);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\n\rUSBStpCB:SetIntfParams SS1 Err = 0x%x", status);
}
#endif
CyCx3_ImageSensor_Set_1080p ();
}
}
break;
case 0x02:
{
CyU3PDebugPrint(4,"\r\n Line:%d: Set 720P@60fps",__LINE__);
/* Write 720pSettings */
#ifndef FX3_STREAMING
status = CyU3PMipicsiSetIntfParams (&cfgUvc720p60NoMclk, CyFalse);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\n\rUSBStpCB:SetIntfParams SS1 Err = 0x%x", status);
}
#endif
CyCx3_ImageSensor_Set_720p ();
}
break;
}
break;
case CY_U3P_HIGH_SPEED:
switch (resolution_index)
{
}
break;
}
}
至此,固件修改完成。编译并下载到Demo 板中测试。可以看到,现在固件可以支持 720P@60fps 的视频传输。
同样,附件提供修改后的固件,供用户参考。