private static int[] GetPCMOutputNumbers(IWMSyncReader Reader, uint OutputNumber) { var result = new ArrayList(); uint formatCount = 0; Reader.GetOutputFormatCount(OutputNumber, out formatCount); int bufferSize = Marshal.SizeOf(typeof(WM_MEDIA_TYPE)) + Marshal.SizeOf(typeof(WaveFormat)); IntPtr buffer = Marshal.AllocCoTaskMem(bufferSize); try { for (int i = 0; i < formatCount; i++) { IWMOutputMediaProps props = null; uint size = 0; Reader.GetOutputFormat(OutputNumber, (uint)i, out props); props.GetMediaType(IntPtr.Zero, ref size); if ((int)size > bufferSize) { bufferSize = (int)size; Marshal.FreeCoTaskMem(buffer); buffer = Marshal.AllocCoTaskMem(bufferSize); } props.GetMediaType(buffer, ref size); var mt = (WM_MEDIA_TYPE)Marshal.PtrToStructure(buffer, typeof(WM_MEDIA_TYPE)); if ((mt.majortype == MediaTypes.WMMEDIATYPE_Audio) && (mt.subtype == MediaTypes.WMMEDIASUBTYPE_PCM) && (mt.formattype == MediaTypes.WMFORMAT_WaveFormatEx) && (mt.cbFormat >= WAVE_FORMAT_EX_SIZE)) { result.Add(i); } } } finally { Marshal.FreeCoTaskMem(buffer); } return((int[])result.ToArray(typeof(int))); }
private void Init(WaveFormat OutputFormat) { m_OutputNumber = GetAudioOutputNumber(m_Reader); if (m_OutputNumber == InvalidOuput) { throw new ArgumentException("An audio stream was not found"); } int[] FormatIndexes = GetPCMOutputNumbers(m_Reader, (uint)m_OutputNumber); if (FormatIndexes.Length == 0) { throw new ArgumentException("An audio stream was not found"); } if (OutputFormat != null) { m_OutputFormatNumber = -1; for (int i = 0; i < FormatIndexes.Length; i++) { WaveFormat fmt = GetOutputFormat(m_Reader, (uint)m_OutputNumber, (uint)FormatIndexes[i]); if ((fmt.wFormatTag == OutputFormat.wFormatTag) && (fmt.nAvgBytesPerSec == OutputFormat.nAvgBytesPerSec) && (fmt.nBlockAlign == OutputFormat.nBlockAlign) && (fmt.nChannels == OutputFormat.nChannels) && (fmt.nSamplesPerSec == OutputFormat.nSamplesPerSec) && (fmt.wBitsPerSample == OutputFormat.wBitsPerSample)) { m_OutputFormatNumber = FormatIndexes[i]; m_OutputFormat = fmt; break; } } if (m_OutputFormatNumber < 0) { throw new ArgumentException("No PCM output found"); } } else { m_OutputFormatNumber = FormatIndexes[0]; m_OutputFormat = GetOutputFormat(m_Reader, (uint)m_OutputNumber, (uint)FormatIndexes[0]); } uint OutputCtns = 0; m_Reader.GetOutputCount(out OutputCtns); ushort[] StreamNumbers = new ushort[OutputCtns]; WMT_STREAM_SELECTION[] StreamSelections = new WMT_STREAM_SELECTION[OutputCtns]; for (uint i = 0; i < OutputCtns; i++) { m_Reader.GetStreamNumberForOutput(i, out StreamNumbers[i]); if (i == m_OutputNumber) { StreamSelections[i] = WMT_STREAM_SELECTION.WMT_ON; m_OuputStream = StreamNumbers[i]; m_Reader.SetReadStreamSamples(m_OuputStream, false); } else { StreamSelections[i] = WMT_STREAM_SELECTION.WMT_OFF; } } m_Reader.SetStreamsSelected((ushort)OutputCtns, StreamNumbers, StreamSelections); IWMOutputMediaProps Props = null; m_Reader.GetOutputFormat((uint)m_OutputNumber, (uint)m_OutputFormatNumber, out Props); m_Reader.SetOutputProps((uint)m_OutputNumber, Props); uint Size = 0; Props.GetMediaType(IntPtr.Zero, ref Size); IntPtr buffer = Marshal.AllocCoTaskMem((int)Size); try { WM_MEDIA_TYPE mt; Props.GetMediaType(buffer, ref Size); mt = (WM_MEDIA_TYPE)Marshal.PtrToStructure(buffer, typeof(WM_MEDIA_TYPE)); m_SampleSize = mt.lSampleSize; } finally { Marshal.FreeCoTaskMem(buffer); Props = null; } m_Seekable = false; m_Length = -1; WMHeaderInfo head = new WMHeaderInfo(HeaderInfo); try { m_Seekable = (bool)head[WM.g_wszWMSeekable]; m_Length = SampleTime2BytePosition((ulong)head[WM.g_wszWMDuration]); } catch (COMException e) { if (e.ErrorCode != WM.ASF_E_NOTFOUND) { throw(e); } } }
private static WaveFormat GetOutputFormat(IWMSyncReader reader, uint outputNumber, uint formatNumber) { IWMOutputMediaProps Props = null; int size = 0; WaveFormat fmt = null; reader.GetOutputFormat(outputNumber, formatNumber, out Props); Props.GetMediaType(IntPtr.Zero, ref size); IntPtr buffer = Marshal.AllocCoTaskMem(Math.Max(size, Marshal.SizeOf(typeof(WM_MEDIA_TYPE)) + Marshal.SizeOf(typeof(WaveFormat)))); try { Props.GetMediaType(buffer, ref size); var mt = (WM_MEDIA_TYPE)Marshal.PtrToStructure(buffer, typeof(WM_MEDIA_TYPE)); if ((mt.majortype == MediaTypes.WMMEDIATYPE_Audio) && (mt.subtype == MediaTypes.WMMEDIASUBTYPE_PCM) && (mt.formattype == MediaTypes.WMFORMAT_WaveFormatEx) && (mt.cbFormat >= WAVE_FORMAT_EX_SIZE)) { fmt = new WaveFormat(44100, 16, 2); Marshal.PtrToStructure(mt.pbFormat, fmt); } else { throw new ArgumentException(string.Format("The format {0} of the output {1} is not a valid PCM format", formatNumber, outputNumber)); } } finally { Marshal.FreeCoTaskMem(buffer); } return fmt; }
private static int[] GetPCMOutputNumbers(IWMSyncReader Reader, uint OutputNumber) { var result = new List<int>(); uint FormatCount = 0; Reader.GetOutputFormatCount(OutputNumber, out FormatCount); int BufferSize = Marshal.SizeOf(typeof(WM_MEDIA_TYPE)) + Marshal.SizeOf(typeof(WaveFormat)); IntPtr buffer = Marshal.AllocCoTaskMem(BufferSize); try { for (int i = 0; i < FormatCount; i++) { IWMOutputMediaProps Props = null; int size = 0; WM_MEDIA_TYPE mt; Reader.GetOutputFormat(OutputNumber, (uint)i, out Props); Props.GetMediaType(IntPtr.Zero, ref size); if (size > BufferSize) { BufferSize = size; Marshal.FreeCoTaskMem(buffer); buffer = Marshal.AllocCoTaskMem(BufferSize); } Props.GetMediaType(buffer, ref size); mt = (WM_MEDIA_TYPE)Marshal.PtrToStructure(buffer, typeof(WM_MEDIA_TYPE)); if ((mt.majortype == MediaTypes.WMMEDIATYPE_Audio) && (mt.subtype == MediaTypes.WMMEDIASUBTYPE_PCM) && (mt.formattype == MediaTypes.WMFORMAT_WaveFormatEx) && (mt.cbFormat >= WAVE_FORMAT_EX_SIZE)) { result.Add(i); } } } finally { Marshal.FreeCoTaskMem(buffer); } return result.ToArray(); }
public void FindVideoOutputFormat(uint outputNum, ref WM_MEDIA_TYPE mediaType, ref Guid subtype, ref VideoInfoHeader outputVideoInfoHeader) { IWMOutputMediaProps readerOutputProps = null; uint bufferSize = (uint)(Marshal.SizeOf(typeof(WM_MEDIA_TYPE)) + Marshal.SizeOf(typeof(VideoInfoHeader))); uint formatCount; Logger.WriteLogMessage("Finding video output formats for reader, output [" + outputNum + "]."); _reader.GetOutputFormatCount(outputNum, out formatCount); Logger.WriteLogMessage("Reader can produce " + formatCount + " possible video output formats."); IntPtr buffer = Marshal.AllocCoTaskMem((int)bufferSize); try { for (uint j = 0; j < formatCount; j++) { uint size = 0; _reader.GetOutputFormat(outputNum, j, out readerOutputProps); readerOutputProps.GetMediaType(IntPtr.Zero, ref size); if (size > bufferSize) { bufferSize = size; Marshal.FreeCoTaskMem(buffer); buffer = Marshal.AllocCoTaskMem((int)bufferSize); } readerOutputProps.GetMediaType(buffer, ref size); mediaType = (WM_MEDIA_TYPE)Marshal.PtrToStructure(buffer, typeof(WM_MEDIA_TYPE)); if (mediaType.formattype == FormatTypes.WMFORMAT_VideoInfo) { Logger.WriteLogMessage("Walking output format [" + j + "], format type [" + GetFormatTypeName(mediaType.formattype) + "], subtype [" + GetSubTypeName(mediaType.subtype) + "], sample size [" + mediaType.lSampleSize + "]."); // // NOTE: only look for RGB subtypes // if ((mediaType.subtype == MediaSubTypes.WMMEDIASUBTYPE_RGB555) || (mediaType.subtype == MediaSubTypes.WMMEDIASUBTYPE_RGB24) || (mediaType.subtype == MediaSubTypes.WMMEDIASUBTYPE_RGB32)) { Logger.WriteLogMessage("- Found RGB555, RGB24 or RGB32 sub type, grabbing VideoInfoHeader."); subtype = mediaType.subtype; outputVideoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.pbFormat, typeof(VideoInfoHeader)); Logger.WriteLogMessage("- width [" + outputVideoInfoHeader.bmiHeader.biWidth + "], height [" + outputVideoInfoHeader.bmiHeader.biHeight + "], dwBitrate [" + outputVideoInfoHeader.dwBitRate + "], dwBitErrorRate [" + outputVideoInfoHeader.dwBitErrorRate + "]."); _reader.SetOutputProps(outputNum, readerOutputProps); break; } } } } finally { Marshal.FreeCoTaskMem(buffer); } Marshal.ReleaseComObject(readerOutputProps); }