68 lines
1.5 KiB
C++
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
|