112 lines
2.3 KiB
C++
112 lines
2.3 KiB
C++
#include "Codec.h"
|
|
#include "ffcpp.h"
|
|
#include <stdexcept>
|
|
|
|
namespace ffcpp {
|
|
|
|
Codec::Codec(): _codecCtx(nullptr), _codec(nullptr) {
|
|
|
|
}
|
|
|
|
Codec::Codec(AVCodecContext *ctx, CodecType type): _codecCtx(ctx) {
|
|
if(type == CodecType::Encoder) {
|
|
_codec = avcodec_find_encoder(ctx->codec_id);
|
|
} else {
|
|
_codec = avcodec_find_decoder(ctx->codec_id);
|
|
}
|
|
|
|
if(!_codec) throw std::runtime_error("cannot find codec");
|
|
|
|
int res = avcodec_open2(_codecCtx, _codec, nullptr);
|
|
throwIfError(res, "cannot open codec");
|
|
}
|
|
|
|
Codec::Codec(AVCodecContext *ctx, AVCodec *codec) {
|
|
_codecCtx = ctx;
|
|
_codec = codec;
|
|
|
|
int res = avcodec_open2(_codecCtx, _codec, nullptr);
|
|
throwIfError(res, "cannot open codec");
|
|
}
|
|
|
|
Codec::~Codec() {
|
|
if(_codecCtx) {
|
|
avcodec_close(_codecCtx);
|
|
}
|
|
}
|
|
|
|
Codec::operator AVCodecContext*() const {
|
|
return _codecCtx;
|
|
}
|
|
|
|
int Codec::width() const {
|
|
return _codecCtx->width;
|
|
}
|
|
|
|
int Codec::height() const {
|
|
return _codecCtx->height;
|
|
}
|
|
|
|
AVRational Codec::timeBase() const {
|
|
return _codecCtx->time_base;
|
|
}
|
|
|
|
int Codec::capabilities() const {
|
|
return _codec->capabilities;
|
|
}
|
|
|
|
AVPixelFormat Codec::pixelFormat() const {
|
|
return _codecCtx->pix_fmt;
|
|
}
|
|
|
|
void Codec::setWidth(int width) {
|
|
_codecCtx->width = width;
|
|
}
|
|
|
|
void Codec::setHeight(int height) {
|
|
_codecCtx->height = height;
|
|
}
|
|
|
|
void Codec::setPixelFormat(AVPixelFormat pixelFormat) {
|
|
_codecCtx->pix_fmt = pixelFormat;
|
|
}
|
|
|
|
Codec::Codec(Codec&& c) {
|
|
*this = std::move(c);
|
|
}
|
|
|
|
Codec& Codec::operator=(Codec&& c) {
|
|
_codec = c._codec;
|
|
_codecCtx = c._codecCtx;
|
|
c._codec = nullptr;
|
|
c._codecCtx = nullptr;
|
|
return *this;
|
|
}
|
|
|
|
Frame Codec::decode(Packet &packet) {
|
|
Frame frame;
|
|
int gotPicture = 0;
|
|
auto decFunc = (_codecCtx->codec_type == AVMEDIA_TYPE_VIDEO ? avcodec_decode_video2 : avcodec_decode_audio4);
|
|
|
|
while(!gotPicture) {
|
|
int res = decFunc(_codecCtx, frame, &gotPicture, packet);
|
|
if(res < 0) throw std::runtime_error("cannot decode packet");
|
|
}
|
|
|
|
frame.guessPts();
|
|
return frame;
|
|
}
|
|
|
|
Packet Codec::encode(AVFrame* frame) {
|
|
Packet packet;
|
|
int gotPacket = 0;
|
|
auto encFunc = (_codecCtx->codec_type == AVMEDIA_TYPE_VIDEO ? avcodec_encode_video2 : avcodec_encode_audio2);
|
|
|
|
int res = encFunc(_codecCtx, packet, frame, &gotPacket);
|
|
if(res < 0) throw std::runtime_error("cannot encode frame");
|
|
|
|
return packet;
|
|
}
|
|
|
|
}
|