#include "av.hpp" extern "C" { #include #include #include #include } #include #include namespace av { format_context format_open_input(const std::string& filename, AVInputFormat* format, AVDictionary** options){ AVFormatContext * ctx = nullptr; avformat_open_input(&ctx, filename.c_str(), format, options); if(!ctx) throw error("Unable to open input " + filename); // This might be optional, but AFAIK people always do this after opening input avformat_find_stream_info(ctx, options); return {ctx, [](auto x){ avformat_close_input(&x); }}; } format_context format_alloc_context(){ auto ptr = avformat_alloc_context(); if(!ptr) throw error("Could not allocate AVFormatContext"); return {avformat_alloc_context(), &avformat_free_context}; } open_codec codec_open(AVCodecContext* ctx, AVCodec* codec, AVDictionary** options){ if(!ctx) throw error("Invalid codec context"); if(!codec) throw error("Invalid codec"); if(avcodec_open2(ctx, codec, options) < 0) throw error("Could not open codec"); return {ctx, [](auto x){ avcodec_close(x); }}; } packet read_frame(format_context& ctx, packet_buffer& p){ if(!av_read_frame(ctx.get(), &p)){ return {nullptr, &av_free_packet}; } else { return {&p, &av_free_packet}; } } frame frame_alloc() { auto ptr = av_frame_alloc(); if(!ptr) throw error("Could not allocate AVFrame"); return {ptr, [](auto x){ av_frame_free(&x); }}; } frame frame_clone(const frame& f){ auto ptr = av_frame_clone(f.get()); if(!ptr) throw error("Could not clone AVFrame"); return {ptr, [](auto x){ av_frame_free(&x); }}; } AVPixelFormat get_format(const frame& f){ return static_cast(f->format); } }