范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

FFmpeg入门学习03缓存队列的实现

  1、前言
  在之前的文章中实现了打开视频文件并进行解封装的功能,解封装之后即可进行解码操作。 为使解码过程不会受到解封装过程进展的影响,解封装和解码一般并行操作,两者之间通过缓存数据进行交互。
  2、背景2.1 线程安全队列
  由于 STL 中的容器是非线程安全的,因此要实现解封装和解码的并行操作需要实现一个线程安全的队列。 由于 std::deque 可以方便的在头尾进行数据的读写,此处选用 std::deque 来简单实现一个线程安全的队列。 2.2 AVPacket 和 AVFrame
  在 FFmpeg 中解码前和解码后的数据分别使用 AVPacket 和 AVFrame 进行存储。 AVPacket 及 AVFrame 是采用引用计数的方式进行内部资源的管理,在对缓存数据进行读写时要特别注意数据的释放问题,以避免内存泄漏。 2.3 成员函数模板特例化
  由于 AVPacket 和 AVFrame 资源管理的接口不同,为避免特例化类的所有成员,仅把相关方法通过类的成员函数模板特化来实现。 3、缓存队列的实现3.1 概述
  此处实现的缓存队列仅满足对 AVPacket 和 AVFrame 的管理,且读写两个并发操作互相不受影响即可。 3.2 接口设计template  class Queue { private:     std::deque    queue;     mutable std::mutex   mutex;//访问互斥信号量     int       maxSize{0};//最大容量 public:     Queue() = default;     explicit Queue(int m_size ): maxSize(m_size){}     ~Queue() = default;          bool    IsEmpty() const;//判断队列是否为空     int     size() const;//当前元素个数     bool    IsFull() const;//判断队列是否已满     void    pushBack( T* t );//尾部添加元素     void    pushFront( T* t );//头部添加元素     T *     front();//读取首元素     T *     back();//读取尾元素     T *     operator[](int i);//按下标读取元素     void    popBack();//删除尾元素     void    popFront();//删除首元素     void    clear();//清空队列 };3.2 通用方法实现
  为实现基本的线程安全保存,所有的成员方法必须加锁,实现如下: bool    IsEmpty() const {       std::unique_lock lock(mutex);       return queue.empty(); }//判断队列是否为空 int     size() const {       std::unique_lock lock(mutex);       return queue.size(); }//当前元素个数 bool    IsFull() const {       std::unique_lock lock(mutex);       return maxSize <= queue.size(); }//判断队列是否已满 void    pushBack( T* t ) {       std::unique_lock lock(mutex);       queue.push_back(t); }//尾部添加元素 void    pushFront( T* t ) {       std::unique_lock lock(mutex);       queue.push_front(t); }//头部添加元素3.3 成员函数模板特例化
  涉及到数据读取、删除等资源管理相关操作,要进行成员函数模板特例化实现,以 front() 方法的实现为例: 成员函数实现为模板 T *     front()  {     return  frontImpl(); }//读取首元素 private:     template      void    popFrontImpl();进行 AVPacket 特例化 template <> void popFrontImpl() {     std::unique_lock lock(mutex);     if (!queue.empty())     {           auto packet = queue.front();           av_packet_unref(packet);           av_packet_free(&packet);           queue.pop_front();     } }进行 AVFrame 特例化 template <> void popFrontImpl() {       std::unique_lock lock(mutex);       if (!queue.empty())       {           auto frame = queue.front();           av_frame_unref(frame);           av_frame_free(&frame);           queue.pop_front();       } }4、缓存队列使用示例
  C++音视频学习资料免费获取方法:关注音视频开发T哥  ,点击「链接」即可免费获取2023年最新 C++音视频开发进阶独家免费学习大礼包! 4.1 完善 FFmpegPlayer 类
  在 FFmpegPlayer 类中增加两个成员,用于保存音视频解封装后的数据包: class FFmpegPlayer { public:     explicit FFmpegPlayer(const char* m_url);     ~FFmpegPlayer(); public:     bool        openFile();//打开文件     void        startDecode();//开启循环解码     void        abortDecode();//中断解码 private:     int         readOnePacket();//读一个包     int         readPacket();//循环读包 private:     std::string       url;//文件路径     AVFormatContext*  formatContext = nullptr;//封装格式上下文     AVPacket          packet{}; //用于读包      std::thread *     read_thread = nullptr;//数据读取线程     bool              abort_request{false};//强制结束     bool              readEof{false};//读包结束      int               video_index{-1};//视频流索引     int               audio_index{-1};//音频流索引     Queue*  video_packet_Queue{ nullptr };//视频 packet 队列     Queue*  audio_packet_Queue{ nullptr };//视频 packet 队列  };
  4.2 初始化队列大小
  在 FFmpegPlayer 类构造函数中初始化两个缓存队列,代码如下: FFmpegPlayer::FFmpegPlayer(const char *m_url):         url(m_url) ,         video_packet_Queue(new Queue(20)),         audio_packet_Queue(new Queue(20)) {      }4.2 完善 readPacket() 方法
  使用 av_packet_move_ref 方法转移对资源的引用、以保证资源的正确释放,代码如下: int FFmpegPlayer::readPacket()  {     while(true)     {         if( abort_request ) break;//用户退出         std::shared_ptr pktClear(&packet, [](AVPacket *p)         {             av_packet_unref(p);         });//用来确保每次 av_read_frame 后 pkt 缓存被清理了          int ret = readOnePacket();         if( ret == 0 )         {             if (packet.stream_index == video_index && !video_packet_Queue->IsFull() )             {                 AVPacket* m_packet =  av_packet_alloc();                 av_packet_move_ref(m_packet,&packet);                 video_packet_Queue->pushBack(m_packet);                  std::cout << "video_packet_Queue size " << video_packet_Queue->size() << std::endl;             }             else  if (packet.stream_index == audio_index && !audio_packet_Queue->IsFull())             {                 AVPacket* m_packet =  av_packet_alloc();                 av_packet_move_ref(m_packet,&packet);                 audio_packet_Queue->pushBack(m_packet);                  std::cout << "audio_packet_Queue size " << audio_packet_Queue->size() << std::endl;             }         }      }     return 0; }4.3 代码运行示例
  文件打开成功后,调用解复用接口,代码如下: #include "FFmpegPlayer.h" int main() {      const char  * url = "C:LzcWorkCodetest.mkv";     FFmpegPlayer * player = new FFmpegPlayer(url);     if( player->openFile())     {         std::cout << "文件打开成功!"<startDecode();     }          system("pause");     return 0; }
  运行结果如下:
  原文链接:FFmpeg 入门学习 03--缓存队列的实现

中医讲堂面瘫正确的中医临床思维(三)面瘫定义面瘫是以口角(眼)向一侧歪斜为主症的病证,又称口眼斜。可发生于任何年龄,无明显的季节性,多发病急速,以一侧面部发病多见。本篇所述为周围性面神经麻痹,常见于贝尔麻痹亦见广东人看了直摇头的3类差劲酒,喝完就上头,酒友全是假酒中国23个省,5个自治区,4个直辖市,2个特别行政区,但要说哪里人最爱养生,还得是广东人!很多人对广东人的第一印象就是不仅爱吃还会吃,但凡是能入口的,他们都能做成美食,也不管是天上美白精华哪个好?这个日系发光瓶不能错过美白,永恒经典的护肤课题,除了防晒外,美白产品的选择也是爱美功课的重中之重,今天就来讲讲我们该从什么维度来判断美白产品。拿我过去一年空瓶的3盒的玛丽安保莱发光瓶来说,它基本围绕了黑44岁刘涛与40岁阿sa在巴黎时装周同框,一甜美一冷艳巴黎时装周在法国巴黎拉开序幕了,不少国内明星都赶到了那里,其中不饭有演技派也有人气派明星,章子怡章泽天薛凯琪成毅刘涛阿娇阿sa等都已抵达巴黎。刘涛在抵达巴黎后,就火速地来上了一组时张馨予身材真丰满,微胖身材穿半透内搭,丰满翘臀太性感了!在大众的认知里,往往以瘦作为衡量女性美丑的标准。好比说A4纸腰反手摸肚脐再或者体重不过百等等。然而这样的标准,使得有很多女性,因为自身体重不够瘦,而不自信。在娱乐圈里,就有很多比较靳东朱亚文亲身示范西服配运动鞋,风衣不配皮鞋,帅气不油腻随着年龄的增长,我们的审美也要与时俱进,选择符合年龄契合气质的穿衣打扮,才不会给人装嫩或显老的感觉。尤其是进入中年阶段的男性,要明确区分油腻大叔和叔圈男神,前者表现为不修边幅邋遢的SPSS下载统计分析软件SPSSv25至SPSSv27版下载安装激活教程SPSS(StatisticalProductandServiceSolutions)是一款由IBM公司开发的统计分析软件,它为用户提供了强大的统计分析和数据挖掘工具,可帮助用户从36氪首发丨傲雪睿视完成数千万元PreA轮融资,致力于打造适用于元宇宙的XR终端36氪获悉,中国VR及MR头显厂商傲雪睿视已于近日完成了数千万元PreA轮融资(投资方暂不透露),本轮融资将主要于新品研发市场拓展人员扩充等方面。图片由企业官方提供傲雪睿视致力于轻普尔34分勇士下半场吊打快船获4连胜勇士主场11591大胜快船送给对手4连败,同时取得4连胜。祖巴茨马库斯莫里斯缺阵,勇士这边库里维金斯也缺席。勇士上来让格林对位放空威少。威少靠着两次突破拿分,普拉姆利连投带罚,快船激情碰撞!首届杨浦区中式台球锦标赛圆满收杆近日,2022年第一届杨浦区中式台球锦标赛于在杨浦区OT台球俱乐部举行。比赛采用双败淘汰制,经过六轮近九小时的激烈比拼,最后由徐人杰胡思昊陈泽祺选手荣获比赛前三名。本次比赛由杨浦区沃尔玛又关一店,曾经流行的大卖场为什么越来越少了?曾经人头攒动的大卖场,如今正在逐渐淡出我们的生活圈。近日,商业那点事儿小编发现,新世界百货大望路店地下一层的沃尔玛大卖场出现多数货架空置的情况,冰柜也基本已被清空,不少商品正在通过
洲际酒店集团2023年大中华区开业计划一览续添在华强劲动能,邀请全球宾客重启美好旅程2023年2月23日,上海伴随国内文旅市场火爆势头不减港澳和内地全面恢复通关以及跨境旅游有序复苏等多重利好的释放,文旅行业亦将日新月异启新走进区域看发展以后坐高铁去看大足石刻从这个站下走800米就到了工作人员给大家介绍成渝中线高铁大足石刻站在建情况。华龙网新重庆客户端记者罗杰摄华龙网新重庆客户端讯(记者伊永军)大足石刻作为人类文化艺术的瑰宝,一直以来吸引着世界各地的游客前来观摩四川成都旅游最火的5个川味古镇,小众宝藏地,你去过吗?头条创作挑战赛头条免费正版图著名女作家毕淑敏说一个地方要适合私奔,至少要具备两个条件第一是风景秀美,在有山有水的地方才有心思谈情说爱第二要人迹罕见。在四川成都就有5个特色的古镇,不三亚大小洞天景区第二十四批新疆支教队将前往塔县支教新海南客户端南海网南国都市报2月23日消息(记者符彩云马子涛)2月23日,三亚大小洞天景区第二十四批援疆支教活动启动仪式举行。2023年招募的3名志愿者作为第二十四批支教队员将于2汝阳县乡村会客厅绘出乡村振兴新图景河南日报客户端记者李宗宽郭歌通讯员张晨薛艺辉袁一文金英莉2月23日,汝阳县付店镇,在新落成的付店镇乡村会客厅,花团锦簇,一步一景。造型别致的吊灯下摆放着木质大茶桌,和绿色植物相映成谷主说遇见玛御谷,遇见美好生活晨曦的阳光柔和地擦亮山谷,缕缕晨雾像人清醒前的呢喃梦呓,缓缓飘向天空。这是山谷给予清晨的回应,也是新的一天到来的标识。大清早,李继东便开始了他一如既往的课题晨练。小镇的自然环境优越超便捷!广州至香港直通巴士可一站直达了随着香港全面恢复通关,各公路陆路口岸的直通巴士线路也陆续恢复。为便利广州旅客访港,近日,环岛中港通推出广州到香港巴士一站直达服务,改变了几十年来需在市内绕道途径几站上客的营运方式。杭州亚运会在幼儿园萌娃眼里是怎么样的互动课上他们又问又玩好开心离杭州亚运会召开的时间越来越近了,亚运会氛围也越来越浓厚了,不少孩子在家长的带领下,走进亚运场馆了解即将举行的亚运赛事。近日,杭州市童星幼儿园开展了一场亚运知识知多少的活动。亚运会浊水溪位于台湾本岛西中部,源出中央山脉合欢山南麓浊水溪,是中国台湾省最长的河流。位于台湾本岛西中部,河长186。4公里,流域面积3100平方公里。源出中央山脉合欢山南麓,向南接纳万大溪,沿山脉走向南下,接纳南来的郡大溪后,向西流湛江这些入围的特色景点,有你想去的吗?湛江旅游官方微信公众号关注为推进绿美广东生态建设经过前期调研挖掘设计近日广东省林业局公布了10条南粤红绿径特色线路其中湛茂阳线路榜上有名此次推出的线路囊括了广东多处红色印迹自然保护为什么人口大爆发的清朝,汉族人口越来越多,而蒙古满族越来越少清朝和其他历史朝代所不同的是,这个朝代在面对了前朝的经验面前,建立起来了一个皇权巅峰的王朝,但同时有一个很大的问题,就是不知道该如何处理国族之中的巨额穷人,这些正是人口大爆发时代清