音视频解码和数据输出到播放器的时侯,解码器首先解码音视频文件,然后音视频文件数据流的输出。在QT设计中可以对帧缓冲区进行直接操作,也是一大特色。因此,能够让解码完成的数据经过帧缓冲区输出到播放器上去,实现全部设计的解码并且数据输出效果。
3FFmpeg实现音视频播放
3。1FFmpeg介绍
既然选择用FFmpeg来实现音视频播放效果,那肯定是有其特殊的优点。FFmpeg是一个集录制、转换、音/视频编码解码功能为一体的完整的开源解决方案。FFmpeg的开发是基于Linux操作系统,但是可以在大多数操作系统中编译和使用。FFmpeg支持MPEG、DivX、MPEG4、AC3、DV、FLV等40多种编码,AVI、MPEG、OGG、Matroska、ASF等90多种解码。TCPMP,VLC,MPlayer等开源播放器都用到了FFmpeg。
FFmpeg主目录下主要有libavcodec、libavformat和libavutil等子目录。其中libavcodec用于存放各个encode/decode模块,libavformat用于存放muxer/demuxer模块,libavutil用于存放内存操作等辅助性模块。以flashmovie的flv文件格式为例,muxer/demuxer的flvenc。c和flvdec。c文件在libavformat目录下,encode/decode的mpegvideo。c和h263de。c在libavcodec目录下。
FFmpeg的主要数据结构:AVFormatContext是FFMpeg格式转换过程中实现输入和输出功能、保存相关数据的主要结构。AVCodecContext保存AVCodec指针和与codec相关数据,如video的width、height,audio的samplerate等。AVCodecContext中的codec_type,codec_id二个变量对于encoder/decoder的匹配来说,最为重要。AVStream结构保存与数据流相关的编解码器,数据段等信息。比较重要的有如下二个成员:AVCodecContext*codec;
/**<codeccontext*/、void*priv_data。AVInputStream/AVOutputStream根据输入和输出流的不同,前述的AVStream结构都是封装在AVInputStream和AVOutputStream结构中,在av_encode()函数中使用。AVInputStream中还保存的有与时间有关的信息。AVOutputStream中还保存有与音视频同步等相关的信息。AVPacket结构是用于保存读取的packet数据。
3。2音视频实现原理
本实现原理围绕媒体流为中心,分别为为视频流、音频流。作用于视频解码器和音频解码器中。
播放一个视频文件时,最令人不舒服的就是音视频不在一个频道,我看这里,可是声音却早就不在这了,特别影响观看效果。既然如此,我们就思考?一个视频不单单肯定包括声音,当然,早年的默片不算。那我们如何才能让音视频同步呢?从技术上来说,目前让音视频同步的首选就是时间戳。进一步思考到底什么是时间戳,它的原理是什么呢?首先,我们需要选择一个时间线性参考时钟,以便我们可以记录的开始时间和结束时间的视频播放。视频文件播放时,在按照参考时钟依次计算数据块上已经记录好的时间戳决定播放。如果数据块的起始时间大于当前参考时钟上的时间,则该数据块不会暂时被播放。那到什么时候播放呢?答案是数据块的启动时间和当前参考时钟一样大。同样,如果启动数据块的播放时间比当前参考时钟的时间小,“尽可能快”播放这段数据或扔掉这段数据,以达到播放进度和参考时钟同步的效果。
在时间戳播放时仅凭对时间戳和数据块处理就可以实现音视频同步吗?显而易见,仅凭数据块等待或者快进,肯定是不可以完全实现的。那我们怎么让播放更加舒服呢?那就需要我们自己去调节播放性能,在后台代码里在加入一个反馈信息的机制。反馈机制到底是怎么反馈的呢?它的实现原理就是:无论当前数据流的速度很快或者很慢,我们都会将它的状态反馈给信息“源”,目的是能够让源控制数据流速度。数据流速度慢源就加快它的速度,反之,放慢数据流的速度。那么到底加入什么反馈机制呢?了解过DirectShow的人肯定清楚,DirectShow原理的质量控制(质量控制)符合这个反馈机制。所以,我们选择用DirectShow来实现音频和视频同步是特别明确的。但当SDK是播放视频,只是读的ASF数据流解码不考虑如何显示音频和视频内容。论文网 QT的视频媒体播放器的设计(4):http://www.youerw.com/zidonghua/lunwen_199193.html