git-svn-id: https://openitg.svn.sourceforge.net/svnroot/openitg@32 83fadc84-e282...
authorPatrick McIlroy <itgpmc@gmail.com>
Wed, 20 Feb 2008 06:57:31 +0000 (06:57 +0000)
committerPatrick McIlroy <itgpmc@gmail.com>
Wed, 20 Feb 2008 06:57:31 +0000 (06:57 +0000)
src/arch/MovieTexture/MovieTexture_FFMpeg.cpp

index ae50174..5939d9d 100755 (executable)
@@ -1,3 +1,5 @@
+#define __STDC_CONSTANT_MACROS
+#include <stdint.h>
 #include "global.h"
 #include "MovieTexture_FFMpeg.h"
 
@@ -20,9 +22,31 @@ namespace avcodec
 #if defined(_WIN32)
 #include "ffmpeg/include/ffmpeg/avformat.h"
 #else
+extern "C"
+{
 #include <ffmpeg/avformat.h>
+}
 #endif
-};
+
+#if !defined(HAVE_IMG_CONVERT)
+extern "C"
+{
+#include <ffmpeg/swscale.h>
+}
+#endif // HAVE_IMG_CONVERT
+    void img_convert__(AVPicture *dst, int dst_pix_fmt,
+                       const AVPicture *src, int pix_fmt,
+                       int width, int height)
+    {
+#ifdef HAVE_IMG_CONVERT
+        img_convert(dst, dst_pix_fmt, src, pix_fmt, width, height);
+#else
+        static SwsContext* context = 0;
+        context = sws_getCachedContext(context, width, height, pix_fmt, width, height, dst_pix_fmt, 0, NULL, NULL, NULL);
+        sws_scale(context, const_cast<uint8_t**>(src->data), const_cast<int*>(src->linesize), 0, height, dst->data, dst->linesize);
+#endif // HAVE_IMG_CONVERT
+    }
+}
 
 #if defined(_MSC_VER)
        #pragma comment(lib, "ffmpeg/lib/avcodec.lib")
@@ -307,7 +331,11 @@ int FFMpeg_Helper::DecodePacket()
                if ( GetNextTimestamp )
                {
                        if (pkt.dts != int64_t(AV_NOPTS_VALUE))
-                               pts = (float)pkt.dts / AV_TIME_BASE;
+#if (LIBAVCODEC_BUILD >= 4754)
+                               pts = (float)pkt.dts * m_stream->time_base.num / m_stream->time_base.den;
+#else
+                               pts = (float)pkt.dts / AV_TIME_BASE;
+#endif
                        else
                                pts = -1;
                        GetNextTimestamp = false;
@@ -326,7 +354,11 @@ int FFMpeg_Helper::DecodePacket()
                 * 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_stream->codec, 
+#if (LIBAVCODEC_BUILD >= 4754)
+                               m_stream->codec, 
+#else
+                               &m_stream->codec, 
+#endif
                                &frame, &got_frame,
                                pkt.size? pkt.data:dummy, pkt.size );
                CHECKPOINT;
@@ -360,7 +392,11 @@ int FFMpeg_Helper::DecodePacket()
                }
 
                /* Length of this frame: */
-               LastFrameDelay = (float)m_stream->codec.frame_rate_base / m_stream->codec.frame_rate;
+#if (LIBAVCODEC_BUILD >= 4754)
+               LastFrameDelay = (float)m_stream->codec->time_base.num / m_stream->codec->time_base.den;
+#else
+               LastFrameDelay = (float)m_stream->codec.frame_rate_base / m_stream->codec.frame_rate;
+#endif
                LastFrameDelay += frame.repeat_pict * (LastFrameDelay * 0.5f);
 
                return 1;
@@ -377,10 +413,15 @@ void MovieTexture_FFMpeg::ConvertFrame()
        pict.data[0] = (unsigned char *)m_img->pixels;
        pict.linesize[0] = m_img->pitch;
 
-       avcodec::img_convert(&pict, AVPixelFormats[m_AVTexfmt].pf,
+#if (LIBAVCODEC_BUILD >= 4754)
+       avcodec::img_convert__(&pict, AVPixelFormats[m_AVTexfmt].pf,
+                       (avcodec::AVPicture *) &decoder->frame, decoder->m_stream->codec->pix_fmt, 
+                       decoder->m_stream->codec->width, decoder->m_stream->codec->height);
+#else
+       avcodec::img_convert__(&pict, AVPixelFormats[m_AVTexfmt].pf,
                        (avcodec::AVPicture *) &decoder->frame, decoder->m_stream->codec.pix_fmt, 
                        decoder->m_stream->codec.width, decoder->m_stream->codec.height);
-
+#endif
        m_ImageWaiting = FRAME_WAITING;
 }
 
