Files
gdmp/imagescaler.h
2025-09-25 16:56:53 +08:00

184 lines
6.7 KiB
C++

#ifndef IMAGESCALER_H
#define IMAGESCALER_H
#include "ijkmediaplayer.h"
#include "easylogging++.h"
//Scale算法
enum SwsAlogrithm
{
SWS_SA_FAST_BILINEAR = 0x1,
SWS_SA_BILINEAR = 0x2,
SWS_SA_BICUBIC = 0x4,
SWS_SA_X = 0x8,
SWS_SA_POINT = 0x10,
SWS_SA_AREA = 0x20,
SWS_SA_BICUBLIN = 0x40,
SWS_SA_GAUSS = 0x80,
SWS_SA_SINC = 0x100,
SWS_SA_LANCZOS = 0x200,
SWS_SA_SPLINE = 0x400,
};
typedef struct VideoFrame
{
uint8_t *data[8] = {NULL}; // 类似FFmpeg的buf, 如果是
int32_t linesize[8] = {0};
int32_t width;
int32_t height;
int format = AV_PIX_FMT_YUV420P;
}VideoFrame;
class ImageScaler
{
public:
ImageScaler(void) {
sws_ctx_ = NULL;
src_pix_fmt_ = AV_PIX_FMT_NONE;
dst_pix_fmt_ = AV_PIX_FMT_NONE;
en_alogrithm_ = SWS_SA_FAST_BILINEAR;
src_width_ = src_height_ = 0;
dst_width_ = dst_height_ = 0;
}
~ImageScaler(void) {
DeInit();
}
RET_CODE Init(uint32_t src_width, uint32_t src_height, int src_pix_fmt,
uint32_t dst_width, uint32_t dst_height, int dst_pix_fmt,
int en_alogrithm = SWS_SA_FAST_BILINEAR) {
src_width_ = src_width;
src_height_ = src_height;
src_pix_fmt_ = (AVPixelFormat)src_pix_fmt;
dst_width_ = dst_width;
dst_height_ = dst_height;
dst_pix_fmt_ = (AVPixelFormat)dst_pix_fmt;
en_alogrithm_ = en_alogrithm;
sws_ctx_ = sws_getContext(
src_width_,
src_height_,
(AVPixelFormat)src_pix_fmt_,
dst_width_,
dst_height_,
(AVPixelFormat)dst_pix_fmt_,
SWS_FAST_BILINEAR,
NULL,
NULL,
NULL);
if (!sws_ctx_) {
LOG(ERROR) << "Impossible to create scale context for the conversion fmt:"
<< av_get_pix_fmt_name((enum AVPixelFormat)src_pix_fmt_)
<< ", s:" << src_width_ << "x" << src_height_ << " -> fmt:" << av_get_pix_fmt_name(dst_pix_fmt_)
<< ", s:" << dst_width_ << "x" << dst_height_;
return RET_FAIL;
}
return RET_OK;
}
void DeInit( ) {
if(sws_ctx_) {
sws_freeContext(sws_ctx_);
sws_ctx_ = NULL;
}
}
RET_CODE Scale(const AVFrame *src_frame, AVFrame *dst_frame) {
if(src_frame->width != src_width_
|| src_frame->height != src_height_
|| src_frame->format != src_pix_fmt_
|| dst_frame->width != dst_width_
|| dst_frame->height != dst_height_
|| dst_frame->format != dst_pix_fmt_
|| !sws_ctx_) {
// 重新初始化
DeInit();
RET_CODE ret = Init(src_frame->width, src_frame->height, src_frame->format,
dst_frame->width, dst_frame->height, dst_frame->format,
en_alogrithm_);
if(ret != RET_OK) {
LOG(ERROR) << "Init failed: " << ret;
return ret;
}
}
int dst_slice_h = sws_scale(sws_ctx_, (const uint8_t **) src_frame->data, src_frame->linesize, 0, src_frame->height,
dst_frame->data, dst_frame->linesize);
if(dst_slice_h>0)
return RET_OK;
else
return RET_FAIL;
}
RET_CODE Scale2(const VideoFrame *src_frame, VideoFrame *dst_frame) {
if(src_frame->width != src_width_
|| src_frame->height != src_height_
|| src_frame->format != src_pix_fmt_
|| dst_frame->width != dst_width_
|| dst_frame->height != dst_height_
|| dst_frame->format != dst_pix_fmt_
|| !sws_ctx_) {
DeInit();
RET_CODE ret = Init(src_frame->width, src_frame->height, src_frame->format,
dst_frame->width, dst_frame->height, dst_frame->format,
en_alogrithm_);
if(ret != RET_OK) {
LOG(ERROR) << "Init failed: " << ret;
return ret;
}
}
int dst_slice_h = sws_scale(sws_ctx_,
(const uint8_t **)src_frame->data,
src_frame->linesize,
0, // 起始位置
src_frame->height, //处理多少行
dst_frame->data,
dst_frame->linesize);
if(dst_slice_h>0)
return RET_OK;
else
return RET_FAIL;
}
RET_CODE Scale3(const Frame *src_frame, VideoFrame *dst_frame) {
if(src_frame->width != src_width_
|| src_frame->height != src_height_
|| src_frame->format != src_pix_fmt_
|| dst_frame->width != dst_width_
|| dst_frame->height != dst_height_
|| dst_frame->format != dst_pix_fmt_
|| !sws_ctx_) {
DeInit();
RET_CODE ret = Init(src_frame->width, src_frame->height, src_frame->format,
dst_frame->width, dst_frame->height, dst_frame->format,
en_alogrithm_);
if(ret != RET_OK) {
LOG(ERROR) << "Init failed: " << ret;
return ret;
}
}
int dst_slice_h = sws_scale(sws_ctx_,
(const uint8_t **)src_frame->frame->data,
src_frame->frame->linesize,
0, // 起始位置
src_frame->height, //处理多少行
dst_frame->data,
dst_frame->linesize);
if(dst_slice_h>0)
return RET_OK;
else
return RET_FAIL;
}
private:
SwsContext* sws_ctx_; //SWS对象
AVPixelFormat src_pix_fmt_; //源像素格式
AVPixelFormat dst_pix_fmt_; //目标像素格式
int en_alogrithm_ = SWS_SA_FAST_BILINEAR; //Resize算法
int src_width_, src_height_; //源图像宽高
int dst_width_, dst_height_; //目标图像宽高
};
#endif // IMAGESCALER_H