openal中使用现代C++智能指针管理ffmpeg中裸指针的用法

这篇具有很好参考价值的文章主要介绍了openal中使用现代C++智能指针管理ffmpeg中裸指针的用法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

裸指针包装


/* Define unique_ptrs to auto-cleanup associated ffmpeg objects. */
struct AVIOContextDeleter {
    void operator()(AVIOContext *ptr) { avio_closep(&ptr); }
};
using AVIOContextPtr = std::unique_ptr<AVIOContext,AVIOContextDeleter>;

struct AVFormatCtxDeleter {
    void operator()(AVFormatContext *ptr) { avformat_close_input(&ptr); }
};
using AVFormatCtxPtr = std::unique_ptr<AVFormatContext,AVFormatCtxDeleter>;

struct AVCodecCtxDeleter {
    void operator()(AVCodecContext *ptr) { avcodec_free_context(&ptr); }
};
using AVCodecCtxPtr = std::unique_ptr<AVCodecContext,AVCodecCtxDeleter>;

struct AVPacketDeleter {
    void operator()(AVPacket *pkt) { av_packet_free(&pkt); }
};
using AVPacketPtr = std::unique_ptr<AVPacket,AVPacketDeleter>;

struct AVFrameDeleter {
    void operator()(AVFrame *ptr) { av_frame_free(&ptr); }
};
using AVFramePtr = std::unique_ptr<AVFrame,AVFrameDeleter>;

struct SwrContextDeleter {
    void operator()(SwrContext *ptr) { swr_free(&ptr); }
};
using SwrContextPtr = std::unique_ptr<SwrContext,SwrContextDeleter>;

struct SwsContextDeleter {
    void operator()(SwsContext *ptr) { sws_freeContext(ptr); }
};
using SwsContextPtr = std::unique_ptr<SwsContext,SwsContextDeleter>;

对象


struct ChannelLayout : public AVChannelLayout {
    ChannelLayout() : AVChannelLayout{} { }
    ~ChannelLayout() { av_channel_layout_uninit(this); }
};

智能指针使用和轮子—解包队列

template<size_t SizeLimit>
class DataQueue {
    std::mutex mPacketMutex, mFrameMutex;
    std::condition_variable mPacketCond;
    std::condition_variable mInFrameCond, mOutFrameCond;

    std::deque<AVPacketPtr> mPackets;
    size_t mTotalSize{0};
    bool mFinished{false};

    AVPacketPtr getPacket()
    {
        std::unique_lock<std::mutex> plock{mPacketMutex};
        while(mPackets.empty() && !mFinished)
            mPacketCond.wait(plock);
        if(mPackets.empty())
            return nullptr;

        auto ret = std::move(mPackets.front());
        mPackets.pop_front();
        mTotalSize -= static_cast<unsigned int>(ret->size);
        return ret;
    }

public:
    int sendPacket(AVCodecContext *codecctx)
    {
        AVPacketPtr packet{getPacket()};

        int ret{};
        {
            std::unique_lock<std::mutex> flock{mFrameMutex};
            while((ret=avcodec_send_packet(codecctx, packet.get())) == AVERROR(EAGAIN))
                mInFrameCond.wait_for(flock, milliseconds{50});
        }
        mOutFrameCond.notify_one();

        if(!packet)
        {
            if(!ret) return AVErrorEOF;
            std::cerr<< "Failed to send flush packet: "<<ret <<std::endl;
            return ret;
        }
        if(ret < 0)
            std::cerr<< "Failed to send packet: "<<ret <<std::endl;
        return ret;
    }

    int receiveFrame(AVCodecContext *codecctx, AVFrame *frame)
    {
        int ret{};
        {
            std::unique_lock<std::mutex> flock{mFrameMutex};
            while((ret=avcodec_receive_frame(codecctx, frame)) == AVERROR(EAGAIN))
                mOutFrameCond.wait_for(flock, milliseconds{50});
        }
        mInFrameCond.notify_one();
        return ret;
    }

    void setFinished()
    {
        {
            std::lock_guard<std::mutex> _{mPacketMutex};
            mFinished = true;
        }
        mPacketCond.notify_one();
    }

    void flush()
    {
        {
            std::lock_guard<std::mutex> _{mPacketMutex};
            mFinished = true;

            mPackets.clear();
            mTotalSize = 0;
        }
        mPacketCond.notify_one();
    }

