ffmpeg 在 GPU 上生成缩略图

Posted

技术标签:

【中文标题】ffmpeg 在 GPU 上生成缩略图【英文标题】:ffmpeg generate thumbnails on GPU 【发布时间】:2018-06-15 16:04:12 【问题描述】:

我尝试在 GPU 上生成带有加速的缩略图,所以编译 ffmpeg 3.4.1 并运行命令:

./ffmpeg  -i ~/Videos/1080.mp4 -vf "hwupload_cuda,thumbnail_cuda=100,scale_cuda=107:60,hwdownload,format=yuv420p" -vframes 1 -y ~/Videos/thumbs/thumb%03d.jpg

但我得到错误的输出图片(缩略图的颜色是绿色):

正确的图像必须是黑色的。 如何制作第一张颜色正确的图片?

日志:-loglevel 详细

ffmpeg version N-89707-g89b84cb Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 4.8 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
  configuration: --cpu=native --enable-pthreads --extra-version=hd --enable-gnutls --enable-vaapi --enable-vdpau --enable-nonfree --enable-gpl --enable-swscale --enable-libx264 --enable-version3 --enable-nvenc --enable-libnpp --enable-cuda --enable-cuvid --enable-cuda-sdk --enable-filter=scale_cuda --enable-filter=thumbnail_cuda --extra-cflags=-I/usr/local/cuda-8.0/include --extra-ldflags=-L/usr/local/cuda-8.0/lib64
  libavutil      56.  7.100 / 56.  7.100
  libavcodec     58.  9.100 / 58.  9.100
  libavformat    58.  3.100 / 58.  3.100
  libavdevice    58.  0.100 / 58.  0.100
  libavfilter     7. 11.100 /  7. 11.100
  libswscale      5.  0.101 /  5.  0.101
  libswresample   3.  0.101 /  3.  0.101
  libpostproc    55.  0.100 / 55.  0.100
[h264 @ 0x392ed40] Reinit context to 1920x1088, pix_fmt: yuv420p
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/alex/Videos/1080.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2012-05-30T20:01:34.000000Z
  Duration: 00:01:14.21, start: 0.000000, bitrate: 5476 kb/s
    Stream #0:0(und): Video: h264 (High), 1 reference frame (avc1 / 0x31637661), yuv420p(left), 1920x1080 (1920x1088), 5321 kb/s, 29.97 fps, 29.97 tbr, 60k tbn, 59.94 tbc (default)
    Metadata:
      creation_time   : 1970-01-01T00:00:00.000000Z
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 152 kb/s (default)
    Metadata:
      creation_time   : 2012-05-30T20:01:34.000000Z
      handler_name    : IsoMedia File Produced by Google, 5-11-2011
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> mjpeg (native))
Press [q] to stop, [?] for help
[h264 @ 0x3a38280] Reinit context to 1920x1088, pix_fmt: yuv420p
[Parsed_thumbnail_cuda_1 @ 0x4e3d8c0] batch size: 100 frames
[graph 0 input from stream 0:0 @ 0x4e8b640] w:1920 h:1080 pixfmt:yuv420p tb:1/60000 fr:30000/1001 sar:0/1 sws_param:flags=2
[auto_scaler_0 @ 0x4e8ca00] w:iw h:ih flags:'bicubic' interl:0
[format @ 0x4e8b540] auto-inserting filter 'auto_scaler_0' between the filter 'Parsed_format_4' and the filter 'format'
[Parsed_scale_cuda_2 @ 0x4e89380] w:1920 h:1080 -> w:107 h:60
[swscaler @ 0x4ebf0c0] deprecated pixel format used, make sure you did set range correctly
[auto_scaler_0 @ 0x4e8ca00] w:107 h:60 fmt:yuv420p sar:0/1 -> w:107 h:60 fmt:yuvj420p sar:0/1 flags:0x4
Output #0, image2, to '/home/alex/Videos/thumbs/thumb%03d.jpg':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    encoder         : Lavf58.3.100
    Stream #0:0(und): Video: mjpeg, 1 reference frame, yuvj420p(pc, left), 107x60, q=2-31, 200 kb/s, 29.97 fps, 29.97 tbn, 29.97 tbc (default)
    Metadata:
      creation_time   : 1970-01-01T00:00:00.000000Z
      handler_name    : VideoHandler
      encoder         : Lavc58.9.100 mjpeg
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
[Parsed_thumbnail_cuda_1 @ 0x4e3d8c0] frame id #76 (pts_time=2.535867) selected from a set of 100 images
No more output streams to write to, finishing.
frame=    1 fps=0.9 q=3.1 Lsize=N/A time=00:00:02.56 bitrate=N/A speed=2.26x    
video:2kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Input file #0 (/home/alex/Videos/1080.mp4):
  Input stream #0:0 (video): 115 packets read (134655 bytes); 101 frames decoded; 
  Input stream #0:1 (audio): 1 packets read (9 bytes); 
  Total: 116 packets (134664 bytes) demuxed
