diff --git a/Makefile b/Makefile index ad2759ff8..9cc7fac6e 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,10 @@ # # Uncomment next line for Windows static cross-compile build (mxe) #WINDOWS_STATIC=1 +# +# Uncomment the next line if you wish to use SFML to load images instead +# of FFmpeg (has no effect if NO_MOVIE=1) +#SFML_IMAGES=1 ############################### #FE_DEBUG=1 @@ -158,6 +162,7 @@ ifeq ($(WINDOWS_STATIC),1) LIBS += $(shell $(PKG_CONFIG) --static --libs sfml) CFLAGS += -DSFML_STATIC $(shell $(PKG_CONFIG) --static --cflags sfml) FE_WINDOWS_COMPILE=1 + else ifeq ($(NO_NET),1) @@ -170,12 +175,14 @@ else -lsfml-window \ -lsfml-network \ -lsfml-system - - _DEP += fe_net.hpp - _OBJ += fe_net.o endif endif +ifneq ($(NO_NET),1) + _DEP += fe_net.hpp + _OBJ += fe_net.o +endif + ifeq ($(FE_WINDOWS_COMPILE),1) CFLAGS += -mconsole EXE_EXT = .exe @@ -252,6 +259,10 @@ else _DEP += media.hpp _OBJ += media.o + ifeq ($(SFML_IMAGES),1) + FE_FLAGS += -DSFML_IMAGES + endif + CFLAGS += -I$(EXTLIBS_DIR)/audio/include AUDIO = $(OBJ_DIR)/libaudio.a endif diff --git a/src/fe_image.cpp b/src/fe_image.cpp index 7862b8792..a5badec69 100644 --- a/src/fe_image.cpp +++ b/src/fe_image.cpp @@ -275,56 +275,60 @@ bool FeTextureContainer::common_load( std::vector &image_names ) { bool loaded=false; + #ifndef NO_MOVIE + if ( m_video_flags & VF_DisableVideo ) + non_image_names.clear(); + +#ifndef SFML_IMAGES + while ( !image_names.empty() ) + { + non_image_names.push_back( image_names.back() ); + image_names.pop_back(); + } +#endif ASSERT( !m_movie ); // m_movie should always be empty at this point... - if ( !(m_video_flags & VF_DisableVideo) ) + std::string movie_file; + for ( std::vector::iterator itr = non_image_names.begin(); + itr != non_image_names.end(); ++itr ) { - std::string movie_file; - for ( std::vector::iterator itr = non_image_names.begin(); - itr != non_image_names.end(); ++itr ) + if ( FeMedia::is_supported_media_file( *itr ) ) { - if ( FeMedia::is_supported_media_file( *itr ) ) - { - movie_file = (*itr); - break; - } + movie_file = (*itr); + break; } + } - if ( !movie_file.empty() ) - { - m_movie = new FeMedia( FeMedia::AudioVideo ); + if ( !movie_file.empty() ) + { + m_movie = new FeMedia( FeMedia::AudioVideo ); - if (!m_movie->openFromFile( movie_file )) - { - std::cout << "ERROR loading video: " - << movie_file << std::endl; - } - else + if (!m_movie->openFromFile( movie_file, &m_texture )) + { + std::cout << "ERROR loading video: " + << movie_file << std::endl; + } + else + { + loaded = true; + m_file_name = movie_file; + + if ( !m_movie->is_multiframe() ) { - sf::Texture *t = m_movie->get_texture(); - ASSERT( t ); // openFromFile should create this! - if ( t ) t->setSmooth( m_texture.isSmooth() ); + m_movie_status = -1; // don't play if there is only one frame - loaded = true; - m_file_name = movie_file; - - if ( m_movie->number_of_frames() == 1 ) - { - m_movie_status = -1; // don't play if there is only one frame - - // if there is only one frame, then we can update the texture immediately - // (the frame will have been preloaded) and delete our movie object now - notify_texture_change(); - delete m_movie; - m_movie = NULL; - } - else if (m_video_flags & VF_NoAutoStart) - m_movie_status = 0; // 0=loaded but not on track to play - else - m_movie_status = 1; // 1=on track to be played + // if there is only one frame, then we can update the texture immediately + // (the frame will have been preloaded) and delete our movie object now + notify_texture_change(); + delete m_movie; + m_movie = NULL; } + else if (m_video_flags & VF_NoAutoStart) + m_movie_status = 0; // 0=loaded but not on track to play + else + m_movie_status = 1; // 1=on track to be played } } #endif @@ -351,14 +355,6 @@ bool FeTextureContainer::common_load( const sf::Texture &FeTextureContainer::get_texture() { -#ifndef NO_MOVIE - if ( m_movie ) - { - const sf::Texture *t = m_movie->get_texture(); - if ( t ) return *t; - } -#endif - return m_texture; } @@ -689,14 +685,6 @@ void FeTextureContainer::clear() void FeTextureContainer::set_smooth( bool s ) { -#ifndef NO_MOVIE - if ( m_movie ) - { - sf::Texture *t = m_movie->get_texture(); - if ( t ) - t->setSmooth( s ); - } -#endif m_texture.setSmooth( s ); } diff --git a/src/media.cpp b/src/media.cpp index 4dd19dbee..ca8a65f6d 100644 --- a/src/media.cpp +++ b/src/media.cpp @@ -157,8 +157,8 @@ class FeVideoImp : public FeBaseStream public: bool run_video_thread; sf::Time time_base; - sf::Texture display_texture; sf::Clock video_timer; + sf::Texture *display_texture; SwsContext *sws_ctx; int sws_flags; @@ -292,6 +292,7 @@ FeVideoImp::FeVideoImp( FeMedia *p ) m_video_thread( &FeVideoImp::video_thread, this ), m_parent( p ), run_video_thread( false ), + display_texture( NULL ), sws_ctx( NULL ), sws_flags( SWS_FAST_BILINEAR ), display_frame( NULL ) @@ -420,7 +421,7 @@ void FeVideoImp::preload() my_pict->linesize ); sf::Lock l( image_swap_mutex ); - display_texture.update( my_pict->data[0] ); + display_texture->update( my_pict->data[0] ); keep_going = false; @@ -679,13 +680,6 @@ void FeMedia::init_av() } } -sf::Texture *FeMedia::get_texture() -{ - if ( m_video ) - return &(m_video->display_texture); - return NULL; -} - sf::Time FeMedia::get_video_time() { // @@ -795,7 +789,7 @@ void FeMedia::setVolume(float volume) sf::SoundStream::setVolume( volume ); } -bool FeMedia::openFromFile( const std::string &name ) +bool FeMedia::openFromFile( const std::string &name, sf::Texture *outt ) { close(); init_av(); @@ -878,6 +872,9 @@ bool FeMedia::openFromFile( const std::string &name ) { m_format_ctx->streams[stream_id]->codec->workaround_bugs = FF_BUG_AUTODETECT; + // Note also: http://trac.ffmpeg.org/ticket/4404 + m_format_ctx->streams[stream_id]->codec->thread_count=1; + if ( avcodec_open2( m_format_ctx->streams[stream_id]->codec, dec, NULL ) < 0 ) { @@ -893,10 +890,9 @@ bool FeMedia::openFromFile( const std::string &name ) m_video->time_base = sf::seconds( av_q2d(m_format_ctx->streams[stream_id]->time_base) ); - m_video->display_texture = sf::Texture(); - m_video->display_texture.create( m_video->codec_ctx->width, + m_video->display_texture = outt; + m_video->display_texture->create( m_video->codec_ctx->width, m_video->codec_ctx->height ); - m_video->display_texture.setSmooth( true ); m_video->preload(); } } @@ -951,7 +947,7 @@ bool FeMedia::tick() sf::Lock l( m_video->image_swap_mutex ); if ( m_video->display_frame ) { - m_video->display_texture.update( m_video->display_frame ); + m_video->display_texture->update( m_video->display_frame ); m_video->display_frame = NULL; return true; } @@ -1174,12 +1170,20 @@ bool FeMedia::is_supported_media_file( const std::string &filename ) } -int FeMedia::number_of_frames() const +bool FeMedia::is_multiframe() const { if ( m_video && m_format_ctx ) - return m_format_ctx->streams[ m_video->stream_id ]->nb_frames; + { + if (( m_format_ctx->streams[ m_video->stream_id ]->nb_frames > 1 ) +#ifdef AV_CODEC_ID_APNG + || ( m_format_ctx->streams[ m_video->stream_id ]->id == AV_CODEC_ID_APNG ) +#endif + || ( m_format_ctx->streams[ m_video->stream_id ]->id == AV_CODEC_ID_GIF )) + return true; - return 0; + } + + return false; } sf::Time FeMedia::get_duration() const diff --git a/src/media.hpp b/src/media.hpp index 28eff9e75..4c2672a49 100644 --- a/src/media.hpp +++ b/src/media.hpp @@ -47,8 +47,8 @@ friend class FeVideoImp; FeMedia( Type t ); ~FeMedia(); - bool openFromFile( const std::string &name ); - sf::Texture *get_texture(); + bool openFromFile( const std::string &name, + sf::Texture *out_texture=NULL ); using sf::SoundStream::setPosition; using sf::SoundStream::getPosition; @@ -71,7 +71,7 @@ friend class FeVideoImp; void setVolume(float volume); bool is_playing(); - int number_of_frames() const; + bool is_multiframe() const; sf::Time get_video_time(); sf::Time get_duration() const;