[Ffmpeg-devel] [PATCH] dlopen libamrnb / libamrwb instead of linking

Pavlov Konstantin thresh
Thu Apr 19 14:20:10 CEST 2007


Hi guys.

The attached patch was made by led at altlinux.ru to allow ffmpeg dlopen
libamrnb and libamrwb instead of linking to it.

I've tested that on amr-nb files on x86-32, works fine. It would be nice
if someone could test it with wb as well as on x86-64.

-- 
Maryann's Law:
	You can always find what you're not looking for.
-------------- next part --------------
diff --git a/configure b/configure
index 60255fb..10393c0 100755
--- a/configure
+++ b/configure
@@ -100,8 +100,10 @@ show_help(){
   echo "  --enable-xvid            enable Xvid encoding via xvidcore,"
   echo "                           native MPEG-4/Xvid encoder exists [default=no]"
   echo "  --enable-amr-nb          enable amr-nb floating point audio codec"
+  echo "  --enable-libamrnbbin     open libamrnb.so.2 at runtime [default=no]"
   echo "  --enable-amr-nb-fixed    enable amr-nb fixed-point codec"
   echo "  --enable-amr-wb          enable amr-wb floating point audio codec"
+  echo "  --enable-libamrwbbin     open libamwnb.so.2 at runtime [default=no]"
   echo ""
   echo "Advanced options (experts only):"
   echo "  --source-path=PATH       path to source code [$source_path]"
@@ -558,8 +560,10 @@ CONFIG_LIST='
     demuxers
     amr
     amr_nb
+    libamrnbbin
     amr_nb_fixed
     amr_wb
+    libamrwbbin
     audio_beos
     audio_oss
     avisynth
@@ -791,8 +795,10 @@ v4l="yes"
 
 # libraries
 amr_nb="no"
+libamrnbbin="no"
 amr_nb_fixed="no"
 amr_wb="no"
+libamrwbbin="no"
 avisynth="no"
 dc1394="no"
 dlfcn_h="no"
@@ -1583,7 +1589,7 @@ for thread in $THREADS_LIST; do
     fi
 done
 
-enabled_any amr_nb amr_nb_fixed amr_wb && enable amr
+enabled_any amr_nb libamrnbbin amr_nb_fixed amr_wb libamrwbbin && enable amr
 enabled_all amr_nb amr_nb_fixed &&
     die "Only one of amr_nb and amr_nb_fixed may be enabled."
 
@@ -1606,6 +1612,9 @@ enabled libfaac    && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaa
 enabled libfaad    && require2 libfaad faad.h faacDecOpen -lfaad
 enabled avisynth   && require2 vfw32 "windows.h vfw.h" AVIFileInit -lvfw32
 
+enabled libamrnbbin && enable amr_nb
+enabled libamrwbbin && enable amr_wb
+
 # test for lrintf in math.h
 check_exec <<EOF && lrintf=yes || lrintf=no
 #define _ISOC9X_SOURCE  1
@@ -1632,7 +1641,7 @@ fi
 
 test "$vhook" = "default" && vhook="$dlopen"
 
-enabled_any vhook liba52bin libfaadbin ffserver && add_extralibs $ldl
+enabled_any vhook libamrnbbin libamrwbbin liba52bin libfaadbin ffserver && add_extralibs $ldl
 
 if test "$targetos" = cygwin && enabled static ; then
     vhook="no"
@@ -1864,8 +1873,10 @@ echo "x264 enabled              $x264"
 echo "XviD enabled              $xvid"
 echo "zlib enabled              $zlib"
 echo "AMR-NB float support      $amr_nb"
+echo "AMR-NB float dlopened     $libamrnbbin"
 echo "AMR-NB fixed support      $amr_nb_fixed"
 echo "AMR-WB float support      $amr_wb"
+echo "AMR-WB float dlopened     $libamrwbbin"
 if disabled gpl; then
     echo "License: LGPL"
 else
diff --git a/libavcodec/amr.c b/libavcodec/amr.c
index bff406c..ce3a622 100644
--- a/libavcodec/amr.c
+++ b/libavcodec/amr.c
@@ -65,6 +65,18 @@
 
 #include "avcodec.h"
 
+#if defined(CONFIG_LIBAMRNBBIN) || defined(CONFIG_LIBAMRWBBIN)
+#include <dlfcn.h>
+static void* dlsymm(void* handle, char type, const char* symbol)
+{
+    void* f = dlsym(handle, symbol);
+    if (!f)
+        av_log( NULL, AV_LOG_ERROR, "AMR-%cB Codec - function '%s' can't be resolved\n", type, symbol);
+    return f;
+}
+#endif
+
+#if defined(CONFIG_AMR_NB) || defined(CONFIG_AMR_NB_FIXED)
 #ifdef CONFIG_AMR_NB_FIXED
 
 #define MMS_IO
@@ -77,9 +89,13 @@
 #include "amr/e_homing.h"
 
 #else
+#ifdef CONFIG_LIBAMRNBBIN
+static const char* libamrnbname = "libamrnb.so.2";
+#else
 #include <amrnb/interf_dec.h>
 #include <amrnb/interf_enc.h>
 #endif
+#endif
 
 static const char *nb_bitrate_unsupported =
     "bitrate not supported: use one of 4.75k, 5.15k, 5.9k, 6.7k, 7.4k, 7.95k, 10.2k or 12.2k\n";
@@ -90,13 +106,27 @@ static const char *wb_bitrate_unsupported =
 typedef struct AMR_bitrates
 {
     int rate;
+#ifdef CONFIG_LIBAMRNBBIN
+    int mode;
+#else
     enum Mode mode;
+#endif
 } AMR_bitrates;
 
 /* Match desired bitrate */
 static int getBitrateMode(int bitrate)
 {
     /* make the correspondance between bitrate and mode */
+#ifdef CONFIG_LIBAMRNBBIN
+    AMR_bitrates rates[]={ {4750,0},
+                           {5150,1},
+                           {5900,2},
+                           {6700,3},
+                           {7400,4},
+                           {7950,5},
+                           {10200,6},
+                           {12200,7},
+#else
     AMR_bitrates rates[]={ {4750,MR475},
                            {5150,MR515},
                            {5900,MR59},
@@ -105,6 +135,7 @@ static int getBitrateMode(int bitrate)
                            {7950,MR795},
                            {10200,MR102},
                            {12200,MR122},
+#endif
                          };
     int i;
 
@@ -359,14 +390,51 @@ typedef struct AMRContext {
     void * decState;
     int *enstate;
     int enc_bitrate;
+#ifdef CONFIG_LIBAMRNBBIN
+    void* handle;
+    union {
+	void* (*amrnb_dec_init)(void);
+	void* (*amrnb_enc_init)(int dtx, char vad2_code);
+    };
+    union {
+	void (*amrnb_decode)(void *st, unsigned char *bits, short *synth, int bfi);
+	int (*amrnb_encode)(void *st, int mode, short *speech, unsigned char *serial, int forceSpeech, char vad2_code);
+    };
+    void (*amrnb_exit)(void *state);
+#endif
 } AMRContext;
 
+#ifdef CONFIG_LIBAMRNBBIN
+static void* dlsymn(void* handle, const char* symbol)
+{
+    return dlsymm(handle, 'N', symbol);
+}
+#endif
+
 static int amr_nb_decode_init(AVCodecContext * avctx)
 {
     AMRContext *s = avctx->priv_data;
 
     s->frameCount=0;
+#ifdef CONFIG_LIBAMRNBBIN
+    s->handle = dlopen(libamrnbname, RTLD_LAZY);
+    if (!s->handle)
+    {
+        av_log( avctx, AV_LOG_ERROR, "AMR-NB library %s could not be opened! \n%s\n", libamrnbname, dlerror());
+        return -1;
+    }
+    s->amrnb_dec_init=(void (*)) dlsymn(s->handle, "Decoder_Interface_init");
+    s->amrnb_exit=(void (*)(void*)) dlsymn(s->handle, "Decoder_Interface_exit");
+    s->amrnb_decode=(void (*)(void *, unsigned char *, short *, int)) dlsymn(s->handle, "GP3Decoder_Interface_Decode");
+    if (!s->amrnb_dec_init || !s->amrnb_exit || !s->amrnb_decode)
+    {
+        dlclose(s->handle);
+        return -1;
+    }
+    s->decState=s->amrnb_dec_init();
+#else
     s->decState=Decoder_Interface_init();
+#endif
     if(!s->decState)
     {
         av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\r\n");
@@ -405,7 +473,25 @@ static int amr_nb_encode_init(AVCodecContext * avctx)
     avctx->frame_size=160;
     avctx->coded_frame= avcodec_alloc_frame();
 
+#ifdef CONFIG_LIBAMRNBBIN
+    s->handle = dlopen(libamrnbname, RTLD_LAZY);
+    if (!s->handle)
+    {
+        av_log( avctx, AV_LOG_ERROR, "amrnb library %s could not be opened! \n%s\n", libamrnbname, dlerror());
+        return -1;
+    }
+    s->amrnb_enc_init=(void* (*)(int, char)) dlsymn(s->handle, "VADxEncoder_Interface_init");
+    s->amrnb_exit=(void (*)(void*)) dlsymn(s->handle, "Encoder_Interface_exit");
+    s->amrnb_encode=(int (*)(void*, int, short*, unsigned char*, int, char)) dlsymn(s->handle, "GP3VADxEncoder_Interface_Encode");
+    if (!s->amrnb_enc_init || !s->amrnb_exit || !s->amrnb_encode)
+    {
+        dlclose(s->handle);
+        return -1;
+    }
+    s->enstate=s->amrnb_enc_init(0, 1);
+#else
     s->enstate=Encoder_Interface_init(0);
+#endif
     if(!s->enstate)
     {
         av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n");
@@ -425,7 +511,12 @@ static int amr_nb_decode_close(AVCodecContext * avctx)
 {
     AMRContext *s = avctx->priv_data;
 
+#ifdef CONFIG_LIBAMRNBBIN
+    s->amrnb_exit(s->decState);
+    dlclose(s->handle);
+#else
     Decoder_Interface_exit(s->decState);
+#endif
     return 0;
 }
 
@@ -433,7 +524,12 @@ static int amr_nb_encode_close(AVCodecContext * avctx)
 {
     AMRContext *s = avctx->priv_data;
 
+#ifdef CONFIG_LIBAMRNBBIN
+    s->amrnb_exit(s->enstate);
+    dlclose(s->handle);
+#else
     Encoder_Interface_exit(s->enstate);
+#endif
     av_freep(&avctx->coded_frame);
     return 0;
 }
@@ -445,7 +541,11 @@ static int amr_nb_decode_frame(AVCodecContext * avctx,
     AMRContext *s = avctx->priv_data;
     uint8_t*amrData=buf;
     static short block_size[16]={ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
+#ifdef CONFIG_LIBAMRNBBIN
+    int dec_mode;
+#else
     enum Mode dec_mode;
+#endif
     int packet_size;
 
     /* av_log(NULL,AV_LOG_DEBUG,"amr_decode_frame buf=%p buf_size=%d frameCount=%d!!\n",buf,buf_size,s->frameCount); */
@@ -461,7 +561,11 @@ static int amr_nb_decode_frame(AVCodecContext * avctx,
     s->frameCount++;
     /* av_log(NULL,AV_LOG_DEBUG,"packet_size=%d amrData= 0x%X %X %X %X\n",packet_size,amrData[0],amrData[1],amrData[2],amrData[3]); */
     /* call decoder */
+#ifdef CONFIG_LIBAMRNBBIN
+    s->amrnb_decode(s->decState, amrData, data, 0);
+#else
     Decoder_Interface_Decode(s->decState, amrData, data, 0);
+#endif
     *data_size=160*2;
 
     return packet_size;
@@ -479,11 +583,15 @@ static int amr_nb_encode_frame(AVCodecContext *avctx,
         return -1;
     }
 
+#ifdef CONFIG_LIBAMRNBBIN
+    written = s->amrnb_encode(s->enstate, s->enc_bitrate, data, frame, 0, 0);
+#else
     written = Encoder_Interface_Encode(s->enstate,
         s->enc_bitrate,
         data,
         frame,
         0);
+#endif
     /* av_log(NULL,AV_LOG_DEBUG,"amr_nb_encode_frame encoded %u bytes, bitrate %u, first byte was %#02x\n",written, s->enc_bitrate, frame[0] ); */
 
     return written;
@@ -491,8 +599,6 @@ static int amr_nb_encode_frame(AVCodecContext *avctx,
 
 #endif
 
-#if defined(CONFIG_AMR_NB) || defined(CONFIG_AMR_NB_FIXED)
-
 AVCodec amr_nb_decoder =
 {
     "amr_nb",
@@ -527,9 +633,15 @@ AVCodec amr_nb_encoder =
 #define typedef_h
 #endif
 
+#define CONFIG_LIBAMRWBBIN
+#ifdef CONFIG_LIBAMRWBBIN
+#include <stdint.h>
+static const char* libamrwbname = "libamrwb.so.2";
+#else
 #include <amrwb/enc_if.h>
 #include <amrwb/dec_if.h>
 #include <amrwb/if_rom.h>
+#endif
 
 /* Common code for fixed and float version*/
 typedef struct AMRWB_bitrates
@@ -569,9 +681,32 @@ typedef struct AMRWBContext {
     int frameCount;
     void *state;
     int mode;
+#ifdef CONFIG_LIBAMRWBBIN
+    void* handle;
+    void* (*amrwb_init)(void);
+    union {
+	void (*amrwb_decode)(void *st, uint8_t *bits, int16_t *synth, int32_t bfi);
+	int (*amrwb_encode)(void *st, int16_t mode, int16_t *speech, uint8_t *serial, int16_t dtx);
+    };
+    void (*amrwb_exit)(void *state);
+#if 0
+    uint8_t (*amrwb_block_size)(int index);
+#else
+    uint8_t *amrwb_block_size;
+#endif
+    int16_t allow_dtx;
+#else
     Word16 allow_dtx;
+#endif
 } AMRWBContext;
 
+#ifdef CONFIG_LIBAMRWBBIN
+static void* dlsymw(void* handle, const char* symbol)
+{
+    return dlsymm(handle, 'W', symbol);
+}
+#endif
+
 static int amr_wb_encode_init(AVCodecContext * avctx)
 {
     AMRWBContext *s = avctx->priv_data;
@@ -599,7 +734,25 @@ static int amr_wb_encode_init(AVCodecContext * avctx)
     avctx->frame_size=320;
     avctx->coded_frame= avcodec_alloc_frame();
 
+#ifdef CONFIG_LIBAMRWBBIN
+    s->handle = dlopen(libamrwbname, RTLD_LAZY);
+    if (!s->handle)
+    {
+        av_log( avctx, AV_LOG_ERROR, "AMR-WB library %s could not be opened! \n%s\n", libamrnbname, dlerror());
+        return -1;
+    }
+    s->amrwb_init=(void (*)) dlsymw(s->handle, "E_IF_init");
+    s->amrwb_exit=(void (*)(void*)) dlsymw(s->handle, "E_IF_exit");
+    s->amrwb_encode=(int (*)(void *, int16_t, int16_t *, uint8_t *, int16_t)) dlsymw(s->handle, "GP3E_IF_encode");
+    if (!s->amrwb_init || !s->amrwb_exit || !s->amrwb_encode)
+    {
+        dlclose(s->handle);
+        return -1;
+    }
+    s->state=s->amrwb_init();
+#else
     s->state = E_IF_init();
+#endif
     s->allow_dtx=0;
 
     return 0;
@@ -609,7 +762,12 @@ static int amr_wb_encode_close(AVCodecContext * avctx)
 {
     AMRWBContext *s = avctx->priv_data;
 
+#ifdef CONFIG_LIBAMRWBBIN
+    s->amrwb_exit(s->state);
+    dlclose(s->handle);
+#else
     E_IF_exit(s->state);
+#endif
     av_freep(&avctx->coded_frame);
     s->frameCount++;
     return 0;
@@ -626,7 +784,11 @@ static int amr_wb_encode_frame(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR, wb_bitrate_unsupported);
         return -1;
     }
+#ifdef CONFIG_LIBAMRWBBIN
+    size = s->amrwb_encode(s->state, s->mode, data, frame, s->allow_dtx);
+#else
     size = E_IF_encode(s->state, s->mode, data, frame, s->allow_dtx);
+#endif
     return size;
 }
 
@@ -635,7 +797,30 @@ static int amr_wb_decode_init(AVCodecContext * avctx)
     AMRWBContext *s = avctx->priv_data;
 
     s->frameCount=0;
+#ifdef CONFIG_LIBAMRWBBIN
+    s->handle = dlopen(libamrwbname, RTLD_LAZY);
+    if (!s->handle)
+    {
+        av_log( avctx, AV_LOG_ERROR, "AMR-WB library %s could not be opened! \n%s\n", libamrnbname, dlerror());
+        return -1;
+    }
+    s->amrwb_init=(void (*)) dlsymw(s->handle, "D_IF_init");
+    s->amrwb_exit=(void (*)(void*)) dlsymw(s->handle, "D_IF_exit");
+#if 0
+    s->amrwb_block_size=(uint8_t (*)(int)) dlsymw(s->handle, "get_GP3_block_size");
+#else
+    s->amrwb_block_size=(uint8_t (*)) dlsymw(s->handle, "GP3block_size");
+#endif
+    s->amrwb_decode=(void (*)(void *, uint8_t *, int16_t *, int32_t)) dlsymw(s->handle, "GP3D_IF_decode");
+    if (!s->amrwb_init || !s->amrwb_exit || !s->amrwb_block_size || !s->amrwb_decode)
+    {
+        dlclose(s->handle);
+        return -1;
+    }
+    s->state=s->amrwb_init();
+#else
     s->state = D_IF_init();
+#endif
 
     amr_decode_fix_avctx(avctx);
 
@@ -663,7 +848,15 @@ static int amr_wb_decode_frame(AVCodecContext * avctx,
     }
 
     mode = (amrData[0] >> 3) & 0x000F;
+#ifdef CONFIG_LIBAMRWBBIN
+#if 0
+    packet_size = s->amrwb_block_size(mode);
+#else
+    packet_size = s->amrwb_block_size[mode];
+#endif
+#else
     packet_size = block_size[mode];
+#endif
 
     if(packet_size > buf_size) {
         av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n", buf_size, packet_size+1);
@@ -671,7 +864,11 @@ static int amr_wb_decode_frame(AVCodecContext * avctx,
     }
 
     s->frameCount++;
+#ifdef CONFIG_LIBAMRWBBIN
+    s->amrwb_decode(s->state, amrData, data, 0);
+#else
     D_IF_decode( s->state, amrData, data, _good_frame);
+#endif
     *data_size=320*2;
     return packet_size;
 }
@@ -680,7 +877,12 @@ static int amr_wb_decode_close(AVCodecContext * avctx)
 {
     AMRWBContext *s = avctx->priv_data;
 
+#ifdef CONFIG_LIBAMRWBBIN
+    s->amrwb_exit(s->state);
+    dlclose(s->handle);
+#else
     D_IF_exit(s->state);
+#endif
     return 0;
 }
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070419/1e43ed5d/attachment.pgp>



More information about the ffmpeg-devel mailing list