Re: [PATCH] v4l2-ctl: add is_compressed_format() helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu April 11 2013 20:07:01 Tzu-Jung Lee wrote:
> It is used to:
> 
>   bypass precalculate_bars() for OUTPUT device
>   that takes encoded bitstreams.
> 
>   handle the last chunk of input file that has
>   non-buffer-aligned size.

This seems to be the third version of this patch. When you post a new
version, can you 1) add a version number after 'PATCH' (e.g. [PATCHv3])
and 2) mention the differences since the previous version.

That makes a reviewer's life a lot easier.

Thanks!

	Hans

> 
> Signed-off-by: Tzu-Jung Lee <tjlee@xxxxxxxxxxxxx>
> ---
>  utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 132 ++++++++++++++++++++++++++++------
>  1 file changed, 112 insertions(+), 20 deletions(-)
> 
> diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
> index 9e361af..44643e8 100644
> --- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
> +++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
> @@ -115,6 +115,29 @@ static const flag_def tc_flags_def[] = {
>  	{ 0, NULL }
>  };
>  
> +static bool is_compressed_format(__u32 pixfmt)
> +{
> +	switch (pixfmt) {
> +	case V4L2_PIX_FMT_MJPEG:
> +	case V4L2_PIX_FMT_JPEG:
> +	case V4L2_PIX_FMT_DV:
> +	case V4L2_PIX_FMT_MPEG:
> +	case V4L2_PIX_FMT_H264:
> +	case V4L2_PIX_FMT_H264_NO_SC:
> +	case V4L2_PIX_FMT_H263:
> +	case V4L2_PIX_FMT_MPEG1:
> +	case V4L2_PIX_FMT_MPEG2:
> +	case V4L2_PIX_FMT_MPEG4:
> +	case V4L2_PIX_FMT_XVID:
> +	case V4L2_PIX_FMT_VC1_ANNEX_G:
> +		return true;
> +	default:
> +		return false;
> +	}
> +
> +	return false;
> +}
> +
>  static void print_buffer(FILE *f, struct v4l2_buffer &buf)
>  {
>  	fprintf(f, "\tIndex    : %d\n", buf.index);
> @@ -223,25 +246,60 @@ void streaming_cmd(int ch, char *optarg)
>  }
>  
>  static bool fill_buffer_from_file(void *buffers[], unsigned buffer_lengths[],
> -		unsigned buf_index, unsigned num_planes, FILE *fin)
> +				  unsigned buffer_bytesused[], unsigned buf_index,
> +				  unsigned num_planes, bool is_compressed, FILE *fin)
>  {
> +	if (num_planes == 1) {
> +		unsigned i = buf_index;
> +		unsigned sz = fread(buffers[i], 1,
> +				    buffer_lengths[i], fin);
> +
> +		buffer_bytesused[i] = sz;
> +		if (sz == 0 && stream_loop) {
> +			fseek(fin, 0, SEEK_SET);
> +			sz = fread(buffers[i], 1,
> +				   buffer_lengths[i], fin);
> +
> +			buffer_bytesused[i] = sz;
> +		}
> +
> +		if (!sz)
> +			return false;
> +
> +		if (sz == buffer_lengths[i])
> +			return true;
> +
> +		if (is_compressed)
> +			return true;
> +
> +		fprintf(stderr, "%u != %u\n", sz, buffer_lengths[i]);
> +
> +		return false;
> +	}
> +
>  	for (unsigned j = 0; j < num_planes; j++) {
>  		unsigned p = buf_index * num_planes + j;
>  		unsigned sz = fread(buffers[p], 1,
> -				buffer_lengths[p], fin);
> +				    buffer_lengths[p], fin);
>  
> +		buffer_bytesused[j] = sz;
>  		if (j == 0 && sz == 0 && stream_loop) {
>  			fseek(fin, 0, SEEK_SET);
>  			sz = fread(buffers[p], 1,
> -					buffer_lengths[p], fin);
> +				   buffer_lengths[p], fin);
> +
> +			buffer_bytesused[j] = sz;
>  		}
>  		if (sz == buffer_lengths[p])
>  			continue;
> +
> +		// Bail out if we get weird buffer sizes.
>  		if (sz)
>  			fprintf(stderr, "%u != %u\n", sz, buffer_lengths[p]);
> -		// Bail out if we get weird buffer sizes.
> +
>  		return false;
>  	}
> +
>  	return true;
>  }
>  
> @@ -312,16 +370,22 @@ static void do_setup_out_buffers(int fd, struct v4l2_requestbuffers *reqbufs,
>  				 bool is_mplane, unsigned &num_planes, bool is_mmap,
>  				 void *buffers[], unsigned buffer_lengths[], FILE *fin)
>  {
> +	bool is_compressed;
> +
>  	struct v4l2_format fmt;
>  	memset(&fmt, 0, sizeof(fmt));
>  	fmt.type = reqbufs->type;
>  	doioctl(fd, VIDIOC_G_FMT, &fmt);
>  
> -	if (!precalculate_bars(fmt.fmt.pix.pixelformat, stream_pat)) {
> +	is_compressed = is_compressed_format(fmt.fmt.pix.pixelformat);
> +	if (!is_compressed &&
> +	    !precalculate_bars(fmt.fmt.pix.pixelformat, stream_pat)) {
>  		fprintf(stderr, "unsupported pixelformat\n");
>  		return;
>  	}
>  
> +	unsigned buffer_bytesused[reqbufs->count * VIDEO_MAX_PLANES];
> +
>  	for (unsigned i = 0; i < reqbufs->count; i++) {
>  		struct v4l2_plane planes[VIDEO_MAX_PLANES];
>  		struct v4l2_buffer buf;
> @@ -363,11 +427,11 @@ static void do_setup_out_buffers(int fd, struct v4l2_requestbuffers *reqbufs,
>  			// TODO fill_buffer_mp(buffers[i], &fmt.fmt.pix_mp);
>  			if (fin)
>  				fill_buffer_from_file(buffers, buffer_lengths,
> -						      buf.index, num_planes, fin);
> +						      buffer_bytesused, buf.index,
> +						      num_planes, is_compressed, fin);
>  		}
>  		else {
>  			buffer_lengths[i] = buf.length;
> -			buf.bytesused = buf.length;
>  			if (is_mmap) {
>  				buffers[i] = mmap(NULL, buf.length,
>  						  PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
> @@ -381,9 +445,16 @@ static void do_setup_out_buffers(int fd, struct v4l2_requestbuffers *reqbufs,
>  				buffers[i] = calloc(1, buf.length);
>  				buf.m.userptr = (unsigned long)buffers[i];
>  			}
> -			if (!fin || !fill_buffer_from_file(buffers, buffer_lengths,
> -							   buf.index, num_planes, fin))
> +
> +			if (fin && fill_buffer_from_file(buffers, buffer_lengths,
> +							 buffer_bytesused, buf.index,
> +							 num_planes, is_compressed,
> +							 fin)) {
> +				buf.bytesused = buffer_bytesused[buf.index];
> +			}
> +			else {
>  				fill_buffer(buffers[i], &fmt.fmt.pix);
> +			}
>  		}
>  		if (doioctl(fd, VIDIOC_QBUF, &buf))
>  			return;
> @@ -511,12 +582,13 @@ static int do_handle_cap(int fd, struct v4l2_requestbuffers *reqbufs,
>  }
>  
>  static int do_handle_out(int fd, struct v4l2_requestbuffers *reqbufs,
> -			 bool is_mplane, unsigned num_planes,
> +			 bool is_compressed, bool is_mplane, unsigned num_planes,
>  			 void *buffers[], unsigned buffer_lengths[], FILE *fin,
>  			 unsigned &count, unsigned &last, struct timeval &tv_last)
>  {
>  	struct v4l2_plane planes[VIDEO_MAX_PLANES];
>  	struct v4l2_buffer buf;
> +	unsigned buffer_bytesused[reqbufs->count * VIDEO_MAX_PLANES];
>  	int ret;
>  
>  	memset(&buf, 0, sizeof(buf));
> @@ -535,14 +607,17 @@ static int do_handle_out(int fd, struct v4l2_requestbuffers *reqbufs,
>  		fprintf(stderr, "%s: failed: %s\n", "VIDIOC_DQBUF", strerror(errno));
>  		return -1;
>  	}
> -	if (fin && !fill_buffer_from_file(buffers, buffer_lengths,
> -					  buf.index, num_planes, fin))
> +	if (fin &&!fill_buffer_from_file(buffers, buffer_lengths,
> +					 buffer_bytesused, buf.index,
> +					 num_planes, is_compressed,
> +					 fin)) {
>  		return -1;
> +	}
>  	if (is_mplane) {
>  		for (unsigned j = 0; j < buf.length; j++)
> -			buf.m.planes[j].bytesused = buf.m.planes[j].length;
> +			buf.m.planes[j].bytesused = buffer_bytesused[j];
>  	} else {
> -		buf.bytesused = buf.length;
> +		buf.bytesused = buffer_bytesused[buf.index];
>  	}
>  	if (test_ioctl(fd, VIDIOC_QBUF, &buf))
>  		return -1;
> @@ -688,7 +763,9 @@ static void streaming_set_cap(int fd)
>  static void streaming_set_out(int fd)
>  {
>  	struct v4l2_requestbuffers reqbufs;
> +	struct v4l2_format fmt;
>  	int fd_flags = fcntl(fd, F_GETFL);
> +	bool is_compressed;
>  	bool is_mplane = capabilities &
>  			(V4L2_CAP_VIDEO_OUTPUT_MPLANE |
>  				 V4L2_CAP_VIDEO_M2M_MPLANE);
> @@ -710,6 +787,12 @@ static void streaming_set_out(int fd)
>  	reqbufs.type = type;
>  	reqbufs.memory = is_mmap ? V4L2_MEMORY_MMAP : V4L2_MEMORY_USERPTR;
>  
> +	memset(&fmt, 0, sizeof(fmt));
> +	fmt.type = reqbufs.type;
> +	doioctl(fd, VIDIOC_G_FMT, &fmt);
> +
> +	is_compressed = is_compressed_format(fmt.fmt.pix.pixelformat);
> +
>  	if (file_out) {
>  		if (!strcmp(file_out, "-"))
>  			fin = stdin;
> @@ -765,9 +848,9 @@ static void streaming_set_out(int fd)
>  				return;
>  			}
>  		}
> -		r = do_handle_out(fd, &reqbufs, is_mplane, num_planes,
> -				   buffers, buffer_lengths, fin,
> -				   count, last, tv_last);
> +		r = do_handle_out(fd, &reqbufs, is_compressed, is_mplane,
> +				  num_planes, buffers, buffer_lengths,
> +				  fin, count, last, tv_last);
>  		if (r == -1)
>  			break;
>  
> @@ -795,6 +878,9 @@ enum stream_type {
>  
>  static void streaming_set_m2m(int fd)
>  {
> +	struct v4l2_format fmt;
> +	bool is_compressed;
> +
>  	int fd_flags = fcntl(fd, F_GETFL);
>  	bool use_poll = options[OptStreamPoll];
>  
> @@ -864,6 +950,12 @@ static void streaming_set_m2m(int fd)
>  			     is_mmap, buffers_out, buffer_lengths_out,
>  			     file[OUT]);
>  
> +	memset(&fmt, 0, sizeof(fmt));
> +	fmt.type = reqbufs[OUT].type;
> +	doioctl(fd, VIDIOC_G_FMT, &fmt);
> +
> +	is_compressed = is_compressed_format(fmt.fmt.pix.pixelformat);
> +
>  	if (doioctl(fd, VIDIOC_STREAMON, &type[CAP]) ||
>  	    doioctl(fd, VIDIOC_STREAMON, &type[OUT]))
>  		return;
> @@ -927,9 +1019,9 @@ static void streaming_set_m2m(int fd)
>  		}
>  
>  		if (wr_fds && FD_ISSET(fd, wr_fds)) {
> -			r  = do_handle_out(fd, &reqbufs[OUT], is_mplane, num_planes[OUT],
> -					   buffers_out, buffer_lengths_out, file[OUT],
> -					   count[OUT], last[OUT], tv_last[OUT]);
> +			r  = do_handle_out(fd, &reqbufs[OUT], is_compressed, is_mplane,
> +					   num_planes[OUT], buffers_out, buffer_lengths_out,
> +					   file[OUT], count[OUT], last[OUT], tv_last[OUT]);
>  			if (r < 0)  {
>  				wr_fds = NULL;
>  
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux