基于FFmpeg和EMIF驱动的音视频数据传输方法与流程

文档序号:18221473发布日期:2019-07-19 23:02阅读:389来源:国知局
基于FFmpeg和EMIF驱动的音视频数据传输方法与流程

本发明属于嵌入式音视频技术领域,涉及一种音视频数据传输方法,具体涉及一种基于ffmpeg和emif用户空间驱动并通过嵌入式音视频系统实现的音视频数据传输方法,可用于视频监控、视频会议等涉及视频的领域。



背景技术:

随着嵌入式技术的发展,尤其是dsp和fpga这类数据运算芯片可以对大量的数据进行快速、高效的运算,音视频技术在嵌入式系统上的应用越来越成熟,dsp和fpga之间的音视频数据传输成为热点问题。目前有多种dsp和fpga之间音视频传输的方法,其中包括通过网络协议进行传输和通过spi或emif接口进行传输。而dsp和fpga之间通过接口进行数据传输比较方便,外部存储器接口emif是dsp器件提供的一种数据传输接口,可以实现dsp和fpga之间的大量数据传输,广泛应用于dsp和fpga之间传输数据。dsp和fpga之间的音视频数据传输是在嵌入式音视频系统实现,嵌入式音视频系统包括了摄像头、麦克风、视频模数转换模块、音频模数转换模块、数字信号处理器dsp和可编程门阵列fpga。其中摄像头和麦克风负责采集图像模拟信号和音频模拟信号,视频模数转换模块和音频模数转换模块将其转换为图像数字信号和音频数字信号。在dsp上对图像数字信号和音频数字信号进行压缩和封装,再将dsp上封装后的音视频数据通过emif驱动传输给fpga。

目前,dsp和fpga主要通过emif内核驱动来传输音视频数据,但仍存在很多缺点,例如杨峰于2017年发表在《电子科技》的文章“基于达芬奇技术的音视频压缩传输系统”中,公开了一种通过emif内核驱动在dsp和fpga之间传输音视频数据的方法,但该方法中的音视频数据传输用简单的读写函数通过emif内核驱动传输来实现,导致了音视频数据传输的方法可移植性差,而且不利于二次开发,且emif内核驱动,由于在系统启动时要将驱动加载到内核中,增加了使用步骤。

ffmpeg是目前应用最为广泛的一种音视频框架。ffmpeg为开发者提供了丰富的音视频处理的调用接口,便于开发人员开发音视频应用。ffmpeg提供了很多音视频相关的功能,例如编解码、封装和解封装、转换格式、加滤镜等。ffmpeg可移植性强,可以在windows、linux、和嵌入式操作系统上编译及运行。而且由于ffmpeg提供了丰富的音视频处理功能,也便于开发人员进行二次开发。



技术实现要素:

本发明的目的在于克服上述技术存在的缺陷,提供了一种基于ffmpeg和emif驱动的音视频数据传输方法,用于解决现有技术存在的可移植性差和不利于二次开发的技术问题。

为实现上述目的,本发明的采取的技术方案包括如下步骤:

(1)对音频模拟信号和图像模拟信号进行模数转换:

通过视频模数转换模块对摄像头采集的图像模拟信号进行模数转换,得到图像数字信号,通过音频模数转换模块对麦克风采集的音频模拟信号进行模数转换,得到音频数字信号;

(2)在dsp上对音频数字信号和图像数字信号进行压缩:

在dsp上对音频数字信号和图像数字信号进行压缩,得到音频压缩数据和图像压缩数据;

(3)在dsp上对音频压缩数据和图像压缩数据进行封装:

基于ffmpeg音视频框架的封装函数,在数字信号处理器dsp上对音频压缩数据和视频压缩数据进行封装,得到封装后的音视频数据;

(4)编写外部存储器接口emif的用户空间驱动:

(4a)将外部存储器接口emif的寄存器物理地址和数据传输物理地址分别映射到emif驱动程序的用户空间,得到寄存器的虚拟内存地址和用于emif数据传输的虚拟内存地址;

