• 音视频项目—基于FFmpeg和SDL的音视频播放器解析(十一)


    介绍

    在本系列,我打算花大篇幅讲解我的 gitee 项目音视频播放器,在这个项目,您可以学到音视频解封装,解码,SDL渲染相关的知识。您对源代码感兴趣的话,请查看基于FFmpeg和SDL的音视频播放器

    如果您不理解本文,可参考我的前一篇文章音视频项目—基于FFmpeg和SDL的音视频播放器解析(十)

    解析

    我们这一篇文章讲解 AVFrameQueue,先看 .h 文件代码

    1. #ifndef AVFRAMEQUEUE_H_
    2. #define AVFRAMEQUEUE_H_
    3. #include"queue.h"
    4. #ifdef __cplusplus
    5. extern "C" {
    6. #include"libavutil/avutil.h"
    7. #include"libavformat/avformat.h"
    8. #include"libavcodec/avcodec.h"
    9. }
    10. #endif
    11. class AVFrameQueue{
    12. public:
    13. AVFrameQueue();
    14. ~AVFrameQueue();
    15. void Abort();
    16. int Push(AVFrame* val);
    17. AVFrame* Pop(const int timeout);
    18. AVFrame* Front();
    19. int Size();
    20. private:
    21. void release();
    22. Queue queue_t;
    23. };
    24. #endif

    整体上看,与 AVPacketQueue 的函数没有什么区别,都是 Abort,Push,Pop,Front,Size,release,只是存放的数据不一样,一个放的是包(Packet),一个放的是帧(Frame)。

    我们来看一下函数的实现

    Abort:
    1. void AVFrameQueue::Abort(){
    2. release();
    3. queue_t.Abort();
    4. }

    这函数负责程序的中断,先调用了 release 函数释放了队列的数据,在调用 Queue 父类的 Abort 方法终止程序。

    Push:
    1. int AVFrameQueue::Push(AVFrame* val){
    2. return queue_t.Push(val);
    3. }

    这函数负责队列的增加数据。直接调用 Queue 父类的 Push 方法,很好理解。

    Pop:
    1. AVFrame* AVFrameQueue::Pop(const int timeout){
    2. AVFrame* av_frame = nullptr;
    3. int ret = queue_t.Pop(av_frame, timeout);
    4. if(ret < 0){
    5. perror("AVFrameQueue:: Pop failed");
    6. }
    7. return av_frame;
    8. }

    这函数负责队列弹出数据。由于这个 Queue 父类的方法需要讲弹出的数据赋值给参数,因此我们需要在函数头部增加一个 AVFrame 的变量,用来传递给函数。

    Front:
    1. AVFrame* AVFrameQueue::Front(){
    2. AVFrame* av_frame = nullptr;
    3. int ret = queue_t.Front(av_frame);
    4. if(ret < 0){
    5. perror("AVFrameQueue:: Front failed");
    6. }
    7. return av_frame;
    8. }

    这函数负责返回队列的首部数据。这也很好理解,直接调用 Queue 父类的 Front 函数。

    Size:
    1. int AVFrameQueue::Size(){
    2. return queue_t.Size();
    3. }

    这函数负责返回队列的长度。直接调用 Queue 的 Size 方法即可。

    release:
    1. void AVFrameQueue::release(){
    2. while(true){
    3. AVFrame* av_frame = nullptr;
    4. int ret = queue_t.Pop(av_frame, 1);
    5. if(ret < 0){
    6. break;
    7. }else {
    8. av_frame_free(&av_frame);
    9. }
    10. }
    11. }

    这函数负责释放队列的所有元素。函数有一个 while 的死循环,然后不断 Pop 队列的数据,直到没有为止,跳出循环。

    好了,Queue,AVPacketQueue,AVFrameQueue 都讲完了。下一篇文章我们会讲音视频同步的机制以及如何实现。

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

  • 相关阅读:
    生成模型相关算法:EM算法步骤和公式推导
    数据库字典Navicat自动生成版本
    Mysql索引
    【计算机组成原理】读书笔记第二期:使用有棱有角的内存
    docker构建python3容器、压缩python镜像大小
    MES在流程和离散制造企业的15个差别(上)
    【Java】解决Java报错:ConcurrentModificationException
    SIMULIA|Abaqus 2022x新功能介绍第三弹
    Java版工程行业管理系统源码-专业的工程管理软件- 工程项目各模块及其功能点清单
    使用OAK-D相机跑ORB-SLAM3算法遇到的问题总结
  • 原文地址:https://blog.csdn.net/weixin_60701731/article/details/134474591