#include "CodecContext.h" #include extern "C" { #include } 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