⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mstapi3.cpp

📁 jtapi for telephone
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    // enumerate the addresses
    hr = tapi->EnumerateAddresses( &pEnumAddress );
    if (FAILED(hr)) {
		logger->error("EnumerateAddresses() failed: hr=%08X.", hr);
        return hr;
    }

    while (TRUE) {
        hr = pEnumAddress->Next( 1, &pAddress, NULL );
        if(FAILED(hr)) {
			logger->error("pEnumAddress->Next() failed: hr=%08X.", hr);
            break;
        }
		if(hr == S_FALSE) {
			logger->info("pEnumAddress done.");
			break;
		}

		BSTR bstrAddrName;
		hr = pAddress->get_AddressName(&bstrAddrName);
		if(FAILED(hr)) {
			logger->error("Cannot retrieve address name: hr=%08X.", hr);
			continue;
		}
		addresses.insert(AddressMap::value_type(bstrAddrName, pAddress));
		char addressName[256];
		sprintf(addressName, "%S", bstrAddrName);
		logger->info("Address %s added.", addressName);
		SysFreeString(bstrAddrName);

        // does the address support audio?
        if (AddressSupportsMediaType(pAddress, TAPIMEDIATYPE_AUDIO)) {
            // If it does then we'll listen.
			long lRegister;
            hr = ListenOnThisAddress(pAddress, &lRegister);
            if (FAILED(hr)) {
                logger->error("Listen failed on address %s.", addressName);
            } else {
				callNotificationRegisters.push_back(lRegister);
                logger->info("Listener registered on address %s with register %ld.", addressName, lRegister);
			}
        } else {
			logger->info("Not listening on address %s...", addressName);
		}

		pAddress->Release();
    }
    pEnumAddress->Release();
    return S_OK;
}


///////////////////////////////////////////////////////////////////
// ListenOnThisAddress
//
// We call RegisterCallNotifications to inform TAPI that we want
// notifications of calls on this address. We already resistered
// our notification interface with TAPI, so now we are just telling
// TAPI that we want calls from this address to trigger events on
// our existing notification interface.
//    
///////////////////////////////////////////////////////////////////
HRESULT MSTapi3::ListenOnThisAddress(ITAddress* pAddress, long* pRegister) {
    //
    // RegisterCallNotifications takes a media type bitmap indicating
    // the set of media types we are interested in. We know the
    // address supports audio, but let's add in video as well
    // if the address supports it.
    //
    long lMediaTypes = TAPIMEDIATYPE_AUDIO;

    if(AddressSupportsMediaType(pAddress, TAPIMEDIATYPE_VIDEO)) {
        lMediaTypes |= TAPIMEDIATYPE_VIDEO;
    }

    HRESULT  hr;
    hr = tapi->RegisterCallNotifications(
                                           pAddress,
                                           VARIANT_TRUE,
                                           VARIANT_TRUE,
                                           lMediaTypes,
                                           gulAdvise,
                                           pRegister
                                          );
    return hr;
}

/////////////////////////////////////////////////////////////////
// IsVideoCaptureStream
//
// Returns true if the stream is for video capture
/////////////////////////////////////////////////////////////////
BOOL MSTapi3::IsVideoCaptureStream(ITStream * pStream) {
    TERMINAL_DIRECTION tdStreamDirection;
    long               lStreamMediaType;

    if ( FAILED( pStream  ->get_Direction(&tdStreamDirection)   ) ) { return FALSE; }
    if ( FAILED( pStream  ->get_MediaType(&lStreamMediaType)    ) ) { return FALSE; }

    return (tdStreamDirection == TD_CAPTURE) &&
           (lStreamMediaType  == TAPIMEDIATYPE_VIDEO);
}

