CMedia更新至v1.4.3

来源:互联网 发布:怎么下载小品软件 编辑:程序博客网 时间:2024/05/09 05:57

//========================================================================
//TITLE:
//    CMedia更新至v1.4.3
//AUTHOR:
//    norains
//DATE:
//    Friday  27-July-2007
//Environment:
//        EVC4.0 + Windows CE 5.0 Standard SDK
//========================================================================

    相对v1.2.0版本进行的改进:

    1.增加GetMediaProperty函数获得的属性,增加如下属性:llDuration,llAvailableEarliest,llAvailableLatest.
   
    2.增加如下函数:SetRate(),GetRate(),GetPositionCurrent(),SetPositionCurrent() ,GetDisplayMode()
   
    3.改进之前一些函数的HRESULT值返回BOOL值的判定方法
   
    4.增加SetVideoWindow()一个参数,以设置可以在窗口的任意位置为起点播放视频
   
    5.改进SetDisplayMode()函数,当窗口句柄为空时,设置播放区域为0,并返回FALSE
   
    6.改进SetNotifyWindow()函数,令其能够接收普通的窗口消息
   
    7.Open()的参数改为const类型,更符合实际意义


    v1.2.0版本及相关用法见:http://blog.csdn.net/norains/archive/2007/05/14/1609118.aspx

 


    我们来看看具体更新了哪些功能:
   
    1.MEDIAPROPERTY
   
        增加了llDuration,llAvailableEarliest,llAvailableLatest属性,分别代表影片的时间长度,最早的可拖拽的时间位置,最早的可拖拽的时间位置.这个属性可以用在GetMediaProperty()函数中.
       
       
       
    2.SetRate(),GetRate()
   
        SetRate()设置当前的播放速率,"1"为正常速率,"2"即为两倍速,以此类推.
       
        GetRate()获取当前播放的速率.
       
       
       
    3.GetPositionCurrent(),SetPositionCurrent()
   
        GetPositionCurrent():获取当前的时间位置,返回的时间值以100ns为基本单位.   

        SetPositionCurrent():设置播放的时间位置,该范围必须是llAvailableEarliest和llAvailableLatest之间的数值.
       
       
       
    4.GetDisplayMode()
   
         该函数用来获取当前的播放模式.


   
   
    v1.4.3的完整代码如下:


///////////////////////////////////////////////////////////////////////
//Media.h: interface for the CMedia class.
//
//Version:
//    1.4.3
//Date:
//    2007.07.19
//////////////////////////////////////////////////////////////////////
#ifndef MEDIA_H
#define    MEDIA_H


#include 
<mmsystem.h>
#include 
<streams.h>

//--------------------------------------------------------------------
//Macro define

//The volume value
#define MAX_VOLUME                    0
#define MIN_VOLUME                    -10000

//The balance value
#define MAX_BALANCE                    10000
#define MIN_BALANCE                    -10000

//The flag means that the area is the whole window 
const RECT RC_WHOLE_WINDOWN_AREA = {0,0,0,0};            

//--------------------------------------------------------------------
//Enum value

enum DISPLAYMODE
{    
    
//Fit to the play window size. How wide (height) the window is, how 
    
//is the move. Keep aspect ratio.
    DISP_FIT,

    
//Not support.Stretch to the play window size. Don't keep the aspect ratio.
    DISP_STRETCH,

    
//Full screen play.
    DISP_FULLSCREEN,

    
//When the size of video is smaller than the play window, it displayes
    
//as the video size. If it's bigger , it just like the DISP_FIT mode.
    DISP_NATIVE
};
//--------------------------------------------------------------------

