[Ffmpeg-devel] [PATCH] Cygwin vhook, always static avformat

Víctor Paesa wzrlpy
Mon Aug 7 16:37:10 CEST 2006


Hi,

> On Wed, Aug 02, 2006 at 03:45:42PM +0200, V?ctor Paesa wrote:
>>
>> The reason is that WIN32 does not allow undefined symbols during
>> linking.
>>
>> These symbols might be defined by:
>>
>> a) Adding the av[ucf]* libraries as VHOOKLIBS (the
>> ffmpeg.cygwin.vhook.6.patch way)
>>
>> b) Creating a .def for the _av_mallocz, _avpicture_get_size, etc. that
>> exist in ffmpeg.exe (static build), then adding
>> that .def to the linking steps in vhooks.
>>
>> c) Using __declspec(dllimport) (a.ka. FF_IMPORT_ATTR) somehow, somewhere
>> in vhooks (shared libraries builds).
>>
>> I believe that (a) is the solution that minimizes changes and is more
>> portable.
>
> But it has the downsize of creating huge vhooks.  This is not
> acceptable.  I'm confident that this is just a matter of finding the
> right linker incantation ...

Using (a) there would be huge vhooks only for static builds.
The linker docs mentions undefined sysmbols as one limitation of Win32
loader, I have not been able to find the proper linker spell ...

I tried other ways to circumvent this.

First, activate vhooks:

--- ffmpeg-old/configure        2006-08-04 18:41:06.000000000 +0200
+++ ffmpeg/configure    2006-08-07 12:48:37.518246100 +0200
@@ -590,7 +590,7 @@
 v4l2="no"
 audio_oss="yes"
 dv1394="no"
-vhook="no"
+VHOOKFLAGS='-shared'
 extralibs=""
 EXESUF=".exe"
 SLIBPREF="cyg"

Then some attempts:

d) ld is able to link DLLs directly, so let's link vhooks with ffmpeg_g.exe
(disguised as DLL thanks to a symbolic link)
(see "info ld")

./configure --enable-static --disable-shared; make

Fails at linking vhook null.c, then issue this commands:

ln -s ffmpeg_g.exe ffmpeg_g.dll
cd vhook
gcc -fPIC -O3  -g -Wdeclaration-after-statement -Wall -Wno-switch -I..
-I/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg
-I/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavformat
-I/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavcodec
-I/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavutil
-DHAVE_AV_CONFIG_H `freetype-config --cflags`   -c -o null.o null.c
gcc -Wl,--warn-common   -rdynamic -export-dynamic -Wl,--as-needed
-Wl,-rpath-link,/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavcodec
-Wl,-rpath-link,/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavformat
-Wl,-rpath-link,/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavutil
`freetype-config --libs` -g -o null.dll -shared null.o ../ffmpeg_g.dll


The resulting vhook is huge:
$ ls -lrt null.*
-rw-r--r-- 1 wzrlpy Users    2071 Jul 12 17:54 null.c
-rw-r--r-- 1 wzrlpy Users   30437 Aug  7 13:26 null.o
-rwxr-xr-x 1 wzrlpy Users 4278242 Aug  7 13:28 null.dll


Even after stripping:
$ ls -lrt null.*
total 1512
-rw-r--r-- 1 wzrlpy Users    2071 Jul 12 17:54 null.c
-rw-r--r-- 1 wzrlpy Users   30437 Aug  7 13:26 null.o
-rwxr-xr-x 1 wzrlpy Users 3496448 Aug  7 13:27 null.dll

So way (d) is not acceptable.


