Build the StepMania Source in Linux
Contents |
FFMpeg
Latest CVS
The latest CVS snapshot can be compiled using the build.sh (/stepmania/Utils/build.sh) script. The script will download the required ffmpeg version. It will then compile ffmpeg and then StepMania will be compiled by statically linking to the built ffmpeg. Pass --help to build.sh to see all of the options. You may need to run autogen.sh before running build.sh, if you checked the source out from CVS yourself.
3.9 and Older CVS
3.9 and 4.0 CVS won't compile correctly with FFMpeg 0.4.9_p20050906, the default version currently for Gentoo ~x86. I'm guessing 3.9 releases will suffer the same problem, but I haven't tested.
Glenn:
Here's the source I use, which is 0.4.9 with a backported patch to fix last-frame flushing (without which I forget exactly what happens, but I think the decoder ends up never receiving EOF, and ends up spinning):
http://zewt.org/~glenn/ffmpeg-0.4.9-pre1-sm.tar.gz
I think it should be configured with no options. It'll build only static libraries. Drop everything (*.o) in /usr/local/lib, copy in the includes (*.h), to ../include/ffmpeg. Copy everything under libav*, not just the root of ffmpeg. Be sure to recompile SM, and make sure that it picks up the right includes; if you have a distro-installed ffmpeg in /usr/include and they don't match, it'll probably explode. If the linker picks up shared libraries elsewhere, move the .so files out (just the symlink) and it should pick up the static archives.
ffmpeg patch for StepMania CVS
Index: src/arch/MovieTexture/MovieTexture_FFMpeg.cpp
===================================================================
RCS file: /cvsroot/stepmania/stepmania/src/arch/MovieTexture/MovieTexture_FFMpeg.cpp,v
retrieving revision 1.97
diff -u -r1.97 MovieTexture_FFMpeg.cpp
--- src/arch/MovieTexture/MovieTexture_FFMpeg.cpp 14 Feb 2006 11:40:24 -0000 1.97
+++ src/arch/MovieTexture/MovieTexture_FFMpeg.cpp 21 Mar 2006 06:09:31 -0000
@@ -166,8 +166,8 @@
int GetFrame( RageSurface *pOut, float fTargetTime );
- int GetWidth() const { return m_pStream->codec.width; }
- int GetHeight() const { return m_pStream->codec.height; }
+ int GetWidth() const { return m_pStream->codec->width; }
+ int GetHeight() const { return m_pStream->codec->height; }
RageSurface *CreateCompatibleSurface( int iTextureWidth, int iTextureHeight, bool bPreferHighColor );
@@ -332,8 +332,8 @@
bool bSkipThisFrame =
fTargetTime != -1 &&
- GetTimestamp() + GetFrameDuration() <= fTargetTime &&
- (m_pStream->codec.frame_number % 2) == 0;
+ GetTimestamp() + GetFrameDuration() <= fTargetTime &&
+ (m_pStream->codec->frame_number % 2) == 0;
int iGotFrame;
CHECKPOINT;
@@ -341,9 +341,9 @@
* to give it a buffer to read from since it tries to read anyway. */
static uint8_t dummy[FF_INPUT_BUFFER_PADDING_SIZE] = { 0 };
int len = avcodec::avcodec_decode_video(
- &m_pStream->codec,
+ m_pStream->codec,
&m_Frame, &iGotFrame,
- m_Packet.size? m_Packet.data:dummy, m_Packet.size );
+ m_Packet.size? m_Packet.data:dummy, m_Packet.size );
CHECKPOINT;
if( len < 0 )
@@ -375,7 +375,11 @@
}
/* Length of this frame: */
- m_fLastFrameDelay = (float)m_pStream->codec.frame_rate_base / m_pStream->codec.frame_rate;
+ /* FIXME - not sure how to get proper frame_rate,
+ it was disabled by the following patch:
+ http://www1.mplayerhq.hu/cgi-bin/cvsweb.cgi/ffmpeg/libavcodec/avcodec.h.diff?r1=1.392&r2=1.393&cvsroot=FFMpeg
+ */
+ m_fLastFrameDelay = (float)DEFAULT_FRAME_RATE_BASE / 30;
m_fLastFrameDelay += m_Frame.repeat_pict * (m_fLastFrameDelay * 0.5f);
++m_iFrameNumber;
@@ -416,8 +420,8 @@
pict.linesize[0] = pSurface->pitch;
avcodec::img_convert( &pict, m_AVTexfmt,
- (avcodec::AVPicture *) &m_Frame, m_pStream->codec.pix_fmt,
- m_pStream->codec.width, m_pStream->codec.height );
+ (avcodec::AVPicture *) &m_Frame, m_pStream->codec->pix_fmt,
+ m_pStream->codec->width, m_pStream->codec->height );
}
static avcodec::AVStream *FindVideoStream( avcodec::AVFormatContext *m_fctx )
@@ -425,7 +429,7 @@
for( int stream = 0; stream < m_fctx->nb_streams; ++stream )
{
avcodec::AVStream *enc = m_fctx->streams[stream];
- if( enc->codec.codec_type == avcodec::CODEC_TYPE_VIDEO )
+ if( enc->codec->codec_type == avcodec::CODEC_TYPE_VIDEO )
return enc;
}
return NULL;
@@ -549,21 +553,21 @@
if ( stream == NULL )
return ssprintf( "AVCodec (%s): Couldn't find any video streams", sFile.c_str() );
- if( stream->codec.codec_id == avcodec::CODEC_ID_NONE )
- return ssprintf( "AVCodec (%s): Unsupported codec %08x", sFile.c_str(), stream->codec.codec_tag );
+ if( stream->codec->codec_id == avcodec::CODEC_ID_NONE )
+ return ssprintf( "AVCodec (%s): Unsupported codec %08x", sFile.c_str(), stream->codec->codec_tag );
- avcodec::AVCodec *codec = avcodec::avcodec_find_decoder( stream->codec.codec_id );
+ avcodec::AVCodec *codec = avcodec::avcodec_find_decoder( stream->codec->codec_id );
if( codec == NULL )
- return ssprintf( "AVCodec (%s): Couldn't find decoder %i", sFile.c_str(), stream->codec.codec_id );
+ return ssprintf( "AVCodec (%s): Couldn't find decoder %i", sFile.c_str(), stream->codec->codec_id );
LOG->Trace("Opening codec %s", codec->name );
- ret = avcodec::avcodec_open( &stream->codec, codec );
+ ret = avcodec::avcodec_open( stream->codec, codec );
if ( ret < 0 )
return ssprintf( averr_ssprintf(ret, "AVCodec (%s): Couldn't open codec \"%s\"", sFile.c_str(), codec->name) );
m_pStream = stream;
- LOG->Trace( "Bitrate: %i", m_pStream->codec.bit_rate );
- LOG->Trace( "Codec pixel format: %s", avcodec::avcodec_get_pix_fmt_name(m_pStream->codec.pix_fmt) );
+ LOG->Trace( "Bitrate: %i", m_pStream->codec->bit_rate );
+ LOG->Trace( "Codec pixel format: %s", avcodec::avcodec_get_pix_fmt_name(m_pStream->codec->pix_fmt) );
return RString();
}
@@ -572,7 +576,7 @@
{
if( m_pStream )
{
- avcodec::avcodec_close( &m_pStream->codec );
+ avcodec::avcodec_close( m_pStream->codec );
m_pStream = NULL;
}
RTF:
When compiling under GCC4 a different patch is needed. http://www.linuxfromscratch.org/blfs/downloads/svn/ffmpeg-0.4.9-pre1-gcc4-1.patch Untar the original ffmpeg-0.4.9-pre1 source, drop patch into ffmpeg root, use "patch -p1 <ffmpeg-0.4.9-pre1-gcc4-1.patch" and then a default configure. Then follow Glenn's compile instructions. (I clarified some things he said since they confused me as an inexperienced compile-fixer)
Lua
For Lua, just use any standard 5.0 (not 5.1) installation, which should include static libraries. If you have lua-config or lua-config50, the autoconf script should probably use static libraries automatically (see autoconf/m4/lua.m4: "lua-config50 --static" should tell it how to link them); since it didn't do this for you, you might need to do the same as above (move the .so files out so it can't find them).
Compare the ldd output of the resulting binary; it should be identical to rc2a (the hex offsets may be different). If it's different, you're pulling in different libraries, and we should figure out why.