//The media file property
typedef struct
{

    
//The volume range is –10,000 to 0.
    
//Divide by 100 to get equivalent decibel value (for example –10,000 = –100 dB). 
    LONG lVolume;


    
//The value from –10,000 to 10,000 indicating the stereo balance
    
//As with the Volume property, units correspond to .01 decibels (multiplied by –1 when plBalance is a positive value).
    
//For example, a value of 1000 indicates –10 dB on the right channel and –90 dB on the left channel. 
    LONG lBalance;


    
//Width of the video  
    LONG lWidth;


    
//Height of the video
    LONG lHeight;


    
//Approximate bit rate
    LONG lBitRate;

    
//The length of time that the media stream will play.
    
//The duration assumes normal playback speed, and it is therefore unaffected by the rate
    LONGLONG llDuration;


    
//Earliest time that can be efficiently seeked to. 
    LONGLONG llAvailableEarliest;

    
//Latest time that can be efficiently seeked to
    LONGLONG llAvailableLatest;

}MEDIAPROPERTY,
*PMEDIAPROPERTY;
//--------------------------------------------------------------------
class CMedia  
{
public:
    DISPLAYMODE GetDisplayMode();
    BOOL SetPositionCurrent(LONGLONG llPos);
    BOOL GetPositionCurrent(LONGLONG 
*pllPos);
    BOOL GetRate(
double *pdRate);
    BOOL SetRate(
double dRate);
    BOOL GetEvent(LONG 
*plEvCode, LONG *plParam1, LONG *plParam2);
    BOOL SetNotifyWindow(HWND hWnd, UINT wMsg,
long lInstanceData);
    BOOL SetVolume(LONG lVolume, LONG lBalance 
= 0);
    BOOL SetDisplayMode(DISPLAYMODE mode);
    BOOL GetMediaProperty(PMEDIAPROPERTY pOutProperty);
    
static CMedia * GetInstance();
    
void Close();
    BOOL CheckVisibility();
    BOOL SetVideoWindow(HWND hWndVideo,
const RECT &rcDisp = RC_WHOLE_WINDOWN_AREA);
    BOOL Open(
const TCHAR *pcszFileName);
    BOOL Stop();
    BOOL Pause();
    BOOL Play();
    
virtual ~CMedia();

protected:


    CMedia();
    
    
// Collection of interfaces
    IGraphBuilder *m_pGB;
    IMediaControl 
*m_pMC;
    IMediaEventEx 
*m_pME;
    IVideoWindow  
*m_pVW;
    IBasicAudio   
*m_pBA;
    IBasicVideo   
*m_pBV;
    IMediaSeeking 
*m_pMS;

    TCHAR m_szFileName[MAX_PATH];
    HWND m_hWndVideo; 
//The window play video
    HWND m_hWndNotify; //The window notify
    BOOL m_bExitThrd;
    BOOL m_bThrdRunning;
    
static CMedia * m_pInstance;
    DISPLAYMODE m_DispMode;
    DWORD m_dwCapability;
    RECT m_rcDisp;
};

#endif //#ifndef MEDIA_H

 


///////////////////////////////////////////////////////////////////////
// Media.cpp: implementation of the CMedia class.
//
//////////////////////////////////////////////////////////////////////

#include 
"stdafx.h"
#include 
"Media.h"



//========================================================================================================
//Link the .lib
//The lib also is copy from "(InstallDir)WINCE500PUBLICDIRECTXSDKLIB"

#pragma comment (lib,"Ole32.lib")

#ifdef CPU_X86EM
    
#pragma comment (lib,"./lib/X86em/Strmiids.lib")
    
#pragma comment (lib,"./lib/X86em/Strmbase.lib")
#endif

#ifdef CPU_MIPSII
    
#pragma comment (lib,"./lib/MIPSII/Strmiids.lib")
    
#pragma comment (lib,"./lib/MIPSII/Strmbase.lib")
#endif

#ifdef CPU_ARM4I
    
#pragma comment (lib,"./lib/ARM4I/Strmiids.lib")
    
#pragma comment (lib,"./lib/ARM4I/Strmbase.lib")
#endif
//========================================================================================================

//----------------------------------------------------------------------------------------------
//Macro define