(4b)对寄存器的虚拟内存地址偏移量为14h处的内存地址重新赋值,并通过所赋的值确定emif数据传输的位数和10mbps以下的emif数据传输速率;

(4c)对用于emif数据传输的虚拟内存地址、emif数据传输的位数和10mbps以下的emif数据传输速率进行组合,外部存储器接口emif的用户空间驱动;

(5)基于ffmpeg和emif用户空间驱动,将封装后的音视频数据传输至fpga:

(5a)通过ffmpeg音视频框架中的avformat_alloc_context()函数,申请ffmpeg中的avformatcontext结构体;

(5b)通过ffmpeg音视频框架中的av_malloc()函数,在dsp中申请一段内存,并将所申请的内存的指针和大小作为ffmpeg中avio_alloc_context()函数的参数,然后在avio_alloc_context()函数中注册用于读取dsp内存数据的回调函数,同时通过avio_alloc_context()函数申请ffmpeg中的aviocontext结构体;

(5c)将avformatcontext结构体的aviocontext类型的指针pb指向aviocontext结构体,得到指定音视频数据输出位置为dsp内存的avformatcontext结构体,并通过avformat_open_input()函数打开指定音视频数据输出位置为dsp内存的avformatcontext结构体,将封装后的音视频数据存储到在dsp中申请的内存中;

(5d)在步骤(5b)注册的回调函数内,将dsp内存中存储的封装后的音视频数据循环读取并复制到emif用户空间驱动中用于数据传输的虚拟内存地址中,每个循环读取并复制数据的位数与emif用户空间驱动中emif数据传输的位数相同;

(5e)外部存储器接口emif按照emif用户空间驱动中的emif数据传输速率,读取复制到emif用户空间驱动中用于数据传输的虚拟内存地址中的封装后的音视频数据,并传输至fpga。

本发明与现有技术相比,具有如下优点:

(1)本发明首先通过ffmpeg中的函数把封装后的音视频数据存储到dsp内存,再通过ffmpeg中的回调函数把dsp内存中的音视频数据通过emif驱动传输给fpga,实现了利用ffmpeg音视频框架通过emif传输音视频数据,由于ffmpeg支持多种操作系统,可以将音视频传输方法移植到其它系统中,与现有技术相比,提高了音视频数据传输方法的可移植性,并且ffmpeg提供了丰富的音视频处理函数接口,通过这些函数接口可以完成采集、编码、封装、转码、加滤镜的功能,有利于二次开发。

(2)本发明编写的emif用户空间驱动,通过将外部存储器接口emif的寄存器物理地址和数据传输物理地址分别映射到emif驱动程序的用户空间,去掉了emif内核驱动需要把驱动加载到内核中的步骤,与现有技术相比,简化了传输流程。

附图说明

图1为本发明的嵌入式音视频系统的结构示意图;

图2为本发明的实现流程图;

图3为本发明的音视频数据封装流程图;

图4为本发明通过ffmpeg传输音视频数据流程图。

具体实施方式

以下结合附图和具体实施例,对本发明的技术方案进行详细说明:

参照图1,实现本发明采用的嵌入式音视频系统:

该嵌入式音视频系统包括摄像头、麦克风、视频模数转换模块、音频模数转换模块、数字信号处理器dsp和可编程门阵列fpga。通过摄像头和麦克风采集图像模拟信号和音频模拟信号,通过视频模数转换模块和音频模数转换模块将其转换为图像数字信号和音频数字信号,在dsp上对图像数字信号和音频数字信号进行压缩和封装,再将dsp上封装后的音视频数据通过emif驱动传输给fpga。

参照图2,本发明包括如下步骤:

步骤1)对音频模拟信号和图像模拟信号进行采集并模数转换:

采集音频模拟信号和图像模拟信号,对音频模拟信号和图像模拟信号进行模数转换,即对音频模拟信号和图像模拟信号分别进行采样,得到音频离散信号和图像离散信号,并对音频离散信号和图像离散信号分别进行量化,得到音频数字信号和图像数字信号;

步骤2)在dsp上对音频数字信号和图像数字信号进行压缩:

