Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2165bc1a authored by Sriharsha Allenki's avatar Sriharsha Allenki
Browse files

usb: gadget: Support H264 format for f_uvc driver



Added support for H264 payload format and UVC 1.5
specification for existing f_uvc driver.

Change-Id: I2bad365dc6af7473bb2a62cc013da6e83c209811
Signed-off-by: default avatarSriharsha Allenki <sallenki@codeaurora.org>
parent 8e362602
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ static struct usb_interface_descriptor uvc_control_intf = {
	.bNumEndpoints		= 1,
	.bInterfaceClass	= USB_CLASS_VIDEO,
	.bInterfaceSubClass	= UVC_SC_VIDEOCONTROL,
	.bInterfaceProtocol	= 0x00,
	.bInterfaceProtocol	= 0x01,
	.iInterface		= 0,
};

@@ -121,7 +121,7 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt0 = {
	.bNumEndpoints		= 0,
	.bInterfaceClass	= USB_CLASS_VIDEO,
	.bInterfaceSubClass	= UVC_SC_VIDEOSTREAMING,
	.bInterfaceProtocol	= 0x00,
	.bInterfaceProtocol	= 0x01,
	.iInterface		= 0,
};

@@ -133,7 +133,7 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt1 = {
	.bNumEndpoints		= 1,
	.bInterfaceClass	= USB_CLASS_VIDEO,
	.bInterfaceSubClass	= UVC_SC_VIDEOSTREAMING,
	.bInterfaceProtocol	= 0x00,
	.bInterfaceProtocol	= 0x01,
	.iInterface		= 0,
};

+102 −8
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = {
	.bLength		= UVC_DT_HEADER_SIZE(1),
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VC_HEADER,
	.bcdUVC			= cpu_to_le16(0x0100),
	.bcdUVC			= cpu_to_le16(0x0150),
	.wTotalLength		= 0, /* dynamic */
	.dwClockFrequency	= cpu_to_le32(48000000),
	.bInCollection		= 0, /* dynamic */
@@ -52,7 +52,7 @@ static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = {
	.wObjectiveFocalLengthMax	= cpu_to_le16(0),
	.wOcularFocalLength		= cpu_to_le16(0),
	.bControlSize		= 3,
	.bmControls[0]		= 2,
	.bmControls[0]		= 14,
	.bmControls[1]		= 0,
	.bmControls[2]		= 0,
};
@@ -65,8 +65,8 @@ static const struct uvc_processing_unit_descriptor uvc_processing = {
	.bSourceID		= 1,
	.wMaxMultiplier		= cpu_to_le16(16*1024),
	.bControlSize		= 2,
	.bmControls[0]		= 1,
	.bmControls[1]		= 0,
	.bmControls[0]		= 64,
	.bmControls[1]		= 16,
	.iProcessing		= 0,
};

@@ -81,13 +81,13 @@ static const struct uvc_output_terminal_descriptor uvc_output_terminal = {
	.iTerminal		= 0,
};

DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 2);
DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(1, 3);

