Opened 12 years ago

Closed 11 years ago

Last modified 8 years ago

#1457 closed enhancement (fixed)

Add support for libshine-fxp fixed point math MP3 encoder

Reported by: patters Owned by:
Priority: wish Component: avcodec
Version: git-master Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

I'm not a developer so I lack the experience to hack this into the source myself, but it would be useful on ARM systems which lack an FPU to have fast MP3 encoder support, by adding optional external support for this library:
http://sourceforge.net/projects/libshine-fxp/

I found in my own testing that shineenc was 13x faster than LAME. Details here:
http://forum.serviio.org/viewtopic.php?f=7&t=6458&p=46596

The quality of the encode is supposedly worse than LAME, but encoding at 320Kbps makes up for this and is still comparatively very fast. This would allow basic ARM systems such as the Marvell mv6282 SoC to transcode audio to MP3 in realtime - something they cannot currently achieve.

Change History (30)

comment:1 by patters, 12 years ago

The only FFmpeg parameter that really needs passing to this library is -ab

shineenc v1.01 2007-01-02
USAGE   :  shineenc [options] <infile> <outfile>
options : -h            this help message
          -b <bitrate>  set the bitrate [32-320], default 128kbit
          -c            set copyright flag, default off
Last edited 12 years ago by patters (previous) (diff)

comment:2 by Carl Eugen Hoyos, 12 years ago

Component: undeterminedavcodec
Version: unspecifiedgit-master

Could you add some statistics comparing the speed of libshine, libmp3lame and FFmpeg's mp2 encoder here on the tracker? Additionally, please compare the quality of FFmpeg's mp2 encoder and libshine.

comment:3 by patters, 12 years ago

Sure, this was the test data I had linked to:

