Quantcast
Channel: Media Foundation Development for Windows Desktop forum
Viewing all articles
Browse latest Browse all 1079

encode WAVE_FORMAT_EXTENSIBLE with a FLOAT format to WMA Lossless

$
0
0

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






Viewing all articles
Browse latest Browse all 1079

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>