    bool put(const AVPacket *pkt)
    {
        {
            std::unique_lock<std::mutex> lock{mPacketMutex};
            if(mTotalSize >= SizeLimit || mFinished)
                return false;

            mPackets.push_back(AVPacketPtr{av_packet_alloc()});
            if(av_packet_ref(mPackets.back().get(), pkt) != 0)
            {
                mPackets.pop_back();
                return true;
            }

            mTotalSize += static_cast<unsigned int>(mPackets.back()->size);
        }
        mPacketCond.notify_one();
        return true;
    }
};

文章来源地址https://www.toymoban.com/news/detail-811526.html

到了这里,关于openal中使用现代C++智能指针管理ffmpeg中裸指针的用法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++智能指针shared_ptr使用详解

    shared_ptr 是一个共享所有权的智能指针,允许多个指针指向同一个对象。 ​ shared_ptr 使用 引用计数 ,每一个shared_ptr的拷贝都指向相同的内存。每使用它一次,内部的引用计数加1,每析构一次,内部的引用计数减1,减为0时,释放所指向的堆内存。shared_ptr内部的引用计数是安

    2024年02月07日
    浏览(42)
  • 【C++ 观察者模式 思想理解】C++中的观察者模式:松耦合设计与动态交互的艺术,合理使用智能指针观察者

    在进入技术细节之前,理解观察者模式(Observer Pattern)的基本概念和它在现代编程中的重要性是至关重要的。 观察者模式是一种设计模式,它定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。在C++中,这个

    2024年01月24日
    浏览(56)
  • 【重学C++】02 脱离指针陷阱:深入浅出 C++ 智能指针

    【重学C++】02 脱离指针陷阱:深入浅出 C++ 智能指针 大家好,今天是【重学C++】系列的第二讲,我们来聊聊C++的智能指针。 在上一讲《01 C++如何进行内存资源管理》中,提到了对于堆上的内存资源,需要我们手动分配和释放。管理这些资源是个技术活,一不小心,就会导致内

    2024年02月05日
    浏览(59)
  • 写个简单的管理数组指针的智能指针

    模板智能数组指针 1.管理任意类型的数组指针 2.释放的时候自动删除数组指针指向的内存 3.通过指针计算数组中的个数   3.要有指针的样式和数组的样式 4.支持for范围查询和迭代器 5.实例用法  

    2024年02月08日
    浏览(51)
  • C++新特性:智能指针

    智能指针主要解决以下问题: 1)内存泄漏:内存手动释放,使用智能指针可以自动释放 2)共享所有权指针的传播和释放,比如多线程使用同一个对象时析构问题,例如同样的数据帧,但是业务A和业务B处理的逻辑不一样(都是只读)。可以用 shared_ptr 共享数据帧对象的所有

    2024年02月09日
    浏览(43)
  • C++——智能指针

    内存泄漏 什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内 存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对 该段内存的控制,因而造成了内存的浪费。 内存泄漏的危害:长期运行的

    2024年02月09日
    浏览(72)
  • C++进阶 智能指针

    本篇博客简介:介绍C++中的智能指针 我们首先来看下面的这段代码 在上面这段代码中有着一个很明显的内存泄露风险 当我们的程序运行在Func函数内的div函数时 很可能因为除0错误而跳转到另外一个执行流从而导致Func函数内两个new出来的内存没法被回收 为了解决这个问题我

    2024年02月13日
    浏览(50)
  • 智能指针——C++

    智能指针相较于普通指针的区别,就是智能指针可以不用主动释放内存空间,系统会自动释放,避免了内存泄漏。 需包含的头文件: #include memory unique_ptr 三种定义方式 先定义一个类 使用std::make_unique的方式:推荐使用的方式 程序结束自动调用析构函数 使用new的方式声明智能

    2023年04月22日
    浏览(49)
  • 【C++学习】智能指针

    🐱作者:一只大喵咪1201 🐱专栏:《C++学习》 🔥格言: 你只管努力,剩下的交给时间! 如上图代码所示,在Func中开辟动态空间,在调用完Division函数后释放该空间。 如果Division没有抛异常,那么动态空间会被正常释放。 如果Division抛了异常,就会去匹配对应的catch,而Fu

    2024年02月06日
    浏览(57)
  • c++ 学习系列 -- 智能指针

    C++ 程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理。但使用普通指针,容易造成内存泄露(忘记释放)、二次释放、程序发生异常时内存泄露等问题等。 另外,使用普通指针容易产生 野指针、悬空指针 等问题。 所以 C++11 就引入了智能指

    2024年02月13日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包