//Default play mode
#define DEFAULT_DISPLAY_MODE        DISP_NATIVE

//----------------------------------------------------------------------
//Initialize
CMedia *CMedia::m_pInstance = NULL;
//------------------------------------------------------------------------


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMedia::CMedia():
m_pGB(NULL),
m_pMC(NULL),
m_pME(NULL),
m_pVW(NULL),
m_pBA(NULL),
m_pBV(NULL),
m_pMS(NULL),
m_hWndVideo(NULL),
m_bExitThrd(TRUE),
m_bThrdRunning(FALSE),
m_DispMode(DEFAULT_DISPLAY_MODE),
m_hWndNotify(NULL),
m_rcDisp(RC_WHOLE_WINDOWN_AREA)
{
    memset(m_szFileName,
0,sizeof(m_szFileName));
}

CMedia::
~CMedia()
{
    
if(m_pInstance != NULL)
    {
        delete m_pInstance;
        m_pInstance 
= NULL;
    }

}




//------------------------------------------------------------
//Description:
//    Play the media file
//    When you call the function,you should call Open() before.
//
//-------------------------------------------------------------
BOOL CMedia::Play()
{    
    
// Run the graph to play the media file

    
if(m_pMC == NULL)
    {
        
return FALSE;
    }

        


    
return SUCCEEDED(m_pMC->Run());

}




//------------------------------------------------------------
//Description:
//    Pause. 
//    When you call the function,you should call Open() before.
//
//-------------------------------------------------------------
BOOL CMedia::Pause()
{

    
if(m_pMC == NULL)
    {
        
return FALSE;
    }
    
    
return SUCCEEDED(m_pMC->Pause());

    
}




//------------------------------------------------------------
//Description:
//    Stop.
//    When you call the function,you should call Open() before.
//
//-------------------------------------------------------------
BOOL CMedia::Stop()
{

    
if(m_pMC == NULL || m_pMS == NULL)
    {
        
return FALSE;
    }

    HRESULT hr;
    hr 
= m_pMC->Stop();    
    SetPositionCurrent(
0);    
   
    
return SUCCEEDED(hr);
}




//--------------------------------------------------------------------------
//Description:
//    Open the media file. When succeed in calling the function ,
//you should call the Close() to release the resource
//
//-------------------------------------------------------------------------
BOOL CMedia::Open(const TCHAR *pcszFileName)
{
    BOOL bResult 
= FALSE;
    

    
if(_tcslen(pcszFileName) >= MAX_PATH)
    {
        
goto END;
    }
    
else
    {
        _tcscpy(m_szFileName,pcszFileName);

        
//Check the file existing
        HANDLE hdFile = CreateFile(m_szFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
        
if(hdFile == INVALID_HANDLE_VALUE)
        {
            
//The file doesn't exist
            goto END;
        }
        
else
        {
            CloseHandle(hdFile);
        }
    }

    



    
// Initialize COM 
    if(CoInitializeEx(NULL, COINIT_MULTITHREADED) != S_OK)
    {
        
goto END;
    }

    
// Get the interface for DirectShow's GraphBuilder
    if(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB) != S_OK)
    {
        
goto END;
    }


    
// Have the graph construct its the appropriate graph automatically
    if(m_pGB->RenderFile(m_szFileName, NULL) != NOERROR)
    {
        
goto END;
    }
    

    
// QueryInterface for DirectShow interfaces
    if(m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC) != NOERROR)
    {
        
goto END;
    }
    
if(m_pGB->QueryInterface(IID_IMediaEventEx, (void **)&m_pME) != NOERROR)
    {
        
goto END;
    }
    
if(m_pGB->QueryInterface(IID_IMediaSeeking, (void **)&m_pMS) != NOERROR)
    {
        
goto END;
    }
    
    
    
    
// Query for video interfaces, which may not be relevant for audio files
    if(m_pGB->QueryInterface(IID_IVideoWindow, (void **)&m_pVW) != NOERROR)
    {
        
goto END;
    }
    
