Opened 14 years ago

Closed 14 years ago

#1041 closed defect (fixed)

VideoBuffers::CreateBuffers(), memory alignment, linuxppc and altivec

Reported by: jwestfall@… 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)

videobuffers.diff (1.0 KB) - added by jwestfall@… 14 years ago.
use av_malloc() in VideoBuffers::CreateBuffers?() instead of new

Download all attachments as: .zip

Change History (3)

Changed 14 years ago by jwestfall@…

Attachment: videobuffers.diff added

use av_malloc() in VideoBuffers::CreateBuffers?() instead of new

comment:1 Changed 14 years ago by danielk

Milestone: 0.19
Owner: changed from Isaac Richards to danielk
Status: newassigned
Version: head

comment:2 Changed 14 years ago by danielk

Resolution: fixed
Status: assignedclosed

(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.

Note: See TracTickets for help on using tickets.