Hi Michael,

first, let me thank you for your work.

Am Dienstag, den 20.05.2014, 19:17 +0200 schrieb Michael Niedermayer:
> Hi
> 
> On Tue, May 20, 2014 at 09:14:33AM +0100, Richard Ash wrote:
> > On Wed, 14 May 2014 19:27:38 +0200
> > Michael Niedermayer <[email protected]> wrote:
> > > On Sun, May 11, 2014 at 09:16:29PM +0200, Benjamin Drung wrote:
> > > > That's why I send this mail to this mailing list to request help. Is
> > > > there anyone who has the time and skill to help porting Audacity to
> > > > the latest FFmpeg API version?
> > > > 
> > > > [1] http://bugzilla.audacityteam.org/show_bug.cgi?id=606
> > 
> > I think I'm right in saying that no-one on the audacity-devel list was
> > specifically aware of this work/request (or I might have said something
> > earlier).

I had the spontaneous idea to ask for help on the libav-user mailing
list. I didn't communicated this idea to any audacity developer or
mailing list.

> > As a result of this problem, one of the Audacity contributors, Leyland
> > Lucius, has been perusing the use of Gstreamer as an abstraction layer
> > for ffmpeg. This work has recently arrived in Audacity SVN, so you
> > should be able to see where it is at (it isn't working for me, but I
> > don't think it's Leyland's fault).
> 
> I wasnt aware of that, but still is there no interrest in directly
> supporting FFmpeg ?

The lacking interest in continue supporting FFmpeg was caused by the
missing manpower to keep Audacity updated against the changing API of
FFmpeg.

I assume that no Audacity will be against having FFmpeg support in the
source code if this support is kept up-to-date. I like to commit your
work to the Audacity SVN so that we have both - support for FFmpeg and
Gstreamer.

> Also i just fixed planar export & put the disabled options back so
> my github should contain a audacity that fully works with latest
> ffmpeg, of course there will be bugs but iam happy to fix them if
> they get reported to me ...

I tested your patches with FFmpeg 2.2.1-2 on Ubuntu 14.04 with the
--disable-dynamic-loading configure flag. To succeed compiling, I had to
apply the attached 0001*.patch.

Then I modified the code and successfully compiled Audacity against the
libav version from Ubuntu 14.04. For that I had to create the second
0002*.patch (there you have to use --disable-dynamic-loading)

Importing and exporting ac3 and wma works with both libraries (including
setting the audio quality).

I found some issues:

1) There was a debugging line left in the code: fprintf(stderr, "READ %d
ret %d\n", size, ret);

2) I can't export audio as mp4. Neither as mp4 export, nor as custom
FFmpeg export (can't be selected there). FFmpeg has mp4 support enabled:

$ ffmpeg -formats 2>/dev/null | grep mp4
 D  mov,mp4,m4a,3gp,3g2,mj2 QuickTime / MOV
  E mp4             MP4 (MPEG-4 Part 14)


> >
> > The rationale for doing this is that the Gstreamer 1.0 API is much more
> > stable than the libAV one, and there is an (actively maintained)
> > gst-plugin-libav which provides the functionality of libAV through that
> > API. Thus the problem of providing up-to-date builds of libAV is
> > reduced, and an abstraction layer is provided.
> 
> Iam quite aware of the API stability issues in our API.
> Its a result of FFmpeg supporting all features and bugfixes as well
> as to be API compatible to the fork (libav) and that changing the API
> all the time.
> 
> One question here would be if there would be interrest if FFmpeg would
> provide a seperate simple API which isnt designed to be as efficient
> as possible and which makes no attempt to be compatible with libav.
> such API could then be long term stable
> ?
> This idea did come up already a few times IIRC. Just noone imlpemented
> it yet, but the more people support the idea the more likely someone
> will sit down and write it ...

IMO it would make sense to have a subset of the API (it doesn't have to
be a separate API) where you promise long term stability.

> > This also has the benefit of allowing (in principal) any other codecs
> > which are supported in Gstreamer (or by plugins for it) to be added to
> > Audacity relatively easily. This is something we hope to make modular,
> > so that it doesn't need a complete new build of audacity to use new
> > gstreamer plug-ins, and every download of Audacity doesn't have to ship
> > with every possible codec library.

Are there really codecs that are supported by Gstreamer, but not by
FFmpeg?

> hmm, i dont know exactly which codecs gstreamer supports but ffmpeg
> also supports quite a few external libs as codecs, the ones ive enabled
> on my local build:
> 
> decoders:
>  A....D libfdk_aac           Fraunhofer FDK AAC (codec aac)
>  A....D libopencore_amrnb    OpenCORE AMR-NB (Adaptive Multi-Rate 
> Narrow-Band) (codec amr_nb)
>  A....D libopencore_amrwb    OpenCORE AMR-WB (Adaptive Multi-Rate Wide-Band) 
> (codec amr_wb)
>  A....D libgsm               libgsm GSM (codec gsm)
>  A....D libgsm_ms            libgsm GSM Microsoft variant (codec gsm_ms)
>  A....D libilbc              iLBC (Internet Low Bitrate Codec) (codec ilbc)
>  A....D libopus              libopus Opus (codec opus)
>  A....D libspeex             libspeex Speex (codec speex)
>  A..... libvorbis            libvorbis (codec vorbis)
> 
> encoders:
>  A..... libfaac              libfaac AAC (Advanced Audio Coding) (codec aac)
>  A..... libfdk_aac           Fraunhofer FDK AAC (codec aac)
>  A..... libvo_aacenc         Android VisualOn AAC (Advanced Audio Coding) 
> (codec aac)
>  A..... libaacplus           libaacplus AAC+ (Advanced Audio Codec with 
> SBR+PS) (codec aac)
>  A..... libopencore_amrnb    OpenCORE AMR-NB (Adaptive Multi-Rate 
> Narrow-Band) (codec amr_nb)
>  A..... libvo_amrwbenc       Android VisualOn AMR-WB (Adaptive Multi-Rate 
> Wide-Band) (codec amr_wb)
>  A..... libgsm               libgsm GSM (codec gsm)
>  A..... libgsm_ms            libgsm GSM Microsoft variant (codec gsm_ms)
>  A..... libilbc              iLBC (Internet Low Bitrate Codec) (codec ilbc)
>  A..... libmp3lame           libmp3lame MP3 (MPEG audio layer 3) (codec mp3)
>  A..... libopus              libopus Opus (codec opus)
>  A..... libspeex             libspeex Speex (codec speex)
>  A..... libvorbis            libvorbis (codec vorbis)
> 
> changing these would generally require a rebuild of libavcodec though
> but not audacity.
> Also if someone wants to change ffmpegs external lib support to use
> dlopen for some or all cases, i surely wouldnt mind ...
> 
> Also according to:
> ./ffmpeg -filters | egrep '\->A|A\-' | wc
> there are 58 audio filters in ffmpegs libavfilter (not counting ones
> that arent enabled in my local build)
> So maybe libavfilter support might be interresting to audacity too ?
> 
> And the codecs in ffmpeg support quite a few more options than what
> is available to be set from audacity currently. It should be fairly
> easy to add generic option support for someone who knows the
> audacity API.
> random example:
> ./ffmpeg -help encoder=libopus
> ...
> Encoder libopus [libopus Opus]:
>     Threading capabilities: no
>     Supported sample rates: 48000 24000 16000 12000 8000
>     Supported sample formats: s16 flt
>     Supported channel layouts: mono stereo 3.0 quad 5.0 5.1 6.1 7.1
> libopus AVOptions:
>   -application       <int>        E...A... Intended application type (from 
> 2048 to 2051) (default 2049)
>      voip                         E...A... Favor improved speech 
> intelligibility
>      audio                        E...A... Favor faithfulness to the input
>      lowdelay                     E...A... Restrict to only the lowest delay 
> modes
>   -frame_duration    <float>      E...A... Duration of a frame in 
> milliseconds (from 2.5 to 60) (default 20)
>   -packet_loss       <int>        E...A... Expected packet loss percentage 
> (from 0 to 100) (default 0)
>   -vbr               <int>        E...A... Variable bit rate mode (from 0 to 
> 2) (default 1)
>      off                          E...A... Use constant bit rate
>      on                           E...A... Use variable bit rate
>      constrained                  E...A... Use constrained VBR
> 
> 
> Thanks
> 


-- 
Benjamin Drung
Debian & Ubuntu Developer
>From bb3a031280d843beabce754bb08df35885591f97 Mon Sep 17 00:00:00 2001
From: Benjamin Drung <[email protected]>
Date: Sun, 18 May 2014 16:15:12 +0200
Subject: [PATCH 1/2] Prefer newer av_get_bits_per_sample_fmt over
 av_get_bits_per_sample_format.

---
 src/FFmpeg.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/FFmpeg.cpp b/src/FFmpeg.cpp
index 7eef781..bfbda86 100644
--- a/src/FFmpeg.cpp
+++ b/src/FFmpeg.cpp
@@ -378,7 +378,7 @@ int import_ffmpeg_decode_frame(streamContext *sc, bool flushing)
    }
 
    sc->m_samplefmt = sc->m_codecCtx->sample_fmt;