if(m_pGB->QueryInterface(IID_IBasicVideo, (void **)&m_pBV) != NOERROR)
    {
        
goto END;
    }
    
    
if(CheckVisibility() == FALSE)
    {
        
//It just be the audio file, and don't need video filter.

        
// Relinquish ownership (IMPORTANT!) after hiding
        if(m_pVW != NULL)
        {
            m_pVW
->put_Visible(OAFALSE);
            m_pVW
->put_Owner(NULL);
        }

        
if(m_pBV != NULL)
        {
            m_pBV
->Release();
            m_pBV 
= NULL;
        }    

    
        
if(m_pVW != NULL)
        {
            m_pVW
->Release();
            m_pVW 
= NULL;
        }
    }
    

    
// Query for audio interfaces, which may not be relevant for video-only files
    if(m_pGB->QueryInterface(IID_IBasicAudio, (void **)&m_pBA) != NOERROR)
    {
        
goto END;
    }


    
//Set play mode
    SetDisplayMode(m_DispMode);
    
    
//Get the capabilities of the media file.
    m_pMS->GetCapabilities(&m_dwCapability);
    
    bResult 
= TRUE;

END:    

    
if(bResult == FALSE)
    {
        
//Release the resource
        Close();
    }

    
return bResult;
}




//------------------------------------------------------------
//Description:
//    This method sets an owning parent for the video window. 
//
//Parameters:
//    hWnd : [in] Handle of new owner window. 
//    rcDisp: [in] The display area. If the parameter is not set,
//            it will be set as RC_WHOLE_WINDOWN_AREA which means thai
//            the whole window is for displaying the video.
//
//----------------------------------------------------------
BOOL CMedia::SetVideoWindow(HWND hWndVideo,const RECT &rcDisp)
{
    m_hWndVideo 
= hWndVideo;
    
    m_rcDisp 
= rcDisp;

    
if(m_pVW == NULL)
    {
        
return FALSE;
    }

    
if(FAILED(m_pVW->put_Owner((OAHWND)hWndVideo)))
    {
        
return FALSE;
    }

    
if(FAILED(m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)))
    {
        
return FALSE;
    }

    
//Set play mode in order to notify the displayed area
    return SetDisplayMode(m_DispMode);
}



//------------------------------------------------------------
//Description:
//    Check the file visibility
//    When you call the function,you should call Open() before.
//
//Parameters:
//    TRUE: Video
//    FALSE: It's not the video 
//
//------------------------------------------------------------
BOOL CMedia::CheckVisibility()
{
    
    
    
if (!m_pVW)
    {
        
//No VideoWindow interface.  Assuming audio/MIDI file or unsupported video codec
        return FALSE;
    }
    
    
if (!m_pBV)
    {
        
//No BasicVideo interface.  Assuming audio/MIDI file or unsupported video codec.
        return FALSE;
    }
    
    
    
// If this is an audio-only clip, get_Visible() won't work.
    
//
    
// Also, if this video is encoded with an unsupported codec,
    
// we won't see any video, although the audio will work if it is
    
// of a supported format.
    long lVisible;
    
return SUCCEEDED(m_pVW->get_Visible(&lVisible));
    
}




//------------------------------------------------------------
//Description:
//    Release the resource which opened in the Open()    
//
//------------------------------------------------------------
void CMedia::Close()
{

    
// Relinquish ownership (IMPORTANT!) after hiding
    if(m_pVW != NULL)
    {
        m_pVW
->put_Visible(OAFALSE);
        m_pVW
->put_Owner(NULL);
    }

    
if(m_pMC != NULL)
    {
        m_pMC
->Release();
        m_pMC 
= NULL;
    }

    
if(m_pME != NULL)
    {
        m_pME
->SetNotifyWindow(NULL,NULL,NULL);

        m_pME
->Release();
        m_pME 
= NULL;
    }

    
if(m_pMS != NULL)
    {
        m_pMS
->Release();
        m_pMS 
= NULL;
    }

    
if(m_pBV != NULL)
    {
        m_pBV
->Release();
        m_pBV 
= NULL;
    }
    
    
if(m_pBA != NULL)
    {
        m_pBA
->Release();
        m_pBA 
= NULL;
    }
    
    
if(m_pVW != NULL)
    {
        m_pVW
->Release();
        m_pVW 
= NULL;
    }

    
if(m_pGB != NULL)
    {
        m_pGB
->Release();
        m_pGB 
= NULL;
    }

    
// Finished with COM
    memset(m_szFileName,0,sizeof(m_szFileName));


    CoUninitialize();
}


