private int GetUInt32(Guid key) { int value; mediaType.GetUINT32(key, out value); return(value); }
/// <summary> /// Validates a media type for this transform. /// </summary> /// <param name="pmt">The media type to validate.</param> /// <returns>S_Ok or MF_E_INVALIDTYPE.</returns> /// <remarks>Since both input and output types must be /// the same, they both call this routine.</remarks> private HResult OnCheckMediaType(IMFMediaType pmt) { HResult hr = HResult.S_OK; hr = CheckMediaType(pmt, MFMediaType.Video, m_MediaSubtypes); if (Succeeded(hr)) { int interlace; // Video must be progressive frames. m_MightBeInterlaced = false; MFError throwonhr = pmt.GetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, out interlace); MFVideoInterlaceMode im = (MFVideoInterlaceMode)interlace; // Mostly we only accept Progressive. if (im != MFVideoInterlaceMode.Progressive) { // If the type MIGHT be interlaced, we'll accept it. if (im != MFVideoInterlaceMode.MixedInterlaceOrProgressive) { hr = HResult.MF_E_INVALIDTYPE; } else { // But we will check to see if any samples actually // are interlaced, and reject them. m_MightBeInterlaced = true; } } } return(hr); }
public HRESULT GetUINT32(Guid guidKey, out uint punValue) { var hr = _type.GetUINT32(guidKey, out punValue); Trace("guid: " + guidKey.ToName() + " value: " + punValue + " hr: " + hr); return(hr); }
/// <summary>Validate a PCM audio media type.</summary> /// <param name="pmt">The audio type to validate.</param> /// <returns>S_Ok if valid, else MF_E_INVALIDMEDIATYPE.</returns> HResult ValidatePCMAudioType(IMFMediaType pmt) { HResult hr = HResult.S_OK; hr = CheckMediaType(pmt, MFMediaType.Audio, m_MediaSubtypes); if (Succeeded(hr)) { // Get attributes from the media type. // Each of these attributes is required for uncompressed PCM // audio, so fail if any are not present. int nChannels = 0; int nSamplesPerSec = 0; int nAvgBytesPerSec = 0; int nBlockAlign = 0; int wBitsPerSample = 0; MFError throwonhr; throwonhr = pmt.GetUINT32(MFAttributesClsid.MF_MT_AUDIO_NUM_CHANNELS, out nChannels); throwonhr = pmt.GetUINT32(MFAttributesClsid.MF_MT_AUDIO_SAMPLES_PER_SECOND, out nSamplesPerSec); throwonhr = pmt.GetUINT32(MFAttributesClsid.MF_MT_AUDIO_AVG_BYTES_PER_SECOND, out nAvgBytesPerSec); throwonhr = pmt.GetUINT32(MFAttributesClsid.MF_MT_AUDIO_BLOCK_ALIGNMENT, out nBlockAlign); throwonhr = pmt.GetUINT32(MFAttributesClsid.MF_MT_AUDIO_BITS_PER_SAMPLE, out wBitsPerSample); // Validate the values. if ( (nChannels == 1 || nChannels == 2) && (wBitsPerSample == 8 || wBitsPerSample == 16) && (nBlockAlign == nChannels * (wBitsPerSample / 8)) && (nSamplesPerSec < (int)(int.MaxValue / nBlockAlign)) && (nAvgBytesPerSec == nSamplesPerSec * nBlockAlign) ) { hr = HResult.S_OK; } else { hr = HResult.MF_E_INVALIDMEDIATYPE; } } return(hr); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Called when the input type gets set. We record the basic image /// size and format information here. /// /// Expects the InputType variable to have been set. This will have been /// done in the base class immediately before this routine gets called /// /// An override of the virtual stub in TantaMFTBase_Sync. /// </summary> /// <history> /// 01 Nov 18 Cynic - Ported In /// </history> override protected void OnSetInputType() { HResult hr; // init some things m_imageWidthInPixels = 0; m_imageHeightInPixels = 0; m_cbImageSize = 0; m_lStrideIfContiguous = 0; // get this now, the type can be null to clear IMFMediaType pmt = InputType; if (pmt == null) { // Since the input must be set before the output, nulling the // input must also clear the output. Note that nulling the // input is only valid if we are not actively streaming. OutputType = null; return; } // get the image width and height in pixels. These will become // very important later when the time comes to size and center the // text we will write on the screen. // Note that changing the size of the image on the screen, by resizing // the EVR control does not change this image size. The EVR will // remove various rows and columns as necssary for display purposes hr = MFExtern.MFGetAttributeSize(pmt, MFAttributesClsid.MF_MT_FRAME_SIZE, out m_imageWidthInPixels, out m_imageHeightInPixels); if (hr != HResult.S_OK) { throw new Exception("OnSetInputType call to get the image size failed failed. Err=" + hr.ToString()); } // get the image size hr = MFExtern.MFGetAttributeSize(pmt, MFAttributesClsid.MF_MT_FRAME_SIZE, out m_imageWidthInPixels, out m_imageHeightInPixels); if (hr != HResult.S_OK) { throw new Exception("OnSetInputType call to get MFGetAttributeSize failed failed. Err=" + hr.ToString()); } // get the image stride. The stride is the number of bytes from one row of pixels in memory // to the next row of pixels in memory. If padding bytes are present, the stride is wider // than the width of the image. hr = pmt.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out m_lStrideIfContiguous); if (hr != HResult.S_OK) { throw new Exception("OnSetInputType call to MF_MT_DEFAULT_STRIDE failed failed. Err=" + hr.ToString()); } // Calculate the image size (including padding) m_cbImageSize = m_imageHeightInPixels * m_lStrideIfContiguous; OnSetOutputType(); }
public static bool GetBoolean(this IMFMediaType input, Guid key, bool defaultValue = false) { if (input == null) { throw new ArgumentNullException(nameof(input)); } if (input.GetUINT32(key, out var value).IsError) { return(defaultValue); } return(value != 0); }
public static uint GetUInt32(this IMFMediaType input, Guid key, uint defaultValue = 0) { if (input == null) { throw new ArgumentNullException(nameof(input)); } if (input.GetUINT32(key, out var value).IsError) { return(defaultValue); } return(value); }
public static int GetInt32(this IMFMediaType obj, Guid key, int defaultValue = 0) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } if (obj.GetUINT32(key, out var value).IsError) { return(defaultValue); } return((int)value); }
//----------------------------------------------------------------------------- // GetDefaultStride // // Gets the default stride for a video frame, assuming no extra padding bytes. // //----------------------------------------------------------------------------- private static int GetDefaultStride(IMFMediaType pType, out int plStride) { int lStride; plStride = 0; // Try to get the default stride from the media type. var hr = pType.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out lStride); if (Failed(hr)) { // Attribute not set. Try to calculate the default stride. Guid subtype; var width = 0; // ReSharper disable once TooWideLocalVariableScope // ReSharper disable once RedundantAssignment var height = 0; // Get the subtype and the image size. hr = pType.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out subtype); if (Succeeded(hr)) { hr = CProcess.MfGetAttributeSize(pType, out width, out height); } if (Succeeded(hr)) { var f = new FourCC(subtype); hr = MFExtern.MFGetStrideForBitmapInfoHeader(f.ToInt32(), width, out lStride); } // Set the attribute for later reference. if (Succeeded(hr)) { hr = pType.SetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, lStride); } } if (Succeeded(hr)) { plStride = lStride; } return(hr); }
//----------------------------------------------------------------------------- // GetDefaultStride // // Gets the default stride for a video frame, assuming no extra padding bytes. // //----------------------------------------------------------------------------- private static HResult GetDefaultStride(IMFMediaType pType, out int plStride) { int lStride = 0; plStride = 0; // Try to get the default stride from the media type. HResult hr = pType.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out lStride); if (Failed(hr)) { // Attribute not set. Try to calculate the default stride. Guid subtype = Guid.Empty; int width = 0; int height = 0; // Get the subtype and the image size. hr = pType.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out subtype); if (Succeeded(hr)) { hr = MFExtern.MFGetAttributeSize(pType, MFAttributesClsid.MF_MT_FRAME_SIZE, out width, out height); } if (Succeeded(hr)) { FourCC f = new FourCC(subtype); hr = MFExtern.MFGetStrideForBitmapInfoHeader(f.ToInt32(), width, out lStride); } // Set the attribute for later reference. if (Succeeded(hr)) { hr = pType.SetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, lStride); } } if (Succeeded(hr)) { plStride = lStride; } return(hr); }
override protected void OnSetInputType() { MFError throwonhr; m_imageWidthInPixels = 0; m_imageHeightInPixels = 0; m_cbImageSizeInput = 0; m_cbImageSizeOutput = 0; m_StrideOut = 0; IMFMediaType pmt = InputType; // type can be null to clear if (pmt != null) { TraceAttributes(pmt); throwonhr = MFExtern.MFGetAttributeSize(pmt, MFAttributesClsid.MF_MT_FRAME_SIZE, out m_imageWidthInPixels, out m_imageHeightInPixels); // Calculate the image size (not including padding) m_StrideOut = m_imageWidthInPixels * 4; if (Failed(pmt.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out m_StrideIn))) { m_StrideIn = m_imageWidthInPixels * 2; } m_cbImageSizeInput = m_StrideIn * m_imageHeightInPixels; m_cbImageSizeOutput = m_StrideOut * m_imageHeightInPixels; // If the output type isn't set yet, we can pre-populate it, // since output is based on the input. This can // save a (tiny) bit of time in negotiating types. OnSetOutputType(); } else { // Since the input must be set before the output, nulling the // input must also clear the output. Note that nulling the // input is only valid if we are not actively streaming. OutputType = null; } }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Validates a media type for this transform. Since both input and output types must be /// the same, they both call this routine. /// </summary> /// <param name="pmt">The media type to validate.</param> /// <returns>S_Ok or MF_E_INVALIDTYPE.</returns> /// <history> /// 01 Nov 18 Cynic - Ported over /// </history> private HResult OnCheckMediaType(IMFMediaType pmt) { int interlace; HResult hr = HResult.S_OK; // see if the media type is one of our list of acceptable subtypes hr = TantaWMFUtils.CheckMediaType(pmt, MFMediaType.Video, m_MediaSubtypes); if (hr != HResult.S_OK) { throw new Exception("OnCheckMediaType call to TantaWMFUtils.CheckMediaType failed. Err=" + hr.ToString()); } // Video must be progressive frames. Set this now m_MightBeInterlaced = false; // get the interlace mode hr = pmt.GetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, out interlace); if (hr != HResult.S_OK) { throw new Exception("OnCheckMediaType call to getting the interlace mode failed. Err=" + hr.ToString()); } // set it now MFVideoInterlaceMode im = (MFVideoInterlaceMode)interlace; // Mostly we only accept Progressive. if (im == MFVideoInterlaceMode.Progressive) { return(HResult.S_OK); } // If the type MIGHT be interlaced, we'll accept it. if (im == MFVideoInterlaceMode.MixedInterlaceOrProgressive) { // But we will check to see if any samples actually // are interlaced, and reject them. m_MightBeInterlaced = true; return(HResult.S_OK); } // not a valid option return(HResult.MF_E_INVALIDTYPE); }
/// <summary> /// Validates a media type for this transform. /// </summary> /// <param name="pmt">The media type to validate.</param> /// <returns>S_Ok or MF_E_INVALIDTYPE.</returns> /// <remarks>Since both input and output types must be /// the same, they both call this routine.</remarks> private HResult OnCheckMediaType(IMFMediaType pmt, Guid[] gType) { HResult hr = HResult.S_OK; hr = CheckMediaType(pmt, MFMediaType.Video, gType); if (Succeeded(hr)) { MFError throwonhr; int interlace; // Video must be progressive frames. throwonhr = pmt.GetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, out interlace); MFVideoInterlaceMode im = (MFVideoInterlaceMode)interlace; if (im == MFVideoInterlaceMode.Progressive) { m_MightBeInterlaced = false; } else { if (im == MFVideoInterlaceMode.MixedInterlaceOrProgressive) { m_MightBeInterlaced = true; } else { hr = HResult.MF_E_INVALIDTYPE; } } } // In theory we should check to ensure sizes etc are the same as // input, but I'm just going to assume. return(hr); }
//----------------------------------------------------------------------------- // GetDefaultStride // // Gets the default stride for a video frame, assuming no extra padding bytes. // //----------------------------------------------------------------------------- private static int GetDefaultStride(IMFMediaType pType, out int plStride) { int lStride; plStride = 0; // Try to get the default stride from the media type. var hr = pType.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out lStride); if (Failed(hr)) { // Attribute not set. Try to calculate the default stride. Guid subtype; var width = 0; // ReSharper disable once TooWideLocalVariableScope // ReSharper disable once RedundantAssignment var height = 0; // Get the subtype and the image size. hr = pType.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out subtype); if (Succeeded(hr)) { hr = CProcess.MfGetAttributeSize(pType, out width, out height); } if (Succeeded(hr)) { var f = new FourCC(subtype); hr = MFExtern.MFGetStrideForBitmapInfoHeader(f.ToInt32(), width, out lStride); } // Set the attribute for later reference. if (Succeeded(hr)) { hr = pType.SetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, lStride); } } if (Succeeded(hr)) { plStride = lStride; } return hr; }
override protected void OnSetInputType() { MFError throwonhr; m_imageWidthInPixels = 0; m_imageHeightInPixels = 0; m_cbImageSize = 0; m_lStrideIfContiguous = 0; IMFMediaType pmt = InputType; // type can be null to clear if (pmt != null) { throwonhr = MFExtern.MFGetAttributeSize(pmt, MFAttributesClsid.MF_MT_FRAME_SIZE, out m_imageWidthInPixels, out m_imageHeightInPixels); throwonhr = pmt.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out m_lStrideIfContiguous); // Calculate the image size (not including padding) m_cbImageSize = m_imageHeightInPixels * m_lStrideIfContiguous; float fSize; // scale the font size in some portion to the video image fSize = 9; fSize *= (m_imageWidthInPixels / 64.0f); if (m_fontOverlay != null) { m_fontOverlay.Dispose(); } m_fontOverlay = new Font("Times New Roman", fSize, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); // scale the font size in some portion to the video image fSize = 5; fSize *= (m_imageWidthInPixels / 64.0f); if (m_transparentFont != null) { m_transparentFont.Dispose(); } m_transparentFont = new Font("Tahoma", fSize, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); // If the output type isn't set yet, we can pre-populate it, // since output must always exactly equal input. This can // save a (tiny) bit of time in negotiating types. OnSetOutputType(); } else { // Since the input must be set before the output, nulling the // input must also clear the output. Note that nulling the // input is only valid if we are not actively streaming. OutputType = null; } }
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); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Called when the input type gets set. We record the basic image /// size and format information here. /// /// Expects the InputType variable to have been set. This will have been /// done in the base class immediately before this routine gets called /// /// An override of the virtual stub in TantaMFTBase_Sync. /// </summary> /// <history> /// 01 Nov 18 Cynic - Ported In /// </history> override protected void OnSetInputType() { HResult hr; float fSize; // init some things m_imageWidthInPixels = 0; m_imageHeightInPixels = 0; m_cbImageSize = 0; m_lStrideIfContiguous = 0; // get this now, the type can be null to clear IMFMediaType pmt = InputType; if (pmt == null) { // Since the input must be set before the output, nulling the // input must also clear the output. Note that nulling the // input is only valid if we are not actively streaming. OutputType = null; return; } // get the image width and height in pixels. These will become // very important later when the time comes to size and center the // text we will write on the screen. // Note that changing the size of the image on the screen, by resizing // the EVR control does not change this image size. The EVR will // remove various rows and columns as necssary for display purposes hr = MFExtern.MFGetAttributeSize(pmt, MFAttributesClsid.MF_MT_FRAME_SIZE, out m_imageWidthInPixels, out m_imageHeightInPixels); if (hr != HResult.S_OK) { throw new Exception("OnSetInputType call to get the image size failed failed. Err=" + hr.ToString()); } // get the image size hr = MFExtern.MFGetAttributeSize(pmt, MFAttributesClsid.MF_MT_FRAME_SIZE, out m_imageWidthInPixels, out m_imageHeightInPixels); if (hr != HResult.S_OK) { throw new Exception("OnSetInputType call to get MFGetAttributeSize failed failed. Err=" + hr.ToString()); } // get the image stride. The stride is the number of bytes from one row of pixels in memory // to the next row of pixels in memory. If padding bytes are present, the stride is wider // than the width of the image. hr = pmt.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out m_lStrideIfContiguous); if (hr != HResult.S_OK) { throw new Exception("OnSetInputType call to MF_MT_DEFAULT_STRIDE failed failed. Err=" + hr.ToString()); } // Calculate the image size (including padding) m_cbImageSize = m_imageHeightInPixels * m_lStrideIfContiguous; // now perform the initial setup of the fonts we will use to draw the text. // since this information does not change (without a format change event) // this is done once here, rather than over and over again for each frame // first the overlay font which we use for the main centered text // scale the font size in some portion to the video image fSize = 9; fSize *= (m_imageWidthInPixels / 64.0f); // clean up if (m_fontOverlay != null) { m_fontOverlay.Dispose(); } // create the font m_fontOverlay = new Font( "Times New Roman", fSize, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); // now the transparent font for the frame count in the // bottom right hand corner // scale the font size in some portion to the video image fSize = 5; fSize *= (m_imageWidthInPixels / 64.0f); if (m_transparentFont != null) { m_transparentFont.Dispose(); } m_transparentFont = new Font( "Tahoma", fSize, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); // If the output type isn't set yet, we can pre-populate it, // since output must always exactly equal input. This can // save a (tiny) bit of time in negotiating types. OnSetOutputType(); }
//----------------------------------------------------------------------------- // GetDefaultStride // // Gets the default stride for a video frame, assuming no extra padding bytes. // //----------------------------------------------------------------------------- private static int GetDefaultStride(IMFMediaType pType, out int plStride) { int lStride = 0; plStride = 0; // Try to get the default stride from the media type. int hr = pType.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out lStride); if (Failed(hr)) { // Attribute not set. Try to calculate the default stride. Guid subtype = Guid.Empty; int width = 0; int height = 0; // Get the subtype and the image size. hr = pType.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out subtype); if (Succeeded(hr)) { hr = MFGetAttributeSize(pType, MFAttributesClsid.MF_MT_FRAME_SIZE, out width, out height); } if (Succeeded(hr)) { FourCC f = new FourCC(subtype); hr = MediaFoundation.MFExtern.MFGetStrideForBitmapInfoHeader(f.ToInt32(), width, out lStride); } // Set the attribute for later reference. if (Succeeded(hr)) { hr = pType.SetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, lStride); } } if (Succeeded(hr)) { plStride = lStride; } return hr; }
override protected void OnSetInputType() { MFError throwonhr; m_imageWidthInPixels = 0; m_imageHeightInPixels = 0; m_videoFOURCC = new FourCC(0); m_cbImageSize = 0; m_lStrideIfContiguous = 0; m_pTransformFn = null; IMFMediaType pmt = InputType; // type can be null to clear if (pmt != null) { Guid subtype; throwonhr = pmt.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out subtype); throwonhr = MFExtern.MFGetAttributeSize(pmt, MFAttributesClsid.MF_MT_FRAME_SIZE, out m_imageWidthInPixels, out m_imageHeightInPixels); m_videoFOURCC = new FourCC(subtype); if (m_videoFOURCC == FOURCC_YUY2) { m_pTransformFn = Update_YUY2; m_lStrideIfContiguous = m_imageWidthInPixels * 2; } else if (m_videoFOURCC == FOURCC_UYVY) { m_pTransformFn = Update_UYVY; m_lStrideIfContiguous = m_imageWidthInPixels * 2; } else if (m_videoFOURCC == FOURCC_NV12) { m_pTransformFn = Update_NV12; m_lStrideIfContiguous = m_imageWidthInPixels; } else { throw new COMException("Unrecognized type", (int)HResult.E_UNEXPECTED); } // Calculate the image size (not including padding) int lImageSize; if (Succeeded(pmt.GetUINT32(MFAttributesClsid.MF_MT_SAMPLE_SIZE, out lImageSize))) { m_cbImageSize = lImageSize; } else { m_cbImageSize = GetImageSize(m_videoFOURCC, m_imageWidthInPixels, m_imageHeightInPixels); } int lStrideIfContiguous; if (Succeeded(pmt.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out lStrideIfContiguous))) { m_lStrideIfContiguous = lStrideIfContiguous; } // If the output type isn't set yet, we can pre-populate it, // since output must always exactly equal input. This can // save a (tiny) bit of time in negotiating types. OnSetOutputType(); } else { // Since the input must be set before the output, nulling the // input must also clear the output. Note that nulling the // input is only valid if we are not actively streaming. OutputType = null; } }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Called when the input type gets set. We record the basic image /// size and format information here. /// /// Expects the InputType variable to have been set. This will have been /// done in the base class immediately before this routine gets called /// /// An override of the virtual stub in TantaMFTBase_Sync. /// </summary> /// <history> /// 01 Nov 18 Cynic - Ported In /// </history> override protected void OnSetInputType() { int lImageSize; int lStrideIfContiguous; Guid subtype; HResult hr; // init some things m_imageWidthInPixels = 0; m_imageHeightInPixels = 0; m_videoFOURCC = new FourCC(0); m_cbImageSize = 0; m_lStrideIfContiguous = 0; TransformImageFunction = null; // get this now, the type can be null to clear IMFMediaType pmt = InputType; if (pmt == null) { // Since the input must be set before the output, nulling the // input must also clear the output. Note that nulling the // input is only valid if we are not actively streaming. OutputType = null; return; } // get the subtype GUID hr = pmt.GetGUID(MFAttributesClsid.MF_MT_SUBTYPE, out subtype); if (hr != HResult.S_OK) { throw new Exception("OnSetInputType call to get the subtype guid failed. Err=" + hr.ToString()); } // get the image width and height in pixels. These will become // very important later when the time comes to convert to grey scale // Note that changing the size of the image on the screen, by resizing // the EVR control does not change this image size. The EVR will // remove various rows and columns as necssary for display purposes hr = MFExtern.MFGetAttributeSize(pmt, MFAttributesClsid.MF_MT_FRAME_SIZE, out m_imageWidthInPixels, out m_imageHeightInPixels); if (hr != HResult.S_OK) { throw new Exception("OnSetInputType call to get the image size failed failed. Err=" + hr.ToString()); } // create a working FourCC subtype from the Guid. This only works because we can always // figure out the FOURCC code from the subtype Guid - it is the first four hex digits in // reverse order m_videoFOURCC = new FourCC(subtype); // switch based on the supported formats and set our transform function // and other format specific based info if (m_videoFOURCC == FOURCC_YUY2) { TransformImageFunction = TransformImageOfTypeYUY2; m_lStrideIfContiguous = m_imageWidthInPixels * 2; } else if (m_videoFOURCC == FOURCC_UYVY) { TransformImageFunction = TransformImageOfTypeUYVY; m_lStrideIfContiguous = m_imageWidthInPixels * 2; } else if (m_videoFOURCC == FOURCC_NV12) { TransformImageFunction = TransformImageOfTypeNV12; m_lStrideIfContiguous = m_imageWidthInPixels; } else { throw new Exception("OnSetInputType Unrecognized type. Type =" + m_videoFOURCC.ToString()); } // Calculate the image size (not including padding) hr = pmt.GetUINT32(MFAttributesClsid.MF_MT_SAMPLE_SIZE, out lImageSize); if (hr == HResult.S_OK) { // we have an attribute with the image size use that m_cbImageSize = lImageSize; } else { // we calculate the image size from the format m_cbImageSize = GetImageSize(m_videoFOURCC, m_imageWidthInPixels, m_imageHeightInPixels); } // get the default stride. The stride is the number of bytes from one row of pixels in memory // to the next row of pixels in memory. If padding bytes are present, the stride is wider // than the width of the image. We will need this if the frames come in IMFMediaBuffers, // if the frames come in IMF2DBuffers we can get the stride directly from the buffer hr = pmt.GetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, out lStrideIfContiguous); if (hr != HResult.S_OK) { throw new Exception("OnSetInputType call to MFAttributesClsid.MF_MT_DEFAULT_STRIDE failed. Err=" + hr.ToString()); } // we have an attribute with the default stride m_lStrideIfContiguous = lStrideIfContiguous; // If the output type isn't set yet, we can pre-populate it, // since output must always exactly equal input. This can // save a (tiny) bit of time in negotiating types. OnSetOutputType(); }