1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/mediactrl.cpp
3 // Purpose: wxMediaCtrl MSW
4 // Author: Ryan Norton <wxprojects@comcast.net>
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 //---------------------------------------------------------------------------
14 //---------------------------------------------------------------------------
16 //#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
17 //#pragma implementation "moviectrl.h"
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 #include "wx/mediactrl.h"
31 //###########################################################################
33 //###########################################################################
35 IMPLEMENT_CLASS(wxMediaCtrl
, wxControl
);
36 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent
, wxEvent
);
37 DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED
);
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 wxMediaCtrlImpl() : m_bLoaded(false)
49 virtual ~wxMediaCtrlImpl()
52 virtual bool Create(wxMediaCtrl
* WXUNUSED(ctrl
))
55 virtual bool Play() { return false; }
56 virtual bool Pause() { return false; }
57 virtual bool Stop() { return false; }
59 virtual bool Load(const wxString
&) { return false; }
60 virtual bool Load(const wxURI
&) { return false; }
62 virtual wxMediaState
GetState() { return wxMEDIASTATE_STOPPED
; }
64 virtual bool SetPosition(long) { return 0; }
65 virtual long GetPosition() { return 0; }
66 virtual long GetDuration() { return 0; }
68 virtual void DoMoveWindow(int, int, int, int) { }
69 virtual wxSize
DoGetBestSize() const { return wxSize(0,0); }
71 virtual double GetPlaybackRate() { return 0; }
72 virtual bool SetPlaybackRate(double) { return false; }
74 virtual bool MSWWindowProc(WXUINT
, WXWPARAM
, WXLPARAM
) { return false; }
82 //---------------------------------------------------------------------------
84 //---------------------------------------------------------------------------
90 #define WM_GRAPHNOTIFY WM_USER+13
93 #define wxDSVERIFY(x) wxASSERT( SUCCEEDED ((x)) )
95 #define wxDSVERIFY(x) (x)
98 class wxDXMediaCtrlImpl
: public wxMediaCtrlImpl
103 virtual ~wxDXMediaCtrlImpl();
105 virtual bool Create(wxMediaCtrl
* ctrl
);
108 virtual bool Pause();
111 virtual bool Load(const wxString
& fileName
);
112 virtual bool Load(const wxURI
& location
);
114 virtual wxMediaState
GetState();
116 virtual bool SetPosition(long where
);
117 virtual long GetPosition();
118 virtual long GetDuration();
120 virtual void DoMoveWindow(int x
, int y
, int w
, int h
);
121 wxSize
DoGetBestSize() const;
123 virtual double GetPlaybackRate();
124 virtual bool SetPlaybackRate(double);
130 bool MSWWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
);
134 IGraphBuilder
* m_pGB
;
135 IMediaControl
* m_pMC
;
136 IMediaEventEx
* m_pME
;
140 IMediaSeeking
* m_pMS
;
145 #endif //wxUSE_DIRECTSHOW
147 //---------------------------------------------------------------------------
148 // wxWMMEMediaCtrlImpl
149 //---------------------------------------------------------------------------
151 #include <mmsystem.h>
152 #include <digitalv.h>
154 class wxWMMEMediaCtrlImpl
: public wxMediaCtrlImpl
158 wxWMMEMediaCtrlImpl();
159 ~wxWMMEMediaCtrlImpl();
161 virtual bool Create(wxMediaCtrl
* ctrl
);
164 virtual bool Pause();
167 virtual bool Load(const wxString
& fileName
);
168 virtual bool Load(const wxURI
& location
);
170 virtual wxMediaState
GetState();
172 virtual bool SetPosition(long where
);
173 virtual long GetPosition();
174 virtual long GetDuration();
176 virtual void DoMoveWindow(int x
, int y
, int w
, int h
);
177 wxSize
DoGetBestSize() const;
179 virtual double GetPlaybackRate();
180 virtual bool SetPlaybackRate(double);
187 //---------------------------------------------------------------------------
188 // wxAVIFileMediaCtrlImpl
189 //---------------------------------------------------------------------------
193 //#pragma comment(lib, "vfw32.lib")
195 class wxAVIFileMediaCtrlImpl : public wxMediaCtrlImpl
199 wxAVIFileMediaCtrlImpl();
200 ~wxAVIFileMediaCtrlImpl();
202 virtual bool Create(wxMediaCtrl* ctrl);
205 virtual bool Pause();
208 virtual bool Load(const wxString& fileName);
209 virtual bool Load(const wxURI& location);
211 virtual wxMediaState GetState();
213 virtual bool SetPosition(long where);
214 virtual long GetPosition();
215 virtual long GetDuration();
217 virtual void DoMoveWindow(int x, int y, int w, int h);
218 wxSize DoGetBestSize() const;
220 virtual double GetPlaybackRate();
221 virtual bool SetPlaybackRate(double);
229 //###########################################################################
233 //###########################################################################
235 //---------------------------------------------------------------------------
239 //---------------------------------------------------------------------------
241 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
, const wxString
& fileName
,
242 const wxPoint
& pos
, const wxSize
& size
,
243 long style
, long WXUNUSED(driver
), const wxString
& name
)
246 if ( !wxControl::Create(parent
, id
, pos
, size
, (style
| wxNO_BORDER
) | wxCLIP_CHILDREN
,
247 wxDefaultValidator
, name
) )
250 //Set our background color to black by default
251 SetBackgroundColour(*wxBLACK
);
254 m_imp
= new wxDXMediaCtrlImpl
;
255 if(!m_imp
->Create(this))
259 m_imp
= new wxWMMEMediaCtrlImpl
;
260 if(!m_imp
->Create(this))
270 if(!fileName
.empty())
279 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
, const wxURI
& location
,
280 const wxPoint
& pos
, const wxSize
& size
,
281 long style
, long WXUNUSED(driver
), const wxString
& name
)
284 if ( !wxControl::Create(parent
, id
, pos
, size
, (style
| wxNO_BORDER
) | wxCLIP_CHILDREN
,
285 wxDefaultValidator
, name
) )
288 //Set our background color to black by default
289 SetBackgroundColour(*wxBLACK
);
292 m_imp
= new wxDXMediaCtrlImpl
;
293 if(!m_imp
->Create(this))
297 m_imp
= new wxWMMEMediaCtrlImpl
;
298 if(!m_imp
->Create(this))
314 bool wxMediaCtrl::Load(const wxString
& fileName
)
317 return m_imp
->Load(fileName
);
321 bool wxMediaCtrl::Load(const wxURI
& location
)
324 return m_imp
->Load(location
);
328 bool wxMediaCtrl::Play()
330 if(m_imp
&& m_imp
->IsLoaded())
331 return m_imp
->Play();
335 bool wxMediaCtrl::Pause()
337 if(m_imp
&& m_imp
->IsLoaded())
338 return m_imp
->Pause();
342 bool wxMediaCtrl::Stop()
344 if(m_imp
&& m_imp
->IsLoaded())
345 return m_imp
->Stop();
349 double wxMediaCtrl::GetPlaybackRate()
351 if(m_imp
&& m_imp
->IsLoaded())
352 return m_imp
->GetPlaybackRate();
356 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
358 if(m_imp
&& m_imp
->IsLoaded())
359 return m_imp
->SetPlaybackRate(dRate
);
363 bool wxMediaCtrl::SetPosition(long where
)
365 if(m_imp
&& m_imp
->IsLoaded())
366 return m_imp
->SetPosition(where
);
370 long wxMediaCtrl::GetPosition()
372 if(m_imp
&& m_imp
->IsLoaded())
373 return m_imp
->GetPosition();
377 long wxMediaCtrl::GetDuration()
379 if(m_imp
&& m_imp
->IsLoaded())
380 return m_imp
->GetDuration();
384 wxMediaState
wxMediaCtrl::GetState()
386 if(m_imp
&& m_imp
->IsLoaded())
387 return m_imp
->GetState();
388 return wxMEDIASTATE_STOPPED
;
391 WXLRESULT
wxMediaCtrl::MSWWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
)
393 if(m_imp
&& m_imp
->IsLoaded() && m_imp
->MSWWindowProc(nMsg
, wParam
, lParam
) )
394 return wxControl::MSWDefWindowProc(nMsg
, wParam
, lParam
);
395 //pass the event to our parent
396 return wxControl::MSWWindowProc(nMsg
, wParam
, lParam
);
399 wxSize
wxMediaCtrl::DoGetBestSize() const
401 if(m_imp
&& m_imp
->IsLoaded())
402 return m_imp
->DoGetBestSize();
406 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
408 wxControl::DoMoveWindow(x
,y
,w
,h
);
410 if(m_imp
&& m_imp
->IsLoaded())
411 m_imp
->DoMoveWindow(x
, y
, w
, h
);
414 wxMediaCtrl::~wxMediaCtrl()
421 //---------------------------------------------------------------------------
425 //---------------------------------------------------------------------------
429 wxDXMediaCtrlImpl::wxDXMediaCtrlImpl() : m_pGB(NULL
)
433 bool wxDXMediaCtrlImpl::Create(wxMediaCtrl
* ctrl
)
435 //create our filter graph
436 HRESULT hr
= CoCreateInstance(CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
,
437 IID_IGraphBuilder
, (void**)&m_pGB
);
439 //directshow not installed?
448 #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
450 bool wxDXMediaCtrlImpl::Load(const wxString
& fileName
)
457 CoCreateInstance(CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
,
458 IID_IGraphBuilder
, (void**)&m_pGB
);
460 //load the graph & render
461 if( FAILED(m_pGB
->RenderFile(fileName
.wc_str(wxConvLocal
), NULL
)) )
464 //get the interfaces, all of them
465 wxDSVERIFY( m_pGB
->QueryInterface(IID_IMediaControl
, (void**)&m_pMC
) );
466 wxDSVERIFY( m_pGB
->QueryInterface(IID_IMediaEventEx
, (void**)&m_pME
) );
467 wxDSVERIFY( m_pGB
->QueryInterface(IID_IMediaSeeking
, (void**)&m_pMS
) );
468 wxDSVERIFY( m_pGB
->QueryInterface(IID_IVideoWindow
, (void**)&m_pVW
) );
469 wxDSVERIFY( m_pGB
->QueryInterface(IID_IBasicAudio
, (void**)&m_pBA
) );
470 wxDSVERIFY( m_pGB
->QueryInterface(IID_IBasicVideo
, (void**)&m_pBV
) );
473 //pBA->get_Volume(&lVolume);
476 //get the _actual_ size of the movie & remember it
477 long nX
, nY
, nSX
, nSY
;
478 if (FAILED(m_pVW
->GetWindowPosition(&nX
,&nY
,&nSX
,&nSY
)))
494 wxDSVERIFY( m_pVW
->put_Owner((OAHWND
)m_ctrl
->GetHandle()) );
495 wxDSVERIFY( m_pVW
->put_WindowStyle(WS_CHILD
| WS_CLIPSIBLINGS
) );
496 wxDSVERIFY( m_pVW
->put_Visible(OATRUE
) ); //OATRUE == -1
499 //make it so that wxEVT_MOVIE_FINISHED works
500 wxDSVERIFY( m_pME
->SetNotifyWindow((OAHWND
)m_ctrl
->GetHandle(), WM_GRAPHNOTIFY
, 0) );
502 //set the time format
503 wxDSVERIFY( m_pMS
->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME
) );
505 //so that DoGetBestSize will work :)
508 //work around refresh issues
509 m_ctrl
->InvalidateBestSize();
510 m_ctrl
->GetParent()->Layout();
511 m_ctrl
->GetParent()->Refresh();
512 m_ctrl
->GetParent()->Update();
517 bool wxDXMediaCtrlImpl::Load(const wxURI
& location
)
519 return Load(location
.BuildUnescapedURI());
522 bool wxDXMediaCtrlImpl::Play()
524 return SUCCEEDED( m_pMC
->Run() );
527 bool wxDXMediaCtrlImpl::Pause()
529 return SUCCEEDED( m_pMC
->Pause() );
532 bool wxDXMediaCtrlImpl::Stop()
534 bool bOK
= SUCCEEDED( m_pMC
->Stop() );
536 //We don't care if it can't get to the beginning in directshow -
537 //it could be a non-seeking filter (wince midi) in which case playing
538 //starts all over again
543 bool wxDXMediaCtrlImpl::SetPosition(long where
)
545 //DS uses 100 nanos - so we need a 10 mult
546 LONGLONG pos
= ((LONGLONG
)where
) * 10000;
548 return SUCCEEDED( m_pMS
->SetPositions(
550 AM_SEEKING_AbsolutePositioning
,
552 AM_SEEKING_NoPositioning
556 long wxDXMediaCtrlImpl::GetPosition()
558 LONGLONG outCur
, outStop
;
559 wxDSVERIFY( m_pMS
->GetPositions(&outCur
, &outStop
) );
561 //h,m,s,milli - outdur is in 100 nanos
565 long wxDXMediaCtrlImpl::GetDuration()
567 LONGLONG outDuration
;
568 wxDSVERIFY( m_pMS
->GetDuration(&outDuration
) );
570 //h,m,s,milli - outdur is in 100 nanos
571 return outDuration
/10000;
574 wxMediaState
wxDXMediaCtrlImpl::GetState()
576 //TODO: MS recommends against INFINITE here - do it in stages
578 OAFilterState theState
;
579 hr
= m_pMC
->GetState(INFINITE
, &theState
);
581 wxASSERT( SUCCEEDED(hr
) );
583 //MSW state is the same as ours
585 //State_Paused = State_Stopped + 1,
586 //State_Running = State_Paused + 1
588 return (wxMediaState
) theState
;
591 double wxDXMediaCtrlImpl::GetPlaybackRate()
594 wxDSVERIFY( m_pMS
->GetRate(&dRate
) );
598 bool wxDXMediaCtrlImpl::SetPlaybackRate(double dRate
)
600 return SUCCEEDED( m_pMS
->SetRate(dRate
) );
603 bool wxDXMediaCtrlImpl::MSWWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
)
605 if (nMsg
== WM_GRAPHNOTIFY
)
607 LONG evCode
, evParam1
, evParam2
;
610 // Process all queued events
611 while(SUCCEEDED(m_pME
->GetEvent(&evCode
, (LONG_PTR
*) &evParam1
,
612 (LONG_PTR
*) &evParam2
, 0)
616 // Free memory associated with callback, since we're not using it
617 hr
= m_pME
->FreeEventParams(evCode
, evParam1
, evParam2
);
619 // If this is the end of the clip, notify handler
620 if(EC_COMPLETE
== evCode
)
622 //Interestingly enough, DirectShow does not actually stop
623 //the filters - even when it reaches the end!
630 wxMediaEvent
theEvent(wxEVT_MEDIA_FINISHED
, m_ctrl
->GetId());
631 m_ctrl
->GetParent()->ProcessEvent(theEvent
);
639 void wxDXMediaCtrlImpl::Cleanup()
641 // Hide then disown the window
644 m_pVW
->put_Visible(OAFALSE
); //OSFALSE == 0
645 m_pVW
->put_Owner(NULL
);
648 // Release and zero DirectShow interfaces
657 wxDXMediaCtrlImpl::~wxDXMediaCtrlImpl()
665 wxSize
wxDXMediaCtrlImpl::DoGetBestSize() const
670 void wxDXMediaCtrlImpl::DoMoveWindow(int x
, int y
, int w
, int h
)
672 if(m_bLoaded
&& m_bVideo
)
674 wxDSVERIFY( m_pVW
->SetWindowPosition(0, 0, w
, h
) );
678 #endif //wxUSE_DIRECTSHOW
680 //---------------------------------------------------------------------------
682 // wxWMMEMediaCtrlImpl
684 //---------------------------------------------------------------------------
686 wxWMMEMediaCtrlImpl::wxWMMEMediaCtrlImpl() : m_bVideo(false)
691 wxWMMEMediaCtrlImpl::~wxWMMEMediaCtrlImpl()
693 mciSendCommand(m_hDev
, MCI_CLOSE
, 0, 0);
696 bool wxWMMEMediaCtrlImpl::Create(wxMediaCtrl
* ctrl
)
702 bool wxWMMEMediaCtrlImpl::Play()
704 return (mciSendCommand(m_hDev
, MCI_PLAY
, 0, 0) == 0) ||
705 (mciSendCommand(m_hDev
, MCI_RESUME
, 0, 0) == 0);
708 bool wxWMMEMediaCtrlImpl::Pause()
710 return (mciSendCommand(m_hDev
, MCI_PAUSE
, MCI_WAIT
, 0) == 0);
713 bool wxWMMEMediaCtrlImpl::Stop()
715 return (mciSendCommand(m_hDev
, MCI_STOP
, MCI_WAIT
, 0) == 0) &&
716 SetPosition(GetDuration());
721 bool wxWMMEMediaCtrlImpl::Load(const wxString
& fileName
)
724 mciSendCommand(m_hDev
, MCI_CLOSE
, 0, 0);
726 MCI_OPEN_PARMS openParms
;
727 MCI_SET_PARMS setParms
;
729 memset(&openParms
, 0, sizeof(MCI_DGV_OPEN_PARMS
));
730 openParms
.lpstrElementName
= (wxChar
*) fileName
.c_str();
734 for(size_t i
= MCI_DEVTYPE_FIRST
; i
<= MCI_DEVTYPE_LAST
; ++i
)
736 openParms
.lpstrDeviceType
= (LPSTR
)i
;
740 if ((nError
= mciSendCommand(0, MCI_OPEN
,
741 MCI_OPEN_ELEMENT
|MCI_OPEN_ELEMENT
|MCI_OPEN_TYPE
|MCI_OPEN_TYPE_ID
,
742 (DWORD
)(LPVOID
)&openParms
)) == 0)
752 m_hDev
= openParms
.wDeviceID
;
755 setParms
.dwCallback
= 0;
756 setParms
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
758 if (mciSendCommand(m_hDev
, MCI_SET
, MCI_SET_TIME_FORMAT
,
759 (DWORD
)(LPVOID
)&setParms
) != 0)
763 //TODO: Does this work?
765 MCI_DGV_WINDOW_PARMS windowParms;
767 windowParms.hWnd = (HWND)m_ctrl->GetHWND();
768 m_bVideo = (mciSendCommand(m_hDev, MCI_WINDOW,
769 MCI_DGV_WINDOW_HWND, (DWORD)(LPVOID)&windowParms) == 0);
776 bool wxWMMEMediaCtrlImpl::Load(const wxURI
& WXUNUSED(location
))
781 wxMediaState
wxWMMEMediaCtrlImpl::GetState()
783 MCI_STATUS_PARMS statusParms
;
784 statusParms
.dwItem
= MCI_STATUS_MODE
;
785 mciSendCommand(m_hDev
, MCI_STATUS
, MCI_STATUS_ITEM
,
786 (DWORD
)(LPVOID
)&statusParms
);
788 if(statusParms
.dwReturn
== MCI_MODE_PAUSE
)
789 return wxMEDIASTATE_PAUSED
;
790 else if(statusParms
.dwReturn
== MCI_MODE_PLAY
)
791 return wxMEDIASTATE_PLAYING
;
793 return wxMEDIASTATE_STOPPED
;
796 bool wxWMMEMediaCtrlImpl::SetPosition(long where
)
798 MCI_SEEK_PARMS seekParms
;
799 seekParms
.dwCallback
= 0;
800 seekParms
.dwTo
= where
;
802 bool bReplay
= GetState() == wxMEDIASTATE_PLAYING
;
804 if( mciSendCommand(m_hDev
, MCI_SEEK
, MCI_TO
, (DWORD
)(LPVOID
)&seekParms
) != 0)
807 mciGetErrorString(nError, sz, 5000);
808 wxMessageBox(wxString::Format(_T("Error:%s"), sz));
817 long wxWMMEMediaCtrlImpl::GetPosition()
819 MCI_STATUS_PARMS statusParms
;
821 statusParms
.dwItem
= MCI_STATUS_POSITION
;
822 if (mciSendCommand(m_hDev
, MCI_STATUS
, MCI_STATUS_ITEM
,
823 (DWORD
)(LPSTR
)&statusParms
) != 0)
826 return statusParms
.dwReturn
;
829 long wxWMMEMediaCtrlImpl::GetDuration()
831 MCI_STATUS_PARMS statusParms
;
833 statusParms
.dwItem
= MCI_STATUS_LENGTH
;
834 if (mciSendCommand(m_hDev
, MCI_STATUS
, MCI_STATUS_ITEM
,
835 (DWORD
)(LPSTR
)&statusParms
) != 0)
838 return statusParms
.dwReturn
;
841 void wxWMMEMediaCtrlImpl::DoMoveWindow(int, int, int, int)
845 wxSize
wxWMMEMediaCtrlImpl::DoGetBestSize() const
849 //TODO: Does this work?
851 MCI_DGV_RECT_PARMS rect;
853 mciSendCommand(m_hDev, MCI_WHERE, MCI_DGV_WHERE_SOURCE, (DWORD)(LPSTR)&rect);
854 return wxSize(rect.rc.right, rect.rc.bottom);
860 double wxWMMEMediaCtrlImpl::GetPlaybackRate()
865 bool wxWMMEMediaCtrlImpl::SetPlaybackRate(double)
870 //---------------------------------------------------------------------------
872 // wxAVIFileMediaCtrlImpl
874 //---------------------------------------------------------------------------
876 //---------------------------------------------------------------------------
877 // Functions located in msvfw32.dll
878 //---------------------------------------------------------------------------
882 typedef void (WINAPI *LPAVIFileInit) ();
883 typedef void (WINAPI *LPAVIFileExit) ();
885 typedef ULONG (WINAPI *LPAVIFileOpen) (
886 PAVIFILE FAR * ppfile,
887 const wxChar* szFile,
892 typedef ULONG (WINAPI *LPAVIFileRelease) (PAVIFILE pfile);
894 wxAVIFileMediaCtrlImpl::wxAVIFileMediaCtrlImpl()
898 wxAVIFileMediaCtrlImpl::~wxAVIFileMediaCtrlImpl()
902 bool wxAVIFileMediaCtrlImpl::Create(wxMediaCtrl* ctrl)
904 m_hDll = ::LoadLibrary(_T("avifil32.dll"));
909 LPAVIFileInit pAVIFileInit = (LPAVIFileInit) ::GetProcAddress(m_hDll, _T("AVIFileInit"));
921 bool wxAVIFileMediaCtrlImpl::Load(const wxString& fileName)
923 // if( AVIFileOpen(&m_hAVIFile, fileName.c_str(), OF_SHARE_DENY_WRITE, 0L) != 0)
931 bool wxAVIFileMediaCtrlImpl::Load(const wxURI& WXUNUSED(location))
936 bool wxAVIFileMediaCtrlImpl::Play()
941 bool wxAVIFileMediaCtrlImpl::Pause()
946 bool wxAVIFileMediaCtrlImpl::Stop()
951 wxMediaState wxAVIFileMediaCtrlImpl::GetState()
953 return wxMEDIASTATE_STOPPED;
956 bool wxAVIFileMediaCtrlImpl::SetPosition(long where)
961 long wxAVIFileMediaCtrlImpl::GetPosition()
966 long wxAVIFileMediaCtrlImpl::GetDuration()
971 void wxAVIFileMediaCtrlImpl::DoMoveWindow(int, int, int, int)
975 wxSize wxAVIFileMediaCtrlImpl::DoGetBestSize() const
980 double wxAVIFileMediaCtrlImpl::GetPlaybackRate()
985 bool wxAVIFileMediaCtrlImpl::SetPlaybackRate(double)
992 #endif //wxUSE_MEDIACTRL