//------------------------------------------------------------
//Description:
//    Get the instance of object
//
//------------------------------------------------------------
CMedia * CMedia::GetInstance()
{
    
if(m_pInstance == NULL)
    {
        m_pInstance 
= new CMedia();
    }

    
return m_pInstance;
}




//------------------------------------------------------------
//Description:
//    Get the media file property.
//    When you call the function,you should call Open() before.
//
//------------------------------------------------------------
BOOL CMedia::GetMediaProperty(PMEDIAPROPERTY pOutProperty)
{

    MEDIAPROPERTY prop 
= {0};

    
if(m_pBA == NULL && m_pBV == NULL && m_pMS == NULL)
    {
        
return FALSE;
    }


    
//Get the audio property
    if(m_pBA != NULL)
    {
        m_pBA
->get_Volume(&prop.lVolume);
        m_pBA
->get_Balance(&prop.lBalance);
    }


    
//Get the video property
    if(CheckVisibility() == TRUE && m_pBV != NULL)
    {        
        m_pBV
->get_BitRate(&prop.lBitRate);
        m_pBV
->GetVideoSize(&prop.lWidth,&prop.lHeight);        
    }


    
//Get the seeking property
    if(m_pMS != NULL)
    {
        m_pMS
->GetDuration(&prop.llDuration);
        m_pMS
->GetAvailable(&prop.llAvailableEarliest,&prop.llAvailableLatest);
    }



    
*pOutProperty = prop;


    
return TRUE;
}


