X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ecd20d4a916884895dcd8873a9f1156e34f4ac89..ce0d1032d1c9e63bd034575542c5ee4337ab3510:/src/cocoa/mediactrl.mm diff --git a/src/cocoa/mediactrl.mm b/src/cocoa/mediactrl.mm index f350636a95..fa0ebb15b0 100644 --- a/src/cocoa/mediactrl.mm +++ b/src/cocoa/mediactrl.mm @@ -17,10 +17,6 @@ // Pre-compiled header stuff //--------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "mediactrl.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -51,6 +47,7 @@ //--------------------------------------------------------------------------- // QT Includes //--------------------------------------------------------------------------- +#include "wx/timer.h" #include #include "wx/cocoa/autorelease.h" @@ -102,6 +99,7 @@ public: NSMovieView* m_movieview; //NSMovieView instance wxControl* m_ctrl; //Parent control bool m_bVideo; //Whether or not we have video + class _wxQTTimer* m_timer; //Timer for streaming the movie DECLARE_DYNAMIC_CLASS(wxQTMediaBackend); }; @@ -115,12 +113,74 @@ public: IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend); +//Time between timer calls +#define MOVIE_DELAY 100 + +// -------------------------------------------------------------------------- +// wxQTTimer - Handle Asyncronous Playing +// -------------------------------------------------------------------------- +class _wxQTTimer : public wxTimer +{ +public: + _wxQTTimer(Movie movie, wxQTMediaBackend* parent) : + m_movie(movie), m_bPaused(false), m_parent(parent) + { + } + + ~_wxQTTimer() + { + } + + bool GetPaused() {return m_bPaused;} + void SetPaused(bool bPaused) {m_bPaused = bPaused;} + + //----------------------------------------------------------------------- + // _wxQTTimer::Notify + // + // 1) Checks to see if the movie is done, and if not continues + // streaming the movie + // 2) Sends the wxEVT_MEDIA_STOP event if we have reached the end of + // the movie. + //----------------------------------------------------------------------- + void Notify() + { + if (!m_bPaused) + { + if(!IsMovieDone(m_movie)) + MoviesTask(m_movie, MOVIE_DELAY); + else + { + wxMediaEvent theEvent(wxEVT_MEDIA_STOP, + m_parent->m_ctrl->GetId()); + m_parent->m_ctrl->ProcessEvent(theEvent); + + if(theEvent.IsAllowed()) + { + Stop(); + m_parent->Stop(); + wxASSERT(::GetMoviesError() == noErr); + + //send the event to our child + wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED, + m_parent->m_ctrl->GetId()); + m_parent->m_ctrl->ProcessEvent(theEvent); + } + } + } + } + +protected: + Movie m_movie; //Our movie instance + bool m_bPaused; //Whether we are paused or not + wxQTMediaBackend* m_parent; //Backend pointer +}; + //--------------------------------------------------------------------------- // wxQTMediaBackend Constructor // // Sets m_timer to NULL signifying we havn't loaded anything yet //--------------------------------------------------------------------------- -wxQTMediaBackend::wxQTMediaBackend() +wxQTMediaBackend::wxQTMediaBackend() : m_timer(NULL) { } @@ -135,10 +195,11 @@ wxQTMediaBackend::wxQTMediaBackend() //--------------------------------------------------------------------------- wxQTMediaBackend::~wxQTMediaBackend() { - Cleanup(); + if(m_timer) + Cleanup(); - //Note that ExitMovies() is not neccessary... - ::ExitMovies(); + //Note that ExitMovies() is not necessary... + ExitMovies(); } //--------------------------------------------------------------------------- @@ -174,7 +235,7 @@ bool wxQTMediaBackend::CreateControl(wxControl* inctrl, wxWindow* parent, parent->CocoaAddChild(ctrl); ctrl->SetInitialFrameRect(pos,size); } - + [theView showController:false adjustingSize:true]; m_movieview = theView; m_ctrl = ctrl; @@ -203,7 +264,8 @@ bool wxQTMediaBackend::Load(const wxString& fileName) //--------------------------------------------------------------------------- bool wxQTMediaBackend::Load(const wxURI& location) { - Cleanup(); + if(m_timer) + Cleanup(); wxString theURI = location.BuildURI(); @@ -212,6 +274,16 @@ bool wxQTMediaBackend::Load(const wxURI& location) m_movie = (Movie) [[m_movieview movie] QTMovie]; + //preroll movie for streaming + //TODO:Async this using threads? + TimeValue timeNow; + Fixed playRate; + timeNow = GetMovieTime(m_movie, NULL); + playRate = GetMoviePreferredRate(m_movie); + PrePrerollMovie(m_movie, timeNow, playRate, NULL, NULL); + PrerollMovie(m_movie, timeNow, playRate); + SetMovieRate(m_movie, playRate); + FinishLoad(); return ::GetMoviesError() == noErr; @@ -219,9 +291,20 @@ bool wxQTMediaBackend::Load(const wxURI& location) //--------------------------------------------------------------------------- // wxQTMediaBackend::FinishLoad +// +// 1) Create the movie timer +// 2) Get real size of movie for GetBestSize/sizers +// 3) See if there is video in the movie, and if so then either +// SetMovieGWorld if < 10.2 or use Native CreateMovieControl +// 4) Set the movie time scale to something usable so that seeking +// etc. will work correctly +// 5) Refresh parent window //--------------------------------------------------------------------------- void wxQTMediaBackend::FinishLoad() { + m_timer = new _wxQTTimer(m_movie, (wxQTMediaBackend*) this); + wxASSERT(m_timer); + //get the real size of the movie Rect outRect; ::GetMovieNaturalBoundsRect (m_movie, &outRect); @@ -237,7 +320,7 @@ void wxQTMediaBackend::FinishLoad() // //Here, if the parent of the control has a sizer - we //tell it to recalculate the size of this control since - //the user opened a seperate media file + //the user opened a separate media file // m_ctrl->InvalidateBestSize(); m_ctrl->GetParent()->Layout(); @@ -253,7 +336,9 @@ void wxQTMediaBackend::FinishLoad() //--------------------------------------------------------------------------- bool wxQTMediaBackend::Play() { - [m_movieview start:NULL]; + ::StartMovie(m_movie); + m_timer->SetPaused(false); + m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS); return ::GetMoviesError() == noErr; } @@ -265,7 +350,9 @@ bool wxQTMediaBackend::Play() //--------------------------------------------------------------------------- bool wxQTMediaBackend::Pause() { - [m_movieview stop:NULL]; + ::StopMovie(m_movie); + m_timer->SetPaused(true); + m_timer->Stop(); return ::GetMoviesError() == noErr; } @@ -278,8 +365,14 @@ bool wxQTMediaBackend::Pause() //--------------------------------------------------------------------------- bool wxQTMediaBackend::Stop() { - [m_movieview stop:NULL]; - [m_movieview gotoBeginning:NULL]; + m_timer->SetPaused(false); + m_timer->Stop(); + + ::StopMovie(m_movie); + if(::GetMoviesError() != noErr) + return false; + + ::GoToBeginningOfMovie(m_movie); return ::GetMoviesError() == noErr; } @@ -353,11 +446,12 @@ wxLongLong wxQTMediaBackend::GetDuration() //--------------------------------------------------------------------------- wxMediaState wxQTMediaBackend::GetState() { - if ( [m_movieview isPlaying] ) - return wxMEDIASTATE_PLAYING; - - if( wxQTMediaBackend::GetPosition() == 0 ) + if ( !m_timer || (m_timer->IsRunning() == false && + m_timer->GetPaused() == false) ) return wxMEDIASTATE_STOPPED; + + if( m_timer->IsRunning() == true ) + return wxMEDIASTATE_PLAYING; else return wxMEDIASTATE_PAUSED; } @@ -370,11 +464,11 @@ wxMediaState wxQTMediaBackend::GetState() //--------------------------------------------------------------------------- void wxQTMediaBackend::Cleanup() { - if([m_movieview movie]) - { - [[m_movieview movie] release]; - [m_movieview setMovie:NULL]; - } + delete m_timer; + m_timer = NULL; + + [[m_movieview movie] release]; + [m_movieview setMovie:NULL]; } //--------------------------------------------------------------------------- @@ -402,8 +496,3 @@ void wxQTMediaBackend::Move(int x, int y, int w, int h) FORCE_LINK_ME(basewxmediabackends); #endif //wxUSE_MEDIACTRL - - - - -