Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webm encoding slower through av than from command line #11

Open
thomasp85 opened this issue Dec 11, 2018 · 10 comments
Open

webm encoding slower through av than from command line #11

thomasp85 opened this issue Dec 11, 2018 · 10 comments

Comments

@thomasp85
Copy link

It appears encoding to webm is much slower when done through av, compared to calling ffmpeg directly from the command-line. This is only a difference for the webm format as mp4 has the same encoding time no matter how you call it...

pngfile <- tempfile(fileext = '.png')
webmfile <- tempfile(fileext = '.webm')
mp4file <- tempfile(fileext = '.mp4')
png(pngfile)
plot(1:10, 1:10)
dev.off()
#> quartz_off_screen 
#>                 2
system.time(av::av_encode_video(rep(pngfile, 100), output = webmfile))
#>    user  system elapsed 
#>  11.214   0.073  11.321
system.time(av::av_encode_video(rep(pngfile, 100), output = mp4file))
#>    user  system elapsed 
#>   0.957   0.066   0.467

Created on 2018-12-11 by the reprex package (v0.2.1)

@jeroen
Copy link
Member

jeroen commented Dec 11, 2018

Thanks. Some hypotheses:

  • The webm codec has a quality parameter that I'm setting to max
  • The command line uses hardware encoding or multithreading
  • My code is applying unnecessary filters somewhere.

@thomasp85
Copy link
Author

Hmm... constructing a minimal equivalent system call seems to make the difference much smaller than I experienced through gganimate... It is still there, but not as extreme

pngfile <- tempfile(fileext = '.png')
webmfile <- tempfile(fileext = '.webm')
mp4file <- tempfile(fileext = '.mp4')
png(pngfile)
plot(1:10, 1:10)
dev.off()
#> quartz_off_screen 
#>                 2
system.time(av::av_encode_video(rep(pngfile, 100), output = webmfile))
#>    user  system elapsed 
#>  11.516   0.078  11.706
system.time(av::av_encode_video(rep(pngfile, 100), output = mp4file))
#>    user  system elapsed 
#>   0.760   0.057   0.368

pngfiles <- sprintf(paste0(file.path(tempdir(), 'file'), '%04d.png'), seq_len(100))
file.copy(pngfile, pngfiles)
#>   [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [15] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [29] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [43] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [57] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [71] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [85] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [99] TRUE TRUE
glob <- file.path(dirname(pngfiles[1]), sub('^.*(\\..+$)', 'file%4d\\1', basename(pngfiles[1])))

system.time(system2(
  'ffmpeg', 
  c("-pattern_type sequence",
    paste0('-i ', glob),
    '-y',
    webmfile
)))
#>    user  system elapsed 
#>  14.822   0.127   8.186

Created on 2018-12-11 by the reprex package (v0.2.1)

@thomasp85 thomasp85 changed the title webm encoding much slower through av than from command line webm encoding slower through av than from command line Dec 11, 2018
@jeroen
Copy link
Member

jeroen commented Dec 11, 2018

Can you compare if the two different outputs have the same bitrate / quality parameters?

@thomasp85
Copy link
Author

what settings do I need to set on the command line to ensure the same quality as default av?

@jeroen
Copy link
Member

jeroen commented Dec 11, 2018

I would think they use the same defaults, but perhaps the command line is overriding this. You can try the ffprobe command line util on both video files to check the bitrate (or av::av_video_info)

@thomasp85
Copy link
Author

av's default bitrate is x20 of using the command line (32 kb/s vs 664 kb/s) so this might indeed be the reason

@jeroen
Copy link
Member

jeroen commented Dec 11, 2018

We probably need something like this but then for webm:

av/src/video.c

Lines 301 to 304 in f54806d

if (codec->id == AV_CODEC_ID_H264){
bail_if(av_opt_set(video_encoder->priv_data, "preset", "slow", 0), "Set x264 preset to slow");
//bail_if(av_opt_set(video_encoder->priv_data, "crf", "0", 0), "Set x264 quality to lossless");
}

@thomasp85
Copy link
Author

I think if it is just because av chooses a higher quality default setting, then it is not a problem... I was more worried that av was doing some unnecessary work of some sort that resulted in a slowdown

@jeroen
Copy link
Member

jeroen commented Dec 11, 2018

Well it's still nice to get it sorted out to use a sensible default.

@jeroen
Copy link
Member

jeroen commented Dec 11, 2018

If I add -b:v 0 to the command line as recommended here the speed is quite similar as in av. 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants