/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Sets the transform information panel on the control /// </summary> /// <param name="transformToDisplay">the transform to display</param> /// <history> /// 01 Nov 18 Cynic - Started /// </history> private void SetTransformInfoPanel(TantaMFTCapabilityContainer transformToDisplay) { List <IMFMediaType> outputTypes = null; List <IMFMediaType> inputTypes = null; StringBuilder displaySb = new StringBuilder(); StringBuilder outputSb = new StringBuilder(); StringBuilder inputSb = new StringBuilder(); StringBuilder headerSb = new StringBuilder(); StringBuilder outSb; HResult hr; // clear it down ClearTransformInfoPanel(); if (transformToDisplay == null) { return; } // set up our header information headerSb.Append(transformToDisplay.TransformFriendlyName); headerSb.Append("\r\n"); headerSb.Append(transformToDisplay.TransformGuidValueAsString); headerSb.Append("\r\n"); if (transformToDisplay.IsAsyncMFT == "x") { headerSb.Append("IsAsyncMFT" + ", "); } if (transformToDisplay.IsSyncMFT == "x") { headerSb.Append("IsSyncMFT" + ", "); } if (transformToDisplay.IsFieldOfUse == "x") { headerSb.Append("IsFieldOfUse" + ", "); } // we do not include these, the enum function does not give us this // if (transformToDisplay.IsHardware == "x") headerSb.Append("IsHardware" + ", "); // if (transformToDisplay.IsLocalMFT == "x") headerSb.Append("IsLocalMFT" + ", "); // if (transformToDisplay.IsTranscodeOnly == "x") headerSb.Append("IsTranscodeOnly" + ", "); headerSb.Append("\r\n"); try { // populate the RichText box with the input media type capabilities inputTypes = TantaWMFUtils.GetInputMediaTypesFromTransformByGuid(transformToDisplay.TransformGuidValue, false); // do we have any input types? if ((inputTypes != null) && (inputTypes.Count != 0)) { // go through the types foreach (IMFMediaType mediaType in inputTypes) { // the major media type hr = TantaMediaTypeInfo.GetMediaMajorTypeAsText(mediaType, out outSb); if (hr != HResult.S_OK) { continue; } if (outSb == null) { continue; } inputSb.Append(outSb); inputSb.Append("\r\n"); // the sub media type hr = TantaMediaTypeInfo.GetMediaSubTypeAsText(mediaType, out outSb); if (hr != HResult.S_OK) { continue; } if (outSb == null) { continue; } inputSb.Append(outSb); inputSb.Append("\r\n"); // enumerate all of the possible Attributes so we can see which ones are present that we did not report on StringBuilder allAttrs = new StringBuilder(); hr = TantaMediaTypeInfo.EnumerateAllAttributeNamesInMediaTypeAsText(mediaType, true, true, TantaWMFUtils.MAX_TYPES_TESTED_PER_TRANSFORM, out allAttrs); if (hr != HResult.S_OK) { continue; } char[] charsToTrim = { ',', '.', ' ' }; inputSb.Append("OtherAttrs=" + allAttrs.ToString().TrimEnd(charsToTrim)); inputSb.Append("\r\n"); inputSb.Append("\r\n"); } } } finally { // release the list of media type objects if ((inputTypes != null) && (inputTypes.Count != 0)) { foreach (IMFMediaType mediaType in inputTypes) { Marshal.ReleaseComObject(mediaType); } } } try { // populate the RichText box with the output media type capabilities outputTypes = TantaWMFUtils.GetOutputMediaTypesFromTransformByGuid(transformToDisplay.TransformGuidValue, false); // do we have any output types? if ((outputTypes != null) && (outputTypes.Count != 0)) { // go through the types foreach (IMFMediaType mediaType in outputTypes) { // the major media type hr = TantaMediaTypeInfo.GetMediaMajorTypeAsText(mediaType, out outSb); if (hr != HResult.S_OK) { continue; } if (outSb == null) { continue; } outputSb.Append(outSb); outputSb.Append("\r\n"); // the sub media type hr = TantaMediaTypeInfo.GetMediaSubTypeAsText(mediaType, out outSb); if (hr != HResult.S_OK) { continue; } if (outSb == null) { continue; } outputSb.Append(outSb); outputSb.Append("\r\n"); // enumerate all of the possible Attributes so we can see which ones are present that we did not report on StringBuilder allAttrs = new StringBuilder(); hr = TantaMediaTypeInfo.EnumerateAllAttributeNamesInMediaTypeAsText(mediaType, true, true, TantaWMFUtils.MAX_TYPES_TESTED_PER_TRANSFORM, out allAttrs); if (hr != HResult.S_OK) { continue; } char[] charsToTrim = { ',', '.', ' ' }; outputSb.Append("OtherAttrs=" + allAttrs.ToString().TrimEnd(charsToTrim)); outputSb.Append("\r\n"); outputSb.Append("\r\n"); } } } finally { // release the list of media type objects if ((outputTypes != null) && (outputTypes.Count != 0)) { foreach (IMFMediaType mediaType in outputTypes) { Marshal.ReleaseComObject(mediaType); } } } // display what we have displaySb.Append(headerSb); displaySb.Append("\r\n"); displaySb.Append("\r\n"); displaySb.Append("####\r\n"); displaySb.Append("#### INPUT TYPES\r\n"); displaySb.Append("####\r\n"); displaySb.Append("\r\n"); if (inputSb.Length > 0) { displaySb.Append(inputSb); } else { displaySb.Append("<not known>"); displaySb.Append("\r\n"); } displaySb.Append("\r\n"); displaySb.Append("####\r\n"); displaySb.Append("#### OUTPUT TYPES\r\n"); displaySb.Append("####\r\n"); displaySb.Append("\r\n"); if (outputSb.Length > 0) { displaySb.Append(outputSb); } else { displaySb.Append("<not known>"); displaySb.Append("\r\n"); } displaySb.Append("\r\n"); richTextBoxtTransformDetails.Text = displaySb.ToString(); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Displays the video formats for the currently selected video device. This /// is more complicated than it looks. We have to open the video source, convert /// that to a Media Source and then interrogate the that source to find a list /// of video formats. /// </summary> /// <history> /// 01 Nov 18 Cynic - Started /// </history> private void DisplayVideoFormatsForCurrentCaptureDevice() { IMFSourceReaderAsync tmpSourceReader = null; List <TantaMFVideoFormatContainer> formatList; HResult hr; try { // clear what we have now listViewSupportedFormats.Clear(); // reset this listViewSupportedFormats.ListViewItemSorter = null; // get the currently selected device TantaMFDevice currentDevice = (TantaMFDevice)comboBoxCaptureDevices.SelectedItem; if (currentDevice == null) { return; } // open up the media source tmpSourceReader = TantaWMFUtils.CreateSourceReaderAsyncFromDevice(currentDevice, null); if (tmpSourceReader == null) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice, CreateSourceReaderAsyncFromDevice did not return a media source. Cannot continue."); } // now get a list of all supported formats from the video device hr = TantaMediaTypeInfo.GetSupportedVideoFormatsFromSourceReaderInFormatContainers(currentDevice, tmpSourceReader, 100, out formatList); if (hr != HResult.S_OK) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice, GetSupportedVideoFormatsFromSourceReaderInFormatContainers failed. HR=" + hr.ToString()); } if (formatList == null) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice, GetSupportedVideoFormatsFromSourceReaderInFormatContainers did not return a format list. Cannot continue."); } // now display the formats foreach (TantaMFVideoFormatContainer videoFormat in formatList) { ListViewItem lvi = new ListViewItem(new[] { videoFormat.SubTypeAsString, videoFormat.FrameSizeAsString, videoFormat.FrameRateAsString, videoFormat.FrameRateMaxAsString, videoFormat.AllAttributes }); lvi.Tag = videoFormat; listViewSupportedFormats.Items.Add(lvi); } listViewSupportedFormats.Columns.Add("Type", 70); listViewSupportedFormats.Columns.Add("FrameSize WxH", 100); listViewSupportedFormats.Columns.Add("FrameRate f/s", 100); listViewSupportedFormats.Columns.Add("FrameRateMax f/s", 100); listViewSupportedFormats.Columns.Add("All Attributes", 2500); } finally { if (tmpSourceReader != null) { // close and release Marshal.ReleaseComObject(tmpSourceReader); tmpSourceReader = null; } } }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Displays the video formats for the currently selected video device. This /// is more complicated than it looks. We have to open the video source, convert /// that to a Media Source and then interrogate the that source to find a list /// of video formats. /// /// NOTE: this function will throw exceptions - caller must trap them /// </summary> /// <history> /// 01 Nov 18 Cynic - Started /// </history> private void DisplayVideoFormatsForCurrentCaptureDevice() { IMFPresentationDescriptor sourcePresentationDescriptor = null; int sourceStreamCount = 0; bool streamIsSelected = false; IMFStreamDescriptor videoStreamDescriptor = null; IMFMediaTypeHandler typeHandler = null; int mediaTypeCount = 0; List <TantaMFVideoFormatContainer> formatList = new List <TantaMFVideoFormatContainer>(); HResult hr; IMFMediaSource mediaSource = null; try { // clear what we have now listViewSupportedFormats.Clear(); // reset this listViewSupportedFormats.ListViewItemSorter = null; // get the currently selected device TantaMFDevice currentDevice = (TantaMFDevice)comboBoxCaptureDevices.SelectedItem; if (currentDevice == null) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice currentDevice == null"); } // use the device symbolic name to create the media source for the video device. Media sources are objects that generate media data. // For example, the data might come from a video file, a network stream, or a hardware device, such as a camera. Each // media source contains one or more streams, and each stream delivers data of one type, such as audio or video. mediaSource = TantaWMFUtils.GetMediaSourceFromTantaDevice(currentDevice); if (mediaSource == null) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to mediaSource == null"); } // A presentation is a set of related media streams that share a common presentation time. // we don't need that functionality in this app but we do need to presentation descriptor // to find out the stream descriptors, these will give us the media types on offer hr = mediaSource.CreatePresentationDescriptor(out sourcePresentationDescriptor); if (hr != HResult.S_OK) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to mediaSource.CreatePresentationDescriptor failed. Err=" + hr.ToString()); } if (sourcePresentationDescriptor == null) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to mediaSource.CreatePresentationDescriptor failed. sourcePresentationDescriptor == null"); } // Now we get the number of stream descriptors in the presentation. // A presentation descriptor contains a list of one or more // stream descriptors. hr = sourcePresentationDescriptor.GetStreamDescriptorCount(out sourceStreamCount); if (hr != HResult.S_OK) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to sourcePresentationDescriptor.GetStreamDescriptorCount failed. Err=" + hr.ToString()); } if (sourceStreamCount == 0) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to sourcePresentationDescriptor.GetStreamDescriptorCount failed. sourceStreamCount == 0"); } // look for the video stream for (int i = 0; i < sourceStreamCount; i++) { // we require the major type to be video Guid guidMajorType = TantaWMFUtils.GetMajorMediaTypeFromPresentationDescriptor(sourcePresentationDescriptor, i); if (guidMajorType != MFMediaType.Video) { continue; } // we also require the stream to be enabled hr = sourcePresentationDescriptor.GetStreamDescriptorByIndex(i, out streamIsSelected, out videoStreamDescriptor); if (hr != HResult.S_OK) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to sourcePresentationDescriptor.GetStreamDescriptorByIndex(v) failed. Err=" + hr.ToString()); } if (videoStreamDescriptor == null) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to sourcePresentationDescriptor.GetStreamDescriptorByIndex(v) failed. videoStreamDescriptor == null"); } // if the stream is not selected (enabled) look for the next if (streamIsSelected == false) { Marshal.ReleaseComObject(videoStreamDescriptor); videoStreamDescriptor = null; continue; } // Get the media type handler for the stream. IMFMediaTypeHandler // interface is a standard way of looking at the media types on an stream hr = videoStreamDescriptor.GetMediaTypeHandler(out typeHandler); if (hr != HResult.S_OK) { throw new Exception("call to videoStreamDescriptor.GetMediaTypeHandler failed. Err=" + hr.ToString()); } if (typeHandler == null) { throw new Exception("call to videoStreamDescriptor.GetMediaTypeHandler failed. typeHandler == null"); } // Now we get the number of media types in the stream descriptor. hr = typeHandler.GetMediaTypeCount(out mediaTypeCount); if (hr != HResult.S_OK) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to typeHandler.GetMediaTypeCount failed. Err=" + hr.ToString()); } if (mediaTypeCount == 0) { throw new Exception("DisplayVideoFormatsForCurrentCaptureDevice call to typeHandler.GetMediaTypeCount failed. mediaTypeCount == 0"); } // now loop through each media type for (int mediaTypeId = 0; mediaTypeId < mediaTypeCount; mediaTypeId++) { // Now we have the handler, get the media type. IMFMediaType workingMediaType = null; hr = typeHandler.GetMediaTypeByIndex(mediaTypeId, out workingMediaType); if (hr != HResult.S_OK) { throw new Exception("GetMediaTypeFromStreamDescriptorById call to typeHandler.GetMediaTypeByIndex failed. Err=" + hr.ToString()); } if (workingMediaType == null) { throw new Exception("GetMediaTypeFromStreamDescriptorById call to typeHandler.GetMediaTypeByIndex failed. workingMediaType == null"); } TantaMFVideoFormatContainer tmpContainer = TantaMediaTypeInfo.GetVideoFormatContainerFromMediaTypeObject(workingMediaType, currentDevice); if (tmpContainer == null) { // we failed throw new Exception("GetSupportedVideoFormatsFromSourceReaderInFormatContainers failed on call to GetVideoFormatContainerFromMediaTypeObject"); } // now add it formatList.Add(tmpContainer); Marshal.ReleaseComObject(workingMediaType); workingMediaType = null; } // NOTE: we only do the first enabled video stream we find. // it is possible to have more but our control // cannot cope with that break; } // now display the formats foreach (TantaMFVideoFormatContainer videoFormat in formatList) { ListViewItem lvi = new ListViewItem(new[] { videoFormat.SubTypeAsString, videoFormat.FrameSizeAsString, videoFormat.FrameRateAsString, videoFormat.FrameRateMaxAsString, videoFormat.AllAttributes }); lvi.Tag = videoFormat; listViewSupportedFormats.Items.Add(lvi); } listViewSupportedFormats.Columns.Add("Type", 70); listViewSupportedFormats.Columns.Add("FrameSize WxH", 100); listViewSupportedFormats.Columns.Add("FrameRate f/s", 100); listViewSupportedFormats.Columns.Add("FrameRateMax f/s", 100); listViewSupportedFormats.Columns.Add("All Attributes", 2500); } finally { // close and release if (mediaSource != null) { Marshal.ReleaseComObject(mediaSource); mediaSource = null; } if (sourcePresentationDescriptor != null) { Marshal.ReleaseComObject(sourcePresentationDescriptor); sourcePresentationDescriptor = null; } if (videoStreamDescriptor != null) { Marshal.ReleaseComObject(videoStreamDescriptor); videoStreamDescriptor = null; } if (typeHandler != null) { Marshal.ReleaseComObject(typeHandler); typeHandler = null; } } }