Browse Source

Wraps two av functions in c++

master
Joshua Moerman 10 years ago
parent
commit
3984c7d52b
  1. 25
      lib/av/av.cpp
  2. 5
      lib/av/av.hpp
  3. 20
      lib/image_io.cpp

25
lib/av/av.cpp

@ -6,9 +6,15 @@ extern "C" {
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
} }
#include <iostream>
#include <string> #include <string>
#include <cassert> #include <cassert>
// Was not yet defined in <string> :(
static std::string operator "" s(const char *str, std::size_t len){
return {str, len};
}
namespace av { namespace av {
format_context format_open_input(const std::string& filename, AVInputFormat* format, AVDictionary** options){ format_context format_open_input(const std::string& filename, AVInputFormat* format, AVDictionary** options){
@ -98,4 +104,23 @@ namespace av {
return crop(frame_clone(f), left, top, width, height); return crop(frame_clone(f), left, top, width, height);
} }
bool codec_decode_video(codec_context& ctx, frame& f, const packet& pkt){
int finished = 0;
int ret = avcodec_decode_video2(ctx.get(), f.get(), &finished, pkt.get());
if (ret < 0) {
throw std::runtime_error("Error ["s + std::to_string(ret) + "] while decoding frame: "s + strerror(AVERROR(ret)));
}
return finished;
}
void codec_decode_video_remaining(codec_context& ctx, frame& f){
AVPacket pkt{0, 0, 0, 0, 0}; // data and size should be 0
int finished = 0;
int ret = avcodec_decode_video2(ctx.get(), f.get(), &finished, &pkt);
if (ret < 0) {
throw std::runtime_error("Error ["s + std::to_string(ret) + "] while decoding remaining frame: "s + strerror(AVERROR(ret)));
}
}
} }

5
lib/av/av.hpp

@ -45,4 +45,9 @@ namespace av {
void crop(frame & f, int left, int top, int width, int height); void crop(frame & f, int left, int top, int width, int height);
frame crop(frame && f, int left, int top, int width, int height); frame crop(frame && f, int left, int top, int width, int height);
frame crop(frame const & f, int left, int top, int width, int height); frame crop(frame const & f, int left, int top, int width, int height);
//
bool codec_decode_video(codec_context & ctx, frame & f, packet const & pkt);
void codec_decode_video_remaining(codec_context & ctx, frame & f);
} }

20
lib/image_io.cpp

@ -55,23 +55,21 @@ av::frame open_image(std::string const & filename){
// things to read and decode it // things to read and decode it
av::packet_buffer empty_packet; av::packet_buffer empty_packet;
int finished = 0; bool need_extra_pass = true;
while(auto packet = av::read_frame(format_context, empty_packet)) { while(auto packet = av::read_frame(format_context, empty_packet)) {
if(packet->stream_index != 0) continue; if(packet->stream_index != 0) continue;
int ret = avcodec_decode_video2(codec_context.get(), frame.get(), &finished, packet.get());
if (ret <= 0) {
printf("Error [%d] while decoding frame: %s\n", ret, strerror(AVERROR(ret)));
throw std::runtime_error("boem packet");
}
// we only need the first frame // we only need the first frame
if(finished) break; if(av::codec_decode_video(codec_context, frame, packet)) {
need_extra_pass = false;
break;
}
} }
// some decoders need extra passes // some decoders need an extra pass
while(!finished) { // See the flag CODEC_CAP_DELAY for more info
avcodec_decode_video2(codec_context.get(), frame.get(), &finished, &empty_packet); if(need_extra_pass) {
av::codec_decode_video_remaining(codec_context, frame);
} }
return frame; return frame;

Loading…
Cancel
Save