From d3105e99574a35c37724581af2f0a4a64aee4d89 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Sat, 29 Mar 2025 20:01:02 +0800 Subject: [PATCH] updated, can run. --- FrameRecviver.h | 2 ++ VideoEncoder.cpp | 52 ++++++++++++++++++++++++----------------- VideoEncoder.h | 4 ++-- main.cpp | 60 +++++++++++++++++++++++++++++++----------------- 4 files changed, 74 insertions(+), 44 deletions(-) diff --git a/FrameRecviver.h b/FrameRecviver.h index 2b54c82..ea9efa5 100644 --- a/FrameRecviver.h +++ b/FrameRecviver.h @@ -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; //这样等于不缩放 diff --git a/VideoEncoder.cpp b/VideoEncoder.cpp index 5811b51..e26eb25 100644 --- a/VideoEncoder.cpp +++ b/VideoEncoder.cpp @@ -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) { diff --git a/VideoEncoder.h b/VideoEncoder.h index 3d1ceca..46aae6e 100644 --- a/VideoEncoder.h +++ b/VideoEncoder.h @@ -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; diff --git a/main.cpp b/main.cpp index c6a50aa..63f39a3 100644 --- a/main.cpp +++ b/main.cpp @@ -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: "<0) {