[FFmpeg-cvslog] h264: use struct offsets in get_cabac_bypass_sign_x86().

Aurélien Nephtali aurelien.nephtali at gmail.com
Sun Apr 1 12:30:26 CEST 2012


Hi,

On Thu, Mar 29, 2012 at 4:32 AM, Ronald S. Bultje <git at videolan.org> wrote:
> ffmpeg | branch: master | Ronald S. Bultje <rsbultje at gmail.com> | Fri Mar 16 22:41:17 2012 -0700| [db025929f202bc32459a1278ee06920a06564762] | committer: Ronald S. Bultje
>
> h264: use struct offsets in get_cabac_bypass_sign_x86().
>
>> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=db025929f202bc32459a1278ee06920a06564762
> ---
>
>  libavcodec/x86/cabac.h |   19 +++++++++++--------
>  1 files changed, 11 insertions(+), 8 deletions(-)
>

This change makes libavcodec crash when decoding H.264 streams involving CABAC.

(test done on Mac OS X 10.7.3 with : gcc version 4.2.1 (Based on Apple
Inc. build 5658) (LLVM build 2336.1.00))

ffmpeg -i ~/work/file.ts -an -vcodec libx264 -r 25 -profile baseline
-f mpegts /dev/null
ffmpeg version N-39459-g7a3df01 Copyright (c) 2000-2012 the FFmpeg developers
  built on Apr  1 2012 12:19:49 with llvm_gcc 4.2.1 (Based on Apple
Inc. build 5658) (LLVM build 2336.1.00)
  configuration: --yasmexe=/Users/aurelien/work/yasm-1.1.0/yasm
--prefix=/Users/aurelien/work/local/ --disable-vda --enable-shared
--disable-optimizations --disable-stripping --enable-libx264
--enable-gpl --extra-cflags='-I /Users/aurelien/work/local/include'
--extra-ldflags='-L /Users/aurelien/work/local/lib'
  libavutil      51. 44.100 / 51. 44.100
  libavcodec     54. 12.100 / 54. 12.100
  libavformat    54.  3.100 / 54.  3.100
  libavdevice    53.  4.100 / 53.  4.100
  libavfilter     2. 66.101 /  2. 66.101
  libswscale      2.  1.100 /  2.  1.100
  libswresample   0. 10.100 /  0. 10.100
  libpostproc    52.  0.100 / 52.  0.100
[mpegts @ 0x7fccf9807400] max_analyze_duration 5000000 reached at 5000000
[NULL @ 0x7fccf9843200] start time is not set in estimate_timings_from_pts
[mpegts @ 0x7fccf9807400] PES packet size mismatch
    Last message repeated 1 times
Input #0, mpegts, from '/Users/aurelien/work/speedracer_vm_extrait.ts':
  Duration: 00:02:23.85, start: 0.780000, bitrate: 2375 kb/s
  Program 1
    Stream #0:0[0x3e8]: Video: h264 (Main) ([27][0][0][0] / 0x001B),
yuv420p, 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:1[0x3e9](fra): Audio: mp2 ([3][0][0][0] / 0x0003), 48000
Hz, 2 channels, s16, 192 kb/s
    Stream #0:2[0x3ea](eng): Audio: mp2 ([3][0][0][0] / 0x0003), 48000
Hz, 2 channels, s16, 192 kb/s
    Stream #0:3[0x3ed](fra): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006)
File '/dev/null' already exists. Overwrite ? [y/N] y
w:720 h:576 pixfmt:yuv420p tb:1/1000000 sar:64/45 sws_param:flags=2
[libx264 @ 0x7fccf983dc00] using SAR=64/45
[libx264 @ 0x7fccf983dc00] using cpu capabilities: MMX2 SSE2Fast SSSE3
FastShuffle SSE4.2 AVX
[libx264 @ 0x7fccf983dc00] profile Constrained Baseline, level 3.0
[mpegts @ 0x7fccf983d600] muxrate VBR, pcr every 2 pkts, sdt every
200, pat/pmt every 40 pkts
Output #0, mpegts, to '/dev/null':
  Metadata:
    encoder         : Lavf54.3.100
    Stream #0:0: Video: h264, yuv420p, 720x576 [SAR 64:45 DAR 16:9],
q=-1--1, 90k tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (h264 -> libx264)
Press [q] to stop, [?] for help
Segmentation fault: 11

Depending of the source, the crash location is not the same.
One of them :

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000000000a8cc
[Switching to process 89349 thread 0x2203]
0x0000000100797bb1 in get_cabac_bypass_sign_x86 (c=0x101d35cd0,
val=-1) at cabac.h:111
111	    __asm__ volatile(
(gdb) bt
#0  0x0000000100797bb1 in get_cabac_bypass_sign_x86 (c=0x101d35cd0,
val=-1) at cabac.h:111
#1  0x00000001007a0797 in decode_cabac_residual_internal
(h=0x101cea000, block=0x101d34e10, cat=3, n=49, scantable=0x100c88f74
"", qmul=0x0, max_coeff=4, is_dc=1, chroma422=0) at h264_cabac.c:1746
#2  0x00000001007a0ab9 in decode_cabac_residual_dc_internal
(h=0x101cea000, block=0x101d34e10, cat=3, n=49, scantable=0x100c88f74
"", max_coeff=4) at h264_cabac.c:1757
#3  0x00000001007a0cb6 in decode_cabac_residual_dc (h=0x101cea000,
block=0x101d34e10, cat=3, n=49, scantable=0x100c88f74 "", max_coeff=4)
at h264_cabac.c:1789
#4  0x00000001007a5999 in ff_h264_decode_mb_cabac (h=0x101cea000) at
h264_cabac.c:2393
#5  0x0000000100794fbd in decode_slice (avctx=0x1026cf200,
arg=0x103e67cc8) at h264.c:4010
#6  0x0000000100795ac8 in execute_decode_slices (h=0x101cea000,
context_count=1) at h264.c:4153
#7  0x0000000100796b40 in decode_nal_units (h=0x101cea000,
buf=0x10592ee00 "", buf_size=23719) at h264.c:4445
#8  0x00000001007970c6 in decode_frame (avctx=0x1026cf200,
data=0x1026bab90, data_size=0x1026bad68, avpkt=0x1026bab30) at
h264.c:4557
#9  0x00000001009a593b in frame_worker_thread (arg=0x1026baa00) at pthread.c:381
#10 0x00007fff9716b8bf in _pthread_start ()
#11 0x00007fff9716eb75 in thread_start ()

