Sample Code
Windows Driver Samples/ USBView sample application/ C++/ dispvid.c/
/*++ Copyright (c) 2002-2008 Microsoft Corporation Module Name: DISPVID.C Abstract: This source file contains routines which update the edit control to display information about USB Video descriptors. Environment: user mode Revision History: 11-22-2002 : created 03-28-2003 : major revisions from latest specs. 03-28-2008 : include USB Video Class 1.1 --*/ //***************************************************************************** // I N C L U D E S //***************************************************************************** #include "uvcview.h" #include "h264.h" //***************************************************************************** // G L O B A L S P R I V A T E T O T H I S F I L E //***************************************************************************** int StillMethod = 0; // // USB Device Class Definition for Video Devices 0.8b version // // 3.6.2.3 Camera Terminal Descriptor // STRINGLIST slCameraControl1 [] = { {1, "Scanning Mode", ""}, {2, "Auto-Exposure Mode", ""}, {4, "Auto-Exposure Priority", ""}, {8, "Exposure Time (Absolute)", ""}, {0x10, "Exposure Time (Relative)", ""}, {0x20, "Focus (Absolute)", ""}, {0x40, "Focus (Relative)", ""}, {0x80, "Iris (Absolute)", ""}, }; STRINGLIST slCameraControl2 [] = { {1, "Iris (Relative)", ""}, {2, "Zoom (Absolute)", ""}, {4, "Zoom (Relative)", ""}, {8, "PanTilt (Absolute)", ""}, {0x10, "PanTilt (Relative)", ""}, {0x20, "Roll (Absolute)", ""}, {0x40, "Roll (Relative)", ""}, {0x80, "Reserved", ""}, }; STRINGLIST slCameraControl3 [] = { {1, "Reserved", ""}, {2, "Focus, Auto", ""}, {4, "Privacy", ""}, {8, "Focus, Simple", ""}, {0x10, "Window", ""}, {0x20, "Region of Interest", ""}, {0x40, "Reserved", ""}, {0x80, "Reserved", ""}, }; // 3.6.2.5 Processing Unit Descriptor // STRINGLIST slProcessorControls1 [] = { {1, "Brightness", ""}, {2, "Contrast", ""}, {4, "Hue", ""}, {8, "Saturation", ""}, {0x10, "Sharpness", ""}, {0x20, "Gamma", ""}, {0x40, "White Balance Temperature", ""}, {0x80, "White Balance Component", ""}, }; STRINGLIST slProcessorControls2 [] = { {1, "Backlight Compensation", ""}, {2, "Gain", ""}, {4, "Power Line Frequency", ""}, {8, "Hue, Auto", ""}, {0x10, "White Balance Temperature, Auto", ""}, {0x20, "White Balance Component, Auto", ""}, {0x40, "Digital Multiplier", ""}, {0x80, "Digital Multiplier Limit", ""}, }; STRINGLIST slProcessorControls3 [] = { {1, "Analog Video Standard", ""}, {2, "Analog Video Lock Status", ""}, {4, "Contrast, Auto", ""}, {8, "Reserved", ""}, {0x10, "Reserved", ""}, {0x20, "Reserved", ""}, {0x40, "Reserved", ""}, {0x80, "Reserved", ""}, }; STRINGLIST slProcessorVideoStandards [] = { {1, "None", ""}, {2, "NTSC - 525/60", ""}, {4, "PAL - 625/50", ""}, {8, "SECAM - 625/50", ""}, {0x10, "NTSC - 625/50", ""}, {0x20, "PAL - 525/60", ""}, {0x40, "Reserved", ""}, {0x80, "Reserved", ""}, }; // 3.8.2.1 Input Header Descriptor // STRINGLIST slInputHeaderControls[]= { {1, "Key Frame Rate" , ""}, {2, "P Frame Rate" , ""}, {4, "Compression Quality" , ""}, {8, "Compression Window Size", ""}, {0x10, "Generate Key Frame" , ""}, {0x20, "Update Frame Segment" , ""}, {0x40, "Reserved" , ""}, {0x80, "Reserved" , ""}, }; STRINGLIST slOutputHeaderControls[]= { {1, "Key Frame Rate" , ""}, {2, "P Frame Rate" , ""}, {4, "Compression Quality" , ""}, {8, "Compression Window Size", ""}, {0x10, "Reserved" , ""}, {0x20, "Reserved" , ""}, {0x40, "Reserved" , ""}, {0x80, "Reserved" , ""}, }; STRINGLIST slMediaTransportControls[]= { {1, "Transport Control" , ""}, {2, "Absolute Track Number Control", ""}, {4, "Media Information" , ""}, {8, "Time Code Information" , ""}, {0x10, "Reserved" , ""}, {0x20, "Reserved" , ""}, {0x40, "Reserved" , ""}, {0x80, "Reserved" , ""}, }; STRINGLIST slMediaTransportModes1[]= { {1, "Play Forward", ""}, {2, "Pause", ""}, {4, "Rewind", ""}, {8, "Fast Forward", ""}, {0x10, "High Speed Rewind", ""}, {0x20, "Stop", ""}, {0x40, "Eject", ""}, {0x80, "Play Next Frame", ""}, }; STRINGLIST slMediaTransportModes2[]= { {1, "Play Slowest Forward", ""}, {2, "Play Slow Forward 4", ""}, {4, "Play Slow Forward 3", ""}, {8, "Play Slow Forward 2", ""}, {0x10, "Play Slow Forward 1", ""}, {0x20, "Play X1", ""}, {0x40, "Play Fast Forward 1", ""}, {0x80, "Play Fast Forward 2", ""}, }; STRINGLIST slMediaTransportModes3[]= { {1, "Play Fast Forward 3", ""}, {2, "Play Fast Forward 4", ""}, {4, "Play Fastest Forward", ""}, {8, "Play Previous Frame", ""}, {0x10, "Play Slowest Reverse", ""}, {0x20, "Play Slow Reverse 4", ""}, {0x40, "Play Slow Reverse 3", ""}, {0x80, "Play Slow Reverse 2", ""}, }; STRINGLIST slMediaTransportModes4[]= { {1, "Play Slow Reverse 1", ""}, {2, "Play X1 Reverse", ""}, {4, "Play Fast Reverse 1", ""}, {8, "Play Fast Reverse 2", ""}, {0x10, "Play Fast Reverse 3", ""}, {0x20, "Play Fast Reverse 4", ""}, {0x40, "Play Fastest Reverse", ""}, {0x80, "Record StateStart", ""}, }; STRINGLIST slMediaTransportModes5[]= { {1, "Record Pause", ""}, {2, "Reserved", ""}, {4, "Reserved", ""}, {8, "Reserved", ""}, {0x10, "Reserved", ""}, {0x20, "Reserved", ""}, {0x40, "Reserved", ""}, {0x80, "Reserved", ""}, }; STRINGLIST slInputTermTypes[]= { {0x0100, "TT_VENDOR_SPECIFIC", "I//O"}, {0x0101, "TT_STREAMING", "I//O"}, {0x0400, "EXTERNAL_VENDOR_SPECIFIC", "I//O"}, {0x0401, "COMPOSITE_CONNECTOR", "I//O"}, {0x0402, "SVIDEO_CONNECTOR", "I//O"}, {0x0403, "COMPONENT_CONNECTOR", "I//O"}, {0x0200, "ITT_VENDOR_SPECIFIC", "I"}, {0x0201, "ITT_CAMERA", "I"}, {0x0202, "ITT_MEDIA_TRANSPORT_INPUT", "I"}, }; STRINGLIST slOutputTermTypes[]= { {0x0100, "TT_VENDOR_SPECIFIC", "I//O"}, {0x0101, "TT_STREAMING", "I//O"}, {0x0400, "EXTERNAL_VENDOR_SPECIFIC", "I//O"}, {0x0401, "COMPOSITE_CONNECTOR", "I//O"}, {0x0402, "SVIDEO_CONNECTOR", "I//O"}, {0x0403, "COMPONENT_CONNECTOR", "I//O"}, {0x0300, "OTT_VENDOR_SPECIFIC", "O"}, {0x0301, "OTT_DISPLAY", "O"}, {0x0302, "OTT_MEDIA_TRANSPORT_OUTPUT", "O"}, }; //***************************************************************************** // L O C A L F U N C T I O N P R O T O T Y P E S //***************************************************************************** BOOL DisplayVCHeader ( PVIDEO_CONTROL_HEADER_UNIT VCInterfaceDesc ); BOOL DisplayVCInputTerminal ( PVIDEO_INPUT_TERMINAL VidITDesc, PSTRING_DESCRIPTOR_NODE StringDescs, DEVICE_POWER_STATE LatestDevicePowerState ); BOOL DisplayVCOutputTerminal ( PVIDEO_OUTPUT_TERMINAL VidOTDesc, PSTRING_DESCRIPTOR_NODE StringDescs, DEVICE_POWER_STATE LatestDevicePowerState ); BOOL DisplayVCCameraTerminal ( PVIDEO_CAMERA_TERMINAL CameraDesc ); BOOL DisplayVCMediaTransInputTerminal ( PVIDEO_INPUT_MTT VCMedTransInDesc ); BOOL DisplayVCMediaTransOutputTerminal ( PVIDEO_OUTPUT_MTT VCMedTransOutDesc ); BOOL DisplayVCSelectorUnit ( PVIDEO_SELECTOR_UNIT VidSelectorDesc, PSTRING_DESCRIPTOR_NODE StringDescs, DEVICE_POWER_STATE LatestDevicePowerState ); BOOL DisplayVCProcessingUnit ( PVIDEO_PROCESSING_UNIT VidProcessingDesc, PSTRING_DESCRIPTOR_NODE StringDescs, DEVICE_POWER_STATE LatestDevicePowerState ); BOOL DisplayVCExtensionUnit ( PVIDEO_EXTENSION_UNIT VidExtensionDesc, PSTRING_DESCRIPTOR_NODE StringDescs, DEVICE_POWER_STATE LatestDevicePowerState ); BOOL DisplayVidInHeader ( PVIDEO_STREAMING_INPUT_HEADER VidInHeaderDesc ); BOOL DisplayVidOutHeader ( PVIDEO_STREAMING_OUTPUT_HEADER VidOutHeaderDesc ); BOOL DisplayStillImageFrame ( PVIDEO_STILL_IMAGE_FRAME StillFrameDesc ); BOOL DisplayColorMatching ( PVIDEO_COLORFORMAT ColorMatchDesc ); BOOL DisplayUncompressedFormat ( PVIDEO_FORMAT_UNCOMPRESSED UnCompFormatDesc ); BOOL DisplayUncompressedFrameType ( PVIDEO_FRAME_UNCOMPRESSED UnCompFrameDesc ); BOOL DisplayUnComContinuousFrameType( PVIDEO_FRAME_UNCOMPRESSED UContinuousDesc ); BOOL DisplayUnComDiscreteFrameType( PVIDEO_FRAME_UNCOMPRESSED UDiscreteDesc ); BOOL DisplayMJPEGFormat ( PVIDEO_FORMAT_MJPEG MJPEGFormatDesc ); BOOL DisplayMJPEGFrameType ( PVIDEO_FRAME_MJPEG MJPEGFrameDesc ); BOOL DisplayMJPEGContinuousFrameType( PVIDEO_FRAME_MJPEG MContinuousDesc ); BOOL DisplayMJPEGDiscreteFrameType( PVIDEO_FRAME_MJPEG MDiscreteDesc ); BOOL DisplayMPEG1SSFormat ( PVIDEO_FORMAT_MPEG1SS MPEG1SSFormatDesc ); BOOL DisplayMPEG2PSFormat ( PVIDEO_FORMAT_MPEG2PS MPEG2PSFormatDesc ); BOOL DisplayMPEG2TSFormat ( PVIDEO_FORMAT_MPEG2TS MPEG2TSFormatDesc ); BOOL DisplayMPEG4SLFormat ( PVIDEO_FORMAT_MPEG4SL MPEG4SLFormatDesc ); BOOL DisplayDVFormat ( PVIDEO_FORMAT_DV DVFormatDesc ); BOOL DisplayVendorVidFormat ( PVIDEO_FORMAT_VENDOR VendorVidFormatDesc ); BOOL DisplayVendorVidFrameType ( PVIDEO_FRAME_VENDOR VendorVidFrameDesc ); BOOL DisplayVendorVidContinuousFrameType( PVIDEO_FRAME_VENDOR VContinuousDesc ); BOOL DisplayVendorVidDiscreteFrameType( PVIDEO_FRAME_VENDOR VDiscreteDesc ); BOOL DisplayFramePayloadFormat( PVIDEO_FORMAT_FRAME FramePayloadFormatDesc ); BOOL DisplayFramePayloadFrame( PVIDEO_FRAME_FRAME FramePayloadFrameDesc ); BOOL DisplayFramePayloadContinuousFrameType( PVIDEO_FRAME_FRAME FContinuousDesc ); BOOL DisplayFramePayloadDiscreteFrameType( PVIDEO_FRAME_FRAME FDiscreteDesc ); BOOL DisplayStreamPayload( PVIDEO_FORMAT_STREAM StreamPayloadDesc ); BOOL DisplayVSEndpoint ( PVIDEO_CS_INTERRUPT VidEndpointDesc ); VOID VDisplayBytes ( PUCHAR Data, USHORT Len ); PCHAR VidFormatGUIDCodeToName ( REFGUID VidFormatGUIDCode ); UINT GetVCInterfaceSize ( PVIDEO_CONTROL_HEADER_UNIT VCInterfaceDesc ); UINT CheckForColorMatchingDesc ( PVIDEO_SPECIFIC FormatDesc, UCHAR bNumFrameDescriptors, UCHAR bDescriptorSubtype ); UINT GetVSInterfaceSize ( PUSB_COMMON_DESCRIPTOR VidInHeaderDesc, USHORT wTotalLength ); BOOL ValidateTerminalID( UINT uTerminalID ); VOID VDisplayDescString ( UINT uControlSize, PUCHAR pControl , PSTRINGLIST pslControl ); //***************************************************************************** // L O C A L F U N C T I O N S //***************************************************************************** //***************************************************************************** // // DisplayVideoDescriptor() UPDATED // // VidCommonDesc - An Video Class Descriptor // // bInterfaceSubClass - The SubClass of the Interface containing the descriptor // //***************************************************************************** BOOL DisplayVideoDescriptor ( PVIDEO_SPECIFIC VidCommonDesc, UCHAR bInterfaceSubClass, PSTRING_DESCRIPTOR_NODE StringDescs, DEVICE_POWER_STATE LatestDevicePowerState ) { //@@DisplayVideoDescriptor -Class-Specific Video Descriptor switch (VidCommonDesc->bDescriptorType) { case CS_INTERFACE: //@@DisplayVideoDescriptor -Class-Specific Video Interface Descriptor switch (bInterfaceSubClass) { case VIDEO_SUBCLASS_CONTROL: //@@DisplayVideoDescriptor -Class-Specific Video Control Interface Descriptor switch (VidCommonDesc->bDescriptorSubtype) { case VC_HEADER: return DisplayVCHeader( (PVIDEO_CONTROL_HEADER_UNIT)VidCommonDesc); case INPUT_TERMINAL: return DisplayVCInputTerminal( (PVIDEO_INPUT_TERMINAL)VidCommonDesc, StringDescs, LatestDevicePowerState); case OUTPUT_TERMINAL: return DisplayVCOutputTerminal( (PVIDEO_OUTPUT_TERMINAL)VidCommonDesc, StringDescs, LatestDevicePowerState); case SELECTOR_UNIT: return DisplayVCSelectorUnit( (PVIDEO_SELECTOR_UNIT)VidCommonDesc, StringDescs, LatestDevicePowerState); case PROCESSING_UNIT: return DisplayVCProcessingUnit( (PVIDEO_PROCESSING_UNIT)VidCommonDesc, StringDescs, LatestDevicePowerState); case EXTENSION_UNIT: return DisplayVCExtensionUnit( (PVIDEO_EXTENSION_UNIT)VidCommonDesc, StringDescs, LatestDevicePowerState); #ifdef H264_SUPPORT case H264_ENCODING_UNIT: return DisplayVCH264EncodingUnit( (PVIDEO_ENCODING_UNIT)VidCommonDesc ); #endif #ifdef H264_SUPPORT case MAX_TYPE_UNIT+1: // for H.264, the bDescriptorSubtype = 7, which is equal to MAX_TYPE_UNIT // so now MAX_TYPE_UNIT needs to be set to 8 //(TODO: need to change nt\sdpublic\internal\drivers\inc\uvcdesc.h's define // of MAX_TYPE_UNIT from7 to 8, and ad the type for H.264 = 8) #else case MAX_TYPE_UNIT: #endif //@@TestCase B1.1 //@@CAUTION //@@Descriptor Field - bDescriptorSubtype //@@An undefined descriptor subtype has been defined AppendTextBuffer("*!*CAUTION: This is an undefined class specific "\ "Video Control bDescriptorSubtype\r\n"); break; default: //@@TestCase B1.2 //@@ERROR //@@Descriptor Field - bDescriptorSubtype //@@An unknown descriptor subtype has been defined AppendTextBuffer("*!*ERROR: unknown bDescriptorSubtype\r\n"); OOPS(); break; } break; case VIDEO_SUBCLASS_STREAMING: //@@DisplayVideoDescriptor -Class-Specific Video Streaming Interface Descriptor switch (VidCommonDesc->bDescriptorSubtype) { case VS_INPUT_HEADER: return DisplayVidInHeader( (PVIDEO_STREAMING_INPUT_HEADER)VidCommonDesc); case VS_OUTPUT_HEADER: return DisplayVidOutHeader( (PVIDEO_STREAMING_OUTPUT_HEADER)VidCommonDesc); case VS_STILL_IMAGE_FRAME: return DisplayStillImageFrame( (PVIDEO_STILL_IMAGE_FRAME)VidCommonDesc); case VS_FORMAT_UNCOMPRESSED: #ifdef H264_SUPPORT { BOOL retCode = DisplayUncompressedFormat( (PVIDEO_FORMAT_UNCOMPRESSED)VidCommonDesc ); g_expectedNumberOfUncompressedFrameFrameDescriptors += ((PVIDEO_FORMAT_UNCOMPRESSED)VidCommonDesc)->bNumFrameDescriptors; return retCode; } #else return DisplayUncompressedFormat( (PVIDEO_FORMAT_UNCOMPRESSED)VidCommonDesc); #endif case VS_FRAME_UNCOMPRESSED: #ifdef H264_SUPPORT { BOOL retCode = DisplayUncompressedFrameType( (PVIDEO_FRAME_UNCOMPRESSED)VidCommonDesc ); g_numberOfUncompressedFrameFrameDescriptors++; return retCode; } #else return DisplayUncompressedFrameType( (PVIDEO_FRAME_UNCOMPRESSED)VidCommonDesc); #endif #ifdef H264_SUPPORT case VS_FORMAT_H264: { BOOL retCode = DisplayVCH264Format( (PVIDEO_FORMAT_H264)VidCommonDesc ); g_expectedNumberOfH264FrameDescriptors += ((PVIDEO_FORMAT_H264)VidCommonDesc)->bNumFrameDescriptors; return retCode; } case VS_FRAME_H264: { BOOL retCode = DisplayVCH264FrameType( (PVIDEO_FRAME_H264)VidCommonDesc ); g_numberOfH264FrameDescriptors++; return retCode; } #endif case VS_FORMAT_MJPEG: #ifdef H264_SUPPORT // additional checks { BOOL retCode = DisplayMJPEGFormat( (PVIDEO_FORMAT_MJPEG)VidCommonDesc ); g_expectedNumberOfMJPEGFrameDescriptors += ((PVIDEO_FORMAT_MJPEG)VidCommonDesc)->bNumFrameDescriptors; return retCode; } #else return DisplayMJPEGFormat( (PVIDEO_FORMAT_MJPEG)VidCommonDesc); #endif case VS_FRAME_MJPEG: #ifdef H264_SUPPORT { BOOL retCode = DisplayMJPEGFrameType( (PVIDEO_FRAME_MJPEG)VidCommonDesc ); g_numberOfMJPEGFrameDescriptors++; return retCode; } #else return DisplayMJPEGFrameType( (PVIDEO_FRAME_MJPEG)VidCommonDesc); #endif case VS_FORMAT_MPEG1: { if (UVC10 == g_chUVCversion) { return DisplayMPEG1SSFormat( (PVIDEO_FORMAT_MPEG1SS)VidCommonDesc); } else // this format is obsoleted in UVC version >= 1.1 { AppendTextBuffer("*!*ERROR: obsoleted bDescriptorSubtype\r\n"); OOPS(); break; } } case VS_FORMAT_MPEG2PS: { if (UVC10 == g_chUVCversion) { return DisplayMPEG2PSFormat( (PVIDEO_FORMAT_MPEG2PS)VidCommonDesc); } else // this format is obsoleted in UVC version >= 1.1 { AppendTextBuffer("*!*ERROR: obsoleted bDescriptorSubtype\r\n"); OOPS(); break; } } case VS_FORMAT_MPEG2TS: return DisplayMPEG2TSFormat( (PVIDEO_FORMAT_MPEG2TS)VidCommonDesc); case VS_FORMAT_MPEG4SL: { if (UVC10 == g_chUVCversion) { return DisplayMPEG4SLFormat( (PVIDEO_FORMAT_MPEG4SL)VidCommonDesc); } else // this format is obsoleted in UVC version >= 1.1 { AppendTextBuffer("*!*ERROR: obsoleted bDescriptorSubtype\r\n"); OOPS(); break; } } case VS_FORMAT_DV: return DisplayDVFormat( (PVIDEO_FORMAT_DV)VidCommonDesc); case VS_COLORFORMAT: return DisplayColorMatching( (PVIDEO_COLORFORMAT)VidCommonDesc); case VS_FORMAT_VENDOR: { if (UVC10 == g_chUVCversion) { return DisplayVendorVidFormat( (PVIDEO_FORMAT_VENDOR)VidCommonDesc); } else // this format is obsoleted in UVC version >= 1.1 { AppendTextBuffer("*!*ERROR: obsoleted bDescriptorSubtype\r\n"); OOPS(); break; } } case VS_FRAME_VENDOR: { if (UVC10 == g_chUVCversion) { return DisplayVendorVidFrameType( (PVIDEO_FRAME_VENDOR)VidCommonDesc); } else // this format is obsoleted in UVC version >= 1.1 { AppendTextBuffer("*!*ERROR: obsoleted bDescriptorSubtype\r\n"); OOPS(); break; } } case VS_FORMAT_FRAME_BASED: { if (UVC10 != g_chUVCversion) { return DisplayFramePayloadFormat( (PVIDEO_FORMAT_FRAME)VidCommonDesc); } else // this format did not exist in UVC 1.0 { AppendTextBuffer("*!*ERROR: bDescriptorSubtype did not exist in UVC 1.0\r\n"); OOPS(); break; } } case VS_FRAME_FRAME_BASED: { if (UVC10 != g_chUVCversion) { return DisplayFramePayloadFrame( (PVIDEO_FRAME_FRAME)VidCommonDesc); } else // this format did not exist in UVC 1.0 { AppendTextBuffer("*!*ERROR: bDescriptorSubtype did not exist in UVC 1.0\r\n"); OOPS(); break; } } case VS_FORMAT_STREAM_BASED: { if (UVC10 != g_chUVCversion) { return DisplayStreamPayload( (PVIDEO_FORMAT_STREAM)VidCommonDesc); } else // this format did not exist in UVC 1.0 { AppendTextBuffer("*!*ERROR: bDescriptorSubtype did not exist in UVC 1.0\r\n"); OOPS(); break; } } case VS_DESCRIPTOR_UNDEFINED: //@@TestCase B1.3 //@@CAUTION //@@Descriptor Field - bDescriptorSubtype //@@An undefined descriptor subtype has been defined AppendTextBuffer("*!*CAUTION: This is an undefined class specific Video "\ "Streaming bDescriptorSubtype\r\n"); break; default: //@@TestCase B1.4 //@@ERROR //@@Descriptor Field - bDescriptorSubtype //@@An unknown descriptor subtype has been defined AppendTextBuffer("*!*ERROR: unknown bDescriptorSubtype\r\n"); OOPS(); break; } break; default: //@@TestCase B1.6 //@@ERROR //@@Descriptor Field - bInterfaceSubClass //@@An unknown interface sub-class has been defined AppendTextBuffer("*!*ERROR: unknown bInterfaceSubClass\r\n"); OOPS(); break; } break; case CS_ENDPOINT: //@@DisplayVideoDescriptor -Class-Specific Video Endpoint Descriptor switch (VidCommonDesc->bDescriptorSubtype) { //@@TestCase B1.7 //@@CAUTION //@@Descriptor Field - bInterfaceSubtype //@@An undefined descriptor subtype has been defined case EP_UNDEFINED: AppendTextBuffer("*!*CAUTION: This is an undefined bDescriptorSubtype\r\n"); break; //@@TestCase B1.8 //@@Not yet implemented - Priority 3 //@@Descriptor Field - bDescriptorSubtype //@@Question: How valid are VIDEO_EP_GENERAL and VIDEO_EP_ENDPOINT? Should we test? case EP_GENERAL: break; case EP_ENDPOINT: break; case EP_INTERRUPT: return DisplayVSEndpoint( (PVIDEO_CS_INTERRUPT)VidCommonDesc); break; default: //@@TestCase B1.9 //@@ERROR //@@Descriptor Field - bDescriptorSubtype //@@An unknown descriptor subtype has been defined AppendTextBuffer("*!*CAUTION: Unknown bDescriptorSubtype"); break; } break; //@@DisplayVideoDescriptor -Class-Specific Video Device Descriptor //@@DisplayVideoDescriptor -Class-Specific Video Configuration Descriptor //@@DisplayVideoDescriptor -Class-Specific Video String Descriptor //@@DisplayVideoDescriptor -Class-Specific Video Undefined Descriptor //@@TestCase B1.10 //@@Not yet implemented - Priority 3 //@@Descriptor -Class-Specific Device, Configuration, String, Undefined //@@Descriptor Field - bDescriptorType //@@Question: How valid are these Descriptor Types? Should we test? /* case USB_VIDEO_CS_DEVICE: AppendTextBuffer("USB_VIDEO_CS_DEVICE bDescriptorType\r\n"); break; case USB_VIDEO_CS_CONFIGURATION: AppendTextBuffer("USB_VIDEO_CS_CONFIGURATION bDescriptorType\r\n"); break; case USB_VIDEO_CS_STRING: AppendTextBuffer("USB_VIDEO_CS_STRING bDescriptorType\r\n"); break; case USB_VIDEO_CS_UNDEFINED: AppendTextBuffer("USB_VIDEO_CS_UNDEFINED bDescriptorType\r\n"); break; */ default: //@@TestCase B1.11 //@@ERROR //@@Descriptor Field - bDescriptorType //@@An unknown descriptor type has been defined AppendTextBuffer("*!*CAUTION: Unknown bDescriptorSubtype"); OOPS(); break; } return FALSE; } //***************************************************************************** // // DisplayVCHeader() // //***************************************************************************** BOOL DisplayVCHeader ( PVIDEO_CONTROL_HEADER_UNIT VCInterfaceDesc ) { //@@DisplayVCHeader -Video Control Interface Header UINT i = 0; UINT uSize = 0; PUCHAR pData = NULL; AppendTextBuffer("\r\n ===>Class-Specific Video Control Interface Header "\ "Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", VCInterfaceDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VCInterfaceDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VCInterfaceDesc->bDescriptorSubtype); if ( UVC10 == g_chUVCversion ) { AppendTextBuffer("bcdVDC: 0x%04X\r\n", VCInterfaceDesc->bcdVideoSpec); } else { AppendTextBuffer("bcdUVC: 0x%04X\r\n", VCInterfaceDesc->bcdVideoSpec); } AppendTextBuffer("wTotalLength: 0x%04X", VCInterfaceDesc->wTotalLength); // Verify the total interface size (size of this header and all descriptors // following until and not including the first endpoint) uSize = GetVCInterfaceSize(VCInterfaceDesc); if (uSize != VCInterfaceDesc->wTotalLength) { AppendTextBuffer("\r\n*!*ERROR: Invalid total interface size 0x%02X, should be 0x%02X\r\n", VCInterfaceDesc->wTotalLength, uSize); } else { AppendTextBuffer(" -> Validated\r\n"); } AppendTextBuffer("dwClockFreq: 0x%08X", VCInterfaceDesc->dwClockFreq); if (gDoAnnotation) { AppendTextBuffer(" = (%d) Hz", VCInterfaceDesc->dwClockFreq); } AppendTextBuffer("\r\nbInCollection: 0x%02X\r\n", VCInterfaceDesc->bInCollection); // baInterfaceNr is a variable length field // Size is in bInCollection for (i = 1, pData = (PUCHAR) &VCInterfaceDesc->bInCollection; i <= VCInterfaceDesc->bInCollection; i++, pData++) { AppendTextBuffer("baInterfaceNr[%d]: 0x%02X\r\n", i, *pData); } uSize = (sizeof(VIDEO_CONTROL_HEADER_UNIT) + VCInterfaceDesc->bInCollection); if (VCInterfaceDesc->bLength != uSize) { //@@TestCase B2.1 (also in Descript.c) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is less than required length in //@@ the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", VCInterfaceDesc->bLength, uSize); OOPS(); } //@@TestCase B2.2 (also in Descript.c) //@@WARNING //@@Descriptor Field - bcdVDC //@@The bcdVDC version of the device is not the same as the version of used by USBView if(VCInterfaceDesc->bcdVideoSpec < BCDVDC) { AppendTextBuffer("*!*WARNING: This device is set to the old USB Video "\ "Class spec version 0x%04X\r\n", VCInterfaceDesc->bcdVideoSpec); OOPS(); } if (VCInterfaceDesc->dwClockFreq < 1) { //@@TestCase B2.3 (Descript.c Line 70) //@@WARNING //@@dwClockFrequency should be greater than 0 //@@Question should we check that any non-zero value is accurate AppendTextBuffer("*!*ERROR: dwClockFreq must be non-zero\r\n"); OOPS(); } //@@TestCase B2.4 //@@Not yet implemented - Priority 1 //@@Descriptor Field - baInterfaceNr //@@We should test to verify each interface number is valid? // for (i=0; i<VCInterfaceDesc->bInCollection; i++) // {AppendTextBuffer("baInterfaceNr[%d]: 0x%02X\r\n", i+1, // VCInterfaceDesc->baInterfaceNr[i]);} if (gDoAnnotation) { switch(g_chUVCversion) { case UVC10: AppendTextBuffer("USB Video Class device: spec version 1.0\r\n"); break; case UVC11: AppendTextBuffer("USB Video Class device: spec version 1.1\r\n"); break; #ifdef H264_SUPPORT case UVC15: AppendTextBuffer("USB Video Class device: spec version 1.5\r\n"); break; #endif default: break; } } return TRUE; } //***************************************************************************** // // DisplayVCInputTerminal() // //***************************************************************************** BOOL DisplayVCInputTerminal ( PVIDEO_INPUT_TERMINAL VidITDesc, PSTRING_DESCRIPTOR_NODE StringDescs, DEVICE_POWER_STATE LatestDevicePowerState ) { //@@DisplayVCInputTerminal -Video Control Input Terminal PCHAR pStr = NULL; AppendTextBuffer("\r\n ===>Video Control Input Terminal Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", VidITDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidITDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidITDesc->bDescriptorSubtype); AppendTextBuffer("bTerminalID: 0x%02X\r\n", VidITDesc->bTerminalID); AppendTextBuffer("wTerminalType: 0x%04X", VidITDesc->wTerminalType); if(gDoAnnotation) { pStr = GetStringFromList(slInputTermTypes, sizeof(slInputTermTypes) / sizeof(STRINGLIST), VidITDesc->wTerminalType, "Invalid Input Terminal Type"); AppendTextBuffer(" = (%s)", pStr); } AppendTextBuffer("\r\n"); AppendTextBuffer("bAssocTerminal: 0x%02X\r\n", VidITDesc->bAssocTerminal); AppendTextBuffer("iTerminal: 0x%02X\r\n", VidITDesc->iTerminal); if (gDoAnnotation) { if (VidITDesc->iTerminal) { // if executing this code, the configuration descriptor has been // obtained. If a device is suspended, then its configuration // descriptor was not obtained and we do not want errors to be // displayed when string descriptors were not obtained. DisplayStringDescriptor(VidITDesc->iTerminal, StringDescs, LatestDevicePowerState); } } if (VidITDesc->bLength < sizeof(VIDEO_INPUT_TERMINAL)) { //@@TestCase B3.1 (also in Descript.c) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is less than required length in //@@ the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d is too small\r\n", VidITDesc->bLength); OOPS(); } if (VidITDesc->bTerminalID < 1) { //@@TestCase B3.2 (descript.c line 133) //@@ERROR //@@Descriptor Field - bTerminalID //@@bTerminalID should be greater than 0 //@@Question: Should test to verify terminal number is valid AppendTextBuffer("*!*ERROR: bTerminalID of %d is too small\r\n", VidITDesc->bTerminalID); OOPS(); } if (!(pStr)) { //@@TestCase B3.3 //@@CAUTION //@@Descriptor Field - wTerminalType //@@No valid Terminal Type was found AppendTextBuffer("*!*CAUTION: 0x%04X is an unknown wTerminalType for an Input "\ "Terminal\r\n", VidITDesc->wTerminalType); OOPS(); } //@@TestCase B3.4 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bAssocTerminal //@@Should test to verify terminal number is valid? // AppendTextBuffer("bAssocTerminal: 0x%02X\r\n", VidITDesc->bAssocTerminal); switch (VidITDesc->wTerminalType) { case 0x0100: // TT_VENDOR_SPECIFIC Terminal Type break; case 0x0101: // TT_STREAMING Terminal Type break; case 0x0200: // ITT_VENDOR_SPECIFIC Terminal Type break; case 0x0201: // ITT_CAMERA Terminal Type return DisplayVCCameraTerminal( (PVIDEO_CAMERA_TERMINAL)VidITDesc); case 0x0202: // ITT_MEDIA_TRANSPORT_INPUT Terminal Type return DisplayVCMediaTransInputTerminal( (PVIDEO_INPUT_MTT)VidITDesc); case 0x0400: // EXTERNAL_VENDOR_SPECIFIC Terminal Type break; case 0x0401: // COMPOSITE_CONNECTOR Terminal Type break; case 0x0402: // SVIDEO_CONNECTOR Terminal Type break; case 0x0403: // COMPONENT_CONNECTOR Terminal Type break; default: break; } return TRUE; } //***************************************************************************** // // DisplayVCOutputTerminal() // //***************************************************************************** BOOL DisplayVCOutputTerminal ( PVIDEO_OUTPUT_TERMINAL VidOTDesc, PSTRING_DESCRIPTOR_NODE StringDescs, DEVICE_POWER_STATE LatestDevicePowerState ) { //@@DisplayVCOutputTerminal -Video Control Output Terminal PCHAR pStr = NULL; AppendTextBuffer("\r\n ===>Video Control Output Terminal Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", VidOTDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidOTDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidOTDesc->bDescriptorSubtype); AppendTextBuffer("bTerminalID: 0x%02X\r\n", VidOTDesc->bTerminalID); AppendTextBuffer("wTerminalType: 0x%04X", VidOTDesc->wTerminalType); if(gDoAnnotation) { pStr = GetStringFromList(slOutputTermTypes, sizeof(slOutputTermTypes) / sizeof(STRINGLIST), VidOTDesc->wTerminalType, "Invalid Output Terminal Type"); AppendTextBuffer(" = (%s)", pStr); } AppendTextBuffer("\r\n"); AppendTextBuffer("bAssocTerminal: 0x%02X\r\n", VidOTDesc->bAssocTerminal); AppendTextBuffer("bSourceID: 0x%02X\r\n", VidOTDesc->bSourceID); AppendTextBuffer("iTerminal: 0x%02X\r\n", VidOTDesc->iTerminal); if (gDoAnnotation) { if (VidOTDesc->iTerminal) { // if executing this code, the configuration descriptor has been // obtained. If a device is suspended, then its configuration // descriptor was not obtained and we do not want errors to be // displayed when string descriptors were not obtained. DisplayStringDescriptor(VidOTDesc->iTerminal, StringDescs, LatestDevicePowerState); } } if (VidOTDesc->bLength < sizeof(PVIDEO_OUTPUT_TERMINAL)) { //@@TestCase B4.1 (also in Descript.c) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is less than required length in //@@ the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d is too small\r\n", VidOTDesc->bLength); OOPS(); } if (VidOTDesc->bTerminalID < 1) { //@@TestCase B4.2 (see Descript.c line 328) //@@ERROR //@@Descriptor Field - bTerminalID //@@bTerminalID should be greater than 0 //@@Question: Should test to verify terminal number is valid AppendTextBuffer("*!*ERROR: bTerminalID of %d is too small\r\n", VidOTDesc->bTerminalID); OOPS(); } if (!(pStr)) { //@@TestCase B4.3 //@@ERROR //@@Descriptor Field - wTerminalType //@@No valid Terminal Type was found AppendTextBuffer("*!*ERROR: 0x%04X is an invalid wTerminalType for an Output Terminal\r\n", VidOTDesc->wTerminalType); OOPS(); } //@@TestCase B4.4 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bAssocTerminal //@@We should test to verify terminal number is valid // AppendTextBuffer("bAssocTerminal: 0x%02X\r\n", VidOTDesc->bAssocTerminal); if (VidOTDesc->bSourceID < 1) { //@@TestCase B4.5 (see Descript.c line 333) //@@ERROR //@@Descriptor Field - bSourceID //@@bSourceID should be greater than 0 //@@Question: Should test to verify source number is valid AppendTextBuffer("*!*ERROR: bSourceID of %d is too small\r\n", VidOTDesc->bSourceID); OOPS(); } switch (VidOTDesc->wTerminalType) { case 0x0100: // TT_VENDOR_SPECIFIC Terminal Type break; case 0x0101: // TT_STREAMING Terminal Type break; case 0x0300: // OTT_VENDOR_SPECIFIC Terminal Type break; case 0x0301: // OTT_DISPLAY Terminal Type break; case 0x0302: // OTT_MEDIA_TRANSPORT_OUTPUT Terminal Type return DisplayVCMediaTransOutputTerminal( (PVIDEO_OUTPUT_MTT)VidOTDesc); case 0x0400: // EXTERNAL_VENDOR_SPECIFIC Terminal Type break; case 0x0401: // COMPOSITE_CONNECTOR Terminal Type break; case 0x0402: // SVIDEO_CONNECTOR Terminal Type break; case 0x0403: // COMPONENT_CONNECTOR Terminal Type break; default: break; } return TRUE; } //***************************************************************************** // // DisplayVCMediaTransInputTerminal() // //***************************************************************************** BOOL DisplayVCMediaTransInputTerminal( PVIDEO_INPUT_MTT MediaTransportInDesc ) { //@@DisplayVCMediaTransInputTerminal -Video Control Media Transport Input Terminal UCHAR p = 0; PUCHAR pData = NULL; size_t bLength = 0; bLength = SizeOfVideoInputMTT(MediaTransportInDesc); AppendTextBuffer("===>Additional Media Transport Input Terminal Data\r\n"); AppendTextBuffer("bControlSize: 0x%02X\r\n", MediaTransportInDesc->bControlSize); // point to bControlSize pData = & MediaTransportInDesc->bControlSize; // Are there any controls? if (0 < * pData) { UINT uBitIndex = 0; BYTE cCheckBit = 0; BYTE cMask = 1; AppendTextBuffer("bmControls : "); VDisplayBytes(pData + 1, *pData); // map the first control for ( ; uBitIndex < 8; uBitIndex++ ) { cCheckBit = cMask & *(pData + 1); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportControls, sizeof(slMediaTransportControls) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportCtrl bmControl value")); cMask = cMask << 1; } } // point to bTransportModeSize pData = pData + 2 ; // Are there any controls? if (0 < * pData) { UINT uBitIndex = 0; BYTE cCheckBit = 0; BYTE cMask = 1; AppendTextBuffer("bmControls : "); VDisplayBytes(pData + 1, *pData); // map the first control for ( ; uBitIndex < 8; uBitIndex++ ) { cCheckBit = cMask & *(pData + 1); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportModes1, sizeof(slMediaTransportModes1) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportMode value")); cMask = cMask << 1; } // Is there a second control? if (1 < * pData) { // map the second control for ( uBitIndex = 8, cMask = 1; uBitIndex < 16; uBitIndex++ ) { cCheckBit = cMask & *(pData + 2); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportModes2, sizeof(slMediaTransportModes2) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportMode value")); cMask = cMask << 1; } } // Is there a third control? if (2 < * pData) { // map the third control for ( uBitIndex = 16, cMask = 1; uBitIndex < 24; uBitIndex++ ) { cCheckBit = cMask & *(pData + 3); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportModes3, sizeof(slMediaTransportModes3) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportMode value")); cMask = cMask << 1; } } // Is there a fourth control? if (3 < * pData) { // map the fourth control for ( uBitIndex = 24, cMask = 1; uBitIndex < 32; uBitIndex++ ) { cCheckBit = cMask & *(pData + 4); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportModes4, sizeof(slMediaTransportModes4) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportMode value")); cMask = cMask << 1; } } // Is there a fifth control? if (4 < * pData) { // map the fifth control for ( uBitIndex = 32, cMask = 1; uBitIndex < 40; uBitIndex++ ) { cCheckBit = cMask & *(pData + 5); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportModes5, sizeof(slMediaTransportModes5) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportMode value")); cMask = cMask << 1; } } } // The size of a Media Transport Descriptor is // the size of the Descriptor plus // (bControlSize - 1) plus // IF bmControls & 1 THEN 1 (bTransportModeSize) plus // bTransportModeSize // // p = sizeof(VIDEO_INPUT_MTT) + // (MediaTransportInDesc->bControlSize - 1); // if (MediaTransportInDesc->bmControls[0] & 1) // p += 1 + (*pData); if (MediaTransportInDesc->bLength != bLength) { //@@TestCase B5.1 (also in Descript.c) //@@ERROR //@@Descriptor Field - bLength //@@Invalid Descriptor length AppendTextBuffer("*!*ERROR: Invalid descriptor bLength 0x%02X. "\ "Should be 0x%02X\r\n", MediaTransportInDesc->bLength, p); OOPS(); } return TRUE; } //***************************************************************************** // // DisplayVCMediaTransOutputTerminal() // //***************************************************************************** BOOL DisplayVCMediaTransOutputTerminal( PVIDEO_OUTPUT_MTT MediaTransportOutDesc ) { //@@DisplayVCMediaTransOutputTerminal -Video Control Media Transport Output Terminal UCHAR p = 0; PUCHAR pData = NULL; AppendTextBuffer("===>Additional Media Transport Output Terminal Data\r\n"); AppendTextBuffer("bControlSize: 0x%02X\r\n", MediaTransportOutDesc->bControlSize); // point to bControlSize pData = & MediaTransportOutDesc->bControlSize; // Are there any controls? if (0 < * pData) { UINT uBitIndex = 0; BYTE cCheckBit = 0; BYTE cMask = 1; AppendTextBuffer("bmControls : "); VDisplayBytes(pData + 1, *pData); // map the first control for ( ; uBitIndex < 8; uBitIndex++ ) { cCheckBit = cMask & *(pData + 1); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportControls, sizeof(slMediaTransportControls) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportCtrl bmControl value")); cMask = cMask << 1; } } // point to bTransportModeSize pData = pData + 2 ; // Are there any controls? if (0 < * pData) { UINT uBitIndex = 0; BYTE cCheckBit = 0; BYTE cMask = 1; AppendTextBuffer("bmControls : "); VDisplayBytes(pData + 1, *pData); // map the first control for ( ; uBitIndex < 8; uBitIndex++ ) { cCheckBit = cMask & *(pData + 1); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportModes1, sizeof(slMediaTransportModes1) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportMode value")); cMask = cMask << 1; } // Is there a second control? if (1 < * pData) { // map the second control for ( uBitIndex = 8, cMask = 1; uBitIndex < 16; uBitIndex++ ) { cCheckBit = cMask & *(pData + 2); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportModes2, sizeof(slMediaTransportModes2) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportMode value")); cMask = cMask << 1; } } // Is there a third control? if (2 < * pData) { // map the third control for ( uBitIndex = 16, cMask = 1; uBitIndex < 24; uBitIndex++ ) { cCheckBit = cMask & *(pData + 3); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportModes3, sizeof(slMediaTransportModes3) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportMode value")); cMask = cMask << 1; } } // Is there a fourth control? if (3 < * pData) { // map the fourth control for ( uBitIndex = 24, cMask = 1; uBitIndex < 32; uBitIndex++ ) { cCheckBit = cMask & *(pData + 4); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportModes4, sizeof(slMediaTransportModes4) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportMode value")); cMask = cMask << 1; } } // Is there a fifth control? if (4 < * pData) { // map the fourth control for ( uBitIndex = 32, cMask = 1; uBitIndex < 40; uBitIndex++ ) { cCheckBit = cMask & *(pData + 5); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slMediaTransportModes5, sizeof(slMediaTransportModes5) / sizeof(STRINGLIST), cMask, "Invalid MediaTransportMode value")); cMask = cMask << 1; } } } // The size of a Media Transport Descriptor is // the size of the Descriptor plus // (bControlSize - 1) plus // IF bmControls & 1 THEN 1 (bTransportModeSize) plus // bTransportModeSize // p = sizeof(VIDEO_OUTPUT_MTT) + (MediaTransportOutDesc->bControlSize - 1); if (MediaTransportOutDesc->bmControls[0] & 1) p += 1 + (*pData); if (MediaTransportOutDesc->bLength != p) { //@@TestCase B5.1 (also in Descript.c) //@@ERROR //@@Descriptor Field - bLength //@@Invalid Descriptor length AppendTextBuffer("*!*ERROR: Invalid descriptor bLength 0x%02X. "\ "Should be 0x%02X\r\n", MediaTransportOutDesc->bLength, p); OOPS(); } return TRUE; } //***************************************************************************** // // DisplayVCCameraTerminal() // //***************************************************************************** BOOL DisplayVCCameraTerminal( PVIDEO_CAMERA_TERMINAL CameraDesc ) { //@@DisplayVCCameraTerminal -Video Control Camera Terminal UCHAR p = 0; PUCHAR pData = NULL; AppendTextBuffer("===>Camera Input Terminal Data\r\n"); AppendTextBuffer("wObjectiveFocalLengthMin: 0x%04X\r\n", CameraDesc->wObjectiveFocalLengthMin); AppendTextBuffer("wObjectiveFocalLengthMax: 0x%04X\r\n", CameraDesc->wObjectiveFocalLengthMax); AppendTextBuffer("wOcularFocalLength: 0x%04X\r\n", CameraDesc->wOcularFocalLength); AppendTextBuffer("bControlSize: 0x%02X\r\n", CameraDesc->bControlSize); pData = &CameraDesc->bControlSize; // Are there any controls? if (0 < * pData) { UINT uBitIndex = 0; BYTE cCheckBit = 0; BYTE cMask = 1; AppendTextBuffer("bmControls : "); VDisplayBytes(pData + 1, *pData); // map the first control for ( ; uBitIndex < 8; uBitIndex++ ) { cCheckBit = cMask & *(pData + 1); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slCameraControl1, sizeof(slCameraControl1) / sizeof(STRINGLIST), cMask, "Invalid CamCtrl bmControl value")); cMask = cMask << 1; } // Is there a second control? if (1 < * pData) { // map the second control for ( uBitIndex = 8, cMask = 1; uBitIndex < 16; uBitIndex++ ) { cCheckBit = cMask & *(pData + 2); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slCameraControl2, sizeof(slCameraControl2) / sizeof(STRINGLIST), cMask, "Invalid CamCtrl bmControl value")); cMask = cMask << 1; } } // Is there a third control? if (2 < * pData) { // map the third control for ( uBitIndex = 16, cMask = 1; uBitIndex < 24; uBitIndex++ ) { cCheckBit = cMask & *(pData + 3); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slCameraControl3, sizeof(slCameraControl3) / sizeof(STRINGLIST), cMask, "Invalid CamCtrl bmControl value")); cMask = cMask << 1; } } } p = (sizeof(VIDEO_CAMERA_TERMINAL) + CameraDesc->bControlSize); if (CameraDesc->bLength != p) { //@@TestCase B7.1 (also in Descript.c) //@@ERROR //@@Descriptor Field - bLength //@@The descriptor should be the size of the descriptor structure //@@ plus the number of controls AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", CameraDesc->bLength, p); OOPS(); } //@@TestCase B7.2 //@@Not yet implemented - Priority 3 //@@Descriptor Field - wObjectiveFocalLengthMin //@@Question - Should we do any checking here? What are the acceptable boundaries? //@@Question - Is zero an acceptable value? // AppendTextBuffer("wObjectiveFocalLengthMin: 0x%04X\r\n", CameraDesc->wObjectiveFocalLengthMin); //@@TestCase B7.3 //@@Not yet implemented - Priority 3 //@@Descriptor Field - wObjectiveFocalLengthMax //@@Question - Should we do any checking here? What are the acceptable boundaries //@@Question - Is zero an acceptable value? // AppendTextBuffer("wObjectiveFocalLengthMax: 0x%04X\r\n", CameraDesc->wObjectiveFocalLengthMax); //@@TestCase B7.4 //@@Not yet implemented - Priority 3 //@@Descriptor Field - wOcularFocalLength //@@Question - Should we do any checking here? What are the acceptable boundaries //@@Question - Is zero an acceptable value? // AppendTextBuffer("wOcularFocalLength: 0x%04X\r\n", CameraDesc->wOcularFocalLength); //@@TestCase B7.5 //@@ERROR //@@Descriptor Field - wObjectiveFocalLengthMin and wObjectiveFocalLengthMax //@@Verify that wObjectiveFocalLengthMax is greater than wObjectiveFocalLengthMin if(CameraDesc->wObjectiveFocalLengthMin > CameraDesc->wObjectiveFocalLengthMax) { AppendTextBuffer("*!*ERROR: wObjectiveFocalLengthMin is larger than wObjectiveFocalLengthMax\r\n"); OOPS(); } //@@TestCase B7.6 //@@ERROR //@@Descriptor Field - bControlSize //@@Verify that wObjectiveFocalLengthMax is 3 or less if(CameraDesc->bControlSize > 3) { AppendTextBuffer("*!*ERROR: bControlSize must be 3 or less\r\n"); OOPS(); } return TRUE; } //***************************************************************************** // // DisplayVCSelectorUnit() // //***************************************************************************** BOOL DisplayVCSelectorUnit ( PVIDEO_SELECTOR_UNIT VidSelectorDesc, PSTRING_DESCRIPTOR_NODE StringDescs, DEVICE_POWER_STATE LatestDevicePowerState ) { //@@DisplayVCSelectorUnit -Video Control Selector Unit UCHAR i = 0; UCHAR p = 0; PUCHAR pData = NULL; AppendTextBuffer("\r\n ===>Video Control Selector Unit Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", VidSelectorDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidSelectorDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidSelectorDesc->bDescriptorSubtype); AppendTextBuffer("bUnitID: 0x%02X\r\n", VidSelectorDesc->bUnitID); AppendTextBuffer("bNrInPins: 0x%02X\r\n", VidSelectorDesc->bNrInPins); if (gDoAnnotation) { AppendTextBuffer("===>List of Connected Unit and Terminal ID's\r\n"); } // baSourceID is a variable length field // Size is in bNrInPins, must be at least 1 (so index starts at 1) for (i = 1, pData = (PUCHAR) &VidSelectorDesc->baSourceID; i <= VidSelectorDesc->bNrInPins; i++, pData++) { AppendTextBuffer("baSourceID[%d]: 0x%02X\r\n", i, *pData); } // get address of iSelector, the last field in this descriptor pData = (PUCHAR) VidSelectorDesc + (VidSelectorDesc->bLength - 1); AppendTextBuffer("iSelector: 0x%02X\r\n", *pData); if (gDoAnnotation) { if (*pData) { // if executing this code, the configuration descriptor has been // obtained. If a device is suspended, then its configuration // descriptor was not obtained and we do not want errors to be // displayed when string descriptors were not obtained. DisplayStringDescriptor(*pData, StringDescs, LatestDevicePowerState); } } p = (sizeof(VIDEO_SELECTOR_UNIT) + VidSelectorDesc->bNrInPins + 1); if (VidSelectorDesc->bLength != p) { //@@TestCase B8.1 (also in Descript.c) //@@ERROR //@@Descriptor Field - bLength //@@The descriptor should be the size of the descriptor structure plus the number of pins AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", VidSelectorDesc->bLength, p); OOPS(); } if (VidSelectorDesc->bUnitID < 1) { //@@TestCase B8.2 (Descript.c Line 396) //@@ERROR //@@Descriptor Field - bUnitID //@@bUnitID must be greater than 0 //@@Question: Should we test to verify unit number is unique? AppendTextBuffer("*!*ERROR: bUnitID must be non-zero\r\n"); OOPS(); } if (VidSelectorDesc->bNrInPins < 1) { //@@TestCase B8.3 //@@ERROR //@@Descriptor Field - bNrInPins //@@bNrInPins should be greater than 0 //@@Question: Should test to verify total in pins is valid AppendTextBuffer("*!*ERROR: bNrInPins must be non-zero\r\n"); OOPS(); } // baSourceID is a variable length field // Size is in bNrInPins, must be at least 1 (so index starts at 1) for (i = 1, pData = (PUCHAR) &VidSelectorDesc->baSourceID; i <= VidSelectorDesc->bNrInPins; i++, pData++) { if (*pData < 1) { //@@TestCase B8.4 //@@ERROR //@@Descriptor Field - baSourceID[] //@@baSourceID should be greater than 0 AppendTextBuffer("*!*ERROR: baSourceID[%d] must be non-zero\r\n", i); OOPS(); } else { if (! ValidateTerminalID(*pData)) { //@@TestCase B8.5 //@@ERROR //@@Descriptor Field - baSourceID[] //@@baSourceID should be a valid terminal ID AppendTextBuffer("*!*ERROR: baSourceID[%d] must be non-zero\r\n", i); OOPS(); } } } return TRUE; } //***************************************************************************** // // DisplayVCProcessingUnit() // //***************************************************************************** BOOL DisplayVCProcessingUnit ( PVIDEO_PROCESSING_UNIT VidProcessingDesc, PSTRING_DESCRIPTOR_NODE StringDescs, DEVICE_POWER_STATE LatestDevicePowerState ) { //@@DisplayVCProcessingUnit -Video Control Processor Unit PUCHAR pData = NULL; UCHAR bLength = 0; AppendTextBuffer("\r\n ===>Video Control Processing Unit Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", VidProcessingDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidProcessingDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidProcessingDesc->bDescriptorSubtype); AppendTextBuffer("bUnitID: 0x%02X\r\n", VidProcessingDesc->bUnitID); AppendTextBuffer("bSourceID: 0x%02X\r\n", VidProcessingDesc->bSourceID); AppendTextBuffer("wMaxMultiplier: 0x%04X\r\n", VidProcessingDesc->wMaxMultiplier); AppendTextBuffer("bControlSize: 0x%02X\r\n", VidProcessingDesc->bControlSize); pData = &VidProcessingDesc->bControlSize; // Are there any controls? if (0 < * pData) { UINT uBitIndex = 0; BYTE cCheckBit = 0; BYTE cMask = 1; AppendTextBuffer("bmControls : "); VDisplayBytes(pData + 1, *pData); // map the first control for ( ; uBitIndex < 8; uBitIndex++ ) { cCheckBit = cMask & *(pData + 1); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slProcessorControls1, sizeof(slProcessorControls1) / sizeof(STRINGLIST), cMask, "Invalid PU bmControl value")); cMask = cMask << 1; } // Is there a second control? if (1 < * pData) { // map the second control for ( uBitIndex = 8, cMask = 1; uBitIndex < 16; uBitIndex++ ) { cCheckBit = cMask & *(pData + 2); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slProcessorControls2, sizeof(slProcessorControls2) / sizeof(STRINGLIST), cMask, "Invalid PU bmControl value")); cMask = cMask << 1; } } // Is there a third control? if (2 < * pData) { // map the third control for ( uBitIndex = 16, cMask = 1; uBitIndex < 24; uBitIndex++ ) { cCheckBit = cMask & *(pData + 3); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slProcessorControls3, sizeof(slProcessorControls3) / sizeof(STRINGLIST), cMask, "Invalid PU bmControl value")); cMask = cMask << 1; } } } // get address of iProcessing if (UVC10 != g_chUVCversion) { // size of descriptor is struct size plus control size plus 2 if UVC11 bLength = sizeof(VIDEO_PROCESSING_UNIT) + 2 + VidProcessingDesc->bControlSize; pData = (PUCHAR) VidProcessingDesc + (VidProcessingDesc->bLength - 2); } else // UVC 1.0 { // size of descriptor is struct size plus control size plus 1 if UVC10 bLength = sizeof(VIDEO_PROCESSING_UNIT) + 1 + VidProcessingDesc->bControlSize; pData = (PUCHAR) VidProcessingDesc + (VidProcessingDesc->bLength - 1); } AppendTextBuffer("iProcessing : 0x%02X\r\n", *pData); if (gDoAnnotation) { if (*pData) { // if executing this code, the configuration descriptor has been // obtained. If a device is suspended, then its configuration // descriptor was not obtained and we do not want errors to be // displayed when string descriptors were not obtained. DisplayStringDescriptor(*pData, StringDescs, LatestDevicePowerState); } } // check for new UVC 1.1 bmVideoStandards fields if (UVC10 != g_chUVCversion) { UINT uBitIndex = 0; BYTE cCheckBit = 0; BYTE cMask = 1; pData = (PUCHAR) VidProcessingDesc + (VidProcessingDesc->bLength - 1); AppendTextBuffer("bmVideoStandards : "); VDisplayBytes(pData, 1); // map the first control for ( ; uBitIndex < 8; uBitIndex++ ) { cCheckBit = cMask & *(pData); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slProcessorVideoStandards, sizeof(slProcessorVideoStandards) / sizeof(STRINGLIST), cMask, "Invalid PU bmVideoStandards value")); cMask = cMask << 1; } } if (VidProcessingDesc->bLength != bLength) { //@@TestCase B9.1 (also in Descript.c) //@@ERROR //@@Descriptor Field - bLength AppendTextBuffer("*!*ERROR: bLength of 0x%02X incorrect, should be 0x%02X\r\n", VidProcessingDesc->bLength, bLength); OOPS(); } if (VidProcessingDesc->bUnitID < 1) { //@@TestCase B9.2 (Descript.c Line 466) //@@ERROR //@@Descriptor Field - bUnitID //@@bUnitID must be greater than 0 //@@Question: Should we test to verify unit number is unique? AppendTextBuffer("*!*ERROR: bUnitID must be non-zero\r\n"); OOPS(); } if (VidProcessingDesc->bSourceID < 1) { //@@TestCase B9.3 (Descript.c Line 471) //@@ERROR //@@Descriptor Field - bSourceID //@@bSourceID must be non-zero //@@Question: Should we test to verify the bSourceID is valid? AppendTextBuffer("*!*ERROR: bSourceID must be non-zero\r\n"); OOPS(); } //@@TestCase B9.4 //@@Not yet implemented - Priority 1 //@@Descriptor Field - wMaxMultiplier //@@We should test to verify multiplier is valid // AppendTextBuffer("wMaxMultiplier: 0x%04X\r\n", VidProcessingDesc->wMaxMultiplier); return TRUE; } //***************************************************************************** // // DisplayVCExtensionUnit() // //***************************************************************************** BOOL DisplayVCExtensionUnit ( PVIDEO_EXTENSION_UNIT VidExtensionDesc, PSTRING_DESCRIPTOR_NODE StringDescs, DEVICE_POWER_STATE LatestDevicePowerState ) { //@@DisplayVCExtensionUnit -Video Control Extension Unit int i = 0; UCHAR p = 0; UCHAR bControlSize = 0; PUCHAR pData = NULL; OLECHAR szGUID[256]; size_t bLength = 0; bLength = SizeOfVideoExtensionUnit(VidExtensionDesc); memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); i = StringFromGUID2((REFGUID) &VidExtensionDesc->guidExtensionCode, (LPOLESTR) szGUID, 255); i++; AppendTextBuffer("\r\n ===>Video Control Extension Unit Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", VidExtensionDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidExtensionDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidExtensionDesc->bDescriptorSubtype); AppendTextBuffer("bUnitID: 0x%02X\r\n", VidExtensionDesc->bUnitID); AppendTextBuffer("guidExtensionCode: %S\r\n", szGUID); AppendTextBuffer("bNumControls: 0x%02X\r\n", VidExtensionDesc->bNumControls); AppendTextBuffer("bNrInPins: 0x%02X\r\n", VidExtensionDesc->bNrInPins); if (gDoAnnotation) { AppendTextBuffer("===>List of Connected Units and Terminal ID's\r\n"); } // baSourceID is a variable length field // Size is in bNrInPins, must be at least 1 (so index starts at 1) for (i = 1, pData = (PUCHAR) &VidExtensionDesc->baSourceID; i <= VidExtensionDesc->bNrInPins; i++, pData++) { AppendTextBuffer("baSourceID[%d]: 0x%02X\r\n", i, *pData); } // point to bControlSize (address of bNrInPins plus number of fields in bNrInPins // plus 1 for next field) pData = &VidExtensionDesc->bNrInPins + VidExtensionDesc->bNrInPins +1; bControlSize = *pData; AppendTextBuffer("bControlSize: 0x%02X\r\n", bControlSize); // Are there any controls? if ( bControlSize > 0) { AppendTextBuffer("bmControls : "); VDisplayBytes(pData + 1, *pData); // Map one byte at a time of the bmControls field in the Video Control Extension Unit Descriptor for (i = 1; i <= bControlSize; i++) { UINT uBitIndex = 0; BYTE cCheckBit = 0; BYTE cMask = 1; // map byte for ( ; uBitIndex < 8; uBitIndex++ ) { cCheckBit = cMask & *(pData + i); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex + 8 * (i-1), cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", "Vendor-Specific (Optional)"); cMask = cMask << 1; } } } // get address of iExtension pData = &VidExtensionDesc->bNrInPins + VidExtensionDesc->bNrInPins + bControlSize + 2; // pData = (PUCHAR) VidExtensionDesc + (VidExtensionDesc->bLength - 1); AppendTextBuffer("iExtension: 0x%02X\r\n", *pData); if (gDoAnnotation) { if (*pData) { DisplayStringDescriptor(*pData,StringDescs, LatestDevicePowerState); } } // size of descriptor struct size (23) + bNrInPins + bControlSize + iExtension size // // p = (sizeof(VIDEO_EXTENSION_UNIT) // + VidExtensionDesc->bNrInPins + bControlSize + 1); if (VidExtensionDesc->bLength != bLength) { //@@TestCase B10.1 (also in Descript.c) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the //@@ required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of 0x%02X incorrect, should be 0x%02X\r\n", VidExtensionDesc->bLength, p); OOPS(); } if (VidExtensionDesc->bUnitID < 1) { //@@TestCase B10.2 (Descript.c Line 517) //@@ERROR //@@Descriptor Field - bUnitID //@@bUnitID must be non-zero //@@Question: Should we test to verify bUnitID is valid AppendTextBuffer("*!*ERROR: bUnitID must be non-zero\r\n"); OOPS(); } //bugbug do we need two if (VidExtensionDesc->bNrInPins < 1) { //@@TestCase B10.3 (Descript.c Line 522) //@@ERROR //@@Descriptor Field - bNrInPins //@@bNrInPins must be non-zero //@@Question: Should we test to verify bNrInPins is valid AppendTextBuffer("*!*ERROR: bNrInPins must be non-zero\r\n"); OOPS(); } for (i = 1, pData = (PUCHAR) &VidExtensionDesc->baSourceID; i <= VidExtensionDesc->bNrInPins; i++, pData++) { if (*pData == 0) { //@@TestCase B10.4 (Descript.c Line 527) //@@ERROR //@@Descriptor Field - baSourceID[] //@@baSourceID[] must be non-zero //@@Question: Should we test to verify baSourceID is valid AppendTextBuffer("*!*ERROR: baSourceID[%d] must be non-zero\r\n", *pData); OOPS(); } } return TRUE; } //***************************************************************************** // // DisplayVidInHeaderl() // //***************************************************************************** BOOL DisplayVidInHeader ( PVIDEO_STREAMING_INPUT_HEADER VidInHeaderDesc ) { //@@DisplayVidInHeader -Video Streaming Video Input Header UINT p = 0; UINT uCount = 0; PUCHAR pData = NULL; AppendTextBuffer("\r\n ===>Video Class-Specific VS Video Input Header Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", VidInHeaderDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidInHeaderDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidInHeaderDesc->bDescriptorSubtype); AppendTextBuffer("bNumFormats: 0x%02X\r\n", VidInHeaderDesc->bNumFormats); AppendTextBuffer("wTotalLength: 0x%04X", VidInHeaderDesc->wTotalLength); uCount = GetVSInterfaceSize((PUSB_COMMON_DESCRIPTOR) VidInHeaderDesc, VidInHeaderDesc->wTotalLength); if (uCount != VidInHeaderDesc->wTotalLength) { AppendTextBuffer("\r\n*!*ERROR: invalid interface size 0x%02X, should be 0x%02X\r\n", VidInHeaderDesc->wTotalLength, uCount); } else { AppendTextBuffer(" -> Validated\r\n"); } AppendTextBuffer("bEndpointAddress: 0x%02X", VidInHeaderDesc->bEndpointAddress); if (USB_ENDPOINT_DIRECTION_IN(VidInHeaderDesc->bEndpointAddress)) { if (gDoAnnotation) { AppendTextBuffer(" -> Direction: IN - EndpointID: %d", (VidInHeaderDesc->bEndpointAddress & 0x0F)); } AppendTextBuffer("\r\n"); } AppendTextBuffer("bmInfo: 0x%02X", VidInHeaderDesc->bmInfo); if (gDoAnnotation) { AppendTextBuffer(" -> Dynamic Format Change %sSupported", ! (VidInHeaderDesc->bmInfo & 0x01) ? "not " : " "); } AppendTextBuffer("\r\nbTerminalLink: 0x%02X\r\n", VidInHeaderDesc->bTerminalLink); AppendTextBuffer("bStillCaptureMethod: 0x%02X", VidInHeaderDesc->bStillCaptureMethod); // globally save the StillMethod, then verify value StillMethod = VidInHeaderDesc->bStillCaptureMethod; if (StillMethod > 3) { //@@TestCase B11.1 (Descript.c Line 798) //@@ERROR //@@Descriptor Field - bStillCaptureMethod //@@bStillCaptureMethod is greater than 3 AppendTextBuffer("*!*ERROR: invalid bStillCaptureMethod 0x%02X\r\n", VidInHeaderDesc->bStillCaptureMethod); if (gDoAnnotation) { AppendTextBuffer(" -> Invalid Still Capture Method"); } } else { if (0 == StillMethod) { AppendTextBuffer(" -> No Still Capture"); } else { AppendTextBuffer(" -> Still Capture Method %d", VidInHeaderDesc->bStillCaptureMethod); } } AppendTextBuffer("\r\nbTriggerSupport: 0x%02X", VidInHeaderDesc->bTriggerSupport); if(gDoAnnotation) { AppendTextBuffer(" -> "); if (! VidInHeaderDesc->bTriggerSupport) AppendTextBuffer("No "); AppendTextBuffer("Hardware Triggering Support"); } AppendTextBuffer("\r\n"); AppendTextBuffer("bTriggerUsage: 0x%02X", VidInHeaderDesc->bTriggerUsage); if (gDoAnnotation) { if (VidInHeaderDesc->bTriggerSupport != 0) { if (VidInHeaderDesc->bTriggerUsage == 0) AppendTextBuffer(" -> Host will initiate still image capture"); if (VidInHeaderDesc->bTriggerUsage == 1) AppendTextBuffer(" -> Host will notify client application of button event"); } } AppendTextBuffer("\r\nbControlSize: 0x%02X\r\n", VidInHeaderDesc->bControlSize); // are there formats to display? if (VidInHeaderDesc->bNumFormats) { UINT uFormatIndex = 1; UINT uBitIndex = 0; BYTE cCheckBit = 0; BYTE cMask = 1; // There are (bNumFormats) bmaControls fields, each with size (bControlSize) pData = (PUCHAR) &(VidInHeaderDesc->bControlSize); // VidInHeaderDesc->bNumFormats -> number of formats // VidInHeaderDesc->bControlSize -> size of EACH format control // ((PUCHAR) &VidInHeaderDesc->bControlSize) + 1 -> address of first format control for ( pData++ ; uFormatIndex <= VidInHeaderDesc->bNumFormats; uFormatIndex++ ) { AppendTextBuffer("Video Payload Format %d ", uFormatIndex); // Handle case of 0 control size if (! VidInHeaderDesc->bControlSize) { AppendTextBuffer("0x00\r\n"); } else { VDisplayBytes(pData, VidInHeaderDesc->bControlSize); // map the first control for (uBitIndex = 0, cMask = 1; uBitIndex < 8; uBitIndex++ ) { cCheckBit = cMask & *(pData); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slInputHeaderControls, sizeof(slInputHeaderControls) / sizeof(STRINGLIST), cMask, "Invalid Control value")); cMask = cMask << 1; } } pData += VidInHeaderDesc->bControlSize; } } p = (sizeof(VIDEO_STREAMING_INPUT_HEADER) + (VidInHeaderDesc->bNumFormats * VidInHeaderDesc->bControlSize)); if (VidInHeaderDesc->bLength != p) { //@@TestCase B11.2 (also in Descript.c) //@@ERROR //@@Descriptor Field - bLength //@@The descriptor should be the size of the descriptor structure //@@ plus the number of formats times the size of each format AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", VidInHeaderDesc->bLength, p); OOPS(); } if (VidInHeaderDesc->bNumFormats < 1) { //@@TestCase B11.3 (Descript.c Line778) //@@ERROR //@@Descriptor Field - bNumFormats //@@bNumFormats must be non-zero //@@Question: Should we test to verify the non-zero value for bNumFormats is valid AppendTextBuffer("*!*ERROR: bNumFormats must be non-zero\r\n", VidInHeaderDesc->bNumFormats); OOPS(); } if (VidInHeaderDesc->bEndpointAddress < 1) { //@@TestCase B11.4 (Descript.c Line788) //@@ERROR //@@Descriptor Field - bEndpointAddress //@@bEndpointAddress should be greater than 0 //@@Question: Should we test to verify the non-zero value for bEndpointAddress is valid AppendTextBuffer("*!*ERROR: bEndpointAddress of %d is too small\r\n", VidInHeaderDesc->bEndpointAddress); OOPS(); } //@@TestCase B11.5 //@@ERROR //@@Descriptor Field - bEndPointAddress //@@The bEndPointAddress is set incorrectly according to the USB Video Device Specification if (!USB_ENDPOINT_DIRECTION_IN(VidInHeaderDesc->bEndpointAddress)){ AppendTextBuffer("\r\n*!*ERROR: bEndPointAddress needs to have the Direction IN for this header\r\n"); OOPS();} //@@TestCase B11.6 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bmInfo //@@We should validate that reserved bits are set to zero. // AppendTextBuffer("bmInfo: 0x%02X", VidInHeaderDesc->bmInfo); if (VidInHeaderDesc->bTerminalLink < 1) { //@@TestCase B11.7 (Descript.c Line 793) //@@ERROR //@@Descriptor Field - bTerminalLink //@@bTerminalLink should be greater than 0 //@@Question: Should we test to verify the non-zero value for bTerminalLink is valid AppendTextBuffer("*!*ERROR: bTerminalLink of %d is too small\r\n", VidInHeaderDesc->bTerminalLink); OOPS(); } //@@TestCase B11.8 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bTriggerSupport //@@We should validate that reserved bits are set to zero. // AppendTextBuffer("bTriggerSupport: 0x%02X", VidInHeaderDesc->bTriggerSupport); //@@TestCase B11.9 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bTriggerUsage //@@We should validate that reserved bits are set to zero. // AppendTextBuffer("bTriggerUsage: 0x%02X", VidInHeaderDesc->bTriggerUsage); return TRUE; } //***************************************************************************** // // DisplayVidOutHeader() // //***************************************************************************** BOOL DisplayVidOutHeader ( PVIDEO_STREAMING_OUTPUT_HEADER VidOutHeaderDesc ) { //@@DisplayVidOutHeader -Video Streaming Video Output Header UINT uCount = 0; UCHAR bLength = sizeof(VIDEO_STREAMING_OUTPUT_HEADER); AppendTextBuffer("\r\n ===>Video Class-Specific VS Video Output Header Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", VidOutHeaderDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidOutHeaderDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidOutHeaderDesc->bDescriptorSubtype); AppendTextBuffer("bNumFormats: 0x%02X\r\n", VidOutHeaderDesc->bNumFormats); AppendTextBuffer("wTotalLength: 0x%04X", VidOutHeaderDesc->wTotalLength); uCount = GetVSInterfaceSize((PUSB_COMMON_DESCRIPTOR) VidOutHeaderDesc, VidOutHeaderDesc->wTotalLength); if (uCount != VidOutHeaderDesc->wTotalLength) { AppendTextBuffer("\r\n*!*ERROR: invalid interface size 0x%02X, should be 0x%02X\r\n", VidOutHeaderDesc->wTotalLength, uCount); } else { AppendTextBuffer(" -> Validated\r\n"); } AppendTextBuffer("bEndpointAddress: 0x%02X", VidOutHeaderDesc->bEndpointAddress); if(USB_ENDPOINT_DIRECTION_OUT(VidOutHeaderDesc->bEndpointAddress)) { if (gDoAnnotation) { AppendTextBuffer(" -> Direction: OUT - EndpointID: %d", (VidOutHeaderDesc->bEndpointAddress & 0x0F)); } AppendTextBuffer("\r\n"); } AppendTextBuffer("bTerminalLink: 0x%02X\r\n", VidOutHeaderDesc->bTerminalLink); // UVC11 Video Output Header has additional fields, larger size #ifdef H264_SUPPORT if (UVC10 != g_chUVCversion) #else if (UVC11 == g_chUVCversion) #endif { UCHAR bControlSize = 0; PUCHAR pControls = NULL; // bControlSize field is next after bTerminalLink pControls = &(VidOutHeaderDesc->bTerminalLink)+1; bControlSize = *(pControls); // point to first bmaControls pControls++; // Size of UVC 1.1 Video Output Header is 1.0 size // plus 1 (bControlSize field) plus (number of formats * bControlSize) bLength += 1 + (VidOutHeaderDesc->bNumFormats * bControlSize); // Need new uvcdesc.h to handle new fields AppendTextBuffer("bControlSize: 0x%02X\r\n", bControlSize); // are there formats to display? if (VidOutHeaderDesc->bNumFormats) { UINT uFormatIndex = 1; UINT uBitIndex = 0; BYTE cCheckBit = 0; BYTE cMask = 1; // There are (bNumFormats) bmaControls fields, each with size (bControlSize) for ( ; uFormatIndex <= VidOutHeaderDesc->bNumFormats; uFormatIndex++, pControls ++) { AppendTextBuffer("Video Payload Format %d ", uFormatIndex); // Handle case of 0 control size if (0 == bControlSize) { AppendTextBuffer("0x00\r\n"); } else { VDisplayBytes(pControls, bControlSize); // map the first control for (uBitIndex = 0, cMask = 1; uBitIndex < 8; uBitIndex++ ) { cCheckBit = cMask & *(pControls); AppendTextBuffer(" D%02d = %d %s %s\r\n", uBitIndex, cCheckBit ? 1 : 0, cCheckBit ? "yes - " : " no - ", GetStringFromList(slOutputHeaderControls, sizeof(slOutputHeaderControls) / sizeof(STRINGLIST), cMask, "Invalid control value")); cMask = cMask << 1; } } } // for ( pData++ ; uFormatIndex <= VidOutHeaderDesc->bNumFormats; uFormatIndex++ ) } // if (VidOutHeaderDesc->bNumFormats) } // if (UVC11 == g_chUVCversion) if (VidOutHeaderDesc->bLength != bLength) { //@@TestCase B12.1 (also in Descript.c) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the //@@ required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", VidOutHeaderDesc->bLength, sizeof(VIDEO_STREAMING_OUTPUT_HEADER)); OOPS(); } if (VidOutHeaderDesc->bNumFormats < 1) { //@@TestCase B12.2 (Descript.c Line 827) //@@ERROR //@@Descriptor Field - bNumFormats //@@bNumFormats should be greater than 0 //@@Question: Should we test to verify the non-zero value for bNumFormats is valid AppendTextBuffer("*!*ERROR: bNumFormats of %d is too small\r\n", VidOutHeaderDesc->bNumFormats); OOPS(); } if (VidOutHeaderDesc->wTotalLength < VidOutHeaderDesc->bLength) { //@@TestCase B12.3 (Descript.c Line 832) //@@ERROR //@@Descriptor Field - wTotalLength //@@wTotalLength should be greater than bLength //@@Question: Should we calculate wTotalLength to verify the value is valid AppendTextBuffer("*!*ERROR: wTotalLength of %d is small than the bLength of %d\r\n", VidOutHeaderDesc->wTotalLength, VidOutHeaderDesc->bLength); OOPS(); } if (VidOutHeaderDesc->bEndpointAddress < 1) { //@@TestCase B12.4 (Descript.c Line 837) //@@ERROR //@@Descriptor Field - bEndpointAddress //@@bEndpointAddress should be greater than 0 //@@Question: Should we test to verify the non-zero value for bEndpointAddress is valid AppendTextBuffer("*!*ERROR: bEndpointAddress of %d is too small\r\n", VidOutHeaderDesc->bEndpointAddress); OOPS(); } if(!(USB_ENDPOINT_DIRECTION_OUT(VidOutHeaderDesc->bEndpointAddress))) { //@@TestCase B12.5 //@@ERROR //@@Descriptor Field - bEndPointAddress //@@The bEndPointAddress is set for the wrong direction AppendTextBuffer("\r\n*!*ERROR: bEndPointAddress needs to have the Direction OUT for this header\r\n"); OOPS();} if (VidOutHeaderDesc->bTerminalLink < 1) { //@@TestCase B12.6 (Descript.c Line 842) //@@ERROR //@@Descriptor Field - bTerminalLink //@@bTerminalLink should be greater than 0 //@@Question: Should we test to verify the non-zero value for bTerminalLink is valid AppendTextBuffer("*!*ERROR: bTerminalLink of %d is too small\r\n", VidOutHeaderDesc->bTerminalLink); OOPS(); } return TRUE; } //***************************************************************************** // // DisplayStillImageFrame() // //***************************************************************************** BOOL DisplayStillImageFrame ( PVIDEO_STILL_IMAGE_FRAME StillFrameDesc ) { //@@DisplayStillImageFrame -Still Image Frame VIDEO_STILL_IMAGE_RECT * pXY; PUCHAR pbCurr = NULL; UINT i = 0; UINT uNumComp = 0; UINT uSize = 0; size_t bLength = 0; bLength = SizeOfVideoStillImageFrame(StillFrameDesc); AppendTextBuffer("\r\n ===>Still Image Frame Type Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", StillFrameDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", StillFrameDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", StillFrameDesc->bDescriptorSubtype); AppendTextBuffer("bEndpointAddress: 0x%02X\r\n", StillFrameDesc->bEndpointAddress); AppendTextBuffer("bNumImageSizePatterns: 0x%02X\r\n", StillFrameDesc->bNumImageSizePatterns); if (StillFrameDesc->bNumImageSizePatterns < 1) { //@@TestCase B13.1 (also Descript.c Line 886) //@@Not yet implemented - Priority 1 //@@Descriptor Field - bNumImageSizePatterns //@@The bNumImageSizePatterns should be greater than 0 //@@Question: Should we test to verify the non-zero value for bNumImageSizePatterns is valid AppendTextBuffer("*!*ERROR: bNumImageSizePatterns must be non-zero\r\n"); OOPS(); } // point to first StillFrameDesc->dwStillImage structure pXY = (VIDEO_STILL_IMAGE_RECT *) &StillFrameDesc->aStillRect[0]; for (i = 1; i <= StillFrameDesc->bNumImageSizePatterns; i++, pXY++) { AppendTextBuffer("wWidth[%d]: 0x%04X\r\n", i, pXY->wWidth); AppendTextBuffer("wHeight[%d]: 0x%04X\r\n", i, pXY->wHeight); } // point to bNumCompressionPattern field (after variable count field dwStillImage) pbCurr = (PUCHAR) pXY; // get number of compression patterns uNumComp = *pbCurr; AppendTextBuffer("bNumCompressionPattern: 0x%02X\r\n", *pbCurr++); for (i = 1; i <= uNumComp; i++) { AppendTextBuffer("bCompression[%d]: 0x%02X\r\n", i, *pbCurr++); } switch(StillMethod) { case 0: //@@TestCase B13.2 //@@ERROR //@@Descriptor Field - Still Image Frame Type Descriptor //@@An still method type has been defined that shouldn't use a Still Image Frame AppendTextBuffer("*!*ERROR: VS Video Input Header set to "\ "No Still Method support\r\n"); OOPS(); case 1: //@@TestCase B13.3 //@@ERROR //@@Descriptor Field - Still Image Frame Type Descriptor //@@An still method type has been defined that shouldn't use a Still Image Frame AppendTextBuffer("*!*ERROR: VS Video Input Header set to "\ "Still Method One support with a Still Image Frame descriptor\r\n"); OOPS(); default: break;} if (StillFrameDesc->bLength != bLength) { //@@TestCase B13.4 (Also in descript.c) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is incorrect AppendTextBuffer("*!*ERROR: bLength 0x%02X incorrect, should be 0x%02X\r\n", StillFrameDesc->bLength, uSize); OOPS(); } //@@TestCase B13.5 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bEndpointAddress //@@Should test to verify endpoint validity // AppendTextBuffer("bEndpointAddress: 0x%02X", StillFrameDesc->bEndpointAddress); if(USB_ENDPOINT_DIRECTION_IN(StillFrameDesc->bEndpointAddress) && StillMethod==3){ if((StillFrameDesc->bEndpointAddress) == 0){ //@@TestCase B13.6 //@@ERROR //@@Descriptor Field - bEndPointAddress //@@bEndPointAddress should be non-zero for 0 when using StillMethod 3 AppendTextBuffer("\r\n*!*ERROR: bEndpointAddress is reported as %d. "\ "This should be non-zero when using StillMethod 3.\r\n", (StillFrameDesc->bEndpointAddress)); OOPS(); } if (gDoAnnotation) { AppendTextBuffer(" -> Direction: IN - EndpointID: %d", (StillFrameDesc->bEndpointAddress & 0x0F)); } AppendTextBuffer("\r\n"); } else if(USB_ENDPOINT_DIRECTION_OUT(StillFrameDesc->bEndpointAddress) && StillMethod==2) { if((StillFrameDesc->bEndpointAddress & 0x0F) != 0) { //@@TestCase B13.7 //@@ERROR //@@Descriptor Field - bEndPointAddress //@@The EndpointID of bEndPointAddress should be set for 0 when using StillMethod 2 AppendTextBuffer("\r\n*!*ERROR: The EndpointID of the "\ "bEndpointAddress is reported as %d. This should be 0.\r\n", (StillFrameDesc->bEndpointAddress & 0x0F)); OOPS(); } else {AppendTextBuffer("\r\n");}} else if (StillFrameDesc->bEndpointAddress != 0) { //@@TestCase B13.8 //@@ERROR //@@Descriptor Field - bEndPointAddress //@@The bEndPointAddress should be set for 0 when not using StillMethod 2 or 3 AppendTextBuffer("\r\n*!*ERROR: bEndPointAddress should be 0.\r\n"); OOPS(); } else {AppendTextBuffer("\r\n");} return TRUE; } //***************************************************************************** // // DisplayColorMatching() // //***************************************************************************** BOOL DisplayColorMatching ( PVIDEO_COLORFORMAT ColorMatchDesc ) { //@@DisplayColorMatching -Color Matching AppendTextBuffer("\r\n ===>Color Matching Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", ColorMatchDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", ColorMatchDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", ColorMatchDesc->bDescriptorSubtype); AppendTextBuffer("bColorPrimaries: 0x%02X\r\n", ColorMatchDesc->bColorPrimaries); AppendTextBuffer("bTransferCharacteristics: 0x%02X\r\n", ColorMatchDesc->bTransferCharacteristics); AppendTextBuffer("bMatrixCoefficients: 0x%02X\r\n", ColorMatchDesc->bMatrixCoefficients); if (ColorMatchDesc->bLength != sizeof(VIDEO_COLORFORMAT)) { //@@TestCase B14.1 (Descript.c Line 1596) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", ColorMatchDesc->bLength, sizeof(VIDEO_COLORFORMAT)); OOPS(); } //@@TestCase B14.2 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bColorPrimaries //@@Question - Should we test to verify bColorPrimaries // AppendTextBuffer("bColorPrimaries: 0x%02X\r\n", ColorMatchDesc->bColorPrimaries); //@@TestCase B14.3 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bTransferCharacteristics //@@Question - Should we test to verify bTransferCharacteristics // AppendTextBuffer("bTransferCharacteristics: 0x%02X\r\n", ColorMatchDesc->bTransferCharacteristics); //@@TestCase B14.4 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bMatrixCoefficients //@@Question - Should we test to verify bMatrixCoefficients // AppendTextBuffer("bMatrixCoefficients: 0x%02X\r\n", ColorMatchDesc->bMatrixCoefficients); return TRUE; } //***************************************************************************** // // DisplayUncompressedFormat() // //***************************************************************************** BOOL DisplayUncompressedFormat ( PVIDEO_FORMAT_UNCOMPRESSED UnCompFormatDesc ) { //@@DisplayUncompressedFormat - Uncompressed Format int i = 0; PCHAR pStr = NULL; OLECHAR szGUID[256]; // Initialize the default Frame g_chUNCFrameDefault = UnCompFormatDesc->bDefaultFrameIndex; memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); i = StringFromGUID2((REFGUID) &UnCompFormatDesc->guidFormat, (LPOLESTR) szGUID, 255); i++; AppendTextBuffer("\r\n ===>Video Streaming Uncompressed Format Type Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", UnCompFormatDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", UnCompFormatDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", UnCompFormatDesc->bDescriptorSubtype); AppendTextBuffer("bFormatIndex: 0x%02X\r\n", UnCompFormatDesc->bFormatIndex); AppendTextBuffer("bNumFrameDescriptors: 0x%02X\r\n", UnCompFormatDesc->bNumFrameDescriptors); AppendTextBuffer("guidFormat: %S", szGUID); pStr = VidFormatGUIDCodeToName((REFGUID) &UnCompFormatDesc->guidFormat); if ( pStr ) { if ( gDoAnnotation ) { AppendTextBuffer(" = %s Format", pStr); } } AppendTextBuffer("\r\n"); AppendTextBuffer("bBitsPerPixel: 0x%02X\r\n", UnCompFormatDesc->bBitsPerPixel); AppendTextBuffer("bDefaultFrameIndex: 0x%02X\r\n", UnCompFormatDesc->bDefaultFrameIndex); if (UnCompFormatDesc->bLength != sizeof(VIDEO_FORMAT_UNCOMPRESSED)) { //@@TestCase B15.1 (descript.c line 925) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required //@@length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", UnCompFormatDesc->bLength, sizeof(VIDEO_FORMAT_UNCOMPRESSED)); OOPS(); } if (UnCompFormatDesc->bFormatIndex == 0 ) { //@@TestCase B15.2 (descript.c line 930) //@@ERROR //@@Descriptor Field - bFormatIndex //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: bFormatIndex = 0, this is a 1 based index\r\n"); OOPS(); } if (UnCompFormatDesc->bNumFrameDescriptors == 0 ) { //@@TestCase B15.3 (descript.c line 930) //@@ERROR //@@Descriptor Field - bNumFrameDescriptors //@@bNumFrameDescriptors is set to zero which is not in accordance with the //@@USB Video Device Specification AppendTextBuffer("*!*ERROR: bNumFrameDescriptors = 0, must have at least 1 Frame descriptor\r\n"); OOPS(); } if(!(pStr)) { //@@TestCase B15.4 //@@WARNING //@@Descriptor Field - guidFormat //@@guidFormat is set to unknown or undefined format AppendTextBuffer("\r\n*!*WARNING: guidFormat is an unknown format\r\n"); OOPS(); } if (UnCompFormatDesc->bBitsPerPixel == 0 ) { //@@TestCase B15.5 (descript.c line 940) //@@ERROR //@@Descriptor Field - bBitsPerPixel //@@bBitsPerPixel is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: bBitsPerPixel = 0, this invalidates the descriptor\r\n"); OOPS(); } if (UnCompFormatDesc->bDefaultFrameIndex == 0 || UnCompFormatDesc->bDefaultFrameIndex > UnCompFormatDesc->bNumFrameDescriptors) { //@@TestCase B15.6 (desctipt.c line 945) //@@ERROR //@@Descriptor Field - bDefaultFrameIndex //@@The value for bDefaultFrameIndex is not greater than 0 or less than or equal to bNumFrameDescriptors AppendTextBuffer("*!*ERROR: The value %d for the bDefaultFrameIndex is out of range, this invalidates the descriptor\r\n*!*The proper range is 1 to %d)", UnCompFormatDesc->bDefaultFrameIndex, UnCompFormatDesc->bNumFrameDescriptors); OOPS(); } AppendTextBuffer("bAspectRatioX: 0x%02X\r\n", UnCompFormatDesc->bAspectRatioX); AppendTextBuffer("bAspectRatioY: 0x%02X", UnCompFormatDesc->bAspectRatioY); if (((UnCompFormatDesc->bmInterlaceFlags & 0x01) && (UnCompFormatDesc->bAspectRatioY != 0 && UnCompFormatDesc->bAspectRatioX != 0))) { if(gDoAnnotation) { AppendTextBuffer(" -> Aspect Ratio is set for a %d:%d display", (UnCompFormatDesc->bAspectRatioX),(UnCompFormatDesc->bAspectRatioY)); } else { if (UnCompFormatDesc->bAspectRatioY != 0 || UnCompFormatDesc->bAspectRatioX != 0) { //@@TestCase B15.7 //@@ERROR //@@Descriptor Field - bAspectRatioX, bAspectRatioY //@@Verify that that bAspectRatioX and bAspectRatioY are set to zero //@@ if stream is non-interlaced AppendTextBuffer("\r\n*!*ERROR: Both bAspectRatioX and bAspectRatioY "\ "must equal 0 if stream is non-interlaced"); OOPS(); } } } AppendTextBuffer("\r\nbmInterlaceFlags: 0x%02X\r\n", UnCompFormatDesc->bmInterlaceFlags); if (gDoAnnotation) { AppendTextBuffer(" D0 = 0x%02X Interlaced stream or variable: %s\r\n", (UnCompFormatDesc->bmInterlaceFlags & 1), (UnCompFormatDesc->bmInterlaceFlags & 1) ? "Yes" : "No"); AppendTextBuffer(" D1 = 0x%02X Fields per frame: %s\r\n", ((UnCompFormatDesc->bmInterlaceFlags >> 1) & 1), ((UnCompFormatDesc->bmInterlaceFlags >> 1) & 1) ? "1 field" : "2 fields"); AppendTextBuffer(" D2 = 0x%02X Field 1 first: %s\r\n", ((UnCompFormatDesc->bmInterlaceFlags >> 2) & 1), ((UnCompFormatDesc->bmInterlaceFlags >> 2) & 1) ? "Yes" : "No"); //@@TestCase B15.9 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bmInterlaceFlags //@@Validate that reserved bits (D3) are set to zero. AppendTextBuffer(" D3 = 0x%02X Reserved%s\r\n", ((UnCompFormatDesc->bmInterlaceFlags >> 3) & 1), ((UnCompFormatDesc->bmInterlaceFlags >> 3) & 1) ? "\r\n*!*ERROR: Reserved to 0" : "" ); AppendTextBuffer(" D4..5 = 0x%02X Field patterns ->", ((UnCompFormatDesc->bmInterlaceFlags >> 4) & 3)); switch(UnCompFormatDesc->bmInterlaceFlags & 0x30) { case 0x00: AppendTextBuffer(" Field 1 only"); break; case 0x10: AppendTextBuffer(" Field 2 only"); break; case 0x20: AppendTextBuffer(" Regular Pattern of fields 1 and 2"); break; case 0x30: AppendTextBuffer(" Random Pattern of fields 1 and 2"); break; } AppendTextBuffer("\r\n D6..7 = 0x%02X Display Mode ->", ((UnCompFormatDesc->bmInterlaceFlags >> 6) & 3)); switch(UnCompFormatDesc->bmInterlaceFlags & 0xC0) { case 0x00: AppendTextBuffer(" Bob only"); break; case 0x40: AppendTextBuffer(" Weave only"); break; case 0x80: AppendTextBuffer(" Bob or weave"); break; case 0xC0: //@@TestCase B15.10 //@@Not yet implemented - Priority 3 //@@Descriptor Field - bmInterlaceFlags //@@Question - Should we validate that reserved bits are set to zero? AppendTextBuffer(" Reserved"); break; } } //@@TestCase B15.11 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bCopyProtect //@@Question - Are their reserved bits and should we validate that //@@ reserved bits are set to zero? AppendTextBuffer("\r\nbCopyProtect: 0x%02X", UnCompFormatDesc->bCopyProtect); if (gDoAnnotation) { if (UnCompFormatDesc->bCopyProtect) AppendTextBuffer(" -> Duplication Restricted"); else AppendTextBuffer(" -> Duplication Unrestricted"); } AppendTextBuffer("\r\n"); //@@TestCase B15.12 //@@We should check to make sure that a Color Matching Descriptor is included in the device // Check that the correct number of Frame Descriptors and one Color Matching // descriptor follow CheckForColorMatchingDesc ((PVIDEO_SPECIFIC) UnCompFormatDesc, UnCompFormatDesc->bNumFrameDescriptors, VS_FRAME_UNCOMPRESSED); return TRUE; } //***************************************************************************** // // DisplayUncompressedFrameType() // //***************************************************************************** BOOL DisplayUncompressedFrameType ( PVIDEO_FRAME_UNCOMPRESSED UnCompFrameDesc ) { size_t bLength = 0; bLength = SizeOfVideoFrameUncompressed(UnCompFrameDesc); //@@DisplayUncompressedFrameType -Uncompressed Frame AppendTextBuffer("\r\n ===>Video Streaming Uncompressed Frame Type Descriptor<===\r\n"); if (gDoAnnotation) { if(UnCompFrameDesc->bFrameIndex == g_chUNCFrameDefault) { AppendTextBuffer(" --->This is the Default (optimum) Frame index\r\n"); } } AppendTextBuffer("bLength: 0x%02X\r\n", UnCompFrameDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", UnCompFrameDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", UnCompFrameDesc->bDescriptorSubtype); AppendTextBuffer("bFrameIndex: 0x%02X\r\n", UnCompFrameDesc->bFrameIndex); AppendTextBuffer("bmCapabilities: 0x%02X\r\n", UnCompFrameDesc->bmCapabilities); AppendTextBuffer("wWidth: 0x%04X = %d\r\n", UnCompFrameDesc->wWidth, UnCompFrameDesc->wWidth); AppendTextBuffer("wHeight: 0x%04X = %d\r\n", UnCompFrameDesc->wHeight, UnCompFrameDesc->wHeight); AppendTextBuffer("dwMinBitRate: 0x%08X\r\n", UnCompFrameDesc->dwMinBitRate); AppendTextBuffer("dwMaxBitRate: 0x%08X\r\n", UnCompFrameDesc->dwMaxBitRate); AppendTextBuffer("dwMaxVideoFrameBufferSize: 0x%08X\r\n", UnCompFrameDesc->dwMaxVideoFrameBufferSize); // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwDefaultFrameInterval: 0x%08X = %lf mSec (%4.2f Hz)\r\n", UnCompFrameDesc->dwDefaultFrameInterval, ((double)UnCompFrameDesc->dwDefaultFrameInterval)/10000.0, (10000000.0/((double)UnCompFrameDesc->dwDefaultFrameInterval)) ); AppendTextBuffer("bFrameIntervalType: 0x%02X\r\n", UnCompFrameDesc->bFrameIntervalType); if (UnCompFrameDesc->bLength != bLength) { //@@TestCase B15.1 (descript.c line 925) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required //@@length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", UnCompFrameDesc->bLength, bLength); OOPS(); } if (UnCompFrameDesc->bFrameIndex == 0 ) { //@@TestCase B16.2 (descript.c line 991) //@@ERROR //@@Descriptor Field - bFrameIndex //@@bFrameIndex must be nonzero AppendTextBuffer("*!*ERROR: bFrameIndex = 0, this is a 1 based index\r\n"); OOPS(); } //@@TestCase B16.3 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bmCapabilities //@@Question: Should we try to verify that bmCapabilities is valid? // AppendTextBuffer("bmCapabilities: 0x%02X\r\n", UnCompFrameDesc->bmCapabilities); if (UnCompFrameDesc->wWidth == 0 ) { //@@TestCase B16.4 (descript.c line 996) //@@ERROR //@@Descriptor Field - wWidth //@@wWidth must be nonzero AppendTextBuffer("*!*ERROR: wWidth must be nonzero\r\n"); OOPS(); } if (UnCompFrameDesc->wHeight == 0 ) { //@@TestCase B16.5 (descript.c line 1001) //@@ERROR //@@Descriptor Field - wHeight //@@wHeight must be nonzero AppendTextBuffer("*!*ERROR: wHeight must be nonzero\r\n"); OOPS(); } if (UnCompFrameDesc->dwMinBitRate == 0 ) { //@@TestCase B16.6 (descript.c line 1006) //@@ERROR //@@Descriptor Field - dwMinBitRate //@@dwMinBitRate must be nonzero AppendTextBuffer("*!*ERROR: dwMinBitRate must be nonzero\r\n"); OOPS(); } if (UnCompFrameDesc->dwMaxBitRate == 0 ) { //@@TestCase B16.7 (descript.c line 1011) //@@ERROR //@@Descriptor Field - dwMaxBitRate //@@dwMaxBitRate must be nonzero AppendTextBuffer("*!*ERROR: dwMaxBitRate must be nonzero\r\n"); OOPS(); } if(UnCompFrameDesc->dwMinBitRate > UnCompFrameDesc->dwMaxBitRate) { //@@TestCase B16.8 //@@ERROR //@@Descriptor Field - dwMinBitRate and dwMaxBitRate //@@Verify that dwMaxBitRate is greater than dwMinBitRate AppendTextBuffer("*!*ERROR: dwMinBitRate should be less than dwMaxBitRate\r\n"); OOPS(); } else { if (UnCompFrameDesc->bFrameIntervalType == 1 && UnCompFrameDesc->dwMinBitRate != UnCompFrameDesc->dwMaxBitRate) { //@@TestCase B16.9 //@@WARNING //@@Descriptor Field - bFrameIntervalType, dwMinBitRate, and dwMaxBitRate //@@Verify that dwMaxBitRate is equal to dwMinBitRate if bFrameIntervalType is 1 AppendTextBuffer("*!*WARNING: if bFrameIntervalType is 1 then dwMinBitRate "\ "should equal dwMaxBitRate\r\n"); OOPS(); } } if (UnCompFrameDesc->dwMaxVideoFrameBufferSize == 0 ) { //@@TestCase B16.10 (descript.c line 1015) //@@WARNING //@@Descriptor Field - bFrameIndex //@@bFrameIndex must be nonzero AppendTextBuffer("*!*WARNING: dwMaxVideoFrameBufferSize must be nonzero\r\n"); OOPS(); } if (UnCompFrameDesc->dwDefaultFrameInterval == 0 ) { //@@TestCase B16.11 (descript.c line 1020) //@@WARNING //@@Descriptor Field - dwDefaultFrameInterval //@@dwDefaultFrameInterval must be nonzero AppendTextBuffer("*!*WARNING: dwDefaultFrameInterval must be nonzero\r\n"); OOPS(); } if (0 == UnCompFrameDesc->bFrameIntervalType) { DisplayUnComContinuousFrameType(UnCompFrameDesc); } else { DisplayUnComDiscreteFrameType(UnCompFrameDesc); } return TRUE; } //***************************************************************************** // // DisplayUnComContinuousFrameType() // //***************************************************************************** BOOL DisplayUnComContinuousFrameType( PVIDEO_FRAME_UNCOMPRESSED UContinuousDesc ) { //@@DisplayUnComContinuousFrameType -Uncompressed Continuous Frame ULONG dwMinFrameInterval = UContinuousDesc->adwFrameInterval[0]; ULONG dwMaxFrameInterval = UContinuousDesc->adwFrameInterval[1]; ULONG dwFrameIntervalStep = UContinuousDesc->adwFrameInterval[2]; AppendTextBuffer("===>Additional Continuous Frame Type Data\r\n"); // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwMinFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", dwMinFrameInterval, ((double)dwMinFrameInterval)/10000.0, (ULONG)(10000000.0/((double)dwMinFrameInterval) + 0.5)); AppendTextBuffer("dwMaxFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", dwMaxFrameInterval, ((double)dwMaxFrameInterval)/10000.0, (ULONG)(10000000.0/((double)dwMaxFrameInterval) + 0.5)); AppendTextBuffer("dwFrameIntervalStep: 0x%08X\r\n", dwFrameIntervalStep); if (dwMinFrameInterval == 0 ) { //@@TestCase B17.2 (descript.c line 1025) //@@ERROR //@@Descriptor Field - dwMinFrameInterval //@@dwMinFrameInterval is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMinFrameInterval = 0, this invalidates the descriptor\r\n"); OOPS(); } if (dwMaxFrameInterval == 0 ) { //@@TestCase B17.3 (descript.c line 1025) //@@ERROR //@@Descriptor Field - dwMaxFrameInterval //@@dwMaxFrameInterval is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMaxFrameInterval = 0, this invalidates the descriptor\r\n"); OOPS(); } if(dwMinFrameInterval > dwMaxFrameInterval) { //@@TestCase B17.4 (descript.c 1043) //@@ERROR //@@Descriptor Field - dwMinFrameInterval and dwMaxFrameInterval //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval AppendTextBuffer("*!*ERROR: dwMinFrameInterval is larger that dwMaxFrameInterval, this invalidates the descriptor\r\n"); OOPS(); } else if ((dwMinFrameInterval + dwFrameIntervalStep) > dwMaxFrameInterval) { //@@TestCase B17.5 //@@WARNING //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval combined with dwFrameIntervalStep AppendTextBuffer("*!*WARNING: dwMinFrameInterval + dwFrameIntervalStep is greater than dwMaxFrameInterval, this could cause problems\r\n"); OOPS(); } else if ((dwMaxFrameInterval - dwMinFrameInterval) == 0 ) { //@@TestCase B17.6 //@@CAUTION //@@Descriptor Field - dwFrameIntervalStep //@@Suggestion to use descrite frames if dwFrameIntervalStep is zero AppendTextBuffer("*!*CAUTION: dwFrameIntervalStep equals zero, consider using discrete frames\r\n"); OOPS(); } else if ((dwMaxFrameInterval - dwMinFrameInterval) % dwFrameIntervalStep ) { //@@TestCase B17.7 (descript.c 1052) //@@WARNING //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that the difference between dwMaxFrameInterval and dwMinFrameInterval is evenly divisible by dwFrameIntervalStep AppendTextBuffer("*!*WARNING: dwMaxFrameInterval minus dwMinFrameInterval is not evenly divisible by dwFrameIntervalStep, this could cause problems\r\n"); OOPS(); } if (dwFrameIntervalStep == 0 && (dwMaxFrameInterval - dwMinFrameInterval)) { //@@TestCase B17.8 (descript.c line 1032) //@@WARNING //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that the dwFrameIntervalStep is not zero if there is a difference between dwMaxFrameInterval and dwMinFrameInterval AppendTextBuffer("*!*WARNING: dwFrameIntervalStep = 0, this invalidates the descriptor when there is a difference between dwMinFrameInterval and dwMaxFrameInterval\r\n"); OOPS(); } return TRUE; } //***************************************************************************** // // DisplayUnComDiscreteFrameType() // //***************************************************************************** BOOL DisplayUnComDiscreteFrameType( PVIDEO_FRAME_UNCOMPRESSED UDiscreteDesc ) { //@@DisplayUnComDiscreteFrameType -Uncompressed Discrete Frame UINT iNdex = 1; UINT iCurFrame = 0; ULONG * ulFrameInterval = NULL; AppendTextBuffer("===>Additional Discrete Frame Type Data\r\n"); // There are (UDiscreteDesc->bFrameIntervalType) dwFrameIntervals (1 based index) for (; iNdex <= UDiscreteDesc->bFrameIntervalType; iNdex++, iCurFrame++) { ulFrameInterval = &UDiscreteDesc->adwFrameInterval[iCurFrame]; // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwFrameInterval[%d]: 0x%08X = %lf mSec (%4.2f Hz)\r\n", iNdex, *ulFrameInterval, ((double)*ulFrameInterval)/10000.0, (10000000.0/((double)*ulFrameInterval)) ); if (0 == *ulFrameInterval) { //@@TestCase B18.1 (descript.c line 1061) //@@ERROR //@@Descriptor Field - dwFrameInterval[x] //@@dwFrameInterval[x] must be non-zero AppendTextBuffer("*!*ERROR: dwFrameInterval[%d] must be non-zero\r\n", iNdex); OOPS(); } if ((iNdex > 1)&&(*ulFrameInterval <= UDiscreteDesc->adwFrameInterval[iCurFrame - 1])) { //@@TestCase B18.2 (descript.c line 1067) //@@ERROR //@@Descriptor Field - dwFrameInterval[x] //@@dwFrameInterval[n] must be greater than dwFrameInterval[n - 1] AppendTextBuffer("*!*ERROR: dwFrameInterval[0x%02X] must be "\ "greater than preceding dwFrameInterval[0x%02X]\r\n", iNdex, iNdex - 1); OOPS(); } } return TRUE; } //***************************************************************************** // // DisplayMJPEGFormat() // //***************************************************************************** BOOL DisplayMJPEGFormat ( PVIDEO_FORMAT_MJPEG MJPEGFormatDesc ) { //@@DisplayMJPEGFormat - MJPEG Format // Initialize the default Frame g_chMJPEGFrameDefault = MJPEGFormatDesc->bDefaultFrameIndex; AppendTextBuffer("\r\n ===>Video Streaming MJPEG Format Type Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", MJPEGFormatDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MJPEGFormatDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MJPEGFormatDesc->bDescriptorSubtype); AppendTextBuffer("bFormatIndex: 0x%02X\r\n", MJPEGFormatDesc->bFormatIndex); AppendTextBuffer("bNumFrameDescriptors: 0x%02X\r\n", MJPEGFormatDesc->bNumFrameDescriptors); if (MJPEGFormatDesc->bLength != sizeof(VIDEO_FORMAT_MJPEG)) { //@@TestCase B19.1 (descript.c line 1098) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the //@@ required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", MJPEGFormatDesc->bLength, sizeof(VIDEO_FORMAT_MJPEG)); OOPS(); } if (MJPEGFormatDesc->bFormatIndex == 0 ) { //@@TestCase B19.2 (descript.c line 1103) //@@ERROR //@@Descriptor Field - bFormatIndex //@@bFormatIndex is set to zero which is not in accordance with //@@ the USB Video Device Specification AppendTextBuffer("*!*ERROR: bFormatIndex must be non-zero\r\n"); OOPS(); } if (MJPEGFormatDesc->bNumFrameDescriptors == 0 ) { //@@TestCase B19.3 (descript.c line 1108) //@@ERROR //@@Descriptor Field - bNumFrameDescriptors //@@bNumFrameDescriptors is set to zero which is not in accordance //@@ with the USB Video Device Specification AppendTextBuffer("*!*ERROR: bNumFrameDescriptors must be non-zero\r\n"); OOPS(); } AppendTextBuffer("bmFlags: 0x%02X", (MJPEGFormatDesc->bmFlags & 0x01)); //@@TestCase B19.4 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bmFlags //@@We should validate that reserved bits are set to zero. if (gDoAnnotation) { if(MJPEGFormatDesc->bmFlags & 0x01) { AppendTextBuffer(" -> Sample Size is Fixed"); } else { AppendTextBuffer(" -> Sample Size is Not Fixed"); } } AppendTextBuffer("\r\nbDefaultFrameIndex: 0x%02X\r\n", MJPEGFormatDesc->bDefaultFrameIndex); if (MJPEGFormatDesc->bDefaultFrameIndex == 0 || MJPEGFormatDesc->bDefaultFrameIndex > MJPEGFormatDesc->bNumFrameDescriptors) { //@@TestCase B19.5 (descript.c line 1113) //@@ERROR //@@Descriptor Field - bDefaultFrameIndex //@@bDefaultFrameIndex is not in the domain of constrained by //@@ bNumFrameDescriptors AppendTextBuffer("*!*ERROR: bDefaultFrameIndex 0x%02X invalid, should "\ "be between 1 and 0x%02x/r/n", MJPEGFormatDesc->bDefaultFrameIndex, MJPEGFormatDesc->bNumFrameDescriptors); OOPS(); } AppendTextBuffer("bAspectRatioX: 0x%02X\r\n", MJPEGFormatDesc->bAspectRatioX); AppendTextBuffer("bAspectRatioY: 0x%02X", MJPEGFormatDesc->bAspectRatioY); if(((MJPEGFormatDesc->bmInterlaceFlags & 0x01) && ((MJPEGFormatDesc->bAspectRatioY != 0) && (MJPEGFormatDesc->bAspectRatioX != 0)))) { if (gDoAnnotation) { AppendTextBuffer(" -> Aspect Ratio is set for a %d:%d display", (MJPEGFormatDesc->bAspectRatioX), (MJPEGFormatDesc->bAspectRatioY)); } } else { if (MJPEGFormatDesc->bAspectRatioY != 0 || MJPEGFormatDesc->bAspectRatioX != 0) { //@@TestCase B19.6 //@@ERROR //@@Descriptor Field - bAspectRatioX and bAspectRatioY //@@Verify that that bAspectRatioX and bAspectRatioY are set to zero //@@ if stream is non-interlaced AppendTextBuffer("\r\n*!*ERROR: bAspectRatioX and bAspectRatioY must "\ "be 0 if stream non-Interlaced"); OOPS(); } } AppendTextBuffer("\r\nbmInterlaceFlags: 0x%02X\r\n", MJPEGFormatDesc->bmInterlaceFlags); if (gDoAnnotation) { AppendTextBuffer(" D00 = %x %sInterlaced stream or variable\r\n", (MJPEGFormatDesc->bmInterlaceFlags & 1), (MJPEGFormatDesc->bmInterlaceFlags & 1) ? "" : " non-"); AppendTextBuffer(" D01 = %x %s per frame\r\n", ((MJPEGFormatDesc->bmInterlaceFlags >> 1) & 1), ((MJPEGFormatDesc->bmInterlaceFlags >> 1) & 1) ? " 1 field" : " 2 fields"); AppendTextBuffer(" D02 = %x Field 1 %sfirst\r\n", ((MJPEGFormatDesc->bmInterlaceFlags >> 2) & 1), ((MJPEGFormatDesc->bmInterlaceFlags >> 2) & 1) ? "" : "not "); //@@TestCase B19.7 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bmInterlaceFlags //@@Validate that reserved bits (D3) are set to zero. AppendTextBuffer(" D03 = %x Reserved%s\r\n", ((MJPEGFormatDesc->bmInterlaceFlags >> 3) & 1), ((MJPEGFormatDesc->bmInterlaceFlags >> 3) & 1) ? "\r\n*!*ERROR: non zero" : "" ); AppendTextBuffer(" D4..5 = %x Field patterns ->", ((MJPEGFormatDesc->bmInterlaceFlags >> 4) & 3)); switch (MJPEGFormatDesc->bmInterlaceFlags & 0x30) { case 0x00: AppendTextBuffer(" Field 1 only"); break; case 0x10: AppendTextBuffer(" Field 2 only"); break; case 0x20: AppendTextBuffer(" Regular Pattern of fields 1 and 2"); break; case 0x30: AppendTextBuffer(" Random Pattern of fields 1 and 2"); break; } AppendTextBuffer("\r\n D6..7 = %x Display Mode ->", ((MJPEGFormatDesc->bmInterlaceFlags >> 6) & 3)); switch(MJPEGFormatDesc->bmInterlaceFlags & 0xC0) { case 0x00: AppendTextBuffer(" Bob only"); break; case 0x40: AppendTextBuffer(" Weave only"); break; case 0x80: AppendTextBuffer(" Bob or weave"); break; case 0xC0: //@@TestCase B19.8 //@@Not yet implemented - Priority 3 //@@Descriptor Field - bmInterlaceFlags //@@Question - Should we validate that reserved bits are set to zero? AppendTextBuffer(" Reserved"); break; } } //@@TestCase B19.9 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bCopyProtect //@@Question - Are their reserved bits and should we validate that //@@ reserved bits are set to zero? AppendTextBuffer("\r\nbCopyProtect: 0x%02X", MJPEGFormatDesc->bCopyProtect); if (gDoAnnotation) { if (MJPEGFormatDesc->bCopyProtect) AppendTextBuffer(" -> Duplication Restricted"); else AppendTextBuffer(" -> Duplication Unrestricted"); } AppendTextBuffer("\r\n"); // Check that the correct number of Frame Descriptors and one Color Matching // descriptor follow CheckForColorMatchingDesc ((PVIDEO_SPECIFIC) MJPEGFormatDesc, MJPEGFormatDesc->bNumFrameDescriptors, VS_FRAME_MJPEG); return TRUE; } //***************************************************************************** // // DisplayMJPEGFrameType() // //***************************************************************************** BOOL DisplayMJPEGFrameType ( PVIDEO_FRAME_MJPEG MJPEGFrameDesc ) { //@@DisplayMJPEGFrameType -MJPEG Frame size_t bLength = 0; bLength = SizeOfVideoFrameMjpeg(MJPEGFrameDesc); AppendTextBuffer("\r\n ===>Video Streaming MJPEG Frame Type Descriptor<===\r\n"); if (gDoAnnotation) { if(MJPEGFrameDesc->bFrameIndex == g_chMJPEGFrameDefault) { AppendTextBuffer(" --->This is the Default (optimum) Frame index\r\n"); } } AppendTextBuffer("bLength: 0x%02X\r\n", MJPEGFrameDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MJPEGFrameDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MJPEGFrameDesc->bDescriptorSubtype); AppendTextBuffer("bFrameIndex: 0x%02X\r\n", MJPEGFrameDesc->bFrameIndex); AppendTextBuffer("bmCapabilities: 0x%02X\r\n", MJPEGFrameDesc->bmCapabilities); AppendTextBuffer("wWidth: 0x%04X = %d\r\n", MJPEGFrameDesc->wWidth, MJPEGFrameDesc->wWidth); AppendTextBuffer("wHeight: 0x%04X = %d\r\n", MJPEGFrameDesc->wHeight, MJPEGFrameDesc->wHeight); AppendTextBuffer("dwMinBitRate: 0x%08X\r\n", MJPEGFrameDesc->dwMinBitRate); AppendTextBuffer("dwMaxBitRate: 0x%08X\r\n", MJPEGFrameDesc->dwMaxBitRate); AppendTextBuffer("dwMaxVideoFrameBufferSize: 0x%08X\r\n", MJPEGFrameDesc->dwMaxVideoFrameBufferSize); // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwDefaultFrameInterval: 0x%08X = %lf mSec (%4.2f Hz)\r\n", MJPEGFrameDesc->dwDefaultFrameInterval, ((double)MJPEGFrameDesc->dwDefaultFrameInterval)/10000.0, (10000000.0/((double)MJPEGFrameDesc->dwDefaultFrameInterval)) ); AppendTextBuffer("bFrameIntervalType: 0x%02X\r\n", MJPEGFrameDesc->bFrameIntervalType); if (MJPEGFrameDesc->bLength != bLength) { //@@TestCase B20.1 (descript.c line 1154) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is less than required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d is incorrect, should be %d\r\n", MJPEGFrameDesc->bLength, bLength); OOPS(); } if (MJPEGFrameDesc->bFrameIndex == 0 ) { //@@TestCase B20.2 (descript.c line 1159) //@@WARNING //@@Descriptor Field - bFrameIndex //@@bFrameIndex is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*WARNING: bFrameIndex = 0, this invalidates the descriptor\r\n"); OOPS(); } //@@TestCase B20.3 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bmCapabilities //@@Question: Should we try to verify that bmCapabilities is valid? // AppendTextBuffer("bmCapabilities: 0x%02X\r\n", MJPEGFrameDesc->bmCapabilities); if (MJPEGFrameDesc->wWidth == 0 ) { //@@TestCase B20.4 (descript.c line 1164) //@@ERROR //@@Descriptor Field - wWidth //@@wWidth is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: wWidth = 0, this invalidates the descriptor\r\n"); OOPS(); } if (MJPEGFrameDesc->wHeight == 0 ) { //@@TestCase B20.5 (descript.c line 1169) //@@ERROR //@@Descriptor Field - wHeight //@@wHeight is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: wHeight = 0, this invalidates the descriptor\r\n"); OOPS(); } if (MJPEGFrameDesc->dwMinBitRate == 0 ) { //@@TestCase B20.6 (descript.c line 1174) //@@ERROR //@@Descriptor Field - dwMinBitRate //@@dwMinBitRate is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMinBitRate = 0, this invalidates the descriptor\r\n"); OOPS(); } if (MJPEGFrameDesc->dwMaxBitRate == 0 ) { //@@TestCase B20.7 (descript.c line 1179) //@@ERROR //@@Descriptor Field - dwMaxBitRate //@@dwMaxBitRate is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMaxBitRate = 0, this invalidates the descriptor\r\n"); OOPS(); } if(MJPEGFrameDesc->dwMinBitRate > MJPEGFrameDesc->dwMaxBitRate) { //@@TestCase B20.8 //@@ERROR //@@Descriptor Field - dwMinBitRate and dwMaxBitRate //@@Verify that dwMaxBitRate is greater than dwMinBitRate AppendTextBuffer("*!*ERROR: dwMinBitRate > dwMaxBitRate, this invalidates the descriptor\r\n"); OOPS(); } else if(MJPEGFrameDesc->bFrameIntervalType == 1 && MJPEGFrameDesc->dwMinBitRate != MJPEGFrameDesc->dwMaxBitRate) { //@@TestCase B20.9 //@@WARNING //@@Descriptor Field - bFrameIntervalType, dwMinBitRate, and dwMaxBitRate //@@Verify that dwMaxBitRate is equal to dwMinBitRate if bFrameIntervalType is 1 AppendTextBuffer("*!*WARNING: if bFrameIntervalType is 1 then dwMinBitRate should equal dwMaxBitRate\r\n"); OOPS(); } if (MJPEGFrameDesc->dwMaxVideoFrameBufferSize == 0 ) { //@@TestCase B20.10 (descript.c line 1183) //@@ERROR //@@Descriptor Field - dwMaxVideoFrameBufferSize //@@dwMaxVideoFrameBufferSize is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMaxVideoFrameBufferSize = 0, this invalidates the descriptor\r\n"); OOPS(); } if (MJPEGFrameDesc->dwMaxVideoFrameBufferSize == 0 ) { //@@TestCase B20.11 (descript.c line 1188) //@@ERROR //@@Descriptor Field - dwDefaultFrameInterval //@@dwDefaultFrameInterval is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwDefaultFrameInterval = 0, this invalidates the descriptor\r\n"); OOPS(); } if (0 == MJPEGFrameDesc->bFrameIntervalType) { DisplayMJPEGContinuousFrameType(MJPEGFrameDesc); } else { DisplayMJPEGDiscreteFrameType(MJPEGFrameDesc); } return TRUE; } //***************************************************************************** // // DisplayMJPEGContinuousFrameType() // //***************************************************************************** BOOL DisplayMJPEGContinuousFrameType( PVIDEO_FRAME_MJPEG MContinuousDesc ) { //@@DisplayMJPEGContinuousFrameType - MJPEG Continuous Frame ULONG dwMinFrameInterval = MContinuousDesc->adwFrameInterval[0]; ULONG dwMaxFrameInterval = MContinuousDesc->adwFrameInterval[1]; ULONG dwFrameIntervalStep = MContinuousDesc->adwFrameInterval[2]; AppendTextBuffer("===>Additional Continuous Frame Type Data\r\n"); // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwMinFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", dwMinFrameInterval, ((double)dwMinFrameInterval)/10000.0, (ULONG)(10000000.0/((double)dwMinFrameInterval) + 0.5)); AppendTextBuffer("dwMaxFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", dwMaxFrameInterval, ((double)dwMaxFrameInterval)/10000.0, (ULONG)(10000000.0/((double)dwMaxFrameInterval) + 0.5)); AppendTextBuffer("dwFrameIntervalStep: 0x%08X\r\n", dwFrameIntervalStep); if (dwMinFrameInterval == 0 ) { //@@TestCase B21.2 (descript.c line 1188) //@@ERROR //@@Descriptor Field - dwMinFrameInterval //@@dwMinFrameInterval is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMinFrameInterval = 0, this invalidates the descriptor\r\n"); OOPS(); } if (dwMaxFrameInterval == 0 ) { //@@TestCase B21.3 (descript.c line 1188) //@@ERROR //@@Descriptor Field - dwMaxFrameInterval //@@dwMaxFrameInterval is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMaxFrameInterval = 0, this invalidates the descriptor\r\n"); OOPS(); } if(dwMinFrameInterval > dwMaxFrameInterval) { //@@TestCase B21.4 (descript.c line 1211) //@@ERROR //@@Descriptor Field - dwMinFrameInterval and dwMaxFrameInterval //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval AppendTextBuffer("*!*ERROR: dwMinFrameInterval is larger that dwMaxFrameInterval, this invalidates the descriptor\r\n"); OOPS(); } else if ((dwMinFrameInterval + dwFrameIntervalStep) > dwMaxFrameInterval) { //@@TestCase B21.5 //@@WARNING //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval combined with dwFrameIntervalStep AppendTextBuffer("*!*WARNING: dwMinFrameInterval + dwFrameIntervalStep is greater than dwMaxFrameInterval, this could cause problems\r\n"); OOPS(); } else if ((dwMaxFrameInterval - dwMinFrameInterval) == 0 ) { //@@TestCase B21.6 //@@CAUTION //@@Descriptor Field - dwFrameIntervalStep //@@Suggestion to use descrite frames if dwFrameIntervalStep is zero AppendTextBuffer("*!*CAUTION: dwFrameIntervalStep equals zero, consider using discrete frames\r\n"); OOPS(); } else if ((dwMaxFrameInterval - dwMinFrameInterval) % dwFrameIntervalStep ) { //@@TestCase B21.7 (descript.c line 1220) //@@WARNING //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that the difference between dwMaxFrameInterval and dwMinFrameInterval is evenly divisible by dwFrameIntervalStep AppendTextBuffer("*!*WARNING: dwMaxFrameInterval minus dwMinFrameInterval is not evenly divisible by dwFrameIntervalStep, this could cause problems\r\n"); OOPS(); } if (dwFrameIntervalStep == 0 && (dwMaxFrameInterval - dwMinFrameInterval)) { //@@TestCase B21.8 (descript.c line 1200) //@@WARNING //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that the dwFrameIntervalStep is not zero if there is a difference between dwMaxFrameInterval and dwMinFrameInterval AppendTextBuffer("*!*WARNING: dwFrameIntervalStep = 0, this invalidates the descriptor when there is a difference between \r\n *!*dwMinFrameInterval and dwMaxFrameInterval\r\n"); OOPS(); } return TRUE; } //***************************************************************************** // // DisplayMJPEGDiscreteFrameType() // //***************************************************************************** BOOL DisplayMJPEGDiscreteFrameType( PVIDEO_FRAME_MJPEG MDiscreteDesc ) { //@@DisplayMJPEGDiscreteFrameType -MJPEG Discrete Frame UINT iNdex = 1; UINT iCurFrame = 0; ULONG * ulFrameInterval = NULL; AppendTextBuffer("===>Additional Discrete Frame TypeData\r\n"); // There are (MDiscreteDesc->bFrameIntervalType) dwFrameIntervals (1 based index) for (; iNdex <= MDiscreteDesc->bFrameIntervalType; iNdex++, iCurFrame++) { ulFrameInterval = &MDiscreteDesc->adwFrameInterval[iCurFrame]; // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwFrameInterval[%d]: 0x%08X = %lf mSec (%4.2f Hz)\r\n", iNdex, *ulFrameInterval, ((double)*ulFrameInterval)/10000.0, (10000000.0/((double)*ulFrameInterval)) ); if (0 == *ulFrameInterval) { //@@TestCase B22.1 (descript.c line 1229) //@@ERROR //@@Descriptor Field - dwFrameInterval[x] //@@dwFrameInterval[x] must be non-zero AppendTextBuffer("*!*ERROR: dwFrameInterval[%d] must be non-zero\r\n", iNdex); OOPS(); } if ((iNdex > 1)&&(*ulFrameInterval <= MDiscreteDesc->adwFrameInterval[iCurFrame - 1])) { //@@TestCase B22.2 (descript.c line 1235) //@@ERROR //@@Descriptor Field - dwFrameInterval[x] //@@dwFrameInterval[n] must be greater than dwFrameInterval[n - 1] AppendTextBuffer("*!*ERROR: dwFrameInterval[0x%02X] must be "\ "greater than preceding dwFrameInterval[0x%02X]\r\n", iNdex, iNdex - 1); OOPS(); } } return TRUE; } //***************************************************************************** // // DisplayMPEG1SSFormat() // //***************************************************************************** BOOL DisplayMPEG1SSFormat ( PVIDEO_FORMAT_MPEG1SS MPEG1SSFormatDesc ) { //@@DisplayMPEG1SSFormat -MPEG1 SS Format AppendTextBuffer("\r\n ===>Video Streaming MPEG1-SS Format Type Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", MPEG1SSFormatDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MPEG1SSFormatDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MPEG1SSFormatDesc->bDescriptorSubtype); AppendTextBuffer("bFormatIndex: 0x%02X\r\n", MPEG1SSFormatDesc->bFormatIndex); AppendTextBuffer("wPacketLength: 0x%02X\r\n", MPEG1SSFormatDesc->bPacketLength); AppendTextBuffer("wPackLength: 0x%02X\r\n", MPEG1SSFormatDesc->bPackLength); AppendTextBuffer("bPackdataType: 0x%02X", (MPEG1SSFormatDesc->bPackDataType)); if(gDoAnnotation) { if(MPEG1SSFormatDesc->bPackDataType & 0x01){AppendTextBuffer(" -> Pack data size fixed\r\n");} else {AppendTextBuffer(" -> Pack data size variable\r\n"); }} else {AppendTextBuffer("\r\n");} if (MPEG1SSFormatDesc->bLength != sizeof(VIDEO_FORMAT_MPEG1SS)) { //@@TestCase B23.1 (descript.c line 1514) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d. USBView cannot correctly display descriptor\r\n", MPEG1SSFormatDesc->bLength, sizeof(VIDEO_FORMAT_MPEG1SS)); OOPS(); } if (MPEG1SSFormatDesc->bFormatIndex == 0 ) { //@@TestCase B23.2 (descript.c line 1519) //@@WARNING //@@Descriptor Field - bFormatIndex //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*WARNING: bFormatIndex = 0, this invalidates the descriptor\r\n"); OOPS(); } //@@TestCase B23.3 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bPackdataType //@@Question - Should we validate that reserved bits are set to zero? // AppendTextBuffer("bPackdataType: 0x%02X", (MPEG1SSFormatDesc->bPackdataType & 0x01)); // This descriptor is deprecated for UVC 1.1 #ifdef H264_SUPPORT if (UVC10 != g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC version >= 1.1 devices\r\n"); } #else if (UVC11 == g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.1 devices\r\n"); } #endif return TRUE; } //***************************************************************************** // // DisplayMPEG2PSFormat() // //***************************************************************************** BOOL DisplayMPEG2PSFormat ( PVIDEO_FORMAT_MPEG2PS MPEG2PSFormatDesc ) { //@@DisplayMPEG2PSFormat -MPEG2 PS Format AppendTextBuffer("\r\n ===>Video Streaming MPEG2-PS Format Type Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", MPEG2PSFormatDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MPEG2PSFormatDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MPEG2PSFormatDesc->bDescriptorSubtype); AppendTextBuffer("bFormatIndex: 0x%02X\r\n", MPEG2PSFormatDesc->bFormatIndex); AppendTextBuffer("bPacketLength: 0x%02X\r\n", MPEG2PSFormatDesc->bPacketLength); AppendTextBuffer("bPackLength: 0x%02X\r\n", MPEG2PSFormatDesc->bPackLength); AppendTextBuffer("bPackDataType: 0x%02X", (MPEG2PSFormatDesc->bPackDataType)); if (MPEG2PSFormatDesc->bLength != sizeof(VIDEO_FORMAT_MPEG2PS)) { //@@TestCase B24.1 (descript.c line 1542) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d. USBView cannot correctly display descriptor\r\n", MPEG2PSFormatDesc->bLength, sizeof(VIDEO_FORMAT_MPEG2PS)); OOPS(); AppendTextBuffer("*!*USBView will try to display the rest of the descriptor but results may not be accurate\r\n"); } if (MPEG2PSFormatDesc->bFormatIndex == 0 ) { //@@TestCase B24.2 (descript.c line 1547) //@@WARNING //@@Descriptor Field - bFormatIndex //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*WARNING: bFormatIndex = 0, this invalidates the descriptor\r\n"); OOPS(); } //@@TestCase B24.3 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bPackdataType //@@Question - Should we validate that reserved bits are set to zero? // AppendTextBuffer("bPackdataType: 0x%02X", (MPEG2PSFormatDesc->bPackdataType & 0x01)); // This descriptor is deprecated for UVC 1.1 #ifdef H264_SUPPORT if (UVC10 != g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC version >= 1.1 devices\r\n"); } #else if (UVC11 == g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.1 devices\r\n"); } #endif return TRUE; } //***************************************************************************** // // DisplayMPEG2TSFormat() // //***************************************************************************** BOOL DisplayMPEG2TSFormat ( PVIDEO_FORMAT_MPEG2TS MPEG2TSFormatDesc ) { //@@DisplayMPEG2TSFormat -MPEG2 TS Format UCHAR bLength = sizeof(VIDEO_FORMAT_MPEG2TS); AppendTextBuffer("\r\n ===>Video Streaming MPEG2-TS Format Type Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", MPEG2TSFormatDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MPEG2TSFormatDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MPEG2TSFormatDesc->bDescriptorSubtype); AppendTextBuffer("bFormatIndex: 0x%02X\r\n", MPEG2TSFormatDesc->bFormatIndex); AppendTextBuffer("bDataOffset: 0x%02X\r\n", MPEG2TSFormatDesc->bDataOffset); AppendTextBuffer("bPacketLength: 0x%02X\r\n", MPEG2TSFormatDesc->bPacketLength); AppendTextBuffer("bStrideLength: 0x%02X\r\n", MPEG2TSFormatDesc->bStrideLength); #ifdef H264_SUPPORT if (UVC10 != g_chUVCversion) #else if (UVC11 == g_chUVCversion) #endif { int i = 0; PCHAR pStr = NULL; OLECHAR szGUID[256]; GUID * pStrideGuid = NULL; pStrideGuid = (GUID *) (&MPEG2TSFormatDesc->bStrideLength + 1); memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); i = StringFromGUID2((REFGUID) pStrideGuid, (LPOLESTR) szGUID, 255); i++; AppendTextBuffer("guidStrideFormat: %S", szGUID); pStr = VidFormatGUIDCodeToName((REFGUID) pStrideGuid); if(gDoAnnotation) { if (pStr) { AppendTextBuffer(" = %s Format", pStr); } } AppendTextBuffer("\r\n"); bLength = sizeof(VIDEO_FORMAT_MPEG2TS) + sizeof(GUID); } if (MPEG2TSFormatDesc->bLength != bLength) { //@@TestCase B25.1 (descript.c line 1486) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", MPEG2TSFormatDesc->bLength, sizeof(VIDEO_FORMAT_MPEG2TS)); OOPS(); } if (MPEG2TSFormatDesc->bFormatIndex == 0 ) { //@@TestCase B25.2 (descript.c line 1491) //@@WARNING //@@Descriptor Field - bFormatIndex //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*WARNING: bFormatIndex = 0, this invalidates the descriptor\r\n"); OOPS(); } //@@TestCase B25.3 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bDataOffset, wPacket and wStride //@@Question - Should we check that if bDataOffset is 0 that wPacket and wStride should equal each other // AppendTextBuffer("bDataOffset: 0x%02X\r\n", MPEG2TSFormatDesc->bDataOffset); return TRUE; } //***************************************************************************** // // DisplayMPEG4SLFormat() // //***************************************************************************** BOOL DisplayMPEG4SLFormat ( PVIDEO_FORMAT_MPEG4SL MPEG4SLFormatDesc ) { //@@DisplayMPEG4SLFormat -MPEG4 SL Format AppendTextBuffer("\r\n ===>Video Streaming MPEG4-SL Format Type Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", MPEG4SLFormatDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", MPEG4SLFormatDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", MPEG4SLFormatDesc->bDescriptorSubtype); AppendTextBuffer("bFormatIndex: 0x%02X\r\n", MPEG4SLFormatDesc->bFormatIndex); AppendTextBuffer("bPacketLength: 0x%02X\r\n", MPEG4SLFormatDesc->bPacketLength); if (MPEG4SLFormatDesc->bLength != sizeof(VIDEO_FORMAT_MPEG4SL)) { //@@TestCase B26.1 (descript.c line 1568) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d. USBView cannot correctly display descriptor\r\n", MPEG4SLFormatDesc->bLength, sizeof(VIDEO_FORMAT_MPEG4SL)); OOPS(); } if (MPEG4SLFormatDesc->bFormatIndex == 0 ) { //@@TestCase B26.2 (descript.c line 1573) //@@WARNING //@@Descriptor Field - bFormatIndex //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*WARNING: bFormatIndex = 0, this invalidates the descriptor\r\n"); OOPS(); } // This descriptor is deprecated for UVC 1.1 #ifdef H264_SUPPORT if (UVC10 != g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC version >= 1.1 devices\r\n"); } #else if (UVC11 == g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.1 devices\r\n"); } #endif return TRUE; } //***************************************************************************** // // DisplayStreamPayload() // //***************************************************************************** BOOL DisplayStreamPayload ( PVIDEO_FORMAT_STREAM StreamPayloadDesc ) { //@@DisplayStreamPayload -Stream Based Payload Format PCHAR pStr = NULL; OLECHAR szGUID[256]; int i = 0; memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); i = StringFromGUID2((REFGUID) &StreamPayloadDesc->guidFormat, (LPOLESTR) szGUID, 255); i++; AppendTextBuffer("\r\n ===>Video Streaming Stream Based Payload Format Type Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", StreamPayloadDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", StreamPayloadDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", StreamPayloadDesc->bDescriptorSubtype); AppendTextBuffer("bFormatIndex: 0x%02X\r\n", StreamPayloadDesc->bFormatIndex); AppendTextBuffer("guidFormat: %S", szGUID); pStr = VidFormatGUIDCodeToName((REFGUID) &StreamPayloadDesc->guidFormat); if(gDoAnnotation) { if (pStr) { AppendTextBuffer(" = %s Format", pStr); } } AppendTextBuffer("\r\n"); AppendTextBuffer("dwPacketLength: 0x%02X\r\n", StreamPayloadDesc->dwPacketLength); if (StreamPayloadDesc->bLength != sizeof(VIDEO_FORMAT_STREAM)) { //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", StreamPayloadDesc->bLength, sizeof(PVIDEO_FORMAT_STREAM)); OOPS(); } if (StreamPayloadDesc->bFormatIndex == 0 ) { //@@WARNING //@@Descriptor Field - bFormatIndex //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*WARNING: bFormatIndex = 0, this is a 1 based index\r\n"); OOPS(); } // This descriptor is new for UVC 1.1 if (UVC10 == g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.0 devices\r\n"); } return TRUE; } //***************************************************************************** // // DisplayDVFormat() // //***************************************************************************** BOOL DisplayDVFormat ( PVIDEO_FORMAT_DV DVFormatDesc ) { //@@DisplayDVFormat -Digital Video Format AppendTextBuffer("\r\n ===>Video Streaming DV Format Type Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", DVFormatDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", DVFormatDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", DVFormatDesc->bDescriptorSubtype); AppendTextBuffer("bFormatIndex: 0x%02X\r\n", DVFormatDesc->bFormatIndex); AppendTextBuffer("dwMaxVideoFrameBufferSize: 0x%08X\r\n", DVFormatDesc->dwMaxVideoFrameBufferSize); AppendTextBuffer("bFormatType: 0x%02X\r\n", DVFormatDesc->bFormatType); if (gDoAnnotation) { AppendTextBuffer(" D0..6 = Format Type ->"); switch(DVFormatDesc->bFormatType & 0x03) { case 0x00: AppendTextBuffer(" SD-DV\r\n"); break; case 0x01: AppendTextBuffer(" SDL-DV\r\n"); break; case 0x02: AppendTextBuffer(" HD-DV\r\n"); break; default: AppendTextBuffer(" Unknown Format\r\n"); break; } if (DVFormatDesc->bFormatType & 0x80) AppendTextBuffer(" D7 = 60Hz"); else AppendTextBuffer(" D7 = 50Hz"); AppendTextBuffer("\r\n");} if (DVFormatDesc->bLength != sizeof(VIDEO_FORMAT_DV)) { //@@TestCase B27.1 (descript.c line 1453) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", DVFormatDesc->bLength, sizeof(VIDEO_FORMAT_DV)); OOPS(); } if (DVFormatDesc->bFormatIndex == 0 ) { //@@TestCase B27.2 (descript.c line 1458) //@@ERROR //@@Descriptor Field - bFormatIndex //@@bFormatIndex invalid AppendTextBuffer("*!*ERROR: bFormatIndex of 0x%02X is invalid\r\n", DVFormatDesc->bFormatIndex); OOPS(); } if (DVFormatDesc->dwMaxVideoFrameBufferSize == 0 ) { //@@TestCase B27.3 (descript.c line 1463) //@@ERROR //@@Descriptor Field - dwMaxVideoFrameBufferSize //@@dwMaxVideoFrameBufferSize invalid AppendTextBuffer("*!*ERROR: dwMaxVideoFrameBufferSize of 0x%02X is invalid\r\n", DVFormatDesc->dwMaxVideoFrameBufferSize); OOPS(); } //@@TestCase B27.4 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bFormatType //@@Question - Should we validate that reserved bits are set to zero? return TRUE; } //***************************************************************************** // // DisplayVidVendorFormat() // //***************************************************************************** BOOL DisplayVendorVidFormat ( PVIDEO_FORMAT_VENDOR VendorVidFormatDesc ) { //@@DisplayVendorVidFormat -Vendor Video Format OLECHAR szGUID[256]; int i = 0; // Initialize the default Frame g_chVendorFrameDefault = VendorVidFormatDesc->bDefaultFrameIndex; memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); i = StringFromGUID2((REFGUID) &VendorVidFormatDesc->guidMajorFormat, (LPOLESTR) szGUID, 255); i++; AppendTextBuffer("\r\n ===>Video Streaming Vendor Video Format Type Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", VendorVidFormatDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VendorVidFormatDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VendorVidFormatDesc->bDescriptorSubtype); AppendTextBuffer("bFormatIndex: 0x%02X\r\n", VendorVidFormatDesc->bFormatIndex); AppendTextBuffer("bNumFrameDescriptors: 0x%02X\r\n", VendorVidFormatDesc->bNumFrameDescriptors); AppendTextBuffer("guidMajorFormat: %S\r\n", szGUID); i = StringFromGUID2((REFGUID) &VendorVidFormatDesc->guidSubFormat, (LPOLESTR) szGUID, 255); i++; AppendTextBuffer("guidSubFormat: %S\r\n", szGUID); i = StringFromGUID2((REFGUID) &VendorVidFormatDesc->guidSpecifier, (LPOLESTR) szGUID, 255); i++; AppendTextBuffer("guidSpecifier: %S\r\n", szGUID); AppendTextBuffer("bPayloadClass: 0x%02X\r\n", VendorVidFormatDesc->bPayloadClass); AppendTextBuffer("bDefaultFrameIndex: 0x%02X\r\n", VendorVidFormatDesc->bDefaultFrameIndex); AppendTextBuffer("bCopyProtect: 0x%02X", VendorVidFormatDesc->bCopyProtect); if(gDoAnnotation) { if(VendorVidFormatDesc->bCopyProtect) { AppendTextBuffer(" -> Duplication Restricted\r\n");} else {AppendTextBuffer(" -> Duplication Unrestricted\r\n");}} else {AppendTextBuffer("\r\n");} if (VendorVidFormatDesc->bLength != sizeof(VIDEO_FORMAT_VENDOR)) { //@@TestCase B28.1 (descript.c line 1297) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d. USBView cannot correctly display descriptor\r\n", VendorVidFormatDesc->bLength, sizeof(VIDEO_FORMAT_VENDOR)); OOPS(); } if (VendorVidFormatDesc->bFormatIndex == 0 ) { //@@TestCase B28.2 (descript.c line 1302) //@@ERROR //@@Descriptor Field - bFormatIndex //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: bFormatIndex = 0, this invalidates the descriptor\r\n"); OOPS(); } if (VendorVidFormatDesc->bNumFrameDescriptors == 0 ) { //@@TestCase B28.3 (descript.c line 1307) //@@ERROR //@@Descriptor Field - bNumFrameDescriptors //@@bNumFrameDescriptors is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: bNumFrameDescriptors = 0, this invalidates the descriptor\r\n"); OOPS(); } if(VendorVidFormatDesc->bPayloadClass > 1) { //@@TestCase B28.4 //@@WARNING //@@Descriptor Field - bPayloadClass //@@bPayloadClass is using reserved space AppendTextBuffer("*!*WARNING: bPayloadClass is incorrectly using reserved space\r\n"); OOPS(); } else { if (gDoAnnotation) { if(VendorVidFormatDesc->bPayloadClass == 1) { AppendTextBuffer(" -> Using a Frame Based Payload\r\n");} else { AppendTextBuffer(" -> Using a Stream Based Payload\r\n");} } else {AppendTextBuffer("\r\n");} } if (VendorVidFormatDesc->bDefaultFrameIndex == 0 ) { //@@TestCase B28.5 (descript.c line 1312) //@@ERROR //@@Descriptor Field - bDefaultFrameIndex //@@bDefaultFrameIndex is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: bDefaultFrameIndex = 0, this invalidates the descriptor\r\n"); OOPS(); } if (VendorVidFormatDesc->bDefaultFrameIndex == 0 || VendorVidFormatDesc->bDefaultFrameIndex > VendorVidFormatDesc->bNumFrameDescriptors) { //@@TestCase B28.6 //@@WARNING //@@Descriptor Field - bDefaultFrameIndex //@@bDefaultFrameIndex is out of range AppendTextBuffer("*!*WARNING: The value %d for the bDefaultFrameIndex is out of range this invalidates the descriptor\r\n*!* The proper range is 1 to %d)", VendorVidFormatDesc->bDefaultFrameIndex, VendorVidFormatDesc->bNumFrameDescriptors); OOPS(); } //@@TestCase B28.7 //@@Not yet implemented - Priority 1 //@@Descriptor Field - bCopyProtect //@@Question - Are their reserved bits and should we validate that reserved bits are set to zero? // AppendTextBuffer("bCopyProtect: 0x%02X", VendorVidFormatDesc->bCopyProtect); // Check that the correct number of Frame Descriptors and one Color Matching // descriptor follow CheckForColorMatchingDesc ((PVIDEO_SPECIFIC) VendorVidFormatDesc, VendorVidFormatDesc->bNumFrameDescriptors, VS_FRAME_VENDOR); // This descriptor is deprecated for UVC 1.1 #ifdef H264_SUPPORT if (UVC10 != g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC version >= 1.1 devices\r\n"); } #else if (UVC11 == g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.1 devices\r\n"); } #endif return TRUE; } //***************************************************************************** // // DisplayVendorVidFrameType() // //***************************************************************************** BOOL DisplayVendorVidFrameType ( PVIDEO_FRAME_VENDOR VendorVidFrameDesc ) { //@@DisplayVendorVidFrameType -Vendor Video Frame size_t bLength = 0; bLength = SizeOfVideoFrameVendor(VendorVidFrameDesc); AppendTextBuffer("\r\n ===>Video Streaming Vendor Video Frame Type Descriptor<===\r\n"); if (gDoAnnotation) { if(VendorVidFrameDesc->bFrameIndex == g_chVendorFrameDefault) { AppendTextBuffer(" --->This is the Default (optimum) Frame index\r\n"); } } AppendTextBuffer("bLength: 0x%02X\r\n", VendorVidFrameDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VendorVidFrameDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VendorVidFrameDesc->bDescriptorSubtype); AppendTextBuffer("bFrameIndex: 0x%02X\r\n", VendorVidFrameDesc->bFrameIndex); if (VendorVidFrameDesc->bLength != bLength) { //@@TestCase B29.1 (descript.c line 1352) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is less than required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", VendorVidFrameDesc->bLength, bLength); OOPS(); } if (VendorVidFrameDesc->bFrameIndex == 0 ) { //@@TestCase B29.2 (descript.c line 1357) //@@ERROR //@@Descriptor Field - bFrameIndex //@@bFrameIndex is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: bFrameIndex = 0, this is a 1 based index\r\n"); OOPS(); } AppendTextBuffer("bmCapabilities: 0x%02X", VendorVidFrameDesc->bmCapabilities); if(VendorVidFrameDesc->bmCapabilities & 0x01){ if(gDoAnnotation) { AppendTextBuffer(" -> Still Images are supported\r\n");} else {AppendTextBuffer("\r\n");} } else if (VendorVidFrameDesc->bmCapabilities & 0xFF) { //@@TestCase B29.3 //@@WARNING //@@Descriptor Field - bmCapabilities //@@bmCapabilities has a bit using reserved areas that should be set to zero AppendTextBuffer("\r\n*!*WARNING: bmCapabilities is using reserved areas.\r\n"); OOPS(); } else {AppendTextBuffer("\r\n");} AppendTextBuffer("wWidth: 0x%04X = %d\r\n", VendorVidFrameDesc->wWidth, VendorVidFrameDesc->wWidth); AppendTextBuffer("wHeight: 0x%04X = %d\r\n", VendorVidFrameDesc->wHeight, VendorVidFrameDesc->wHeight); AppendTextBuffer("dwMinBitRate: 0x%08X\r\n", VendorVidFrameDesc->dwMinBitRate); AppendTextBuffer("dwMaxBitRate: 0x%08X\r\n", VendorVidFrameDesc->dwMaxBitRate); AppendTextBuffer("dwMaxVideoFrameBufferSize: 0x%08X\r\n", VendorVidFrameDesc->dwMaxVideoFrameBufferSize); // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwDefaultFrameInterval: 0x%08X = %lf mSec (%4.2f Hz)\r\n", VendorVidFrameDesc->dwDefaultFrameInterval, ((double)VendorVidFrameDesc->dwDefaultFrameInterval)/10000.0, (10000000.0/((double)VendorVidFrameDesc->dwDefaultFrameInterval)) ); AppendTextBuffer("bFrameIntervalType: 0x%02X\r\n", VendorVidFrameDesc->bFrameIntervalType); if (VendorVidFrameDesc->wWidth == 0 ) { //@@TestCase B29.4 (descript.c line 1362) //@@ERROR //@@Descriptor Field - wWidth //@@wWidth is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: wWidth must be nonzero\r\n"); OOPS(); } if (VendorVidFrameDesc->wHeight == 0 ) { //@@TestCase B29.5 (descript.c line 1367) //@@ERROR //@@Descriptor Field - wHeight //@@wHeight is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: wHeight must be nonzero\r\n"); OOPS(); } if (VendorVidFrameDesc->dwMinBitRate == 0 ) { //@@TestCase B29.6 (descript.c line 1372) //@@ERROR //@@Descriptor Field - dwMinBitRate //@@dwMinBitRate is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMinBitRate must be nonzero\r\n"); OOPS(); } if (VendorVidFrameDesc->dwMaxBitRate == 0 ) { //@@TestCase B29.7 (descript.c line 1377) //@@ERROR //@@Descriptor Field - dwMaxBitRate //@@dwMaxBitRate is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMaxBitRate must be nonzero\r\n"); OOPS(); } if(VendorVidFrameDesc->dwMinBitRate > VendorVidFrameDesc->dwMaxBitRate) { //@@TestCase B29.8 //@@ERROR //@@Descriptor Field - dwMinBitRate and dwMaxBitRate //@@Verify that dwMaxBitRate is greater than dwMinBitRate AppendTextBuffer("*!*ERROR: dwMinBitRate should be less than dwMaxBitRate\r\n"); OOPS(); } else { if (VendorVidFrameDesc->bFrameIntervalType == 1 && VendorVidFrameDesc->dwMinBitRate != VendorVidFrameDesc->dwMaxBitRate) { //@@TestCase B29.9 //@@WARNING //@@Descriptor Field - bFrameIntervalType, dwMinBitRate, and dwMaxBitRate //@@Verify that dwMaxBitRate is equal to dwMinBitRate if bFrameIntervalType is 1 AppendTextBuffer("*!*WARNING: if bFrameIntervalType is 1 then dwMinBitRate "\ "should equal dwMaxBitRate\r\n"); OOPS(); } } if (VendorVidFrameDesc->dwMaxVideoFrameBufferSize == 0 ) { //@@TestCase B29.10 (descript.c line 1382) //@@WARNING //@@Descriptor Field - dwMaxVideoFrameBufferSize //@@dwMaxVideoFrameBufferSize is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*WARNING: dwMaxVideoFrameBufferSize must be nonzero\r\n"); OOPS(); } if (VendorVidFrameDesc->dwDefaultFrameInterval == 0 ) { //@@TestCase B29.11 (descript.c line 1020) //@@WARNING //@@Descriptor Field - dwDefaultFrameInterval //@@dwDefaultFrameInterval must be nonzero AppendTextBuffer("*!*WARNING: dwDefaultFrameInterval must be nonzero\r\n"); OOPS(); } if (VendorVidFrameDesc->bFrameIntervalType == 0) { DisplayVendorVidContinuousFrameType(VendorVidFrameDesc); } else { DisplayVendorVidDiscreteFrameType(VendorVidFrameDesc); } // This descriptor is deprecated for UVC 1.1 #ifdef H264_SUPPORT if (UVC10 != g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC version >= 1.1 devices\r\n"); } #else if (UVC11 == g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.1 devices\r\n"); } #endif return TRUE; } //***************************************************************************** // // DisplayVendorVidContinuousFrameType() // //***************************************************************************** BOOL DisplayVendorVidContinuousFrameType( PVIDEO_FRAME_VENDOR VContinuousDesc ) { //@@DisplayVendorVidContinuousFrameType -Vendor Video Continuous Frame ULONG dwMinFrameInterval = VContinuousDesc->adwFrameInterval[0]; ULONG dwMaxFrameInterval = VContinuousDesc->adwFrameInterval[1]; ULONG dwFrameIntervalStep = VContinuousDesc->adwFrameInterval[2]; AppendTextBuffer("===>Additional Continuous Frame Type Data\r\n"); // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwMinFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", dwMinFrameInterval, ((double)dwMinFrameInterval)/10000.0, (ULONG)(10000000.0/((double)dwMinFrameInterval) + 0.5)); AppendTextBuffer("dwMaxFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", dwMaxFrameInterval, ((double)dwMaxFrameInterval)/10000.0, (ULONG)(10000000.0/((double)dwMaxFrameInterval) + 0.5)); AppendTextBuffer("dwFrameIntervalStep: 0x%08X\r\n", dwFrameIntervalStep); if (dwMinFrameInterval == 0 ) { //@@TestCase B30.2 (descript.c line 1388) //@@ERROR //@@Descriptor Field - dwMinFrameInterval //@@dwMinFrameInterval is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMinFrameInterval = 0, this invalidates the descriptor\r\n"); OOPS(); } if (dwMaxFrameInterval == 0 ) { //@@TestCase B30.3 (descript.c line 1388) //@@ERROR //@@Descriptor Field - dwMaxFrameInterval //@@dwMaxFrameInterval is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMaxFrameInterval = 0, this invalidates the descriptor\r\n"); OOPS(); } if(dwMinFrameInterval > dwMaxFrameInterval) { //@@TestCase B30.4 (descript.c line 1405) //@@ERROR //@@Descriptor Field - dwMinFrameInterval and dwMaxFrameInterval //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval AppendTextBuffer("*!*ERROR: dwMinFrameInterval is larger that dwMaxFrameInterval, this invalidates the descriptor\r\n"); OOPS(); } else if ((dwMinFrameInterval + dwFrameIntervalStep) > dwMaxFrameInterval) { //@@TestCase B30.5 //@@WARNING //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval combined with dwFrameIntervalStep AppendTextBuffer("*!*WARNING: dwMinFrameInterval + dwFrameIntervalStep is greater than dwMaxFrameInterval, this could cause problems\r\n"); OOPS(); } else if ((dwMaxFrameInterval - dwMinFrameInterval) == 0 ) { //@@TestCase B30.6 //@@CAUTION //@@Descriptor Field - dwFrameIntervalStep //@@Suggestion to use descrite frames if dwFrameIntervalStep is zero AppendTextBuffer("*!*CAUTION: dwFrameIntervalStep equals zero, consider using discrete frames\r\n"); OOPS(); } else if ((dwMaxFrameInterval - dwMinFrameInterval) % dwFrameIntervalStep ) { //@@TestCase B30.7 (descript.c line 1414) //@@ERROR //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that the difference between dwMaxFrameInterval and dwMinFrameInterval is evenly divisible by dwFrameIntervalStep AppendTextBuffer("*!*ERROR: dwMaxFrameInterval minus dwMinFrameInterval is not evenly divisible by dwFrameIntervalStep, this could cause problems\r\n"); OOPS(); } if (dwFrameIntervalStep == 0 && (dwMaxFrameInterval - dwMinFrameInterval)) { //@@TestCase B30.8 (descript.c line 1394) //@@ERROR //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that the dwFrameIntervalStep is not zero if there is a difference between dwMaxFrameInterval and dwMinFrameInterval AppendTextBuffer("*!*ERROR: dwFrameIntervalStep = 0, this invalidates the descriptor when there is a difference between \r\n dwMinFrameInterval and dwMaxFrameInterval\r\n"); OOPS(); } return TRUE; } //***************************************************************************** // // DisplayVendorVidDiscreteFrameType() // //***************************************************************************** BOOL DisplayVendorVidDiscreteFrameType( PVIDEO_FRAME_VENDOR VDiscreteDesc ) { //@@DisplayVendorVidDiscreteFrameType -Vendor Video Discrete Frame UINT iNdex = 1; UINT iCurFrame = 0; ULONG * ulFrameInterval = NULL; AppendTextBuffer("===>Additional Discrete Frame TypeData\r\n"); // There are (VDiscreteDesc->bFrameIntervalType) dwFrameIntervals for (; iNdex <= VDiscreteDesc->bFrameIntervalType; iNdex++, iCurFrame++) { ulFrameInterval = &VDiscreteDesc->adwFrameInterval[iCurFrame]; // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwFrameInterval[%d]: 0x%08X = %lf mSec (%4.2f Hz)\r\n", iNdex, *ulFrameInterval, ((double)*ulFrameInterval)/10000.0, (10000000.0/((double)*ulFrameInterval)) ); if (0 == *ulFrameInterval) { //@@TestCase B31.1 (descript.c line 1061) //@@ERROR //@@Descriptor Field - dwFrameInterval[x] //@@dwFrameInterval[x] must be non-zero AppendTextBuffer("*!*ERROR: dwFrameInterval[%d] must be non-zero\r\n", iNdex); OOPS(); } if ((iNdex > 1)&&(*ulFrameInterval <= VDiscreteDesc->adwFrameInterval[iCurFrame - 1])) { //@@TestCase B31.2 (descript.c line 1067) //@@ERROR //@@Descriptor Field - dwFrameInterval[x] //@@dwFrameInterval[n] must be greater than dwFrameInterval[n - 1] AppendTextBuffer("*!*ERROR: dwFrameInterval[0x%02X] must be "\ "greater than preceding dwFrameInterval[0x%02X]\r\n", iNdex, iNdex - 1); OOPS(); } } return TRUE; } //***************************************************************************** // // DisplayFramePayloadFormat() // //***************************************************************************** BOOL DisplayFramePayloadFormat ( PVIDEO_FORMAT_FRAME FramePayloadFormatDesc ) { //@@DisplayFramePayloadFormat - FrameBased Payload Format PCHAR pStr = NULL; OLECHAR szGUID[256]; int i = 0; // Initialize the default Frame g_chFrameBasedFrameDefault = FramePayloadFormatDesc->bDefaultFrameIndex; memset((LPOLESTR) szGUID, 0, sizeof(OLECHAR) * 256); i = StringFromGUID2((REFGUID) &FramePayloadFormatDesc->guidFormat, (LPOLESTR) szGUID, 255); i++; AppendTextBuffer("\r\n ===>Video Streaming Frame Based Payload Format Type Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X\r\n", FramePayloadFormatDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", FramePayloadFormatDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", FramePayloadFormatDesc->bDescriptorSubtype); AppendTextBuffer("bFormatIndex: 0x%02X\r\n", FramePayloadFormatDesc->bFormatIndex); AppendTextBuffer("bNumFrameDescriptors: 0x%02X\r\n", FramePayloadFormatDesc->bNumFrameDescriptors); AppendTextBuffer("guidFormat: %S", szGUID); pStr = VidFormatGUIDCodeToName((REFGUID) &FramePayloadFormatDesc->guidFormat); if ( pStr ) { if ( gDoAnnotation ) { AppendTextBuffer(" = %s Format", pStr); } } AppendTextBuffer("\r\n"); AppendTextBuffer("bBitsPerPixel: 0x%02X\r\n", FramePayloadFormatDesc->bBitsPerPixel); AppendTextBuffer("bDefaultFrameIndex: 0x%02X\r\n", FramePayloadFormatDesc->bDefaultFrameIndex); if (FramePayloadFormatDesc->bLength != sizeof(VIDEO_FORMAT_FRAME)) { //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required //@@length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", FramePayloadFormatDesc->bLength, sizeof(VIDEO_FORMAT_FRAME)); OOPS(); } if (FramePayloadFormatDesc->bFormatIndex == 0 ) { //@@ERROR //@@Descriptor Field - bFormatIndex //@@bFormatIndex is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: bFormatIndex = 0, this is a 1 based index\r\n"); OOPS(); } if (FramePayloadFormatDesc->bNumFrameDescriptors == 0 ) { //@@ERROR //@@Descriptor Field - bNumFrameDescriptors //@@bNumFrameDescriptors is set to zero which is not in accordance with the //@@USB Video Device Specification AppendTextBuffer("*!*ERROR: bNumFrameDescriptors = 0, must have at least 1 Frame descriptor\r\n"); OOPS(); } if(!(pStr)) { //@@WARNING //@@Descriptor Field - guidFormat //@@guidFormat is set to unknown or undefined format AppendTextBuffer("\r\n*!*WARNING: guidFormat is an unknown format\r\n"); OOPS(); } if (FramePayloadFormatDesc->bBitsPerPixel == 0 ) { //@@ERROR //@@Descriptor Field - bBitsPerPixel //@@bBitsPerPixel is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: bBitsPerPixel = 0, this invalidates the descriptor\r\n"); OOPS(); } if (FramePayloadFormatDesc->bDefaultFrameIndex == 0 || FramePayloadFormatDesc->bDefaultFrameIndex > FramePayloadFormatDesc->bNumFrameDescriptors) { //@@ERROR //@@Descriptor Field - bDefaultFrameIndex //@@The value for bDefaultFrameIndex is not greater than 0 or less than or equal to bNumFrameDescriptors AppendTextBuffer("*!*ERROR: The value %d for the bDefaultFrameIndex is out of range, this invalidates the descriptor\r\n*!*The proper range is 1 to %d)", FramePayloadFormatDesc->bDefaultFrameIndex, FramePayloadFormatDesc->bNumFrameDescriptors); OOPS(); } AppendTextBuffer("bAspectRatioX: 0x%02X\r\n", FramePayloadFormatDesc->bAspectRatioX); AppendTextBuffer("bAspectRatioY: 0x%02X", FramePayloadFormatDesc->bAspectRatioY); if (((FramePayloadFormatDesc->bmInterlaceFlags & 0x01) && (FramePayloadFormatDesc->bAspectRatioY != 0 && FramePayloadFormatDesc->bAspectRatioX != 0))) { if(gDoAnnotation) { AppendTextBuffer(" -> Aspect Ratio is set for a %d:%d display", (FramePayloadFormatDesc->bAspectRatioX),(FramePayloadFormatDesc->bAspectRatioY)); } else { if (FramePayloadFormatDesc->bAspectRatioY != 0 || FramePayloadFormatDesc->bAspectRatioX != 0) { //@@ERROR //@@Descriptor Field - bAspectRatioX, bAspectRatioY //@@Verify that that bAspectRatioX and bAspectRatioY are set to zero //@@ if stream is non-interlaced AppendTextBuffer("\r\n*!*ERROR: Both bAspectRatioX and bAspectRatioY "\ "must equal 0 if stream is non-interlaced"); OOPS(); } } } AppendTextBuffer("\r\nbmInterlaceFlags: 0x%02X\r\n", FramePayloadFormatDesc->bmInterlaceFlags); if (gDoAnnotation) { AppendTextBuffer(" D0 = 0x%02X Interlaced stream or variable: %s\r\n", (FramePayloadFormatDesc->bmInterlaceFlags & 1), (FramePayloadFormatDesc->bmInterlaceFlags & 1) ? "Yes" : "No"); AppendTextBuffer(" D1 = 0x%02X Fields per frame: %s\r\n", ((FramePayloadFormatDesc->bmInterlaceFlags >> 1) & 1), ((FramePayloadFormatDesc->bmInterlaceFlags >> 1) & 1) ? "1 field" : "2 fields"); AppendTextBuffer(" D2 = 0x%02X Field 1 first: %s\r\n", ((FramePayloadFormatDesc->bmInterlaceFlags >> 2) & 1), ((FramePayloadFormatDesc->bmInterlaceFlags >> 2) & 1) ? "Yes" : "No"); //@@Descriptor Field - bmInterlaceFlags //@@Validate that reserved bits (D3) are set to zero. AppendTextBuffer(" D3 = 0x%02X Reserved%s\r\n", ((FramePayloadFormatDesc->bmInterlaceFlags >> 3) & 1), ((FramePayloadFormatDesc->bmInterlaceFlags >> 3) & 1) ? "\r\n*!*ERROR: Reserved to 0" : "" ); AppendTextBuffer(" D4..5 = 0x%02X Field patterns ->", ((FramePayloadFormatDesc->bmInterlaceFlags >> 4) & 3)); switch(FramePayloadFormatDesc->bmInterlaceFlags & 0x30) { case 0x00: AppendTextBuffer(" Field 1 only"); break; case 0x10: AppendTextBuffer(" Field 2 only"); break; case 0x20: AppendTextBuffer(" Regular Pattern of fields 1 and 2"); break; case 0x30: AppendTextBuffer(" Random Pattern of fields 1 and 2"); break; } AppendTextBuffer("\r\n D6..7 = 0x%02X Display Mode ->", ((FramePayloadFormatDesc->bmInterlaceFlags >> 6) & 3)); switch(FramePayloadFormatDesc->bmInterlaceFlags & 0xC0) { case 0x00: AppendTextBuffer(" Bob only"); break; case 0x40: AppendTextBuffer(" Weave only"); break; case 0x80: AppendTextBuffer(" Bob or weave"); break; case 0xC0: //@@Descriptor Field - bmInterlaceFlags //@@Question - Should we validate that reserved bits are set to zero? AppendTextBuffer(" Reserved"); break; } } //@@Descriptor Field - bCopyProtect //@@Question - Are their reserved bits and should we validate that //@@ reserved bits are set to zero? AppendTextBuffer("\r\nbCopyProtect: 0x%02X", FramePayloadFormatDesc->bCopyProtect); if (gDoAnnotation) { if (FramePayloadFormatDesc->bCopyProtect) AppendTextBuffer(" -> Duplication Restricted"); else AppendTextBuffer(" -> Duplication Unrestricted"); } //@@Descriptor Field - bVariableSize AppendTextBuffer("\r\nbVariableSize: 0x%02X", FramePayloadFormatDesc->bVariableSize); if (gDoAnnotation) { if (FramePayloadFormatDesc->bVariableSize) AppendTextBuffer(" -> Variable Size"); else AppendTextBuffer(" -> Fixed Size"); } AppendTextBuffer("\r\n"); // Check that the correct number of Frame Descriptors and one Color Matching // descriptor follow CheckForColorMatchingDesc ((PVIDEO_SPECIFIC) FramePayloadFormatDesc, FramePayloadFormatDesc->bNumFrameDescriptors, VS_FRAME_FRAME_BASED); // This descriptor is new for UVC 1.1 if (UVC10 == g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.0 devices\r\n"); } return TRUE; } //***************************************************************************** // // DisplayFramePayloadFrame() // //***************************************************************************** BOOL DisplayFramePayloadFrame ( PVIDEO_FRAME_FRAME FramePayloadFrameDesc ) { size_t bLength = 0; bLength = SizeOfVideoFrameFrame(FramePayloadFrameDesc); //@@DisplayFramePayloadFrame -Frame Based Payload Frame AppendTextBuffer("\r\n ===>Video Streaming Frame Based Payload Frame Type Descriptor<===\r\n"); if (gDoAnnotation) { if(FramePayloadFrameDesc->bFrameIndex == g_chFrameBasedFrameDefault) { AppendTextBuffer(" --->This is the Default (optimum) Frame index\r\n"); } } AppendTextBuffer("bLength: 0x%02X\r\n", FramePayloadFrameDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", FramePayloadFrameDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", FramePayloadFrameDesc->bDescriptorSubtype); AppendTextBuffer("bFrameIndex: 0x%02X\r\n", FramePayloadFrameDesc->bFrameIndex); AppendTextBuffer("bmCapabilities: 0x%02X\r\n", FramePayloadFrameDesc->bmCapabilities); AppendTextBuffer("wWidth: 0x%04X = %d\r\n", FramePayloadFrameDesc->wWidth, FramePayloadFrameDesc->wWidth); AppendTextBuffer("wHeight: 0x%04X = %d\r\n", FramePayloadFrameDesc->wHeight, FramePayloadFrameDesc->wHeight); AppendTextBuffer("dwMinBitRate: 0x%08X\r\n", FramePayloadFrameDesc->dwMinBitRate); AppendTextBuffer("dwMaxBitRate: 0x%08X\r\n", FramePayloadFrameDesc->dwMaxBitRate); // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwDefaultFrameInterval: 0x%08X = %lf mSec (%4.2f Hz)\r\n", FramePayloadFrameDesc->dwDefaultFrameInterval, ((double)FramePayloadFrameDesc->dwDefaultFrameInterval)/10000.0, (10000000.0/((double)FramePayloadFrameDesc->dwDefaultFrameInterval)) ); AppendTextBuffer("bFrameIntervalType: 0x%02X\r\n", FramePayloadFrameDesc->bFrameIntervalType); if (FramePayloadFrameDesc->bLength != bLength) { //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required //@@length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d\r\n", FramePayloadFrameDesc->bLength, bLength); OOPS(); } if (FramePayloadFrameDesc->bFrameIndex == 0 ) { //@@ERROR //@@Descriptor Field - bFrameIndex //@@bFrameIndex must be nonzero AppendTextBuffer("*!*ERROR: bFrameIndex = 0, this is a 1 based index\r\n"); OOPS(); } //@@Descriptor Field - bmCapabilities //@@Question: Should we try to verify that bmCapabilities is valid? // AppendTextBuffer("bmCapabilities: 0x%02X\r\n", UnCompFrameDesc->bmCapabilities); if (FramePayloadFrameDesc->wWidth == 0 ) { //@@ERROR //@@Descriptor Field - wWidth //@@wWidth must be nonzero AppendTextBuffer("*!*ERROR: wWidth must be nonzero\r\n"); OOPS(); } if (FramePayloadFrameDesc->wHeight == 0 ) { //@@ERROR //@@Descriptor Field - wHeight //@@wHeight must be nonzero AppendTextBuffer("*!*ERROR: wHeight must be nonzero\r\n"); OOPS(); } if (FramePayloadFrameDesc->dwMinBitRate == 0 ) { //@@ERROR //@@Descriptor Field - dwMinBitRate //@@dwMinBitRate must be nonzero AppendTextBuffer("*!*ERROR: dwMinBitRate must be nonzero\r\n"); OOPS(); } if (FramePayloadFrameDesc->dwMaxBitRate == 0 ) { //@@ERROR //@@Descriptor Field - dwMaxBitRate //@@dwMaxBitRate must be nonzero AppendTextBuffer("*!*ERROR: dwMaxBitRate must be nonzero\r\n"); OOPS(); } if(FramePayloadFrameDesc->dwMinBitRate > FramePayloadFrameDesc->dwMaxBitRate) { //@@ERROR //@@Descriptor Field - dwMinBitRate and dwMaxBitRate //@@Verify that dwMaxBitRate is greater than dwMinBitRate AppendTextBuffer("*!*ERROR: dwMinBitRate should be less than dwMaxBitRate\r\n"); OOPS(); } else { if (FramePayloadFrameDesc->bFrameIntervalType == 1 && FramePayloadFrameDesc->dwMinBitRate != FramePayloadFrameDesc->dwMaxBitRate) { //@@WARNING //@@Descriptor Field - bFrameIntervalType, dwMinBitRate, and dwMaxBitRate //@@Verify that dwMaxBitRate is equal to dwMinBitRate if bFrameIntervalType is 1 AppendTextBuffer("*!*WARNING: if bFrameIntervalType is 1 then dwMinBitRate "\ "should equal dwMaxBitRate\r\n"); OOPS(); } } if (FramePayloadFrameDesc->dwDefaultFrameInterval == 0 ) { //@@TestCase B16.11 (descript.c line 1020) //@@WARNING //@@Descriptor Field - dwDefaultFrameInterval //@@dwDefaultFrameInterval must be nonzero AppendTextBuffer("*!*WARNING: dwDefaultFrameInterval must be nonzero\r\n"); OOPS(); } if (0 == FramePayloadFrameDesc->bFrameIntervalType) { DisplayFramePayloadContinuousFrameType(FramePayloadFrameDesc); } else { DisplayFramePayloadDiscreteFrameType(FramePayloadFrameDesc); } // This descriptor is new for UVC 1.1 if (UVC10 == g_chUVCversion) { AppendTextBuffer("*!*ERROR: This format is NOT ALLOWED for UVC 1.0 devices\r\n"); } return TRUE; } //***************************************************************************** // // DisplayFramePayloadContinuousFrameType() // //***************************************************************************** BOOL DisplayFramePayloadContinuousFrameType( PVIDEO_FRAME_FRAME FContinuousDesc ) { //@@DisplayFramePayloadContinuousFrameType -Frame Payload Continuous Frame ULONG dwMinFrameInterval = FContinuousDesc->adwFrameInterval[0]; ULONG dwMaxFrameInterval = FContinuousDesc->adwFrameInterval[1]; ULONG dwFrameIntervalStep = FContinuousDesc->adwFrameInterval[2]; AppendTextBuffer("===>Additional Continuous Frame Type Data\r\n"); // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwMinFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", dwMinFrameInterval, ((double)dwMinFrameInterval)/10000.0, (ULONG)(10000000.0/((double)dwMinFrameInterval) + 0.5)); AppendTextBuffer("dwMaxFrameInterval: 0x%08X = %lf mSec (%d Hz)\r\n", dwMaxFrameInterval, ((double)dwMaxFrameInterval)/10000.0, (ULONG)(10000000.0/((double)dwMaxFrameInterval) + 0.5)); AppendTextBuffer("dwFrameIntervalStep: 0x%08X\r\n", dwFrameIntervalStep); if (dwMinFrameInterval == 0 ) { //@@ERROR //@@Descriptor Field - dwMinFrameInterval //@@dwMinFrameInterval is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMinFrameInterval = 0, this invalidates the descriptor\r\n"); OOPS(); } if (dwMaxFrameInterval == 0 ) { //@@ERROR //@@Descriptor Field - dwMaxFrameInterval //@@dwMaxFrameInterval is set to zero which is not in accordance with the USB Video Device Specification AppendTextBuffer("*!*ERROR: dwMaxFrameInterval = 0, this invalidates the descriptor\r\n"); OOPS(); } if(dwMinFrameInterval > dwMaxFrameInterval) { //@@ERROR //@@Descriptor Field - dwMinFrameInterval and dwMaxFrameInterval //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval AppendTextBuffer("*!*ERROR: dwMinFrameInterval is larger that dwMaxFrameInterval, this invalidates the descriptor\r\n"); OOPS(); } else if ((dwMinFrameInterval + dwFrameIntervalStep) > dwMaxFrameInterval) { //@@WARNING //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that dwMaxFrameInterval is greater than dwMinFrameInterval combined with dwFrameIntervalStep AppendTextBuffer("*!*WARNING: dwMinFrameInterval + dwFrameIntervalStep is greater than dwMaxFrameInterval, this could cause problems\r\n"); OOPS(); } else if ((dwMaxFrameInterval - dwMinFrameInterval) == 0 ) { //@@CAUTION //@@Descriptor Field - dwFrameIntervalStep //@@Suggestion to use descrite frames if dwFrameIntervalStep is zero AppendTextBuffer("*!*CAUTION: dwFrameIntervalStep equals zero, consider using discrete frames\r\n"); OOPS(); } else if ((dwMaxFrameInterval - dwMinFrameInterval) % dwFrameIntervalStep ) { //@@WARNING //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that the difference between dwMaxFrameInterval and dwMinFrameInterval is evenly divisible by dwFrameIntervalStep AppendTextBuffer("*!*WARNING: dwMaxFrameInterval minus dwMinFrameInterval is not evenly divisible by dwFrameIntervalStep, this could cause problems\r\n"); OOPS(); } if (dwFrameIntervalStep == 0 && (dwMaxFrameInterval - dwMinFrameInterval)) { //@@WARNING //@@Descriptor Field - dwFrameIntervalStep, dwMinFrameInterval, and dwMaxFrameInterval //@@Verify that the dwFrameIntervalStep is not zero if there is a difference between dwMaxFrameInterval and dwMinFrameInterval AppendTextBuffer("*!*WARNING: dwFrameIntervalStep = 0, this invalidates the descriptor when there is a difference between dwMinFrameInterval and dwMaxFrameInterval\r\n"); OOPS(); } return TRUE; } //***************************************************************************** // // DisplayFramePayloadDiscreteFrameType() // //***************************************************************************** BOOL DisplayFramePayloadDiscreteFrameType( PVIDEO_FRAME_FRAME FDiscreteDesc ) { //@@DisplayFramePayloadDiscreteFrameType -Frame Based Payload Discrete Frame UINT iNdex = 1; UINT iCurFrame = 0; ULONG * ulFrameInterval = NULL; AppendTextBuffer("===>Additional Discrete Frame Type Data\r\n"); // There are (UDiscreteDesc->bFrameIntervalType) dwFrameIntervals (1 based index) for (; iNdex <= FDiscreteDesc->bFrameIntervalType; iNdex++, iCurFrame++) { ulFrameInterval = &FDiscreteDesc->adwFrameInterval[iCurFrame]; // To convert the default frame interval, which is in 100 ns units, to milliseconds, we divide by 10,000. // 100 ns = 10^(-7) seconds = 10^(-7) sec * 1000 msec/sec = 10^(-7) * 10^3 milleseconds = 10^(-4) seconds // = 1/10,000 milliseconds // To convert the frame interval to Hz, we divide by 10,000,000 and then take the inverse AppendTextBuffer("dwFrameInterval[%d]: 0x%08X = %lf mSec (%4.2f Hz)\r\n", iNdex, *ulFrameInterval, ((double)*ulFrameInterval)/10000.0, (10000000.0/((double)*ulFrameInterval)) ); if (0 == *ulFrameInterval) { //@@TestCase B18.1 (descript.c line 1061) //@@ERROR //@@Descriptor Field - dwFrameInterval[x] //@@dwFrameInterval[x] must be non-zero AppendTextBuffer("*!*ERROR: dwFrameInterval[%d] must be non-zero\r\n", iNdex); OOPS(); } if ((iNdex > 1)&&(*ulFrameInterval <= FDiscreteDesc->adwFrameInterval[iCurFrame - 1])) { //@@TestCase B18.2 (descript.c line 1067) //@@ERROR //@@Descriptor Field - dwFrameInterval[x] //@@dwFrameInterval[n] must be greater than dwFrameInterval[n - 1] AppendTextBuffer("*!*ERROR: dwFrameInterval[0x%02X] must be "\ "greater than preceding dwFrameInterval[0x%02X]\r\n", iNdex, iNdex - 1); OOPS(); } } return TRUE; } //***************************************************************************** // // DisplayVSEndpoint() // //***************************************************************************** BOOL DisplayVSEndpoint ( PVIDEO_CS_INTERRUPT VidEndpointDesc ) { //@@DisplayVSEndpoint - Video Streaming Endpoint AppendTextBuffer("\r\n ===>Class-specific VC Interrupt Endpoint Descriptor<===\r\n"); AppendTextBuffer("bLength: 0x%02X \r\n", VidEndpointDesc->bLength); AppendTextBuffer("bDescriptorType: 0x%02X\r\n", VidEndpointDesc->bDescriptorType); AppendTextBuffer("bDescriptorSubtype: 0x%02X\r\n", VidEndpointDesc->bDescriptorSubtype); AppendTextBuffer("wMaxTransferSize: 0x%04X", VidEndpointDesc->wMaxTransferSize); if(gDoAnnotation) { AppendTextBuffer(" = (%d) Bytes\r\n", VidEndpointDesc->wMaxTransferSize);} else {AppendTextBuffer("\r\n");} if (VidEndpointDesc->bLength != sizeof(VIDEO_CS_INTERRUPT)) { //@@TestCase B32.1 (descript.c line 1616) //@@ERROR //@@Descriptor Field - bLength //@@The declared length in the device descriptor is not equal to the required length in the USB Video Device Specification AppendTextBuffer("*!*ERROR: bLength of %d incorrect, should be %d. USBView cannot correctly display descriptor\r\n", VidEndpointDesc->bLength, sizeof(VIDEO_CS_INTERRUPT)); OOPS(); } return TRUE; } //***************************************************************************** // // VDisplayBytes() // //***************************************************************************** VOID VDisplayBytes ( PUCHAR Data, USHORT Len ) { USHORT i = 0; for (i = 0; i < Len; i++) { AppendTextBuffer("0x%02X ", Data[i]); if (i % 16 == 15) { AppendTextBuffer("\r\n"); } } if (i % 16 != 0) { AppendTextBuffer("\r\n"); } } //***************************************************************************** // // VidFormatGUIDCodeToName() // //***************************************************************************** PCHAR VidFormatGUIDCodeToName ( REFGUID VidFormatGUIDCode ) { // GUID pYUY2 = YUY2_Format; // GUID pNV12 = NV12_Format; if (IsEqualGUID(VidFormatGUIDCode, (REFGUID) &YUY2_Format)) { return (PCHAR) &"YUY2"; } if (IsEqualGUID(VidFormatGUIDCode, (REFGUID) &NV12_Format)) { return (PCHAR) &"NV12"; } #ifdef H264_SUPPORT // GUID pH264 = H264_Format; if (IsEqualGUID(VidFormatGUIDCode, (REFGUID) &H264_Format)) { return (PCHAR) &"H.264"; } #endif return FALSE; } /***************************************************************************** GetVCInterfaceSize() *****************************************************************************/ UINT GetVCInterfaceSize ( PVIDEO_CONTROL_HEADER_UNIT VCInterfaceDesc ) { PUSB_COMMON_DESCRIPTOR commonDesc = (PUSB_COMMON_DESCRIPTOR) VCInterfaceDesc; PUCHAR descEnd = (PUCHAR) VCInterfaceDesc + VCInterfaceDesc->wTotalLength; UINT uCount = 0; // return this interface's sum of descriptor lengths // starting from this header until (and not including) the first endpoint while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd && (PUCHAR)commonDesc + commonDesc->bLength <= descEnd) { if (commonDesc->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) break; uCount += commonDesc->bLength; commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); } return (uCount); } /***************************************************************************** CheckForColorMatchingDesc () Given starting address of format descriptor; number of frame descriptors; subtype of frame to look for; 1) walk through each descriptor = if desc is frame of given subtype, update counter = if desc is still frame, update counter = if desc is color matching descriptor, update counter ! if frame is something else, break (all these frames should be consecutive) ! if next frame is beyond ending address of configuration, break PASS frame count == numframes passed in color match == 1 still frames are handled in the video stream input header and the frame displays *****************************************************************************/ UINT CheckForColorMatchingDesc ( PVIDEO_SPECIFIC pFormatDesc, UCHAR bNumFrameDescriptors, UCHAR bDescriptorSubtype ) { UINT uFrameCount = 0; UINT uStillFrameCount = 0; UINT uColorCount = 0; // DONE if the descriptor address is beyond the configuration range for ( ; ValidateDescAddress ((PUSB_COMMON_DESCRIPTOR) pFormatDesc); ) { // DONE if it's not an interface desc if (CS_INTERFACE != pFormatDesc->bDescriptorType) { break; } switch (pFormatDesc->bDescriptorSubtype) { case VS_STILL_IMAGE_FRAME: uStillFrameCount++; break; case VS_COLORFORMAT: uColorCount++; break; default: if (bDescriptorSubtype == pFormatDesc->bDescriptorSubtype) { uFrameCount++; } break; } pFormatDesc = (PVIDEO_SPECIFIC) ((PUCHAR) pFormatDesc + pFormatDesc->bLength); } if (uFrameCount != bNumFrameDescriptors) { AppendTextBuffer("*!*ERROR: Found %d frame descriptors (should be %d)\r\n", uFrameCount, bNumFrameDescriptors); } // We already check Still Frames in the Video Info Header and Still Frames displays if (0 == uColorCount) { AppendTextBuffer("*!*ERROR: no Color Matching Descriptor for this format\r\n"); } return (uColorCount); } /***************************************************************************** GetVSInterfaceSize() *****************************************************************************/ UINT GetVSInterfaceSize ( PUSB_COMMON_DESCRIPTOR VidInHeaderDesc, USHORT wTotalLength ) { PUSB_COMMON_DESCRIPTOR commonDesc = (PUSB_COMMON_DESCRIPTOR) VidInHeaderDesc; PUCHAR descEnd = (PUCHAR) VidInHeaderDesc + wTotalLength; UINT uCount = 0; // return this interface's sum of descriptor lengths // starting from this header until (and not including) the first endpoint while ((PUCHAR)commonDesc + sizeof(USB_COMMON_DESCRIPTOR) < descEnd && (PUCHAR)commonDesc + commonDesc->bLength <= descEnd) { if (commonDesc->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) break; uCount += commonDesc->bLength; commonDesc = (PUSB_COMMON_DESCRIPTOR) ((PUCHAR) commonDesc + commonDesc->bLength); } return (uCount); } /***************************************************************************** ValidateTerminalID() *****************************************************************************/ BOOL ValidateTerminalID( UINT uTerminalID ) { UNREFERENCED_PARAMETER(uTerminalID); return (TRUE); }
Our Services
-
What our customers say about us?
Read our customer testimonials to find out why our clients keep returning for their projects.
View Testimonials