/////////////////////////////////////////////////////////
// GetVideoRenderTerminal
//
// Creates a dynamic terminal for the Video Render mediatype / direction
//
/////////////////////////////////////////////////////////
HRESULT MSTapi3::GetVideoRenderTerminal(
                   ITAddress   * pAddress,
                   ITTerminal ** ppTerminal
                  )
{
    //
    // Construct a BSTR for the correct IID.
    //
    LPOLESTR            lpTerminalClass;
    HRESULT             hr;

    hr = StringFromIID(CLSID_VideoWindowTerm, &lpTerminalClass);
    if (SUCCEEDED(hr)) {
        BSTR bstrTerminalClass;

        bstrTerminalClass = SysAllocString ( lpTerminalClass );

        CoTaskMemFree( lpTerminalClass );

        if ( bstrTerminalClass == NULL ) {
            hr = E_OUTOFMEMORY;
        }
        else {
            // Get the terminal support interface
            ITTerminalSupport * pTerminalSupport;
            hr = pAddress->QueryInterface(IID_ITTerminalSupport, (void **)&pTerminalSupport);
            if (SUCCEEDED(hr)) {
                // Create the video render terminal.
                hr = pTerminalSupport->CreateTerminal(bstrTerminalClass,
                                                      TAPIMEDIATYPE_VIDEO,
                                                      TD_RENDER,
                                                      ppTerminal);
                pTerminalSupport->Release();
            }
            SysFreeString( bstrTerminalClass );
        }
    }
    return hr;
}

/////////////////////////////////////////////////////////////////
// EnablePreview
//
// Selects a video render terminal on a video capture stream,
// thereby enabling video preview.
/////////////////////////////////////////////////////////////////
HRESULT MSTapi3::EnablePreview(ITAddress* pAddress, ITStream* pStream) {
    ITTerminal* pTerminal;
    HRESULT hr = GetVideoRenderTerminal(pAddress, &pTerminal);
    if(FAILED(hr)) {
		logger->error("GetVideoRenderTerminal() failed: hr=%08X.", hr);
	} else {
        hr = pStream->SelectTerminal(pTerminal);
        pTerminal->Release();
    }
    return hr;
}

/////////////////////////////////////////////////////////
// GetTerminal
//
// Creates the default terminal for the passed-in stream.
/////////////////////////////////////////////////////////
HRESULT MSTapi3::GetTerminal(ITAddress* pAddress, ITStream* pStream, ITTerminal** ppTerminal) {
    // Determine the media type and direction of this stream.
    
    HRESULT hr;
    long lMediaType;
    TERMINAL_DIRECTION dir;

    hr = pStream->get_MediaType( &lMediaType );
    if ( FAILED(hr) ) return hr;

    hr = pStream->get_Direction( &dir );
    if ( FAILED(hr) ) return hr;

    // Since video render is a dynamic terminal, the procedure for creating it is different.    
    if (( lMediaType == TAPIMEDIATYPE_VIDEO) && (dir == TD_RENDER)) {
        return GetVideoRenderTerminal(pAddress, ppTerminal);
    }

    // For all other terminals we use GetDefaultStaticTerminal.
    // First, get the terminal support interface.
    ITTerminalSupport * pTerminalSupport;
    hr = pAddress->QueryInterface( IID_ITTerminalSupport, (void **)&pTerminalSupport);
    if (SUCCEEDED(hr)) {
        // get the default terminal for this MediaType and direction
        hr = pTerminalSupport->GetDefaultStaticTerminal(lMediaType, dir, ppTerminal);
        pTerminalSupport->Release();
    }
    return hr;
}

