#include <sstream>
#include <math.h>
#include <time.h>
#include "mem.h"
#include <fstream>
#include <mutex>
#include "videostate.h"
#include "myspdlog.h"
using namespace std;
using namespace N1::N2::N3;
#define FF_QUIT_EVENT (SDL_USEREVENT + 2)
#define FF_INITIATIVE_QUIT_EVENT (SDL_USEREVENT + 3) // 主动关闭视频
PacketQueue::PacketQueue() {
}
PacketQueue::~PacketQueue() {
}
int PacketQueue::packet_queue_init() {
/*
MyAVPacketList *_first_pkt, *_last_pkt;
int _nb_packets;
int _size;
int64_t _duration;
int _abort_request;
int _serial;
SDL_mutex *_mutex;
SDL_cond *_cond;
*/
_first_pkt = _last_pkt = NULL;
_nb_packets = _size = 0;
_duration = 0;
_abort_request = 0;
_serial = 0;
_mutex = NULL;
_cond = NULL;
_mutex = SDL_CreateMutex();
if (!_mutex) {
av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
_cond = SDL_CreateCond();
if (!_cond) {
av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
_abort_request = 1;// ffplay也置为1
return 0;
}
void PacketQueue::packet_queue_flush()
{
/*
MyAVPacketList *_first_pkt, *_last_pkt;
int _nb_packets;
int _size;
int64_t _duration;
int _abort_request;
int _serial;
SDL_mutex *_mutex;
SDL_cond *_cond;
*/
MyAVPacketList *pkt, *pkt1;// pkt指向当前包,pkt1指向当前包的下一个包
SDL_LockMutex(_mutex);
// 遍历链表只用_first_pkt即可,_last_pkt的作用请看packet_queue_put_private.
for (pkt = _first_pkt; pkt; pkt = pkt1) {
pkt1 = pkt->next;
av_packet_unref(&pkt->pkt);// 取消对数据包引用的缓冲区的引用,并将其余的数据包字段重置为默认值。注意flush_pkt也是在队列的,并且因为MyAVPacketList的AVPacket是局部变量,
// 所以只能使用av_packet_unref统一处理,AVPacket可以自动回收;而二次开发时若节点的AVPacket是new出来的,回收时要用delete而不是av_packet_unref,
// 所以应当注意单独使用av_packet_unref回收flush_pkt,因为flush_pkt是全局变量
av_freep(&pkt);// 释放put时malloc的MyAVPacketList节点
}
_last_pkt = NULL;
_first_pkt = NULL;
_nb_packets = 0;
_size = 0;
_duration = 0;
SDL_UnlockMutex(_mutex);
}
void PacketQueue::packet_queue_destroy()
{
// 1. 先清除所有的节点
packet_queue_flush();
// 2. 释放内部资源
if(_mutex){
SDL_DestroyMutex(_mutex);
_mutex = NULL;
}
if(_cond){
SDL_DestroyCond(_cond);
_cond = NULL;
}
}
/**
* @brief 往包队列插入一个包。
* @param q 包队列。可能是音视频、字幕包队列。
* @param pkt 要插入的包。可能是数据包,也可能是个空包,用于刷掉帧队列剩余的帧。
* @return 成功0 失败-1
*/
int PacketQueue::packet_queue_put_private(AVPacket *pkt)
{
MyAVPacketList *pkt1;
// 1. 如果已中止,则放入失败
if (_abort_request)
return -1;
// 2. 分配节点内存
pkt1 = (MyAVPacketList*)av_malloc(sizeof(MyAVPacketList));
if (!pkt1) //内存不足,则返回失败
return -1;
// 3. 赋值,和判断是否插入的是flush_pkt包。
// 没有做引用计数,那这里也说明av_read_frame不会释放替用户释放buffer。
pkt1->pkt = *pkt; //拷贝AVPacket(浅拷贝,AVPacket.data等内存并没有拷贝)
pkt1->next = NULL;
if (pkt == &flush_pkt)//如果放入的是flush_pkt,需要增加队列的播放序列号,以区分不连续的两段数据。
{
_serial++;
printf("q->serial = %d\n", _serial);
}
pkt1->serial = _serial; //用队列序列号标记节点序列号。和上面的包队列->serial作用一样,上面的不变,这里的也不变,上面的变,这里的也会变。
//这里看到,添加flush_pkt时的这个节点的serial也是自增。
/*
* 4. 队列操作:如果last_pkt为空,说明队列是空的,新增节点为队头;例如包队列只有一个包时,first_pkt、last_pkt指向同一个包。
* 注意last_pkt不是指向NULL,和平时的设计不一样,不过内部的next是可能指向NULL。
* 否则,队列有数据,则让原队尾的next为新增节点。 最后将队尾指向新增节点。
*
* 他这个队列的特点:1)first_pkt只操作一次,永远指向首包; 2)last_pkt永远指向尾包,不会指向NULL,但尾包last_pkt内部的next永远指向NULL。
*/
if (!_last_pkt)
_first_pkt = pkt1;
else
_last_pkt->next = pkt1;
_last_pkt = pkt1;
// 5. 队列属性操作:增加节点数、cache大小、cache总时长, 用来控制队列的大小
_nb_packets++;
_size += pkt1->pkt.size + sizeof(*pkt1);// 每个包的大小由:实际数据 + MyAVPacketList的大小。
_duration += pkt1->pkt.duration; // 如果是空包,在av_init_packet时duration被赋值为0.
/* XXX: should duplicate packet data in DV case */
// 6. 发出信号,表明当前队列中有数据了,通知等待中的读线程可以取数据了。这里的读线程应该指解码线程,以便读取包进行解码。
SDL_CondSignal(_cond);
return 0;
}
/**
* @brief 往包队列插入一个包。
* @param q 包队列。可能是音视频、字幕包队列。
* @param pkt 要插入的包。可能是数据包,也可能是个空包,用于刷掉帧队列剩余的帧。
* @return 成功0 失败-1。 see packet_queue_put_private。
*/
int PacketQueue::packet_queue_put(AVPacket *pkt)
{
int ret;
// 1. 调用packet_queue_put_private往包队列put一个包。
SDL_LockMutex(_mutex);
ret = packet_queue_put_private(pkt);//主要实现
SDL_UnlockMutex(_mutex);
// 2. 如果不是flush_pkt包并且放入失败的话,需要释放掉,因为av_read_frame不会帮你释放
// 只有队列中断或者malloc失败返回值才会小于0,所以不需要回收malloc的内容.
if (pkt != &flush_pkt && ret < 0)
av_packet_unref(pkt);
return ret;
}
/**
* @brief 往包队列插入空包。插入空包说明码流数据读取完毕了,之前讲解码的时候说过刷空包是为了从解码器把所有帧都读出来。
* @param q 包队列。可能是音视频、字幕包队列。
* @param stream_index 对应流的下标。可能是音视频、字幕下标。
* @return 成功0 失败-1。 see packet_queue_put、packet_queue_put_private.
*/
int PacketQueue::packet_queue_put_nullpacket(int stream_index)
{
AVPacket pkt1, *pkt = &pkt1;
av_init_packet(pkt);// 以默认值初始化除了data、size外的字段。data、size必须由用户设置。
pkt->data = NULL;
pkt->size = 0;
pkt->stream_index = stream_index;
return packet_queue_put(pkt);
}
void PacketQueue::packet_queue_abort()
{
SDL_LockMutex(_mutex);
_abort_request = 1; // 请求退出.队列的设计带有中断标志,置为1的目的只有1个,就是使packet_queue_put、packet_queue_get这两个函数不能再操作。
SDL_CondSignal(_cond); // 释放一个条件信号.这里只是为了唤醒packet_queue_get中阻塞获取时(SDL_CondWait(_cond, _mutex);),让其更快中断。
SDL_UnlockMutex(_mutex);
}
/**
* @brief packet_queue_get
* @param q 包队列。
* @param pkt 传入传出参数,即MyAVPacketList.pkt。
* @param block 调用者是否需要在没节点可取的情况下阻塞等待。0非阻塞,1阻塞。
* @param serial 传入传出参数,即MyAVPacketList.serial。
* @return <0: aborted; =0: no packet; >0: has packet。
*
* 该队列的get的设计与rtsp-publish推流的PacketQueue的get类似。
* packet_queue_ge
没有合适的资源?快使用搜索试试~ 我知道了~
一个使用C++实现ffplay的项目,包括源码以及dll的方式.zip
共666个文件
h:499个
dll:95个
lib:44个
需积分: 1 0 下载量 36 浏览量
2024-08-09
10:04:35
上传
评论
收藏 158.25MB ZIP 举报
温馨提示
优质项目,资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松copy复刻,拿到资料包后可轻松复现出一样的项目。 本人系统开发经验充足,有任何使用问题欢迎随时与我联系,我会及时为你解惑,提供帮助。 【资源内容】:项目具体内容可查看下方的资源详情,包含完整源码+工程文件+说明等(若有)。 【附带帮助】: 若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步。 【本人专注计算机领域】: 有任何使用问题欢迎随时与我联系,我会及时解答,第一时间为你提供帮助,CSDN博客端可私信,为你解惑,欢迎交流。 【适合场景】: 相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可以基于此项目进行扩展来开发出更多功能 【无积分此资源可联系获取】 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。积分/付费仅作为资源整理辛苦费用。
资源推荐
资源详情
资源评论
收起资源包目录
一个使用C++实现ffplay的项目,包括源码以及dll的方式.zip (666个子文件)
ffplayCppDllTest.pro.user.4.8-pre1 63KB
ffplayCppDll.pro.user.4.8-pre1 61KB
ffplayCpp.pro.user.4.8-pre1 43KB
SDL_config.h.cmake 18KB
SDL_config.h.cmake 18KB
videostate.cpp 287KB
ffplay.cpp 281KB
properties.cpp 5KB
myspdlog.cpp 2KB
main.cpp 2KB
main.cpp 1KB
libharfbuzz-0.dll 44.39MB
libharfbuzz-0.dll 44.39MB
libharfbuzz-0.dll 43.39MB
libharfbuzz-0.dll 43.39MB
libharfbuzz-subset-0.dll 25.03MB
libharfbuzz-subset-0.dll 25.03MB
libharfbuzz-subset-0.dll 23.94MB
libharfbuzz-subset-0.dll 23.94MB
avcodec-58.dll 13.35MB
avcodec-58.dll 13.35MB
avcodec-58.dll 13.2MB
avcodec-58.dll 13.2MB
libfdk-aac-2.dll 9.44MB
libfdk-aac-2.dll 9.44MB
libfdk-aac-2.dll 8.95MB
libfdk-aac-2.dll 8.95MB
libxml2-2.dll 5.66MB
libxml2-2.dll 5.66MB
libxml2-2.dll 5.18MB
libxml2-2.dll 5.18MB
libfreetype-6.dll 3.75MB
libfreetype-6.dll 3.75MB
libfreetype-6.dll 3.57MB
libfreetype-6.dll 3.57MB
avfilter-7.dll 2.89MB
avfilter-7.dll 2.89MB
avfilter-7.dll 2.81MB
avfilter-7.dll 2.81MB
avformat-58.dll 2.44MB
avformat-58.dll 2.44MB
libx264-164.dll 2.4MB
libx264-164.dll 2.4MB
libx264-164.dll 2.25MB
libx264-164.dll 2.25MB
avformat-58.dll 2.17MB
avformat-58.dll 2.17MB
SDL2.dll 2.15MB
SDL2.dll 2.15MB
SDL2.dll 1.95MB
SDL2.dll 1.95MB
SDL2.dll 1.88MB
SDL2.dll 1.88MB
libstdc++-6.dll 1.47MB
libass-9.dll 1.45MB
libass-9.dll 1.45MB
libfontconfig-1.dll 1.41MB
libfontconfig-1.dll 1.41MB
libass-9.dll 1.37MB
libass-9.dll 1.37MB
libfontconfig-1.dll 1.28MB
libfontconfig-1.dll 1.28MB
libiconv-2.dll 1.07MB
libiconv-2.dll 1.07MB
avutil-56.dll 591KB
avutil-56.dll 591KB
swscale-5.dll 556KB
swscale-5.dll 556KB
swscale-5.dll 526KB
swscale-5.dll 526KB
avutil-56.dll 516KB
avutil-56.dll 516KB
libfribidi-0.dll 300KB
libfribidi-0.dll 300KB
libfribidi-0.dll 285KB
libfribidi-0.dll 285KB
liblzma-5.dll 169KB
liblzma-5.dll 169KB
avdevice-58.dll 149KB
avdevice-58.dll 149KB
libintl-8.dll 144KB
libintl-8.dll 144KB
libgcc_s_dw2-1.dll 142KB
libgcc_s_dw2-1.dll 142KB
libbrotlicommon.dll 141KB
libbrotlicommon.dll 141KB
avdevice-58.dll 141KB
avdevice-58.dll 141KB
libintl-8.dll 134KB
libintl-8.dll 134KB
postproc-55.dll 131KB
postproc-55.dll 131KB
postproc-55.dll 129KB
postproc-55.dll 129KB
swresample-3.dll 127KB
swresample-3.dll 127KB
zlib1.dll 122KB
zlib1.dll 122KB
swresample-3.dll 121KB
swresample-3.dll 121KB
共 666 条
- 1
- 2
- 3
- 4
- 5
- 6
- 7
资源评论
专家大圣
- 粉丝: 1490
- 资源: 6298
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功