//------------------------------------------------------------
//Description:
//    Set the display mode.
//    When you call the function,you should call SetVideoWindow() before.
//If the parent windows (m_hWndVideo) is NULL, the display area would be set to zero.
//
//------------------------------------------------------------
BOOL CMedia::SetDisplayMode(DISPLAYMODE mode)
{

    
if(m_pVW == NULL)
    {
        
return FALSE;
    }

    
if(m_hWndVideo == NULL)
    {
        m_pVW
->put_Left(0);
        m_pVW
->put_Top(0);
        m_pVW
->put_Width(0);
        m_pVW
->put_Height(0);

        
return FALSE;
    }

    m_DispMode 
= mode;

    
if(mode == DISP_FULLSCREEN)
    {
        m_pVW
->put_FullScreenMode(OATRUE);
    }
    
else
    {
        
//Restore to the normal mode
        m_pVW->put_FullScreenMode(OAFALSE);
        
        RECT rcWnd 
= m_rcDisp;
        
if(rcWnd.left == RC_WHOLE_WINDOWN_AREA.left &&
            rcWnd.top 
== RC_WHOLE_WINDOWN_AREA.top &&
            rcWnd.right 
== RC_WHOLE_WINDOWN_AREA.right &&
            rcWnd.bottom 
== RC_WHOLE_WINDOWN_AREA.bottom )
        {
            GetClientRect(m_hWndVideo,
&rcWnd);
        }
        LONG lWndWidth 
= rcWnd.right - rcWnd.left;
        LONG lWndHeight 
= rcWnd.bottom - rcWnd.top;

        MEDIAPROPERTY prop 
= {0};
        GetMediaProperty(
&prop);


        
if(mode == DISP_FIT || mode == DISP_NATIVE)
        {
            LONG lDispLeft,lDispTop,lDispWidth,lDispHeight;

            
if(mode == DISP_NATIVE && lWndWidth >= prop.lWidth && lWndHeight >= prop.lHeight)
            {
                lDispLeft 
= (lWndWidth - prop.lWidth) / 2 + rcWnd.left;
                lDispTop 
= (lWndHeight - prop.lHeight) / 2 + rcWnd.top;
                lDispWidth 
= prop.lWidth ;
                lDispHeight 
= prop.lHeight ;
            }
            
else
            {
                
if(prop.lWidth * lWndHeight > lWndWidth * prop.lHeight)
                {
                    lDispWidth 
= lWndWidth;                
                    lDispHeight 
= (LONG)((float)lDispWidth / (float)prop.lWidth * prop.lHeight);
                    lDispLeft 
= rcWnd.left;
                    lDispTop 
= (lWndHeight - lDispHeight) / 2 + rcWnd.top;        
                }
                
else if(prop.lWidth * lWndHeight < lWndWidth * prop.lHeight)
                {
                    lDispHeight 
= lWndHeight;
                    lDispWidth 
= (LONG)((float)lDispHeight / (float)prop.lHeight * prop.lWidth);
                    lDispLeft 
= (lWndWidth - lDispWidth) / 2 + rcWnd.left;
                    lDispTop 
= rcWnd.top;
                }
                
else
                {
                    lDispWidth 
= lWndWidth;                
                    lDispHeight 
= lWndHeight;
                    lDispLeft 
= rcWnd.left;
                    lDispTop 
= rcWnd.top;
                }
            }

            



            m_pVW
->put_Left(lDispLeft);
            m_pVW
->put_Top(lDispTop);
            m_pVW
->put_Width(lDispWidth);
            m_pVW
->put_Height(lDispHeight);
        }
        
else if(mode == DISP_STRETCH)
        {

            m_pVW
->put_Left(rcWnd.left);
            m_pVW
->put_Top(rcWnd.top);
            m_pVW
->put_Width(lWndWidth);
            m_pVW
->put_Height(lWndHeight);
        }
    
    }



    
return TRUE;
}


//------------------------------------------------------------
//Description:
//    Set the volume.
//    When you call the function,you should call Open() before.
//
//Parameters:
//    lVolume:[in] The volume (amplitude) of the audio signal. 
//            Range is –10,000 to 0.
//    lBalance:[in]  The balance for the audio signal. Default value is 0.
//            The value from –10,000 to 10,000 indicating the stereo balance.
//
//------------------------------------------------------------
BOOL CMedia::SetVolume(LONG lVolume, LONG lBalance)
{
    
if(m_pBA == NULL)
    {
        
return FALSE;
    }

    
if(lVolume < MIN_VOLUME && lVolume > MAX_VOLUME && lBalance < MIN_BALANCE && lBalance > MAX_BALANCE)
    {
        
return FALSE;
    }

    m_pBA
->put_Volume(lVolume);
    m_pBA
->put_Balance(lBalance);

    
return TRUE;
}




