Files
SubWave/src/engine/ffmpeg/CodecContext.cpp
T

68 lines
1.5 KiB
C++

#include "CodecContext.h"
#include <QDebug>
extern "C" {
#include <libavcodec/avcodec.h>
}
namespace engine::ffmpeg {
void CodecContext::Deleter::operator()(AVCodecContext *p) const {
avcodec_free_context(&p);
}
bool CodecContext::open(const AVCodecParameters *par) {
close();
const AVCodec *dec = avcodec_find_decoder(par->codec_id);
if (!dec) {
qWarning() << "[CodecContext] No decoder found for codec_id" << par->codec_id;
return false;
}
AVCodecContext *raw = avcodec_alloc_context3(dec);
if (!raw) {
qWarning() << "[CodecContext] Failed to allocate codec context";
return false;
}
avcodec_parameters_to_context(raw, par);
if (avcodec_open2(raw, dec, nullptr) < 0) {
avcodec_free_context(&raw);
qWarning() << "[CodecContext] Cannot open codec";
return false;
}
m_ctx.reset(raw);
return true;
}
void CodecContext::close() {
m_ctx.reset();
}
bool CodecContext::sendPacket(const AVPacket *pkt) const {
return m_ctx && avcodec_send_packet(m_ctx.get(), pkt) >= 0;
}
bool CodecContext::receiveFrame(AVFrame *frame) const {
if (!m_ctx) return false;
int ret = avcodec_receive_frame(m_ctx.get(), frame);
return ret == 0;
}
void CodecContext::flush() {
if (m_ctx) avcodec_flush_buffers(m_ctx.get());
}
int CodecContext::sampleRate() const {
return m_ctx ? m_ctx->sample_rate : 0;
}
int CodecContext::channels() const {
return m_ctx ? m_ctx->ch_layout.nb_channels : 0;
}
} // namespace engine::ffmpeg