[mythtv-commits] Ticket #1041: VideoBuffers::CreateBuffers(), memory alignment, linuxppc and altivec

MythTV mythtv at cvs.mythtv.org
Mon Jan 16 00:57:45 UTC 2006


#1041: VideoBuffers::CreateBuffers(), memory alignment, linuxppc and altivec
----------------------------------------+-----------------------------------
 Reporter:  jwestfall at surrealistic.net  |       Owner:  ijr
     Type:  defect                      |      Status:  new
 Priority:  minor                       |   Milestone:     
Component:  mythtv                      |     Version:     
 Severity:  medium                      |  
----------------------------------------+-----------------------------------
 Hi

 I started using mythtv on my macmini w/linuxppc again and still see the
 issue with segfaults on VideoBuffers::DeleteBuffers() reported many months
 ago.  I was able to track down the issue.

 Here are traces from valgrind for both ffmpeg and libmpeg2 showing them
 corrupting the memory allocations from VideoBuffers::CreateBuffers().


 {{{
 ffmpeg
 ==27640== Invalid write of size 8
 ==27640==    at 0xF412EF4: put_pixels16_altivec (dsputil_altivec.c:710)
 ==27640==    by 0xF265400: MPV_motion (mpegvideo.c:2928)
 ==27640==    by 0xF2643E4: MPV_decode_mb (mpegvideo.c:3872)
 ==27640==    by 0xF317A7C: mpeg_decode_slice (mpeg12.c:2660)
 ==27640==    by 0xF318CFC: mpeg_decode_frame (mpeg12.c:3227)
 ==27640==    by 0xF25A9DC: avcodec_decode_video (utils.c:946)
 ==27640==    by 0xFAF7408: AvFormatDecoder::GetFrame(int)
 (avformatdecoder.cpp:2509)
 ==27640==    by 0xFAB973C: NuppelVideoPlayer::GetFrameNormal(int)
 (NuppelVideoPlayer.cpp:938)
 ==27640==    by 0xFABA438: NuppelVideoPlayer::GetFrame(int, bool)
 (NuppelVideoPlayer.cpp:1016)
 ==27640==    by 0xFAC2524: NuppelVideoPlayer::StartPlaying()
 (NuppelVideoPlayer.cpp:2451)
 ==27640==    by 0x100449C8: SpawnDecoder(void*) (playbackbox.cpp:1575)
 ==27640==    by 0xE294D28: pthread_start_thread (in
 /lib/libpthread-0.10.so)
 ==27640==  Address 0x788C020 is 8 bytes before a block of size 380,226
 alloc'd
 ==27640==    at 0xFFBB4DC: operator new[](unsigned) (in /usr/lib/valgrind
 /ppc32-linux/vgpreload_memcheck.so)
 ==27640==    by 0xFB5BD60: VideoBuffers::CreateBuffers(int, int,
 std::vector<unsigned char*, std::allocator<unsigned char*> >) (videobuffer
 s.cpp:1075)
 ==27640==    by 0xFB5BC28: VideoBuffers::CreateBuffers(int, int)
 (videobuffers.cpp:1064)
 ==27640==    by 0xFB54B94: VideoOutputNull::Init(int, int, float, unsigned
 long, int, int, int, int, unsigned long) (videoout_null.cpp:96)
 ==27640==    by 0xFAB4934: NuppelVideoPlayer::InitVideo()
 (NuppelVideoPlayer.cpp:360)
 ==27640==    by 0xFAC127C: NuppelVideoPlayer::StartPlaying()
 (NuppelVideoPlayer.cpp:2197)
 ==27640==    by 0x100449C8: SpawnDecoder(void*) (playbackbox.cpp:1575)
 ==27640==    by 0xE294D28: pthread_start_thread (in
 /lib/libpthread-0.10.so)
 ==27640==    by 0xE041DF0: clone (in /lib/libc-2.3.5.so)

 libmpeg2
 ==27683== Invalid write of size 8
 ==27683==    at 0xFD5DF00: MC_put_o_16_altivec (motion_comp_altivec.c:87)
 ==27683==    by 0xFD4D66C: motion_zero_420 (slice.c:1503)
 ==27683==    by 0xFD566B0: mpeg2_slice (slice.c:1874)
 ==27683==    by 0xFD47D1C: mpeg2_parse (decode.c:188)
 ==27683==    by 0xFAE6D78:
 AvFormatDecoderPrivate::DecodeMPEG2Video(AVCodecContext*, AVFrame*, int*,
 unsigned char*, int) (avformatdecoder.
 cpp:145)
 ==27683==    by 0xFAF73DC: AvFormatDecoder::GetFrame(int)
 (avformatdecoder.cpp:2506)
 ==27683==    by 0xFAB973C: NuppelVideoPlayer::GetFrameNormal(int)
 (NuppelVideoPlayer.cpp:938)
 ==27683==    by 0xFABA438: NuppelVideoPlayer::GetFrame(int, bool)
 (NuppelVideoPlayer.cpp:1016)
 ==27683==    by 0xFAC2524: NuppelVideoPlayer::StartPlaying()
 (NuppelVideoPlayer.cpp:2451)
 ==27683==    by 0x100449C8: SpawnDecoder(void*) (playbackbox.cpp:1575)
 ==27683==    by 0xE294D28: pthread_start_thread (in
 /lib/libpthread-0.10.so)
 ==27683==    by 0xE041DF0: clone (in /lib/libc-2.3.5.so)
 ==27683==  Address 0x8F88880 is 8 bytes before a block of size 380,226
 alloc'd
 ==27683==    at 0xFFBB4DC: operator new[](unsigned) (in /usr/lib/valgrind
 /ppc32-linux/vgpreload_memcheck.so)
 ==27683==    by 0xFB5BD60: VideoBuffers::CreateBuffers(int, int,
 std::vector<unsigned char*, std::allocator<unsigned char*> >) (videobuffer
 s.cpp:1075)
 ==27683==    by 0xFB5BC28: VideoBuffers::CreateBuffers(int, int)
 (videobuffers.cpp:1064)
 ==27683==    by 0xFB54B94: VideoOutputNull::Init(int, int, float, unsigned
 long, int, int, int, int, unsigned long) (videoout_null.cpp:96)
 ==27683==    by 0xFAB4934: NuppelVideoPlayer::InitVideo()
 (NuppelVideoPlayer.cpp:360)
 ==27683==    by 0xFAC127C: NuppelVideoPlayer::StartPlaying()
 (NuppelVideoPlayer.cpp:2197)
 ==27683==    by 0x100449C8: SpawnDecoder(void*) (playbackbox.cpp:1575)
 ==27683==    by 0xE294D28: pthread_start_thread (in
 /lib/libpthread-0.10.so)
 ==27683==    by 0xE041DF0: clone (in /lib/libc-2.3.5.so)

 }}}

 Both altivec optimized versions of these 2 'put 16' functions require the
 destination buffer be 16-byte aligned.  If the buffer isnt, bad things
 happens when it attempts to store a vector to the beginning of the buffer.

 vec_st(src,0,dest);

 If dest isnt 16-byte aligned the altivec store instruction will truncate
 dest so it is, then store the src vector at that address.  This is whats
 happening in the traces above and ends up causing a buffer underrun on the
 VideoBuffers allocations

 This doesnt seem to be an issue with OSX, since its malloc always returns
 16-byte aligned memory.

 Attaching a patch that changes the new() call in ::CreateBuffers() to
 av_malloc(), which returns 16-byte aligned memory.

 thanks
 jim

-- 
Ticket URL: <http://cvs.mythtv.org/trac/ticket/1041>
MythTV <http://www.mythtv.org/>
MythTV


More information about the mythtv-commits mailing list