javacv
javacv copied to clipboard
Low GPU Utilization When Transcoding Videos Using javacv ffmpeg
When I use the following code to transcode videos, I find that the GPU utilization is much lower compared to directly using cmd to call ffmpeg.
public boolean convert(String inputFileUrl, String outPutUrl, String hlsBaseUrl, String segmentFilename, int hlsTime, ConvertObserver convertObserver) {
MyFFmpegLogBack.setLevel(AV_LOG_INFO);
MyFFmpegLogBack.set();
try (FFmpegFrameGrabber grabber=new FFmpegFrameGrabber(inputFileUrl)){
grabber.start();
var videoBitrate = grabber.getVideoBitrate();
grabber.setVideoCodecName("h264_cuvid");
grabber.restart();
String m3u8SaveUrl=outPutUrl+"index.m3u8";
String segmentSaveFileUrl=(outPutUrl+hlsBaseUrl+segmentFilename).toString();
try(FFmpegFrameRecorder recorder=new FFmpegFrameRecorder(m3u8SaveUrl,grabber.getImageWidth(),grabber.getImageHeight(), grabber.getAudioChannels())){
recorder.setVideoCodecName("h264_nvenc");
Integer selectedFormat = null;
AVCodec enc = avcodec_find_encoder_by_name(recorder.getVideoCodecName());
if(enc!=null){
IntPointer formats = enc.pix_fmts();
int i = 0;
while (true) {
int format = formats.get(i++);
// always prefer yuv420p, if available
if(format == avutil.AV_PIX_FMT_YUV420P) {
selectedFormat = avutil.AV_PIX_FMT_YUV420P;
break;
}
if(format == avutil.AV_PIX_FMT_NONE) {
selectedFormat = avcodec.avcodec_find_best_pix_fmt_of_list(formats, avutil.AV_PIX_FMT_YUV420P, 0, null);
break;
}
}
}
if(selectedFormat==null){
selectedFormat = avutil.AV_PIX_FMT_YUV420P;
}
recorder.setPixelFormat(selectedFormat);
recorder.setVideoOption("threads", "10");
recorder.setFormat("hls");
recorder.setOption("hls_playlist_type","vod");
recorder.setOption("hls_list_size", "0");
recorder.setOption("hls_flags", "delete_segments");
recorder.setOption("hls_delete_threshold", "1");
recorder.setOption("hls_segment_type", "mpegts");
recorder.setOption("hls_time", String.valueOf(hlsTime));
recorder.setOption("hls_segment_filename",segmentSaveFileUrl);
recorder.setFrameRate(25);
recorder.setVideoBitrate(2000000);
recorder.setGopSize(hlsTime);
recorder.start();
Frame capturedFrame;
while (true) {
capturedFrame = grabber.grabFrame();
if (capturedFrame == null) {
log.info("success");
recorder.stop();
recorder.release();
grabber.stop();
grabber.release();
break;
}
recorder.record(capturedFrame);
}
return true;
}catch (Exception e){
}
}catch (Exception e){
}
return false;
}
i use nvidia-smi dmon to watch utilization
this use javacv GPU Utilization:
this is use command line:
my gpu is Nvidia GTX2060SUPER