ffmpeg overlay_cuda 필터를 사용하여 SBS 비디오를 만드는 방법은 무엇입니까?

Aug 18 2020

FFMPEG는 몇 달 전에 새 필터 "overlay_cuda"를 사용하여 FFMPEG의 새 버전을 출시했습니다.이 필터는 "오버레이"와 동일하지만 Nvidia 카드를 사용하여 적용합니다.

FFMPEG 웹 사이트에서 필터에 대한 설명을 찾았지만 사용 방법에 대한 예는 없습니다. 내가 찾은 유일한 예는 개발자 커밋에서 가져온 것이지만 다른 비디오 위에 비디오 또는 사진을 넣는 것입니다.

두 배 너비의 nullsrc 이미지를 사용하여 일반 오버레이 필터를 사용하기 전에이 필터를 사용하는 방법을 모르겠습니다.

커밋 설명 : https://patchwork.ffmpeg.org/project/ffmpeg/patch/[email protected]/ ffmpeg 문서 웹 페이지 : https://ffmpeg.org/ffmpeg-filters.html#overlay_005fcuda-1

당신이 나를 도울 수 있기를 바랍니다.

최신 정보:

이 FFmpeg 주문을 다음과 같이 만들었습니다.

  1. 각 영상을 입력합니다.
  2. 첫 번째 동영상은 오른쪽에 패딩을 생성 한 다음 카드 메모리에 업로드됩니다.
  3. 오버레이 Cuda를 사용하면 다른 비디오가 원본 비디오의 오른쪽에 배치됩니다.
ffmpeg -y -loglevel info \
-i $video_1 \ -hwaccel cuda -hwaccel_output_format cuda -i $video_2 \
-filter_complex \
" \
[0:v]pad=w=2*iw:h=ih:x=0:y=0,hwupload_cuda[base];
[base][1:v]overlay_cuda=x=800:y=0" \
-an -c:v h264_nvenc overlay_test.mp4

하지만이 오류 메시지가 나타납니다.

[overlay_cuda @ 0x55fdec4b2ec0] Can't overlay nv12 on yuv420p 
[Parsed_overlay_cuda_2 @ 0x55fdec4b2d80] Failed to configure output pad on Parsed_overlay_cuda_2
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #1:0

픽셀 형식에 문제가 있습니다. 도와 주실 수 있기를 바랍니다.

업데이트 2 :

마침내 픽셀 형식 문제를 해결하고 이제 패딩으로 오버레이를 만듭니다 (오버레이 비디오에 공간 추가).

다음은 성공한 명령입니다.

ffmpeg -y -loglevel info \
-i $video_1 \ -hwaccel cuda -hwaccel_output_format cuda -i $video_2 \
-filter_complex \
" \
[0:v]pad=w=2*iw:h=ih:x=0:y=0,hwupload_cuda,scale_npp=format=nv12[base];
[base][1:v]overlay_cuda=x=800:y=0" \
-an -c:v h264_nvenc overlay_test.mp4

이제 x=800같은 변수 로 변경하고 싶지만 x=iw+1이 필터가 지원하지 않는 것 같습니다. 전역 변수를 설정하는 방법이 있습니까?

답변

Maxtrix Aug 24 2020 at 17:37

알았어! Cuda 필터로 할 수있는 작업을 다시 읽은 후 scale_npp에서 비디오 크기를 조정할뿐만 아니라 픽셀 형식도 변경할 수 있음을 발견했습니다 .

그래서 몇 가지 테스트 후 매우 좋은 해결책을 찾았습니다.

ffmpeg -y -loglevel info \
-hwaccel cuda -hwaccel_output_format cuda -i $video_1 \ -hwaccel cuda -hwaccel_output_format cuda -i $video_2 \
-filter_complex \
" \
[0:v]scale_npp=640:-2:format=yuv420p,hwdownload,pad=w=2*iw:h=ih:x=0:y=0,hwupload_cuda,scale_npp=format=nv12[base];
[1:v]scale_npp=640:-2:format=nv12[overlay_video];
[base][overlay_video]overlay_cuda=x=640:y=0" \
-an -c:v h264_nvenc overlay_test.mp4

이 FFMPEG 명령을 만드는 이유 :

  1. Cuda 디코딩으로 두 개의 비디오를 입력하십시오.
  2. 첫 번째 비디오 [0:v]:
    • YUV420P 픽셀 형식으로 Aspect 라디오를 유지하면서 640 픽셀 너비로 확장
    • GPU 메모리에서 시스템 메모리로 다운로드
    • 패딩 필터를 적용하여 비디오 오른쪽에 640 픽셀 너비 추가
    • GPU 메모리에 다시 업로드
    • 픽셀 형식을 nv12로 변경
    • 다음으로 레이블 지정 [base]
  3. 두 번째 비디오 [1:v]
    • NV12 픽셀 형식으로 Aspect 라디오를 유지하면서 너비를 640 픽셀로 확장
    • 다음으로 레이블 지정 [overlay_video]
  4. overlay_cuda필터 적용
    • [base] 배경 비디오로 비디오
    • [overlay_video] 비디오를 전경 비디오로
    • 동영상으로 [overlay_video]오른쪽에 640 픽셀 삽입[base]
  5. 인코딩 완료
    • -an as Audio null (이는 삭제할 수 있습니다. 실제 사용에서는 오디오 신호를 혼합하거나 두 비디오 중 하나를 선택하거나 외부 오디오 소스를 추가해야합니다.)
    • -c:v h264_nvenc h264 코덱으로 GPU를 사용하여 비디오를 인코딩합니다 (여기에서 필요에 따라 변경할 수 있음).

유일한 단점은 미리 해상도를 설정해야한다는 것입니다. 입력 해상도를 설정할 수있는 방법이 없습니다 (일반 오버레이 필터처럼). 다행히도 이것을 스크립트의 변수처럼 만들고 ffprobe이전에이 변수를 가져 오는 데 사용할 수 있습니다.