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;
    }
};

相关推荐

  1. C++智能指针

    2024-01-13 07:02:02       8 阅读
  2. C++11智能指针

    2024-01-13 07:02:02       10 阅读
  3. 不安全指针

    2024-01-13 07:02:02       37 阅读
  4. C++指针详解

    2024-01-13 07:02:02       11 阅读
  5. c++/c指针和悬空指针示例

    2024-01-13 07:02:02       7 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-13 07:02:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-13 07:02:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-13 07:02:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-13 07:02:02       20 阅读

热门阅读

  1. 构建神经网络的流程是什么?

    2024-01-13 07:02:02       30 阅读
  2. vue3中的hook公共函数封装及运用

    2024-01-13 07:02:02       36 阅读
  3. 二Dockerfile实战

    2024-01-13 07:02:02       32 阅读
  4. 【算法题】50. Pow(x, n)

    2024-01-13 07:02:02       34 阅读
  5. 【docker】Docker Stack 详细使用及注意事项

    2024-01-13 07:02:02       33 阅读
  6. Unity 鼠标点击或触摸任意拖动UGUI的方法

    2024-01-13 07:02:02       33 阅读
  7. 50天精通Golang(第15天)

    2024-01-13 07:02:02       32 阅读
  8. mysql undo log、redo log、binlog、mvcc、Buffer Pool的关系

    2024-01-13 07:02:02       33 阅读
  9. ETL详解--数据仓库技术

    2024-01-13 07:02:02       39 阅读
  10. git hooks

    2024-01-13 07:02:02       34 阅读