-   sc->m_samplesize = av_get_bits_per_sample_format(sc->m_samplefmt) / 8;
+   sc->m_samplesize = av_get_bits_per_sample_fmt(sc->m_samplefmt) / 8;
 
    int channels = sc->m_codecCtx->channels;
    unsigned int newsize = sc->m_samplesize * frame->nb_samples * channels;
@@ -907,7 +907,7 @@ bool FFmpegLibs::InitLibs(wxString libpath_format, bool WXUNUSED(showerr))
    FFMPEG_INITDYN(avcodec, av_codec_next);
    FFMPEG_INITDYN(avcodec, av_codec_is_encoder);
 
-   FFMPEG_INITALT(avcodec, av_get_bits_per_sample_format, av_get_bits_per_sample_fmt);
+   FFMPEG_INITALT(avcodec, av_get_bits_per_sample_fmt, av_get_bits_per_sample_format);
 
    FFMPEG_INITDYN(avutil, av_free);
    FFMPEG_INITDYN(avutil, av_log_set_callback);
-- 
1.9.1

>From 35b8c9ce2399322ccba37f5482c605d46da9d148 Mon Sep 17 00:00:00 2001
From: Benjamin Drung <[email protected]>
Date: Sun, 18 May 2014 23:36:21 +0200
Subject: [PATCH 2/2] Add support for libav 9.

