697 lines
25 KiB
C
697 lines
25 KiB
C
|
//==========================================================================;
|
||
|
//
|
||
|
// playbackimpl.h : additional infrastructure to support implementing IMSVidPlayback
|
||
|
// nicely from c++
|
||
|
// Copyright (c) Microsoft Corporation 1999.
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#ifndef PLAYBACKIMPL_H
|
||
|
#define PLAYBACKIMPL_H
|
||
|
#include <math.h>
|
||
|
#include "inputimpl.h"
|
||
|
#include <uuids.h>
|
||
|
namespace MSVideoControl {
|
||
|
|
||
|
#define BACKWARDS_STEPPING 0
|
||
|
const long nano_to_hundredths = 100000;
|
||
|
template<class T, LPCGUID LibID, LPCGUID KSCategory, class MostDerivedInterface = IMSVidPlayback>
|
||
|
class DECLSPEC_NOVTABLE IMSVidPlaybackImpl :
|
||
|
public IMSVidInputDeviceImpl<T, LibID, KSCategory, MostDerivedInterface> {
|
||
|
protected:
|
||
|
bool m_fEnableResetOnStop;
|
||
|
public:
|
||
|
IMSVidPlaybackImpl():
|
||
|
m_fEnableResetOnStop(false) {}
|
||
|
|
||
|
virtual ~IMSVidPlaybackImpl() {}
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
// Name:
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
STDMETHOD(get_Length)(/*[out, retval]*/long *lLength){
|
||
|
HRESULT hr = S_OK;
|
||
|
LONGLONG tempval;
|
||
|
PositionModeList curMode;
|
||
|
try{
|
||
|
// Checking args and init'ing interfaces
|
||
|
if (!lLength){
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
if (!m_pGraph) {
|
||
|
// graph not valid
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
|
||
|
}
|
||
|
|
||
|
// See if object supports IMediaSeeking
|
||
|
PQMediaSeeking PQIMSeeking(m_pGraph);
|
||
|
if(PQIMSeeking){
|
||
|
// Find out what postion mode is being used
|
||
|
hr = get_PositionMode(&curMode);
|
||
|
if(FAILED(hr)){
|
||
|
return hr;
|
||
|
}
|
||
|
hr = PQIMSeeking->GetDuration(&tempval);
|
||
|
if(FAILED(hr)){
|
||
|
return hr;
|
||
|
}
|
||
|
// If it is FrameMode no conversion needed
|
||
|
if(curMode == FrameMode){
|
||
|
*lLength = static_cast<long>(tempval);
|
||
|
hr = S_OK;
|
||
|
return hr;
|
||
|
}
|
||
|
// If it is TenthsSecondsMode need to be converted from 100 nanosecond units
|
||
|
else if(curMode == TenthsSecondsMode){
|
||
|
*lLength = static_cast<long>(tempval / nano_to_hundredths);
|
||
|
hr = S_OK;
|
||
|
return hr;
|
||
|
}
|
||
|
// If it is some other mode not supported by the vidctl
|
||
|
else{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// See if object supports IMediaPostion
|
||
|
PQMediaPosition PQIMPos(m_pGraph);
|
||
|
if(PQIMPos){
|
||
|
// Get position
|
||
|
double tempDub;
|
||
|
hr = PQIMPos->get_CurrentPosition(&tempDub);
|
||
|
// IMediaPostion only supports 100 Nanosecond units
|
||
|
*lLength = static_cast<long>(tempDub / nano_to_hundredths);
|
||
|
hr = S_OK;
|
||
|
return hr;
|
||
|
}
|
||
|
// Could Not QI IMedia Seeking or Position
|
||
|
return ImplReportError(__uuidof(T), IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
|
||
|
|
||
|
}
|
||
|
|
||
|
catch(HRESULT hrTmp){
|
||
|
// Something went bad, threw a HRESULT
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
|
||
|
}
|
||
|
catch(...){
|
||
|
// Something went bad, dont know what it threw
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
// Name: get_CurrentPosition(LONGLONG*)
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
STDMETHOD(get_CurrentPosition)(/*[out,retval]*/long *lPosition) {
|
||
|
HRESULT hr = S_OK;
|
||
|
LONGLONG tempval;
|
||
|
PositionModeList curMode;
|
||
|
try{
|
||
|
// Checking args and init'ing interfaces
|
||
|
if (!lPosition){
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
if (!m_pGraph) {
|
||
|
// graph not valid
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
|
||
|
}
|
||
|
|
||
|
// See if object supports IMediaSeeking
|
||
|
PQMediaSeeking PQIMSeeking(m_pGraph);
|
||
|
if(PQIMSeeking){
|
||
|
// Find out what postion mode is being used
|
||
|
hr = get_PositionMode(&curMode);
|
||
|
if(FAILED(hr)){
|
||
|
return hr;
|
||
|
}
|
||
|
hr = PQIMSeeking->GetCurrentPosition(&tempval);
|
||
|
if(FAILED(hr)){
|
||
|
return hr;
|
||
|
}
|
||
|
// If it is FrameMode no conversion needed
|
||
|
if(curMode == FrameMode){
|
||
|
*lPosition = static_cast<long>(tempval);
|
||
|
hr = S_OK;
|
||
|
return hr;
|
||
|
}
|
||
|
// If it is TenthsSecondsMode need to be converted from 100 nanosecond units
|
||
|
else if(curMode == TenthsSecondsMode){
|
||
|
*lPosition = static_cast<long>(tempval / nano_to_hundredths);
|
||
|
hr = S_OK;
|
||
|
return hr;
|
||
|
}
|
||
|
// If it is some other mode not supported by the vidctl
|
||
|
else{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// See if object supports IMediaPostion
|
||
|
PQMediaPosition PQIMPos(m_pGraph);
|
||
|
if(PQIMPos){
|
||
|
// Get position
|
||
|
double tempDub;
|
||
|
hr = PQIMPos->get_CurrentPosition(&tempDub);
|
||
|
// IMediaPostion only supports 100 Nanosecond units
|
||
|
*lPosition = static_cast<long>(tempDub / nano_to_hundredths);
|
||
|
hr = S_OK;
|
||
|
return hr;
|
||
|
}
|
||
|
// Could Not QI IMedia Seeking or Position
|
||
|
return ImplReportError(__uuidof(T), IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
|
||
|
|
||
|
}
|
||
|
|
||
|
catch(HRESULT hrTmp){
|
||
|
// Something went bad, threw a HRESULT
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
|
||
|
}
|
||
|
catch(...){
|
||
|
// Something went bad, dont know what it threw
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
// Name: put_CurrentPosition(LONGLONG)
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
STDMETHOD(put_CurrentPosition)(/*[in]*/long lPosition) {
|
||
|
HRESULT hr = S_OK;
|
||
|
LONGLONG tempval = 0;
|
||
|
PositionModeList curMode;
|
||
|
LONG curPos;
|
||
|
try{
|
||
|
// Checking args and interfaces
|
||
|
if (!m_pGraph) {
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
|
||
|
}
|
||
|
|
||
|
hr = get_CurrentPosition(&curPos);
|
||
|
if(curPos == lPosition){
|
||
|
return NOERROR;
|
||
|
}
|
||
|
// Check for a IMediaSeeking Interface
|
||
|
PQMediaSeeking PQIMSeeking(m_pGraph);
|
||
|
if(PQIMSeeking){
|
||
|
// Get the position Mode
|
||
|
hr = get_PositionMode(&curMode);
|
||
|
if(FAILED(hr)){
|
||
|
return hr;
|
||
|
}
|
||
|
tempval = lPosition;
|
||
|
// If it is in TenthsSecondsMode convert input into 100 nanosecond units
|
||
|
if(curMode == TenthsSecondsMode){
|
||
|
tempval = static_cast<LONGLONG>(lPosition);
|
||
|
tempval = tempval * nano_to_hundredths;
|
||
|
}
|
||
|
// If it is in some other mode
|
||
|
else if(curMode != FrameMode){
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
// Set the new Position
|
||
|
#if 0
|
||
|
if(curPos > lPosition && !m_pGraph.IsStopped()){
|
||
|
|
||
|
DWORD seekingFlags = AM_SEEKING_CanSeekBackwards;
|
||
|
hr = PQIMSeeking->CheckCapabilities(&seekingFlags);
|
||
|
if(FAILED(hr)){
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
hr = PQIMSeeking->SetPositions(&tempval, AM_SEEKING_AbsolutePositioning, NULL, 0);
|
||
|
return hr;
|
||
|
}
|
||
|
// Check for a IMediaPostion
|
||
|
PQMediaPosition PQIMPos(m_pGraph);
|
||
|
if(PQIMPos){
|
||
|
if(curPos > lPosition && !m_pGraph.IsStopped()){
|
||
|
long canSeekBackwardRetVal;
|
||
|
PQIMPos->CanSeekBackward(&canSeekBackwardRetVal);
|
||
|
if(canSeekBackwardRetVal != -1){// OATRUE = -1
|
||
|
return E_INVALIDARG;
|
||
|
}
|
||
|
}
|
||
|
// IMediaPosition only does 100 nanosecond units
|
||
|
double tempDub = lPosition;
|
||
|
tempDub = tempDub * nano_to_hundredths;
|
||
|
hr = PQIMPos->put_CurrentPosition(tempDub);
|
||
|
return hr;
|
||
|
}
|
||
|
// Could Not QI Media Position or Seeking
|
||
|
return ImplReportError(__uuidof(T), IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
|
||
|
|
||
|
}
|
||
|
|
||
|
catch(HRESULT hrTmp){
|
||
|
// Something went bad, threw a HRESULT
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
|
||
|
}
|
||
|
catch(...){
|
||
|
// Something went bad, dont know what it threw
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
// Name: put_PositionMode(LONGLONG)
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHOD(put_PositionMode)(/*[in]*/PositionModeList lPositionMode) {
|
||
|
HRESULT hr = S_OK;
|
||
|
double testval;
|
||
|
get_Rate(&testval);
|
||
|
try{
|
||
|
// Checking args and interfaces
|
||
|
if (!m_pGraph) {
|
||
|
// graph not valid
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
|
||
|
}
|
||
|
// only valid values
|
||
|
if(lPositionMode != FrameMode && lPositionMode != TenthsSecondsMode){
|
||
|
return E_INVALIDARG;
|
||
|
}
|
||
|
// Try for a IMediaSeeking
|
||
|
PQMediaSeeking PQIMSeeking(m_pGraph);
|
||
|
if(PQIMSeeking){
|
||
|
// Set the new mode
|
||
|
if(lPositionMode == FrameMode){
|
||
|
return PQIMSeeking->SetTimeFormat( &( static_cast<GUID>(TIME_FORMAT_FRAME) ) );
|
||
|
}
|
||
|
if(lPositionMode == TenthsSecondsMode){
|
||
|
return PQIMSeeking->SetTimeFormat(&(static_cast<GUID>(TIME_FORMAT_MEDIA_TIME)));
|
||
|
}
|
||
|
}
|
||
|
// Try for a IMediaPosition
|
||
|
PQMediaPosition PQIMPos(m_pGraph);
|
||
|
if(PQIMPos){
|
||
|
// Only supports TenthsSecondsMode
|
||
|
if(lPositionMode == TenthsSecondsMode){
|
||
|
return S_OK;
|
||
|
}
|
||
|
else{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
}
|
||
|
// Could Not QI
|
||
|
return ImplReportError(__uuidof(T), IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
|
||
|
|
||
|
}
|
||
|
|
||
|
catch(HRESULT hrTmp){
|
||
|
// Something went bad, threw a HRESULT
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
|
||
|
}
|
||
|
catch(...){
|
||
|
// Something went bad, dont know what it threw
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
// Name: get_PositionMode(LONGLONG*)
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
STDMETHOD(get_PositionMode)(/*[out,retval]*/PositionModeList* lPositionMode) {
|
||
|
HRESULT hr = S_OK;
|
||
|
double testval;
|
||
|
get_Rate(&testval);
|
||
|
try{
|
||
|
// Checking args and interfaces
|
||
|
if(!lPositionMode){
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
if (!m_pGraph) {
|
||
|
// graph not valid
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
|
||
|
}
|
||
|
// Get an IMediaSeeking Interface
|
||
|
PQMediaSeeking PQIMSeeking(m_pGraph);
|
||
|
if(PQIMSeeking){
|
||
|
// Get the mode
|
||
|
GUID cur_mode;
|
||
|
hr = PQIMSeeking->GetTimeFormat(&cur_mode);
|
||
|
if(FAILED(hr)){
|
||
|
return hr;
|
||
|
}
|
||
|
// Check to see which mode it is in
|
||
|
if(cur_mode == static_cast<GUID>(TIME_FORMAT_FRAME)){
|
||
|
*lPositionMode = FrameMode;
|
||
|
return S_OK;
|
||
|
}
|
||
|
if(cur_mode == static_cast<GUID>(TIME_FORMAT_MEDIA_TIME)){
|
||
|
*lPositionMode = TenthsSecondsMode;
|
||
|
return S_OK;
|
||
|
}
|
||
|
// Not in a vidctl supported mode
|
||
|
else{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
}
|
||
|
// Get IMediaPosition
|
||
|
PQMediaPosition PQIMPos(m_pGraph);
|
||
|
if(PQIMPos){
|
||
|
// Only supports TenthsSecondsMode
|
||
|
*lPositionMode = TenthsSecondsMode;
|
||
|
return S_OK;
|
||
|
}
|
||
|
// Could Not QI
|
||
|
return ImplReportError(__uuidof(T), IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
|
||
|
|
||
|
}
|
||
|
|
||
|
catch(HRESULT hrTmp){
|
||
|
// Something went bad, threw a HRESULT
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
|
||
|
}
|
||
|
catch(...){
|
||
|
// Something went bad, dont know what it threw
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
STDMETHOD(get_Duration)(double *dPos) {
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
STDMETHOD(get_PrerollTime)(double *dPos) {
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
STDMETHOD(put_PrerollTime)(double dPos) {
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
STDMETHOD(get_StartTime)(double *StartTime) {
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
STDMETHOD(put_StartTime)(double StartTime) {
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
STDMETHOD(get_StopTime)(double *StopTime) {
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
STDMETHOD(put_StopTime)(double StopTime) {
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
// Name: get_EnableResetOnStop(VARIANT_BOOL*)
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
STDMETHOD(get_EnableResetOnStop)(/*[out, retval]*/ VARIANT_BOOL *pVal){
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
try {
|
||
|
if(NULL == pVal){
|
||
|
throw(E_POINTER);
|
||
|
}
|
||
|
|
||
|
if(m_fEnableResetOnStop == true){
|
||
|
*pVal = VARIANT_TRUE;
|
||
|
}
|
||
|
else{
|
||
|
*pVal = VARIANT_FALSE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
catch(HRESULT hrTmp){
|
||
|
hr = hrTmp;
|
||
|
}
|
||
|
|
||
|
catch(...){
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}// end of function get_EnableResetOnStop
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
// Name: put_EnableResetOnStop(VARIANT_BOOL)
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
STDMETHOD(put_EnableResetOnStop)(/*[in]*/ VARIANT_BOOL newVal){
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
try {
|
||
|
if(newVal == VARIANT_TRUE){
|
||
|
m_fEnableResetOnStop = true;
|
||
|
}
|
||
|
else{
|
||
|
m_fEnableResetOnStop = false;
|
||
|
}
|
||
|
}
|
||
|
catch(...){
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}// end of function put_EnableResetOnStop
|
||
|
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
// Name: get_CanStep(VARIANT_BOOL, VARIANT_BOOL*)
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
STDMETHOD(get_CanStep)(VARIANT_BOOL fBackwards, VARIANT_BOOL *pfCan){
|
||
|
// NOTE: NO ONE supports backwords stepping (why not? who knows)
|
||
|
// so just like everyone else we dont either
|
||
|
try{
|
||
|
// Checking args and interfaces
|
||
|
|
||
|
if(NULL == pfCan){
|
||
|
// Passed a NULL Pointer
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
|
||
|
if (!m_pGraph) {
|
||
|
// graph not valid
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
|
||
|
}
|
||
|
|
||
|
//Get a VideoFrameStep Interface
|
||
|
PQVideoFrameStep pVFS(m_pGraph);
|
||
|
if(!pVFS){
|
||
|
// Could Not QI
|
||
|
return ImplReportError(__uuidof(T), IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
|
||
|
}
|
||
|
|
||
|
|
||
|
#if BACKWARDS_STEPPING // Checking for Backward Stepping should always be 0
|
||
|
if(fBackwards == VARIANT_TRUE){
|
||
|
// Backwords Stepping Not Supported Most Likely
|
||
|
if(pVFS->CanStep(TRUE, NULL)==S_OK){
|
||
|
// It is all Good, Can Step Backwords
|
||
|
*pfCan = VARIANT_TRUE;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
*pfCan = VARIANT_FALSE;
|
||
|
return S_OK;
|
||
|
}
|
||
|
#else // Still checking for Backward Stepping
|
||
|
if(fBackwards == VARIANT_TRUE){
|
||
|
*pfCan = VARIANT_FALSE;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
#endif // End checking for Backward Stepping
|
||
|
|
||
|
// Checking for Forward Stepping
|
||
|
else{
|
||
|
if(pVFS->CanStep(FALSE, NULL)==S_OK){
|
||
|
// It is all Good, Can Step Forward
|
||
|
*pfCan = VARIANT_TRUE;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
else{
|
||
|
// Can't Step
|
||
|
*pfCan = VARIANT_FALSE;
|
||
|
return S_OK;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch(HRESULT hrTmp){
|
||
|
// Something went bad, threw a HRESULT
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
|
||
|
}
|
||
|
catch(...){
|
||
|
// Something went bad, dont know what it threw
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
// Name: Step(long)
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
STDMETHOD(Step)(long lStep){
|
||
|
try{
|
||
|
// Checking args and interfaces
|
||
|
|
||
|
if (!m_pGraph) {
|
||
|
// graph not valid
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
|
||
|
}
|
||
|
|
||
|
PQVideoFrameStep pVFS(m_pGraph);
|
||
|
|
||
|
if(!pVFS){
|
||
|
// Could Not QI
|
||
|
return ImplReportError(__uuidof(T), IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
|
||
|
|
||
|
}
|
||
|
|
||
|
#if BACKWARDS_STEPPING // Checking for Backward Stepping should always be 0
|
||
|
// If backwords stepping set rate or what ever needs to be done
|
||
|
|
||
|
if(lStep < 0){
|
||
|
// Backwords Stepping Not Supported Most Likely
|
||
|
if(pVFS->CanStep(TRUE, NULL)==S_OK){
|
||
|
// It is all Good, Can Step Backwords
|
||
|
CComQIPtr<IMediaPosition> IMPos(m_pGraph);
|
||
|
CComQIPtr<IMediaControl> IMCon(m_pGraph);
|
||
|
if(IMPos&&IMCon){
|
||
|
OAFilterState enterState;
|
||
|
IMCon->GetState(INFINITE , &enterState);
|
||
|
HRESULT hr = IMPos->put_Rate(1);
|
||
|
if(SUCCEEDED(hr)){
|
||
|
hr = pVFS->Step((-lStep), NULL);
|
||
|
if(SUCCEEDED(hr)){
|
||
|
return S_OK;
|
||
|
}
|
||
|
else{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// Backwords stepping not supported
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
#else // Still checking for Backward Stepping
|
||
|
|
||
|
if(lStep < 0){
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
#endif // End checking for Backward Stepping
|
||
|
// Make it step
|
||
|
return pVFS->Step(lStep, NULL);
|
||
|
}
|
||
|
|
||
|
catch(HRESULT hrTmp){
|
||
|
// Something went bad, threw a HRESULT
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
|
||
|
}
|
||
|
catch(...){
|
||
|
// Something went bad, dont know what it threw
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// note: the following methods control the playback device *NOT* the graph.
|
||
|
// if the underlying source filter only supports these functions via
|
||
|
// imediacontrol on the graph then this device segment object should return E_NOTIMPL.
|
||
|
STDMETHOD(Run)() {
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
STDMETHOD(Pause)() {
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
STDMETHOD(Stop)() {
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
// Name: put_Rate(double)
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
STDMETHOD(put_Rate)(double lRate){
|
||
|
HRESULT hr = S_OK;
|
||
|
try{
|
||
|
/*** Checking args and init'ing interfaces ***/
|
||
|
|
||
|
if (!m_pGraph) {
|
||
|
// graph not valid
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
|
||
|
}
|
||
|
|
||
|
// Attempt to set the rate using IMediaSeeking
|
||
|
PQMediaSeeking PQIMSeeking(m_pGraph);
|
||
|
if(PQIMSeeking){
|
||
|
return PQIMSeeking->SetRate(lRate);
|
||
|
}
|
||
|
|
||
|
// If IMediaSeeking FAILS try IMediaPostion
|
||
|
PQMediaPosition PQIMPos(m_pGraph);
|
||
|
if(PQIMPos){
|
||
|
// Change rate
|
||
|
return PQIMPos->put_Rate((double)lRate);
|
||
|
}
|
||
|
|
||
|
// Could Not QI Either one set the error
|
||
|
return ImplReportError(__uuidof(T), IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
|
||
|
|
||
|
}
|
||
|
|
||
|
catch(HRESULT hrTmp){
|
||
|
// Something went bad, threw a HRESULT
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
|
||
|
}
|
||
|
catch(...){
|
||
|
// Something went bad, dont know what it threw
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
// Name: get_Rate(double*)
|
||
|
//-----------------------------------------------------------------------------------------
|
||
|
STDMETHOD(get_Rate)(double *plRate){
|
||
|
HRESULT hr = S_OK;
|
||
|
double curRate = 1;
|
||
|
try{
|
||
|
/*** Checking args and init'ing interfaces ***/
|
||
|
if (!plRate){
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
if (!m_pGraph) {
|
||
|
// graph not valid
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
|
||
|
}
|
||
|
PQMediaSeeking PQIMSeeking(m_pGraph);
|
||
|
if(PQIMSeeking){
|
||
|
hr = PQIMSeeking->GetRate(&curRate);
|
||
|
}
|
||
|
else{
|
||
|
PQMediaPosition PQIMPos(m_pGraph);
|
||
|
if(PQIMPos){
|
||
|
// Get rate
|
||
|
hr = PQIMPos->get_Rate(&curRate);
|
||
|
}
|
||
|
// Could Not QI
|
||
|
else{
|
||
|
return ImplReportError(__uuidof(T), IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(SUCCEEDED(hr)){
|
||
|
*plRate = curRate;
|
||
|
TRACELSM(TRACE_DETAIL, (dbgDump << "Playbackimpl::get_Rate() rate = " << curRate), "");
|
||
|
}
|
||
|
else{
|
||
|
TRACELSM(TRACE_ERROR, (dbgDump << "Playbackimpl::get_Rate() get_rate failed"), "");
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
catch(HRESULT hrTmp){
|
||
|
// Something went bad, threw a HRESULT
|
||
|
return ImplReportError(__uuidof(T), IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
|
||
|
}
|
||
|
catch(...){
|
||
|
// Something went bad, dont know what it threw
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
}; // namespace
|
||
|
|
||
|
#endif
|
||
|
// end of file - playbackimpl.h
|