bytedeco/javacv

Low GPU Utilization When Transcoding Videos Using javacv ffmpeg

Open

#2.189 geöffnet am 21. Feb. 2024

Auf GitHub ansehen
 (0 Kommentare) (0 Reaktionen) (0 zugewiesene Personen)Java (1.583 Forks)batch import
help wantedquestion

Repository-Metriken

Stars
 (6.985 Stars)
PR-Merge-Metriken
 (Keine gemergten PRs in 30 T)

Beschreibung

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: 1

this is use command line: 2

my gpu is Nvidia GTX2060SUPER

Contributor Guide