static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = {
	.bLength		= UVC_DT_INPUT_HEADER_SIZE(1, 2),
static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 3) uvc_input_header = {
	.bLength		= UVC_DT_INPUT_HEADER_SIZE(1, 3),
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VS_INPUT_HEADER,
	.bNumFormats		= 2,
	.bNumFormats		= 3,
	.wTotalLength		= 0, /* dynamic */
	.bEndpointAddress	= 0, /* dynamic */
	.bmInfo			= 0,
@@ -98,6 +98,7 @@ static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = {
	.bControlSize		= 1,
	.bmaControls[0][0]	= 0,
	.bmaControls[1][0]	= 4,
	.bmaControls[2][0]	= 0,
};

static const struct uvc_format_uncompressed uvc_format_yuv = {
@@ -205,6 +206,90 @@ static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = {
	.dwFrameInterval[0]	= cpu_to_le32(5000000),
};

static const struct uvc_format_h264 uvc_fmt_h264 = {
	.bLength				= UVC_DT_FORMAT_H264_SIZE,
	.bDescriptorType			= USB_DT_CS_INTERFACE,
	.bDescriptorSubType			= UVC_VS_FORMAT_H264,
	.bFormatIndex				= 3,
	.bNumFrameDescriptors			= 2,
	.bDefaultFrameIndex			= 1,
	.bMaxCodecConfigDelay			= 0x4,
	.bmSupportedSliceModes			= 0,
	.bmSupportedSyncFrameTypes		= 0x76,
	.bResolutionScaling			= 0,
	.Reserved1				= 0,
	.bmSupportedRateControlModes		= 0x3F,
	.wMaxMBperSecOneResNoScalability	= cpu_to_le16(972),
	.wMaxMBperSecTwoResNoScalability	= 0,
	.wMaxMBperSecThreeResNoScalability	= 0,
	.wMaxMBperSecFourResNoScalability	= 0,
	.wMaxMBperSecOneResTemporalScalability	= cpu_to_le16(972),
	.wMaxMBperSecTwoResTemporalScalability	= 0,
	.wMaxMBperSecThreeResTemporalScalability	= 0,
	.wMaxMBperSecFourResTemporalScalability		= 0,
	.wMaxMBperSecOneResTemporalQualityScalability	= cpu_to_le16(972),
	.wMaxMBperSecTwoResTemporalQualityScalability	= 0,
	.wMaxMBperSecThreeResTemporalQualityScalability	= 0,
	.wMaxMBperSecFourResTemporalQualityScalability	= 0,
	.wMaxMBperSecOneResTemporalSpatialScalability	= 0,
	.wMaxMBperSecTwoResTemporalSpatialScalability	= 0,
	.wMaxMBperSecThreeResTemporalSpatialScalability	= 0,
	.wMaxMBperSecFourResTemporalSpatialScalability	= 0,
	.wMaxMBperSecOneResFullScalability		= 0,
	.wMaxMBperSecTwoResFullScalability		= 0,
	.wMaxMBperSecThreeResFullScalability		= 0,
	.wMaxMBperSecFourResFullScalability		= 0,
};

DECLARE_UVC_FRAME_H264(1);
DECLARE_UVC_FRAME_H264(3);

static const struct UVC_FRAME_H264(1) uvc_frame_h264_1920p = {
	.bLength		= UVC_DT_FRAME_H264_SIZE(1),
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VS_FRAME_H264,
	.bFrameIndex		= 1,
	.wWidth			= cpu_to_le16(3840),
	.wHeight		= cpu_to_le16(1920),
	.wSARwidth		= 0,
	.wSARheight		= 0,
	.wProfile		= 0x6400,
	.bLevelIDC		= 0x33,
	.bmSupportedUsages	= 0x70003,
	.wConstrainedToolset	= cpu_to_le16(0),
	.bmCapabilities		= 0x47,
	.bmSVCCapabilities	= 0x4,
	.bmMVCCapabilities	= 0,
	.dwMinBitRate		= cpu_to_le16(29491200),
	.dwMaxBitRate		= cpu_to_le16(100000000),
	.dwDefaultFrameInterval	= cpu_to_le16(333667),
	.bNumFrameIntervals	= 1,
	.dwFrameInterval[0]	= cpu_to_le16(333667),
};

static const struct UVC_FRAME_H264(3) uvc_frame_h264_960p = {
	.bLength		= UVC_DT_FRAME_H264_SIZE(3),
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VS_FRAME_H264,
	.bFrameIndex		= 2,
	.wWidth			= cpu_to_le16(1920),
	.wHeight		= cpu_to_le16(960),
	.wSARwidth		= 0,
	.wSARheight		= 0,
	.wProfile		= 0x6400,
	.bLevelIDC		= 0x28,
	.bmSupportedUsages	= 0x70003,
	.wConstrainedToolset	= cpu_to_le16(0),
	.bmCapabilities		= 0x47,
	.bmSVCCapabilities	= 0x4,
	.bmMVCCapabilities	= 0,
	.dwMinBitRate		= cpu_to_le16(29491200),
	.dwMaxBitRate		= cpu_to_le16(100000000),
	.dwDefaultFrameInterval	= cpu_to_le16(333667),
	.bNumFrameIntervals	= 1,
	.dwFrameInterval[0]	= cpu_to_le16(333667),
};

static const struct uvc_color_matching_descriptor uvc_color_matching = {
	.bLength		= UVC_DT_COLOR_MATCHING_SIZE,
	.bDescriptorType	= USB_DT_CS_INTERFACE,
@@ -238,6 +323,9 @@ static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = {
	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
	(const struct uvc_descriptor_header *) &uvc_fmt_h264,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_960p,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_1920p,
	(const struct uvc_descriptor_header *) &uvc_color_matching,
	NULL,
};
@@ -250,6 +338,9 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
	(const struct uvc_descriptor_header *) &uvc_fmt_h264,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_960p,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_1920p,
	(const struct uvc_descriptor_header *) &uvc_color_matching,
	NULL,
};
@@ -262,6 +353,9 @@ static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = {
	(const struct uvc_descriptor_header *) &uvc_format_mjpg,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
	(const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
	(const struct uvc_descriptor_header *) &uvc_fmt_h264,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_960p,
	(const struct uvc_descriptor_header *) &uvc_frame_h264_1920p,
	(const struct uvc_descriptor_header *) &uvc_color_matching,
	NULL,
};
+93 −0
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@
#define UVC_VS_FORMAT_FRAME_BASED			0x10
#define UVC_VS_FRAME_FRAME_BASED			0x11
#define UVC_VS_FORMAT_STREAM_BASED			0x12
#define UVC_VS_FORMAT_H264				0x13
#define UVC_VS_FRAME_H264				0x14

/* A.7. Video Class-Specific Endpoint Descriptor Subtypes */
#define UVC_EP_UNDEFINED				0x00
@@ -564,5 +566,96 @@ struct UVC_FRAME_MJPEG(n) { \
	__u32 dwFrameInterval[n];			\
} __attribute__ ((packed))

/* H264 Payload - 3.1.1. H264 Video Format Descriptor */
struct uvc_format_h264 {
	__u8  bLength;
	__u8  bDescriptorType;
	__u8  bDescriptorSubType;
	__u8  bFormatIndex;
	__u8  bNumFrameDescriptors;
	__u8  bDefaultFrameIndex;
	__u8  bMaxCodecConfigDelay;
	__u8  bmSupportedSliceModes;
	__u8  bmSupportedSyncFrameTypes;
	__u8  bResolutionScaling;
	__u8  Reserved1;
	__u8  bmSupportedRateControlModes;
	__u16 wMaxMBperSecOneResNoScalability;
	__u16 wMaxMBperSecTwoResNoScalability;
	__u16 wMaxMBperSecThreeResNoScalability;
	__u16 wMaxMBperSecFourResNoScalability;
	__u16 wMaxMBperSecOneResTemporalScalability;
	__u16 wMaxMBperSecTwoResTemporalScalability;
	__u16 wMaxMBperSecThreeResTemporalScalability;
	__u16 wMaxMBperSecFourResTemporalScalability;
	__u16 wMaxMBperSecOneResTemporalQualityScalability;
	__u16 wMaxMBperSecTwoResTemporalQualityScalability;
	__u16 wMaxMBperSecThreeResTemporalQualityScalability;
	__u16 wMaxMBperSecFourResTemporalQualityScalability;
	__u16 wMaxMBperSecOneResTemporalSpatialScalability;
	__u16 wMaxMBperSecTwoResTemporalSpatialScalability;
	__u16 wMaxMBperSecThreeResTemporalSpatialScalability;
	__u16 wMaxMBperSecFourResTemporalSpatialScalability;
	__u16 wMaxMBperSecOneResFullScalability;
	__u16 wMaxMBperSecTwoResFullScalability;
	__u16 wMaxMBperSecThreeResFullScalability;
	__u16 wMaxMBperSecFourResFullScalability;
} __attribute__((__packed__));

#define UVC_DT_FORMAT_H264_SIZE		52

/* H264 Payload - 3.1.2. H264 Video Frame Descriptor */
struct uvc_frame_h264 {
	__u8  bLength;
	__u8  bDescriptorType;
	__u8  bDescriptorSubType;
	__u8  bFrameIndex;
	__u16 wWidth;
	__u16 wHeight;
	__u16 wSARwidth;
	__u16 wSARheight;
	__u16 wProfile;
	__u8  bLevelIDC;
	__u16 wConstrainedToolset;
	__u32 bmSupportedUsages;
	__u16 bmCapabilities;
	__u32 bmSVCCapabilities;
	__u32 bmMVCCapabilities;
	__u32 dwMinBitRate;
	__u32 dwMaxBitRate;
	__u32 dwDefaultFrameInterval;
	__u8  bNumFrameIntervals;
	__u32 dwFrameInterval[];
} __attribute__((__packed__));

#define UVC_DT_FRAME_H264_SIZE(n)			(44+4*(n))

#define UVC_FRAME_H264(n) \
	uvc_frame_h264_##n

#define DECLARE_UVC_FRAME_H264(n)			\
struct UVC_FRAME_H264(n) {				\
	__u8  bLength;					\
	__u8  bDescriptorType;				\
	__u8  bDescriptorSubType;			\
	__u8  bFrameIndex;				\
	__u16 wWidth;					\
	__u16 wHeight;					\
	__u16 wSARwidth;				\
	__u16 wSARheight;				\
	__u16 wProfile;					\
	__u8  bLevelIDC;				\
	__u16 wConstrainedToolset;			\
	__u32 bmSupportedUsages;			\
	__u16 bmCapabilities;				\
	__u32 bmSVCCapabilities;			\
	__u32 bmMVCCapabilities;			\
	__u32 dwMinBitRate;				\
	__u32 dwMaxBitRate;				\
	__u32 dwDefaultFrameInterval;			\
	__u8  bNumFrameIntervals;			\
	__u32 dwFrameInterval[n];			\
} __attribute__ ((packed))

#endif /* __LINUX_USB_VIDEO_H */