设置AAC解码器输入类型始终失败(UWP)

发布于 2025-02-12 19:37:11 字数 1180 浏览 2 评论 0原文

我正在尝试在clsid_msaacdecmft对象的实例上设置输入类型,但是它总是失败 针对媒体类型指定的数据无效,不一致或不受此对象的支持。

基于Microsoft文档,我在尝试将其设置为输入之前设置了强制性值:

    ComPtr<IUnknown> pUnknown = nullptr;
    HRESULT hResult = CoCreateInstance(CLSID_MSAACDecMFT, nullptr, CLSCTX_INPROC_SERVER, IID_IUnknown, &pUnknown);
    if (S_OK != hResult) {
        LogError("Failed to create AAC decoder");
        return false;
    }

    hResult = pUnknown->QueryInterface(IID_PPV_ARGS(&mAudioDecoder));
    if (hResult != S_OK) {
        LogError("Failed to create AAC decoder");
        return false;
    }

    ComPtr<IMFMediaType> pInputMediaType = nullptr;
    hResult = MFCreateMediaType(&pInputMediaType);
    if (S_OK != hResult) {
        return false;
    }

    pInputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
    pInputMediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);

    pInputMediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
    pInputMediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000);
    pInputMediaType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, 2);

任何人都可以告诉我为什么失败?

非常感谢 彼得

I'm trying to set the input type on a instance of the CLSID_MSAACDecMFT object, but it always fails with
The data specified for the media type is invalid, inconsistent, or not supported by this object.

Based on the Microsoft documentation I've set the mandatory values before attempting to set it as input:

    ComPtr<IUnknown> pUnknown = nullptr;
    HRESULT hResult = CoCreateInstance(CLSID_MSAACDecMFT, nullptr, CLSCTX_INPROC_SERVER, IID_IUnknown, &pUnknown);
    if (S_OK != hResult) {
        LogError("Failed to create AAC decoder");
        return false;
    }

    hResult = pUnknown->QueryInterface(IID_PPV_ARGS(&mAudioDecoder));
    if (hResult != S_OK) {
        LogError("Failed to create AAC decoder");
        return false;
    }

    ComPtr<IMFMediaType> pInputMediaType = nullptr;
    hResult = MFCreateMediaType(&pInputMediaType);
    if (S_OK != hResult) {
        return false;
    }

    pInputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
    pInputMediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);

    pInputMediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
    pInputMediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000);
    pInputMediaType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, 2);

Can anyone tell me why this fails?

Many thanks,
Peter

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

诠释孤独 2025-02-19 19:37:11

好吧,这很痛苦!误读文档,还有一个其他字段要设置,mf_mt_user_data字段。经过大量的反复错误,我明白了:

    hResult = MFCreateMediaType(&pInputMediaType);
    if (S_OK != hResult) {
        return false;
    }

    pInputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
    pInputMediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);

    std::shared_ptr<AudioMp4Track> audioTrack = mDemuxer->getAudioTrack();

    pInputMediaType->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 0);
    pInputMediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, audioTrack->getSampleRate());
    pInputMediaType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, audioTrack->getChannelCount());

    // This is the desired output bits, why it goes into input, I do not know.
    pInputMediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 32);

    // This 14 byte array consists of the HEAACWAVEINFO struct members after WaveFormatEx plus a 2 byte config header
    // Config (from https://wiki.multimedia.cx/index.php/MPEG-4_Audio):
    // Type (5 bits)
    // Sample Rate Index (4 bits)
    // Channel Map Index (4 bits)
    // Reserved and 0 (3 bits)
    // 2 bytes in total
    // 00001 0011 0010 000 0x0990
    uint8_t config[] = { 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x90 };

如何设置MF_MF_USER_DATA不太清楚,您无需创建waveformatex object objoct waveformatex这就是您只需要在介质类型上设置斑点,代表波格格式结构以后的相关字段。