@@ -389,8 +430,13 @@ static avcodec::AVStream *FindVideoStream( avcodec::AVFormatContext *m_fctx )
     for( int stream = 0; stream < m_fctx->nb_streams; ++stream )
        {
                avcodec::AVStream *enc = m_fctx->streams[stream];
+#if (LIBAVCODEC_BUILD >= 4754)
+        if( enc->codec->codec_type == avcodec::CODEC_TYPE_VIDEO )
+                       return enc;
+#else
         if( enc->codec.codec_type == avcodec::CODEC_TYPE_VIDEO )
                        return enc;
+#endif
        }
        return NULL;
 }
@@ -423,8 +469,13 @@ CString MovieTexture_FFMpeg::Init()
        if( sError != "" )
                return sError;
 
+#if (LIBAVCODEC_BUILD >= 4754)
+       LOG->Trace("Bitrate: %i", decoder->m_stream->codec->bit_rate );
+       LOG->Trace("Codec pixel format: %s", avcodec::avcodec_get_pix_fmt_name(decoder->m_stream->codec->pix_fmt) );
+#else
        LOG->Trace("Bitrate: %i", decoder->m_stream->codec.bit_rate );
        LOG->Trace("Codec pixel format: %s", avcodec::avcodec_get_pix_fmt_name(decoder->m_stream->codec.pix_fmt) );
+#endif
 
        /* Decode one frame, to guarantee that the texture is drawn when this function returns. */
        int ret = decoder->GetFrame();
@@ -483,7 +534,6 @@ static CString averr_ssprintf( int err, const char *fmt, ... )
        case AVERROR_INVALIDDATA:       Error = "invalid data found"; break;
        case AVERROR_NOMEM:                     Error = "not enough memory"; break;
        case AVERROR_NOFMT:                     Error = "unknown format"; break;
-       case AVERROR_UNKNOWN:           Error = "unknown error"; break;
        default: Error = ssprintf( "unknown error %i", err ); break;
        }
 
@@ -583,6 +633,17 @@ CString MovieTexture_FFMpeg::CreateDecoder()
        if ( stream == NULL )
                return ssprintf( "AVCodec (%s): Couldn't find any video streams", GetID().filename.c_str() );
 
+#if (LIBAVCODEC_BUILD >= 4754)
+       if( stream->codec->codec_id == avcodec::CODEC_ID_NONE )
+               return ssprintf( "AVCodec (%s): Unsupported codec %08x", GetID().filename.c_str(), stream->codec->codec_tag );
+
+       avcodec::AVCodec *codec = avcodec::avcodec_find_decoder( stream->codec->codec_id );
+       if( codec == NULL )
+               return ssprintf( "AVCodec (%s): Couldn't find decoder %i", GetID().filename.c_str(), stream->codec->codec_id );
+
+       LOG->Trace("Opening codec %s", codec->name );
+       ret = avcodec::avcodec_open( stream->codec, codec );
+#else
        if( stream->codec.codec_id == avcodec::CODEC_ID_NONE )
                return ssprintf( "AVCodec (%s): Unsupported codec %08x", GetID().filename.c_str(), stream->codec.codec_tag );
 
@@ -592,6 +653,7 @@ CString MovieTexture_FFMpeg::CreateDecoder()
 
        LOG->Trace("Opening codec %s", codec->name );
        ret = avcodec::avcodec_open( &stream->codec, codec );
+#endif
        if ( ret < 0 )
                return ssprintf( averr_ssprintf(ret, "AVCodec (%s): Couldn't open codec \"%s\"", GetID().filename.c_str(), codec->name) );
 
@@ -608,7 +670,11 @@ void MovieTexture_FFMpeg::DestroyDecoder()
 {
        if( decoder->m_stream )
        {
-               avcodec::avcodec_close( &decoder->m_stream->codec );
+#if (LIBAVCODEC_BUILD >= 4754)
+               avcodec::avcodec_close( decoder->m_stream->codec );
+#else
+               avcodec::avcodec_close( &decoder->m_stream->codec );
+#endif
                decoder->m_stream = NULL;
        }
 
@@ -649,8 +715,13 @@ void MovieTexture_FFMpeg::CreateTexture()
        /* Cap the max texture size to the hardware max. */
        actualID.iMaxSize = min( actualID.iMaxSize, DISPLAY->GetMaxTextureSize() );
 
+#if (LIBAVCODEC_BUILD >= 4754)
+       m_iSourceWidth  = decoder->m_stream->codec->width;
+       m_iSourceHeight = decoder->m_stream->codec->height;
+#else
        m_iSourceWidth  = decoder->m_stream->codec.width;
        m_iSourceHeight = decoder->m_stream->codec.height;
+#endif
 
        /* image size cannot exceed max size */
        m_iImageWidth = min( m_iSourceWidth, actualID.iMaxSize );
@@ -823,7 +894,11 @@ float MovieTexture_FFMpeg::CheckFrameTime()
                m_FrameSkipMode = true;
        }
 
+#if (LIBAVCODEC_BUILD >= 4754)
+       if( m_FrameSkipMode && decoder->m_stream->codec->frame_number % 2 )
+#else
        if( m_FrameSkipMode && decoder->m_stream->codec.frame_number % 2 )
+#endif
                return -1; /* skip */
        
        return 0;