// Set frame's size and rate for the specified stream configuration private void SetFrameSizeAndRate( IAMStreamConfig streamConfig, Size size, int frameRate ) { bool sizeSet = false; AMMediaType mediaType; // get current format streamConfig.GetFormat( out mediaType ); // change frame size if required if ( ( size.Width != 0 ) && ( size.Height != 0 ) ) { // iterate through device's capabilities to find mediaType for desired resolution int capabilitiesCount = 0, capabilitySize = 0; AMMediaType newMediaType = null; VideoStreamConfigCaps caps = new VideoStreamConfigCaps( ); streamConfig.GetNumberOfCapabilities( out capabilitiesCount, out capabilitySize ); for ( int i = 0; i < capabilitiesCount; i++ ) { if ( streamConfig.GetStreamCaps( i, out newMediaType, caps ) == 0 ) { if ( caps.InputSize == size ) { mediaType.Dispose( ); mediaType = newMediaType; sizeSet = true; break; } else { newMediaType.Dispose( ); } } } } VideoInfoHeader infoHeader = (VideoInfoHeader) Marshal.PtrToStructure( mediaType.FormatPtr, typeof( VideoInfoHeader ) ); // try changing size manually if failed finding mediaType before if ( ( size.Width != 0 ) && ( size.Height != 0 ) && ( !sizeSet ) ) { infoHeader.BmiHeader.Width = size.Width; infoHeader.BmiHeader.Height = size.Height; } // change frame rate if required if ( frameRate != 0 ) { infoHeader.AverageTimePerFrame = 10000000 / frameRate; } // copy the media structure back Marshal.StructureToPtr( infoHeader, mediaType.FormatPtr, false ); // set the new format streamConfig.SetFormat( mediaType ); mediaType.Dispose( ); }
// Retrieve capabilities of a video device internal VideoCapabilities( IAMStreamConfig videoStreamConfig, int index ) { AMMediaType mediaType = null; VideoStreamConfigCaps caps = new VideoStreamConfigCaps( ); try { // retrieve capabilities struct at the specified index int hr = videoStreamConfig.GetStreamCaps( index, out mediaType, caps ); if ( hr != 0 ) Marshal.ThrowExceptionForHR( hr ); if ( mediaType.FormatType == FormatType.VideoInfo ) { VideoInfoHeader videoInfo = (VideoInfoHeader) Marshal.PtrToStructure( mediaType.FormatPtr, typeof( VideoInfoHeader ) ); FrameSize = new Size( videoInfo.BmiHeader.Width, videoInfo.BmiHeader.Height ); BitCount = videoInfo.BmiHeader.BitCount; AverageFrameRate = (int) ( 10000000 / videoInfo.AverageTimePerFrame ); MaximumFrameRate = (int) ( 10000000 / caps.MinFrameInterval ); } else if ( mediaType.FormatType == FormatType.VideoInfo2 ) { VideoInfoHeader2 videoInfo = (VideoInfoHeader2) Marshal.PtrToStructure( mediaType.FormatPtr, typeof( VideoInfoHeader2 ) ); FrameSize = new Size( videoInfo.BmiHeader.Width, videoInfo.BmiHeader.Height ); BitCount = videoInfo.BmiHeader.BitCount; AverageFrameRate = (int) ( 10000000 / videoInfo.AverageTimePerFrame ); MaximumFrameRate = (int) ( 10000000 / caps.MinFrameInterval ); } else { throw new ApplicationException( "Unsupported format found." ); } // ignore 12 bpp formats for now, since it was noticed they cause issues on Windows 8 // TODO: proper fix needs to be done so ICaptureGraphBuilder2::RenderStream() does not fail // on such formats if ( BitCount <= 12 ) { throw new ApplicationException( "Unsupported format found." ); } } finally { if ( mediaType != null ) mediaType.Dispose( ); } }
// Set resolution for the specified stream configuration private void SetResolution( IAMStreamConfig streamConfig, VideoCapabilities resolution ) { if ( resolution == null ) { return; } // iterate through device's capabilities to find mediaType for desired resolution int capabilitiesCount = 0, capabilitySize = 0; AMMediaType newMediaType = null; VideoStreamConfigCaps caps = new VideoStreamConfigCaps( ); streamConfig.GetNumberOfCapabilities( out capabilitiesCount, out capabilitySize ); for ( int i = 0; i < capabilitiesCount; i++ ) { try { VideoCapabilities vc = new VideoCapabilities( streamConfig, i ); if ( resolution == vc ) { if ( streamConfig.GetStreamCaps( i, out newMediaType, caps ) == 0 ) { break; } } } catch { } } // set the new format if ( newMediaType != null ) { streamConfig.SetFormat( newMediaType ); newMediaType.Dispose( ); } }
// Retrieve capabilities of a video device internal VideoCapabilities( IAMStreamConfig videoStreamConfig, int index ) { AMMediaType mediaType = null; VideoStreamConfigCaps caps = new VideoStreamConfigCaps( ); try { // retrieve capabilities struct at the specified index int hr = videoStreamConfig.GetStreamCaps( index, out mediaType, caps ); if ( hr != 0 ) Marshal.ThrowExceptionForHR( hr ); // extract info FrameSize = caps.InputSize; MaxFrameRate = (int) ( 10000000 / caps.MinFrameInterval ); } finally { if ( mediaType != null ) mediaType.Dispose( ); } }