The goal was to generate a wrapper for the
ffmpeg-library in Java.
1) checkout the ffmpeg sources
2) compile ffmpeg.
3) generate wrapper sources (Java and C)
4) compile native part of wrapper
Those steps are performed by the attached shell script.
The interface definition file looks like this:
(right now just for one of the headers)
----------------------
%module ffmpeg
%{
/* Includes the header in the wrapper code */
#include "ffmpeg/avcodec.h"
%}
/* Parse the header file to generate wrappers */
%include "ffmpeg-linux/include/ffmpeg/avcodec.h"
----------------------
Running the script results in these error messages:
----------------------
$ ./generate.sh
ffmpeg-linux/include/ffmpeg/avcodec.h:25: Warning(305):
Bad constant value (ignored).
ffmpeg-linux/include/ffmpeg/avcodec.h:601:
Warning(451): Setting a const char * variable may leak
memory.
ffmpeg-linux/include/ffmpeg/avcodec.h:1945:
Warning(451): Setting a const char * variable may leak
memory.
temp/ffmpeg_wrap.c: In function
'Java_videal_wrapper_ffmpeg_ffmpegJNI_AVFrame_1motion_1val_1set':
temp/ffmpeg_wrap.c:2394: error: expected identifier or
'(' before ')' token
temp/ffmpeg_wrap.c:2395: error: 'b' undeclared (first
use in this function)
temp/ffmpeg_wrap.c:2395: error: (Each undeclared
identifier is reported only once
temp/ffmpeg_wrap.c:2395: error: for each function it
appears in.)
temp/ffmpeg_wrap.c:2395: error: expected ')' before '*'
token
----------------------
The problematic code that was generated:
----------------------
JNIEXPORT void JNICALL
Java_videal_wrapper_ffmpeg_ffmpegJNI_AVFrame_1motion_1val_1set(JNIEnv
*jenv, jclass jcls, jlong jarg1, jlong jarg2) {
AVFrame *arg1 = (AVFrame *) 0 ;
int16_t (**arg2)[2] ;
(void)jenv;
(void)jcls;
arg1 = *(AVFrame **)&jarg1;
arg2 = *(int16_t (***)[2])&jarg2;
{
size_t ii;
int16_t (*)[2] *b = (int16_t (*)[2] *)
arg1->motion_val;
for (ii = 0; ii < (size_t)2; ii++) b[ii] =
*((int16_t (*)[2] *) arg2 + ii);
}
}
----------------------
Seems the generation of this line does not work as
expected:
int16_t (*)[2] *b = (int16_t (*)[2] *) rg1->motion_val;
Uncommenting that line and the next one, and the native
part of the wrapper compiles.
Configuration of the linux system:
swig 1.3.29
gcc 4.1.1
Logged In: YES
user_id=242951
The cutdown source for this troublesome code is below and
fails for all languages one way or another.
#define FF_COMMON_FRAME
/**\ * Motion vector table.\ * @code\ * example:\ * int mv_sample_log2= 4 - motion_subsample_log2;\ * int mb_width= (width+15)>>4;\ * int mv_stride= (mb_width << mv_sample_log2) + 1;\ * motion_val[direction][x + y*mv_stride][0->mv_x,
1->mv_y];\ * @endcode\ * - encoding: set by user\ * - decoding: set by lavc\ */\ int16_t (*motion_val[2])[2];\
typedef struct AVFrame {
FF_COMMON_FRAME
} AVFrame;
Egad, what is it?? :)
Seems SF has mangled the code by escaping it - I've attempted to undo that, and this fails to generated valid C code with git master a bit before 4.1.0 (tested with
-python
):This much simpler example also fails:
I think that still contains the nub of the problem here - the code produce with
-java
seems to have essentially the same problem as that shown above.It's a two dimension array of function pointers if I've understood it correctly, though I'm not certain I have.
Actually, I think it's a two dimensional array of pointers to int.
Still reproducible. Possibly related to https://github.com/swig/swig/issues/142