You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
65 lines
1.8 KiB
65 lines
1.8 KiB
10 years ago
|
#include "av.hpp"
|
||
|
|
||
|
extern "C" {
|
||
|
#include <libavutil/frame.h>
|
||
|
#include <libavformat/avformat.h>
|
||
|
#include <libavcodec/avcodec.h>
|
||
|
#include <libswscale/swscale.h>
|
||
|
}
|
||
|
|
||
|
#include <string>
|
||
|
#include <cassert>
|
||
|
|
||
|
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<AVPixelFormat>(f->format);
|
||
|
}
|
||
|
|
||
|
}
|