---
 src/FFmpeg.cpp                     |  8 ++++++--
 src/export/ExportFFmpeg.cpp        |  4 ++++
 src/export/ExportFFmpegDialogs.cpp | 10 ++++++++++
 src/import/ImportFFmpeg.cpp        |  4 ++++
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/FFmpeg.cpp b/src/FFmpeg.cpp
index bfbda86..83ac08b 100644
--- a/src/FFmpeg.cpp
+++ b/src/FFmpeg.cpp
@@ -378,7 +378,11 @@ int import_ffmpeg_decode_frame(streamContext *sc, bool flushing)
    }
 
    sc->m_samplefmt = sc->m_codecCtx->sample_fmt;
+#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || (LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 4, 0))
    sc->m_samplesize = av_get_bits_per_sample_fmt(sc->m_samplefmt) / 8;
+#else
+   sc->m_samplesize = av_get_bytes_per_sample(sc->m_samplefmt);
+#endif
 
    int channels = sc->m_codecCtx->channels;
    unsigned int newsize = sc->m_samplesize * frame->nb_samples * channels;
@@ -926,8 +930,8 @@ bool FFmpegLibs::InitLibs(wxString libpath_format, bool WXUNUSED(showerr))
    FFMPEG_INITDYN(avutil, av_freep);
    FFMPEG_INITDYN(avutil, av_rescale_q);
    FFMPEG_INITDYN(avutil, avutil_version);
-   FFMPEG_INITDYN(avutil, av_frame_alloc);
-   FFMPEG_INITDYN(avutil, av_frame_free);
+   FFMPEG_INITALT(avutil, av_frame_alloc, avcodec_alloc_frame);
+   FFMPEG_INITALT(avutil, av_frame_free, avcodec_free_frame);
    FFMPEG_INITDYN(avutil, av_samples_get_buffer_size);
 
    wxLogMessage(wxT("All symbols loaded successfully. Initializing the library."));
