Skip to main content

Topic: Multi-threaded Opus and AAC encoding, call for ABX (Read 2678 times) previous topic - next topic

0 Members and 1 Guest are viewing this topic.
  • enzo
  • [*][*]
  • Developer
Multi-threaded Opus and AAC encoding, call for ABX
Hi all,

Loosely based on the original idea of LAME MT to run multiple codec instances in parallel on chunks of consecutive frames, I built multi-threaded Opus, FAAC and Core Audio (iTunes) codec drivers for fre:ac to explorer the feasibility of this approach.

My reason for this is that for the usual approach of encoding multiple tracks in parallel, you need to have multiple tracks to encode in the first place. It does not help when encoding to a single output file and is inefficient when there are less tracks to convert than CPU threads available.

Today I published the results of my work in a blog article and made the first public preview release for everyone to try out. It would be great if everyone could have a look at it and try out the preview.

Speed-wise I get 440x realtime for Opus and 375x for Core Audio LC-AAC encoding @128kbps on an i7-5820K. That's roughly a 5x speed-up over single threaded encoding.

My implementation takes overlapping chunks of audio frames and feeds them to a number of codec instances. It then takes the encoded audio packets from the codecs and writes them to the output stream in the correct order, throwing away the overlapping frames. Some overlap is necessary to avoid distortions at chunk boundaries due to inter-frame processing in the codecs.

This works great for Opus and AAC as they have constant frame lengths and straight forward frame packing. I plan to roll-out this technology to LAME later, which will be more challenging because of MP3 frame packing, but should theoretically be possible. For Ogg Vorbis, though, I think this is not feasible because of variable frame lengths.

As this is a new approach, it needs testing. It would be great if some of you could take the time to try and ABX the output of the multi-threaded encoders vs. the regular ones. I already did my own tests of course and did not find any issues with the current implementation.

Please tell me what you think! I'm open to your opinions, suggestions and maybe even further ideas on this.

Thanks in advance for you help!

  • Kamedo2
  • [*][*][*][*]
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #1
I tried but I don't know how to use this.
Code: [Select]
freac-1.1-alpha-20170902-superfast-x64\freaccmd.exe -h superopus
Entity: line 33: parser error : AttValue: ' expected
????????????????????????????????????????????????????????????????????????????????
                                                                               ^
Entity: line 33: parser error : attributes construct error
????????????????????????????????????????????????????????????????????????????????
                                                                               ^
Entity: line 33: parser error : Couldn't find end of Start Tag option
????????????????????????????????????????????????????????????????????????????????
                                                                               ^
fre:ac - free audio converter v1.1 Alpha 20170902 (x86-64) command line interface
Copyright (C) 2001-2017 Robert Kausch

Options for Opus Audio Encoder v1.2.1 (SuperFast):

        no options for Opus Audio Encoder v1.2.1 (SuperFast)

Code: [Select]
freac-1.1-alpha-20170902-superfast-x64\freaccmd.exe --help
Entity: line 33: parser error : AttValue: ' expected
????????????????????????????????????????????????????????????????????????????????
                                                                               ^
Entity: line 33: parser error : attributes construct error
????????????????????????????????????????????????????????????????????????????????
                                                                               ^
Entity: line 33: parser error : Couldn't find end of Start Tag option
????????????????????????????????????????????????????????????????????????????????
                                                                               ^
fre:ac - free audio converter v1.1 Alpha 20170902 (x86-64) command line interface
Copyright (C) 2001-2017 Robert Kausch

Usage:  freaccmd [options] [file(s)]

  --encoder=<id>  | -e <id>     Specify the encoder to use (default is LAME)
  --help=<id>     | -h <id>     Print help for encoder specific options

                    -d <dir>    Specify output directory for encoded files
                    -o <file>   Specify output file name in single file mode
  --pattern=<pat> | -p <pat>    Specify output file name pattern

  --list-configs                Print a list of available configurations
  --config=<cfg>                Specify configuration to use

  --quiet                       Do not print any messages

Encoder <id> can be one of:

        avconv-alac, faac, superfaac, flac, lame, meh, mac, mpc, vorbis, ofr, opus,
        superopus, sndfile, speex, tak, wv, wma

Default for <pat> is "<artist> - <title>".


freac-1.1-alpha-20170902-superfast-x64\freaccmd.exe --list-configs
Entity: line 33: parser error : AttValue: ' expected
????????????????????????????????????????????????????????????????????????????????
                                                                               ^
Entity: line 33: parser error : attributes construct error
????????????????????????????????????????????????????????????????????????????????
                                                                               ^
Entity: line 33: parser error : Couldn't find end of Start Tag option
????????????????????????????????????????????????????????????????????????????????
                                                                               ^
fre:ac - free audio converter v1.1 Alpha 20170902 (x86-64) command line interface
Copyright (C) 2001-2017 Robert Kausch

Available configurations:

        Default configuration


