// This is called from the DoProcessOutput method if the stream format // has changed. // // Thread context: decoder thread bool DecoderMF::HandleStreamChange() { bool ret = false; HRESULT hr; DWORD numOutputStreams; IMFMediaType* mediaType = NULL; AM_MEDIA_TYPE* mformt = NULL; hr = m_h264Decoder->GetStreamCount(NULL, &numOutputStreams); if (FAILED(hr)) goto bail; if (numOutputStreams != 1) goto bail; hr = S_OK; int idx = 0; while (hr == S_OK) { hr = m_h264Decoder->GetOutputAvailableType(0, idx, &mediaType); if (FAILED(hr)) goto bail; mediaType->GetRepresentation(FORMAT_MFVideoFormat , (LPVOID*)&mformt); MFVIDEOFORMAT* z = (MFVIDEOFORMAT*)mformt->pbFormat; unsigned int format = z->surfaceInfo.Format; mediaType->FreeRepresentation(FORMAT_MFVideoFormat ,(LPVOID)mformt); if (format == '2YUY') break; ++idx; } hr = m_h264Decoder->SetOutputType(0, mediaType, 0); if (FAILED(hr)) goto bail; if (! CreateOutputSample()) goto bail; if (m_previewWindow != NULL) { if (! m_previewWindow->SetMediaType(mediaType)) goto bail; m_previewConfigured = true; } ret = true; bail: if (mediaType != NULL) mediaType->Release(); return ret; }
MediaFoundationTransform::MediaFoundationTransform(IMFActivate *activationObj, WmaEncodingFormat encodingFormat) { UINT32 nameLen; // Transform name is an MFActivate object property, so get that first activationObj->GetString(MFT_FRIENDLY_NAME_Attribute, _transformName, sizeof(_transformName), &nameLen); HRESULT hr = activationObj->ActivateObject(IID_PPV_ARGS(&_mfEncoder)); hr = _mfEncoder->QueryInterface(IID_PPV_ARGS(&_propertyStore)); // Configure the tranform to perform the requested compression format switch (encodingFormat) { case WmaEncodingFormat::Lossless: SetBooleanProperty(MFPKEY_VBRENABLED, true); SetBooleanProperty(MFPKEY_CONSTRAIN_ENUMERATED_VBRQUALITY, true); SetUint32Property(MFPKEY_DESIRED_VBRQUALITY, 100); break; case WmaEncodingFormat::Quality_10: SetBooleanProperty(MFPKEY_VBRENABLED, true); SetBooleanProperty(MFPKEY_CONSTRAIN_ENUMERATED_VBRQUALITY, true); SetUint32Property(MFPKEY_DESIRED_VBRQUALITY, 10); break; case WmaEncodingFormat::Quality_25: SetBooleanProperty(MFPKEY_VBRENABLED, true); SetBooleanProperty(MFPKEY_CONSTRAIN_ENUMERATED_VBRQUALITY, true); SetUint32Property(MFPKEY_DESIRED_VBRQUALITY, 25); break; case WmaEncodingFormat::Quality_50: SetBooleanProperty(MFPKEY_VBRENABLED, true); SetBooleanProperty(MFPKEY_CONSTRAIN_ENUMERATED_VBRQUALITY, true); SetUint32Property(MFPKEY_DESIRED_VBRQUALITY, 50); break; case WmaEncodingFormat::Quality_75: SetBooleanProperty(MFPKEY_VBRENABLED, true); SetBooleanProperty(MFPKEY_CONSTRAIN_ENUMERATED_VBRQUALITY, true); SetUint32Property(MFPKEY_DESIRED_VBRQUALITY, 75); break; case WmaEncodingFormat::Quality_90: SetBooleanProperty(MFPKEY_VBRENABLED, true); SetBooleanProperty(MFPKEY_CONSTRAIN_ENUMERATED_VBRQUALITY, true); SetUint32Property(MFPKEY_DESIRED_VBRQUALITY, 90); break; case WmaEncodingFormat::Quality_98: SetBooleanProperty(MFPKEY_VBRENABLED, true); SetBooleanProperty(MFPKEY_CONSTRAIN_ENUMERATED_VBRQUALITY, true); SetUint32Property(MFPKEY_DESIRED_VBRQUALITY, 98); break; } hr = _propertyStore->Commit(); // enumerate output types and try to find the appropriate one for our purposes DWORD index = 0; while (true) { IMFMediaType *mediaType; hr = _mfEncoder->GetOutputAvailableType(0, index++, &mediaType); if (hr == MF_E_NO_MORE_TYPES) break; // Get the AM_MEDIA_TYPE structure from the media type, in case we want to need // to differentiate between Standard and Pro WMA codecs in the future... AM_MEDIA_TYPE *amMediaType; mediaType->GetRepresentation(AM_MEDIA_TYPE_REPRESENTATION, (LPVOID *) &amMediaType); WAVEFORMATEX *waveFormat = (WAVEFORMATEX *) amMediaType->pbFormat; // there's only a few things we're interested in with the output type, so only bother grabbing those values UINT32 channelCount; UINT32 samplesPerSecond; UINT32 bitsPerSample; hr = mediaType->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &channelCount); hr = mediaType->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &samplesPerSecond); hr = mediaType->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, &bitsPerSample); if ((channelCount == 2) && (bitsPerSample == 16) && (samplesPerSecond == 44100)) { _mfMediaType = mediaType; // IMFActivate *areYouFuckingSerious; // activationObj->ShutdownObject(); // _mfEncoder->Release(); // hr = MFCreateWMAEncoderActivate(mediaType, _propertyStore, &areYouFuckingSerious); // hr = areYouFuckingSerious->ActivateObject(IID_PPV_ARGS(&_mfEncoder)); break; } } index = 0; }