Linux,Unix,BSD/Jetson

[jetson] GStreamer를 이용한 영상 파일 x265 인코딩

채윤아빠 2024. 4. 9. 08:52
728x90
반응형

개요

jetson 기기에서 "GStreamer"의 "nvv4l2h265enc"을 이용하여 H.264 코덱 영상을 H.265 코덱으로 인코딩하는 방법을 알아보도록 하겠습니다.

시험 환경

  • Jetson : AGX Orin 64
  • L4T : r36.2

H.265 코덱으로의 인코딩 기본

아래 참고자료를 참조하여 H.264 코덱으로 인코딩된 영상을 H.265 코덱으로 인코딩을 시도해 보았습니다.

아래 예제는 계속 정상적으로 동작을 하지 않고 멈춰 있어서 강제 종료하였습니다. H.264 코덱으로 인코딩된 영상을 디코딩하는 과정에서 제대로 파싱이 되지 않도록 파이프라인을 구성하여 멈추어 버렸습니다.

gst-launch-1.0 filesrc location=My-VideoClip-HU.mp4 ! \
  'video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, \
  format=(string)NV12, framerate=(fraction)30/1' ! nvv4l2h265enc \
  bitrate=4000000 preset-level=SlowPreset ! h265parse ! qtmux ! filesink \
  location=My-VideoClip-HU_x265.mp4 -e
Setting pipeline to PAUSED ...
Opening in BLOCKING MODE
Pipeline is PREROLLING ...
Redistribute latency...
NvMMLiteOpen : Block : BlockType = 8
===== NvVideo: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 8
Caught SIGSEGV
Spinning.  Please run 'gdb gst-launch-1.0 50215' to continue debugging, Ctrl-C to quit, or Ctrl-\ to dump core.
^Chandling interrupt.
Interrupt: Stopping pipeline ...
EOS on shutdown enabled -- Forcing EOS on the pipeline

^C


"videoparse"로 H.264 코덱의 영상을 디코딩하고자 하였으나 다음과 같이 오류가 발생합니다.

gst-launch-1.0 filesrc location=My-VideoClip-HU.mp4 ! \
 videoparse width=1280 height=720 framerate=30 ! \
 'video/x-raw, format=(string)NV24' ! nvvidconv ! \
 'video/x-raw(memory:NVMM), format=(string)NV24' ! \
 nvv4l2h265enc preset-level=SlowPreset profile=Main ! \
 h265parse ! filesink location=My-VideoClip-HU_x265.mp4 -e

Setting pipeline to PAUSED ...
Opening in BLOCKING MODE
Pipeline is PREROLLING ...
ERROR: from element /GstPipeline:pipeline0/GstVideoParse:videoparse0/GstRawVideoParse:inner_rawvideoparse: Internal data stream error.
Additional debug info:
../libs/gst/base/gstbaseparse.c(3681): gst_base_parse_loop (): /GstPipeline:pipeline0/GstVideoParse:videoparse0/GstRawVideoParse:inner_rawvideoparse:
streaming stopped, reason not-negotiated (-4)
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...


다음과 같이 "qtdemux", "h264parse" 및 "nvv4l2decoder"를 이용 하면, 주어진 H.264 코덱 영상 파일을 H.265 코덱으로 인코딩합니다.

preset-level=4로 하면 가장 압축률이 높습니다.

gst-launch-1.0 filesrc location=My-VideoClip-HU.mp4 ! \
 qtdemux name=demux ! h264parse ! nvv4l2decoder ! \
 nvv4l2h265enc bitrate=40000000 preset-level=4 profile=Main ! \
 h265parse ! filesink location=My-VideoClip-HU_x265.mp4 -e

AGX Orin에서 H.265 코덱으로 인코딩한 결과는 다음과 같습니다.


My-VideoClip-HU.mp4 : HD (1280 X 720) / 118min / 3,171,040,477 ==> 1.7GB ; 17min


profile=3인 경우에 인코딩된 파일이 가장 컸습니다. "profile" 옵션은 작을수록 압축률이 높아 인코딩된 파일의 크기가 작아집니다.


H.265 VBR로 인코딩

아래 예제는 H.265 VBR로 인코딩을 하는 예제입니다. VBR로 인코딩하기 위해서는 control-rate=variable_bitrate, bitrate, peak-bitrate 옵션을 지정해 주어야만 합니다.

"preset-level" 옵션의 경우에는 0 ~ 4까지 지정이 가능한데, 압축률에 크게 연관이 되어 있지는 않았습니다.

date ; time gst-launch-1.0 filesrc location=JUL-703-HU.mp4 ! \
 qtdemux name=demux ! h264parse ! nvv4l2decoder ! \
 nvv4l2h265enc bitrate=2000000 control-rate=variable_bitrate peak-bitrate=4000000 preset-level=4 profile=3 ! \
 h265parse ! filesink location=JUL-703-pl4.mp4 -e

 

preset-level enc file size encoding time
0 2,663,818,362 17m14.261s
3 2,663,818,362 17m11.828s

VBR bitrate 상관 관계

H.265 VBR로 인코딩 시, bitrate 옵션에 크게 영향을 받습니다.

date ; time gst-launch-1.0 filesrc location=My-VideoClip-HU.mp4 ! \
 qtdemux name=demux ! h264parse ! nvv4l2decoder ! \
 nvv4l2h265enc bitrate=1000000 control-rate=variable_bitrate peak-bitrate=4000000 preset-level=4 profile=0 ! \
 h265parse ! filesink location=My-VideoClip-HU_1000.mp4 -e
bitrate enc file size encoding time
1000000 920,079,789 17m11.168s
1000000 1,791,630,226 17m10.073s

 


맺음말

지금까지 Jetson AGX Orin 에서 GStreamer를 이용하여 영상을 H.265로 인코딩하는 방법을 알아 보았습니다. Jetson AGX Orin 인코딩 성능은 아주 좋았습니다. 위에서 예제로 사용한 영상이 HD화질 120분짜리 영상이었는데, 17분 만에 인코딩을 완료해 주었습니다.
단점은 음성 없이 영상만 인코딩 된다는 점입니다. ^^;
음성까지 인코딩하는 방법을 찾게되면 관련글을 정리하여 올리도록 하겠습니다.


참고자료