本篇是在上一篇的基础上增加队列处理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_HGQueue.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_HGStatus.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_HGAudio.cpp
#include "GAudio.h" GAudio::GAudio(GStatus *gStatus) { this->gStatus = gStatus; queue = new GQueue(gStatus); } GAudio::~GAudio() { }