音视频项目—基于FFmpeg和SDL的音视频播放器解析(十)
介绍
在本系列,我打算花大篇幅讲解我的 gitee 项目音视频播放器,在这个项目,您可以学到音视频解封装,解码,SDL渲染相关的知识。您对源代码感兴趣的话,请查看基于FFmpeg和SDL的音视频播放器
如果您不理解本文,可参考我的前一篇文章音视频项目—基于FFmpeg和SDL的音视频播放器解析(九)
解析
我们上次文章解析了父类 Queue,这次我们解析子类之一,AVPacketQueue。
我们先看 .h 的代码:
#pragma once
#ifndef AVPACKETQUEUE_H_
#define AVPACKETQUEUE_H_
#include "queue.h"
#ifdef __cplusplus
extern "C" {
#include"libavutil/avutil.h"
#include"libavformat/avformat.h"
#include"libavcodec/avcodec.h"
}
#endif // __cplusplus
class AVPacketQueue{
public:
AVPacketQueue();
~AVPacketQueue();
void Abort();
int Size();
int Push(AVPacket* val);
AVPacket* Pop(const int timeout);
private:
void release();
Queue<AVPacket*> my_queue;
};
#endif
大家可以注意一下,在这里我们的 AVPacketQueue 并没有直接继承 Queue,而是将 Queue 作为私有成员的一个变量。
其他的成员变量都是函数,其中只有 release 是私有成员。
接下来我们要解析五个函数:Abort,Size,Push,Pop,release,大家放心,代码量不大。
Abort:
void AVPacketQueue::Abort() {
release();
my_queue.Abort();
}
这个函数是负责程序中断的,其中引用的函数 release 我们等会讲。然后队列就使用了 Abort 函数,没了解的读者朋友可以看看前面的文章。
Size:
int AVPacketQueue::Size() {
return my_queue.Size();
}
这也很好理解,就调用了 Queue 父类本身的 Size 函数,返回了队列长度。
Push:
int AVPacketQueue::Push(AVPacket* val) {
return my_queue.Push(val);
}
同理,直接调用了父类的 Push 方法。
Pop:
AVPacket* AVPacketQueue::Pop(const int timeout) {
AVPacket* avPack = nullptr;
int ret = my_queue.Pop(avPack, timeout);
if (ret < 0) {
perror("AVPackeQueuet: Pop failed");
}
return avPack;
}
这里也同样调用了父类的 Pop 方法,不过首先还声明了一个 AVPacket 变量,因为这里的 Pop 函数不是简单的弹出,还要讲弹出的数据赋值给参数。
Release:
void AVPacketQueue::release() {
while (true)
{
AVPacket* packet = nullptr;
int ret = my_queue.Pop(packet, 1);
if(ret < 0){
break;
}else {
av_packet_free(&packet);
}
}
}
这函数是释放相关资源。这是一个死循环函数,然后队列不断弹出数据,直到没有为止。
好了,那么 AVPacketQueue 我们就讲完了,下一篇文章我们会解析 AVFrameQueue。
欲知后事如何,请听下回分解。