private void NegotiateStream(uint streamIndex, Guid majorType, Guid[] possibleSubtypes) { IMFMediaType outputMediaType = null; Exception lastException = null; bool foundValidType = false; foreach (Guid subType in possibleSubtypes) { try { // Create a partial media type MFHelper.MFCreateMediaType(out outputMediaType); outputMediaType.SetGUID(new Guid(Consts.MF_MT_MAJOR_TYPE), majorType); outputMediaType.SetGUID(new Guid(Consts.MF_MT_SUBTYPE), subType); // Set it as the current media type in source reader this.sourceReader.SetCurrentMediaType(streamIndex, IntPtr.Zero, outputMediaType); // Get the full media type from Source Reader this.sourceReader.GetCurrentMediaType(streamIndex, out outputMediaType); // Set it as the input media type in Sink Writer this.sinkWriter.SetInputMediaType(this.streamsInfo[streamIndex].OutputStreamIndex, outputMediaType, null); // If no exceptions were thrown a suitable media type was found foundValidType = true; // Break from the loop so no more media types are tried break; } catch (Exception ex) { // Something went wrong, the loop will continue and the next type will be tried lastException = ex; } } // If FormatFound is false no suitable type was found and the operation can't continue if (foundValidType == false) { if (lastException != null) { throw new Exception(lastException.Message, lastException); } else { throw new Exception("Unknown error occurred"); } } }
private IMFMediaType CreateTargetVideoMediaType() { IMFMediaType mediaType = null; MFHelper.MFCreateMediaType(out mediaType); mediaType.SetGUID(new Guid(Consts.MF_MT_MAJOR_TYPE), new Guid(Consts.MFMediaType_Video)); mediaType.SetGUID(new Guid(Consts.MF_MT_SUBTYPE), this.videoOutput.Subtype); mediaType.SetUINT64(new Guid(Consts.MF_MT_FRAME_SIZE), this.videoOutput.FrameSize.Packed); mediaType.SetUINT64(new Guid(Consts.MF_MT_FRAME_RATE), this.videoOutput.FrameRate.Packed); mediaType.SetUINT64(new Guid(Consts.MF_MT_PIXEL_ASPECT_RATIO), this.videoOutput.PixelAspectRatio.Packed); mediaType.SetUINT32(new Guid(Consts.MF_MT_AVG_BITRATE), this.videoOutput.AvgBitRate); mediaType.SetUINT32(new Guid(Consts.MF_MT_INTERLACE_MODE), this.videoOutput.InterlaceMode); return(mediaType); }
private IMFMediaType CreateTargetAudioMediaType() { IMFMediaType mediaType = null; if (audioOutput.Subtype.Equals(new Guid(Consts.MFAudioFormat_AAC))) { // Create the AAC media type MFHelper.MFCreateMediaType(out mediaType); mediaType.SetGUID(new Guid(Consts.MF_MT_MAJOR_TYPE), new Guid(Consts.MFMediaType_Audio)); mediaType.SetGUID(new Guid(Consts.MF_MT_SUBTYPE), this.audioOutput.Subtype); mediaType.SetUINT32(new Guid(Consts.MF_MT_AUDIO_AVG_BYTES_PER_SECOND), this.audioOutput.AvgBytePerSecond); mediaType.SetUINT32(new Guid(Consts.MF_MT_AUDIO_NUM_CHANNELS), this.audioOutput.NumOfChannels); mediaType.SetUINT32(new Guid(Consts.MF_MT_AUDIO_SAMPLES_PER_SECOND), this.audioOutput.SamplesPerSecond); mediaType.SetUINT32(new Guid(Consts.MF_MT_AUDIO_BLOCK_ALIGNMENT), this.audioOutput.BlockAlignment); mediaType.SetUINT32(new Guid(Consts.MF_MT_AUDIO_BITS_PER_SAMPLE), this.audioOutput.BitsPerSample); } else { // Create the WMA media type uint codecConfig = 0; uint elementsNumber = 0; uint selectedType = 0; int avgBitrateDiff = int.MaxValue; uint avgBytePerSecond = uint.MaxValue; object supportedAttributes = null; // Get the available audio ouput types for the required sub type IMFCollection availableTypes = null; MFHelper.MFTranscodeGetAudioOutputAvailableTypes(audioOutput.Subtype, (uint)Enums.MFT_ENUM_FLAG.MFT_ENUM_FLAG_ALL, codecConfig, out availableTypes); // Get the number of types availableTypes.GetElementCount(out elementsNumber); for (uint elementIndex = 0; elementIndex < elementsNumber; elementIndex++) { // Get the next element availableTypes.GetElement(elementIndex, out supportedAttributes); mediaType = (IMFMediaType)supportedAttributes; // Get the byte per second mediaType.GetUINT32(new Guid(Consts.MF_MT_AUDIO_AVG_BYTES_PER_SECOND), out avgBytePerSecond); // If this is better than the last one found remember the index if (Math.Abs((int)avgBytePerSecond - (int)audioOutput.AvgBytePerSecond) < avgBitrateDiff) { selectedType = elementIndex; avgBitrateDiff = Math.Abs((int)avgBytePerSecond - (int)audioOutput.AvgBytePerSecond); } mediaType = null; } // Get the best audio type found availableTypes.GetElement(selectedType, out supportedAttributes); mediaType = (IMFMediaType)supportedAttributes; } return(mediaType); }