จะใช้ฟิลเตอร์ ffmpeg overlay_cuda เพื่อสร้างวิดีโอ SBS ได้อย่างไร

Aug 18 2020

FFMPEG เมื่อไม่กี่เดือนที่ผ่านมาได้เปิดตัว FFMPEG เวอร์ชันใหม่พร้อมกับฟิลเตอร์ใหม่ "overlay_cuda" ตัวกรองนี้จะเหมือนกับ "โอเวอร์เลย์" แต่ใช้การ์ด 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]:
    • เพิ่มความกว้างเป็น 640 พิกเซลรักษาวิทยุด้านด้วยรูปแบบพิกเซล YUV420P
    • ดาวน์โหลดจากหน่วยความจำ GPU ไปยังหน่วยความจำระบบ
    • ใช้ตัวกรอง Padding เพื่อเพิ่มความกว้าง 640 พิกเซลทางด้านขวาของวิดีโอ
    • อัปโหลดอีกครั้งไปยังหน่วยความจำ GPU
    • เปลี่ยนรูปแบบพิกเซลเป็น nv12
    • ติดป้ายกำกับเป็น [base]
  3. วิดีโอที่สอง [1:v]
    • ขยายความกว้างเป็น 640 พิกเซลรักษาวิทยุด้านด้วยรูปแบบ NV12 พิกเซล
    • ติดป้ายกำกับเป็น [overlay_video]
  4. ใช้overlay_cudaตัวกรอง
    • [base] วิดีโอเป็นวิดีโอพื้นหลัง
    • [overlay_video] วิดีโอเป็นวิดีโอเบื้องหน้า
    • แทรก[overlay_video]640 พิกเซลทางด้านขวาเป็น[base]วิดีโอ
  5. เสร็จสิ้นการเข้ารหัส
    • -an เป็นเสียงว่าง (สิ่งนี้สามารถลบได้ในการใช้งานจริงคุณต้องผสมสัญญาณเสียงหรือเลือกหนึ่งรายการจากวิดีโอสองรายการหรือแม้แต่เพิ่มแหล่งเสียงภายนอก)
    • -c:v h264_nvenc เข้ารหัสวิดีโอโดยใช้ GPU ด้วยตัวแปลงสัญญาณ h264 (ที่นี่คุณสามารถเปลี่ยนได้ตามความต้องการของคุณ)

ข้อเสียเปรียบเพียงประการเดียวคือคุณต้องตั้งค่าความละเอียดไว้ล่วงหน้าไม่มีวิธีใดในการตั้งค่าความละเอียดอินพุต (เช่นเดียวกับในตัวกรองภาพซ้อนทับปกติ) โชคดีที่คุณสามารถทำให้เป็นเหมือนตัวแปรสำหรับสคริปต์และใช้ffprobeเพื่อรับตัวแปรนี้มาก่อน