为了降低音频数据和视频数据的数据量,调用音频编码器和视频编码器在数字信号处理器dsp上分别对音频数字信号和图像数字信号进行压缩,得到音频压缩数据和图像压缩数据;

步骤3)在dsp上对音频压缩数据和图像压缩数据进行封装:

为了让音频压缩数据和图像压缩数据复用成音视频数据,并实现音频和视频的同步,要对音频压缩数据和图像压缩数据进行封装,如图3所示,基于ffmpeg对音频压缩数据和图像压缩数据进行封装的操作步骤如下:

步骤3a)通过av_register_all()函数注册文件格式和编解码的库;

步骤3b)通过av_open_input_file()函数打开音视频文件,该函数会读取音视频数据中的信息并把这些信息保存到avformatcontext结构体中;

步骤3c)通过av_find_stream_info()函数添加文件中的音视频数据流的信息,该函数为pformatctx->streams填充上流的信息;

步骤3d)通过avformat_alloc_output_context2()函数初始化用于输出的avformatcontext结构体;

步骤3e)通过avformat_new_stream()函数申请avstream结构体,avstream结构体主要作为存放音频、视频、字幕数据流使用;

步骤3f)通过avcodec_copy_context()函数将输入视频/音频的参数拷贝至输出视频和音频的avcodeccontext结构体;

步骤3g)用av_read_frame()函数从音视频数据中读取avpacket,在将取出的avpacket写入到输出文件之前,用av_compare_ts()函数来比较时间戳决定该写入视频还是音频,然后用av_interleaved_write_frame()函数将packet写入到封装数据包中,得到封装后的音视频数据;

步骤4)编写外部存储器接口emif的用户空间驱动:

步骤4a)调用linux系统函数中的open()函数打开dsp的内存设备,获得dsp的内存设备的文件描述符,以dsp的内存设备文件描述符为参数,通过linux系统函数中的mmap()函数建立内存映射,将emif寄存器物理地址和emif数据传输物理地址映射到emif驱动程序的用户空间,返回映射首地址的指针,得到寄存器的虚拟内存地址和用于emif数据传输的虚拟内存地址;

步骤4b)对寄存器的虚拟内存地址偏移量为14h处的内存地址重新赋值,并通过所赋的值确定emif数据传输的位数和10mbps以下的emif数据传输速率;

步骤4c)对用于emif数据传输的虚拟内存地址、emif数据传输的位数和10mbps以下的emif数据传输速率进行组合,外部存储器接口emif的用户空间驱动;

步骤5)基于ffmpeg和emif用户空间驱动,将封装后的音视频数据传输至fpga,如图4所示,步骤如下:

步骤5a)通过ffmpeg音视频框架中的avformat_alloc_context()函数,申请ffmpeg中的avformatcontext结构体;

步骤5b)通过ffmpeg音视频框架中的av_malloc()函数,在dsp中申请一段内存,并将所申请的内存的指针和大小作为ffmpeg中avio_alloc_context()函数的参数,然后在avio_alloc_context()函数中注册用于读取dsp内存数据的回调函数,同时通过avio_alloc_context()函数申请ffmpeg中的aviocontext结构体;

步骤5c)将avformatcontext结构体的aviocontext类型的指针pb指向aviocontext结构体,得到指定音视频数据输出位置为dsp内存的avformatcontext结构体,并通过avformat_open_input()函数打开指定音视频数据输出位置为dsp内存的avformatcontext结构体,将封装后的音视频数据存储到在dsp中申请的内存中;

步骤5d)在步骤(5b)注册的回调函数内,将dsp内存中存储的封装后的音视频数据循环读取并复制到emif用户空间驱动中用于数据传输的虚拟内存地址中,每个循环读取并复制数据的位数与emif用户空间驱动中emif数据传输的位数相同;

步骤5e)外部存储器接口emif按照emif用户空间驱动中的emif数据传输速率,读取复制到emif用户空间驱动中用于数据传输的虚拟内存地址中的封装后的音视频数据,并传输至fpga。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1