人们还可能使用的是如何生成输出类型...文件仅表示有三个强制性字段:数字通道,位和样本率。这对我不起作用,但是我通过可能的输出类型的列表进行了迭代,并且只要有浮点输出类型,将其采用并使用了:

    ComPtr<IMFMediaType> pOutputType = nullptr;
    hResult = MFCreateMediaType(&pOutputType);
    if (S_OK != hResult) {
        return false;
    }

    GUID guidSubType;
    for (int i = 0; i < 10; ++i) {

        ComPtr<IMFMediaType> pTempOutputType = nullptr;
        hResult = MFCreateMediaType(&pTempOutputType);
        if (S_OK != hResult) {
            return false;
        }

        hResult = mAudioDecoder->GetOutputAvailableType(0, i, &pTempOutputType);
        if (hResult == MF_E_NO_MORE_TYPES) {
            break;
        }

        hResult = pTempOutputType->GetGUID(MF_MT_SUBTYPE, &guidSubType);
        if (S_OK != hResult) {
            LogError("oh no");
            continue;
        }

        if (guidSubType == MFAudioFormat_Float) {
            pTempOutputType->CopyAllItems(pOutputType.Get());
            break;
        }
    }

    uint32_t floatOutputBits = 0;
    pOutputType->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, &floatOutputBits);
    if (floatOutputBits != 32) {
        LogError("No float output type for decoder");
        return false;
    }

    hResult = mAudioDecoder->SetOutputType(0, pOutputType.Get(), 0);
    if (S_OK != hResult) {
        LogError("Couldn't set output type of audio decoder.");
        return false;
    }

Well this was a pain! Misread the documents and there is an additional field to set, the MF_MT_USER_DATA field. After a lot of trial and error, I got it:

    hResult = MFCreateMediaType(&pInputMediaType);
    if (S_OK != hResult) {
        return false;
    }

    pInputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
    pInputMediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);

    std::shared_ptr<AudioMp4Track> audioTrack = mDemuxer->getAudioTrack();

    pInputMediaType->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 0);
    pInputMediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, audioTrack->getSampleRate());
    pInputMediaType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, audioTrack->getChannelCount());

    // This is the desired output bits, why it goes into input, I do not know.
    pInputMediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 32);

    // This 14 byte array consists of the HEAACWAVEINFO struct members after WaveFormatEx plus a 2 byte config header
    // Config (from https://wiki.multimedia.cx/index.php/MPEG-4_Audio):
    // Type (5 bits)
    // Sample Rate Index (4 bits)
    // Channel Map Index (4 bits)
    // Reserved and 0 (3 bits)
    // 2 bytes in total
    // 00001 0011 0010 000 0x0990
    uint8_t config[] = { 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x90 };

How to set the MF_MF_USER_DATA wasn't very clear, you don't need to create the WAVEFORMATEX object or anything like that, you only need to set a blob on the media type, representing the relevant fields after wave format struct.

What will also potentially be of use to people is how to generate the output type... The documents only say that there are three mandatory fields: num channels, bits and sample rate. This didn't work for me, but I iterated through the list of possible output types and, provided there is a float output type, took it and used it:

    ComPtr<IMFMediaType> pOutputType = nullptr;
    hResult = MFCreateMediaType(&pOutputType);
    if (S_OK != hResult) {
        return false;
    }

    GUID guidSubType;
    for (int i = 0; i < 10; ++i) {

        ComPtr<IMFMediaType> pTempOutputType = nullptr;
        hResult = MFCreateMediaType(&pTempOutputType);
        if (S_OK != hResult) {
            return false;
        }

        hResult = mAudioDecoder->GetOutputAvailableType(0, i, &pTempOutputType);
        if (hResult == MF_E_NO_MORE_TYPES) {
            break;
        }

        hResult = pTempOutputType->GetGUID(MF_MT_SUBTYPE, &guidSubType);
        if (S_OK != hResult) {
            LogError("oh no");
            continue;
        }

        if (guidSubType == MFAudioFormat_Float) {
            pTempOutputType->CopyAllItems(pOutputType.Get());
            break;
        }
    }

    uint32_t floatOutputBits = 0;
    pOutputType->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, &floatOutputBits);
    if (floatOutputBits != 32) {
        LogError("No float output type for decoder");
        return false;
    }

    hResult = mAudioDecoder->SetOutputType(0, pOutputType.Get(), 0);
    if (S_OK != hResult) {
        LogError("Couldn't set output type of audio decoder.");
        return false;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文