Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Audio IMFTTransform::ProcessOutput返回HE-AAC的MF_E_TRANSFORM_STREAM_CHANGE->;PCM 我尝试使用MediaFoundation转换将HE-AAC音频流(由LIVE55,RTP图书馆接收)转换成PCM(通过 WaveXXXX < /代码> Win32 API)播放。然而,目前我正在处理预先录制的数据包_Audio_Visual C++_Ms Media Foundation_Aac - Fatal编程技术网

Audio IMFTTransform::ProcessOutput返回HE-AAC的MF_E_TRANSFORM_STREAM_CHANGE->;PCM 我尝试使用MediaFoundation转换将HE-AAC音频流(由LIVE55,RTP图书馆接收)转换成PCM(通过 WaveXXXX < /代码> Win32 API)播放。然而,目前我正在处理预先录制的数据包

Audio IMFTTransform::ProcessOutput返回HE-AAC的MF_E_TRANSFORM_STREAM_CHANGE->;PCM 我尝试使用MediaFoundation转换将HE-AAC音频流(由LIVE55,RTP图书馆接收)转换成PCM(通过 WaveXXXX < /代码> Win32 API)播放。然而,目前我正在处理预先录制的数据包,audio,visual-c++,ms-media-foundation,aac,Audio,Visual C++,Ms Media Foundation,Aac,当我调用imfttransform::ProcessOutput时,它返回MF\u E\u TRANSFORM\u STREAM\u CHANGE。 中的文档表明,我应该确定正确的流类型,并再次调用IMFTransform::SetOutputType 但是,我无法确定SetOutputType的正确参数 作为参考,流的RTSP描述如下 m=audio 0 RTP/AVP 97 a=rtpmap:97 mpeg4-generic/16000/1 a=fmtp:97 streamtype=5; p

当我调用
imfttransform::ProcessOutput
时,它返回
MF\u E\u TRANSFORM\u STREAM\u CHANGE
。 中的文档表明,我应该确定正确的流类型,并再次调用
IMFTransform::SetOutputType

但是,我无法确定
SetOutputType
的正确参数

作为参考,流的RTSP描述如下

m=audio 0 RTP/AVP 97
a=rtpmap:97 mpeg4-generic/16000/1
a=fmtp:97 streamtype=5; profile-level-id=15; mode=AAC-hbr; config=1408; 
  sizeLength=13; indexLength=3; indexDeltaLength=3; profile=1; bitrate=32000;
我的代码是(很抱歉长度太长;为简洁起见,错误处理已删除)