diff --git a/src/export/ExportFFmpeg.cpp b/src/export/ExportFFmpeg.cpp
index 454d897..2acddbd 100644
--- a/src/export/ExportFFmpeg.cpp
+++ b/src/export/ExportFFmpeg.cpp
@@ -286,7 +286,11 @@ bool ExportFFmpeg::Init(const char *shortname, AudacityProject *project, Tags *m
    memcpy(mEncFormatCtx->filename, OSINPUT(mName), strlen(OSINPUT(mName))+1);
    
    // At the moment Audacity can export only one audio stream
+#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 10, 0))
    if ((mEncAudioStream = av_new_stream(mEncFormatCtx, 1)) == NULL)
+#else
+   if ((mEncAudioStream = avformat_new_stream(mEncFormatCtx, NULL)) == NULL)
+#endif
    {
       wxLogError(wxT("FFmpeg : ERROR - Can't add audio stream to output file \"%s\"."), mName.c_str());
       return false;
diff --git a/src/export/ExportFFmpegDialogs.cpp b/src/export/ExportFFmpegDialogs.cpp
index df0f5b7..0c8024d 100644
--- a/src/export/ExportFFmpegDialogs.cpp
+++ b/src/export/ExportFFmpegDialogs.cpp
@@ -839,8 +839,10 @@ CompatibilityEntry ExportFFmpegOptions::CompatibilityList[] =
    { wxT("asf"), CODEC_ID_IMC },
    { wxT("asf"), CODEC_ID_AC3 },
    { wxT("asf"), CODEC_ID_DTS },
+#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || (LIBAVCODEC_VERSION_MAJOR == 53)
    { wxT("asf"), CODEC_ID_SONIC },
    { wxT("asf"), CODEC_ID_SONIC_LS },
+#endif
    { wxT("asf"), CODEC_ID_FLAC },
    { wxT("asf"), CODEC_ID_ADPCM_SWF },
    { wxT("asf"), CODEC_ID_VORBIS },
@@ -875,8 +877,10 @@ CompatibilityEntry ExportFFmpegOptions::CompatibilityList[] =
    { wxT("avi"), CODEC_ID_IMC },
    { wxT("avi"), CODEC_ID_AC3 },
    { wxT("avi"), CODEC_ID_DTS },
+#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || (LIBAVCODEC_VERSION_MAJOR == 53)
    { wxT("avi"), CODEC_ID_SONIC },
    { wxT("avi"), CODEC_ID_SONIC_LS },
+#endif
    { wxT("avi"), CODEC_ID_FLAC },
    { wxT("avi"), CODEC_ID_ADPCM_SWF },
    { wxT("avi"), CODEC_ID_VORBIS },
@@ -924,8 +928,10 @@ CompatibilityEntry ExportFFmpegOptions::CompatibilityList[] =
    { wxT("matroska"), CODEC_ID_IMC },
    { wxT("matroska"), CODEC_ID_AC3 },
    { wxT("matroska"), CODEC_ID_DTS },
+#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || (LIBAVCODEC_VERSION_MAJOR == 53)
    { wxT("matroska"), CODEC_ID_SONIC },
    { wxT("matroska"), CODEC_ID_SONIC_LS },
+#endif
    { wxT("matroska"), CODEC_ID_FLAC },
    { wxT("matroska"), CODEC_ID_ADPCM_SWF },
    { wxT("matroska"), CODEC_ID_VORBIS },
@@ -1032,8 +1038,10 @@ CompatibilityEntry ExportFFmpegOptions::CompatibilityList[] =
    { wxT("nut"), CODEC_ID_IMC },
    { wxT("nut"), CODEC_ID_AC3 },
    { wxT("nut"), CODEC_ID_DTS },
+#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || (LIBAVCODEC_VERSION_MAJOR == 53)
    { wxT("nut"), CODEC_ID_SONIC },
    { wxT("nut"), CODEC_ID_SONIC_LS },
+#endif
    { wxT("nut"), CODEC_ID_FLAC },
    { wxT("nut"), CODEC_ID_ADPCM_SWF },
    { wxT("nut"), CODEC_ID_VORBIS },
@@ -1082,8 +1090,10 @@ CompatibilityEntry ExportFFmpegOptions::CompatibilityList[] =
    { wxT("wav"), CODEC_ID_IMC },
    { wxT("wav"), CODEC_ID_AC3 },
    { wxT("wav"), CODEC_ID_DTS },
+#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || (LIBAVCODEC_VERSION_MAJOR == 53)
    { wxT("wav"), CODEC_ID_SONIC },
    { wxT("wav"), CODEC_ID_SONIC_LS },
+#endif
    { wxT("wav"), CODEC_ID_FLAC },
    { wxT("wav"), CODEC_ID_ADPCM_SWF },
    { wxT("wav"), CODEC_ID_VORBIS },
diff --git a/src/import/ImportFFmpeg.cpp b/src/import/ImportFFmpeg.cpp
index f21f140..a737c99 100644
--- a/src/import/ImportFFmpeg.cpp
+++ b/src/import/ImportFFmpeg.cpp
@@ -369,7 +369,11 @@ bool FFmpegImportFileHandle::Init()
       return false;
    }
 
+#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 3, 0))
    err = av_find_stream_info(mFormatContext);
+#else
+   err = avformat_find_stream_info(mFormatContext, NULL);
+#endif
    if (err < 0)
    {
       wxLogError(wxT("FFmpeg : av_find_stream_info() failed for file %s"),mName.c_str());
-- 
1.9.1

_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

Reply via email to