2017-01-03 2 views
-1

Я кодирую H264 видео с помощью Windows Media Foundation. (Я использую его через C# с помощью MFNet Wrapper).Media Foundation MP4 Кодирование: IMFSinkWriter не принимает вход PCM

Видеокодирование работает отлично. Я получаю MP4 с видео H264.

Теперь я пытаюсь добавить аудио. Я хочу передать в несжатый PCM из памяти и выйти из кодированного AAC. Я добавляю аудиопоток к моему SinkWriter. öНо звоните SetInputMediaType, я получаю MF_E_INVALIDMEDIATYPE.

Почему?

Вот мой код:

IMFMediaType audioTypeOut, audioTypeIn, videoTypeOut, videoTypeIn; 
IMFSinkWriter sinkWriter; 

Check = MFCreateSinkWriterFromURL(outputFile.Replace(".avi",".mp4"), null, attributes, out sinkWriter); // the assignment to "Check" throws an exception if a method fails. 

//[ ... setup video input & output - works perfectly ...] 
Check = sinkWriter.AddStream(videoTypeOut, out videoStreamIndex); 
Check = sinkWriter.SetInputMediaType(videoStreamIndex, videoTypeIn, null); 

// Now setup Audio: 
// Input PCM from memory 
Check = MFExtern.MFCreateMediaType(out audioTypeIn); 
Check = audioTypeIn.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Audio); 
Check = audioTypeIn.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.PCM); // this .PCM enum value is equal to MFAudioFormat_PCM in the C++ api (I checked) 
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_NUM_CHANNELS, 2); 
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100); 
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_BLOCK_ALIGNMENT, 4); 
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 * 4); 
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_BITS_PER_SAMPLE, 16); 
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_ALL_SAMPLES_INDEPENDENT, 1); 

// and output AAC to the MP4 file 
Check = MFExtern.MFCreateMediaType(out audioTypeOut); 
Check = audioTypeOut.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Audio); 
Check = audioTypeOut.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.AAC); 
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_NUM_CHANNELS, 2); 
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100); 
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_BITS_PER_SAMPLE, 16); 
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_ALL_SAMPLES_INDEPENDENT, 0); 

// pass it to the sinkWriter 
Check = sinkWriter.AddStream(audioTypeOut, out audioStreamIndex); 
Check = sinkWriter.SetInputMediaType(audioStreamIndex, audioTypeIn, null); // this call fails 

Теперь, когда я пытаюсь передать в AAC, настроечный код работает отлично. Заставляет меня думать, что я неправильно настраиваю PCM IMFMediaType, но я не могу обнаружить ошибку.

+1

Вход для входа FYI AAC должен быть «MFAudioFormat_PCM». Для вашего LPCM может потребоваться преобразование, которое недоступно как автоматическое. –

+0

@ RomanR. Спасибо, я изменил его на PCM. Без изменений - появляется та же ошибка. (И я подтвердил, что мой «PCM» в C# api имеет то же значение, что и MFAudioFormat_PCM в официальном SDK) – LTR

+1

ОК, так что следующая вещь, не выглядящая хорошо, - это ваш MF_MT_ALL_SAMPLES_INDEPENDENT по типу AAC. Почему бы вам не прокомментировать это полностью. –

ответ

1

типы аудио медиа могут быть инициализированы следующим образом: будет получена

// Input PCM from memory 
Check = MFExtern.MFCreateMediaType(out audioTypeIn); 
Check = audioTypeIn.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Audio); 
Check = audioTypeIn.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.PCM); 
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_NUM_CHANNELS, 2); 
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100); 
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_BITS_PER_SAMPLE, 16); 

// and output AAC to the MP4 file 
Check = MFExtern.MFCreateMediaType(out audioTypeOut); 
Check = audioTypeOut.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Audio); 
Check = audioTypeOut.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.AAC); 
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_NUM_CHANNELS, 2); 
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100); 
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_BITS_PER_SAMPLE, 16); 

Другие атрибуты, и неправильное использование MF_MT_ALL_SAMPLES_INDEPENDENT в исходном фрагменте кода предотвращает от инициализации кодека.