Медиа фундамент: запись G711 PCMU в mp4 - PullRequest
1 голос
/ 12 февраля 2020

У нас есть требование (Windows приложение UWP) хранить аудио и видео данные, полученные с камер (RTP-пакеты) в формате mp4.Видео - h264, а аудио - g711 pcmu

* 1004. * Мы используем media foundation (c# с использованием MF. Net) sinkWriter для записи видеоданных в mp4, что прекрасно работает. Я хотел бы знать, как записать аудио образцы в mp4. Я пробовал следующим образом:
private void SetupAudioMediaType(out IMFMediaType mediaType, in Guid audioSubType)
{    
    HResult hr = HResult.S_OK;

    hr = MFExtern.MFCreateMediaType(out mediaType);
    if (!hr.Succeeded())
    {
        Debug.Fail("MFCreateMediaType for audio failed " + hr.ToString());
        return;
    }

    hr = mediaType.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Audio);
    if (!hr.Succeeded())
    {
        Debug.Fail("Set MF_MT_MAJOR_TYPE media-out failed " + hr.ToString());
        return ;
    }
    hr = mediaType.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, audioSubType);
    if (!hr.Succeeded())
    {
        Debug.Fail("Set MF_MT_SUBTYPE media-out failed " + hr.ToString());
        return ;
    }

    hr = mediaType.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000);
    if (!hr.Succeeded())
    {
        Debug.Fail("Set MF_MT_AUDIO_SAMPLES_PER_SECOND media-out failed " + hr.ToString());
        return 
    }

    hr = mediaType.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_NUM_CHANNELS, 1);
    if (!hr.Succeeded())
    {
        Debug.Fail("Set MF_MT_AUDIO_NUM_CHANNELS media-out failed " + hr.ToString());
        return ;
    }

    hr = mediaType.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_BITS_PER_SAMPLE, 8);
    if (!hr.Succeeded())
    {
        Debug.Fail("Set MF_MT_AUDIO_BITS_PER_SAMPLE media-out failed " + hr.ToString());
        return ;
    }

    return errorCode;
}



private MultiplexerErrorCode SetupAudio()
{
    HResult hr = HResult.S_OK;

    IMFMediaType mediaTypeOut = null;
    IMFMediaType mediaTypeIn = null;

    SetupAudioMediaType(out mediaTypeOut, MFMediaType.AAC);  // or mp3 (MP4 in windows support mp3 or aac)
    if (errorCode != MultiplexerErrorCode.Success)
    {
        Debug.Fail("setupAudioMediaType output failed:", errorCode.ToString());
    }
    else
    {
        hr = sinkWriter.AddStream(mediaTypeOut, out audioStreamIndex);
        if (!hr.Succeeded())
        {
            Debug.Fail("AddStream  audio  failed " + hr.ToString());
        }
        else
        {
            Guid PcmuAudioSubType = (new FourCC(7,0,0,0)).ToMediaSubtype();   //PCMU
            SetupAudioMediaType(out mediaTypeIn, PcmuAudioSubType);
            hr = sinkWriter.SetInputMediaType(audioStreamIndex, mediaTypeIn, null);
            if (!hr.Succeeded())
            {
                Debug.Fail("SetInputMediaType audio  failed " + hr.ToString());
            }
        }
    }

    return ;
}

SetInputMediaType возвращает ошибку MF_E_INVALIDMEDIATYPE. Из моего анализа ниже приведены причины ошибки

1) Я думаю, что тип ввода PCMU не поддерживается. Это должен быть PCM. Это понимание является основным? Если это так, значит ли это, что я должен декодировать PCMU в PCM. Если есть какой-либо API windows c#, который это делает? И как только будет выполнено это декодирование, каковы биты на выборку в выходных pcm. Это 16?

2) Даже если я предоставлю pcm в качестве типа ввода, SetInputMediaType возвращает ошибку MF_E_INVALIDMEDIATYPE. Это потому, что кодировщик c поддерживает только частоту дискретизации 44,1 и 48 кГц. (mp3 поддерживает 32 кГц, ...). Если мое понимание верно, как мне преодолеть проблему. Должен ли я обновить. Если да, то как?

3) Есть ли более простой способ записи pcmu (8000 выборок в секунду, 8 бит на выборку) в mp4 вместе с видеокадрами

1 Ответ

1 голос
/ 13 февраля 2020

Для 1) и 3) прочитайте это: muxing-only-audio-into-mp4-ffmpeg-failed

Для 2)

  • декодирование G711 - PCM (CLSID_MULawCodecWrapper: 92B66080-5E2D-449E-90C4-C41F268E5514)
  • использовать аудио ресемплер ( Audio Resampler DSP )
  • кодировать PCM с преобразованием в AAM 10 10 * ( AA C Encoder )

Возможно, CLSID_MULawCodecWrapper может выполнить повторную выборку. Возможно, у вас будут проблемы с синхронизацией аудио / видео.

...