Hi,
i am working on audio encoding and struggling with the initialization of the sink writers input and output.
My app does real time audio recording of the system mix via loopback/event-driven-buffering and the formats i am getting with the buffer are not always plain mono/stereo wave format. So when its a multichannel wave format i definitly want to record all the present channels and it seems that only the Windows Media Audio Professional/Lossless and the MPEG2 Audio codec are able to do this in Windows Media Foundation.
This is the source format i have at the moment :
Wave Format = WAVE_FORMAT_EXTENSIBLE / 65534
Audio Format = WAVE_FORMAT_IEEE_FLOAT
Audio Channels = 6
Audio Channel Mask = 1551
Audio Samples = 48000
Audio Bits Per Sample = 32
Audio Valid Bits Per Sample = 32
Audio Block Alignment = 24
After reading into the available codecs for Media Foundation i chose WMA Lossless because it should give me exactly what i want. In my app i am capturing audio and video in real time and because video encoding with sink writer is already finished and runs perfectly i just tryed to add an audio stream. First i was creating an MPEG4 file sink and set input and output for video, which worked fine, then i added an audiostream and the app crashed ( tryed hundreds of codec settings and of course went precise after the documentary ). But because i never succeded with the audiostream ( not even when i build the sink myslef with plain stereo WMV/WMA streams ) i became curious. So i did build a simple testapp with just one button for recording, and took the "capturing a stream" example from here : http://msdn.microsoft.com/en-us/library/windows/desktop/dd370800(v=vs.85).aspx
Here is the code for the sink writer initialization which Crashs :
HRESULT InitializeSinkWriter(WAVEFORMATEX *pwfx) { IMFMediaType *pMediaTypeIn = NULL; IMFMediaType *pMediaTypeOut = NULL; HRESULT hr = MFCreateSinkWriterFromURL(L"C:\\Users\\XXXXX\\Videos\\Output.wma", NULL, NULL, &pSinkWriter); WAVEFORMATEXTENSIBLE *pwfex = reinterpret_cast<WAVEFORMATEXTENSIBLE*>(pwfx); if(SUCCEEDED(hr))hr = MFCreateMediaType(&pMediaTypeOut); if(SUCCEEDED(hr))hr = pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio); if(SUCCEEDED(hr))hr = pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_WMAudio_Lossless); if(SUCCEEDED(hr))hr = pMediaTypeOut->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, pwfex->Format.nChannels); if(SUCCEEDED(hr))hr = pMediaTypeOut->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, pwfex->Format.nSamplesPerSec); if(SUCCEEDED(hr))hr = pMediaTypeOut->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, pwfex->Format.wBitsPerSample); if(SUCCEEDED(hr))hr = pMediaTypeOut->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, pwfex->Format.nBlockAlign); if(SUCCEEDED(hr))hr = pMediaTypeOut->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, pwfex->Format.nAvgBytesPerSec); if(SUCCEEDED(hr))hr = pSinkWriter->AddStream(pMediaTypeOut, &audioStream); if(SUCCEEDED(hr))hr = MFCreateMediaType(&pMediaTypeIn); if(SUCCEEDED(hr))hr = pMediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio); if(SUCCEEDED(hr))hr = pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_Float); if(SUCCEEDED(hr))hr = pMediaTypeIn->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, pwfex->Format.nChannels); if(SUCCEEDED(hr))hr = pMediaTypeIn->SetUINT32(MF_MT_AUDIO_CHANNEL_MASK, pwfex->dwChannelMask); if(SUCCEEDED(hr))hr = pMediaTypeIn->SetUINT32(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND, pwfex->Format.nSamplesPerSec); if(SUCCEEDED(hr))hr = pMediaTypeIn->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, pwfex->Format.wBitsPerSample); if(SUCCEEDED(hr))hr = pMediaTypeIn->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, pwfex->Format.nAvgBytesPerSec); if(SUCCEEDED(hr))hr = pMediaTypeIn->SetUINT32(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, pwfex->Samples.wValidBitsPerSample); if(SUCCEEDED(hr))hr = pMediaTypeIn->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, pwfex->Format.nBlockAlign); if(SUCCEEDED(hr))hr = pMediaTypeIn->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); if(SUCCEEDED(hr))hr = pSinkWriter->SetInputMediaType(audioStream, pMediaTypeIn, NULL); if(SUCCEEDED(hr))hr = pSinkWriter->BeginWriting(); pMediaTypeOut->Release(); pMediaTypeIn->Release(); return hr; }
The average bytes per second on the output type should be different from the input of course but theres no guideline in the documentary how high it can go ( for all other codecs its in the documentary... ) or how to set the compression/quality rate ( from the documentary it seems the wma/wmv MFT has a default rate when u dont set anything ). But whatever u set the average bytes per second to it doesnt change anything crash related. The app crashs on both lines pMediaTypeOut- and pMediaTypeIn->Release, what makes it obvious that the pointers are already NULL and never were set right.
EDIT : If i omit these 2 pointer release lines then the app dont crash
Any ideas ?
regards
coOKie