354 lines
12 KiB
C++
354 lines
12 KiB
C++
//==========================================================================;
|
|
// MSVidVideoRenderer.h : Declaration of the CMSVidVideoRenderer
|
|
// copyright (c) Microsoft Corp. 1998-1999.
|
|
//==========================================================================;
|
|
|
|
#ifndef __MSVidVIDEORENDERER_H_
|
|
#define __MSVidVIDEORENDERER_H_
|
|
|
|
#pragma once
|
|
|
|
#include <algorithm>
|
|
#include <evcode.h>
|
|
#include <uuids.h>
|
|
#include <amvideo.h>
|
|
#include <strmif.h>
|
|
#include <objectwithsiteimplsec.h>
|
|
#include "vidrect.h"
|
|
#include "vidvidimpl.h"
|
|
#include "vrsegimpl.h"
|
|
#include "devimpl.h"
|
|
#include "seg.h"
|
|
#include "videorenderercp.h"
|
|
#include "strmif.h"
|
|
#include "resource.h" // main symbols
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMSVidVideoRenderer
|
|
class ATL_NO_VTABLE __declspec(uuid("37B03543-A4C8-11d2-B634-00C04F79498E")) CMSVidVideoRenderer :
|
|
public CComObjectRootEx<CComSingleThreadModel>,
|
|
public CComCoClass<CMSVidVideoRenderer, &__uuidof(CMSVidVideoRenderer)>,
|
|
public IObjectWithSiteImplSec<CMSVidVideoRenderer>,
|
|
public ISupportErrorInfo,
|
|
public CProxy_IMSVidVideoRenderer<CMSVidVideoRenderer>,
|
|
public IConnectionPointContainerImpl<CMSVidVideoRenderer>,
|
|
public IMSVidVideoRendererImpl<CMSVidVideoRenderer, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidVideoRenderer2>,
|
|
public IProvideClassInfo2Impl<&CLSID_MSVidVideoRenderer, &IID_IMSVidVideoRendererEvent, &LIBID_MSVidCtlLib>
|
|
{
|
|
public:
|
|
CMSVidVideoRenderer()
|
|
{
|
|
m_APid = -1;
|
|
m_compositorGuid = GUID_NULL;
|
|
m_opacity = -1;
|
|
m_rectPosition.top = -1;
|
|
m_rectPosition.left = -1;
|
|
m_rectPosition.bottom = -1;
|
|
m_rectPosition.right = -1;
|
|
m_SourceSize = sslFullSize;
|
|
m_lOverScan = 1;
|
|
}
|
|
virtual ~CMSVidVideoRenderer() {
|
|
m_PQIPicture.Release();
|
|
CleanupVMR();
|
|
}
|
|
|
|
REGISTER_AUTOMATION_OBJECT(IDS_PROJNAME,
|
|
IDS_REG_VIDEORENDERER_PROGID,
|
|
IDS_REG_VIDEORENDERER_DESC,
|
|
LIBID_MSVidCtlLib,
|
|
__uuidof(CMSVidVideoRenderer));
|
|
|
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
|
|
|
BEGIN_COM_MAP(CMSVidVideoRenderer)
|
|
COM_INTERFACE_ENTRY(IMSVidVideoRenderer)
|
|
COM_INTERFACE_ENTRY(IMSVidVRGraphSegment)
|
|
COM_INTERFACE_ENTRY(IMSVidGraphSegment)
|
|
COM_INTERFACE_ENTRY(IMSVidVideoRenderer2)
|
|
COM_INTERFACE_ENTRY(IMSVidOutputDevice)
|
|
COM_INTERFACE_ENTRY(IMSVidDevice)
|
|
COM_INTERFACE_ENTRY(IDispatch)
|
|
COM_INTERFACE_ENTRY(IObjectWithSite)
|
|
COM_INTERFACE_ENTRY(IConnectionPointContainer)
|
|
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
|
COM_INTERFACE_ENTRY(IPersist)
|
|
COM_INTERFACE_ENTRY(IProvideClassInfo2)
|
|
COM_INTERFACE_ENTRY(IProvideClassInfo)
|
|
END_COM_MAP()
|
|
|
|
BEGIN_CATEGORY_MAP(CMSVidVideoRenderer)
|
|
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
|
|
IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
|
|
IMPLEMENTED_CATEGORY(CATID_PersistsToPropertyBag)
|
|
END_CATEGORY_MAP()
|
|
|
|
BEGIN_CONNECTION_POINT_MAP(CMSVidVideoRenderer)
|
|
// CONNECTION_POINT_ENTRY(IID_IMSVidVideoRendererEvent2)
|
|
CONNECTION_POINT_ENTRY(IID_IMSVidVideoRendererEvent)
|
|
END_CONNECTION_POINT_MAP()
|
|
|
|
// ISupportsErrorInfo
|
|
protected:
|
|
DSPinList connectedPins;
|
|
public:
|
|
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
|
// IMSVidDevice
|
|
CComBSTR __declspec(property(get=GetName)) m_Name;
|
|
CComBSTR GetName(void) {
|
|
CString csName;
|
|
if(m_iVideoRenderer != -1){
|
|
csName = (m_Filters[m_iVideoRenderer]).GetName();
|
|
}
|
|
if (csName.IsEmpty()) {
|
|
csName = _T("Video Mixing Renderer");
|
|
}
|
|
csName += _T(" Segment");
|
|
return CComBSTR(csName);
|
|
}
|
|
|
|
STDMETHOD(get_Name)(BSTR * Name) {
|
|
if (!m_fInit) {
|
|
return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
|
|
}
|
|
if (Name == NULL)
|
|
return E_POINTER;
|
|
try {
|
|
*Name = m_Name.Copy();
|
|
} catch(...) {
|
|
return E_POINTER;
|
|
}
|
|
return NOERROR;
|
|
}
|
|
STDMETHOD(get_Status)(LONG * Status) {
|
|
if (!m_fInit) {
|
|
return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
|
|
}
|
|
if (Status == NULL)
|
|
return E_POINTER;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHOD(get_Segment)(IMSVidGraphSegment * * pIMSVidGraphSegment)
|
|
{
|
|
if (!m_fInit) {
|
|
return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
|
|
}
|
|
try {
|
|
if (pIMSVidGraphSegment == NULL) {
|
|
return E_POINTER;
|
|
}
|
|
*pIMSVidGraphSegment = reinterpret_cast<IMSVidGraphSegment*>(this);
|
|
AddRef();
|
|
return NOERROR;
|
|
} catch(...) {
|
|
return E_POINTER;
|
|
}
|
|
}
|
|
STDMETHOD(put_SuppressEffects)(/*in*/ VARIANT_BOOL bSuppress);
|
|
STDMETHOD(get_SuppressEffects)(/*out, retval*/ VARIANT_BOOL *bSuppress);
|
|
// Methods to access the allocator presenter object in the vmr
|
|
STDMETHOD(SetAllocator)(/*[in]*/ IUnknown *Allocator, long ID = -1){
|
|
try{
|
|
if(!Allocator){
|
|
return _SetAllocator(NULL, ID);
|
|
}
|
|
PQVMRSAlloc qiAllocator(Allocator);
|
|
if(!qiAllocator){
|
|
_ASSERT(false);
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
return _SetAllocator(qiAllocator, ID);
|
|
|
|
}
|
|
catch(...){
|
|
_ASSERT(false);
|
|
return E_UNEXPECTED;
|
|
}
|
|
}
|
|
STDMETHOD(_SetAllocator)(/*[in]*/ IVMRSurfaceAllocator *Allocator, long ID = -1){
|
|
try{
|
|
PQVMRSAlloc qiAllocator(Allocator);
|
|
|
|
HRESULT hr = CleanupVMR();
|
|
if(FAILED(hr)){
|
|
return hr;
|
|
}
|
|
|
|
qiSurfAlloc = qiAllocator;
|
|
m_APid = ID;
|
|
return S_OK;
|
|
}
|
|
catch(...){
|
|
_ASSERT(false);
|
|
return E_UNEXPECTED;
|
|
}
|
|
}
|
|
|
|
STDMETHOD(get_Allocator)(/*[in]*/ IUnknown **Allocator){
|
|
try{
|
|
if(!Allocator){
|
|
return E_POINTER;
|
|
}
|
|
if(!qiSurfAlloc){
|
|
return E_FAIL;
|
|
}
|
|
PUnknown retVal(qiSurfAlloc);
|
|
if(!retVal){
|
|
_ASSERT(false);
|
|
return E_UNEXPECTED;
|
|
}
|
|
*Allocator = retVal.Detach();
|
|
_ASSERT(Allocator);
|
|
return S_OK;
|
|
}
|
|
catch(...){
|
|
_ASSERT(false);
|
|
return E_UNEXPECTED;
|
|
}
|
|
}
|
|
STDMETHOD(get__Allocator)(/*[in]*/ IVMRSurfaceAllocator **Allocator){
|
|
try{
|
|
if(!Allocator){
|
|
return E_POINTER;
|
|
}
|
|
if(!qiSurfAlloc){
|
|
return E_FAIL; // should be un-inited failure
|
|
}
|
|
PQVMRSAlloc qiAllocator(qiSurfAlloc);
|
|
if(!qiAllocator){
|
|
_ASSERT(false);
|
|
return E_UNEXPECTED;
|
|
}
|
|
*Allocator = qiAllocator.Detach();
|
|
_ASSERT(Allocator);
|
|
return S_OK;
|
|
}
|
|
catch(...){
|
|
_ASSERT(false);
|
|
return E_UNEXPECTED;
|
|
}
|
|
}
|
|
STDMETHOD(get_Allocator_ID)(long *ID){
|
|
try{
|
|
if(!ID){
|
|
return E_POINTER;
|
|
}
|
|
*ID = m_APid;
|
|
return S_OK;
|
|
}
|
|
catch(...){
|
|
_ASSERT(false);
|
|
return E_UNEXPECTED;
|
|
}
|
|
}
|
|
STDMETHOD(OnEventNotify)(LONG lEventCode, LONG_PTR lEventParm1, LONG_PTR lEventParm2){
|
|
if (lEventCode == EC_VMR_RENDERDEVICE_SET) {
|
|
VARIANT_BOOL fUsingOverlay;
|
|
get_UsingOverlay(&fUsingOverlay);
|
|
if (fUsingOverlay == VARIANT_TRUE && !(lEventParm1 & VMR_RENDER_DEVICE_OVERLAY)) {
|
|
put_UsingOverlay(VARIANT_FALSE);
|
|
Fire_OverlayUnavailable();
|
|
ReComputeSourceRect();
|
|
return NOERROR;
|
|
}
|
|
}
|
|
if (lEventCode == EC_VMR_RENDERDEVICE_SET ||
|
|
lEventCode == EC_VIDEO_SIZE_CHANGED) {
|
|
ReComputeSourceRect();
|
|
}
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHOD(PostStop)(){
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop()"), "");
|
|
HRESULT hr = IMSVidVideoRendererImpl<CMSVidVideoRenderer, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidVideoRenderer2>::PostStop();
|
|
if(FAILED(hr)){
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() base class PostStop failed; hr = " << std::hex << hr), "");
|
|
return hr;
|
|
}
|
|
// need stestrops fix for deallocate on stop
|
|
DSFilter sp_VMR = m_Filters[m_iVideoRenderer];
|
|
if(!sp_VMR){
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() could not get vmr filter"), "");
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
int i = 0;
|
|
for(DSFilter::iterator pin = sp_VMR.begin(); pin != sp_VMR.end(); ++pin, ++i){
|
|
if( (*pin).IsConnected()){
|
|
hr = (*pin).Disconnect();
|
|
if(FAILED(hr)){
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() disconnect failed; hr = " << std::hex << hr), "");
|
|
return hr;
|
|
}
|
|
}
|
|
}
|
|
#ifdef _WIN64
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() NumPins: " << (long)connectedPins.size() << " pins."), "");
|
|
#endif
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHOD(PreRun)(){
|
|
HRESULT hr = IMSVidVideoRendererImpl<CMSVidVideoRenderer, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidVideoRenderer2>::PreRun();
|
|
if(FAILED(hr)){
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PreRun() base class PostStop failed; hr = " << std::hex << hr), "");
|
|
return hr;
|
|
}
|
|
// need stestrops fix for deallocate on stop
|
|
DSFilter sp_VMR = m_Filters[m_iVideoRenderer];
|
|
if(!sp_VMR){
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() could not get vmr filter"), "");
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
if(connectedPins.size() == 0){ // if the pin list is empty rebuild it otherwise reconnect the pins
|
|
int i = 0;
|
|
for(DSFilter::iterator pin = sp_VMR.begin(); pin != sp_VMR.end(); ++pin, ++i){
|
|
if( (*pin).IsConnected()){
|
|
connectedPins.push_back((*pin).GetConnection());
|
|
}
|
|
}
|
|
#ifndef _WIN64
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PostStop() Storing: " << connectedPins.size() << " pins."), "");
|
|
#endif
|
|
}
|
|
else{
|
|
DSFilter::iterator vmrPin = sp_VMR.begin();
|
|
for(DSPinList::iterator pin = connectedPins.begin(); pin != connectedPins.end() && vmrPin != sp_VMR.end(); ++pin, ++vmrPin){
|
|
if(!(*vmrPin).IsConnected()){
|
|
hr = (*vmrPin).Connect(*pin);
|
|
if(FAILED(hr)){
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PreRun() connect failed; hr = " << std::hex << hr), "");
|
|
return hr;
|
|
}
|
|
}
|
|
else{
|
|
_ASSERT((*vmrPin).GetConnection() != (*pin));
|
|
}
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(Decompose)(){
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::Decompose() killing pin list"), "");
|
|
connectedPins.clear();
|
|
HRESULT hr = IMSVidVideoRendererImpl<CMSVidVideoRenderer, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidVideoRenderer2>::Decompose();
|
|
if(FAILED(hr) && hr != E_NOTIMPL){
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "MSVidVideoRenderer2::PreRun() base class Decompose failed; hr = " << std::hex << hr), "");
|
|
return hr;
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
#if 0
|
|
STDMETHOD(get__CustomCompositorClass)(/*[out, retval]*/ GUID* CompositorCLSID) {
|
|
return IMSVidVideoRendererImpl<CMSVidVideoRenderer, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidVideoRenderer2>::get__CustomCompositorClass(CompositorCLSID);
|
|
}
|
|
#endif
|
|
};
|
|
#endif //__MSVidVIDEORENDERER_H_
|