#include "H264Palyer.h" #include "BoostLog.h" extern "C" { #include #include } H264Palyer::H264Palyer() { } H264Palyer::~H264Palyer() { if (m_packet != nullptr) { av_packet_free(&m_packet); } } void H264Palyer::open() { auto codec = avcodec_find_decoder(AV_CODEC_ID_H264); if (!codec) { LOG(error) << "cannot find h264 codec."; return; } m_codecContext = avcodec_alloc_context3(codec); if (m_codecContext == nullptr) { LOG(error) << "Could not allocate video codec context"; return; } if (avcodec_open2(m_codecContext, codec, nullptr) < 0) { LOG(error) << "Could not open codec"; return; } m_packet = av_packet_alloc(); if (m_packet == nullptr) { LOG(error) << "Could not allocate AVPacket"; } m_frame = av_frame_alloc(); if (m_frame == nullptr) { LOG(error) << "Could not allocate AVFrame"; } } std::optional H264Palyer::decode(const uint8_t *data, uint32_t size) { m_packet->data = const_cast(data); m_packet->size = size; int ret = avcodec_send_packet(m_codecContext, m_packet); if (ret < 0) { return std::nullopt; } ret = avcodec_receive_frame(m_codecContext, m_frame); if (ret < 0) { return std::nullopt; } SwsContext *swsCtx = sws_getContext(m_frame->width, m_frame->height, m_codecContext->pix_fmt, m_frame->width, m_frame->height, AV_PIX_FMT_RGB24, SWS_BILINEAR, nullptr, nullptr, nullptr); QImage image(m_frame->width, m_frame->height, QImage::Format_RGB888); uint8_t *imageData[1] = {image.bits()}; int linesize[1] = {3 * m_frame->width}; sws_scale(swsCtx, m_frame->data, m_frame->linesize, 0, m_frame->height, imageData, linesize); sws_freeContext(swsCtx); // LOG(info) << image.width() << "x" << image.height(); return image; }