Wraps two av functions in c++
This commit is contained in:
parent
6ee3eb6cfb
commit
3984c7d52b
3 changed files with 39 additions and 11 deletions
|
@ -6,9 +6,15 @@ extern "C" {
|
|||
#include <libavcodec/avcodec.h>
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#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 {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,4 +45,9 @@ namespace av {
|
|||
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 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);
|
||||
}
|
||||
|
|
|
@ -55,23 +55,21 @@ av::frame open_image(std::string const & filename){
|
|||
|
||||
// things to read and decode it
|
||||
av::packet_buffer empty_packet;
|
||||
int finished = 0;
|
||||
bool need_extra_pass = true;
|
||||
while(auto packet = av::read_frame(format_context, empty_packet)) {
|
||||
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
|
||||
if(finished) break;
|
||||
if(av::codec_decode_video(codec_context, frame, packet)) {
|
||||
need_extra_pass = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// some decoders need extra passes
|
||||
while(!finished) {
|
||||
avcodec_decode_video2(codec_context.get(), frame.get(), &finished, &empty_packet);
|
||||
// some decoders need an extra pass
|
||||
// See the flag CODEC_CAP_DELAY for more info
|
||||
if(need_extra_pass) {
|
||||
av::codec_decode_video_remaining(codec_context, frame);
|
||||
}
|
||||
|
||||
return frame;
|
||||
|
|
Reference in a new issue