read

Some days ago, a coworker benchmarked a pipeline job that converts audio files and then concatenates them with FFmpeg. The results showed that in our pipeline conversion and concatenation took a similar amount of time. Since converting audio is processing intensive and concatenating is not, I suspected that the concatenation process encoded the already encoded input files again. A timing test showed that FFmpeg indeed does this, if the codec is not set to “stream copy” by invoking FFmpeg with “-c copy”.

To reproduce the result, follow these steps:

Create a file containing two minutes of silence and measure how long
FFmpeg takes to encode the silence using GNU time:

$ time -f %E ffmpeg -loglevel quiet -t 120 -f u8 -i /dev/zero test.opus
0:05.33  

Create a playlist containing the filename of our file several times:

$ printf 'file test.opus\nfile test.opus\nfile test.opus\n' >test.txt
$ cat test.txt
file test.opus  
file test.opus  
file test.opus  

Concatenate the playlist using FFmpeg without “-c copy” and measure
how long it takes using GNU time:

$ time -f %E ffmpeg -loglevel quiet -f concat -i test.txt test2.opus
0:24.26  

Concatenate the playlist using FFmpeg with “-c copy” and measure how
long it takes using GNU time:

$ time -f %E ffmpeg -loglevel quiet -f concat -i test.txt -c copy test3.opus
0:00.64  

While a speedup of this magnitude (by a factor of more than 35) may seem
surprising, the explanation is simple: If invoked with “-c copy”, FFmpeg
skips decoding and encoding completely – copying multimedia data streams
instead of modifying them. Since one can not change stream contents that
way, this option is only useful for muxing and demuxing operations. This
includes concatenation, but also changing metadata or container formats.

Blog Logo

Nils Dagsson Moskopp


Published

Image

The Engine Room

thoughts, stories and ideas | from the grandcentrix team

Back to Overview