关于V4L2编程中获取视频流的误区

最近在做视频流的采集,然后保存成图片的形式,网上找的例程对映射缓存区的读取是这样的

struct v4l2_buffer buf;
ioctl(fd, VIDIOC_DQBUF,&buf);
process_image(usr_buf[buf.index].start, usr_buf[buf.index].length);//保存成图片的函数
ioctl(fd, VIDIOC_QBUF,&buf);
但是看网上有的程序不是用的申请的缓存区的长度
usr_buf[buf.index].length
而是用的ioctl(fd, VIDIOC_DQBUF,&buf);读取回来的buf.bytesused
这两者的区别在哪呢?

1.先说一下

usr_buf[buf.index].length 是从哪里来的呢?在建立mmap的时候,用户层会向内核申请一部分的内存资源作为映射区,具体命令是
ioctl(fd,VIDIOC_QUERYBUF,&buf) ,具体内容如下
struct v4l2_buffer {
        __u32                   index;
        enum v4l2_buf_type      type;
        __u32                   bytesused;
        __u32                   flags;
        enum v4l2_field         field;
        struct timeval          timestamp;
        struct v4l2_timecode    timecode;
        __u32                   sequence;
        /* memory location */
        enum v4l2_memory        memory;
        union {
                __u32           offset;
                unsigned long   userptr;
        } m;
        __u32                   length;
        __u32                   input;
        __u32                   reserved;
};
其中标红的地方就是内核返回的消息,说明映射的这一片区域的大小。
2.那么在请求缓冲的视频帧的时候,
ioctl(fd, VIDIOC_DQBUF,&buf);
返回信息中的buf.bytesused 
就是实际占用的大小,如果你在保存的时候用的是
usr_buf[buf.index].length



那么得到的图片是一个固定大小的图片,并且很大,很多空间都是NULL填充的无效信息,因为length是指的是整个映射区域的大小,并不是实际用的大小,所以在存储的时候要采用buf.bytesused 存储实际用的字节数。

3.还有一个个人感觉很傻的问题,就是为什么每次保存的JPG图片的大小不一样。因为分辨率是一样的。为什么大小不一样呢?对图片格式小白的我理所当然的认为,应该一样大的。
其实jpg格式本身就是一种压缩格式化,每一张图片因为拍摄的图像不一样,压缩率肯定不一样。比如对一张白纸和对花花草草拍照,白纸要明显小得多,因为像素分布单一,压缩的比较厉害,所以就小的多。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值