介绍
在本系列,我打算花大篇幅讲解我的 gitee 项目音视频播放器,在这个项目,您可以学到音视频解封装,解码,SDL渲染相关的知识。您对源代码感兴趣的话,请查看基于FFmpeg和SDL的音视频播放器
如果您不理解本文,可参考我的前一篇文章音视频项目—基于FFmpeg和SDL的音视频播放器解析(十)
解析
我们这一篇文章讲解 AVFrameQueue,先看 .h 文件代码
- #ifndef AVFRAMEQUEUE_H_
- #define AVFRAMEQUEUE_H_
-
- #include"queue.h"
-
- #ifdef __cplusplus
-
- extern "C" {
- #include"libavutil/avutil.h"
- #include"libavformat/avformat.h"
- #include"libavcodec/avcodec.h"
- }
-
- #endif
-
- class AVFrameQueue{
- public:
- AVFrameQueue();
- ~AVFrameQueue();
- void Abort();
- int Push(AVFrame* val);
- AVFrame* Pop(const int timeout);
- AVFrame* Front();
- int Size();
- private:
- void release();
- Queue
queue_t; - };
-
- #endif
整体上看,与 AVPacketQueue 的函数没有什么区别,都是 Abort,Push,Pop,Front,Size,release,只是存放的数据不一样,一个放的是包(Packet),一个放的是帧(Frame)。
我们来看一下函数的实现
- void AVFrameQueue::Abort(){
- release();
- queue_t.Abort();
- }
这函数负责程序的中断,先调用了 release 函数释放了队列的数据,在调用 Queue 父类的 Abort 方法终止程序。
- int AVFrameQueue::Push(AVFrame* val){
- return queue_t.Push(val);
- }
这函数负责队列的增加数据。直接调用 Queue 父类的 Push 方法,很好理解。
- AVFrame* AVFrameQueue::Pop(const int timeout){
- AVFrame* av_frame = nullptr;
- int ret = queue_t.Pop(av_frame, timeout);
- if(ret < 0){
- perror("AVFrameQueue:: Pop failed");
- }
- return av_frame;
- }
这函数负责队列弹出数据。由于这个 Queue 父类的方法需要讲弹出的数据赋值给参数,因此我们需要在函数头部增加一个 AVFrame 的变量,用来传递给函数。
- AVFrame* AVFrameQueue::Front(){
- AVFrame* av_frame = nullptr;
- int ret = queue_t.Front(av_frame);
- if(ret < 0){
- perror("AVFrameQueue:: Front failed");
- }
- return av_frame;
- }
这函数负责返回队列的首部数据。这也很好理解,直接调用 Queue 父类的 Front 函数。
- int AVFrameQueue::Size(){
- return queue_t.Size();
- }
这函数负责返回队列的长度。直接调用 Queue 的 Size 方法即可。
- void AVFrameQueue::release(){
- while(true){
- AVFrame* av_frame = nullptr;
- int ret = queue_t.Pop(av_frame, 1);
- if(ret < 0){
- break;
- }else {
- av_frame_free(&av_frame);
- }
- }
- }
这函数负责释放队列的所有元素。函数有一个 while 的死循环,然后不断 Pop 队列的数据,直到没有为止,跳出循环。
好了,Queue,AVPacketQueue,AVFrameQueue 都讲完了。下一篇文章我们会讲音视频同步的机制以及如何实现。
欲知后事如何,请听下回分解。