3m48s WAV file ripped from CD (Aphex Twin - Pulsewidth.wav):
libmp3lame 3.99-5 @128Kbps - encoded in 6m09s
libshine @128Kbps - encoded in 42s
libshine @320Kbps - encoded in 46s (Sounds perfectly fine on headphones to me, though perhaps my choice of test track isn't ideal for assessing quality. Guitar music might be better to show up any problems).

Both libmp3lame and libshine had audible artifacts at 128Kbps. I found it difficult to distinguish libshine@320Kbps from the source WAV.

Re: your comment, as far as I understood mp2 audio sampling rate is limited to 24000Hz so it wouldn't really be sufficient for typical music streaming requirements which tend to demand 44100Hz. EDIT - Do you mean this mp2? Thing is, my need for mp3 transcoding is for devices that may not play mp2 (DLNA media server).

I'll update the ticket again tomorrow with some more test results and quality comparisons. I'll attach some sample clips too, so it's not just my subjective opinion.

Last edited 12 years ago by patters (previous) (diff)

comment:4 by Carl Eugen Hoyos, 12 years ago

Please test the speed of FFmpeg's mp2 encoder (which supports up to 48kHz), you can remove "#define USE_FLOATS" in line 62 of libavcodec/mpegaudioenc.c to further improve (?) performance on ARM.
It is not necessary to provide samples, but if you comment on the quality of FFmpeg's mp2 encoder compared to libshine, this may help your goal (to get a faster mp3 encoder with acceptable quality).

comment:5 by toots, 12 years ago

Hi,

You can find and reworked version of the shine code there:

https://github.com/savonet/shine

The code has be cleaned-out to remove all global variables and simplify it's API. It should be super easy to integrate within ffmpeg.

You can also find performances comparisons there. As for audio quality, it is actually really good. Finally, the licensing should be LGPL-clean.

All in all, it'd be a great addition to ffmpeg for developers working without a FPU.

comment:6 by Carl Eugen Hoyos, 12 years ago

Could you compare shine's performance against FFmpeg's mp2 encoder (possibly without #define USE_FLOATS)?

comment:7 by Elon Musk, 12 years ago

Unfortunately your code have bug which cause that libshine can no be build dynamically into FFmpeg.
libshine use libm stuff but does not link to it:

ldd /usr/local/lib/libshine.so.1

/usr/local/lib/libshine.so.1:

libc.so.7 => /lib/libc.so.7 (0x280a5000)

Until this is not resolved writing working wrapper is not possible.

comment:8 by Elon Musk, 12 years ago

Also library have at least one mayor flaw, it requires caller to feed constant number of samples (1152) this makes it impossible to implement wrapper in FFmpeg.

comment:9 by Cigaes, 12 years ago

What makes you say that? A lot of encoders, both internal and external, have that kind of requirement. They just have to set the frame_size field of their context.

Your message about libm seems dubious too, for all systems I know it would be enough to add -lm to the compiler flags (and it is already there).

comment:10 by Elon Musk, 12 years ago

I just got it wrong.

in reply to:  6 comment:11 by patters, 12 years ago

Replying to cehoyos:

Could you compare shine's performance against FFmpeg's mp2 encoder (possibly without #define USE_FLOATS)?

Sorry for the delay, I've been very busy with other things. I compiled using that modification, and used some rock music to better determine quality (a track by Garbage - Queer):
lame -b 320 -f (fast mode) took 7m41s
shineenc -b 320 took 57s
ffmpeg -acodec mp2 -ab 320 took 12s

To my non-audiophile ears the shine encoded file was pretty indistinguishable from the LAME encoded one. The MP2 file did sound noticeably worse on the high frequency parts (cymbals), though the difference was fairly slight. I used decent headphones for the comparison.

So yes, FFmpeg's current MP2 encoder is very fast but it isn't suitable for the task that myself and others would like to use FFmpeg for - transcoding music to MP3 in realtime on ARM for streaming to mobile phones and other devices which don't support MP2.

Shine is 8x faster than LAME's fast mode at the same bitrate.

Last edited 12 years ago by patters (previous) (diff)

comment:12 by Elon Musk, 12 years ago

Hi, you can find patch that adds encoding support via liquidsoap version of shine here:

http://ffmpeg.org/pipermail/ffmpeg-devel/2012-July/128645.html

There is one issue (duno if its only me) but if shine and mp3lame are compiled together mp3lame will segv when encoding.

comment:13 by patters, 12 years ago

I'll try and give that a go. The configure script builder for that version of Shine needs a threaded version of Perl though which will need compiling from scratch on my platform (Synology NAS). I tried to compile Perl this morning and ran into issues. Will report back if I get it working.

comment:14 by patters, 12 years ago

double post

Last edited 12 years ago by patters (previous) (diff)

comment:15 by patters, 12 years ago

I can't seem to compile a threaded perl so I haven't been able to test:
http://www.linuxquestions.org/questions/linux-newbie-8/perl-compilation-failing-no-error-definitions-found-at-errno_pm-pl-922506/

I also tried cross compiling (which I have used successfully to build other things), but that fails miserably too.

Apparently someone solved this on the QNAP NAS platform by compiling a newer GCC but that would probably take weeks of solid effort - time I don't have right now unfortunately.

comment:16 by patters, 11 years ago

I was able to finally devote some time to this and I realised that I didn't need that multithreaded perl in the end. I ran the libshine bootstrap on a Ubuntu VM and then I realised that once created, the configure script could be transported and run on any destination CPU architecture. However, I ended up cross compiling - my method here:
http://pcloadletter.co.uk/2012/10/12/ffmpeg-shared-libs-for-synology/

FFmpeg with libshine seems to work nicely for music encoding. I did once spot a crash while transcoding a video file with an error relating to having run out of temporary buffer space, but I didn't make a note of the exact error. I also noticed the issue richardpl reported above - that libmp3lame will crash when support for both lame and shine libraries is compiled in. Is it normal that they would be mutually exclusive? I notice that when only libshine is compiled in and when no encoder is specified but output format mp3 is declared, libshine is automatically used, so maybe that's why.

I did notice that libshine seems to produce garbage audio when the input source is a surround stream (observed this with AC3 and DTS), but other than that it seems fine. I have included it in the ARM Synology NAS package for Serviio DLNA server.

Is libshine support likely to get officially included into FFmpeg?

Last edited 11 years ago by patters (previous) (diff)

in reply to:  16 comment:17 by Elon Musk, 11 years ago

Replying to patters:

I was able to finally devote some time to this and I realised that I didn't need that multithreaded perl in the end. I ran the libshine bootstrap on a Ubuntu VM and then I realised that once created, the configure script could be transported and run on any destination CPU architecture. However, I ended up cross compiling - my method here:
http://pcloadletter.co.uk/2012/10/12/ffmpeg-shared-libs-for-synology/

FFmpeg with libshine seems to work nicely for music encoding. I did once spot a crash while transcoding a video file with an error relating to having run out of temporary buffer space, but I didn't make a note of the exact error. I also noticed the issue richardpl reported above - that libmp3lame will crash when support for both lame and shine libraries is compiled in. Is it normal that they would be mutually exclusive? I notice that when only libshine is compiled in and when no encoder is specified but output format mp3 is declared, libshine is automatically used, so maybe that's why.

I did notice that libshine seems to produce garbage audio when the input source is a surround stream (observed this with AC3 and DTS), but other than that it seems fine. I have included it in the ARM Synology NAS package for Serviio DLNA server.

Is libshine support likely to get officially included into FFmpeg?

Unlikely until mayor issue (clash with libmp3lame) is resolved.

comment:18 by Elon Musk, 11 years ago

Bug with encoding surround stream is because libshine support encoding up to 2 channels - this is bug in wrapper, thanks for spotting it.

comment:19 by patters, 11 years ago

Can you post back here if you make a new version of the wrapper source?

Last edited 11 years ago by patters (previous) (diff)

comment:20 by patters, 11 years ago

I discovered that in fact this mod breaks other aspects of FFmpeg - in particular the AC3 encoder. I get garbage audio with other AC3 transcodes if I use this same libshine-enabled binary with Serviio. Won't this libshine support be officially integrated into the project? It would be very useful...

in reply to:  20 comment:21 by Elon Musk, 11 years ago

Replying to patters:

I discovered that in fact this mod breaks other aspects of FFmpeg - in particular the AC3 encoder. I get garbage audio with other AC3 transcodes if I use this same libshine-enabled binary with Serviio. Won't this libshine support be officially integrated into the project? It would be very useful...

Contact maintainer of libshine (libshine is on github) for resolving remaining issues.

Latest wrapper version can be found in shine branch of my ffmpeg fork on github too.

comment:22 by patters, 11 years ago

Actually I could be wrong about issues - have recompiled without libshine using the exact same method and it's still a problem, however an earlier static compile of the same source is fine. Can you post a link to your fork on Github? I don't understand how I would find it. Thanks.

Last edited 11 years ago by patters (previous) (diff)

comment:23 by Elon Musk, 11 years ago

https://github.com/richardpl/ffmpeg/tree/shine

It is already listed on FFmpeg download page.

comment:24 by patters, 11 years ago

Crumbs. Over 3 hours of painstaking testing before I realised that the cross toolchain Synology supply for their ARM NAS products is the problem. :(
Compiled natively on a bootstrapped ARM system and it's fine. Cheers for the link - built using your latest wrapper code.

comment:25 by csholmq, 11 years ago

The remaining issues against libmp3lame have been resolved. Confirmed to build with --enable-libmp3lame --enable-libshine.

https://github.com/savonet/shine/commit/6341ce5ff4e35187d48ab34a8fb3a33374e71e81

comment:26 by Elon Musk, 11 years ago

Not here, libmp3lame still crashes.

comment:27 by romain.beauxis, 11 years ago

Hi, liquidsoap's shine maintainer writting :-)

It'd be nice if you could provide me with some logs/trace of the crash, either here or (better) there:

https://github.com/savonet/shine/issues/new

Last edited 11 years ago by romain.beauxis (previous) (diff)

comment:28 by romain.beauxis, 11 years ago

Alright, I can reproduce on my OSX when statically compiling shine and lame. Will be fixing ASAP.

comment:29 by romain.beauxis, 11 years ago

Ok, I've prefixed every exported symbol and pushed a new API for shine. I can now compile with lame and shine statically linked and encode in mp3 using any of those two libs without issues..

I've also pushed a PR to richardpl/FFmpeg there:

https://github.com/richardpl/FFmpeg/pull/1

comment:30 by Elon Musk, 11 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.