From 26660110e5f900c5ca93993b212fec66c390b0bd Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 17 Dec 2012 00:20:56 -0800 Subject: [PATCH] Allow building the video player without ffmpeg (playVideo will always throw an exception) --- apps/openmw/mwrender/videoplayer.cpp | 122 ++++++++++++++++++--------- apps/openmw/mwrender/videoplayer.hpp | 22 ++--- 2 files changed, 89 insertions(+), 55 deletions(-) diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index 3e1701095f..9c4546d15a 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -1,5 +1,15 @@ #include "videoplayer.hpp" +#define __STDC_CONSTANT_MACROS +#include + +#include +#include + +#include +#include + +#include #include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" @@ -8,17 +18,24 @@ #include "../mwsound/sound.hpp" +namespace MWRender +{ + +#ifdef OPENMW_USE_FFMPEG + +extern "C" +{ +#include +#include +#include +} + #define MAX_AUDIOQ_SIZE (5 * 16 * 1024) #define MAX_VIDEOQ_SIZE (5 * 256 * 1024) #define AV_SYNC_THRESHOLD 0.01 -#define SAMPLE_CORRECTION_PERCENT_MAX 10 #define AUDIO_DIFF_AVG_NB 20 #define VIDEO_PICTURE_QUEUE_SIZE 1 - -namespace MWRender -{ - enum { AV_SYNC_AUDIO_MASTER, AV_SYNC_VIDEO_MASTER, @@ -27,6 +44,7 @@ enum { AV_SYNC_DEFAULT = AV_SYNC_EXTERNAL_MASTER }; + struct PacketQueue { PacketQueue() : first_pkt(NULL), last_pkt(NULL), flushing(false), nb_packets(0), size(0) @@ -66,16 +84,21 @@ struct VideoState { video_clock(0.0), sws_context(NULL), rgbaFrame(NULL), pictq_size(0), pictq_rindex(0), pictq_windex(0) , refresh_rate_ms(10), refresh(false), quit(false), display_ready(false) - { } + { + // Register all formats and codecs + av_register_all(); + } ~VideoState() - { } + { deinit(); } void init(const std::string& resourceName); void deinit(); int stream_open(int stream_index, AVFormatContext *pFormatCtx); + bool update(Ogre::MaterialPtr &mat, Ogre::Rectangle2D *rect, int screen_width, int screen_height); + static void video_thread_loop(VideoState *is); static void decode_thread_loop(VideoState *is); @@ -791,6 +814,35 @@ void VideoState::decode_thread_loop(VideoState *self) } +bool VideoState::update(Ogre::MaterialPtr &mat, Ogre::Rectangle2D *rect, int screen_width, int screen_height) +{ + if(this->quit) + return false; + + if(this->refresh) + { + this->refresh = false; + this->video_refresh_timer(); + // Would be nice not to do this all the time... + if(this->display_ready) + mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("VideoTexture"); + + // Correct aspect ratio by adding black bars + double videoaspect = av_q2d((*this->video_st)->codec->sample_aspect_ratio); + if(videoaspect == 0.0) + videoaspect = 1.0; + videoaspect *= static_cast((*this->video_st)->codec->width) / (*this->video_st)->codec->height; + + double screenaspect = static_cast(screen_width) / screen_height; + double aspect_correction = videoaspect / screenaspect; + + rect->setCorners(std::max(-1.0, -1.0 * aspect_correction), std::min( 1.0, 1.0 / aspect_correction), + std::min( 1.0, 1.0 * aspect_correction), std::max(-1.0, -1.0 / aspect_correction)); + } + return true; +} + + int VideoState::stream_open(int stream_index, AVFormatContext *pFormatCtx) { MWSound::DecoderPtr decoder; @@ -899,12 +951,7 @@ void VideoState::init(const std::string& resourceName) this->parse_thread = boost::thread(decode_thread_loop, this); } - catch(std::runtime_error& e) - { - this->quit = true; - throw; - } - catch(Ogre::Exception& e) + catch(...) { this->quit = true; throw; @@ -913,6 +960,8 @@ void VideoState::init(const std::string& resourceName) void VideoState::deinit() { + this->quit = true; + this->audioq.cond.notify_one(); this->videoq.cond.notify_one(); @@ -939,6 +988,27 @@ void VideoState::deinit() } } +#else // defined OPENMW_USE_FFMPEG + +class VideoState +{ +public: + VideoState() { } + + void init(const std::string& resourceName) + { + throw std::runtime_error("FFmpeg not supported, cannot play video \""+resourceName+"\""); + } + void deinit() { } + + void close() { } + + bool update(Ogre::MaterialPtr &mat, Ogre::Rectangle2D *rect, int screen_width, int screen_height) + { return false; } +}; + +#endif // defined OPENMW_USE_FFMPEG + VideoPlayer::VideoPlayer(Ogre::SceneManager* sceneMgr) : mState(NULL) @@ -1009,9 +1079,6 @@ VideoPlayer::~VideoPlayer() void VideoPlayer::playVideo(const std::string &resourceName) { - // Register all formats and codecs - av_register_all(); - if(mState) close(); @@ -1041,34 +1108,13 @@ void VideoPlayer::update () { if(mState) { - if(mState->quit) + if(!mState->update(mVideoMaterial, mRectangle, mWidth, mHeight)) close(); - else if(mState->refresh) - { - mState->refresh = false; - mState->video_refresh_timer(); - // Would be nice not to do this all the time... - if(mState->display_ready) - mVideoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("VideoTexture"); - - // Correct aspect ratio by adding black bars - double videoaspect = av_q2d((*mState->video_st)->codec->sample_aspect_ratio); - if(videoaspect == 0.0) - videoaspect = 1.0; - videoaspect *= static_cast((*mState->video_st)->codec->width) / (*mState->video_st)->codec->height; - - double screenaspect = static_cast(mWidth) / mHeight; - double aspect_correction = videoaspect / screenaspect; - - mRectangle->setCorners(std::max(-1.0, -1.0 * aspect_correction), std::min( 1.0, 1.0 / aspect_correction), - std::min( 1.0, 1.0 * aspect_correction), std::max(-1.0, -1.0 / aspect_correction)); - } } } void VideoPlayer::close() { - mState->quit = true; mState->deinit(); delete mState; diff --git a/apps/openmw/mwrender/videoplayer.hpp b/apps/openmw/mwrender/videoplayer.hpp index c82a16e15a..d8c1902aa4 100644 --- a/apps/openmw/mwrender/videoplayer.hpp +++ b/apps/openmw/mwrender/videoplayer.hpp @@ -1,27 +1,15 @@ #ifndef VIDEOPLAYER_H #define VIDEOPLAYER_H -#include -#include +#include -#include - - -#define __STDC_CONSTANT_MACROS -#include -extern "C" +namespace Ogre { -#include -#include -#include + class SceneManager; + class SceneNode; + class Rectangle2D; } -#include -#include - -#include "../mwbase/soundmanager.hpp" - - namespace MWRender { struct VideoState;