在选定的视频文件中,第一个分离器将对其进行分离筛选,将数据流中的数据自动分解成音视频数据。经过各自的解码器解码之后,在进行目前系统时钟的比较,然后得到精准无误的时间进一步进行比较。结果就是,音频和视频同步就输出它们,反之,视频和音频不同步,那么就需要音频进行等候或者直接跳帧处理,处理后视频和音频一起同步将他们输出。
3。3 音视频播放系统
设设播放器播放文件的流程如图3-1所示:视频文件首先通过用户操作调用
Open(constchar*path)函数打开文件读入数据。
通过读入数据的文件头,调用avformat_open_input(&ic,path,0,0)函数获取相应的信息,并将视频信息保存在ic中。比如:视频文件的编码类型、视频的总时长等信息。
在遍历流信息,使用的是for(inti=0;i<ic->nb_streams;i++)循环对音视频流进行分离。然后,将音频数据流和视频数据流分别放置到音频队列和视频队列中。在调用avcodec_find_decoder(enc->codec_id)找到解码器。在调用avcodec_open2(enc,codec,NULL)找到对应的解码器。在调用av_frame_alloc()函数为解码帧分配内存。在调用
avcodec_send_packet(ic->streams[pkt->stream_index]->codec,pkt)和avcodec_receive_frame(ic->streams[pkt->stream_index]->codec,frame)对音视频解码。最后,重新整理解码后的音频信号和视频信号,以达到音视频可以同步输出到缓冲区,在各自分别从对应的音/视频模块中输出来的目的。
图3-1播放器系统
在设计中,如何对音频和视频数据流进行解码、解码和输出?可以在后台代码中调用voidrun()这个函数,利用多线程的技术实现音视频同步的,以便一边音/视频在解码另一边一直入音/视频数据流,让它们各自进到自己的缓冲区等候被解码,利用缓冲区加强解码的效率。最初实现对音/视频数据的读取,然后把最初的音视频数据送到缓存中。追究到底,其实打开视频文件是接口函数调用解码器实现的。文献综述
打开一个视频文件的大概流程是什么样的呢?我们先点击播放器界面播放文件按钮,选择要播放的文件,输入模块接收文件,打开文件,获取文件名、文件格式等基本信息。也还要检查播放文件名和播发文件的格式等是不是合理,播放文件是不是为空等。然后底层代码里的函数接口会去调用解码器,接着,解码器对播放文件进行解码的操作。这时底层的函数接口调用初始化函数会初始化对视频播放器,以至于实现播放文件解码、播放。
一个视频文件输出有什么呢?一般我们接触的视频肯定有视频和音频。所以,输出模块由音频输出和视频输出组成。那都是怎么划分音频输出和视频输出的呢?不言而喻,输出的内容是音频那么音频模块输出它,输出的内容是视频那么视频模块输出它。这样做的目的是为了解码后音视频信号的输出做准备。音频模块和视频模块在设计上也是毫不相干,各自做自己。尽管解码后会对音频和视频进一步同步处理,可是视频和音频同步后输出的介质各不相同。音频信号通过音频输出通道输出,而视频信号则通过视频通道输出。利用底层函数函数接口实现来实现控制音视频同步。以达到令人满意的播放效果,即音频和视频同步。
实现关键代码:读取帧数据功能av_read_frame会自动给视频帧分配空间,返回值0表示成功。