2019-03-12 13:59:35 -07:00

107 lines
2.3 KiB
C++

#ifndef LIBAV_CODEC_CONTEXT_HPP
#define LIBAV_CODEC_CONTEXT_HPP
#include "libav/fmt/context.hpp"
#include <utility> //exchange
extern "C"{
# include <libavcodec/avcodec.h>
}
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