updated, can run.

This commit is contained in:
hyzboy 2025-03-29 20:01:02 +08:00
parent e79d779723
commit d3105e9957
4 changed files with 74 additions and 44 deletions

View File

@ -34,6 +34,8 @@ public:
const Size2u &GetSourceFrameSize()const{return src_format.size;}
const Size2u &GetTargetFrameSize()const{return dst_format.size;}
virtual void SetPass(int)=0;
virtual Size2u ComputeDstFrameSize(const Size2u &src_size)
{
return src_size; //这样等于不缩放

View File

@ -20,25 +20,22 @@ namespace
constexpr EncodecName_by_ID encodec_name_by_id[]=
{
//{AV_CODEC_ID_H264 ,"h264_nvenc"},
//{AV_CODEC_ID_H264 ,"nvenc"},
//{AV_CODEC_ID_H264 ,"nvenc_h264"},
//
{AV_CODEC_ID_H264 ,"h264_nvenc"},
{AV_CODEC_ID_H264 ,"nvenc"},
{AV_CODEC_ID_H264 ,"nvenc_h264"},
//{AV_CODEC_ID_HEVC ,"hevc_nvenc"},
//{AV_CODEC_ID_HEVC ,"nvenc_hevc"},
{AV_CODEC_ID_HEVC ,"hevc_nvenc"},
{AV_CODEC_ID_HEVC ,"nvenc_hevc"},
//{AV_CODEC_ID_H264 ,"h264_amf"},
//{AV_CODEC_ID_HEVC ,"hevc_amf"},
{AV_CODEC_ID_H264 ,"h264_amf"},
{AV_CODEC_ID_HEVC ,"hevc_amf"},
//{AV_CODEC_ID_MJPEG ,"mjpeg_qsv"},
//{AV_CODEC_ID_MPEG2VIDEO ,"mpeg2_qsv"},
//{AV_CODEC_ID_H264 ,"h264_qsv"},
//{AV_CODEC_ID_HEVC ,"hevc_qsv"},
//{AV_CODEC_ID_VP9 ,"vp9_qsv"},
{AV_CODEC_ID_HEVC ,"libx265"},
{AV_CODEC_ID_H264 ,"libx264"},
{AV_CODEC_ID_MJPEG ,"mjpeg_qsv"},
{AV_CODEC_ID_MPEG2VIDEO ,"mpeg2_qsv"},
{AV_CODEC_ID_H264 ,"h264_qsv"},
{AV_CODEC_ID_HEVC ,"hevc_qsv"},
{AV_CODEC_ID_VP9 ,"vp9_qsv"},
{AV_CODEC_ID_NONE ,""}
};
@ -75,7 +72,7 @@ namespace
class FFMPEGVideoEncoder:public VideoEncoder
{
const AVCodec *codec;
AVFrame *frame;
AVStream *video_stream=nullptr;
@ -114,6 +111,8 @@ public:
~FFMPEGVideoEncoder()
{
Finish();
if(frame)
av_frame_free(&frame);
@ -123,9 +122,9 @@ public:
avformat_free_context(fmt_ctx);
}
void Set(const AVRational &fr,const Size2u &s) override
void SetFrameRateSize(const AVRational &fr,const Size2u &s) override
{
VideoEncoder::Set(fr,s);
VideoEncoder::SetFrameRateSize(fr,s);
codec_ctx->bit_rate =bit_rate;
codec_ctx->width =s.width;
@ -150,15 +149,26 @@ public:
m_video_stream_index = 0;
}
bool Init() override
bool Init(int pass) override
{
avcodec_parameters_to_context(codec_ctx,video_stream->codecpar);
av_opt_set(codec_ctx->priv_data,"preset","veryslow",0);
av_opt_set(codec_ctx->priv_data,"crf","10",0);
if(pass==1)
{
av_opt_set(codec_ctx->priv_data, "pass", "1", 0);
av_opt_set(codec_ctx->priv_data, "stats_file", "ffmpeg2pass-0.log", 0);
}
else
{
av_opt_set(codec_ctx->priv_data, "pass", "2", 0);
av_opt_set(codec_ctx->priv_data, "stats_file", "ffmpeg2pass-0.log", 0);
}
if(fmt_ctx->oformat->flags&AVFMT_GLOBALHEADER)
codec_ctx->flags|=AV_CODEC_FLAG_GLOBAL_HEADER;
codec_ctx->flags|=AV_CODEC_FLAG_GLOBAL_HEADER;
if(avcodec_open2(codec_ctx,codec,nullptr)<0)
{

View File

@ -42,13 +42,13 @@ public:
virtual ~VideoEncoder()=default;
virtual void Set(const AVRational &fr,const Size2u &size)
virtual void SetFrameRateSize(const AVRational &fr,const Size2u &size)
{
frame_size=size;
frame_rate=fr;
}
virtual bool Init()=0;
virtual bool Init(int pass)=0;
virtual bool WriteFrame(const uint8 *rgba_data)=0;

View File

@ -21,12 +21,15 @@ class EvoFrameRecviver:public RGBAFrameRecviver
bool frame_init=false;
int pass;
public:
EvoFrameRecviver(VideoEncoder *rgb,const uint nh)
{
rgb_encoder=rgb;
new_height=nh;
pass=0;
}
~EvoFrameRecviver()
@ -52,35 +55,45 @@ public:
result.height =GetAlignValue(src_size.height);
}
rgb_encoder->Set(frame_rate,result);
rgb_encoder->SetFrameRateSize(frame_rate,result);
frame_init=rgb_encoder->Init();
frame_init=rgb_encoder->Init(pass);
return result;
}
void SetPass(int p) override
{
pass=p;
}
bool OnFrameRGBA(const uint8 *rgba_data) override
{
return rgb_encoder->WriteFrame(rgba_data);
}
};
uint32_t ConvertMovie(const char *src,const char *rgb,const uint32_t new_height,const uint32_t bit_rate,const bool use_hardware)
uint32_t ConvertMovie(const char *src,const char *rgb,const uint32_t new_height,const uint32_t bit_rate,const int pass,const bool use_hardware)
{
VideoEncoder *ve_rgb=CreateVideoEncoder(rgb,bit_rate,false);
FrameRecviver *fr=new EvoFrameRecviver(ve_rgb,new_height);
VideoDecoder *vd=CreateVideoDecoder(src,fr,use_hardware);
vd->Start();
VideoEncoder *video_encoder=CreateVideoEncoder(rgb,bit_rate,false);
FrameRecviver *frame_recv=new EvoFrameRecviver(video_encoder,new_height);
VideoDecoder *video_decoder=CreateVideoDecoder(src,frame_recv,use_hardware);
uint32_t frame_count=0;
while(vd->NextFrame())
++frame_count;
{
frame_recv->SetPass(pass);
video_decoder->Start();
delete vd;
delete fr;
delete ve_rgb;
while(video_decoder->NextFrame())
++frame_count;
video_encoder->Finish();
}
delete video_decoder;
delete frame_recv;
delete video_encoder;
return frame_count;
}
@ -92,18 +105,23 @@ bool Convert(const char *src,const char *rgb,const uint32_t bit_rate,const uint3
std::cout<<" bit_rate: "<<bit_rate<<std::endl;
std::cout<<" new height: "<<new_height<<std::endl;
// return true;
uint32_t frame_count;
uint32_t frame_count=ConvertMovie(src,rgb,new_height,bit_rate,true);
if(frame_count==0)
for(int pass=1;pass<=2;pass++)
{
std::cerr<<"first decoder/encoder failed, try use software decoder/encoder"<<std::endl;
std::cout<<"pass "<<pass<<std::endl;
frame_count=ConvertMovie(src,rgb,new_height,bit_rate,false);
}
frame_count=ConvertMovie(src,rgb,new_height,bit_rate,pass,true);
if(frame_count==0)
{
std::cerr<<"first decoder/encoder failed, try use software decoder/encoder"<<std::endl;
frame_count=ConvertMovie(src,rgb,new_height,bit_rate,pass,false);
}
std::cout<<std::endl;
std::cout<<std::endl;
}
if(frame_count>0)
{