// This code and information is provided "as is" without warranty of
// any kind, either expressed or implied, including but not limited to
// the implied warranties of merchantability and/or fitness for a
// particular purpose.
// Copyright (C) 1996 - 1997 Intel corporation. All rights reserved.
// IPlaydoc.cpp : implementation of the CIPlayDoc class
//
#include "stdafx.h"
#include "IPlay.h"
#include "IPlaydoc.h"
#include <initguid.h> // OLE (Quartz) initialization
#include "ax_spec.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CIPlayDoc
IMPLEMENT_DYNCREATE(CIPlayDoc, CDocument)
#define new DEBUG_NEW //Checking for mem leaks in debug mode
BEGIN_MESSAGE_MAP(CIPlayDoc, CDocument)
//{{AFX_MSG_MAP(CIPlayDoc)
ON_COMMAND(ID_MEDIA_LOOP, OnMediaLoop)
ON_COMMAND(ID_MEDIA_PAUSE, OnMediaPause)
ON_COMMAND(ID_MEDIA_ZOOMX2, OnMediaZoomx2)
ON_UPDATE_COMMAND_UI(ID_MEDIA_PAUSE, OnUpdateMediaPause)
ON_UPDATE_COMMAND_UI(ID_MEDIA_PLAY, OnUpdateMediaPlay)
ON_UPDATE_COMMAND_UI(ID_MEDIA_STOP, OnUpdateMediaStop)
ON_UPDATE_COMMAND_UI(ID_MEDIA_ZOOMX2, OnUpdateMediaZoomx2)
ON_UPDATE_COMMAND_UI(ID_MEDIA_LOOP, OnUpdateMediaLoop)
ON_COMMAND(ID_MEDIA_PLAY, OnMediaPlay)
ON_COMMAND(ID_MEDIA_STOP, OnMediaStop)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
R4_DEC_SEQ_DATA m_r4SeqData; // Indeo data structures
R4_DEC_FRAME_DATA m_r4FrameData;
/////////////////////////////////////////////////////////////////////////////
// CIPlayDoc construction/destruction
CIPlayDoc::CIPlayDoc()
{
m_pGraph = NULL;
m_hGraphEvent = NULL;
m_pIndeo = NULL;
m_lpstrPath[0] = '\0';
m_bLoop = FALSE;
m_bZoom = FALSE;
m_lWidth = 0;
m_lHeight = 0;
m_State = Uninitialized;
// Initialize the headers for the Indeo data structures
// This stuff never changes (except for dwFlags)
m_r4FrameData.dwSize = sizeof(R4_DEC_FRAME_DATA);
m_r4FrameData.dwFourCC = FOURCC_IV41;
m_r4FrameData.dwVersion = SPECIFIC_INTERFACE_VERSION;
m_r4FrameData.oeEnvironment = OE_32;
m_r4FrameData.dwFlags = 0;
m_r4SeqData.dwSize = sizeof(R4_DEC_SEQ_DATA);
m_r4SeqData.dwFourCC = FOURCC_IV41;
m_r4SeqData.dwVersion = SPECIFIC_INTERFACE_VERSION;
m_r4SeqData.oeEnvironment = OE_32;
m_r4SeqData.dwFlags = 0;
((CIPlayApp *) AfxGetApp())->OnDocumentCreated( this );
}
CIPlayDoc::~CIPlayDoc()
{
DeleteContents();
((CIPlayApp *) AfxGetApp())->OnDocumentDestroyed( this );
}
/////////////////////////////////////////////////////////////////////////////
// CIPlayDoc diagnostics
#ifdef _DEBUG
void CIPlayDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CIPlayDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CIPlayDoc Message Handlers
BOOL CIPlayDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
WCHAR wPath[MAX_PATH];
char szDrive[ _MAX_DRIVE ] ;
char szDir[ _MAX_DIR ];
char szFname[ _MAX_FNAME ];
char szExt[ _MAX_EXT ];
IBaseFilter *pFilter; // EnumFilters vars
IEnumFilters *pEnum;
ULONG pcFetched;
HRESULT hr;
//HWND hVidWin;
void *pIF; // generic interface to graph object
// Get rid of any previously opened graph.
DeleteContents();
// Create a new filter graph object.
if ( !CreateFilterGraph() ) {
AfxMessageBox(IDS_CANT_INIT_QUARTZ);
return FALSE;
}
// Render the file using the new filter graph.
// This will add the necessary filters to the
// graph (which up til now was empty).
strcpy(m_lpstrPath, lpszPathName);
MultiByteToWideChar( CP_ACP, 0, lpszPathName,
-1, wPath, MAX_PATH );
hr = m_pGraph->QueryInterface(IID_IGraphBuilder, &pIF);
if (FAILED( ((IGraphBuilder *)pIF)->RenderFile(wPath, NULL) )) {
AfxMessageBox(IDS_CANT_RENDER_FILE);
return FALSE;
}
((IGraphBuilder *)pIF)->Release();
// Position and set the title of the video window.
_splitpath( lpszPathName, szDrive, szDir, szFname, szExt );
MultiByteToWideChar( CP_ACP, 0, CString(szFname) + szExt,-1,
wPath, _MAX_FNAME + _MAX_EXT);
SetWindow((BSTR)wPath);
// Get and save the native video size -- used for
// zoom by 2.
hr = m_pGraph->QueryInterface(IID_IBasicVideo, &pIF);
if( SUCCEEDED(hr) ){
((IBasicVideo *)pIF)->GetVideoSize(&m_lWidth, &m_lHeight);
((IBasicVideo *)pIF)->Release();
}
// Call the stop function to queue up the first
// frame of the clip. Have to set the state first
// to Paused so we can transistion to Stopped.
m_State = Paused;
OnMediaStop();
// See if the Indeo codec filter is in the graph.
hr = m_pGraph->EnumFilters(&pEnum);
if (FAILED(hr))
return TRUE;
while ((hr = pEnum->Next(1, &pFilter, &pcFetched)) == S_OK)
{
hr = pFilter->QueryInterface(IID_IIndeoDecode, &m_pIndeo);
pFilter->Release();
if (hr == S_OK)
break;
}
// This interface needs to be released, even though
// it was not obtained in the usual way with QueryInterface.
pEnum->Release();
// Someday, the following line can replace the above section of code
// that enumerates the filters in the graph to find the
// IIndeoDecode interface, but apparently that someday is not today.
//hr = m_pGraph->QueryInterface(IID_IIndeoDecode, &m_pIndeo);
return TRUE;
}
void CIPlayDoc::OnGraphNotify(void) {
IMediaEvent *pME;
long lEventCode, lParam1, lParam2;
ASSERT( m_hGraphEvent != NULL );
if( SUCCEEDED(m_pGraph->QueryInterface(IID_IMediaEvent, (void **) &pME))){
if( SUCCEEDED(pME->GetEvent(&lEventCode, &lParam1, &lParam2, 0)) ) {
switch (lEventCode) {
case EC_COMPLETE:
OnMediaStop();
if (m_bLoop) OnMediaPlay();
break;
case EC_USERABORT:
case EC_ERRORABORT:
OnMediaStop();
}
}
pME->Release();
}
// Send a message so toolbar gets updated
PostMessage( AfxGetMainWnd()->m_hWnd, WM_USER, 0, 0 );
}
void CIPlayDoc::OnMediaLoop()
{
m_bLoop = !m_bLoop;
}
void CIPlayDoc::OnMediaPause()
{
if( CanPause() ){
HRESULThr;
IMediaControl *pMC;
// Obtain the interface to our filter graph
hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **) &pMC);
if( SUCCEEDED(hr) ){
// Ask the filter graph to pause and release the interface
hr = pMC->Pause();
pMC->Release();
if( SUCCEEDED(hr) ){
m_State = Paused;
return;
}
}
}
}
void CIPlayDoc::OnMediaPlay()
{
if( CanPlay() ){
HRESULThr;
IMediaControl *pMC;
// Obtain the interface to our filter graph
hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **) &pMC);
if( SUCCEEDED(hr) ){
// Ask the filter graph to play and release the interface
hr = pMC->Run();
pMC->Release();
if( SUCCEEDED(hr) ){
m_State=Playing;
// Let Indeo view object know the state changed
UpdateAllViews(NULL);
return;
}
}
}
}
void CIPlayDoc::OnMediaStop()
{
if( CanStop() ){
HRESULThr;
IMediaControl *pMC;
IMediaPosition *pMP;
OAFilterState fstate;
// Obtain the interface to our filter graph
hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **) &pMC);
if( SUCCEEDED(hr) ){
// Ask the filter graph to stop and release the interface
// put graph in stopped state
hr = pMC->Stop();
// Rewind the stream
hr = m_pGraph->QueryInterface(IID_IMediaPosition, (void **) &pMP);
hr = pMP->put_CurrentPosition(0);
hr = pMP->Release();
// Flush the graph
hr = pMC->Pause();
// Wait for state transition to complete
hr = pMC->GetState(5000, &fstate);
// Now back to stopped state
hr = pMC->Stop();
pMC->Release();
if( SUCCEEDED(hr) ){
m_State = Stopped;
// Let Indeo view object know the state changed
UpdateAllViews(NULL);
return;
}
}
}
}
void CIPlayDoc::OnMediaZoomx2()
{
// This function doubles the width & height of the original video
// size -- depending on the hardware, this may result in a
// better quality video than a random stretch of the video window.
// Subsequent calls toggle the video size between the original size
// and the "x2" size, ignoring the fact that the user may have
// resized the window using the window frame. The function attempts to
// keep the video window's center in place (zooms/unzooms from top,
// bottom, right and left).
HRESULT hr;
void *pIF;
long x,y,width,height,width2,height2;
m_bZoom = !m_bZoom;
hr = m_pGraph->QueryInterface(IID_IVideoWindow, &pIF);
if( SUCCEEDED(hr) ){
if (m_bZoom) {
// Set the width & height to twice the native video size
// Allow for the window frame -- we really want to just
// double the size of the client area.
width2 = (m_lWidth * 2) + (m_lWinWidth - m_lWidth);
height2 = (m_lHeight * 2) + (m_lWinHeight - m_lHeight);
((IVideoWindow *)pIF)->GetWindowPosition(&x, &y, &width, &height);
((IVideoWindow *)pIF)->SetWindowPosition(x + (width - width2)/2,
y + (height - height2)/2, width2, height2);
}
else {
// Restore original size
((IVideoWindow *)pIF)->GetWindowPosition(&x, &y, &width, &height);
((IVideoWindow *)pIF)->SetWindowPosition(x +
(width - m_lWinWidth)/2, y + (height - m_lWinHeight)/2,
m_lWinWidth, m_lWinHeight);
}
((IVideoWindow *)pIF)->Release();
}
}
void CIPlayDoc::OnUpdateMediaPause(CCmdUI* pCmdUI)
{
pCmdUI->Enable( CanPause() );
}
void CIPlayDoc::OnUpdateMediaPlay(CCmdUI* pCmdUI)
{
pCmdUI->Enable( CanPlay() );
}
void CIPlayDoc::OnUpdateMediaStop(CCmdUI* pCmdUI)
{
pCmdUI->Enable( CanStop() );
}
void CIPlayDoc::OnUpdateMediaLoop(CCmdUI* pCmdUI)
{
pCmdUI->Enable( IsInitialized() );
pCmdUI->SetCheck( m_bLoop );
}
void CIPlayDoc::OnUpdateMediaZoomx2(CCmdUI* pCmdUI)
{
pCmdUI->Enable( IsInitialized() );
pCmdUI->SetCheck( m_bZoom );
}
/////////////////////////////////////////////////////////////////////////////
// CIPlayDoc Commands
BOOL CIPlayDoc::IsIndeo()
{
return (m_pIndeo != NULL);
}
void CIPlayDoc::GetTransFillRGB(int& red, int& green, int& blue)
{
HRESULT hr;
m_r4FrameData.mtType = MT_DECODE_FRAME_VALUE;
m_r4FrameData.dwFlags = DECFRAME_FILL_COLOR |
DECFRAME_VALID;
m_r4FrameData.dwFillColor = DECFRAME_FILL_UNDEFINED;
hr = ((IIndeoDecode *)m_pIndeo)->get_DecodeFrame(&m_r4FrameData);
if (FAILED( hr )) {
AfxMessageBox(IDS_CANT_GET_FRAME_DATA);
return;
}
if (m_r4FrameData.dwFillColor & DECFRAME_FILL_UNDEFINED) {
red = 0;
green =0;
blue =0;
} else { // Fill color is valid
red = (m_r4FrameData.dwFillColor&0x00FF0000)>>16;
green =(m_r4FrameData.dwFillColor&0x0000FF00)>>8;
blue =(m_r4FrameData.dwFillColor&0x000000FF);
}
return;
}
void CIPlayDoc::GetBCS(int& b, int& c, int& s)
{
HRESULT hr;
m_r4FrameData.mtType = MT_DECODE_FRAME_VALUE;
m_r4FrameData.dwFlags = DECFRAME_BRIGHTNESS |
DECFRAME_CONTRAST |
DECFRAME_SATURATION |
DECFRAME_VALID;
hr = ((IIndeoDecode *)m_pIndeo)->get_DecodeFrame(&m_r4FrameData);
if (FAILED( hr )) {
AfxMessageBox(IDS_CANT_GET_FRAME_DATA);
return;
}
b = LOWORD(m_r4FrameData.lBrightness);
c = LOWORD(m_r4FrameData.lContrast);
s = LOWORD(m_r4FrameData.lSaturation);
return;
}
void CIPlayDoc::GetDecodeTime(DWORD& time)
{
HRESULT hr;
m_r4FrameData.mtType = MT_DECODE_FRAME_VALUE;
m_r4FrameData.dwFlags = DECFRAME_TIME_LIMIT | DECFRAME_VALID;
hr = ((IIndeoDecode *)m_pIndeo)->get_DecodeFrame(&m_r4FrameData);
if (FAILED( hr )) {
AfxMessageBox(IDS_CANT_SET_FRAME_DATA);
return;
}
time = m_r4FrameData.dwTimeLimit;
return;
}
void CIPlayDoc::GetDecodeRect(DWORD& x, DWORD& y, DWORD& width, DWORD& height)
{
HRESULT hr;
m_r4FrameData.mtType = MT_DECODE_FRAME_VALUE;
m_r4FrameData.dwFlags = DECFRAME_DECODE_RECT | DECFRAME_VALID;
hr = ((IIndeoDecode *)m_pIndeo)->get_DecodeFrame(&m_r4FrameData);
if (FAILED( hr )) {
AfxMessageBox(IDS_CANT_GET_FRAME_DATA);
return;
}
x = m_r4FrameData.rDecodeRect.dwX;
y = m_r4FrameData.rDecodeRect.dwY;
width = m_r4FrameData.rDecodeRect.dwWidth;
height = m_r4FrameData.rDecodeRect.dwHeight;
return;
}
void CIPlayDoc::GetViewRect(DWORD& x, DWORD& y, DWORD& width, DWORD& height)
{
HRESULT hr;
m_r4FrameData.mtType = MT_DECODE_FRAME_VALUE;
m_r4FrameData.dwFlags = DECFRAME_VIEW_RECT | DECFRAME_VALID;
hr = ((IIndeoDecode *)m_pIndeo)->get_DecodeFrame(&m_r4FrameData);
if (FAILED( hr )) {
AfxMessageBox(IDS_CANT_GET_FRAME_DATA);
return;
}
x = m_r4FrameData.rViewRect.dwX;
y = m_r4FrameData.rViewRect.dwY;
width = m_r4FrameData.rViewRect.dwWidth;
height = m_r4FrameData.rViewRect.dwHeight;
return;
}
void CIPlayDoc::GetSequenceOptions(BOOL& altline, BOOL& ddframes, BOOL& ddquality, BOOL& trans, BOOL& usekey,
DWORD& key)
{
HRESULT hr;
m_r4SeqData.mtType = MT_DECODE_SEQ_VALUE;
m_r4SeqData.dwFlags =DECSEQ_KEY |
DECSEQ_SCALABILITY |
DECSEQ_FILL_TRANSPARENT |
DECSEQ_ALT_LINE |
DECSEQ_VALID;
hr = ((IIndeoDecode *)m_pIndeo)->get_DecodeSequence(&m_r4SeqData);
if (FAILED( hr )) {
AfxMessageBox(IDS_CANT_GET_SEQ_DATA);
return;
}
altline = m_r4SeqData.fAltLine;
switch (m_r4SeqData.eScalability)
{
case SC_ON:
ddframes = ddquality = FALSE;
break;
case SC_OFF:
ddframes = ddquality = TRUE;
break;
case SC_DONT_DROP_FRAMES:
ddframes = TRUE;
ddquality = FALSE;
break;
case SC_DONT_DROP_QUALITY:
ddframes = FALSE;
ddquality = TRUE;
break;
}
trans = m_r4SeqData.fFillTransparentPixels;
usekey = m_r4SeqData.fEnabledKey;
key = m_r4SeqData.dwKey;
return;
}
void CIPlayDoc::SetTransFillRGB(DWORD rgb)
{
HRESULT hr;
m_r4FrameData.mtType = MT_DECODE_FRAME_VALUE;
m_r4FrameData.dwFlags = DECFRAME_VALID | DECFRAME_FILL_COLOR;
m_r4FrameData.dwFillColor = rgb;
hr = ((IIndeoDecode *)m_pIndeo)->set_DecodeFrame(&m_r4FrameData);
if (FAILED( hr ))
AfxMessageBox(IDS_CANT_SET_FRAME_DATA);
return;
}
void CIPlayDoc::SetBCS(int b, int c, int s)
{
HRESULT hr;
m_r4FrameData.mtType = MT_DECODE_FRAME_VALUE;
m_r4FrameData.dwFlags = DECFRAME_BRIGHTNESS |
DECFRAME_CONTRAST |
DECFRAME_SATURATION |
DECFRAME_VALID;
m_r4FrameData.lBrightness = b;
m_r4FrameData.lContrast = c;
m_r4FrameData.lSaturation = s;
hr = ((IIndeoDecode *)m_pIndeo)->set_DecodeFrame(&m_r4FrameData);
if (FAILED( hr ))
AfxMessageBox(IDS_CANT_SET_FRAME_DATA);
return;
}
void CIPlayDoc::SetDecodeTime(DWORD time)
{
HRESULT hr;
m_r4FrameData.mtType = MT_DECODE_FRAME_VALUE;
m_r4FrameData.dwFlags = DECFRAME_TIME_LIMIT | DECFRAME_VALID;
m_r4FrameData.dwTimeLimit = time;
hr = ((IIndeoDecode *)m_pIndeo)->set_DecodeFrame(&m_r4FrameData);
if (FAILED( hr ))
AfxMessageBox(IDS_CANT_SET_FRAME_DATA);
return;
}
void CIPlayDoc::SetDecodeRect(DWORD x, DWORD y, DWORD width, DWORD height)
{
HRESULT hr;
m_r4FrameData.mtType = MT_DECODE_FRAME_VALUE;
m_r4FrameData.dwFlags = DECFRAME_DECODE_RECT |
DECFRAME_VALID;
m_r4FrameData.rDecodeRect.dwX = x;
m_r4FrameData.rDecodeRect.dwY = y;
m_r4FrameData.rDecodeRect.dwWidth = width;
m_r4FrameData.rDecodeRect.dwHeight = height;
m_r4FrameData.rDecodeRect.dwX = x;
m_r4FrameData.rDecodeRect.dwY = y;
m_r4FrameData.rDecodeRect.dwWidth = width;
m_r4FrameData.rDecodeRect.dwHeight = height;
hr = ((IIndeoDecode *)m_pIndeo)->set_DecodeFrame(&m_r4FrameData);
if (FAILED( hr ))
AfxMessageBox(IDS_CANT_SET_FRAME_DATA);
return;
}
void CIPlayDoc::SetViewRect(BOOL view ,DWORD x, DWORD y, DWORD width, DWORD height)
{
HRESULT hr;
m_r4FrameData.mtType = MT_DECODE_FRAME_VALUE;
m_r4FrameData.dwFlags = DECFRAME_VIEW_RECT |
DECFRAME_VIEW_RECT_ORIGIN |
DECFRAME_VALID;
m_r4FrameData.fViewRectOrigin = view;
m_r4FrameData.rViewRect.dwX = x;
m_r4FrameData.rViewRect.dwY = y;
m_r4FrameData.rViewRect.dwWidth = width;
m_r4FrameData.rViewRect.dwHeight = height;
hr = ((IIndeoDecode *)m_pIndeo)->set_DecodeFrame(&m_r4FrameData);
if (FAILED( hr ))
AfxMessageBox(IDS_CANT_SET_FRAME_DATA);
return;
}
void CIPlayDoc::SetSequenceOptions(BOOL altline, LONG scal, BOOL fill, BOOL usekey, DWORD key)
{
HRESULT hr;
m_r4SeqData.mtType = MT_DECODE_SEQ_VALUE;
m_r4SeqData.dwFlags =DECSEQ_KEY |
DECSEQ_SCALABILITY |
DECSEQ_FILL_TRANSPARENT |
DECSEQ_ALT_LINE |
DECSEQ_VALID;
m_r4SeqData.fAltLine = altline;
m_r4SeqData.eScalability = scal;
m_r4SeqData.fFillTransparentPixels = fill;
m_r4SeqData.fEnabledKey = usekey;
m_r4SeqData.dwKey = key;
hr = ((IIndeoDecode *)m_pIndeo)->set_DecodeSequence(&m_r4SeqData);
if (FAILED( hr ))
AfxMessageBox(IDS_CANT_SET_SEQ_DATA);
return;
}
void CIPlayDoc::GetFrameDefaults(int& b, int& c, int& s, DWORD& time,
DWORD& dx, DWORD& dy, DWORD& dWidth, DWORD& dHeight,
DWORD& vx, DWORD& vy, DWORD& vWidth, DWORD& vHeight)
{
HRESULT hr;
m_r4FrameData.mtType = MT_DECODE_FRAME_DEFAULT;
m_r4FrameData.dwFlags = DECFRAME_BRIGHTNESS |
DECFRAME_CONTRAST |
DECFRAME_SATURATION |
DECFRAME_TIME_LIMIT |
DECFRAME_DECODE_RECT |
DECFRAME_VIEW_RECT |
DECFRAME_VIEW_RECT_ORIGIN |
DECFRAME_VALID;
hr = ((IIndeoDecode *)m_pIndeo)->get_DecodeFrame(&m_r4FrameData);
if (FAILED( hr )) {
AfxMessageBox(IDS_CANT_GET_FRAME_DATA);
return;
}
b = LOWORD(m_r4FrameData.lBrightness);
c = LOWORD(m_r4FrameData.lContrast);
s = LOWORD(m_r4FrameData.lSaturation);
time = m_r4FrameData.dwTimeLimit;
dx = m_r4FrameData.rDecodeRect.dwX;
dy = m_r4FrameData.rDecodeRect.dwY;
dWidth = m_r4FrameData.rDecodeRect.dwWidth;
dHeight = m_r4FrameData.rDecodeRect.dwHeight;
vx = m_r4FrameData.rViewRect.dwX;
vy = m_r4FrameData.rViewRect.dwY;
vWidth = m_r4FrameData.rViewRect.dwWidth;
vHeight = m_r4FrameData.rViewRect.dwHeight;
return;
}
void CIPlayDoc::GetSeqDefaults(BOOL& altline, BOOL& ddframes, BOOL& ddquality, BOOL& trans, BOOL& usekey,
DWORD& key)
{
HRESULT hr;
m_r4SeqData.mtType = MT_DECODE_SEQ_DEFAULT;
m_r4SeqData.dwFlags =DECSEQ_KEY |
DECSEQ_SCALABILITY |
DECSEQ_FILL_TRANSPARENT |
DECSEQ_ALT_LINE |
DECSEQ_VALID;
hr = ((IIndeoDecode *)m_pIndeo)->get_DecodeSequence(&m_r4SeqData);
if (FAILED( hr )) {
AfxMessageBox(IDS_CANT_GET_SEQ_DATA);
return;
}
altline = m_r4SeqData.fAltLine;
switch (m_r4SeqData.eScalability)
{
case SC_ON:
ddframes = ddquality = FALSE;
break;
case SC_OFF:
ddframes = ddquality = TRUE;
break;
case SC_DONT_DROP_FRAMES:
ddframes = TRUE;
ddquality = FALSE;
break;
case SC_DONT_DROP_QUALITY:
ddframes = FALSE;
ddquality = TRUE;
break;
}
trans = m_r4SeqData.fFillTransparentPixels;
usekey = m_r4SeqData.fEnabledKey;
key = m_r4SeqData.dwKey;
}
ULONG CIPlayDoc::VideoWidth()
{
HRESULT hr;
IBasicVideo *pIF;
long width;
hr = m_pGraph->QueryInterface(IID_IBasicVideo, (void **)&pIF);
if( FAILED(hr) ) {
AfxMessageBox(IDS_CANT_GET_VIDEO_INTERFACE);
return 0;
}
pIF->get_DestinationWidth(&width);
pIF->Release();
return width;
}
ULONG CIPlayDoc::VideoHeight()
{
HRESULT hr;
IBasicVideo *pIF;
long height;
hr = m_pGraph->QueryInterface(IID_IBasicVideo, (void **)&pIF);
if( FAILED(hr) ) {
AfxMessageBox(IDS_CANT_GET_VIDEO_INTERFACE);
return 0;
}
pIF->get_DestinationHeight(&height);
pIF->Release();
return height;
}
/////////////////////////////////////////////////////////////////////////////
// CIPlayDoc protected funtions
BOOL CIPlayDoc::CreateFilterGraph(void) {
HRESULT hr;// return code
ASSERT(m_pGraph == NULL);
// Create this document's filter graph object
hr = CoCreateInstance(CLSID_FilterGraph,
NULL,
CLSCTX_INPROC_SERVER,
IID_IFilterGraph,
(void **) &m_pGraph);
if (FAILED(hr)){
m_pGraph = NULL;
return FALSE;
}
// get media event handle
IMediaEvent *pME;
hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **) &pME);
if (FAILED(hr)) {
DeleteContents();
return FALSE;
}
hr = pME->GetEventHandle((OAEVENT*) &m_hGraphEvent);
pME->Release();
if (FAILED(hr)) {
DeleteContents();
return FALSE;
}
return TRUE;
}
void CIPlayDoc::DeleteContents()
{
// Release all interfaces to graph
// and filters.
if (m_pIndeo != NULL) {
((IIndeoDecode *)m_pIndeo)->Release();
m_pIndeo = NULL;
}
if (m_pGraph != NULL) {
m_pGraph->Release();
m_pGraph = NULL;
}
m_hGraphEvent = NULL;
m_State = Uninitialized;
}
void CIPlayDoc::SetWindow(BSTR wPath)
{
HRESULT hr;
IVideoWindow *pVidWin;
RECT rDeskTop;
int x, y;
hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);
if( FAILED(hr) ) {
AfxMessageBox(IDS_CANT_GET_WINDOW_INTERFACE);
return;
}
// Set the caption of the video window
pVidWin->put_Caption(wPath);
// Save the original size for zoom x 2
pVidWin->get_Width(&m_lWinWidth);
pVidWin->get_Height(&m_lWinHeight);
// Center the window on the screen
GetWindowRect(GetDesktopWindow(), &rDeskTop);
if ( m_lWinWidth < (rDeskTop.right - rDeskTop.left) )
x = ((rDeskTop.right - rDeskTop.left) - m_lWinWidth) / 2;
else
x = rDeskTop.left;
if ( m_lWinHeight < (rDeskTop.bottom - rDeskTop.top) )
y = ((rDeskTop.bottom - rDeskTop.top) - m_lWinHeight) / 2;
else
y = rDeskTop.top;
pVidWin->SetWindowPosition(x, y, m_lWinWidth, m_lWinHeight);
pVidWin->Release();
}