[Ffmpeg-devel] [BUG] alignment problems

Christian Bienia cbienia
Wed Sep 20 17:00:27 CEST 2006


Hi,

I could find the source of the problem. It looks like ffmpeg is using
unaligned memory accesses. This is a problem on _all_ architectures - in
the best case, it causes a performance degradation, in the worst case a
segfault. On Intel processors, unaligned memory references require twice
as many bus cycles as aligned memory accesses. On the T1, unaligned
accesses result in bus errors. On Intel processors an alignment check
can be activated which will also raise an exception if unaligned memory
accesses occur.

> > t at 2 (l at 2) signal BUS (invalid address alignment) in
> 
> check which var is unaligned and which is the alignment desired.

I checked the reference manuals of the IA32 and SPARCv9 architectures.
In both cases, an N-byte quantity must be aligned at an N-byte boundary.
Only the behavior of the processor differs. Here's what I've found out
about the bug:



(gdb) run
Starting program: /home/cbienia/ffmpeg/bin/ffmpeg -f image2 -i 02350.png
-b 800 -threads 2 -mbd 2 -trell 1 -me epzs test.mp4
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
  configuration:  --cc=/opt/csw/gcc4/bin/gcc --make=gmake
--extra-cflags=-O0 --extra-ldflags= --enable-pthreads --enable-a52
--enable-gpl --disable-ffserver --disable-ffplay --disable-mmx
--disable-armv5te --disable-iwmmxt --disable-altivec --disable-opts
--disable-strip
--prefix=/home/cbienia/splash3/./bench/media/ffmpeg/inst/sparc-solaris.gcc 
  libavutil version: 49.0.0
  libavcodec version: 51.14.0
  libavformat version: 50.5.0
  built on Sep 20 2006 10:49:43, gcc: 4.0.2
Input #0, image2, from '02350.png':
  Duration: 00:00:00.0, start: 0.000000, bitrate: N/A
  Stream #0.0: Video: png, rgb24, 640x360, 25.00 fps(r)
[New LWP 1]
[New LWP 2]
[New LWP 3]
Output #0, mp4, to 'test.mp4':
  Stream #0.0: Video: mpeg4 (hq), yuv420p, 640x360, q=2-31, 0 kb/s,
25.00 fps(c)
Stream mapping:
  Stream #0.0 -> #0.0
Press [q] to stop encoding

Program received signal SIGSEGV, Segmentation fault.
[Switching to LWP 2]
0x0025477c in put_bits (s=0x75cf14, n=5, value=5) at bitstream.h:231
231             *(uint32_t *)s->buf_ptr = be2me_32(bit_buf);



The error happens because buf_ptr isn't aligned to 32 bit addresses:



(gdb) ptype bit_buf
type = unsigned int
(gdb) ptype s->buf_ptr
type = unsigned char *
(gdb) p ((unsigned)s->buf_ptr) & 0x3
$1 = 2



Some more information to identify the exact location:



(gdb) list
226                 s->buf_ptr[1] = bit_buf >> 16;
227                 s->buf_ptr[2] = bit_buf >>  8;
228                 s->buf_ptr[3] = bit_buf      ;
229             } else
230     #endif
231             *(uint32_t *)s->buf_ptr = be2me_32(bit_buf);
232             //printf("bitbuf = %08x\n", bit_buf);
233             s->buf_ptr+=4;
234             bit_left+=32 - n;
235             bit_buf = value;
(gdb) bt
#0  0x0025477c in put_bits (s=0x75cf14, n=5, value=5) at bitstream.h:231
#1  0x00263d88 in ff_mpeg4_encode_video_packet_header (s=0x75cec0)
    at h263.c:3176
#2  0x000dae54 in encode_thread (c=0x56db00, arg=0x75cec0) at
mpegvideo.c:4992
#3  0x0044330c in worker (v=0x56db00) at pthread.c:70
#4  0xff13fbf0 in _lwp_start () from /lib/libc.so.1
#5  0xff13fbf0 in _lwp_start () from /lib/libc.so.1



I haven't been able to figure out why the error only occurs if more than
1 thread is running, but the error always occurs.

- Chris





More information about the ffmpeg-devel mailing list