v4l2使用vb2框架,同时从保留区分配连续内存
videobuf2 videobuf2-dma-contig.c,从保留区自己手动分配的连续物理内存,但是看代码好像是框架自动申请DMA内存了,,假如需要从保留区自己申请内存,然后关联到VB2上,有朋友遇到这种吗?新手,还不太熟悉,,,用VB2框架,模拟一个YUV420SPNV12格式的 节点是成功了 楼主的意思是不是需要自己指定保留区内存的地址?如果是这样的话,可以参考这里:
https://blog.csdn.net/rikeyone/article/details/105950850
首先在设备树中添加专用CMA节点:
reserved_memory: reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
priv_mem: priv_region {
compatible = "shared-dma-pool";
alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
reusable;
alignment = <0x0 0x400000>;
size = <0x0 0xC00000>;
};
};
然后在设备驱动的设备树节点中引用专用CMA:
qcom,testmodule {
compatible = "qcom,testmodule";
memory-region = <&priv_mem>;
};
参考里面缺了一步,需要在设备驱动程序的probe中添加(假定是platform_device)
struct device *dev = &pdev->dev;
rc = of_reserved_mem_device_init(dev);
之后使用videobuf2-dma-contig.c中的alloc函数分配内存的时候就会优先使用专用保留内存。
thepresent 发表于 2024-3-20 20:37
楼主的意思是不是需要自己指定保留区内存的地址?如果是这样的话,可以参考这里:
https://blog.csdn.net/r ...
(引用自2楼)
目前用的vmalloc做的测试, g_vb_queue.mem_ops = &vb2_vmalloc_memops; 选用的这个分配模式,const struct vb2_mem_ops vb2_vmalloc_memops = {
.alloc = vb2_vmalloc_alloc,
.put = vb2_vmalloc_put,
.get_userptr = vb2_vmalloc_get_userptr,
.put_userptr = vb2_vmalloc_put_userptr,
#ifdef CONFIG_HAS_DMA
.get_dmabuf = vb2_vmalloc_get_dmabuf,
#endif
.map_dmabuf = vb2_vmalloc_map_dmabuf,
.unmap_dmabuf = vb2_vmalloc_unmap_dmabuf,
.attach_dmabuf = vb2_vmalloc_attach_dmabuf,
.detach_dmabuf = vb2_vmalloc_detach_dmabuf,
.vaddr = vb2_vmalloc_vaddr,
.mmap = vb2_vmalloc_mmap,
.num_users = vb2_vmalloc_num_users,
}; 框架都是自动分配了,,vb2_vmalloc_alloc,,,,,,DMA的 vb2_dma_contig_memops,vb2_dc_alloc函数看着也是自动分配的,,,需求是想指定到保留内存,保留内存分为了16个块,FPGA会送数据到对应的块中,,看VB2像是自动分配的 把这16个块写到一个保留区的alloc-ranges = <0x0 0x000000aa 0x0 0xsize 0x0 0xbb 0x0 0xsize>,再设置alignment = <0x0 0xsize>;使用vb2_dc_alloc分配的时候应该会依次从指定内存地址分配内存的。vb2_dc_alloc会优先查找CMA区域,如果CMA区域内存不够才会从其他内存域分配。如果16个块的内存是连续的,可以只指定一个alloc-ranges,也会根据alignment 依次分配的。 thepresent 发表于 2024-3-21 11:42
把这16个块写到一个保留区的alloc-ranges = ,再设置alignment = ;使用vb2_dc_alloc分配的时候应该会依次从 ...
(引用自4楼)
惭愧,,,,新手搞了好久还是没有搞定,,,,,借用 videobuf2 框架,实现虚拟一个NV12 800*600的节点,mmap 方式成功了,,,后面想着抛开这个videobuf2框架,用kmalloc申请内存,自己使用list队列管理,,结果VIDIOC_DQBUF , VIDIOC_QBUF 正常循环了,就是最后的TS视频文件大小不变,没有写成功,,,,感觉像是某些 ioctl命令或者参数没有实现正确,,又找不出来哪里不对...
if( my_dev.buffer_use[ my_dev.outIndex ] == 0 )//应该是空闲的
{
my_dev.buffer_use[ my_dev.outIndex ] = 1;
argp->index = my_dev.outIndex;//给app返回去
argp->bytesused = 800*600*1.5;//实际的长度也返回去
printk("DQ=%d \n", my_dev.outIndex );
my_dev.outIndex++;
if( my_dev.outIndex >=(my_dev.reqBufferCnt) )
{
my_dev.outIndex = 0;
}
mutex_unlock( &( my_dev.my_mutex) );
return 0;
}
else
{
printk("DQBUFerror i= %d.\n\n", my_dev.outIndex );
},,,,,,
这会儿尝试,使用io-mode=5(dmabuf-import)的方式,将从保留区申请的内存,用fd 导出给v4l2src 插件
gst-launch-1.0 v4l2src device=/dev/video0 io-mode=5 ! video/x-raw, format=NV12, width=800, height=600, framerate=60/1 ! omxh265enc qp-mode=auto gop-mode=basic gop-length=30 b-frames=0 target-bitrate=60000 num-slices=8 control-rate=constant prefetch-buffer=true low-bandwidth=false filler-data=true cpb-size=10000 initial-delay=500 ! queue ! mpegtsmux alignment=7 name=mux ! filesink location="./testyuv420sp-mycode-arrayType-800-600-60hz-mode5.ts"
---
页:
[1]