Opened 18 years ago
Closed 18 years ago
#1041 closed defect (fixed)
VideoBuffers::CreateBuffers(), memory alignment, linuxppc and altivec
Reported by: | Owned by: | danielk | |
---|---|---|---|
Priority: | minor | Milestone: | 0.19 |
Component: | mythtv | Version: | head |
Severity: | medium | Keywords: | |
Cc: | Ticket locked: | no |
Description
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
Attachments (1)
Change History (3)
Changed 18 years ago by
Attachment: | videobuffers.diff added |
---|
comment:1 Changed 18 years ago by
Milestone: | → 0.19 |
---|---|
Owner: | changed from Isaac Richards to danielk |
Status: | new → assigned |
Version: | → head |
comment:2 Changed 18 years ago by
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
(In [8623]) Fixes #1041, by applying patch.
This changes the default video buffer allocator from "new" to av_malloc. "new" usually has an alignment equal to the largest non-SIMD register, while av_malloc has a 16 byte alignment, which is generally better. If someone needs a greater alignment, videobuffers allows the VideoOutput? class to allocate data itself. See VideoOutputXv? for an example.
use av_malloc() in VideoBuffers::CreateBuffers?() instead of new