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

📄 processing.cpp

📁 tapi3.0实现
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    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 + -