From 12a921e172b83a7efc96cea84c30e3aca3b3c546 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Wed, 2 Apr 2025 03:09:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=88=90=E5=8A=9F=E6=94=AF=E6=8C=81Radeon=20Im?= =?UTF-8?q?age=20Filter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 7 +++ FrameRecviver.h | 2 - RIFSupport.cpp | 126 +++++++++++++++++++++++++++++++++++++++++++++++ VideoDecoder.cpp | 2 +- VideoEncoder.cpp | 13 +---- VideoEncoder.h | 2 +- main.cpp | 49 +++++++++--------- 7 files changed, 161 insertions(+), 40 deletions(-) create mode 100644 RIFSupport.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index de8333a..3b44db8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,9 @@ PROJECT(VideoEvolution) find_package(libyuv CONFIG REQUIRED) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/RadeonImageFilter/include) +link_directories(${CMAKE_CURRENT_SOURCE_DIR}/RadeonImageFilter/Windows/Dynamic-MT) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg/include) SET(VIDEO_SOURCE VideoDecoder.cpp @@ -24,8 +27,11 @@ SOURCE_GROUP("Audio" FILES ${AUDIO_SOURCE}) SOURCE_GROUP("Video" FILES ${VIDEO_SOURCE}) SOURCE_GROUP("Image" FILES ${IMAGE_SOURCE}) +add_compile_options("/MP") + add_executable(VideoEvolution main.cpp DataType.h + RIFSupport.cpp #${AUDIO_SOURCE} ${VIDEO_SOURCE} ${IMAGE_SOURCE}) @@ -39,4 +45,5 @@ target_link_libraries(VideoEvolution PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg/lib/swresample.lib ${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg/lib/swscale.lib yuv + RadeonImageFilters ) diff --git a/FrameRecviver.h b/FrameRecviver.h index 0b765dc..349e1ac 100644 --- a/FrameRecviver.h +++ b/FrameRecviver.h @@ -34,8 +34,6 @@ 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/RIFSupport.cpp b/RIFSupport.cpp new file mode 100644 index 0000000..c11bfc5 --- /dev/null +++ b/RIFSupport.cpp @@ -0,0 +1,126 @@ +#include"RadeonImageFilters.h" +#include"DataType.h" +#include + +namespace +{ + rif_int status =RIF_SUCCESS; + rif_context context =nullptr; + rif_command_queue queue =nullptr; + rif_image_filter filter =nullptr; + + rif_image_desc image_desc{}; + + rif_image input_image =nullptr; + rif_image output_image=nullptr; + + Size2u image_size; + + uint8 *final_output_bitmap=nullptr; +} + +bool InitRIF(const Size2u &size) +{ + image_size=size; + + int deviceCount = 0; + status = rifGetDeviceCount(RIF_BACKEND_API_DIRECTX12, &deviceCount); + if ( status!=RIF_SUCCESS ) return(false); + + if (deviceCount > 0 || status) + { + status = rifCreateContext(RIF_API_VERSION, RIF_BACKEND_API_DIRECTX12, 0, nullptr, &context); + if (status != RIF_SUCCESS || !context) return(false); + } + + status = rifContextCreateCommandQueue(context, &queue); + if (status != RIF_SUCCESS || !queue) return(nullptr);; + + status = rifContextCreateImageFilter(context, RIF_IMAGE_FILTER_FILMIC_TONEMAP, &filter); + if (status != RIF_SUCCESS)return(nullptr); + + status = rifImageFilterSetParameter1f(filter, "exposure", 1.0f/8.0f); + if (status != RIF_SUCCESS)return(nullptr); + + status = rifImageFilterSetParameter1f(filter, "contrast", 1.0f); + if (status != RIF_SUCCESS)return(nullptr); + + status = rifImageFilterSetParameter1u(filter, "applyToneMap", RIF_TRUE); + if (status != RIF_SUCCESS)return(nullptr); + + //Create input and output images + image_desc.image_width = image_size.width; + image_desc.image_height = image_size.height; + image_desc.num_components = 4; // rgb image + image_desc.type = RIF_COMPONENT_TYPE_UINT8; + + final_output_bitmap=new uint8[image_size.width*image_size.height*4]; + + return true; +} + +void CloseRIF() +{ + delete[] final_output_bitmap; + + //Free resources + rifObjectDelete(queue); + + rifObjectDelete(filter); + + rifObjectDelete(context); +} + +const uint8 *RIFProcess(const uint8 *input,const Size2u &image_size) +{ + status = rifContextCreateImage(context, &image_desc, input, &input_image); + if (status != RIF_SUCCESS) + return(nullptr); + + status = rifContextCreateImage(context, &image_desc, nullptr, &output_image); + if (status != RIF_SUCCESS) + return(nullptr); + + status = rifCommandQueueAttachImageFilter(queue, filter, input_image, output_image); + if (status != RIF_SUCCESS) + return(nullptr); + + //execute queue + status = rifContextExecuteCommandQueue(context, queue, nullptr, nullptr, nullptr); + + rif_image_desc desc; + size_t retSize; + rif_int status = rifImageGetInfo(output_image, RIF_IMAGE_DESC, sizeof(desc), &desc, &retSize); + if (status != RIF_SUCCESS) + { + return(nullptr); + } + rif_uchar* data; + status = rifImageMap(output_image, RIF_IMAGE_MAP_READ, (void**)&data); + if(status==RIF_SUCCESS) + { + uint8 *sp=data; + uint8 *tp=final_output_bitmap; + + for ( uint row=0;rownb_streams;i++) + for(uint i=0;inb_streams;i++) { if(ctx->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) { diff --git a/VideoEncoder.cpp b/VideoEncoder.cpp index 5e477b7..32c6382 100644 --- a/VideoEncoder.cpp +++ b/VideoEncoder.cpp @@ -155,24 +155,13 @@ public: m_video_stream_index = 0; } - bool Init(int pass) override + bool Init() 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; diff --git a/VideoEncoder.h b/VideoEncoder.h index 2ecbd9c..6727c13 100644 --- a/VideoEncoder.h +++ b/VideoEncoder.h @@ -39,7 +39,7 @@ public: frame_size=size; } - virtual bool Init(int pass)=0; + virtual bool Init()=0; virtual bool WriteFrame(const uint8 *rgba_data)=0; diff --git a/main.cpp b/main.cpp index 63f39a3..6a9c506 100644 --- a/main.cpp +++ b/main.cpp @@ -4,6 +4,11 @@ #include"FrameRecviver.h" #include +bool InitRIF(const Size2u &); +void CloseRIF(); +const uint8 *RIFProcess(const uint8 *input,const Size2u &image_size); +void RIFEnd(void *); + constexpr uint32_t ALIGN_PIXELS=8; const uint32_t GetAlignValue(const uint32_t value) @@ -21,19 +26,18 @@ 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() { + CloseRIF(); + rgb_encoder->Finish(); } @@ -57,23 +61,26 @@ public: rgb_encoder->SetFrameRateSize(frame_rate,result); - frame_init=rgb_encoder->Init(pass); + frame_init=rgb_encoder->Init(); + + InitRIF(result); return result; } - void SetPass(int p) override - { - pass=p; - } - bool OnFrameRGBA(const uint8 *rgba_data) override { - return rgb_encoder->WriteFrame(rgba_data); + const uint8 *output=RIFProcess(rgba_data,GetTargetFrameSize()); + + bool result=rgb_encoder->WriteFrame(output); + + RIFEnd((void *)output); + + return result; } }; -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) +uint32_t ConvertMovie(const char *src,const char *rgb,const uint32_t new_height,const uint32_t bit_rate,const bool use_hardware) { VideoEncoder *video_encoder=CreateVideoEncoder(rgb,bit_rate,false); FrameRecviver *frame_recv=new EvoFrameRecviver(video_encoder,new_height); @@ -82,7 +89,6 @@ uint32_t ConvertMovie(const char *src,const char *rgb,const uint32_t new_height, uint32_t frame_count=0; { - frame_recv->SetPass(pass); video_decoder->Start(); while(video_decoder->NextFrame()) @@ -107,21 +113,16 @@ bool Convert(const char *src,const char *rgb,const uint32_t bit_rate,const uint3 uint32_t frame_count; - for(int pass=1;pass<=2;pass++) + frame_count=ConvertMovie(src,rgb,new_height,bit_rate,true); + + if(frame_count==0) { - std::cout<<"pass "<0) {