[Ffmpeg-devel] [PATCH] dlopen libamrnb / libamrwb instead of linking
Pavlov Konstantin
thresh
Fri Apr 20 16:45:27 CEST 2007
On Thu, Apr 19, 2007 at 09:11:05PM +0200, Michael Niedermayer wrote:
Here's the updated patch. It solves some problems you mentioned.
Actually, i'm acting more like a proxy between the patch author and you,
ffmpeg guys. :]
> summary, i really like to have dlopen support for amr* as that allows binary
> packages of ffmpeg to have amr support without strictly depending on libamr
> to be installed on the end users system
> but
> 1. it can be expected that the package maintainer building the binary
> has libamr
> 2. the whole code is a mess this can be done much cleaner,that is with
> a fraction of the #ifdef hell ...
What we're trying to achieve is to be able to build ffmpeg package in a
repository that *DOES NOT* contain libamrwb / libamrnb packages due to
legal issues. That means that package maintainer (me, if it matters)
cannot add BuildRequires: libamr{n,w}b-devel to ffmpeg spec file.
That means we have to duplicate some code to not depend on headers from
those packages.
--
The only time a dog gets complimented is when he doesn't do anything.
-- C. Schulz
-------------- next part --------------
diff -urN ffmpeg-svn-r8757.orig/configure ffmpeg-svn-r8757/configure
--- ffmpeg-svn-r8757.orig/configure 2007-04-16 04:46:01 +0300
+++ ffmpeg-svn-r8757/configure 2007-04-20 13:02:57 +0300
@@ -100,8 +100,10 @@
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 @@
demuxers
amr
amr_nb
+ libamrnbbin
amr_nb_fixed
amr_wb
+ libamrwbbin
audio_beos
audio_oss
avisynth
@@ -791,8 +795,10 @@
# 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 @@
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 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 @@
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 "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 -urN ffmpeg-svn-r8757.orig/libavcodec/amr.c ffmpeg-svn-r8757/libavcodec/amr.c
--- ffmpeg-svn-r8757.orig/libavcodec/amr.c 2007-04-20 01:28:26 +0300
+++ ffmpeg-svn-r8757/libavcodec/amr.c 2007-04-20 13:30:14 +0300
@@ -65,6 +65,25 @@
#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
+
+static void amr_decode_fix_avctx(AVCodecContext* avctx, int sample_rate, int frame_size)
+{
+ if(avctx->sample_rate == 0) avctx->sample_rate = sample_rate;
+ if(avctx->channels == 0) avctx->channels = 1;
+ avctx->frame_size = frame_size;
+}
+
+#if defined(CONFIG_AMR_NB) || defined(CONFIG_AMR_NB_FIXED)
#ifdef CONFIG_AMR_NB_FIXED
#define MMS_IO
@@ -77,9 +96,14 @@
#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
+#define amrnb_decode_fix_avctx(avctx) amr_decode_fix_avctx(avctx, 8000, 160)
+#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";
@@ -87,16 +111,21 @@
"bitrate not supported: use one of 6.6k, 8.85k, 12.65k, 14.25k, 15.85k, 18.25k, 19.85k, 23.05k, or 23.85k\n";
/* Common code for fixed and float version*/
+#ifdef CONFIG_LIBAMRNBBIN
typedef struct AMR_bitrates
{
int rate;
enum Mode mode;
} AMR_bitrates;
+#endif
/* Match desired bitrate */
static int getBitrateMode(int bitrate)
{
/* make the correspondance between bitrate and mode */
+#ifdef CONFIG_LIBAMRNBBIN
+ int rates[]={4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200};
+#else
AMR_bitrates rates[]={ {4750,MR475},
{5150,MR515},
{5900,MR59},
@@ -106,36 +135,26 @@
{10200,MR102},
{12200,MR122},
};
+#endif
int i;
for(i=0;i<8;i++)
{
+#ifdef CONFIG_LIBAMRNBBIN
+ if(rates[i]==bitrate)
+ {
+ return i;
+#else
if(rates[i].rate==bitrate)
{
return(rates[i].mode);
+#endif
}
}
/* no bitrate matching, return an error */
return -1;
}
-static void amr_decode_fix_avctx(AVCodecContext * avctx)
-{
- const int is_amr_wb = 1 + (avctx->codec_id == CODEC_ID_AMR_WB);
-
- if(avctx->sample_rate == 0)
- {
- avctx->sample_rate = 8000 * is_amr_wb;
- }
-
- if(avctx->channels == 0)
- {
- avctx->channels = 1;
- }
-
- avctx->frame_size = 160 * is_amr_wb;
-}
-
#ifdef CONFIG_AMR_NB_FIXED
/* fixed point version*/
/* frame size in serial bitstream file (frame type + serial stream + flags) */
@@ -172,7 +191,7 @@
return -1;
}
- amr_decode_fix_avctx(avctx);
+ amrnb_decode_fix_avctx(avctx);
if(avctx->channels > 1)
{
@@ -359,21 +378,58 @@
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");
return -1;
}
- amr_decode_fix_avctx(avctx);
+ amrnb_decode_fix_avctx(avctx);
if(avctx->channels > 1)
{
@@ -405,7 +461,25 @@
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 +499,12 @@
{
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 +512,12 @@
{
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 +529,11 @@
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 +549,11 @@
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 +571,15 @@
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 +587,6 @@
#endif
-#if defined(CONFIG_AMR_NB) || defined(CONFIG_AMR_NB_FIXED)
-
AVCodec amr_nb_decoder =
{
"amr_nb",
@@ -527,11 +621,18 @@
#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
+
+#define amrwb_decode_fix_avctx(avctx) amr_decode_fix_avctx(avctx, 16000, 320)
-/* Common code for fixed and float version*/
typedef struct AMRWB_bitrates
{
int rate;
@@ -569,9 +670,28 @@
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);
+ uint8_t *amrwb_block_size;
+ 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 +719,25 @@
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 +747,12 @@
{
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 +769,11 @@
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,9 +782,28 @@
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");
+ s->amrwb_block_size=(uint8_t (*)) dlsymw(s->handle, "GP3block_size");
+ 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);
+ amrwb_decode_fix_avctx(avctx);
if(avctx->channels > 1)
{
@@ -663,7 +829,11 @@
}
mode = (amrData[0] >> 3) & 0x000F;
+#ifdef CONFIG_LIBAMRWBBIN
+ packet_size = s->amrwb_block_size[mode];
+#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 +841,11 @@
}
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 +854,12 @@
{
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/20070420/f0b0aaf7/attachment.pgp>
More information about the ffmpeg-devel
mailing list