// 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"
//---------------------------------------------------------------------------
// QT Includes
//---------------------------------------------------------------------------
+#include "wx/timer.h"
#include <QuickTime/QuickTime.h>
#include "wx/cocoa/autorelease.h"
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);
};
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)
{
}
//---------------------------------------------------------------------------
wxQTMediaBackend::~wxQTMediaBackend()
{
- Cleanup();
+ if(m_timer)
+ Cleanup();
- //Note that ExitMovies() is not neccessary...
- ::ExitMovies();
+ //Note that ExitMovies() is not necessary...
+ ExitMovies();
}
//---------------------------------------------------------------------------
parent->CocoaAddChild(ctrl);
ctrl->SetInitialFrameRect(pos,size);
}
-
+
[theView showController:false adjustingSize:true];
m_movieview = theView;
m_ctrl = ctrl;
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Load(const wxURI& location)
{
- Cleanup();
+ if(m_timer)
+ Cleanup();
wxString theURI = location.BuildURI();
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;
//---------------------------------------------------------------------------
// 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);
//
//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();
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Play()
{
- [m_movieview start:NULL];
+ ::StartMovie(m_movie);
+ m_timer->SetPaused(false);
+ m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
return ::GetMoviesError() == noErr;
}
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Pause()
{
- [m_movieview stop:NULL];
+ ::StopMovie(m_movie);
+ m_timer->SetPaused(true);
+ m_timer->Stop();
return ::GetMoviesError() == noErr;
}
//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------
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];
}
//---------------------------------------------------------------------------
FORCE_LINK_ME(basewxmediabackends);
#endif //wxUSE_MEDIACTRL
-
-
-
-
-