Hi, I am trying to use the previewer to debayer pictures coming from the filesystem instead of the capture hardware. The media-ctl links are as follows : preview V4L input -> preview pad 0 (sink), preview pad 1(src) ->preview V4L output. Input output format is set via media-ctl for the preview element, and via the V4L2 api for the V4L2 file descriptors. I am using USERPTR buffer allocated via memalign, and the application goes like this : REQBUFS 1 buf on on input REQBUFS 1 buf on output alloc buffers QBUF on input QBUF on output STREAMON on output STREAMON on input DQBUF on output. The board either panics or hangs (though HUNG_TASK_DETECTION and SOFT_LOCKUP_DETECTION is set) Please find attached the panic log, and the application code.
Attachment:
session.log
Description: Binary data
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/videodev2.h> #include <malloc.h> #include "videobuf.h" #define WIDTH 3664 #define HEIGHT 2752 const char * v4l2_input = "/dev/video3"; const char * v4l2_output = "/dev/video4"; vbuf_desc ibuf; vbuf_desc obuf; #define XIOCTL(fd, name, data) do { \ int rc; \ rc = ioctl(fd, name, data); \ if(rc < 0) { \ perror(#name); \ exit(EXIT_FAILURE); \ } \ } while(0) static long filesize(FILE * stream) { long offs; fseek(stream, 0, SEEK_END); offs = ftell(stream); rewind(stream); return offs; } int main(int argc, char **argv) { int ifd, ofd; FILE * istream, * ostream; struct v4l2_format fmt; struct v4l2_pix_format ipfmt; struct v4l2_pix_format opfmt; struct v4l2_requestbuffers req; struct v4l2_buffer v4l2buf; unsigned char * line; char * fname; long fsize; int l; // open video fds ifd = open(v4l2_input, O_RDWR); if(ifd < 0) { perror(v4l2_input); exit(EXIT_FAILURE); } ofd = open(v4l2_output, O_RDWR); if(ofd < 0) { perror(v4l2_output); exit(EXIT_FAILURE); } // get / set input pixel format at SBGGR10 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ipfmt.width = WIDTH; ipfmt.height = HEIGHT; fmt.fmt.pix = ipfmt; XIOCTL(ifd, VIDIOC_TRY_FMT, &fmt); ipfmt = fmt.fmt.pix; printf("input is %d x %d\n", ipfmt.width, ipfmt.height); XIOCTL(ifd, VIDIOC_S_FMT, &fmt); printf("bytesperline is %d\n",ipfmt.bytesperline); printf("sizeimage is %d\n",ipfmt.sizeimage); // allocate input buffer // allocate output buffer via malloc ibuf.length = ipfmt.sizeimage; ibuf.usrptr = memalign(32, ibuf.length); line = malloc(ipfmt.width); // request buffer in driver req.count = 1; req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; req.memory = V4L2_MEMORY_USERPTR; XIOCTL(ifd, VIDIOC_REQBUFS, &req); // get / set output pixel format fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; XIOCTL(ofd, VIDIOC_TRY_FMT, &fmt); opfmt = fmt.fmt.pix; printf("output is %d x %d\n", opfmt.width, opfmt.height); printf("bytesperline is %d\n",opfmt.bytesperline); printf("sizeimage is %d\n",opfmt.sizeimage); XIOCTL(ofd, VIDIOC_S_FMT, &fmt); // allocate output buffer via malloc obuf.length = fmt.fmt.pix.sizeimage; obuf.usrptr = memalign(32, obuf.length); req.count = 1; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_USERPTR; XIOCTL(ofd, VIDIOC_REQBUFS, &req); // open input file if(argc < 2) { printf("please provide a input file to debayer"); } fname = argv[1]; printf("Opening %s for debayering\n", fname); istream = fopen(fname, "r"); if(!istream) { perror(fname); exit(EXIT_FAILURE); } fsize = filesize(istream); if(fsize != ipfmt.width * ipfmt.height) { if(fsize < ipfmt.width * ipfmt.height) { printf("File is too short fot current input : %d < %d\n", fsize, ipfmt.width * ipfmt.height); exit(EXIT_FAILURE); } else { printf("Warning : too many data in input file\n"); } } // read 8 bit pixel line for(l = 0; l < ipfmt.height; l++) { int idx; fread(line, 1, ipfmt.width, istream); // transform and store 8 bit input line to 10 bit in input buffer for(idx = 0; idx < ipfmt.width; idx++) { unsigned short * pix; pix = (unsigned short *)&ibuf.usrptr[l * ipfmt.bytesperline + idx * 2]; *pix = line[idx] * 4; } } // queue input buf, queue output buf v4l2buf.index = 0; v4l2buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; v4l2buf.memory = V4L2_MEMORY_USERPTR; v4l2buf.m.userptr = ibuf.usrptr; v4l2buf.length = ibuf.length; printf("usrptr = 0x%x \n", v4l2buf.m.userptr); printf("v4l2buf.length = %d\n",ibuf.length); XIOCTL(ifd, VIDIOC_QBUF, &v4l2buf); printf("input buffer queued\n"); v4l2buf.index = 0; v4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2buf.memory = V4L2_MEMORY_USERPTR; v4l2buf.m.userptr = obuf.usrptr; v4l2buf.length = obuf.length; XIOCTL(ofd, VIDIOC_QBUF, &v4l2buf); printf("output buffer queued\n"); // streamon XIOCTL(ofd, VIDIOC_STREAMON, &v4l2buf.type); //printf("output streamon\n"); v4l2buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; XIOCTL(ifd, VIDIOC_STREAMON, &v4l2buf.type); //printf("input streamon\n"); // dequeue output buffer v4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; XIOCTL(ofd, VIDIOC_DQBUF, &v4l2buf); // store buffer data in output file ostream = fopen("output.yuv", "w"); for(l = 0; l < opfmt.height; l++) { fwrite(&obuf.usrptr[l*opfmt.width*2], 2, opfmt.width, ostream); } fclose(ostream); return 0; }