静态IMFMediaType*s_inputMediaType;
静态IMFMediaType*s_outputMediaType;
静态imf变换*s_变换;
静态DWORD s_输出采样;
静态void InitMFT()
{
HRESULT res;
res=coinitializex(NULL,COINIT_APARTMENTTHREADED);//可能应该在生产中使用threaded
#如果0
res=MFCreateMediaType(&inputMediaType);
res=MFCreateMediaType(&outputMediaType);
res=inputMediaType->SetGUID(MF\u MT\u MAJOR\u TYPE,MFMediaType\u Audio);
res=inputMediaType->SetGUID(MF\u MT\u子类型,MFAudioFormat\u AAC);
res=inputMediaType->SetUINT32(中频、音频、音频、电平指示,15);
res=inputMediaType->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE,1);//音频数据传输流
res=outputMediaType->SetGUID(MF\u MT\u MAJOR\u TYPE,MFMediaType\u Audio);
res=outputMediaType->SetGUID(MF\u MT\u子类型,MFAudioFormat\u PCM);
res=outputMediaType->SetUINT32(MF\u MT\u样本大小,2);
res=outputMediaType->SetUINT32(中频、音频、数字通道,2);
res=outputMediaType->SetUINT32(每个采样的中频音频位,8*2);
res=outputMediaType->SetUINT32(每秒音频采样数,8000);
res=outputMediaType->SetUINT32(音频平均字节/秒,8000*2*2);
#恩迪夫
CLSID*clsids=NULL;
UINT32 clsidCount=0;
MFT_寄存器_类型_信息输入类型={MFMediaType_音频,MEDIASUBTYPE_MPEG_HEAAC};//无法搜索WAVE_格式_MPEG_HEAAC
MFT_寄存器_类型_信息输出类型={MFMediaType_音频,WAVE_格式_PCM};//MEDIASUBTYPE_PCM不存在(但如果创建,可以搜索)
res=MFTEnum(MFT_类别_音频_解码器,0,
&输入类型,
NULL,//*&outputType,*///如果outputType不为NULL,则搜索失败
NULL,&clsids,&clsidCount);
列表转码器(clsids、clsidCount);
res=CoCreateInstance(clsids[0],NULL,CLSCTX_ALL,IID_PPV_ARGS(&s_transform));
/*GetStreamCount和GetStreamId始终返回E_NOTIMPL*/
DWORD输入计数;
DWORD输出计数;
res=s\u transform->GetStreamCount(&inputCount,&outputCount);
DWORD inputIDs[16];
DWORD输出[16];
res=s_transform->getStreamId(inputCount,InputId,
输出计数,输出数);
res=s_transform->GetInputAvailableType(0、0和s_inputMediaType);
res=s_transform->SetInputType(0,s_inputMediaType,0);
res=s_transform->GetOutputAvailableType(0,1,&s_outputMediaType);//这里是因为PCM outputer是ListTranscoder中提供的第二个输出
res=s_transform->SetOutputType(0,s_outputMediaType,0);
MFT_输出_流_信息输出流信息;
res=s_transform->GetOutputStreamInfo(0,&outputStreamInfo);
s_outputSampleSize=outputStreamInfo.cbSize;
GUID输入编解码器;
GUID输出编解码器;
res=s\u inputMediaType->GetGUID(MF\u MT\u子类型和inputCodec);
res=s\u outputMediaType->GetGUID(MF\u MT\u子类型和outputCodec);
CoTaskMemFree(clsids);
}
/*
http://msdn.microsoft.com/en-us/library/bb530106%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/bb530123%28v=vs.85%29.aspx
*/
void ProcessData(const void*inputData,DWORD inputSize,
void*outputData、DWORD和outputSize)
{
HRESULT res;
IMFSample*pSample;
IMFMediaBuffer*pBuffer;
字节*pData=NULL;
/****根据提供的数据创建输入样本缓冲区****/
res=MFCreateSample(&pSample);
res=MFCreateMemoryBuffer(inputSize和pBuffer);
res=pBuffer->Lock(&pData,NULL,NULL);
memcpy_s(pData、inputSize、inputData、inputSize);
res=pBuffer->SetCurrentLength(inputSize);
res=pBuffer->Unlock();
res=pSample->AddBuffer(pBuffer);
/****创建输出缓冲区****/
IMFSample*PUTPUTSAMPLE;
IMFMediaBuffer*pOutputBuffer;
res=MFCreateSample(&pOutputSample);
res=MFCreateMemoryBuffer(s_outputSampleSize和pOutputBuffer);
res=pOutputSample->AddBuffer(pOutputBuffer);
MFT_OUTPUT_DATA_BUFFER outputDataBuffer;//可以是数组
outputDataBuffer.dwStreamID=0;
outputDataBuffer.pSample=pOutputSample;
outputDataBuffer.dwStatus=0;
outputDataBuffer.pEvents=NULL;
DWORD输出状态=0;
/***处理数据,并将其取回****/
res=s_transform->ProcessInput(0,pSample,0);
res=s_transform->ProcessOutput(MFT_PROCESS_OUTPUT_DISCARD_当没有缓冲区时,
1、&outputDataBuffer、&outputStatus);
if(res==MF\u E\u变换\u流\u变化)
{
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815%28v=vs.85%29.aspx
//指示输出始终更改
//但不是怎么处理
/*GetStreamCount和GetStreamId始终返回E_NOTIMPL*/
DWORD输入计数;
DWORD输出计数;
res=s\u transform->GetStreamCount(&inputCount,&outputCount);
DWORD inputIDs[16];
DWORD输出[16];
res=s_transform->getStreamId(inputCount,InputId,
输出计数,输出数);
res=s_transform->GetInputAvailableType(0、0和s_inputMediaType);
static IMFMediaType *s_inputMediaType;
static IMFMediaType *s_outputMediaType;
static IMFTransform *s_transform;
static DWORD         s_outputSampleSize;

static void InitMFT()
{
    HRESULT res;
    res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // probably should use threaded in production
#if 0
    res = MFCreateMediaType(&inputMediaType);
    res = MFCreateMediaType(&outputMediaType);

    res = inputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
    res = inputMediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);
    res = inputMediaType->SetUINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, 15);
    res = inputMediaType->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 1); // Audio Data Transport Stream

    res = outputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
    res = outputMediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
    res = outputMediaType->SetUINT32(MF_MT_SAMPLE_SIZE, 2);
    res = outputMediaType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, 2);
    res = outputMediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8 * 2);
    res = outputMediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 8000);
    res = outputMediaType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 8000 * 2 *2);
#endif
    CLSID *clsids = NULL;
    UINT32 clsidCount=0;

    MFT_REGISTER_TYPE_INFO inputType  = {MFMediaType_Audio, MEDIASUBTYPE_MPEG_HEAAC}; // WAVE_FORMAT_MPEG_HEAAC can't be searched for
    MFT_REGISTER_TYPE_INFO outputType = {MFMediaType_Audio, WAVE_FORMAT_PCM};         // MEDIASUBTYPE_PCM doesn't exist (but can be search for if created)

    res = MFTEnum(MFT_CATEGORY_AUDIO_DECODER, 0,
                  &inputType,
                  NULL, /* &outputType, */ // search fails if outputType is not NULL
                  NULL, &clsids, &clsidCount);

    ListTranscoders(clsids, clsidCount);

    res = CoCreateInstance(clsids[0], NULL, CLSCTX_ALL, IID_PPV_ARGS(&s_transform));

    /* GetStreamCount and GetStreamIDs always return E_NOTIMPL */
    DWORD inputCount;
    DWORD outputCount;
    res = s_transform->GetStreamCount(&inputCount, &outputCount);

    DWORD inputIDs[16];
    DWORD outputIDs[16];

    res = s_transform->GetStreamIDs(inputCount, inputIDs,
                                  outputCount, outputIDs);

    res = s_transform->GetInputAvailableType(0, 0, &s_inputMediaType);
    res = s_transform->SetInputType(0, s_inputMediaType, 0);

    res = s_transform->GetOutputAvailableType(0, 1, &s_outputMediaType); // 1 here is because PCM outputer is the second output offered in ListTranscoders
    res = s_transform->SetOutputType(0, s_outputMediaType, 0);

    MFT_OUTPUT_STREAM_INFO outputStreamInfo;
    res = s_transform->GetOutputStreamInfo(0, &outputStreamInfo); 
    s_outputSampleSize = outputStreamInfo.cbSize;

    GUID inputCodec;
    GUID outputCodec;

    res = s_inputMediaType ->GetGUID(MF_MT_SUBTYPE, &inputCodec);
    res = s_outputMediaType->GetGUID(MF_MT_SUBTYPE, &outputCodec);

    CoTaskMemFree(clsids);
}