//----------------------------------------------------------------------
//Description:
//    Registers a window that will handle the notified message when a specified event occurs and some window message
//
//Parameters:
//    hWnd:[in] Handle of window to notify. Pass NULL to stop notification. 
//    wMsg:[in] Window message to be passed as the notification. 
//    lInstanceData:[in] Value (instance data) to be passed as the lParam parameter for the lMsg message.
//
//Remarks:
//    When the notified window receive the wMsg as the notification, you could get the event code.
//    The follow codes show that process:
//
//        //"WM_GRAPHNOTIFY" is the user-define notified message
//        case WM_GRAPHNOTIFY:
//        {
//            LONG evCode,evParam1,evParam2;
//
//            //"m_pMedia" is the instance of the CMedia
//            if(m_pMedia->GetEvent(&evCode,&evParam1,&evParam2) == TRUE)
//            {                
//                //Check the event code
//                if(evCode == EC_COMPLETE)
//                {
//                    //Do something
//                }
//            }
//            return 0;
//        } 
//
//    The event code is as follow:
// EC_ACTIVATE                     An audio or video renderer is losing or gaining activation.  
// EC_BUFFERING_DATA               The buffering status is changing.  
// EC_CLOCK_CHANGED                The filter graph has changed from one reference clock to another.  
// EC_COMPLETE                     All data has been rendered.  
// EC_DRM_LEVEL                    Notifies when content protected by digital rights management (DRM) requests some form of analog content protection. 
// EC_END_OF_SEGMENT               Notifies that a segment end has been reached.  
// EC_ERROR_STILLPLAYING           At least one call to Run failed in an active filter graph. 
//                                    The current state of any underlying filter graph or graphs is indeterminate; they might be running, but some are almost certainly not. 
// EC_ERRORABORT                   An error forced the termination of a requested operation.  
// EC_FULLSCREEN_LOST              The video renderer is switching out of full-screen mode.  
// EC_NEED_RESTART                 The current graph must be stopped and restarted.  
// EC_NOTIFY_WINDOW                Pass the window handle around during pin connection.  
// EC_OLE_EVENT                    A filter is passing a text string to the application.  
// EC_OPENING_FILE                 The open file status is changing.  
// EC_PALETTE_CHANGED              The video palette has changed.  
// EC_QUALITY_CHANGE               The playback quality has changed.  
// EC_REPAINT                      A repaint is required.  
// EC_SEGMENT_STARTED              Notifies that a new segment has been started.  
// EC_SHUTTING_DOWN                The filter graph is starting to shut down. 
//                                    DirectShow passes this notification to any plug-in distributors that support the IMediaEventSink interface. 
// EC_STARVATION                   One of the filters (usually a parser or file source filter) is not receiving enough data. 
//                                    By default, the filter graph manager will pause all running filters and then return to normal operation when enough data is available. 
// EC_STREAM_CONTROL_STARTED       The starting reference time from an earlier call to IAMStreamControl::StartAt passed.  
// EC_STREAM_CONTROL_STOPPED       The stopping reference time from an earlier call to IAMStreamControl::StopAt passed.  
// EC_STREAM_ERROR_STILLPLAYING    The stream is still playing, but should not be playing.  
// EC_STREAM_ERROR_STOPPED         The stream has stopped, but should not have stopped.  
// EC_TIME                         The requested reference time occurred.  
// EC_USERABORT                    A user has forced the termination of a requested operation.  
// EC_VIDEO_SIZE_AR_CHANGED        The size or aspect ratio of the native video has changed.  
// EC_VIDEO_SIZE_CHANGED           The size of the native video has changed.  
// EC_WINDOW_DESTROYED             The video renderer's filter is being removed or destroyed.  
//
//
//
//    DirectShow passes the following messages to the window specified by the hWnd parameter, 
//if and when the application generates them: 
// WM_KEYDOWN 
// WM_KEYUP 
// WM_LBUTTONDBLCLK 
// WM_LBUTTONDOWN 
// WM_LBUTTONUP 
// WM_MBUTTONDBLCLK 
// WM_MBUTTONDOWN 
// WM_MBUTTONUP 
// WM_MOUSEACTIVATE 
// WM_MOUSEMOVE 
// WM_RBUTTONDBLCLK 
// WM_RBUTTONDOWN 
// WM_RBUTTONUP 
//-----------------------------------------------------------------------------
BOOL CMedia::SetNotifyWindow(HWND hWnd, UINT wMsg,long lInstanceData)
{


    
if(m_pME == NULL)
    {
        
return FALSE;
    }

    HRESULT hr;
    hr 
= m_pME->SetNotifyWindow((OAHWND)hWnd,wMsg,lInstanceData);
    
if(FAILED(hr))
    {
        
return FALSE;
    }

    
if(CheckVisibility() == TRUE && m_pVW != NULL)
    {
        hr 
= m_pVW->put_MessageDrain((OAHWND)hWnd);
    }
    

    
    
    
return SUCCEEDED(hr);
}