/////////////////////////////////////////////////////////////////
// SelectTerminalsOnCall
//
// Selects a given terminal on the first compatible stream that exists on the given call.
/////////////////////////////////////////////////////////////////
HRESULT MSTapi3::SelectTerminalsOnCall(ITAddress* pAddress, ITBasicCallControl* pCall) {
    // get the ITStreamControl interface for this call
    ITStreamControl* pStreamControl;
    HRESULT hr = pCall->QueryInterface(IID_ITStreamControl, (void **) &pStreamControl);
    if (FAILED(hr)) {
		logger->error("Interface ITStreamControl not supported: hr=%08X", hr);
	} else {
        // enumerate the streams
        IEnumStream * pEnumStreams;
        hr = pStreamControl->EnumerateStreams(&pEnumStreams);
        pStreamControl->Release();
        if(FAILED(hr)){
			logger->error("EnumerateStreams() failed: hr=%08X", hr);
		} else {
            // for each stream
            ITStream* pStream;
            while (S_OK == pEnumStreams->Next(1, &pStream, NULL)) {
                ITTerminal* pTerminal;
                // Find out the media type and direction of this stream, and
                // create the default terminal for this media type and direction.
                hr = GetTerminal(pAddress, pStream, &pTerminal);
                if(FAILED(hr)) {
					logger->error("GetTerminal() failed: hr=%08X", hr);
				} else {
                    // Select the terminal on the stream.
                    hr = pStream->SelectTerminal(pTerminal);
                    if (FAILED(hr)) {
						logger->error("SelectTerminal() failed: hr=%08X", hr);
					} else {
                        // Also enable preview on the video capture stream.
                        if (IsVideoCaptureStream( pStream )) {
                            EnablePreview(pAddress, pStream);
                        }
                    }
                    pTerminal->Release();
                }
                pStream->Release();
            }
            pEnumStreams->Release();
        }
    }
    return hr;
}
//////////////////////////////////////////////////////////////
// AddressSupportsMediaType
//
// Finds out if the given address supports the given media
// type, and returns TRUE if it does.
//////////////////////////////////////////////////////////////
BOOL MSTapi3::AddressSupportsMediaType(ITAddress* pAddress, long lMediaType)
{
    VARIANT_BOOL     bSupport = VARIANT_FALSE;
    ITMediaSupport * pMediaSupport;
    
    if(SUCCEEDED(pAddress->QueryInterface(IID_ITMediaSupport, (void **)&pMediaSupport))) {
        // does it support this media type?
        pMediaSupport->QueryMediaType(lMediaType, &bSupport);    
        pMediaSupport->Release();
    }
    return (bSupport == VARIANT_TRUE);
}

int MSTapi3::reserveCall(wstring& address) {
	logger->debug("reserveCall() called for %S", address.c_str());
	currCallID++;
	calls[currCallID] = NULL;
	logger->debug("reserveCall() returning callID=%d for %S", currCallID, address.c_str());
	return currCallID;
}

// returns the callID
int MSTapi3::putCall(ITBasicCallControl* pCallControl) {
	currCallID++;
	calls[currCallID] = pCallControl;
	logger->debug("putCall(%d, %p).", currCallID, pCallControl);
	return currCallID;
}

ITBasicCallControl* MSTapi3::getCallControl(int callID) {
	CallMap::iterator it = calls.find(callID);
	if(it != calls.end()) {
		return (*it).second;
	}
	logger->warn("getCallControl(): No call found for callID=%d", callID);
	return NULL;
}

void MSTapi3::removeCallControl(int callID) {
	CallMap::iterator it = calls.find(callID);
	if(it != calls.end()) {
		ITBasicCallControl* pCallControl = (*it).second;
		calls.erase(it);
		if(pCallControl != NULL) {
			pCallControl->Release();
			logger->debug("CallControl released for callID=%d.", callID);
		} else {
			logger->debug("Call reserved but not initialized for callID=%d", callID);
		}
	} else {
		logger->warn("removeCallControl(): No call found for callID=%d", callID);
	}
}

int MSTapi3::getCallID(ITBasicCallControl* pCallControl) {
	for(CallMap::reverse_iterator it = calls.rbegin(); it != calls.rend(); ++it) {
		if((*it).second == pCallControl) {
			int callID = (*it).first;
			logger->debug("getCallID() found callID=%d", callID);
			return callID;
		}
	}
	logger->debug("getCallID(): callID not found.");
	return -1;
}

// Returns -callID if this is a new call
int MSTapi3::getOrCreateCallID(ITBasicCallControl* pCallControl) {
	for(CallMap::reverse_iterator it = calls.rbegin(); it != calls.rend(); ++it) {
		if((*it).second == pCallControl) {
			int callID = (*it).first;
			logger->debug("getOrCreateCallID() found callID=%d", callID);
			return callID;
		}
	}
	int callID = putCall(pCallControl);
	logger->debug("getOrCreateCallID(): call not found. Created new callID=%d.", callID);
	return -callID;
}

ITAddress* MSTapi3::getITAddress(wstring& address) {
	AddressMap::iterator it = addresses.find(address);
	if(it == addresses.end()) {
		logger->warn("Address %S not found", address);
		return NULL;
	}
	ITAddress* pITAddress = (*it).second;
	return pITAddress;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -