#include "basic/frame.h" extern "C" { #include } AVFrame* Frame::Alloc(AVSampleFormat sampleFmt, const AVChannelLayout* channel_layout, int sampleRate, int nbSamples) { AVFrame* frame = av_frame_alloc(); if (!frame) { __DebugPrint("av_frame_alloc failed"); return nullptr; } frame->format = sampleFmt; av_channel_layout_copy(&frame->ch_layout, channel_layout); frame->sample_rate = sampleRate; frame->nb_samples = nbSamples; /* allocate the buffers for the frame data */ if (av_frame_get_buffer(frame, 0) < 0) { __DebugPrint("av_frame_get_buffer failed"); av_frame_free(&frame); return nullptr; } return frame; } Frame::Frame(AVSampleFormat sampleFmt, const AVChannelLayout* channel_layout, int sampleRate, int nbSamples) { frame = Alloc(sampleFmt, channel_layout, sampleRate, nbSamples); if (!frame) { __DebugPrint("Frame::Alloc failed"); return; } } Frame::Frame(AVFrame* frame) { if (frame == nullptr) { this->frame = nullptr; return; } this->frame = Alloc(AVSampleFormat(frame->format), &frame->ch_layout, frame->sample_rate, frame->nb_samples); if (!this->frame) { __DebugPrint("Alloc failed in AUDIO copy ctor"); return; } if (av_frame_copy(this->frame, frame) < 0) { __DebugPrint("av_frame_copy failed in AUDIO copy ctor"); av_frame_free(&this->frame); this->frame = nullptr; return; } } Frame::Frame(AVPixelFormat pixFmt, int width, int height) { frame = Alloc(pixFmt, width, height); if (!frame) { __DebugPrint("Frame::Alloc failed"); return; } } AVFrame* Frame::Alloc(AVPixelFormat pixFmt, int width, int height) { AVFrame* frame = av_frame_alloc(); if (!frame) { __DebugPrint("av_frame_alloc failed"); return nullptr; } frame->format = pixFmt; frame->width = width; frame->height = height; /* allocate the buffers for the frame data */ if (av_frame_get_buffer(frame, 0) < 0) { __DebugPrint("av_frame_get_buffer failed"); av_frame_free(&frame); return nullptr; } return frame; } Frame::Frame(AVFrame* frame) { if (frame == nullptr) { this->frame = nullptr; return; } this->frame = Alloc(AVPixelFormat(frame->format), frame->width, frame->height); if (!this->frame) { __DebugPrint("Alloc failed in VIDEO copy ctor"); return; } if (av_frame_copy(this->frame, frame) < 0) { __DebugPrint("av_frame_copy failed in VIDEO copy ctor"); av_frame_free(&this->frame); this->frame = nullptr; return; } } bool FfmpegConverter::SetSize(int width, int height) { Free(_swsCtx, [this] { sws_freeContext(_swsCtx); }); Free(_frameTo, [this] { av_frame_free(&_frameTo); }); // 创建格式转换 _swsCtx = sws_getContext( width, height, _from, width, height, _to, 0, NULL, NULL, NULL); if (!_swsCtx) { __DebugPrint("sws_getContext failed"); return false; } _frameTo = Frame::Alloc(_to, width, height); if (!_frameTo) { __DebugPrint("Frame::Alloc failed"); return false; } return true; } AVFrame* FfmpegConverter::Trans(AVFrame* frameFrom) { // 如果是空指针,直接把缓存返回 if (frameFrom == nullptr) { return _frameTo; } int rc = sws_scale(_swsCtx, (const uint8_t* const*)frameFrom->data, frameFrom->linesize, 0, frameFrom->height, _frameTo->data, _frameTo->linesize); if (rc < 0) { __DebugPrint("sws_scale failed: rc=%d", rc); return nullptr; } return _frameTo; } FfmpegConverter::~FfmpegConverter() { Free(_swsCtx, [this] { sws_freeContext(_swsCtx); }); Free(_frameTo, [this] { av_frame_free(&_frameTo); }); }