//----------------------------------------------------------------------
//Description:
//    This method retrieves the notification event. 
//
//-----------------------------------------------------------------------
BOOL CMedia::GetEvent(LONG *plEvCode, LONG *plParam1, LONG *plParam2)
{
    
if(m_pME == NULL)
    {
        
return FALSE;
    }

    LONG evCode, evParam1, evParam2;    

    
if(SUCCEEDED(m_pME->GetEvent(&evCode, &evParam1, &evParam2, 0)) == TRUE)
    {
        
*plEvCode = evCode;
        
*plParam1 = evParam1;
        
*plParam2 = evParam2;

        
// Spin through the events
        m_pME->FreeEventParams(evCode, evParam1, evParam2);        
    }
    
else
    {
        
return FALSE;
    }
    

    
return TRUE;
}


//----------------------------------------------------------------------
//Description:
//    This method sets a new playback rate. 
//
//Parameters
//    dRate:[in] New rate, where 1 is the normal rate, 2 is twice as fast, and so on. 

//-----------------------------------------------------------------------
BOOL CMedia::SetRate(double dRate)
{
    
if(m_pMS == NULL)
    {
        
return FALSE;
    }
    
return SUCCEEDED(m_pMS->SetRate(dRate));
}


//----------------------------------------------------------------------
//Description:
//    This method retrieves the current rate.
//
//Parameters:
//    pdRate:[out] The rate
//-----------------------------------------------------------------------
BOOL CMedia::GetRate(double *pdRate)
{
    
if(m_pMS == NULL)
    {
        
return FALSE;
    }

    
return SUCCEEDED(m_pMS->GetRate(pdRate));

}

//----------------------------------------------------------------------
//Description:
//    This method retrieves the current position in terms of the total length of the media stream
//
//Parameters:
//    pllPos:[out]Current position.
//-----------------------------------------------------------------------
BOOL CMedia::GetPositionCurrent(LONGLONG *pllPos)
{
    
if(m_pMS == NULL)
    {
        
return FALSE;
    }

    
if(m_dwCapability & AM_SEEKING_CanGetCurrentPos == 0)
    {
        
return FALSE;
    }

    
return SUCCEEDED(m_pMS->GetCurrentPosition(pllPos));
}

//----------------------------------------------------------------------
//Description:
//    This method sets current positions
//
//Parameters:
//    llPos:[in]Start position if stopped, or position from which to continue if paused. 
//-----------------------------------------------------------------------
BOOL CMedia::SetPositionCurrent(LONGLONG llPos)
{
    
if(m_pMS == NULL)
    {
        
return FALSE;
    }

    LONGLONG llCur 
= 0;
    
if(GetPositionCurrent(&llCur) == TRUE)
    {
        
if((llCur > llPos) && (m_dwCapability & AM_SEEKING_CanSeekBackwards == 0))
        {
            
return FALSE;
        }
        
else if((llCur < llPos) && (m_dwCapability & AM_SEEKING_CanSeekForwards == 0))
        {            
            
return FALSE;            
        }
        
else if(llCur == llPos)
        {
            
//It's the current positon, needn't set
            return TRUE;
        }
    }
    
else if((m_dwCapability & AM_SEEKING_CanSeekBackwards == 0|| (m_dwCapability & AM_SEEKING_CanSeekForwards == 0))
    {
        
return FALSE;
    }


    
return SUCCEEDED(m_pMS->SetPositions(&llPos,AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning));
}


//----------------------------------------------------------------------
//Description:
//    This method get current display mode
//
//----------------------------------------------------------------------
DISPLAYMODE CMedia::GetDisplayMode()
{
    
return m_DispMode;
}


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1712083

 
原创粉丝点击