private void TestInput() { int iCount, iFCount; IWMInputMediaProps pMP, pMP2; m_Writer.GetInputCount(out iCount); m_Writer.GetInputProps(0, out pMP); m_Writer.GetInputFormatCount(0, out iFCount); m_Writer.GetInputFormat(0, 0, out pMP2); m_Writer.SetInputProps(0, pMP); }
/// <summary> /// Create the writer indicating Metadata information /// </summary> /// <param name="output"><see cref="System.IO.Stream"/> Where resulting WMA string will be written</param> /// <param name="format">PCM format of input data received in <see cref="WmaWriter.Write"/> method</param> /// <param name="profile">IWMProfile that describe the resulting compressed stream</param> /// <param name="MetadataAttributes">Array of <see cref="Yeti.WMFSdk.WM_Attr"/> structures describing the metadata information that will be in the result stream</param> public WmaWriter(Stream output, WaveFormat format, IWMProfile profile, WM_Attr[] MetadataAttributes) : base(output, format) { m_Writer = WM.CreateWriter(); IWMWriterAdvanced wa = (IWMWriterAdvanced)m_Writer; wa.AddSink((IWMWriterSink)this); m_Writer.SetProfile(profile); uint inputs; m_Writer.GetInputCount(out inputs); if (inputs == 1) { IWMInputMediaProps InpProps; Guid type; m_Writer.GetInputProps(0, out InpProps); InpProps.GetType(out type); if (type == MediaTypes.WMMEDIATYPE_Audio) { WM_MEDIA_TYPE mt; mt.majortype = MediaTypes.WMMEDIATYPE_Audio; mt.subtype = MediaTypes.WMMEDIASUBTYPE_PCM; mt.bFixedSizeSamples = true; mt.bTemporalCompression = false; mt.lSampleSize = (uint)m_InputDataFormat.nBlockAlign; mt.formattype = MediaTypes.WMFORMAT_WaveFormatEx; mt.pUnk = IntPtr.Zero; mt.cbFormat = (uint)Marshal.SizeOf(m_InputDataFormat); GCHandle h = GCHandle.Alloc(m_InputDataFormat, GCHandleType.Pinned); try { mt.pbFormat = h.AddrOfPinnedObject(); InpProps.SetMediaType(ref mt); } finally { h.Free(); } m_Writer.SetInputProps(0, InpProps); if ( MetadataAttributes != null ) { WMHeaderInfo info = new WMHeaderInfo((IWMHeaderInfo)m_Writer); foreach(WM_Attr attr in MetadataAttributes) { info.SetAttribute(attr); } info = null; } m_Writer.BeginWriting(); m_Profile = profile; } else { throw new ArgumentException("Invalid profile", "profile"); } } else { throw new ArgumentException("Invalid profile", "profile"); } }
/// <summary> /// Create the writer indicating Metadata information /// </summary> /// <param name="output"><see cref="System.IO.Stream"/> Where resulting WMA string will be written</param> /// <param name="format">PCM format of input data received in <see cref="WmaWriter.Write"/> method</param> /// <param name="profile">IWMProfile that describe the resulting compressed stream</param> /// <param name="MetadataAttributes">Array of <see cref="Yeti.WMFSdk.WM_Attr"/> structures describing the metadata information that will be in the result stream</param> public WmaWriter(Stream output, WaveFormat format, IWMProfile profile, WM_Attr[] MetadataAttributes) : base(output, format) { m_Writer = WM.CreateWriter(); IWMWriterAdvanced wa = (IWMWriterAdvanced)m_Writer; wa.AddSink((IWMWriterSink)this); m_Writer.SetProfile(profile); uint inputs; m_Writer.GetInputCount(out inputs); if (inputs == 1) { IWMInputMediaProps InpProps; Guid type; m_Writer.GetInputProps(0, out InpProps); InpProps.GetType(out type); if (type == MediaTypes.WMMEDIATYPE_Audio) { WM_MEDIA_TYPE mt; mt.majortype = MediaTypes.WMMEDIATYPE_Audio; mt.subtype = MediaTypes.WMMEDIASUBTYPE_PCM; mt.bFixedSizeSamples = true; mt.bTemporalCompression = false; mt.lSampleSize = (uint)m_InputDataFormat.nBlockAlign; mt.formattype = MediaTypes.WMFORMAT_WaveFormatEx; mt.pUnk = IntPtr.Zero; mt.cbFormat = (uint)Marshal.SizeOf(m_InputDataFormat); GCHandle h = GCHandle.Alloc(m_InputDataFormat, GCHandleType.Pinned); try { mt.pbFormat = h.AddrOfPinnedObject(); InpProps.SetMediaType(ref mt); } finally { h.Free(); } m_Writer.SetInputProps(0, InpProps); if (MetadataAttributes != null) { WMHeaderInfo info = new WMHeaderInfo((IWMHeaderInfo)m_Writer); foreach (WM_Attr attr in MetadataAttributes) { info.SetAttribute(attr); } info = null; } m_Writer.BeginWriting(); m_Profile = profile; } else { throw new ArgumentException("Invalid profile", "profile"); } } else { throw new ArgumentException("Invalid profile", "profile"); } }
public WMAWriter(string path, WMAWriterSettings settings) { this.m_settings = settings; this.outputPath = path; try { m_pWriter = settings.GetWriter(); int cInputs; m_pWriter.GetInputCount(out cInputs); if (cInputs < 1) { throw new InvalidOperationException(); } IWMInputMediaProps pInput; m_pWriter.GetInputProps(0, out pInput); try { int cbType = 0; AMMediaType pMediaType = null; pInput.GetMediaType(pMediaType, ref cbType); pMediaType = new AMMediaType(); pMediaType.formatSize = cbType - Marshal.SizeOf(typeof(AMMediaType)); pInput.GetMediaType(pMediaType, ref cbType); try { var wfe = new WaveFormatExtensible(m_settings.PCM); Marshal.FreeCoTaskMem(pMediaType.formatPtr); pMediaType.formatPtr = IntPtr.Zero; pMediaType.formatSize = 0; pMediaType.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(wfe)); pMediaType.formatSize = Marshal.SizeOf(wfe); Marshal.StructureToPtr(wfe, pMediaType.formatPtr, false); pInput.SetMediaType(pMediaType); m_pWriter.SetInputProps(0, pInput); } finally { WMUtils.FreeWMMediaType(pMediaType); } } finally { Marshal.ReleaseComObject(pInput); } } catch (Exception ex) { if (m_pWriter != null) { Marshal.ReleaseComObject(m_pWriter); m_pWriter = null; } throw ex; } }
private void Initialize(Bitmap hBitmap) { AMMediaType mt = new AMMediaType(); VideoInfoHeader videoInfo = new VideoInfoHeader(); // Create the VideoInfoHeader using info from the bitmap videoInfo.BmiHeader.Size = Marshal.SizeOf(typeof(BitmapInfoHeader)); videoInfo.BmiHeader.Width = hBitmap.Width; videoInfo.BmiHeader.Height = hBitmap.Height; videoInfo.BmiHeader.Planes = 1; // compression thru clrimportant don't seem to be used. Init them anyway videoInfo.BmiHeader.Compression = 0; videoInfo.BmiHeader.ImageSize = 0; videoInfo.BmiHeader.XPelsPerMeter = 0; videoInfo.BmiHeader.YPelsPerMeter = 0; videoInfo.BmiHeader.ClrUsed = 0; videoInfo.BmiHeader.ClrImportant = 0; switch (hBitmap.PixelFormat) { case PixelFormat.Format32bppRgb: mt.subType = MediaSubType.RGB32; videoInfo.BmiHeader.BitCount = 32; break; case PixelFormat.Format24bppRgb: mt.subType = MediaSubType.RGB24; videoInfo.BmiHeader.BitCount = 24; break; case PixelFormat.Format16bppRgb555: mt.subType = MediaSubType.RGB555; videoInfo.BmiHeader.BitCount = 16; break; default: throw new Exception("Unrecognized Pixelformat in bitmap"); } videoInfo.SrcRect = new Rectangle(0, 0, hBitmap.Width, hBitmap.Height); videoInfo.TargetRect = videoInfo.SrcRect; videoInfo.BmiHeader.ImageSize = hBitmap.Width * hBitmap.Height * (videoInfo.BmiHeader.BitCount / 8); videoInfo.BitRate = videoInfo.BmiHeader.ImageSize * m_iFrameRate; videoInfo.BitErrorRate = 0; videoInfo.AvgTimePerFrame = 10000 * 1000 / m_iFrameRate; mt.majorType = MediaType.Video; mt.fixedSizeSamples = true; mt.temporalCompression = false; mt.sampleSize = videoInfo.BmiHeader.ImageSize; mt.formatType = FormatType.VideoInfo; mt.unkPtr = IntPtr.Zero; mt.formatSize = Marshal.SizeOf(typeof(VideoInfoHeader)); mt.formatPtr = Marshal.AllocCoTaskMem(mt.formatSize); Marshal.StructureToPtr(videoInfo, mt.formatPtr, false); IWMInputMediaProps pProps; m_Writer.GetInputProps(0, out pProps); pProps.SetMediaType(mt); // Now take the inputprops, and set them on the file writer m_Writer.SetInputProps(0, pProps); }
/// <summary> /// Create filename from specified profile using specified framerate /// </summary> /// <param name="lpszFileName">File name to create</param> /// <param name="guidProfileID">WM Profile to use for compression</param> /// <param name="iFrameRate">Frames Per Second</param> public CwmvFile(string lpszFileName, ref Guid guidProfileID, int iFrameRate) { Guid guidInputType; int dwInputCount; IWMProfileManager pWMProfileManager = null; IWMProfile pWMProfile = null; // Initialize all member variables m_iFrameRate = iFrameRate; m_dwVideoInput = -1; m_dwCurrentVideoSample = 0; m_msVideoTime = 0; m_pWMWriter = null; m_pInputProps = null; m_Init = false; try { // Open the profile manager WMUtils.WMCreateProfileManager(out pWMProfileManager); // Convert pWMProfileManager to a IWMProfileManager2 IWMProfileManager2 pProfileManager2 = (IWMProfileManager2)pWMProfileManager; // Specify the version number of the profiles to use pProfileManager2.SetSystemProfileVersion(WMVersion.V8_0); // Load the profile specified by the caller pProfileManager2.LoadProfileByID(guidProfileID, out pWMProfile); // Create a writer. This is the interface we actually write with WMUtils.WMCreateWriter(IntPtr.Zero, out m_pWMWriter); // Set the profile we got into the writer. This controls compression, video // size, # of video channels, # of audio channels, etc m_pWMWriter.SetProfile(pWMProfile); // Find out how many inputs are in the current profile m_pWMWriter.GetInputCount(out dwInputCount); // Assume we won't find any video pins m_dwVideoInput = -1; // Find the first video input on the writer for (int i = 0; i < dwInputCount; i++) { // Get the properties of channel #i m_pWMWriter.GetInputProps(i, out m_pInputProps); // Read the type of the channel m_pInputProps.GetType(out guidInputType); // If it is video, we are done if (guidInputType == MediaType.Video) { m_dwVideoInput = i; break; } } // Didn't find a video channel if (m_dwVideoInput == -1) { throw new Exception("Profile does not accept video input"); } // Specify the file name for the output m_pWMWriter.SetOutputFilename(lpszFileName); } catch { Close(); throw; } finally { // Release the locals if (pWMProfile != null) { Marshal.ReleaseComObject(pWMProfile); pWMProfile = null; } if (pWMProfileManager != null) { Marshal.ReleaseComObject(pWMProfileManager); pWMProfileManager = null; } } }
/// <summary> /// Load a WM Profile (system or custom). /// </summary> /// <param name="prxFile"></param> /// <param name="prIndex"></param> /// <returns></returns> public bool ConfigProfile(String prxFile, uint prIndex) { IWMProfile profile; uint hr = WMFSDKFunctions.WMCreateProfileManager(out profileManager); if (prxFile == "") { //use system profile Guid prg = ProfileIndexToGuid(prIndex); if (prg == Guid.Empty) { profile = null; Debug.WriteLine("Unsupported Profile index."); return(false); } try { GUID prG = WMGuids.ToGUID(prg); profileManager.LoadProfileByID(ref prG, out profile); } catch (Exception e) { eventLog.WriteEntry("Failed to load system profile: " + e.ToString(), EventLogEntryType.Error, 1000); Debug.WriteLine("Failed to load system profile: " + e.ToString()); profile = null; return(false); } } else { //use custom profile profile = LoadCustomProfile(prxFile); if (profile == null) { return(false); } } /// Tell the writer to use this profile. try { writer.SetProfile(profile); string name = GetProfileName(profile); Debug.WriteLine("Using profile: " + name); } catch (Exception e) { eventLog.WriteEntry("Failed to set writer profile: " + e.ToString(), EventLogEntryType.Error, 1000); Debug.WriteLine("Failed to set writer profile: " + e.ToString()); profile = null; return(false); } /// A slightly confusing point: Streams are subobjects of the profile, /// while inputs are subobjects of the Writer. The difference is in the /// multi-bitrate scenario where there may be multiple streams per input. /// Stream numbers start with 1, while input numbers and stream indexes begin at 0. /// If we have a profile that supports scripts, we need the stream number of /// the script stream. For audio and video, we just need input number. scriptBitrate = 0; audioInput = videoInput = 0; scriptStreamNumber = 0; audioProps = videoProps = null; /// If the profile has a script stream, find the bitrate and stream number. uint cStreams; IWMStreamConfig streamConfig; GUID streamType; profile.GetStreamCount(out cStreams); for (uint i = 0; i < cStreams; i++) { profile.GetStream(i, out streamConfig); streamConfig.GetStreamType(out streamType); if (WMGuids.ToGuid(streamType) == WMGuids.WMMEDIATYPE_Script) { streamConfig.GetStreamNumber(out scriptStreamNumber); streamConfig.GetBitrate(out scriptBitrate); } } /// Iterate over writer inputs, holding on to the IWMInputMediaProps* for each, /// so we can later configure them. Also save input numbers for audio and video here. uint cInputs; writer.GetInputCount(out cInputs); GUID guidInputType; IWMInputMediaProps inputProps = null; for (uint i = 0; i < cInputs; i++) { writer.GetInputProps(i, out inputProps); inputProps.GetType(out guidInputType); if (WMGuids.ToGuid(guidInputType) == WMGuids.WMMEDIATYPE_Audio) { audioProps = inputProps; audioInput = i; } else if (WMGuids.ToGuid(guidInputType) == WMGuids.WMMEDIATYPE_Video) { videoProps = inputProps; videoInput = i; } else if (WMGuids.ToGuid(guidInputType) == WMGuids.WMMEDIATYPE_Script) { } else { Debug.WriteLine("Profile contains unrecognized media type."); return(false); } } // We require an audio input, since that drives the timing for the whole stream. if (audioProps == null) { Debug.WriteLine("Profile should contain at least one audio input."); return(false); } return(true); }