usb: gadget: uvc: set req_length based on payload by nreqs instead of req_size
Compressed formats generate content depending amount of data that is set in the vb2 buffer by the payload_size. When streaming those formats it is better to scatter that smaller data over all requests. This patch is doing that by introducing the calculated req_payload_size which is updated by each frame. It the uses this amount of data to fill the isoc requests instead of the video->req_size. For uncompressed formats it will not make a difference since the payload size will be equal to the imagesize. Therefore the code will have no effecta as req_payload_size will be equal to req_size. Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Link: https://lore.kernel.org/r/20240403-uvc_request_length_by_interval-v7-6-e224bb1035f0@pengutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
48dbe73117
commit
98ad032915
@@ -110,6 +110,8 @@ struct uvc_video {
|
||||
|
||||
unsigned int uvc_num_requests;
|
||||
|
||||
unsigned int reqs_per_frame;
|
||||
|
||||
/* Requests */
|
||||
bool is_enabled; /* tracks whether video stream is enabled */
|
||||
unsigned int req_size;
|
||||
|
||||
@@ -58,6 +58,7 @@ static int uvc_queue_setup(struct vb2_queue *vq,
|
||||
static int uvc_buffer_prepare(struct vb2_buffer *vb)
|
||||
{
|
||||
struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct uvc_video *video = container_of(queue, struct uvc_video, queue);
|
||||
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
||||
struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf);
|
||||
|
||||
@@ -78,10 +79,15 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
|
||||
buf->mem = vb2_plane_vaddr(vb, 0);
|
||||
}
|
||||
buf->length = vb2_plane_size(vb, 0);
|
||||
if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
||||
buf->bytesused = 0;
|
||||
else
|
||||
} else {
|
||||
buf->bytesused = vb2_get_plane_payload(vb, 0);
|
||||
buf->req_payload_size =
|
||||
DIV_ROUND_UP(buf->bytesused +
|
||||
(video->reqs_per_frame * UVCG_REQUEST_HEADER_LEN),
|
||||
video->reqs_per_frame);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ struct uvc_buffer {
|
||||
unsigned int offset;
|
||||
unsigned int length;
|
||||
unsigned int bytesused;
|
||||
/* req_payload_size: only used with isoc */
|
||||
unsigned int req_payload_size;
|
||||
};
|
||||
|
||||
#define UVC_QUEUE_DISCONNECTED (1 << 0)
|
||||
|
||||
@@ -136,7 +136,7 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
|
||||
unsigned int pending = buf->bytesused - video->queue.buf_used;
|
||||
struct uvc_request *ureq = req->context;
|
||||
struct scatterlist *sg, *iter;
|
||||
unsigned int len = video->req_size;
|
||||
unsigned int len = buf->req_payload_size;
|
||||
unsigned int sg_left, part = 0;
|
||||
unsigned int i;
|
||||
int header_len;
|
||||
@@ -146,15 +146,15 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
|
||||
|
||||
/* Init the header. */
|
||||
header_len = uvc_video_encode_header(video, buf, ureq->header,
|
||||
video->req_size);
|
||||
buf->req_payload_size);
|
||||
sg_set_buf(sg, ureq->header, header_len);
|
||||
len -= header_len;
|
||||
|
||||
if (pending <= len)
|
||||
len = pending;
|
||||
|
||||
req->length = (len == pending) ?
|
||||
len + header_len : video->req_size;
|
||||
req->length = (len == pending) ? len + header_len :
|
||||
buf->req_payload_size;
|
||||
|
||||
/* Init the pending sgs with payload */
|
||||
sg = sg_next(sg);
|
||||
@@ -202,7 +202,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
|
||||
{
|
||||
void *mem = req->buf;
|
||||
struct uvc_request *ureq = req->context;
|
||||
int len = video->req_size;
|
||||
int len = buf->req_payload_size;
|
||||
int ret;
|
||||
|
||||
/* Add the header. */
|
||||
@@ -214,7 +214,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
|
||||
ret = uvc_video_encode_data(video, buf, mem, len);
|
||||
len -= ret;
|
||||
|
||||
req->length = video->req_size - len;
|
||||
req->length = buf->req_payload_size - len;
|
||||
|
||||
if (buf->bytesused == video->queue.buf_used ||
|
||||
video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) {
|
||||
@@ -504,7 +504,7 @@ uvc_video_prep_requests(struct uvc_video *video)
|
||||
|
||||
if (!usb_endpoint_xfer_isoc(video->ep->desc)) {
|
||||
video->req_size = max_req_size;
|
||||
video->uvc_num_requests =
|
||||
video->reqs_per_frame = video->uvc_num_requests =
|
||||
DIV_ROUND_UP(video->imagesize, max_req_size);
|
||||
|
||||
return;
|
||||
@@ -535,6 +535,7 @@ uvc_video_prep_requests(struct uvc_video *video)
|
||||
* able to fully encode one frame.
|
||||
*/
|
||||
video->uvc_num_requests = nreq + UVCG_REQ_MAX_ZERO_COUNT;
|
||||
video->reqs_per_frame = nreq;
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
Reference in New Issue
Block a user