- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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;}