T3D 1.1 Final - GuiTheoraCtrl causes access violations - RESOLVED (THREED-2594)
by Michael Reino · in Torque 3D Professional · 09/08/2011 (2:27 am) · 3 replies
Build: 1.1 Final
Platform: Windows XP 32
Target: Any use of GuiTheoraCtrl
Issue: The GuiTheoraCtrl has a bug that causes it to overwrite memory if the video resolution is larger than the texture mode allows.
Steps To Repeat: We discovered this bug by loading a 1280x720 ogv video with texture quality set to "Low". You should be able to duplicate the error by loading a video larger than 512x512 with texture quality set to "Lowest". The problem occurs in TheoraTexture::FrameReadItem::execute() because the dMemcpy() statements overwrite the texture buffer.
A simple work-around can be implemented to prevent the crash by changing the following lines in TheoraTexture::FrameReadItem::execute() from:
To:
This work-around just copies as much data as will fit in the texture from the middle of the video frame. It would be nice (although probably impractical) to see a loading solution that scales down the video frame to fit the allotted texture space.
Platform: Windows XP 32
Target: Any use of GuiTheoraCtrl
Issue: The GuiTheoraCtrl has a bug that causes it to overwrite memory if the video resolution is larger than the texture mode allows.
Steps To Repeat: We discovered this bug by loading a 1280x720 ogv video with texture quality set to "Low". You should be able to duplicate the error by loading a video larger than 512x512 with texture quality set to "Lowest". The problem occurs in TheoraTexture::FrameReadItem::execute() because the dMemcpy() statements overwrite the texture buffer.
A simple work-around can be implemented to prevent the crash by changing the following lines in TheoraTexture::FrameReadItem::execute() from:
GFXLockedRect* rect = mFrame->mLockedRect;
if( rect )
{
if( framePitch == rect->pitch )
dMemcpy( rect->bits, frame->data, rect->pitch * height );
else
{
// Scanline length does not match. Copy line by line.
U8* dst = rect->bits;
U8* src = ( U8* ) frame->data;
for( U32 i = 0; i < height; ++ i )
{
dMemcpy( dst, src, framePitch );
dst += rect->pitch;
src += framePitch;
}
}
}To:
GFXLockedRect* rect = mFrame->mLockedRect;
if( rect )
{
const U32 usePitch = getMin(framePitch, mFrame->mTexture->getWidth() * 4);
const U32 useHeight = getMin(height, mFrame->mTexture->getHeight());
if( (framePitch == rect->pitch) && (height == useHeight) )
dMemcpy( rect->bits, frame->data, rect->pitch * height );
else
{
// Scanline length does not match. Copy line by line.
U8* dst = rect->bits;
U8* src = ( U8* ) frame->data;
// Center the ogv if it is too big for the texture mode
if ( height > useHeight )
src += framePitch * ((height - useHeight) / 2);
if ( framePitch > usePitch )
src += (framePitch - usePitch) / 2;
for( U32 i = 0; i < useHeight; ++ i )
{
//dMemcpy( dst, src, framePitch );
dMemcpy( dst, src, usePitch );
dst += rect->pitch;
src += framePitch;
}
}
}This work-around just copies as much data as will fit in the texture from the middle of the video frame. It would be nice (although probably impractical) to see a loading solution that scales down the video frame to fit the allotted texture space.
#2
09/23/2011 (1:15 pm)
Michael, is there any way you can e-mail me the video that you were trying to use? I'm attempting to replicate the issue, but having trouble. I'm using a video that's 960X544 with the Texture Quality set to "lowest", and while the video occasionally flickers and only shows the top left corner of the video, I cannot get the engine to crash. I can better debug and tend to the issue if you can send me the video that's causing you problems. Send it to the e-mail in my GarageGames profile and I'll get to it immediately!
#3
10/11/2011 (2:49 pm)
Fixed in 1.2.
Torque 3D Owner Christopher Tauscher
Default Studio