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 &GetSourceFrameSize()const{return src_format.size;}
const Size2u &GetTargetFrameSize()const{return dst_format.size;} const Size2u &GetTargetFrameSize()const{return dst_format.size;}
virtual void SetPass(int)=0;
virtual Size2u ComputeDstFrameSize(const Size2u &src_size) virtual Size2u ComputeDstFrameSize(const Size2u &src_size)
{ {
return src_size; //这样等于不缩放 return src_size; //这样等于不缩放

View File

@ -20,25 +20,22 @@ namespace
constexpr EncodecName_by_ID encodec_name_by_id[]= constexpr EncodecName_by_ID encodec_name_by_id[]=
{ {
//{AV_CODEC_ID_H264 ,"h264_nvenc"}, {AV_CODEC_ID_H264 ,"h264_nvenc"},
//{AV_CODEC_ID_H264 ,"nvenc"}, {AV_CODEC_ID_H264 ,"nvenc"},
//{AV_CODEC_ID_H264 ,"nvenc_h264"}, {AV_CODEC_ID_H264 ,"nvenc_h264"},
//
//{AV_CODEC_ID_HEVC ,"hevc_nvenc"},
//{AV_CODEC_ID_HEVC ,"nvenc_hevc"},
//{AV_CODEC_ID_H264 ,"h264_amf"}, {AV_CODEC_ID_HEVC ,"hevc_nvenc"},
//{AV_CODEC_ID_HEVC ,"hevc_amf"}, {AV_CODEC_ID_HEVC ,"nvenc_hevc"},
//{AV_CODEC_ID_MJPEG ,"mjpeg_qsv"}, {AV_CODEC_ID_H264 ,"h264_amf"},
//{AV_CODEC_ID_MPEG2VIDEO ,"mpeg2_qsv"}, {AV_CODEC_ID_HEVC ,"hevc_amf"},
//{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_MJPEG ,"mjpeg_qsv"},
{AV_CODEC_ID_H264 ,"libx264"}, {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 ,""} {AV_CODEC_ID_NONE ,""}
}; };
@ -114,6 +111,8 @@ public:
~FFMPEGVideoEncoder() ~FFMPEGVideoEncoder()
{ {
Finish();
if(frame) if(frame)
av_frame_free(&frame); av_frame_free(&frame);
@ -123,9 +122,9 @@ public:
avformat_free_context(fmt_ctx); 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->bit_rate =bit_rate;
codec_ctx->width =s.width; codec_ctx->width =s.width;
@ -150,13 +149,24 @@ public:
m_video_stream_index = 0; m_video_stream_index = 0;
} }
bool Init() override bool Init(int pass) override
{ {
avcodec_parameters_to_context(codec_ctx,video_stream->codecpar); 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,"preset","veryslow",0);
av_opt_set(codec_ctx->priv_data,"crf","10",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) if(fmt_ctx->oformat->flags&AVFMT_GLOBALHEADER)
codec_ctx->flags|=AV_CODEC_FLAG_GLOBAL_HEADER; codec_ctx->flags|=AV_CODEC_FLAG_GLOBAL_HEADER;

View File

@ -42,13 +42,13 @@ public:
virtual ~VideoEncoder()=default; 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_size=size;
frame_rate=fr; frame_rate=fr;
} }
virtual bool Init()=0; virtual bool Init(int pass)=0;
virtual bool WriteFrame(const uint8 *rgba_data)=0; virtual bool WriteFrame(const uint8 *rgba_data)=0;

View File

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