RageSurface *RageMovieTextureDriver_FFMpeg::AVCodecCreateCompatibleSurface( int iTextureWidth, int iTextureHeight, bool bPreferHighColor, int &iAVTexfmt, MovieDecoderPixelFormatYCbCr &fmtout ) { FixLilEndian(); int iAVTexfmtIndex = FindCompatibleAVFormat( bPreferHighColor ); if( iAVTexfmtIndex == -1 ) iAVTexfmtIndex = FindCompatibleAVFormat( !bPreferHighColor ); if( iAVTexfmtIndex == -1 ) { /* No dice. Use the first avcodec format of the preferred bit depth, * and let the display system convert. */ for( iAVTexfmtIndex = 0; AVPixelFormats[iAVTexfmtIndex].bpp; ++iAVTexfmtIndex ) if( AVPixelFormats[iAVTexfmtIndex].bHighColor == bPreferHighColor ) break; ASSERT( AVPixelFormats[iAVTexfmtIndex].bpp != 0 ); } const AVPixelFormat_t *pfd = &AVPixelFormats[iAVTexfmtIndex]; iAVTexfmt = pfd->pf; fmtout = pfd->YUV; LOG->Trace( "Texture pixel format: %i %i (%ibpp, %08x %08x %08x %08x)", iAVTexfmt, fmtout, pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] ); if( pfd->YUV == PixelFormatYCbCr_YUYV422 ) iTextureWidth /= 2; return CreateSurface( iTextureWidth, iTextureHeight, pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] ); }
void MovieTexture_FFMpeg::CreateTexture() { if( m_uTexHandle ) return; CHECKPOINT; RageTextureID actualID = GetID(); actualID.iAlphaBits = 0; /* Cap the max texture size to the hardware max. */ actualID.iMaxSize = min( actualID.iMaxSize, DISPLAY->GetMaxTextureSize() ); m_iSourceWidth = decoder->m_stream->codec.width; m_iSourceHeight = decoder->m_stream->codec.height; /* image size cannot exceed max size */ m_iImageWidth = min( m_iSourceWidth, actualID.iMaxSize ); m_iImageHeight = min( m_iSourceHeight, actualID.iMaxSize ); /* Texture dimensions need to be a power of two; jump to the next. */ m_iTextureWidth = power_of_two(m_iImageWidth); m_iTextureHeight = power_of_two(m_iImageHeight); /* Bogus assignment to shut gcc up. */ RageDisplay::PixelFormat pixfmt = RageDisplay::FMT_RGBA8; bool PreferHighColor = (TEXTUREMAN->GetPrefs().m_iMovieColorDepth == 32); m_AVTexfmt = FindCompatibleAVFormat( pixfmt, PreferHighColor ); if( m_AVTexfmt == -1 ) m_AVTexfmt = FindCompatibleAVFormat( pixfmt, !PreferHighColor ); if( m_AVTexfmt == -1 ) { /* No dice. Use the first avcodec format of the preferred bit depth, * and let the display system convert. */ for( m_AVTexfmt = 0; AVPixelFormats[m_AVTexfmt].bpp; ++m_AVTexfmt ) if( AVPixelFormats[m_AVTexfmt].HighColor == PreferHighColor ) break; ASSERT( AVPixelFormats[m_AVTexfmt].bpp ); switch( TEXTUREMAN->GetPrefs().m_iMovieColorDepth ) { default: ASSERT(0); case 16: if( DISPLAY->SupportsTextureFormat(RageDisplay::FMT_RGB5) ) pixfmt = RageDisplay::FMT_RGB5; else pixfmt = RageDisplay::FMT_RGBA4; // everything supports RGBA4 break; case 32: if( DISPLAY->SupportsTextureFormat(RageDisplay::FMT_RGB8) ) pixfmt = RageDisplay::FMT_RGB8; else if( DISPLAY->SupportsTextureFormat(RageDisplay::FMT_RGBA8) ) pixfmt = RageDisplay::FMT_RGBA8; else if( DISPLAY->SupportsTextureFormat(RageDisplay::FMT_RGB5) ) pixfmt = RageDisplay::FMT_RGB5; else pixfmt = RageDisplay::FMT_RGBA4; // everything supports RGBA4 break; } } if( !m_img ) { const AVPixelFormat_t *pfd = &AVPixelFormats[m_AVTexfmt]; LOG->Trace("format %i, %08x %08x %08x %08x", pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3]); m_img = CreateSurface( m_iTextureWidth, m_iTextureHeight, pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] ); } m_uTexHandle = DISPLAY->CreateTexture( pixfmt, m_img, false ); }