/// <summary> /// Checks if AMMediaType's frame size is appropriate for desired frame size. /// </summary> /// <param name="media_type">Media type to analyze.</param> /// <param name="RefFrameSize">Desired frame size. Can be null or have 0 for height or width if it's not important.</param> private static bool IsFrameSizeAppropiate ( AMMediaType media_type, FrameSize RefFrameSize ) { // if we were asked to choose frame size if (RefFrameSize == null) { return(true); } VideoInfoHeader videoInfoHeader = new VideoInfoHeader(); Marshal.PtrToStructure(media_type.formatPtr, videoInfoHeader); if (RefFrameSize.Width > 0 && videoInfoHeader.BmiHeader.Width != RefFrameSize.Width) { return(false); } if (RefFrameSize.Height > 0 && videoInfoHeader.BmiHeader.Height != RefFrameSize.Height) { return(false); } return(true); }
/// <summary> /// Initializes camera and connects it to HostingControl and Moniker. /// </summary> /// <param name="DisplayPanel">Control that is used for hosting camera's output.</param> /// <param name="Moniker">Moniker (device identification) of camera.</param> /// <seealso cref="DisplayPanel"/> /// <seealso cref="CameraMoniker"/> public Camera ( Control DisplayPanel, IMoniker Moniker, FrameSize FrameSize ) { if (DisplayPanel == null) { throw new ApplicationException("Display panel should be set."); } if (Moniker == null) { throw new ApplicationException("Camera's moniker should be set."); } if (FrameSize == null) { throw new ApplicationException("Frame size should be set."); } _DisplayPanel = DisplayPanel; _CameraMoniker = Moniker; _FrameSize = FrameSize; // Build and Run graph BuildGraph(); RunGraph(); return; }
/// <summary> /// Gets available supported frame sizes with 16 or 24 or 32 bits per color. /// </summary> /// <param name="captureFilter">Capture pin (PinCategory.Capture) for asking for frame sizes list.</param> private static FrameSize[] GetSupportedFrameSizes ( IPin pinOutput ) { List <FrameSize> FrameSizeList = new List <FrameSize>(); // Media type (shoudl be cleaned) AMMediaType media_type = null; //NOTE: pSCC is not used. All we need is media_type IntPtr pSCC = IntPtr.Zero; try { IAMStreamConfig VideoStreamConfig = (IAMStreamConfig)pinOutput; // We want the interface to expose all media types it supports and not only the last one set int hr = VideoStreamConfig.SetFormat(null); DsError.ThrowExceptionForHR(hr); hr = VideoStreamConfig.GetNumberOfCapabilities(out int piCount, out int piSize); DsError.ThrowExceptionForHR(hr); for (int Index = 0; Index < piCount; Index++) { pSCC = Marshal.AllocCoTaskMem(piSize); VideoStreamConfig.GetStreamCaps(Index, out media_type, pSCC); if (IsColorBitCountOK(GetBitCountForMediaType(media_type))) { FrameSize FrameSize = GetFrameSizeForMediaType(media_type); if (!FrameSizeList.Contains(FrameSize)) { FrameSizeList.Add(FrameSize); } } FreeSCCMemory(ref pSCC); FreeMediaType(ref media_type); } } catch { throw; } finally { // clean up FreeSCCMemory(ref pSCC); FreeMediaType(ref media_type); } // return array return(FrameSizeList.ToArray()); }
/// <summary> /// Analyze AMMediaType during enumeration and decide if it's good choice for us. /// </summary> /// <param name="media_type">Media type to analyze.</param> /// <param name="FrameSizeDesired">Desired frame size.</param> private static void AnalyzeMediaType(AMMediaType media_type, FrameSize FrameSizeDesired, out bool bit_count_ok, out bool sub_type_ok, out bool FrameSizeOK) { int bit_count = GetBitCountForMediaType(media_type); bit_count_ok = IsColorBitCountOK(bit_count); // We want (A)RGB32, RGB24 or RGB16 and YUY2. // These have priority // Change this if you're not agree. sub_type_ok = ( media_type.subType == MediaSubType.RGB32 || media_type.subType == MediaSubType.ARGB32 || media_type.subType == MediaSubType.RGB24 || media_type.subType == MediaSubType.RGB16_D3D_DX9_RT || media_type.subType == MediaSubType.RGB16_D3D_DX7_RT || media_type.subType == MediaSubType.YUY2); // flag to show if media_type's frame size is appropriate for us FrameSizeOK = IsFrameSizeAppropiate(media_type, FrameSizeDesired); return; }
/// <summary> /// Program initialization /// </summary> /// <param name="sender">Sender</param> /// <param name="e">Event arguments</param> private void OnLoad(object sender, EventArgs e) { // program title Text = "QRCodeVideoDecoder - " + QRDecoder.VersionNumber + " \u00a9 2013-2018 Uzi Granot. All rights reserved."; #if DEBUG // current directory string CurDir = Environment.CurrentDirectory; string WorkDir = CurDir.Replace("bin\\Debug", "Work"); if (WorkDir != CurDir && Directory.Exists(WorkDir)) { Environment.CurrentDirectory = WorkDir; } // open trace file QRCodeTrace.Open("QRCodeVideoDecoderTrace.txt"); QRCodeTrace.Write(Text); #endif // disable reset button ResetButton.Enabled = false; GoToUriButton.Enabled = false; // get an array of web camera devices DsDevice[] CameraDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); // make sure at least one is available if (CameraDevices == null || CameraDevices.Length == 0) { MessageBox.Show("No video cameras in this computer"); Close(); return; } // select the first camera DsDevice CameraDevice = CameraDevices[0]; // Device moniker IMoniker CameraMoniker = CameraDevice.Moniker; // get a list of frame sizes available FrameSize[] FrameSizes = Camera.GetFrameSizeList(CameraMoniker); // make sure there is at least one frame size if (FrameSizes == null || FrameSizes.Length == 0) { MessageBox.Show("No video cameras in this computer"); Close(); return; } // test if our frame size is available int Index; for (Index = 0; Index < FrameSizes.Length && (FrameSizes[Index].Width != FrameSize.Width || FrameSizes[Index].Height != FrameSize.Height); Index++) { ; } // select first frame size if (Index == FrameSizes.Length) { FrameSize = FrameSizes[0]; } // Set selected camera to camera control with default frame size // Create camera object VideoCamera = new Camera(PreviewPanel, CameraMoniker, FrameSize); // create QR code decoder Decoder = new QRDecoder(); // resize window OnResize(sender, e); // create timer QRCodeTimer = new Timer(); QRCodeTimer.Interval = 200; QRCodeTimer.Tick += QRCodeTimer_Tick; QRCodeTimer.Enabled = true; return; }
/// <summary> /// Sets parameters for source capture pin. /// </summary> /// <param name="pinSourceCapture">Pin of source capture.</param> /// <param name="FrameSize">frame size to set if possible.</param> private static void SetSourceParams(IPin pinSourceCapture, FrameSize FrameSize) { AMMediaType media_type_most_appropriate = null; AMMediaType media_type = null; //NOTE: pSCC is not used. All we need is media_type IntPtr pSCC = IntPtr.Zero; bool appropriate_media_type_found = false; try { // We want the interface to expose all media types it supports and not only the last one set IAMStreamConfig videoStreamConfig = pinSourceCapture as IAMStreamConfig; int hr = videoStreamConfig.SetFormat(null); DsError.ThrowExceptionForHR(hr); hr = videoStreamConfig.GetNumberOfCapabilities(out int piCount, out int piSize); DsError.ThrowExceptionForHR(hr); for (int i = 0; i < piCount; i++) { pSCC = Marshal.AllocCoTaskMem(piSize); videoStreamConfig.GetStreamCaps(i, out media_type, pSCC); FreeSCCMemory(ref pSCC); AnalyzeMediaType(media_type, FrameSize, out bool bit_count_ok, out bool sub_type_ok, out bool FrameSizeOK); if (bit_count_ok && FrameSizeOK) { if (sub_type_ok) { hr = videoStreamConfig.SetFormat(media_type); DsError.ThrowExceptionForHR(hr); appropriate_media_type_found = true; break; // stop search, we've found appropriate media type } else { // save as appropriate if no other found if (media_type_most_appropriate == null) { media_type_most_appropriate = media_type; media_type = null; // we don't want for free it, now it's media_type_most_appropriate's problem } } } FreeMediaType(ref media_type); } if (!appropriate_media_type_found) { // Found nothing exactly as we were asked if (media_type_most_appropriate != null) { // set appropriate RGB format with different frame size hr = videoStreamConfig.SetFormat(media_type_most_appropriate); DsError.ThrowExceptionForHR(hr); } else { // throw. We didn't find exactly what we were asked to throw new Exception("Camera doesn't support media type with requested frame size and bits per pixel."); } } } catch { throw; } finally { // clean up FreeMediaType(ref media_type); FreeMediaType(ref media_type_most_appropriate); FreeSCCMemory(ref pSCC); } return; }