Output file #0 (/home/alex/Videos/thumbs/thumb%03d.jpg):
  Output stream #0:0 (video): 1 frames encoded; 1 packets muxed (1864 bytes); 
  Total: 1 packets (1864 bytes) muxed

更新,工作中! 在 hwupload 之前添加 format=nv12

-vf "format=nv12,hwupload_cuda,thumbnail_cuda,scale_cuda=1280:72‌​0,hwdownload,format=‌​nv12"

【问题讨论】:

共享完整日志。 日志中没有什么特别的,就像通常打印的标准输出一样。 还是分享吧。 已将日志添加到问题中。 在hwupload之前添加format=nv12 【参考方案1】:

这种情况的最佳方法是在 GPU 上解码。它将提高性能,因为 CPU 的负载会减少。您可以使用以下命令来完成:

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i video_source \
       -vf "thumbnail_cuda=2,scale_cuda=107:60,hwdownload,format=nv12" \
       -vframes 1 frame.jpg

在解码步骤中也可以更好地调整大小,如下所示:

ffmpeg -hwaccel cuvid -c:v h264_cuvid -resize 107x60 -i video_source \
       -vf "thumbnail_cuda=2,hwdownload,format=nv12" \
       -vframes 1 frame.jpg

这些命令展示了如何解码 h264 视频,如果您需要解码 mpeg2、hevc、vp8、vp9、vc1,那么您可以从下面的列表中选择合适的解码器:

ffmpeg -decoders | grep cuvid
 V..... h264_cuvid           Nvidia CUVID H264 decoder (codec h264)
 V..... hevc_cuvid           Nvidia CUVID HEVC decoder (codec hevc)
 V..... mjpeg_cuvid          Nvidia CUVID MJPEG decoder (codec mjpeg)
 V..... mpeg1_cuvid          Nvidia CUVID MPEG1VIDEO decoder (codec mpeg1video)
 V..... mpeg2_cuvid          Nvidia CUVID MPEG2VIDEO decoder (codec mpeg2video)
 V..... mpeg4_cuvid          Nvidia CUVID MPEG4 decoder (codec mpeg4)
 V..... vc1_cuvid            Nvidia CUVID VC1 decoder (codec vc1)
 V..... vp8_cuvid            Nvidia CUVID VP8 decoder (codec vp8)
 V..... vp9_cuvid            Nvidia CUVID VP9 decoder (codec vp9)

【讨论】:

使用 GPU 加速解码生成缩略图有什么意义? GPU 上的总 ffmpeg 执行时间约为 0.5 秒,CPU 为 0.01 秒。这完全没有意义,除非你想生成大量的 JPEG 还有大量的JPEG,它也可能没有意义。 JPEG 编码仍在 CPU 上,解码比编码快得多。添加繁重的 hwdownload 操作。 CPU 总是比 GPU“加速”的方法快。 伊万的回答很好。我想知道,你在哪里找到关于thumbnail_cuda 的信息?我想了解更多信息,但谷歌只返回你的答案(这里和 video.stackexchange),我在官方文档(ffmpeg 或 nvidia)上找不到任何东西。

以上是关于ffmpeg 在 GPU 上生成缩略图的主要内容,如果未能解决你的问题,请参考以下文章

ffmpeg 生成缩略图的替代方法是啥

使用ffmpeg从视频制作多个缩略图

使用 ffmpeg 或其他软件从视频中每个场景变化的中间生成缩略图

如何在 ffmpeg 中居中裁剪视频缩略图(方形缩略图)?

phpThumb PDF 缩略图

利用FFmpeg生成视频缩略图