#ifndef LIBAV_CODEC_CONTEXT_HPP #define LIBAV_CODEC_CONTEXT_HPP #include "libav/fmt/context.hpp" #include //exchange extern "C"{ # include } namespace libav::codec{ class context { private: AVCodecContext* m_context = nullptr; const AVCodec* m_codec = nullptr; bool m_open = false; public: context(const libav::fmt::input_context& ctx, int index){ AVCodecParameters* cparms = ctx->streams[index]->codecpar; m_codec = avcodec_find_decoder(cparms->codec_id); m_context = avcodec_alloc_context3(m_codec); if(!m_context) return; avcodec_parameters_to_context(m_context, cparms); } context(const libav::fmt::output_context& ctx, int index){ AVCodecParameters* cparms = ctx->streams[index]->codecpar; m_codec = avcodec_find_encoder(cparms->codec_id); m_context = avcodec_alloc_context3(m_codec); if(!m_context) return; avcodec_parameters_to_context(m_context, cparms); } context(const AVCodec* codec){ m_codec = codec; m_context = avcodec_alloc_context3(m_codec); } context(const context&) = delete; context(context&& c)noexcept: m_context(std::exchange(c.m_context, nullptr)), m_codec(c.m_codec), m_open(c.m_open){} ~context(void){ reset(); } context& operator=(const context&) = delete; context& operator=(context&& c)noexcept{ std::swap(m_context, c.m_context); m_codec = c.m_codec; std::swap(m_open, c.m_open); return *this; } bool open(void){ if(!m_open){ int ret = avcodec_open2(m_context, m_codec, NULL); return (m_open = (ret >= 0)); } return false; } bool is_open(void)const{ return m_open; } void reset(void){ if(m_open) avcodec_close(m_context); if(m_context) avcodec_free_context(&m_context); m_open = false; m_context = nullptr; m_codec = nullptr; } AVCodecContext* release(void){ return std::exchange(m_context, nullptr); } AVCodecContext* operator->(void){ return m_context; } const AVCodecContext* operator->(void)const{ return m_context; } AVCodecContext* get(void){ return m_context; } const AVCodecContext* get(void)const{ return m_context; } operator AVCodecContext*(void){ return m_context; } operator const AVCodecContext*(void)const{ return m_context; } operator bool(void)const{ return m_context; } }; } #endif