int ISampleGrabberCB.SampleCB(double sampleTime, IMediaSample pSample) { var mediaType = new AMMediaType(); /* We query for the media type the sample grabber is using */ int hr = m_sampleGrabber.GetConnectedMediaType(mediaType); var videoInfo = new VideoInfoHeader(); /* 'Cast' the pointer to our managed struct */ Marshal.PtrToStructure(mediaType.formatPtr, videoInfo); /* The stride is "How many bytes across for each pixel line (0 to width)" */ int stride = Math.Abs(videoInfo.BmiHeader.Width * (videoInfo.BmiHeader.BitCount / 8 /* eight bits per byte */)); int width = videoInfo.BmiHeader.Width; int height = videoInfo.BmiHeader.Height; if (m_videoFrame == null) { InitializeBitmapFrame(width, height); } if (m_videoFrame == null) { return(0); } BitmapData bmpData = m_videoFrame.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); /* Get the pointer to the pixels */ IntPtr pBmp = bmpData.Scan0; IntPtr samplePtr; /* Get the native pointer to the sample */ pSample.GetPointer(out samplePtr); int pSize = stride * height; /* Copy the memory from the sample pointer to our bitmap pixel pointer */ CopyMemory(pBmp, samplePtr, pSize); m_videoFrame.UnlockBits(bmpData); InvokeNewVideoSample(new VideoSampleArgs { VideoFrame = m_videoFrame }); DsUtils.FreeAMMediaType(mediaType); /* Dereference the sample COM object */ Marshal.ReleaseComObject(pSample); return(0); }
/// <summary> /// Finds a pin that exists in a graph. /// </summary> /// <param name="majorOrMinorMediaType">The GUID of the major or minor type of the media</param> /// <param name="pinDirection">The direction of the pin - in/out</param> /// <param name="graph">The graph to search in</param> /// <returns>Returns null if the pin was not found, or if a pin is found, returns the first instance of it</returns> protected static IPin FindPinInGraphByMediaType(Guid majorOrMinorMediaType, PinDirection pinDirection, IGraphBuilder graph) { IEnumFilters enumFilters; /* Get the filter enum */ graph.EnumFilters(out enumFilters); /* Init our vars */ var filters = new IBaseFilter[1]; var fetched = IntPtr.Zero; IPin pin = null; IEnumMediaTypes mediaTypesEnum = null; /* Loop over each filter in the graph */ while (enumFilters.Next(1, filters, fetched) == 0) { var filter = filters[0]; int i = 0; /* Loop over each pin in the filter */ while ((pin = DsFindPin.ByDirection(filter, pinDirection, i)) != null) { /* Get the pin enumerator */ pin.EnumMediaTypes(out mediaTypesEnum); var mediaTypesFetched = IntPtr.Zero; var mediaTypes = new AMMediaType[1]; /* Enumerate the media types on the pin */ while (mediaTypesEnum.Next(1, mediaTypes, mediaTypesFetched) == 0) { /* See if the major or subtype meets our requirements */ if (mediaTypes[0].majorType.Equals(majorOrMinorMediaType) || mediaTypes[0].subType.Equals(majorOrMinorMediaType)) { /* We found a match */ goto done; } } i++; } } done: if (mediaTypesEnum != null) { mediaTypesEnum.Reset(); Marshal.ReleaseComObject(mediaTypesEnum); } enumFilters.Reset(); Marshal.ReleaseComObject(enumFilters); return(pin); }
private void SetupSampleGrabber(ISampleGrabber sampleGrabber) { var mediaType = new AMMediaType { majorType = MediaType.Video, subType = MediaSubType.RGB24, formatType = FormatType.VideoInfo }; int hr = sampleGrabber.SetMediaType(mediaType); DsUtils.FreeAMMediaType(mediaType); DsError.ThrowExceptionForHR(hr); hr = sampleGrabber.SetCallback(this, 0); DsError.ThrowExceptionForHR(hr); }
/// <summary> /// Gets the video resolution of a pin on a renderer. /// </summary> /// <param name="renderer">The renderer to inspect</param> /// <param name="direction">The direction the pin is</param> /// <param name="pinIndex">The zero based index of the pin to inspect</param> /// <returns>If successful a video resolution is returned. If not, a 0x0 size is returned</returns> protected static Size GetVideoSize(IBaseFilter renderer, PinDirection direction, int pinIndex) { var size = new Size(); var mediaType = new AMMediaType(); IPin pin = DsFindPin.ByDirection(renderer, direction, pinIndex); if (pin == null) { goto done; } int hr = pin.ConnectionMediaType(mediaType); if (hr != 0) { goto done; } /* Check to see if its a video media type */ if (mediaType.formatType != FormatType.VideoInfo2 && mediaType.formatType != FormatType.VideoInfo) { goto done; } var videoInfo = new VideoInfoHeader(); /* Read the video info header struct from the native pointer */ Marshal.PtrToStructure(mediaType.formatPtr, videoInfo); Rectangle rect = videoInfo.SrcRect.ToRectangle(); size = new Size(rect.Width, rect.Height); done: DsUtils.FreeAMMediaType(mediaType); if (pin != null) { Marshal.ReleaseComObject(pin); } return(size); }
/// <summary> /// Gets the video resolution of a pin on a renderer. /// </summary> /// <param name="renderer">The renderer to inspect</param> /// <param name="direction">The direction the pin is</param> /// <param name="pinIndex">The zero based index of the pin to inspect</param> /// <returns>If successful a video resolution is returned. If not, a 0x0 size is returned</returns> protected static Size GetVideoSize(IBaseFilter renderer, PinDirection direction, int pinIndex) { var size = new Size(); var mediaType = new AMMediaType(); IPin pin = DsFindPin.ByDirection(renderer, direction, pinIndex); if (pin == null) goto done; int hr = pin.ConnectionMediaType(mediaType); if (hr != 0) goto done; /* Check to see if its a video media type */ if (mediaType.formatType != FormatType.VideoInfo2 && mediaType.formatType != FormatType.VideoInfo) { goto done; } var videoInfo = new VideoInfoHeader(); /* Read the video info header struct from the native pointer */ Marshal.PtrToStructure(mediaType.formatPtr, videoInfo); Rectangle rect = videoInfo.SrcRect.ToRectangle(); size = new Size(rect.Width, rect.Height); done: DsUtils.FreeAMMediaType(mediaType); return size; }
/// <summary> /// Finds a pin that exists in a graph. /// </summary> /// <param name="majorOrMinorMediaType">The GUID of the major or minor type of the media</param> /// <param name="pinDirection">The direction of the pin - in/out</param> /// <param name="graph">The graph to search in</param> /// <returns>Returns null if the pin was not found, or if a pin is found, returns the first instance of it</returns> protected static IPin FindPinInGraphByMediaType(Guid majorOrMinorMediaType, PinDirection pinDirection, IGraphBuilder graph) { IEnumFilters enumFilters; /* Get the filter enum */ graph.EnumFilters(out enumFilters); /* Init our vars */ var filters = new IBaseFilter[1]; var fetched = IntPtr.Zero; IPin pin = null; IEnumMediaTypes mediaTypesEnum = null; /* Loop over each filter in the graph */ while (enumFilters.Next(1, filters, fetched) == 0) { var filter = filters[0]; int i = 0; /* Loop over each pin in the filter */ while ((pin = DsFindPin.ByDirection(filter, pinDirection, i)) != null) { /* Get the pin enumerator */ pin.EnumMediaTypes(out mediaTypesEnum); var mediaTypesFetched = IntPtr.Zero; var mediaTypes = new AMMediaType[1]; /* Enumerate the media types on the pin */ while (mediaTypesEnum.Next(1, mediaTypes, mediaTypesFetched) == 0) { /* See if the major or subtype meets our requirements */ if (mediaTypes[0].majorType.Equals(majorOrMinorMediaType) || mediaTypes[0].subType.Equals(majorOrMinorMediaType)) { /* We found a match */ goto done; } } i++; } } done: if (mediaTypesEnum != null) { mediaTypesEnum.Reset(); Marshal.ReleaseComObject(mediaTypesEnum); } enumFilters.Reset(); Marshal.ReleaseComObject(enumFilters); return pin; }
/// <summary> /// Sets the number of DVD buttons found in the current DVD video /// </summary> /// <param name="buttonCount">The total number of buttons</param> private void SetDvdButtonCount(int buttonCount) { m_dvdButtonCount = buttonCount; if (m_dvdButtonCount == 0) { m_isOverButton = false; InvokeOnOverDvdButton(m_isOverButton); } var mediaType = new AMMediaType(); m_dummyRendererPin.ConnectionMediaType(mediaType); /* Check to see if its a video media type */ if (mediaType.formatType != FormatType.VideoInfo2 && mediaType.formatType != FormatType.VideoInfo) { DsUtils.FreeAMMediaType(mediaType); return; } var videoInfo = new VideoInfoHeader(); /* Read the video info header struct from the native pointer */ Marshal.PtrToStructure(mediaType.formatPtr, videoInfo); /* Get the target rect */ m_renderTargetRect = videoInfo.TargetRect.ToRectangle(); DsUtils.FreeAMMediaType(mediaType); }
/// <summary> /// Builds the DVD DirectShow graph /// </summary> private void BuildGraph() { try { FreeResources(); int hr; /* Create our new graph */ m_graph = (IGraphBuilder)new FilterGraphNoThread(); #if DEBUG m_rot = new DsROTEntry(m_graph); #endif /* We are going to use the VMR9 for now. The EVR does not * seem to work with the interactive menus yet. It should * play Dvds fine otherwise */ var rendererType = VideoRendererType.VideoMixingRenderer9; /* Creates and initializes a new renderer ready to render to WPF */ m_renderer = CreateVideoRenderer(rendererType, m_graph, 2); /* Do some VMR9 specific stuff */ if (rendererType == VideoRendererType.VideoMixingRenderer9) { var mixer = m_renderer as IVMRMixerControl9; if(mixer != null) { VMR9MixerPrefs dwPrefs; mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; dwPrefs |= VMR9MixerPrefs.RenderTargetYUV; /* Enable this line to prefer YUV */ //hr = mixer.SetMixingPrefs(dwPrefs); } } /* Create a new DVD Navigator. */ var dvdNav = (IBaseFilter)new DVDNavigator(); /* The DVDControl2 interface lets us control DVD features */ m_dvdControl = dvdNav as IDvdControl2; if (m_dvdControl == null) throw new Exception("Could not QueryInterface the IDvdControl2 interface"); /* QueryInterface the DVDInfo2 */ m_dvdInfo = dvdNav as IDvdInfo2; /* If a Dvd directory has been set then use it, if not, let DShow find the Dvd */ if (!string.IsNullOrEmpty(DvdDirectory)) { hr = m_dvdControl.SetDVDDirectory(DvdDirectory); DsError.ThrowExceptionForHR(hr); } /* This gives us the DVD time in Hours-Minutes-Seconds-Frame time format, and other options */ hr = m_dvdControl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); DsError.ThrowExceptionForHR(hr); /* If the graph stops, resume at the same point */ m_dvdControl.SetOption(DvdOptionFlag.ResetOnStop, false); hr = m_graph.AddFilter(dvdNav, "DVD Navigator"); DsError.ThrowExceptionForHR(hr); IPin dvdVideoPin = null; IPin dvdAudioPin = null; IPin dvdSubPicturePin = null; IPin dvdNavPin; int i = 0; /* Loop all the output pins on the DVD Navigator, trying to find which pins are which. * We could more easily find the pins by name, but this is more fun...and more flexible * if we ever want to use a 3rd party DVD navigator that used different pin names */ while ((dvdNavPin = DsFindPin.ByDirection(dvdNav, PinDirection.Output, i)) != null) { var mediaTypes = new AMMediaType[1]; IntPtr pFetched = IntPtr.Zero; IEnumMediaTypes mediaTypeEnum; dvdNavPin.EnumMediaTypes(out mediaTypeEnum); /* Loop over each of the mediaTypes of each pin */ while (mediaTypeEnum.Next(1, mediaTypes, pFetched) == 0) { AMMediaType mediaType = mediaTypes[0]; /* This will be the video stream pin */ if (mediaType.subType == MediaSubType.Mpeg2Video) { /* Keep the ref and we'll work with it later */ dvdVideoPin = dvdNavPin; break; } /* This will be the audio stream pin */ if (mediaType.subType == MediaSubType.DolbyAC3 || mediaType.subType == MediaSubType.Mpeg2Audio) { /* Keep the ref and we'll work with it later */ dvdAudioPin = dvdNavPin; break; } /* This is the Dvd sub picture pin. This generally * shows overlays for Dvd menus and sometimes closed captions */ if (mediaType.subType == DVD_SUBPICTURE_TYPE) { /* Keep the ref and we'll work with it later */ dvdSubPicturePin = dvdNavPin; break; } } mediaTypeEnum.Reset(); Marshal.ReleaseComObject(mediaTypeEnum); i++; } /* This is the windowed renderer. This is *NEEDED* in order * for interactive menus to work with the other VMR9 in renderless mode */ var dummyRenderer = (IBaseFilter)new VideoMixingRenderer9(); var dummyRendererConfig = (IVMRFilterConfig9)dummyRenderer; /* In order for this interactive menu trick to work, the VMR9 * must be set to Windowed. We will make sure the window is hidden later on */ hr = dummyRendererConfig.SetRenderingMode(VMR9Mode.Windowed); DsError.ThrowExceptionForHR(hr); hr = dummyRendererConfig.SetNumberOfStreams(1); DsError.ThrowExceptionForHR(hr); hr = m_graph.AddFilter(dummyRenderer, "Dummy Windowed"); DsError.ThrowExceptionForHR(hr); if (dvdAudioPin != null) { /* This should render out to the default audio device. We * could modify this code here to go out any audio * device, such as SPDIF or another sound card */ hr = m_graph.Render(dvdAudioPin); DsError.ThrowExceptionForHR(hr); } /* Get the first input pin on our dummy renderer */ m_dummyRendererPin = DsFindPin.ByConnectionStatus(dummyRenderer, /* Filter to search */ PinConnectedStatus.Unconnected, 0); /* Get an available pin on our real renderer */ IPin rendererPin = DsFindPin.ByConnectionStatus(m_renderer, /* Filter to search */ PinConnectedStatus.Unconnected, 0); /* Pin index */ /* Connect the pin to the renderer */ hr = m_graph.Connect(dvdVideoPin, rendererPin); DsError.ThrowExceptionForHR(hr); /* Get the next available pin on our real renderer */ rendererPin = DsFindPin.ByConnectionStatus(m_renderer, /* Filter to search */ PinConnectedStatus.Unconnected, 0); /* Pin index */ /* Render the sub picture, which will connect * the DVD navigator to the codec, not the renderer */ hr = m_graph.Render(dvdSubPicturePin); DsError.ThrowExceptionForHR(hr); /* These are the subtypes most likely to be our dvd subpicture */ var preferedSubpictureTypes = new[]{MediaSubType.ARGB4444, MediaSubType.AI44, MediaSubType.AYUV, MediaSubType.ARGB32}; IPin dvdSubPicturePinOut = null; /* Find what should be the subpicture pin out */ foreach (var guidType in preferedSubpictureTypes) { dvdSubPicturePinOut = FindPinInGraphByMediaType(guidType, /* GUID of the media type being searched for */ PinDirection.Output, m_graph); /* Our current graph */ if (dvdSubPicturePinOut != null) break; } if (dvdSubPicturePinOut == null) throw new Exception("Could not find the sub picture pin out"); /* Here we connec thte Dvd sub picture pin to the video renderer. * This enables the overlays on Dvd menus and some closed * captions to be rendered. */ hr = m_graph.Connect(dvdSubPicturePinOut, rendererPin); DsError.ThrowExceptionForHR(hr); /* Search for the Line21 out in the graph */ IPin line21Out = FindPinInGraphByMediaType(MediaType.AuxLine21Data, PinDirection.Output, m_graph); if (line21Out == null) throw new Exception("Could not find the Line21 pin out"); /* We connect our line21Out out in to the dummy renderer * this is what ultimatly makes interactive DVDs work with * VMR9 in renderless (for WPF) */ hr = m_graph.Connect(line21Out, m_dummyRendererPin); DsError.ThrowExceptionForHR(hr); /* This is the dummy renderers Win32 window. */ m_dummyRenderWindow = dummyRenderer as IVideoWindow; if (m_dummyRenderWindow == null) throw new Exception("Could not QueryInterface for IVideoWindow"); ConfigureDummyWindow(); /* Setup our base classes with this filter graph */ SetupFilterGraph(m_graph); /* Sets the NaturalVideoWidth/Height */ SetNativePixelSizes(m_renderer); } catch (Exception ex) { FreeResources(); InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); return; } InvokeMediaOpened(); }
int ISampleGrabberCB.SampleCB(double sampleTime, IMediaSample pSample) { var mediaType = new AMMediaType(); /* We query for the media type the sample grabber is using */ int hr = m_sampleGrabber.GetConnectedMediaType(mediaType); var videoInfo = new VideoInfoHeader(); /* 'Cast' the pointer to our managed struct */ Marshal.PtrToStructure(mediaType.formatPtr, videoInfo); /* The stride is "How many bytes across for each pixel line (0 to width)" */ int stride = Math.Abs(videoInfo.BmiHeader.Width * (videoInfo.BmiHeader.BitCount / 8 /* eight bits per byte */)); int width = videoInfo.BmiHeader.Width; int height = videoInfo.BmiHeader.Height; if(m_videoFrame == null) InitializeBitmapFrame(width, height); if (m_videoFrame == null) return 0; BitmapData bmpData = m_videoFrame.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); /* Get the pointer to the pixels */ IntPtr pBmp = bmpData.Scan0; IntPtr samplePtr; /* Get the native pointer to the sample */ pSample.GetPointer(out samplePtr); int pSize = stride * height; /* Copy the memory from the sample pointer to our bitmap pixel pointer */ CopyMemory(pBmp, samplePtr, pSize); m_videoFrame.UnlockBits(bmpData); InvokeNewVideoSample(new VideoSampleArgs { VideoFrame = m_videoFrame }); DsUtils.FreeAMMediaType(mediaType); /* Dereference the sample COM object */ Marshal.ReleaseComObject(pSample); return 0; }
private void SetupSampleGrabber() { if (_graph == null) return; int hr; //Get directsound filter IBaseFilter directSoundFilter; hr = _graph.FindFilterByName(DEFAULT_AUDIO_RENDERER_NAME, out directSoundFilter); DsError.ThrowExceptionForHR(hr); IPin rendererPinIn = DsFindPin.ByConnectionStatus(directSoundFilter, PinConnectedStatus.Connected, 0); if (rendererPinIn != null) { IPin audioPinOut; hr = rendererPinIn.ConnectedTo(out audioPinOut); DsError.ThrowExceptionForHR(hr); if (audioPinOut != null) { //Disconect audio decoder to directsound renderer hr = audioPinOut.Disconnect(); DsError.ThrowExceptionForHR(hr); hr = _graph.RemoveFilter(directSoundFilter); DsError.ThrowExceptionForHR(hr); //Add Sample Grabber ISampleGrabber sampleGrabber = new SampleGrabber() as ISampleGrabber; hr = sampleGrabber.SetCallback(this, 1); DsError.ThrowExceptionForHR(hr); AMMediaType media; media = new AMMediaType(); media.majorType = MediaType.Audio; media.subType = MediaSubType.PCM; media.formatType = FormatType.WaveEx; hr = sampleGrabber.SetMediaType(media); DsError.ThrowExceptionForHR(hr); IPin sampleGrabberPinIn = DsFindPin.ByDirection((IBaseFilter)sampleGrabber, PinDirection.Input, 0); IPin sampleGrabberPinOut = DsFindPin.ByDirection((IBaseFilter)sampleGrabber, PinDirection.Output, 0); hr = _graph.AddFilter((IBaseFilter)sampleGrabber, "SampleGrabber"); DsError.ThrowExceptionForHR(hr); PinInfo pinInfo; hr = audioPinOut.QueryPinInfo(out pinInfo); DsError.ThrowExceptionForHR(hr); FilterInfo filterInfo; hr = pinInfo.filter.QueryFilterInfo(out filterInfo); DsError.ThrowExceptionForHR(hr); hr = _graph.Connect(audioPinOut, sampleGrabberPinIn); DsError.ThrowExceptionForHR(hr); //Add null renderer NullRenderer nullRenderer = new NullRenderer(); hr = _graph.AddFilter((IBaseFilter)nullRenderer, "NullRenderer"); DsError.ThrowExceptionForHR(hr); IPin nullRendererPinIn = DsFindPin.ByDirection((IBaseFilter)nullRenderer, PinDirection.Input, 0); hr = _graph.Connect(sampleGrabberPinOut, nullRendererPinIn); DsError.ThrowExceptionForHR(hr); _audioEngine.Setup(this.GetSampleGrabberFormat(sampleGrabber)); } } }
public WaveFormatEx GetSampleGrabberFormat(ISampleGrabber sampleGrabber) { int hr; AMMediaType mediaInfo = new AMMediaType(); hr = sampleGrabber.GetConnectedMediaType(mediaInfo); DsError.ThrowExceptionForHR(hr); if ((mediaInfo.formatType != FormatType.WaveEx) || (mediaInfo.formatPtr == IntPtr.Zero)) { throw new NotSupportedException("Unknown Grabber Media Format"); } WaveFormatEx format = new WaveFormatEx(); format = (WaveFormatEx)Marshal.PtrToStructure(mediaInfo.formatPtr, typeof(WaveFormatEx)); Marshal.FreeCoTaskMem(mediaInfo.formatPtr); mediaInfo.formatPtr = IntPtr.Zero; return format; }
/// <summary> /// Reads the video stream information for the media file /// </summary> private void ReadVideoFormat(AMMediaType mediaType) { m_videoSubType = mediaType.subType; int hr = m_mediaDet.get_StreamLength(out m_videoStreamLength); DsError.ThrowExceptionForHR(hr); if(mediaType.formatType == FormatType.VideoInfo) /* Most common video major type */ { HasVideo = true; /* 'Cast' the unmanaged pointer to our managed struct so we can read the meta data */ var header = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader)); m_fourCC = ConvertFourCC(header.BmiHeader.Compression); m_videoBitsPerPixel = header.BmiHeader.BitCount; m_videoResolution = new Size(header.BmiHeader.Width, header.BmiHeader.Height); } else if (mediaType.formatType == FormatType.VideoInfo2) /* Usually for interlaced video */ { HasVideo = true; /* 'Cast' the unmanaged pointer to our managed struct so we can read the meta data */ var header = (VideoInfoHeader2)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader2)); m_fourCC = ConvertFourCC(header.BmiHeader.Compression); m_videoResolution = new Size(header.BmiHeader.Width, header.BmiHeader.Height); m_videoBitsPerPixel = header.BmiHeader.BitCount; /* TODO: Pull out VideoInfoHeader2 specifics */ } }
/// <summary> /// Reads the audio stream information from the media file /// </summary> private void ReadAudioFormat(AMMediaType mediaType) { m_audioSubType = mediaType.subType; int hr = m_mediaDet.get_StreamLength(out m_audioStreamLength); DsError.ThrowExceptionForHR(hr); if(mediaType.formatType == FormatType.WaveEx) { HasAudio = true; var waveFormatEx = (WaveFormatEx)Marshal.PtrToStructure(mediaType.formatPtr, typeof(WaveFormatEx)); m_audioChannels = waveFormatEx.nChannels; m_audioSamplesPerSecond = (waveFormatEx.nSamplesPerSec); m_audioBitsPerSample = waveFormatEx.wBitsPerSample; } }
private void LoadMedia() { /*Create the COM object and query the IMediaDet interface */ m_mediaDet = new MediaDet() as IMediaDet; if (m_mediaDet == null) throw new NullReferenceException("Could not create an instance of MediaDet COM"); int hr = m_mediaDet.put_Filename(m_filename); DsError.ThrowExceptionForHR(hr); /* We find out how many streams exist in the * media file. These can be audio, video, etc */ hr = m_mediaDet.get_OutputStreams(out m_streamCount); DsError.ThrowExceptionForHR(hr); /* Loop over each of the streams and extract info from them */ for(int i = 0; i < m_streamCount; i++) { /* Set the interface to look at a specific stream */ hr = m_mediaDet.put_CurrentStream(i); DsError.ThrowExceptionForHR(hr); Guid majorType; /* Get the major type of the media */ hr = m_mediaDet.get_StreamType(out majorType); DsError.ThrowExceptionForHR(hr); var mediaType = new AMMediaType(); /* Gets the AMMediaType so we can read some * metadata on the stream */ hr = m_mediaDet.get_StreamMediaType(mediaType); DsError.ThrowExceptionForHR(hr); if(majorType == MediaType.Video) { ReadVideoFormat(mediaType); } else if(majorType == MediaType.Audio) { ReadAudioFormat(mediaType); } /* We need to free this with the helper * because it has an unmanaged pointer * and we don't want any leaks */ DsUtils.FreeAMMediaType(mediaType); } }