e) Extract symbol list from .EXE to create a .def, that will be used to
create an import library
(see section "Building and Using DLLs" in Cygwin's User Guide)

# Note that this will only work if the DLL is not stripped.
# Otherwise you will get an error message: "No symbols in foo.dll".
echo EXPORTS > ffmpeg_g.def
nm ffmpeg_g.exe | grep ' T _' | sed 's/.* T _//' >> ffmpeg_g.def

#Once you have the .def file, you can create an import library:
dlltool --input-def ffmpeg_g.def --dllname ffmpeg_g.exe \
--output-lib ffmpeg_g.a

cd vhook
gcc -fPIC -O3  -g -Wdeclaration-after-statement -Wall -Wno-switch -I..
-I/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg
-I/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavformat
-I/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavcodec
-I/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavutil -DHAVE_AV_CONFIG_H
`freetype-config --cflags`   -c -o null.o null.c
gcc -Wl,--warn-common   -rdynamic -export-dynamic -Wl,--as-needed
-Wl,-rpath-link,/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavcodec
-Wl,-rpath-link,/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavformat
-Wl,-rpath-link,/home/wzrlpy/src/FFMpeg-20060804-5931/ffmpeg/libavutil
`freetype-config --libs` -g -o null.dll -shared null.o ../ffmpeg_g.a

The resulting vhook is small:
$ ls -l null.*
-rw-r--r-- 1 wzrlpy Users  2071 Jul 12 17:54 null.c
-rwxr-xr-x 1 wzrlpy Users 42829 Aug  7 15:38 null.dll
-rw-r--r-- 1 wzrlpy Users 30437 Aug  7 15:38 null.o

Let's run it:
$ ../ffmpeg -i ~/SmallConcert.avi -vhook './null.dll' output.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
  configuration:  --enable-static --disable-shared
  libavutil version: 49.0.0
  libavcodec version: 51.11.0
  libavformat version: 50.5.0
  built on Aug  7 2006 12:55:21, gcc: 3.4.4 (cygming special)
(gdc 0.12, using dmd 0.125)
Input #0, avi, from '/home/wzrlpy/SmallConcert.avi':
  Duration: 00:00:20.2, start: 0.000000, bitrate: 30349 kb/s
  Stream #0.0: Video: dvvideo, yuv420p, 720x576, 25.00 fps(r)
  Stream #0.1: Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Permission denied
Failed to add video hook function: ./null.dll

No idea why I got that "Permission denied", ffmpeg_g.exe shows appropiate
permissions:

$ ls -l ffmpeg_g*
-rw-r--r-- 1 wzrlpy Users   536888 Aug  7 15:38 ffmpeg_g.a
-rw-r--r-- 1 wzrlpy Users    11888 Aug  7 15:38 ffmpeg_g.def
-rwxr-xr-x 1 wzrlpy Users 10016527 Aug  7 15:28 ffmpeg_g.exe


So way (e) does not work.

b) Creating a .def for the _av_mallocz, _avpicture_get_size, etc. that
exist in ffmpeg.exe (static build), then adding
that .def to the linking steps in vhooks.

echo EXPORTS > ffmpeg_g.def
nm ffmpeg_g.exe | egrep ' T
_(av_mallocz|avpicture_get_size|av_malloc|avpicture_fill|img_convert|
av_free)$' | sed 's/.* T _//' >> ffmpeg_g.def
dlltool --input-def ffmpeg_g.def --dllname ffmpeg_g.exe \
--output-lib ffmpeg_g.a

Way (b) is a subset of (e), and is shows the same "Permission denied"
message.


f) Explicit loading of av_mallocz, avpicture_get_size, av_malloc, etc
using the Win32 API.

In each vhook Configure function, use

hinstLib = LoadLibrary("ffmpeg.exe");

and for each undefined function then use

av_mallocz = GetProcAddress(hinstLib, "av_mallocz");
avpicture_get_size = GetProcAddress(hinstLib, "avpicture_get_size");
.
.
.

and so on, so that we get their entries in ffmpeg.exe.

This change is quite intrusive, as would require several #ifdef __WIN32__
in vhook modules.

Before investing more time, do you think this way has any chance of
being accepted?


Regards,
V?ctor Paesa




More information about the ffmpeg-devel mailing list