[FFmpeg-devel] [PATCH] restoring binary compatibility with ffmpeg 0.5
Reinhard Tartler
siretart
Sun Jun 6 17:03:40 CEST 2010
Hi,
I'm sorry for not noticing earlier, but during upgrade tests, I noticed
that there are some functions that went missing in libavformat.so.52
since ffmpeg 0.5. In total, they are:
void ff_av_destruct_packet_nofree(AVPacket *pkt);
void ff_av_destruct_packet(AVPacket *pkt);
int ff_av_new_packet(AVPacket *pkt, int size);
int ff_av_dup_packet(AVPacket *pkt);
void ff_av_free_packet(AVPacket *pkt);
void ff_av_init_packet(AVPacket *pkt);
They all were moved quite some time ago from libavformat to libavcodec.
The API has not been broken, as avcodec is a dependency for avformat.
Still, this is a serious problem if we want to retain binary
compatibility. As a testcase, I'm using the ubuntu ffplay binary (ffmpeg
0.5) with a LD_LIBRARY_PATH, in which ffmpeg 0.6 libraries have been
installed to playback a VP8 file in a WEBM container. Using this setup,
ffplay aborts with:
>> ffplay /tmp/elephant-dream.webm
FFplay version SVN-r0.5.1-4:0.5.1-1ubuntu1, Copyright (c) 2003-2009 Fabrice Bellard, et al.
configuration: --extra-version=4:0.5.1-1ubuntu1 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --disable-stripping --disable-vhook --enable-runtime-cpudetect --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --enable-shared --disable-static
libavutil 49.15. 0 / 49.15. 0
libavcodec 52.20. 1 / 52.72. 2
libavformat 52.31. 0 / 52.64. 2
libavdevice 52. 1. 0 / 52. 2. 0
libavfilter 0. 4. 0 / 0. 4. 0
libswscale 0. 7. 1 / 0.11. 0
libpostproc 51. 2. 0 / 51. 2. 0
built on Mar 4 2010 12:35:30, gcc: 4.4.3
ffplay: relocation error: ffplay: symbol av_init_packet, version LIBAVFORMAT_52 not defined in file libavformat.so.52 with link time reference
The message is exactly right; the mentioned symbols have been removed
from libavformat.so.52.
The safest fix in this situation would be of course to bump major.
However, I've spent now some time to restore binary compatibility by
adding trampoline functions and .symver directives. With the attached
patch, I get the following:
>> ffplay /tmp/elephant-dream.webm
FFplay version SVN-r0.5.1-4:0.5.1-1ubuntu1, Copyright (c) 2003-2009 Fabrice Bellard, et al.
configuration: --extra-version=4:0.5.1-1ubuntu1 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --disable-stripping --disable-vhook --enable-runtime-cpudetect --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --enable-shared --disable-static
libavutil 49.15. 0 / 49.15. 0
libavcodec 52.20. 1 / 52.72. 2
libavformat 52.31. 0 / 52.64. 2
libavdevice 52. 1. 0 / 52. 2. 0
libavfilter 0. 4. 0 / 0. 4. 0
libswscale 0. 7. 1 / 0.11. 0
libpostproc 51. 2. 0 / 51. 2. 0
built on Mar 4 2010 12:35:30, gcc: 4.4.3
diverting av_*_packet function calls to libavcodec. Recompile to improve performance
[libvpx @ 0x9f60b10]v0.9.0
[matroska @ 0x9f2fce0]Estimating duration from bitrate, this may be inaccurate
[libvpx @ 0x9f60b10]v0.9.0
and the video plays back just fine.
I'd really like to have this for ffmpeg 0.6. Is the attached patch
acceptable for trunk?
Index: configure
===================================================================
--- configure (revision 23498)
+++ configure (working copy)
@@ -1086,6 +1086,7 @@
struct_sockaddr_in6
struct_sockaddr_sa_len
struct_sockaddr_storage
+ symbol_versioning
sys_mman_h
sys_resource_h
sys_select_h
@@ -2733,7 +2734,7 @@
echo "X{};" > $TMPV
test_ldflags -Wl,--version-script,$TMPV &&
- append SHFLAGS '-Wl,--version-script,\$(SUBDIR)lib\$(NAME).ver'
+ append SHFLAGS '-Wl,--version-script,\$(SUBDIR)lib\$(NAME).ver' && enable symbol_versioning
if enabled small; then
add_cflags $size_cflags
Index: libavformat/utils.c
===================================================================
--- libavformat/utils.c (revision 23498)
+++ libavformat/utils.c (working copy)
@@ -29,6 +29,9 @@
#include <time.h>
#include <strings.h>
#include <stdarg.h>
+#if HAVE_SYMBOL_VERSIONING && LIBAVFORMAT_VERSION_MAJOR < 53
+#include <dlfcn.h>
+#endif
#if CONFIG_NETWORK
#include "network.h"
#endif
@@ -41,6 +44,10 @@
* various utility functions for use within FFmpeg
*/
+#if HAVE_SYMBOL_VERSIONING && LIBAVFORMAT_VERSION_MAJOR < 53
+static void *avformat_handle;
+#endif
+
unsigned avformat_version(void)
{
return LIBAVFORMAT_VERSION_INT;
@@ -282,9 +289,75 @@
return NULL;
}
-/* memory handling */
+#if HAVE_SYMBOL_VERSIONING && LIBAVFORMAT_VERSION_MAJOR < 53
+/* compatibility trampolines for packet functions */
+void ff_av_destruct_packet_nofree(AVPacket *pkt);
+void ff_av_destruct_packet_nofree(AVPacket *pkt)
+{
+ void (*fn)(AVPacket *pkt) = dlsym(avformat_handle, "av_destruct_packet_nofree");
+ if (!fn)
+ av_log(NULL, AV_LOG_FATAL, "Failed to locate symbol: av_destruct_nofree\n");
+ (*fn)(pkt);
+}
+__asm__(".symver ff_av_destruct_packet_nofree,av_destruct_packet_nofree at LIBAVFORMAT_52");
+void ff_av_destruct_packet(AVPacket *pkt);
+void ff_av_destruct_packet(AVPacket *pkt)
+{
+ void (*fn)(AVPacket *pkt) = dlsym(avformat_handle, "av_destruct_packet");
+ if (!fn)
+ av_log(NULL, AV_LOG_FATAL, "Failed to locate symbol: av_destruct_packet\n");
+ (*fn)(pkt);
+}
+__asm__(".symver ff_av_destruct_packet,av_destruct_packet at LIBAVFORMAT_52");
+
+int ff_av_new_packet(AVPacket *pkt, int size);
+int ff_av_new_packet(AVPacket *pkt, int size)
+{
+ int (*fn)(AVPacket *pkt, int size) = dlsym(avformat_handle, "av_new_packet");
+ if (!fn)
+ av_log(NULL, AV_LOG_FATAL, "Failed to locate symbol: av_new_packet\n");
+ return (*fn)(pkt, size);
+}
+__asm__(".symver ff_av_new_packet,av_new_packet at LIBAVFORMAT_52");
+
+int ff_av_dup_packet(AVPacket *pkt);
+int ff_av_dup_packet(AVPacket *pkt)
+{
+ int (*fn)(AVPacket *pkt) = dlsym(avformat_handle, "av_dup_packet");
+ if (!fn)
+ av_log(NULL, AV_LOG_FATAL, "Failed to locate symbol: av_dup_packet\n");
+ return (*fn)(pkt);
+}
+__asm__(".symver ff_av_dup_packet,av_dup_packet at LIBAVFORMAT_52");
+
+void ff_av_free_packet(AVPacket *pkt);
+void ff_av_free_packet(AVPacket *pkt)
+{
+ void (*fn)(AVPacket *pkt) = dlsym(avformat_handle, "av_free_packet");
+ if (!fn)
+ av_log(NULL, AV_LOG_FATAL, "Failed to locate symbol: av_free_packet\n");
+ (*fn)(pkt);
+}
+__asm__(".symver ff_av_free_packet,av_free_packet at LIBAVFORMAT_52");
+
+void ff_av_init_packet(AVPacket *pkt);
+void ff_av_init_packet(AVPacket *pkt)
+{
+ void (*fn)(AVPacket *pkt);
+ av_log(NULL, AV_LOG_WARNING, "diverting av_*_packet function calls to libavcodec. Recompile to improve performance\n");
+ avformat_handle=dlopen("libavcodec.so.52", RTLD_LAZY);
+ if(!avformat_handle)
+ av_log(NULL, AV_LOG_FATAL, "Could not open libavcodec.so.52\n");
+ fn = dlsym(avformat_handle, "av_init_packet");
+ if (!fn)
+ av_log(NULL, AV_LOG_FATAL, "Failed to locate symbol: av_init_packet\n");
+ (*fn)(pkt);
+}
+__asm__(".symver ff_av_init_packet,av_init_packet at LIBAVFORMAT_52");
+#endif
+
int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size)
{
int ret= av_new_packet(pkt, size);
--
Gruesse/greetings,
Reinhard Tartler, KeyID 945348A4
More information about the ffmpeg-devel
mailing list