Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
[Win32] TAPI3/W2K bug bedlam !?! 28.08.01 23:34
Автор: leo <Леонид Юрьев> Статус: Elderman
|
Что делать просто не знаю, сроки жмут...
А гадость у меня вот какая (Windows 2000 Advanced Server, TAPI3):
TAPI3 - приложение, написано, отлажен, проверенно "от и до" год назад.
Теперь вдруг стало глючить, причем в том куске кода, который взят из примеров Platform SDK.
Приложение (точнее dll) занимается тем, что отвечает на звонки через модемы.
В коде есть цикл копирования "звука" из одного Media-потока в другой.
Метод IStreamSample->Update() возвращает код 0x80040211, что означает VFW_E_NOT_COMMITTED ("Cannot allocate a sample when the allocator is not active" или "The allocator hasn't called the IMemAllocator::Commit() method").
Ошибка возникает на "target" машине, где ПО в конечном счете и будет работать, а на моей машине все хорошо всегда и в любом случае!
Я нашел, как достать этот IMemAllocator::Commit() из доступных интерфейсов и вот что получилось:
- При запуске из-под Terminal Server этот вызов вызывает сбой в менеджере терминалов самого Terminal Server (termmrg.dll);
- При запуске с консоли все работает как надо, но только один (первый) раз после перезагрузки. После, вместо звука в модем "льется" тишина, хотя и нужной длительности. Никаких ошибок не возвращается;
Что делать просто не знаю, сроки жмут...
Может кто-нибудь работал с COM-мультимедиа под W2K - Помогите please.
Ниже кусок исходника...
--------------------------------------------------------------------------------
HRESULT RenderAudioStreamToStream(IMediaStream *pMediaStreamSrc, IMediaStream *pMediaStreamDest, VoteTapiProvider_ErrorInfo &ErrorInfo)
{
const DWORD DATA_SIZE = 8000 * 4;
HRESULT hr;
CStreamSampleQueue DestSampleQ;
IStreamSample *pStreamSample = NULL; // this need not be released
IStreamSample *pSampleStreamSrc = NULL;
IStreamSample *pSampleStreamDest = NULL;
IAudioData *pAudioDataSrc = NULL;
IAudioStreamSample *pAudioStreamSampleSrc = NULL;
IMemoryData *pMemoryDataDest = NULL;
ITAllocatorProperties *pAllocPropDest = NULL;
HANDLE hDestEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if(NULL == hDestEvent)
{
SET_ERROR(CreateEvent());
return E_FAIL;
}
// when we allocate destination samples,
// they will be of size DATA_SIZE
CHECK_ERROR(pMediaStreamDest->QueryInterface(IID_ITAllocatorProperties, (void**)&pAllocPropDest));
CHECK_ERROR(pAllocPropDest->SetBufferSize(DATA_SIZE));
// Create a source sample - we only need one to read
CHECK_ERROR(pMediaStreamSrc->AllocateSample(0, &pSampleStreamSrc));
CHECK_ERROR(pSampleStreamSrc->QueryInterface(IID_IAudioStreamSample, (void**)&pAudioStreamSampleSrc));
CHECK_ERROR(pAudioStreamSampleSrc->GetAudioData(&pAudioDataSrc));
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
//IMemInputPin *pMemInputPin = 0;
//IMemAllocator *pMemAllocator = 0;
//CHECK_ERROR(pMediaStreamDest->QueryInterface(IID_IMemInputPin, (void**)&pMemInputPin));
//CHECK_ERROR(pMemInputPin->GetAllocator(&pMemAllocator));
for(;;)
{
// Create a destination sample
CHECK_ERROR(pMediaStreamDest->AllocateSample(0, &pSampleStreamDest));
CHECK_ERROR(pSampleStreamDest->QueryInterface(IID_IMemoryData, (void**)&pMemoryDataDest));
BYTE *pbDestData;
CHECK_ERROR(pMemoryDataDest->GetInfo(NULL, &pbDestData, NULL));
// point the source sample to the destination buffer
CHECK_ERROR(pAudioDataSrc->SetBuffer(DATA_SIZE, pbDestData, 0));
// Read the sample from the source stream synchronously
hr = pSampleStreamSrc->Update(0, NULL, NULL, 0);
if(hr != S_OK)
{
SET_ERROR(pSampleStreamSrc->Update());
break;
}
DWORD cbSrcActualData;
CHECK_ERROR(pAudioDataSrc->GetInfo(NULL, NULL, &cbSrcActualData));
#if DBG
char temp[255];
wsprintf(temp, "%d bytes in buffer\n", cbSrcActualData);
OutputDebugString(temp);
#endif
if(0 == cbSrcActualData)
break;
// set the size of data read on the destination sample
CHECK_ERROR(pMemoryDataDest->SetActual(cbSrcActualData));
// Write to the destination stream
// we don't wait for the event to be signaled now
// should have some check in between to reuse destination samples
// as using one sample per update is costly
hr = pSampleStreamDest->Update(0, hDestEvent, NULL, 0);
//if(hr == VFW_E_NOT_COMMITTED)
//{
// CHECK_ERROR(pMemAllocator->Commit());
// hr = pSampleStreamDest->Update(0, hDestEvent, NULL, 0);
//}
if((hr != S_OK) && (hr != MS_S_PENDING))
{
SET_ERROR(pSampleStreamDest->Update());
break;
}
// release our references to the destination sample
// except pSampleStreamDest
RELEASE(pMemoryDataDest);
// enqueue destination sample, so that we can wait on its
// status later
if(!DestSampleQ.Enqueue(pSampleStreamDest))
break;
}
// wait for each of the samples to complete
// this ensures that we are done only when all the samples are done
pStreamSample = DestSampleQ.Dequeue();
while(NULL != pStreamSample)
{
// ignore any error values
hr = pStreamSample->CompletionStatus(COMPSTAT_WAIT, 1000 * 60);
if(FAILED(hr))
SET_ERROR(pStreamSample->CompletionStatus);
pStreamSample->Release();
pStreamSample = DestSampleQ.Dequeue();
}
//CHECK_ERROR(pMemAllocator->Decommit());
// tell the stream that there is no more data
pMediaStreamDest->SendEndOfStream(0);
Exit:
//RELEASE(pMemAllocator);
//RELEASE(pMemInputPin);
RELEASE(pAudioDataSrc);
RELEASE(pAudioStreamSampleSrc);
RELEASE(pMemoryDataDest);
RELEASE(pSampleStreamSrc);
RELEASE(pSampleStreamDest);
RELEASE(pAllocPropDest);
CloseHandle(hDestEvent);
return hr;
}
|
|
|