成功支持Radeon Image Filter
This commit is contained in:
@@ -4,6 +4,9 @@ PROJECT(VideoEvolution)
|
|||||||
|
|
||||||
find_package(libyuv CONFIG REQUIRED)
|
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)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg/include)
|
||||||
|
|
||||||
SET(VIDEO_SOURCE VideoDecoder.cpp
|
SET(VIDEO_SOURCE VideoDecoder.cpp
|
||||||
@@ -24,8 +27,11 @@ SOURCE_GROUP("Audio" FILES ${AUDIO_SOURCE})
|
|||||||
SOURCE_GROUP("Video" FILES ${VIDEO_SOURCE})
|
SOURCE_GROUP("Video" FILES ${VIDEO_SOURCE})
|
||||||
SOURCE_GROUP("Image" FILES ${IMAGE_SOURCE})
|
SOURCE_GROUP("Image" FILES ${IMAGE_SOURCE})
|
||||||
|
|
||||||
|
add_compile_options("/MP")
|
||||||
|
|
||||||
add_executable(VideoEvolution main.cpp
|
add_executable(VideoEvolution main.cpp
|
||||||
DataType.h
|
DataType.h
|
||||||
|
RIFSupport.cpp
|
||||||
#${AUDIO_SOURCE}
|
#${AUDIO_SOURCE}
|
||||||
${VIDEO_SOURCE} ${IMAGE_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/swresample.lib
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg/lib/swscale.lib
|
${CMAKE_CURRENT_SOURCE_DIR}/ffmpeg/lib/swscale.lib
|
||||||
yuv
|
yuv
|
||||||
|
RadeonImageFilters
|
||||||
)
|
)
|
||||||
|
@@ -34,8 +34,6 @@ 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; //这样等于不缩放
|
||||||
|
126
RIFSupport.cpp
Normal file
126
RIFSupport.cpp
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
#include"RadeonImageFilters.h"
|
||||||
|
#include"DataType.h"
|
||||||
|
#include<string>
|
||||||
|
|
||||||
|
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;row<image_size.height;++row )
|
||||||
|
{
|
||||||
|
memcpy(tp,sp,image_size.width*4);
|
||||||
|
|
||||||
|
sp+=desc.image_row_pitch;
|
||||||
|
tp+=image_size.width*4;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = rifImageUnmap(output_image,data);
|
||||||
|
|
||||||
|
return final_output_bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RIFEnd(void *data)
|
||||||
|
{
|
||||||
|
rifCommandQueueDetachImageFilter(queue, filter);
|
||||||
|
rifObjectDelete(output_image);
|
||||||
|
rifObjectDelete(input_image);
|
||||||
|
}
|
@@ -129,7 +129,7 @@ public:
|
|||||||
video_stream=nullptr;
|
video_stream=nullptr;
|
||||||
video_stream_index=-1;
|
video_stream_index=-1;
|
||||||
|
|
||||||
for(int i=0;i<ctx->nb_streams;i++)
|
for(uint i=0;i<ctx->nb_streams;i++)
|
||||||
{
|
{
|
||||||
if(ctx->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_VIDEO)
|
if(ctx->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_VIDEO)
|
||||||
{
|
{
|
||||||
|
@@ -155,24 +155,13 @@ public:
|
|||||||
m_video_stream_index = 0;
|
m_video_stream_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Init(int pass) override
|
bool Init() 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;
|
||||||
|
|
||||||
|
@@ -39,7 +39,7 @@ public:
|
|||||||
frame_size=size;
|
frame_size=size;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Init(int pass)=0;
|
virtual bool Init()=0;
|
||||||
|
|
||||||
virtual bool WriteFrame(const uint8 *rgba_data)=0;
|
virtual bool WriteFrame(const uint8 *rgba_data)=0;
|
||||||
|
|
||||||
|
49
main.cpp
49
main.cpp
@@ -4,6 +4,11 @@
|
|||||||
#include"FrameRecviver.h"
|
#include"FrameRecviver.h"
|
||||||
#include<stdlib.h>
|
#include<stdlib.h>
|
||||||
|
|
||||||
|
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;
|
constexpr uint32_t ALIGN_PIXELS=8;
|
||||||
|
|
||||||
const uint32_t GetAlignValue(const uint32_t value)
|
const uint32_t GetAlignValue(const uint32_t value)
|
||||||
@@ -21,19 +26,18 @@ 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()
|
||||||
{
|
{
|
||||||
|
CloseRIF();
|
||||||
|
|
||||||
rgb_encoder->Finish();
|
rgb_encoder->Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,23 +61,26 @@ public:
|
|||||||
|
|
||||||
rgb_encoder->SetFrameRateSize(frame_rate,result);
|
rgb_encoder->SetFrameRateSize(frame_rate,result);
|
||||||
|
|
||||||
frame_init=rgb_encoder->Init(pass);
|
frame_init=rgb_encoder->Init();
|
||||||
|
|
||||||
|
InitRIF(result);
|
||||||
|
|
||||||
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);
|
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);
|
VideoEncoder *video_encoder=CreateVideoEncoder(rgb,bit_rate,false);
|
||||||
FrameRecviver *frame_recv=new EvoFrameRecviver(video_encoder,new_height);
|
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;
|
uint32_t frame_count=0;
|
||||||
|
|
||||||
{
|
{
|
||||||
frame_recv->SetPass(pass);
|
|
||||||
video_decoder->Start();
|
video_decoder->Start();
|
||||||
|
|
||||||
while(video_decoder->NextFrame())
|
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;
|
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 "<<pass<<std::endl;
|
std::cerr<<"first decoder/encoder failed, try use software decoder/encoder"<<std::endl;
|
||||||
|
|
||||||
frame_count=ConvertMovie(src,rgb,new_height,bit_rate,pass,true);
|
frame_count=ConvertMovie(src,rgb,new_height,bit_rate,false);
|
||||||
|
|
||||||
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)
|
if(frame_count>0)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user