📄 processing.cpp
字号:
hr = pCallMediaEvent->get_Stream(&pStream);
if ( FAILED(hr) )
{
LogError("GetTerminalFromMediaEvent: "
"failed to get stream hr = 0x%lx", hr);
return hr;
}
//
// find the terminal on this stream
//
//
// get terminal enumeration on the stream
//
IEnumTerminal *pEnumTerminal = NULL;
hr = pStream->EnumerateTerminals(&pEnumTerminal);
pStream->Release();
pStream = NULL;
if ( FAILED(hr) )
{
LogError("GetTerminalFromMediaEvent: failed to enumerate terminals, "
"hr = 0x%lx", hr);
return hr;
}
//
// walk through terminal enumeration
//
ULONG nTerminalsFetched = 0;
ITTerminal *pStreamTerminal = NULL;
//
// assuming there is at most one terminal selected on the stream
//
hr = pEnumTerminal->Next(1, &pStreamTerminal, &nTerminalsFetched);
pEnumTerminal->Release();
pEnumTerminal = NULL;
if (S_OK != hr)
{
LogError("GetTerminalFromMediaEvent: enumeration returned no "
"terminals, hr = 0x%lx", hr);
return hr;
}
*ppTerminal = pStreamTerminal;
LogMessage("GetTerminalFromMediaEvent: succeeded");
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
//
// GetNumberOfSamplesOnStream
//
// read the terminal's allocator properties to return the number of samples
// the terminal provides
//
///////////////////////////////////////////////////////////////////////////////
HRESULT GetNumberOfSamplesOnStream(IN IMediaStream *pTerminalMediaStream,
IN OUT DWORD *pnNumberOfSamples)
{
HRESULT hr = S_OK;
//
// don't return garbage
//
*pnNumberOfSamples = 0;
//
// get allocator properties
//
ITAllocatorProperties *pAllocProperites = NULL;
hr = pTerminalMediaStream->QueryInterface(IID_ITAllocatorProperties,
(void **)&pAllocProperites);
if (FAILED(hr))
{
LogError("GetNumberOfSamplesOnStream: "
"Failed to QI terminal for ITAllocatorProperties");
return hr;
}
//
// we want to know the number of samples we will be getting
//
ALLOCATOR_PROPERTIES AllocProperties;
hr = pAllocProperites->GetAllocatorProperties(&AllocProperties);
pAllocProperites->Release();
pAllocProperites = NULL;
if (FAILED(hr))
{
LogError("GetNumberOfSamplesOnStream: "
"Failed to get terminal's allocator properties");
return hr;
}
*pnNumberOfSamples = AllocProperties.cBuffers;
//
// log the number of buffers and their sizes
//
LogMessage("GetNumberOfSamplesOnStream: [%ld] samples, [%ld] bytes each",
*pnNumberOfSamples, AllocProperties.cbBuffer);
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
//
// ReleaseEvents
//
//
// close the handles passed into the function and release the array of handles
//
///////////////////////////////////////////////////////////////////////////////
void ReleaseEvents(IN OUT HANDLE *pEvents, // array of events to be freed
IN DWORD nNumberOfEvents // number of events in the array
)
{
//
// close all the handles in the array
//
for (DWORD i = 0; i < nNumberOfEvents; i++)
{
CloseHandle(pEvents[i]);
pEvents[i] = NULL;
}
//
// free the array itself
//
FreeMemory(pEvents);
pEvents = NULL;
}
///////////////////////////////////////////////////////////////////////////////
//
// AllocateEvents
//
// allocate the array of events of size nNumberOfSamples
//
// return pointer to the allocated and initialized array if success
// or NULL if failed
//
///////////////////////////////////////////////////////////////////////////////
HANDLE *AllocateEvents(IN DWORD nNumberOfEvents)
{
//
// pointer to an array of event handles
//
HANDLE *pSampleReadyEvents = NULL;
pSampleReadyEvents =
(HANDLE*)AllocateMemory(sizeof(HANDLE) * nNumberOfEvents);
if (NULL == pSampleReadyEvents)
{
LogError("AllocateEvents: Failed to allocate sample ready events.");
return NULL;
}
//
// create an event for every allocated handle
//
for (DWORD i = 0; i < nNumberOfEvents; i++)
{
pSampleReadyEvents[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
if (NULL == pSampleReadyEvents[i])
{
LogError("AllocateEvents: "
"Failed to create event for sample %d", i);
//
// close handles we have created already
//
for (DWORD j = 0; j< i; j++)
{
CloseHandle(pSampleReadyEvents[j]);
pSampleReadyEvents[j] = NULL;
}
FreeMemory(pSampleReadyEvents);
pSampleReadyEvents = NULL;
return NULL;
}
} // creating events for each sample
//
// succeded creating events. return the pointer to the array
//
return pSampleReadyEvents;
}
///////////////////////////////////////////////////////////////////////////////
//
// ReleaseSamples
//
// aborts and releases every sample in the array of samples of size
// nNumberOfSamples and deallocates the array itself
//
// ppStreamSamples becomes invalid when the function returns
//
///////////////////////////////////////////////////////////////////////////////
void ReleaseSamples(IN OUT IStreamSample **ppStreamSamples,
IN DWORD nNumberOfSamples)
{
for (DWORD i = 0; i < nNumberOfSamples; i++)
{
ppStreamSamples[i]->CompletionStatus(COMPSTAT_WAIT |
COMPSTAT_ABORT,
INFINITE);
//
// regardless of the error code, release the sample
//
ppStreamSamples[i]->Release();
ppStreamSamples[i] = NULL;
}
FreeMemory(ppStreamSamples);
ppStreamSamples = NULL;
}
///////////////////////////////////////////////////////////////////////////////
//
// AllocateStreamSamples
//
// allocate the array of nNumberOfSamples samples, and initialize each sample
// pointer in the array with samples from the supplied stream.
//
// return pointer to the allocated and initialized array if success
// or NULL if failed
//
///////////////////////////////////////////////////////////////////////////////
IStreamSample **AllocateStreamSamples(IN IMediaStream *pMediaStream,
IN DWORD nNumberOfSamples)
{
//
// allocate stream sample array
//
IStreamSample **ppStreamSamples = (IStreamSample **)
AllocateMemory( sizeof(IStreamSample*) * nNumberOfSamples );
if (NULL == ppStreamSamples)
{
LogError("AllocateStreamSamples: Failed to allocate stream sample array");
return NULL;
}
//
// allocate samples from the stream and put them into the array
//
for (DWORD i = 0; i < nNumberOfSamples; i++)
{
HRESULT hr = pMediaStream->AllocateSample(0, &ppStreamSamples[i]);
if (FAILED(hr))
{
LogError("AllocateStreamSamples: Failed to allocateSample. "
"Sample #%d", i);
for (DWORD j = 0; j < i; j++)
{
ppStreamSamples[j]->Release();
ppStreamSamples[j] = NULL;
}
FreeMemory(ppStreamSamples);
ppStreamSamples = NULL;
return NULL;
} // failed AllocateSample()
} // allocating samples on the stream
//
// succeeded allocating samples
//
return ppStreamSamples;
}
///////////////////////////////////////////////////////////////////////////////
//
// AssociateEventsWithSamples
//
// call Update() on every sample of the array of stream samples to associate it
// with an event from the array of events. The events will be signaled when the
// corresponding sample has data and is ready to be written to a file
//
///////////////////////////////////////////////////////////////////////////////
HRESULT AssociateEventsWithSamples(IN HANDLE *pSampleReadyEvents,
IN IStreamSample **ppStreamSamples,
IN DWORD nNumberOfSamples)
{
for (DWORD i = 0; i < nNumberOfSamples; i++)
{
//
// the event passed to Update will be signaled when the sample is
// filled with data
//
HRESULT hr =
ppStreamSamples[i]->Update(0, pSampleReadyEvents[i], NULL, 0);
if (FAILED(hr))
{
LogError("AssociateEventsWithSamples: "
"Failed to call update on sample #%d", i);
//
// abort the samples we have Update()'d
//
for (DWORD j = 0; j < i; j++)
{
//
// no need to check the return code here -- best effort attempt
// if failed -- too bad
//
ppStreamSamples[j]->CompletionStatus(COMPSTAT_WAIT |
COMPSTAT_ABORT,
INFINITE);
}
return hr;
} // Update() failed
} // Update()'ing all samples
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
//
// GetAudioFormat
//
// return a pointer to wave format structure for the audio data produced by
// the stream. the caller is responsible for deallocating returned stucture
//
// returns NULL if failed
//
//////////////////////////////////////////////////////////////////////////////
WAVEFORMATEX *GetAudioFormat(IMediaStream *pTerminalMediaStream)
{
//
// get ITAMMediaFormat interface on the terminal, so we can query for
// audio format
//
ITAMMediaFormat *pITMediaFormat = NULL;
HRESULT hr = pTerminalMediaStream->QueryInterface(IID_ITAMMediaFormat,
(void **)&pITMediaFormat);
if (FAILED(hr))
{
LogError("GetAudioFormat: "
"failed to QI terminal for ITAMMediaFormat");
return NULL;
}
//
// use ITAMMediaFormat to get terminal's media format
//
AM_MEDIA_TYPE *pMediaType = NULL;
hr = pITMediaFormat->get_MediaFormat(&pMediaType);
pITMediaFormat->Release();
pITMediaFormat = NULL;
if (FAILED(hr))
{
LogError("GetAudioFormat: failed to get_MediaFormat hr = 0x%lx", hr);
return NULL;
}
//
// did we get back a format that we can use?
//
if ((pMediaType->pbFormat == NULL) ||
pMediaType->formattype != FORMAT_WaveFormatEx)
{
LogError("GetAudioFormat: invalid format");
DeleteMediaType(pMediaType);
pMediaType = NULL;
return NULL;
}
//
// allocate and return wave format
//
WAVEFORMATEX *pFormat =
(WAVEFORMATEX *)AllocateMemory(pMediaType->cbFormat);
if (NULL != pFormat)
{
CopyMemory(pFormat, pMediaType->pbFormat, pMediaType->cbFormat);
}
else
{
LogError("GetAudioFormat: Failed to allocate memory for audio format");
}
//
// remember to release AM_MEDIA_TYPE that we no longer need
//
DeleteMediaType(pMediaType);
pMediaType = NULL;
return pFormat;
}
///////////////////////////////////////////////////////////////////////////////
//
// WriteSampleToFile
//
// This function writes the data portion of the sample into the file
//
///////////////////////////////////////////////////////////////////////////////
HRESULT WriteSampleToFile(IN IStreamSample *pStreamSample, // sample to record
IN CAVIFileWriter *pFileWriter) // file to record to
{
//
// get the sample's IMemoryData interface so we can get to the
// sample's data
//
IMemoryData *pSampleMemoryData = NULL;
HRESULT hr = pStreamSample->QueryInterface(IID_IMemoryData,
(void **)&pSampleMemoryData);
if (FAILED(hr))
{
LogError("WriteSampleToFile: "
"Failed to qi sample for IMemoryData");
return hr;
}
//
// get to the sample's data buffer
//
DWORD nBufferSize = 0;
BYTE *pnDataBuffer = NULL;
DWORD nActualDataSize = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -