统frame pixelformat/size为FrameFormat,并放弃LIBYUV缩放改用ffmpeg的swscale缩放
This commit is contained in:
parent
f4706aa941
commit
3e9ba60aea
@ -44,6 +44,13 @@ using vec2d=vec2<double>;
|
|||||||
template<typename T> struct Size2
|
template<typename T> struct Size2
|
||||||
{
|
{
|
||||||
T width,height;
|
T width,height;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Size2()
|
||||||
|
{
|
||||||
|
width=height=0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using Size2u=Size2<uint>;
|
using Size2u=Size2<uint>;
|
||||||
|
@ -4,16 +4,19 @@ extern "C"
|
|||||||
#include<libavutil/imgutils.h>
|
#include<libavutil/imgutils.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameConvert::FrameConvert(SwsContext *sc,enum AVPixelFormat dst,enum AVPixelFormat src,const Size2u &src_size)
|
FrameConvert::FrameConvert(SwsContext *sc,const FrameFormat &src,const FrameFormat &dst)
|
||||||
{
|
{
|
||||||
ctx=sc;
|
ctx=sc;
|
||||||
|
|
||||||
dst_fmt=dst;
|
src_frame_fmt=src;
|
||||||
src_fmt=src;
|
dst_frame_fmt=dst;
|
||||||
|
|
||||||
frame_size=src_size;
|
av_image_alloc(dst_data,
|
||||||
|
dst_linesize,
|
||||||
av_image_alloc(dst_data,dst_linesize,frame_size.width,frame_size.height,dst,1);
|
dst_frame_fmt.size.width,
|
||||||
|
dst_frame_fmt.size.height,
|
||||||
|
dst_frame_fmt.pixel_format,
|
||||||
|
1);
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameConvert::~FrameConvert()
|
FrameConvert::~FrameConvert()
|
||||||
@ -26,18 +29,18 @@ void FrameConvert::Convert(const FrameData &src_data,const FrameLinesize &src_li
|
|||||||
{
|
{
|
||||||
sws_scale( ctx,
|
sws_scale( ctx,
|
||||||
src_data,src_linesize,
|
src_data,src_linesize,
|
||||||
0,frame_size.height,
|
0,src_frame_fmt.size.height,
|
||||||
dst_data,dst_linesize);
|
dst_data,dst_linesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameConvert *InitFrameConvert(enum AVPixelFormat dst,enum AVPixelFormat src,const Size2u &src_size)
|
FrameConvert *InitFrameConvert(const FrameFormat &src,const FrameFormat &dst)
|
||||||
{
|
{
|
||||||
SwsContext *sc=sws_getContext( src_size.width,src_size.height,src,
|
SwsContext *sc=sws_getContext( src.size.width,src.size.height,src.pixel_format,
|
||||||
src_size.width,src_size.height,dst,
|
dst.size.width,dst.size.height,dst.pixel_format,
|
||||||
SWS_SPLINE,
|
SWS_SPLINE,
|
||||||
nullptr,nullptr,nullptr);
|
nullptr,nullptr,nullptr);
|
||||||
|
|
||||||
if(!sc)return(nullptr);
|
if(!sc)return(nullptr);
|
||||||
|
|
||||||
return(new FrameConvert(sc,dst,src,src_size));
|
return(new FrameConvert(sc,src,dst));
|
||||||
}
|
}
|
@ -11,10 +11,32 @@ extern "C"
|
|||||||
typedef uint8_t *FrameData[8];
|
typedef uint8_t *FrameData[8];
|
||||||
typedef int FrameLinesize[8];
|
typedef int FrameLinesize[8];
|
||||||
|
|
||||||
|
struct FrameFormat
|
||||||
|
{
|
||||||
|
AVPixelFormat pixel_format;
|
||||||
|
Size2u size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FrameFormat()
|
||||||
|
{
|
||||||
|
pixel_format=AV_PIX_FMT_NONE;
|
||||||
|
size.width=size.height=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameFormat(const AVPixelFormat &pf,const Size2u &s)
|
||||||
|
{
|
||||||
|
pixel_format=pf;
|
||||||
|
size=s;
|
||||||
|
}
|
||||||
|
};//FrameFormat
|
||||||
|
|
||||||
|
void SetFormat(FrameFormat *ff,const AVFrame *);
|
||||||
|
|
||||||
class FrameConvert
|
class FrameConvert
|
||||||
{
|
{
|
||||||
AVPixelFormat src_fmt,dst_fmt;
|
FrameFormat src_frame_fmt;
|
||||||
Size2u frame_size;
|
FrameFormat dst_frame_fmt;
|
||||||
|
|
||||||
SwsContext *ctx;
|
SwsContext *ctx;
|
||||||
|
|
||||||
@ -23,9 +45,9 @@ class FrameConvert
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
friend FrameConvert *InitFrameConvert(enum AVPixelFormat dst,enum AVPixelFormat src,const Size2u &);
|
friend FrameConvert *InitFrameConvert(const FrameFormat &src,const FrameFormat &dst);
|
||||||
|
|
||||||
FrameConvert(SwsContext *sc,enum AVPixelFormat dst,enum AVPixelFormat src,const Size2u &);
|
FrameConvert(SwsContext *sc,const FrameFormat &src,const FrameFormat &dst);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -40,4 +62,4 @@ public:
|
|||||||
const int GetLinesize(const int index)const{return dst_linesize[index];}
|
const int GetLinesize(const int index)const{return dst_linesize[index];}
|
||||||
};//class FrameConvert
|
};//class FrameConvert
|
||||||
|
|
||||||
FrameConvert *InitFrameConvert(enum AVPixelFormat dst,enum AVPixelFormat src,const Size2u &src_size);
|
FrameConvert *InitFrameConvert(const FrameFormat &src,const FrameFormat &dst);
|
||||||
|
@ -12,29 +12,38 @@ class FrameRecviver
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Size2u frame_size;
|
FrameFormat src_format;
|
||||||
|
FrameFormat dst_format;
|
||||||
|
|
||||||
AVRational frame_rate;
|
AVRational frame_rate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
FrameRecviver(const AVPixelFormat &dst_pf)
|
||||||
|
{
|
||||||
|
dst_format.pixel_format=dst_pf;
|
||||||
|
}
|
||||||
virtual ~FrameRecviver()=default;
|
virtual ~FrameRecviver()=default;
|
||||||
|
|
||||||
virtual void SetFrameRate(const AVRational &fr){frame_rate=fr;}
|
virtual void SetFrameRate(const AVRational &fr){frame_rate=fr;}
|
||||||
|
|
||||||
virtual bool OnFrame(const AVFrame *frame)=0;
|
virtual bool OnFrame(const AVFrame *frame)=0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const uint GetWidth()const{return frame_size.width;}
|
const Size2u &GetSourceFrameSize()const{return src_format.size;}
|
||||||
const uint GetHeight()const{return frame_size.height;}
|
const Size2u &GetTargetFrameSize()const{return dst_format.size;}
|
||||||
|
|
||||||
|
virtual Size2u ComputeDstFrameSize(const Size2u &src_size)
|
||||||
|
{
|
||||||
|
return src_size; //这样等于不缩放
|
||||||
|
}
|
||||||
};//
|
};//
|
||||||
|
|
||||||
class RGBAFrameRecviver:public FrameRecviver
|
class RGBAFrameRecviver:public FrameRecviver
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AVPixelFormat src_format=AV_PIX_FMT_NONE;
|
|
||||||
|
|
||||||
FrameConvert *convert=nullptr;
|
FrameConvert *convert=nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -43,6 +52,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
RGBAFrameRecviver():FrameRecviver(AV_PIX_FMT_RGBA){}
|
||||||
virtual ~RGBAFrameRecviver()
|
virtual ~RGBAFrameRecviver()
|
||||||
{
|
{
|
||||||
if(convert)
|
if(convert)
|
||||||
|
@ -6,30 +6,32 @@ extern "C"
|
|||||||
#include<libavutil/pixdesc.h>
|
#include<libavutil/pixdesc.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void out(const char *str,const FrameFormat &ff)
|
||||||
|
{
|
||||||
|
std::cout<<str<<"_size: "<<ff.size.width<<"x"<<ff.size.height<<std::endl
|
||||||
|
<<str<<"_format: "<<av_get_pix_fmt_name(ff.pixel_format)<<std::endl;
|
||||||
|
}
|
||||||
|
}//namespace
|
||||||
|
|
||||||
bool RGBAFrameRecviver::OnFrame(const AVFrame *frame)
|
bool RGBAFrameRecviver::OnFrame(const AVFrame *frame)
|
||||||
{
|
{
|
||||||
if(src_format==AV_PIX_FMT_NONE)
|
if(!convert)
|
||||||
{
|
{
|
||||||
frame_size.width=frame->width;
|
src_format.pixel_format =AVPixelFormat(frame->format);
|
||||||
frame_size.height=frame->height;
|
src_format.size.width =frame->width;
|
||||||
|
src_format.size.height =frame->height;
|
||||||
|
|
||||||
src_format=AVPixelFormat(frame->format);
|
dst_format.size=ComputeDstFrameSize(src_format.size);
|
||||||
|
|
||||||
std::cout<<"size: "<<frame_size.width<<"x"<<frame_size.height<<std::endl
|
out("src",src_format);
|
||||||
<<"format: "<<av_get_pix_fmt_name(src_format)<<std::endl;
|
out("dst",dst_format);
|
||||||
|
|
||||||
if(src_format!=AV_PIX_FMT_RGBA)
|
convert=InitFrameConvert(src_format,dst_format);
|
||||||
convert=InitFrameConvert(AV_PIX_FMT_RGBA,src_format,frame_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(src_format==AV_PIX_FMT_RGBA)
|
convert->Convert(frame->data,frame->linesize);
|
||||||
{
|
|
||||||
return OnFrameRGBA((uint8 *)(frame->data[0]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
convert->Convert(frame->data,frame->linesize);
|
|
||||||
|
|
||||||
return OnFrameRGBA(convert->GetData(0));
|
return OnFrameRGBA(convert->GetData(0));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include"VideoEncoder.h"
|
#include"VideoEncoder.h"
|
||||||
|
#include"libyuv/convert_from_argb.h"
|
||||||
#include<iostream>
|
#include<iostream>
|
||||||
#include"libyuv.h"
|
#include<queue>
|
||||||
#include <queue>
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -123,13 +123,13 @@ public:
|
|||||||
avformat_free_context(fmt_ctx);
|
avformat_free_context(fmt_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Set(const uint w,const uint h,const AVRational &fr) override
|
void Set(const AVRational &fr,const Size2u &s) override
|
||||||
{
|
{
|
||||||
VideoEncoder::Set(w,h,fr);
|
VideoEncoder::Set(fr,s);
|
||||||
|
|
||||||
codec_ctx->bit_rate =bit_rate;
|
codec_ctx->bit_rate =bit_rate;
|
||||||
codec_ctx->width =w;
|
codec_ctx->width =s.width;
|
||||||
codec_ctx->height =h;
|
codec_ctx->height =s.height;
|
||||||
codec_ctx->framerate =fr;
|
codec_ctx->framerate =fr;
|
||||||
codec_ctx->time_base.den=fr.num;
|
codec_ctx->time_base.den=fr.num;
|
||||||
codec_ctx->time_base.num=fr.den;
|
codec_ctx->time_base.num=fr.den;
|
||||||
@ -141,8 +141,8 @@ public:
|
|||||||
video_stream=avformat_new_stream(fmt_ctx,codec);
|
video_stream=avformat_new_stream(fmt_ctx,codec);
|
||||||
video_stream->codecpar->codec_id =fmt_ctx->video_codec_id;
|
video_stream->codecpar->codec_id =fmt_ctx->video_codec_id;
|
||||||
video_stream->codecpar->codec_type =AVMEDIA_TYPE_VIDEO;
|
video_stream->codecpar->codec_type =AVMEDIA_TYPE_VIDEO;
|
||||||
video_stream->codecpar->width =w;
|
video_stream->codecpar->width =s.width;
|
||||||
video_stream->codecpar->height =h;
|
video_stream->codecpar->height =s.height;
|
||||||
video_stream->codecpar->format =codec_ctx->pix_fmt;
|
video_stream->codecpar->format =codec_ctx->pix_fmt;
|
||||||
video_stream->codecpar->bit_rate =bit_rate;
|
video_stream->codecpar->bit_rate =bit_rate;
|
||||||
video_stream->time_base =codec_ctx->time_base;
|
video_stream->time_base =codec_ctx->time_base;
|
||||||
|
@ -22,8 +22,7 @@ protected:
|
|||||||
AVFormatContext* fmt_ctx;
|
AVFormatContext* fmt_ctx;
|
||||||
AVCodecContext* codec_ctx;
|
AVCodecContext* codec_ctx;
|
||||||
|
|
||||||
uint width;
|
Size2u frame_size;
|
||||||
uint height;
|
|
||||||
AVRational frame_rate;
|
AVRational frame_rate;
|
||||||
uint bit_rate;
|
uint bit_rate;
|
||||||
|
|
||||||
@ -35,26 +34,17 @@ public:
|
|||||||
{
|
{
|
||||||
strcpy_s(filename,_MAX_PATH,fn);
|
strcpy_s(filename,_MAX_PATH,fn);
|
||||||
|
|
||||||
width=height=0;
|
|
||||||
bit_rate=br;
|
bit_rate=br;
|
||||||
}
|
}
|
||||||
|
|
||||||
AVFormatContext* GetFrmCtx()
|
AVFormatContext *GetFrmCtx(){return fmt_ctx;}
|
||||||
{
|
AVCodecContext *GetCodecCtx(){return codec_ctx;}
|
||||||
return fmt_ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
AVCodecContext* GetCodecCtx() {
|
|
||||||
return codec_ctx
|
|
||||||
;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~VideoEncoder()=default;
|
virtual ~VideoEncoder()=default;
|
||||||
|
|
||||||
virtual void Set(const uint w,const uint h,const AVRational &fr)
|
virtual void Set(const AVRational &fr,const Size2u &size)
|
||||||
{
|
{
|
||||||
width=w;
|
frame_size=size;
|
||||||
height=h;
|
|
||||||
frame_rate=fr;
|
frame_rate=fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
88
main.cpp
88
main.cpp
@ -3,7 +3,6 @@
|
|||||||
#include"VideoDecoder.h"
|
#include"VideoDecoder.h"
|
||||||
#include"FrameRecviver.h"
|
#include"FrameRecviver.h"
|
||||||
#include<stdlib.h>
|
#include<stdlib.h>
|
||||||
#include"libyuv/scale_argb.h"
|
|
||||||
|
|
||||||
constexpr uint32_t ALIGN_PIXELS=8;
|
constexpr uint32_t ALIGN_PIXELS=8;
|
||||||
|
|
||||||
@ -16,15 +15,11 @@ const uint32_t GetAlignValue(const uint32_t value)
|
|||||||
|
|
||||||
class EvoFrameRecviver:public RGBAFrameRecviver
|
class EvoFrameRecviver:public RGBAFrameRecviver
|
||||||
{
|
{
|
||||||
uint8 *new_image=nullptr;
|
VideoEncoder *rgb_encoder=nullptr;
|
||||||
uint8 *rgb_image=nullptr;
|
|
||||||
|
|
||||||
bool new_size=false;
|
uint new_height=0;
|
||||||
|
|
||||||
uint new_width;
|
bool frame_init=false;
|
||||||
uint new_height;
|
|
||||||
|
|
||||||
VideoEncoder *rgb_encoder;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -37,63 +32,36 @@ public:
|
|||||||
~EvoFrameRecviver()
|
~EvoFrameRecviver()
|
||||||
{
|
{
|
||||||
rgb_encoder->Finish();
|
rgb_encoder->Finish();
|
||||||
|
}
|
||||||
|
|
||||||
delete[] rgb_image;
|
Size2u ComputeDstFrameSize(const Size2u &src_size) override
|
||||||
delete[] new_image;
|
{
|
||||||
|
Size2u result;
|
||||||
|
|
||||||
|
if(new_height>0)
|
||||||
|
{
|
||||||
|
result.height =GetAlignValue(new_height);
|
||||||
|
|
||||||
|
const double scale=double(new_height)/double(src_size.height);
|
||||||
|
|
||||||
|
result.width =GetAlignValue(double(src_size.width)*scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.width =GetAlignValue(src_size.width);
|
||||||
|
result.height =GetAlignValue(src_size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
rgb_encoder->Set(frame_rate,result);
|
||||||
|
|
||||||
|
frame_init=rgb_encoder->Init();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OnFrameRGBA(const uint8 *rgba_data) override
|
bool OnFrameRGBA(const uint8 *rgba_data) override
|
||||||
{
|
{
|
||||||
if(!rgb_image)
|
return rgb_encoder->WriteFrame(rgba_data);
|
||||||
{
|
|
||||||
if(new_height>0)
|
|
||||||
{
|
|
||||||
new_height =GetAlignValue(new_height);
|
|
||||||
|
|
||||||
const double scale=double(new_height)/double(GetHeight());
|
|
||||||
|
|
||||||
new_width =GetAlignValue(double(GetWidth())*scale);
|
|
||||||
|
|
||||||
new_size=true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new_width =GetAlignValue(GetWidth());
|
|
||||||
new_height =GetAlignValue(GetHeight());
|
|
||||||
|
|
||||||
if(new_width!=GetWidth()
|
|
||||||
||new_height!=GetHeight())
|
|
||||||
new_size=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout<<"Movie Origin size: "<<GetWidth()<<"x"<<GetHeight()<<std::endl;
|
|
||||||
|
|
||||||
if(new_size)
|
|
||||||
{
|
|
||||||
std::cout<<"Movie Scaled size: "<<new_width<<"x"<<new_height<<std::endl;
|
|
||||||
new_image=new uint8[new_width*new_height*4*2];
|
|
||||||
}
|
|
||||||
|
|
||||||
rgb_image=new uint8[new_width*new_height*4];
|
|
||||||
|
|
||||||
rgb_encoder->Set(new_width,new_height,frame_rate);
|
|
||||||
if(!rgb_encoder->Init())
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(new_size)
|
|
||||||
{
|
|
||||||
libyuv::ARGBScale( rgba_data, GetWidth()*4, GetWidth(), GetHeight(),
|
|
||||||
rgb_image, new_width*4, new_width, new_height,libyuv::FilterMode::kFilterBox);
|
|
||||||
|
|
||||||
return rgb_encoder->WriteFrame(rgb_image);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return rgb_encoder->WriteFrame(rgba_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//SaveToTGA(filename,(void *)two_image,GetWidth()*2,GetHeight(),24,true);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user