(gdb) disassemble get_cabac_bypass_sign_x86
Dump of assembler code for function get_cabac_bypass_sign_x86:
0x0000000100797b70 <get_cabac_bypass_sign_x86+0>:	push   %rbp
0x0000000100797b71 <get_cabac_bypass_sign_x86+1>:	mov    %rsp,%rbp
0x0000000100797b74 <get_cabac_bypass_sign_x86+4>:	mov    %rdi,-0x8(%rbp)
0x0000000100797b78 <get_cabac_bypass_sign_x86+8>:	mov    %esi,-0xc(%rbp)
0x0000000100797b7b <get_cabac_bypass_sign_x86+11>:	mov    -0x8(%rbp),%rax
0x0000000100797b7f <get_cabac_bypass_sign_x86+15>:	mov    -0xc(%rbp),%ecx
0x0000000100797b82 <get_cabac_bypass_sign_x86+18>:	mov    %rdx,-0x28(%rbp)
0x0000000100797b86 <get_cabac_bypass_sign_x86+22>:	mov    %rax,-0x30(%rbp)
0x0000000100797b8a <get_cabac_bypass_sign_x86+26>:	mov    -0x30(%rbp),%rsi
0x0000000100797b8e <get_cabac_bypass_sign_x86+30>:	mov    0x4(%rsi),%edx
0x0000000100797b91 <get_cabac_bypass_sign_x86+33>:	mov    (%rsi),%eax
0x0000000100797b93 <get_cabac_bypass_sign_x86+35>:	shl    $0x11,%edx
0x0000000100797b96 <get_cabac_bypass_sign_x86+38>:	add    %eax,%eax
0x0000000100797b98 <get_cabac_bypass_sign_x86+40>:	sub    %edx,%eax
0x0000000100797b9a <get_cabac_bypass_sign_x86+42>:	cltd
0x0000000100797b9b <get_cabac_bypass_sign_x86+43>:	and    %edx,%edx
0x0000000100797b9d <get_cabac_bypass_sign_x86+45>:	add    %edx,%eax
0x0000000100797b9f <get_cabac_bypass_sign_x86+47>:	xor    %edx,%ecx
0x0000000100797ba1 <get_cabac_bypass_sign_x86+49>:	sub    %edx,%ecx
0x0000000100797ba3 <get_cabac_bypass_sign_x86+51>:	test   %ax,%ax
0x0000000100797ba6 <get_cabac_bypass_sign_x86+54>:	jne    0x100797bc3
<get_cabac_bypass_sign_x86+83>
0x0000000100797ba8 <get_cabac_bypass_sign_x86+56>:	mov    0x18(%rsi),%rdx
0x0000000100797bac <get_cabac_bypass_sign_x86+60>:	sub    $0xffff,%eax
0x0000000100797bb1 <get_cabac_bypass_sign_x86+65>:	movzwl (%rdx),%edx
0x0000000100797bb4 <get_cabac_bypass_sign_x86+68>:	bswap  %edx
0x0000000100797bb6 <get_cabac_bypass_sign_x86+70>:	shr    $0xf,%edx
0x0000000100797bb9 <get_cabac_bypass_sign_x86+73>:	add    $0x2,%rdx
0x0000000100797bbd <get_cabac_bypass_sign_x86+77>:	add    %edx,%eax
0x0000000100797bbf <get_cabac_bypass_sign_x86+79>:	mov    %rdx,0x18(%rsi)
0x0000000100797bc3 <get_cabac_bypass_sign_x86+83>:	mov    %eax,(%rsi)
0x0000000100797bc5 <get_cabac_bypass_sign_x86+85>:	mov    -0x28(%rbp),%rax
0x0000000100797bc9 <get_cabac_bypass_sign_x86+89>:	mov    %ecx,-0xc(%rbp)
0x0000000100797bcc <get_cabac_bypass_sign_x86+92>:	mov    %rax,-0x20(%rbp)
0x0000000100797bd0 <get_cabac_bypass_sign_x86+96>:	mov    -0xc(%rbp),%eax
0x0000000100797bd3 <get_cabac_bypass_sign_x86+99>:	mov    %eax,-0x14(%rbp)
0x0000000100797bd6 <get_cabac_bypass_sign_x86+102>:	mov    %eax,-0x10(%rbp)
0x0000000100797bd9 <get_cabac_bypass_sign_x86+105>:	mov    -0x10(%rbp),%eax
0x0000000100797bdc <get_cabac_bypass_sign_x86+108>:	pop    %rbp
0x0000000100797bdd <get_cabac_bypass_sign_x86+109>:	retq
End of assembler dump.

Reverting to 5387f9917f1e5a053824f9ba68545b74a2fc225b fixes the crash.
Tested on gcc version 4.6.3 (Debian 4.6.3-1) : no crash.

I can provide more informations if needed (and/or open a ticket).

-- 
Aurélien Nephtali


More information about the ffmpeg-cvslog mailing list