音视频项目—基于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 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。

欲知后事如何,请听下回分解。

你可能感兴趣的:(音视频,ffmpeg)