结合芯片exynos 4412介绍V4L2用来视频编解码的驱动

这里结合芯片exynos 4412介绍一下V4L2用来视频编解码的驱动结构
内核代码基于3.4.106
 linux-3.4.106\drivers\media\video\s5p-mfc
 linux-3.4.106\drivers\media\video

1,V4L2结构




2,几个主要接口
主要接口(ioctl下面的一层)
vidioc_qbuf
vidioc_dqbuf
vidioc_reqbufs
vidioc_s_fmt


3,主要数据结构
struct vb2_queue
struct v4l2_buffer
struct s5p_mfc_ctx
struct vb2_buffer



4,接口调用链

V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE是未解码数据,存放ES流数据
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE是已经解码数据,存放frame data buffer

v4l2_qbuf流程





vidioc_qbuf--vb2_qbuf

---  __enqueue_in_driver

----  q->ops->buf_queue(vb);

----  s5p_mfc_buf_queue

----   list_add_tail(&mfc_buf->list, &ctx->dst_queue);

----    s5p_mfc_try_run





v4l2_dqbuf流程





解出来一帧:

s5p_mfc_irq

---   s5p_mfc_handle_frame

---   s5p_mfc_handle_frame_new

---  vb2_buffer_done

---    wake_up(&q->done_wq);

----   list_add_tail(&vb->done_entry, &q->done_list); 把解出来的一帧挂上队列


vidioc_dqbuf

---  vb2_dqbuf

---  __vb2_get_done_vb

---  __vb2_wait_for_done_vb(查找是否有可用的vb)

