本篇是在上一篇的基础上增加队列处理AVpacket
新增队列类GQueue
GQueue.h
#ifndef GODVMUSIC_GQUEUE_H
#define GODVMUSIC_GQUEUE_H
//队列的头文件
#include "queue"
#include "pthread.h"
#include "GLog.h"
#include "GStatus.h"
extern "C" {
#include <libavcodec/avcodec.h>
};
class GQueue {
public:
//声明一个队列
std::queue<AVPacket *> queuePacket;
//线程锁
pthread_mutex_t mutex;
//条件变量
pthread_cond_t condPacket;
//状态对象
GStatus *gStatus = NULL;
public:
GQueue(GStatus *gStatus);
~GQueue();
//入队函数
int putAVPacket(AVPacket *avPacket);
//出队函数
int getAVPacket(AVPacket *avPacket);
//队列大小
int getQueueSize();
};
#endif //GODVMUSIC_GQUEUE_H
GQueue.cpp
#include "GQueue.h"
GQueue::GQueue(GStatus *gStatus) {
//给状态赋值 构造器初始化
this->gStatus = gStatus;
//初始化
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&condPacket, NULL);
}
GQueue::~GQueue() {
//销毁线程锁
pthread_mutex_destroy(&mutex);
//销毁条件变量
pthread_cond_destroy(&condPacket);
}
//入队函数
int GQueue::putAVPacket(AVPacket *avPacket) {
pthread_mutex_lock(&mutex);
queuePacket.push(avPacket);
if (LOG_DEBUG) {
LOGD("放入一个avPacket到队列中,个数为%d", queuePacket.size());
}
//通知
pthread_cond_signal(&condPacket);
pthread_mutex_unlock(&mutex);
return 0;
}
//出队函数
int GQueue::getAVPacket(AVPacket *avPacket) {
pthread_mutex_lock(&mutex);
while (gStatus != NULL && !gStatus->exit) {
if (queuePacket.size() > 0) {
//拿出队头
AVPacket *packet = queuePacket.front();
//拷贝
if (av_packet_ref(avPacket, packet) == 0) {
queuePacket.pop();
}
//释放
av_packet_free(&packet);
av_free(packet);
packet = NULL;
if (LOG_DEBUG) {
LOGD("从队列里面取出一个avPacket,还剩%d", queuePacket.size());
}
break;
} else {
pthread_cond_wait(&condPacket, &mutex);
}
}
pthread_mutex_unlock(&mutex);
return 0;
}
int GQueue::getQueueSize() {
int size = 0;
pthread_mutex_lock(&mutex);
size = queuePacket.size();
pthread_mutex_unlock(&mutex);
return size;
}
新增一个控制状态的类GStatus
GStatus.h
#ifndef GODVMUSIC_GSTATUS_H
#define GODVMUSIC_GSTATUS_H
class GStatus {
public:
bool exit;
public:
GStatus();
};
#endif //GODVMUSIC_GSTATUS_H
GStatus.cpp
#include "GStatus.h"
GStatus::GStatus() {
exit = false;
}
将GFFmpeg.h 的构造器增加一个标志位
GFFmpeg.h
//成员变量
GStatus *gStatus = NULL;
//构造器
GFFmpeg(GCallJava *callJava, const char *url, GStatus *gStatus);
GFFmpeg.cpp
GFFmpeg::GFFmpeg(GCallJava *callJava, const char *url, GStatus *gStatus) {
this->callJava = callJava;
this->url = url;
this->gStatus = gStatus;
}
修改入口cpp native-lib.cpp 中的 new GFFmpeg(callJava, source, gStatus);
gFFmpeg = new GFFmpeg(callJava, source, gStatus);
GAudio.h
#ifndef GODVMUSIC_GAUDIO_H
#define GODVMUSIC_GAUDIO_H
extern "C" {
#include "include/libavcodec/avcodec.h"
};
#include "GQueue.h"
#include "GStatus.h"
class GAudio {
public:
int streamIndex = -1;
AVCodecParameters *codecpar = NULL;
AVCodecContext *avCodecContext = NULL;
GQueue *queue = NULL;
GStatus *gStatus = NULL;
public:
GAudio(GStatus *gStatus);
~GAudio();
};
#endif //GODVMUSIC_GAUDIO_H
GAudio.cpp
#include "GAudio.h"
GAudio::GAudio(GStatus *gStatus) {
this->gStatus = gStatus;
queue = new GQueue(gStatus);
}
GAudio::~GAudio() {
}