ShockwaveGraph.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 #include "stdafx.h"
00023 #include "shockwavegraph.h"
00024 #include "resource.h"
00025 #include "..\..\DSUtil\DSUtil.h"
00026 
00027 CShockwaveGraph::CShockwaveGraph(HWND hParent, HRESULT& hr)
00028         : m_fs(State_Stopped)
00029 {
00030         hr = S_OK;
00031 
00032         if(!m_wndWindowFrame.Create(NULL, NULL, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
00033                 CRect(0, 0, 0, 0), CWnd::FromHandle(hParent), 0, NULL))
00034         {
00035                 hr = E_FAIL;
00036                 return;
00037         }
00038 
00039         if(!m_wndDestFrame.Create(NULL, WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, 
00040                 CRect(0, 0, 0, 0), &m_wndWindowFrame, 0))
00041         {
00042                 hr = E_FAIL;
00043                 return;
00044         }
00045 }
00046 
00047 CShockwaveGraph::~CShockwaveGraph()
00048 {
00049         m_wndDestFrame.DestroyWindow();
00050         m_wndWindowFrame.DestroyWindow();
00051 }
00052 
00053 // IGraphBuilder
00054 STDMETHODIMP CShockwaveGraph::RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList)
00055 {
00056         try {m_wndDestFrame.LoadMovie(0, CString(lpcwstrFile));}
00057         catch(CException* e) {e->Delete(); return E_FAIL;}
00058         return S_OK;
00059 }
00060 
00061 // IMediaControl
00062 STDMETHODIMP CShockwaveGraph::Run()
00063 {
00064         try {if(m_fs != State_Running) m_wndDestFrame.Play();}
00065         catch(CException* e) {e->Delete(); return E_FAIL;}
00066         m_fs = State_Running;
00067         m_wndWindowFrame.EnableWindow();
00068 //      m_wndDestFrame.EnableWindow();
00069         return S_OK;
00070 }
00071 STDMETHODIMP CShockwaveGraph::Pause()
00072 {
00073         try {if(m_fs == State_Running) m_wndDestFrame.Stop();}
00074         catch(CException* e) {e->Delete(); return E_FAIL;}
00075         m_fs = State_Paused;
00076         return S_OK;
00077 }
00078 STDMETHODIMP CShockwaveGraph::Stop()
00079 {
00080         try {m_wndDestFrame.Stop();}
00081         catch(CException* e) {e->Delete(); return E_FAIL;}
00082         m_fs = State_Stopped;
00083         return S_OK;
00084 }
00085 STDMETHODIMP CShockwaveGraph::GetState(LONG msTimeout, OAFilterState* pfs)
00086 {
00087         OAFilterState fs = m_fs;
00088 
00089         try
00090         {
00091                 if(m_wndDestFrame.IsPlaying() && m_fs == State_Stopped) m_fs = State_Running;
00092                 else if(!m_wndDestFrame.IsPlaying() && m_fs == State_Running) m_fs = State_Stopped;
00093                 fs = m_fs;
00094         }
00095         catch(CException* e)
00096         {
00097                 e->Delete();
00098                 return E_FAIL;
00099         }
00100 
00101         return pfs ? *pfs = fs, S_OK : E_POINTER;
00102 }
00103 
00104 // IMediaSeeking
00105 STDMETHODIMP CShockwaveGraph::IsFormatSupported(const GUID* pFormat)
00106 {
00107         return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_FRAME ? S_OK : S_FALSE;
00108 }
00109 STDMETHODIMP CShockwaveGraph::GetTimeFormat(GUID* pFormat)
00110 {
00111         return pFormat ? *pFormat = TIME_FORMAT_FRAME, S_OK : E_POINTER;
00112 }
00113 STDMETHODIMP CShockwaveGraph::GetDuration(LONGLONG* pDuration)
00114 {
00115         CheckPointer(pDuration, E_POINTER);
00116         *pDuration = 0;
00117         try {if(m_wndDestFrame.get_ReadyState() >= READYSTATE_COMPLETE) *pDuration = m_wndDestFrame.get_TotalFrames();}
00118         catch(CException* e) {e->Delete(); return E_FAIL;}
00119         return S_OK;
00120 }
00121 STDMETHODIMP CShockwaveGraph::GetCurrentPosition(LONGLONG* pCurrent)
00122 {
00123         CheckPointer(pCurrent, E_POINTER);
00124         *pCurrent = 0;
00125         try {if(m_wndDestFrame.get_ReadyState() >= READYSTATE_COMPLETE) *pCurrent = m_wndDestFrame.get_FrameNum();}
00126         catch(CException* e) {e->Delete(); return E_FAIL;}
00127         return S_OK;
00128 }
00129 STDMETHODIMP CShockwaveGraph::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)
00130 {
00131         if(dwCurrentFlags&AM_SEEKING_AbsolutePositioning)
00132         {
00133                 m_wndDestFrame.put_FrameNum(*pCurrent);
00134 
00135                 if(m_fs == State_Running && !m_wndDestFrame.IsPlaying()) 
00136                         m_wndDestFrame.Play();
00137                 else if((m_fs == State_Paused || m_fs == State_Stopped) && m_wndDestFrame.IsPlaying())
00138                         m_wndDestFrame.Stop();
00139 
00140                 m_wndDestFrame.put_Quality(1); // 0=Low, 1=High, 2=AutoLow, 3=AutoHigh
00141 
00142                 return S_OK;
00143         }
00144 
00145         return E_INVALIDARG;
00146 }
00147 
00148 // IVideoWindow
00149 STDMETHODIMP CShockwaveGraph::put_Visible(long Visible)
00150 {
00151         if(IsWindow(m_wndDestFrame.m_hWnd))
00152                 m_wndDestFrame.ShowWindow(Visible == OATRUE ? SW_SHOWNORMAL : SW_HIDE);
00153         return S_OK;
00154 }
00155 STDMETHODIMP CShockwaveGraph::get_Visible(long* pVisible)
00156 {
00157         return pVisible ? *pVisible = (m_wndDestFrame.IsWindowVisible() ? OATRUE : OAFALSE), S_OK : E_POINTER;
00158 }
00159 STDMETHODIMP CShockwaveGraph::SetWindowPosition(long Left, long Top, long Width, long Height)
00160 {
00161         if(IsWindow(m_wndWindowFrame.m_hWnd))
00162                 m_wndWindowFrame.MoveWindow(Left, Top, Width, Height);
00163 
00164         return S_OK;
00165 }
00166 
00167 // IBasicVideo
00168 STDMETHODIMP CShockwaveGraph::SetDestinationPosition(long Left, long Top, long Width, long Height)// {return E_NOTIMPL;}
00169 {
00170         if(IsWindow(m_wndDestFrame.m_hWnd))
00171                 m_wndDestFrame.MoveWindow(Left, Top, Width, Height);
00172 
00173         return S_OK;
00174 }
00175 STDMETHODIMP CShockwaveGraph::GetVideoSize(long* pWidth, long* pHeight)
00176 {
00177         if(!pWidth || !pHeight) return E_POINTER;
00178 
00179         CRect r;
00180         m_wndWindowFrame.GetWindowRect(r);
00181         if(!r.IsRectEmpty())
00182         {
00183                 *pWidth = r.Width();
00184                 *pHeight = r.Height();
00185         }
00186         else
00187         {
00188                 // no call exists to determine these...
00189                 *pWidth = 384;//m_wndDestFrame.get_; 
00190                 *pHeight = 288;
00191 
00192                 NotifyEvent(EC_BG_AUDIO_CHANGED, 2, 0);
00193         }
00194 
00195         return S_OK;
00196 }
00197 
00198 #include <math.h>
00199 
00200 // IBasicAudio
00201 STDMETHODIMP CShockwaveGraph::put_Volume(long lVolume)
00202 {
00203         lVolume = (lVolume == -10000) ? 0 : (int)pow(10.0, ((double)lVolume)/5000+2);
00204         lVolume = lVolume*0x10000/100;
00205         lVolume = max(min(lVolume, 0xffff), 0);
00206         waveOutSetVolume(0, (lVolume<<16)|lVolume);
00207 
00208         return S_OK;
00209 }
00210 STDMETHODIMP CShockwaveGraph::get_Volume(long* plVolume)
00211 {
00212         CheckPointer(plVolume, E_POINTER);
00213 
00214         waveOutGetVolume(0, (DWORD*)plVolume);
00215         *plVolume = (*plVolume&0xffff + ((*plVolume>>16)&0xffff)) / 2;
00216         *plVolume = *plVolume*100/0x10000;
00217         *plVolume = (int)((log10(1.0*(*plVolume))-2)*5000);
00218         *plVolume = max(min(*plVolume, 0), -10000);
00219 
00220         return S_OK;
00221 }
00222 
00223 // IAMOpenProgress
00224 STDMETHODIMP CShockwaveGraph::QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent)
00225 {
00226         *pllTotal = 100;
00227         *pllCurrent = m_wndDestFrame.PercentLoaded();
00228         return S_OK;
00229 }
00230 
00231 // IGraphEngine
00232 STDMETHODIMP_(engine_t) CShockwaveGraph::GetEngine() {return ShockWave;}

Generated on Tue Dec 13 14:47:04 2005 for guliverkli by  doxygen 1.4.5