sefo
2017-01-01 14:06:37 UTC
Hi guys,
this is my first support request in a kernel mailinglist, so please dont
be too harsh if I make some mistakes, i try to obey the rules from
www.ideasonboard.org/uvc/faq/.
I want to stream a stereo Image from the ZED Stereo Camera
(www.stereolabs.com/) and do some hardware accelerated stereo
algorithms. My target platform is the xilinx zynq zedboard
(www.zedboard.org/product/zedboard). I use Kernel Version 4.6.0 cloned
from https://github.com/analogdevicesinc/linux, with a custom uio driver
for my hardware module synthesized into the programmable logic of the zynq.
The ZED Camera supports two resulutions in High-Speed Mode (2560x720 at
4fps and 3840x1080 at 2fps). I try to capture a few frames at the lower
of the both resolutions without any success. I wrote a simple Qt
application to capture the data via V4L2 and display the content. If I
run the application on my Host machine everything works fine. But when I
try to execute on the target, i am not able to get one single complete
frame from the camera. The expected frame size is about 3.7MB, but all I
get is between 37kB and 500kB of data (i read bytesused field from
struct v4l2_buffer, after DQBUF ioctl).
To figure out, if the problem lies in the USB Host Controller of the
zynq, i connected a simple UVC Webcam with ***@25fps (this is about
the same data rate as with the ZED). With this resolution everything
works as expected, without a single frame loss. The difference is that
the ZED Cam transfers the data through a Bulk Endpoint and the Webcam
thorough an ISOC. I thought this could be the reason, but i have no USB
Device connected beside the Camera which could steal the bandwidth of
the Bulk EP.
After enabling the trace of the uvc driver (please see the attachement),
i start digging around in the uvc_video driver and the UVC
Specification. I could figure out that there is an error reported in the
video payload header (D6 of bmHeaderInfo, as described in the UVC Spec).
It is written that in such a case, the "Stream Error Code" must be read,
to identify the error. As the driver does not handle this (or I just not
found the location) I tried to implement it on my own, by calling the
function below.
static void uvc_read_stream_error(struct work_struct *work)
{
int ret;
__u8 err_code;
struct uvc_streaming *stream;
struct my_work_struct* wrk = container_of(work, struct
my_work_struct, work);
stream = wrk->stream;
ret = __uvc_query_ctrl(stream->dev, UVC_GET_CUR, 0, stream->intfnum,
UVC_VS_STREAM_ERROR_CODE_CONTROL, &err_code,
1, uvc_timeout_param);
if (ret > 0)
printk(KERN_ERR "Stream error code = %d\n", (int)err_code);
}
if (data[1] & UVC_STREAM_ERR) {
wrk.stream = stream;
queue_work(err_wq, &wrk.work);
uvc_trace(UVC_TRACE_FRAME, "Marking buffer as bad (error bit "
"set).\n");
buf->error = 1;
}
Because I can not call the function directly from
uvc_video_decode_start() in drivers/media/usb/uvc/uvc_video.c, due to
the IRQ execution context of this function, i moved it to a work queue,
which i start with queue_work() on each detected error. But all i get is
an error code of 0, which means that there is no error.
Currently I have no solution to locate the problem of the incomplete
frames. I would appreciate any help.
Best Regards
Wadim
this is my first support request in a kernel mailinglist, so please dont
be too harsh if I make some mistakes, i try to obey the rules from
www.ideasonboard.org/uvc/faq/.
I want to stream a stereo Image from the ZED Stereo Camera
(www.stereolabs.com/) and do some hardware accelerated stereo
algorithms. My target platform is the xilinx zynq zedboard
(www.zedboard.org/product/zedboard). I use Kernel Version 4.6.0 cloned
from https://github.com/analogdevicesinc/linux, with a custom uio driver
for my hardware module synthesized into the programmable logic of the zynq.
The ZED Camera supports two resulutions in High-Speed Mode (2560x720 at
4fps and 3840x1080 at 2fps). I try to capture a few frames at the lower
of the both resolutions without any success. I wrote a simple Qt
application to capture the data via V4L2 and display the content. If I
run the application on my Host machine everything works fine. But when I
try to execute on the target, i am not able to get one single complete
frame from the camera. The expected frame size is about 3.7MB, but all I
get is between 37kB and 500kB of data (i read bytesused field from
struct v4l2_buffer, after DQBUF ioctl).
To figure out, if the problem lies in the USB Host Controller of the
zynq, i connected a simple UVC Webcam with ***@25fps (this is about
the same data rate as with the ZED). With this resolution everything
works as expected, without a single frame loss. The difference is that
the ZED Cam transfers the data through a Bulk Endpoint and the Webcam
thorough an ISOC. I thought this could be the reason, but i have no USB
Device connected beside the Camera which could steal the bandwidth of
the Bulk EP.
After enabling the trace of the uvc driver (please see the attachement),
i start digging around in the uvc_video driver and the UVC
Specification. I could figure out that there is an error reported in the
video payload header (D6 of bmHeaderInfo, as described in the UVC Spec).
It is written that in such a case, the "Stream Error Code" must be read,
to identify the error. As the driver does not handle this (or I just not
found the location) I tried to implement it on my own, by calling the
function below.
static void uvc_read_stream_error(struct work_struct *work)
{
int ret;
__u8 err_code;
struct uvc_streaming *stream;
struct my_work_struct* wrk = container_of(work, struct
my_work_struct, work);
stream = wrk->stream;
ret = __uvc_query_ctrl(stream->dev, UVC_GET_CUR, 0, stream->intfnum,
UVC_VS_STREAM_ERROR_CODE_CONTROL, &err_code,
1, uvc_timeout_param);
if (ret > 0)
printk(KERN_ERR "Stream error code = %d\n", (int)err_code);
}
if (data[1] & UVC_STREAM_ERR) {
wrk.stream = stream;
queue_work(err_wq, &wrk.work);
uvc_trace(UVC_TRACE_FRAME, "Marking buffer as bad (error bit "
"set).\n");
buf->error = 1;
}
Because I can not call the function directly from
uvc_video_decode_start() in drivers/media/usb/uvc/uvc_video.c, due to
the IRQ execution context of this function, i moved it to a work queue,
which i start with queue_work() on each detected error. But all i get is
an error code of 0, which means that there is no error.
Currently I have no solution to locate the problem of the incomplete
frames. I would appreciate any help.
Best Regards
Wadim