---   wait_event_interruptible(q->done_wq,





5,内存管理方式


主要队列:
分为capture plane(解码后)和output plane(解码前)

从另外一个维度看,
每个plane都有一个done_list队列,表示解码完比的,不用的ES buffer,或者存有有效YUV数据的Frame data buffer,用户态dqbuffer就从这里面取
每个plane都有一个另外的queue队列,表示要解码的ES buffer,或者已经显示完毕的YUV数据的Frame data buffer,用户态qbuffer就从这里取

v4l2-core操作的是vb2-buffer,  这只是个handle而已,实际给MFC的是5p_mfc_buf , 这两种buffer通过v4l2-buffer里面的index来对应起来









初始化分配 input buffer:

vidioc_reqbufs

----vb2_reqbufs

----__vb2_queue_alloc(挂到q->bufs)

---__vb2_buf_mem_alloc

---- call_memop(q, alloc, q->alloc_ctx[plane]

----vb2_dma_contig_alloc

----dma_alloc_coherent分配dmabuffer

----  call_qop(q, buf_init, vb);

---  s5p_mfc_buf_init(相关信息填充到 ctx->src_bufs[i])    这里申请的内存,存放解吗前的数据



初始化分配 out buffer

vidioc_reqbufs

----vb2_reqbufs

----__vb2_queue_alloc(挂到q->bufs)

---__vb2_buf_mem_alloc

---- call_memop(q, alloc, q->alloc_ctx[plane]

--- vb2_dma_contig_alloc

----dma_alloc_coherent分配dmabuffer

---- call_qop(q, buf_init, vb);

---s5p_mfc_buf_init(相关信息填充到 ctx->src_bufs[i]) 这里申请的内存,存放解码完的数据


分配buffer给mfc用

vidioc_reqbufs---s5p_mfc_alloc_codec_buffers---vb2_dma_contig_alloc //分配buffer给mfc用。



中断处理流程

s5p_mfc_irq

---s5p_mfc_handle_seq_done

---s5p_mfc_try_run

----s5p_mfc_set_dec_frame_buffer

---mfc_write(dev, OFFSETA(ctx->dst_bufs[i].cookie.raw.chroma),S5P_FIMV_DEC_CHROMA_ADR + i * 4);

把所有out buffer的地址写进MFC

---s5p_mfc_set_dec_stream_buffer

---把此次要解码的原始数据in buffer地址写进MFC



有效数据存在哪里?

解码前的和解码后的,都在vb->planes[plane].mem_priv里面,这个mem_priv是struct vb2_dc_buf ,里面记录了这块DMA内存的虚拟地址和物理地址,都是在vidioc_reqbufs----vb2_reqbufs----__vb2_queue_alloc(挂到q->bufs)---__vb2_buf_mem_alloc---- call_memop(q, alloc, q->alloc_ctx[plane]---------vb2_dma_contig_alloc的时候记录好的。
然后这些内存的物理地址,在vidioc_reqbufs----vb2_reqbufs----__vb2_queue_alloc(挂到q->bufs)--> call_qop(q, buf_init, vb);--->s5p_mfc_buf_init时候,赋给了ctx->dst_bufs[i].cookie.raw.luma (解码后)   ctx->dst_bufs[i].cookie.raw.chroma(解码后)    ctx->src_bufs[i].cookie.stream ,(解码前)
然后这些地址,在s5p_mfc_set_dec_stream_buffer   ,s5p_mfc_set_dec_frame_buffer时候写进了寄存器,告诉MFC具体地址




Mmap/ querybuf
s5p_mfc_mmap通过 (offset 与 DST_QUEUE_OFF_BASE)来判断是vq_src还是vq_dst ,这个offset是querybuf的时候填上buf->m.planes[i].m.mem_offset的。
buf->m.planes[i].m.mem_offset 是__vb2_queue_alloc里面__setup_offsets的时候,为每个plane的内存写上的vb->v4l2_planes[plane].m.mem_offset = off;  这个mem_offset实际上没什么用。实际上就是个标志位。就是为了mmap的时候能通过这个mem_offset找到每个plane的内存__find_plane_by_offset
这样s5p_mfc_mmap里面通过这个offset判断是ctx->vq_src还是ctx->vq_dst,然后调用vb2_mmap,通过__find_plane_by_offset找到对应vb2_buffer和vb2_buffer里面的plane,然后通过相应的vb->planes[plane].mem_priv,就可以调用vb2_dma_contig_mmap---remap_pfn_range调用标准内核API来mmap了
实际上整个mmap的过程就是找到对应的buffer和plane,一个个的mmap的



6 ,编解码参数设置在那里?


vidioc_s_fmt里面通过fmt = find_format(f, MFC_FMT_DEC);找到static struct s5p_mfc_fmt formats[]里面对应的要解码的格式,然后对struct s5p_mfc_ctx *ctx进行赋值,以便后面使用


V4L2最终要通过对MFC的寄存器读写来控制解码过程

1,启动需要操作的寄存器
MFC poweron 
clk
载入固件
重启MFC
判断固件版本
为两个plane分配内存
初始化各种等待,以及数据队列


2,开始播放需要的寄存器

s5p_mfc_run_init_dec
分配一个tmp buffer,给MFC用
设置sharememory
设置slice,delay之类的
设置第一帧
 
3,播放一帧:
s5p_mfc_run_dec_frame
设置ES流数据的地址和size
告诉MFC哪些buffer不能用
设置第一帧还是中间真还是最后一针























  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Exynos 4412是一款由三星公司设计的系统芯片,用于移动设备和嵌入式系统。这款芯片采用了ARM架构,并且拥有强大的处理能力和丰富的功能。 Exynos 4412芯片手册是为了帮助开发者和制造商了解其技术规格和配置而撰写的指南。手册详细介绍了该芯片的各个方面,包括硬件架构、主要组件、功能特性等。 首先,手册介绍Exynos 4412的硬件架构。它由多个处理核心组成,每个核心可以同时运行多个线程,以提供高性能的处理能力。此外,芯片还包括了与外部设备通信的接口,如USB、UART和SPI。 手册还介绍Exynos 4412芯片的主要组件,例如内存控制器和图形处理器。内存控制器负责管理存储器的分配和访问,而图形处理器则处理图形相关的任务,为用户提供流畅的视觉体验。 此外,手册还详细介绍Exynos 4412芯片的功能特性。它支持多种通信技术,例如蓝牙、Wi-Fi和LTE,使设备能够实现无线连接和高速数据传输。此外,芯片还支持多媒体编解码,包括音频和视频格式的编解码,以实现高质量的音视频播放和录制。 总之,Exynos 4412芯片手册是一本详细介绍芯片技术规格和配置的指南。通过阅读手册,开发者可以更好地了解该芯片的功能和特性,从而更高效地开发相关产品和应用。 ### 回答2: Exynos 4412芯片是由三星电子推出的一款处理器芯片。它是一款基于ARM架构的处理器,采用四核心设计,主频高达1.4GHz。 Exynos 4412芯片手册包含了该芯片的详细规格和功能说明,旨在向芯片开发者和研究人员提供相关的参考信息。手册主要涵盖以下几个方面: 1. 芯片架构:手册介绍Exynos 4412芯片的整体架构,包括处理器核心、内存管理单元和外设控制器等组成部分。这些信息对于理解芯片的工作原理和性能分析至关重要。 2. 功能特性:手册详细介绍Exynos 4412芯片支持的各种功能和技术,包括多路复用、中断处理、DMA控制等。这些特性使得该芯片具备出色的性能和可扩展性。 3. 接口和外设:手册列举了Exynos 4412芯片所支持的各种接口和外设,如UART、SPI、I2C、USB、HDMI等。开发者可以根据手册提供的资料,进行硬件电路设计和软件开发的相关工作。 4. 芯片调试和测试:手册提供了一些关于Exynos 4412芯片调试和测试的建议和指导,包括调试接口的使用、性能测试工具的使用等。这些信息有助于开发者更好地评估芯片的性能表现和进行故障排除。 总之,Exynos 4412芯片手册是Exynos 4412芯片开发者的重要参考资料,它提供了关于芯片架构、功能特性、接口和外设等方面的详细说明。开发者可以根据手册提供的信息,进行芯片的设计、调试和测试工作,从而开发出更加稳定和高效的应用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值