I guess this freaccmd.exe is intended to be used like
Code: [Select]
freaccmd -e superopus -o out.opus in.wav
but is that so?  Is there a way to set the desired bitrate of freaccmd.exe? Commands like -b 123 won't change the bitrate.

  • enzo
  • [*][*]
  • Developer
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #2
I guess this freaccmd.exe is intended to be used like
Code: [Select]
freaccmd -e superopus -o out.opus in.wav
Thank you for trying it! Yes, that should work.
Is there a way to set the desired bitrate of freaccmd.exe? Commands like -b 123 won't change the bitrate.
Unfortunately, the freaccmd command does not support options for Opus yet. This will change with the 1.1 beta release as I plan to refactor the code to generate argument lists dynamically instead of using hard coded options.

For now, freaccmd uses the bitrate configured in the GUI, but it's better to just use the GUI for Opus encoding.

By the way: The errors printed at the top of your listings seem to come from boca_encoder_mpc.1.0.xml which contains a Unicode character in line 33. There is no problem on my computer, though, but I will investigate and try to fix it.

  • saratoga
  • [*][*][*][*][*]
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #3
Mostly off topic, but if you're interested in optimization of encoders, LAME could probably use a lot of attention.  Most of its ASM is 32 bit, and hasn't been updated in over a decade.  Porting some of the ffmpeg project's AVX code to lame (for example) could probably speed it up quite a lot even on single core builds.

  • enzo
  • [*][*]
  • Developer
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #4
There are TMKK's LAME SSE2/3/4.1 optimizations. These are already used in fre:ac 1.1 Alpha.

No AVX yet, though. And unfortunately, my assembly skills are not sufficient to update TMKK's code.

  • Kamedo2
  • [*][*][*][*]
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #5
If you are interested in the fast encode of MP3, you might want to check Helix mp3enc v5.1 Open Source encoder(2005). It's almost 4 times faster than LAME, and the quality is actually better than LAME on 192kbps.
https://hydrogenaud.io/index.php/topic,113324.0.html
https://hydrogenaud.io/index.php/topic,100896.0.html
https://hydrogenaud.io/index.php/topic,96800.0.html

  • Kamedo2
  • [*][*][*][*]
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #6
For now, freaccmd uses the bitrate configured in the GUI, but it's better to just use the GUI for Opus encoding.

I will try after the CUI interface is ready. I have testing environments with assumptions that encoders are available from the command lines.

  • enzo
  • [*][*]
  • Developer
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #7
I will try after the CUI interface is ready. I have testing environments with assumptions that encoders are available from the command lines.
OK, I'm working on it. It will probably be in the next update along with multi-threading support for Speex and FDK-AAC.

  • jmvalin
  • [*][*][*][*][*]
  • Developer
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #8
Do you know about the OPUS_SET_PREDICTION_DISABLED() encoder setting? That should do a much better job at making frames independent. In fact, you can look at similar code I wrote in libopusenc where I can make sample-perfect concatenation (chaining) of Opus files using that feature (which is why it's there).

  • Deathcrow
  • [*]
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #9
It's almost 4 times faster than LAME, and the quality is actually better than LAME on 192kbps.

Any evidence to back up this claim?

  • eahm
  • [*][*][*][*][*]
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #10
It's almost 4 times faster than LAME, and the quality is actually better than LAME on 192kbps.
Any evidence to back up this claim?
Maybe open the links?

  • enzo
  • [*][*]
  • Developer
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #11
Do you know about the OPUS_SET_PREDICTION_DISABLED() encoder setting?
Thanks for the hint! I just tried it, but found overlapping chunks to work much better for me.

We are doing quite different things and disabling the predictor at boundaries seems to help only in your case. You are concatenating streams and feed them to the same encoder instance in libopusenc. In my case, I'm splitting a stream into chunks, feed those to different encoder instances and concatenate the resulting Opus packets.

Disabling the predictor only at boundary frames does not seem to help at all in my case. Disabling it for the whole stream allows me to reduce the overlapping frames by 50% and still get a similar difference signal, but it will reduce overall quality of course.

  • jmvalin
  • [*][*][*][*][*]
  • Developer
Re: Multi-threaded Opus and AAC encoding, call for ABX
Reply #12
Thanks for the hint! I just tried it, but found overlapping chunks to work much better for me.

We are doing quite different things and disabling the predictor at boundaries seems to help only in your case. You are concatenating streams and feed them to the same encoder instance in libopusenc. In my case, I'm splitting a stream into chunks, feed those to different encoder instances and concatenate the resulting Opus packets.

Disabling the predictor only at boundary frames does not seem to help at all in my case. Disabling it for the whole stream allows me to reduce the overlapping frames by 50% and still get a similar difference signal, but it will reduce overall quality of course.

What we are doing is different, but it still has in common that prediction gets in the way. Think of disabling prediction in the same way as a video codec creates a keyframe. You don't want to keep prediction disabled all the time, just at the beginning of each segment. I assume that at each boundary, you have N frames that get encoded twice and that you discard the first N frames of the second encoder, right? With the prediction disabling call, it means you can reduce the overlap to just one frame, as long as the first real frame (that you don't discard) has prediction disabled.