/*
http://msdn.microsoft.com/en-us/library/bb530106%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/bb530123%28v=vs.85%29.aspx
*/

void ProcessData(const void* inputData,  DWORD inputSize,
                       void* outputData, DWORD &outputSize)
{
    HRESULT         res;
    IMFSample      *pSample;
    IMFMediaBuffer *pBuffer;
    BYTE *pData = NULL;

    /**** Create an input sample buffer, from the supplied data ****/
    res = MFCreateSample(&pSample);
    res = MFCreateMemoryBuffer(inputSize, &pBuffer);
    res = pBuffer->Lock(&pData, NULL, NULL);
    memcpy_s(pData, inputSize, inputData, inputSize);
    res = pBuffer->SetCurrentLength(inputSize);
    res = pBuffer->Unlock();
    res = pSample->AddBuffer(pBuffer);

    /**** Create output buffer ****/
    IMFSample      *pOutputSample;
    IMFMediaBuffer *pOutputBuffer;

    res = MFCreateSample(&pOutputSample);
    res = MFCreateMemoryBuffer(s_outputSampleSize, &pOutputBuffer);
    res = pOutputSample->AddBuffer(pOutputBuffer);

    MFT_OUTPUT_DATA_BUFFER outputDataBuffer; // can be an array
    outputDataBuffer.dwStreamID=0;
    outputDataBuffer.pSample=pOutputSample;
    outputDataBuffer.dwStatus=0;
    outputDataBuffer.pEvents = NULL;

    DWORD outputStatus=0;

    /*** Process the data, and get it back ****/
    res = s_transform->ProcessInput(0, pSample, 0);
    res = s_transform->ProcessOutput( MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER, 
                                   1, &outputDataBuffer, &outputStatus);


    if (res==MF_E_TRANSFORM_STREAM_CHANGE)
    {
        // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815%28v=vs.85%29.aspx
        // indicates that the output always changes
        // but not how to handle it

        /* GetStreamCount and GetStreamIDs always return E_NOTIMPL */

        DWORD inputCount;
        DWORD outputCount;
        res = s_transform->GetStreamCount(&inputCount, &outputCount);

        DWORD inputIDs[16];
        DWORD outputIDs[16];

        res = s_transform->GetStreamIDs(inputCount, inputIDs,
                                      outputCount, outputIDs);

        res = s_transform->GetInputAvailableType(0, 0, &s_inputMediaType);
        res = s_transform->SetInputType(0, s_inputMediaType, 0);

        res = s_transform->GetOutputAvailableType(0, 1, &s_outputMediaType); // 1 here is because PCM outputer is the second output offered
        res = s_transform->SetOutputType(0, s_outputMediaType, 0);
    }

    /**** Extract converted audio from the sample ****/
    DWORD dwNumOutputBuffers, i;
    res = outputDataBuffer.pSample->GetBufferCount(&dwNumOutputBuffers);

    for(i=0; i<dwNumOutputBuffers; i++)
    {
        IMFMediaBuffer *outputBuffer;
        res = outputDataBuffer.pSample->GetBufferByIndex(i, &outputBuffer);
        BYTE *outData;
        DWORD outDataLen = 0;

        res = outputBuffer->Lock(&outData, NULL, &outDataLen);

        memcpy(outputBuffer, outData, outDataLen);

        res = outputBuffer->Unlock();
    }

    /* TODO: Release any neccessery references */
}
res = s_transform->GetOutputAvailableType(0, 1, &s_outputMediaType); // 1 here is because PCM outputer is the second output offered
    GUID outputCodec;
    res = s_outputMediaType->GetGUID(MF_MT_SUBTYPE, &outputCodec);
    if (outputCodec == MFAudioFormat_PCM){
        printf("\nDecoder Output is expecting pcm format");                 
        res = s_transform->SetOutputType(0, s_outputMediaType, 0);//setting the type again

    }
    if (outputCodec == MFAudioFormat_Float){
        printf("\nDecoder Output is expecting float pcm format");
    }
    s_transform->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH,NULL);        

    return res;//no output coming get another input to process.