// AForge Direct Show Library // AForge.NET framework // http://www.aforgenet.com/framework/ // // Copyright © AForge.NET, 2009-2013 // contacts@aforgenet.com // namespace AForge.Video.DirectShow { using System; using System.Collections.Generic; using System.Drawing; using System.Runtime.InteropServices; using AForge.Video; using AForge.Video.DirectShow.Internals; /// /// Capabilities of video device such as frame size and frame rate. /// public class VideoCapabilities { /// /// Frame size supported by video device. /// public readonly Size FrameSize; /// /// Frame rate supported by video device for corresponding frame size. /// /// /// This field is depricated - should not be used. /// Its value equals to . /// /// [Obsolete( "No longer supported. Use AverageFrameRate instead." )] public int FrameRate { get { return AverageFrameRate; } } /// /// Average frame rate of video device for corresponding frame size. /// public readonly int AverageFrameRate; /// /// Maximum frame rate of video device for corresponding frame size. /// public readonly int MaximumFrameRate; /// /// Number of bits per pixel provided by the camera. /// public readonly int BitCount; internal VideoCapabilities( ) { } // Retrieve capabilities of a video device static internal VideoCapabilities[] FromStreamConfig( IAMStreamConfig videoStreamConfig ) { if ( videoStreamConfig == null ) throw new ArgumentNullException( "videoStreamConfig" ); // ensure this device reports capabilities int count, size; int hr = videoStreamConfig.GetNumberOfCapabilities( out count, out size ); if ( hr != 0 ) Marshal.ThrowExceptionForHR( hr ); if ( count <= 0 ) throw new NotSupportedException( "This video device does not report capabilities." ); if ( size > Marshal.SizeOf( typeof( VideoStreamConfigCaps ) ) ) throw new NotSupportedException( "Unable to retrieve video device capabilities. This video device requires a larger VideoStreamConfigCaps structure." ); // group capabilities with similar parameters Dictionary videocapsList = new Dictionary( ); for ( int i = 0; i < count; i++ ) { try { VideoCapabilities vc = new VideoCapabilities( videoStreamConfig, i ); uint key = ( ( (uint) vc.FrameSize.Height ) << 32 ) | ( ( (uint) vc.FrameSize.Width ) << 16 ); if ( !videocapsList.ContainsKey( key ) ) { videocapsList.Add( key, vc ); } else { if ( vc.BitCount > videocapsList[key].BitCount ) { videocapsList[key] = vc; } } } catch { } } VideoCapabilities[] videocaps = new VideoCapabilities[videocapsList.Count]; videocapsList.Values.CopyTo( videocaps, 0 ); return videocaps; } // 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( ); } } /// /// Check if the video capability equals to the specified object. /// /// /// Object to compare with. /// /// Returns true if both are equal are equal or false otherwise. /// public override bool Equals( object obj ) { return Equals( obj as VideoCapabilities ); } /// /// Check if two video capabilities are equal. /// /// /// Second video capability to compare with. /// /// Returns true if both video capabilities are equal or false otherwise. /// public bool Equals( VideoCapabilities vc2 ) { if ( (object) vc2 == null ) { return false; } return ( ( FrameSize == vc2.FrameSize ) && ( BitCount == vc2.BitCount ) ); } /// /// Get hash code of the object. /// /// /// Returns hash code ot the object public override int GetHashCode( ) { return FrameSize.GetHashCode( ) ^ BitCount; } /// /// Equality operator. /// /// /// First object to check. /// Seconds object to check. /// /// Return true if both objects are equal or false otherwise. public static bool operator ==( VideoCapabilities a, VideoCapabilities b ) { // if both are null, or both are same instance, return true. if ( object.ReferenceEquals( a, b ) ) { return true; } // if one is null, but not both, return false. if ( ( (object) a == null ) || ( (object) b == null ) ) { return false; } return a.Equals( b ); } /// /// Inequality operator. /// /// /// First object to check. /// Seconds object to check. /// /// Return true if both objects are not equal or false otherwise. public static bool operator !=( VideoCapabilities a, VideoCapabilities b ) { return !( a == b ); } } }