void TestGetValue() { PropVariant p = new PropVariant("FDSA"); int hr = m_me.GetValue(p); MFError.ThrowExceptionForHR(hr); Debug.Assert(p.GetString() == "asdf"); }
private void TestSetValue() { PropVariant p = new PropVariant(); int hr = m_pStore.SetNamedValue("asdf", new PropVariant("testme")); MFError.ThrowExceptionForHR(hr); hr = m_pStore.GetNamedValue("asdf", p); MFError.ThrowExceptionForHR(hr); Debug.Assert(p.GetString() == "testme"); }
void TestSetValue() { PropVariant var = new PropVariant("asdf"); PropertyKey key = new PropertyKey(); key.fmtid = Guid.NewGuid(); key.pID = 3; int hr = m_ps.SetValue(key, var); MFError.ThrowExceptionForHR(hr); }
void TestGetAt() { PropVariant var = new PropVariant(); PropertyKey key = new PropertyKey(); int hr = m_ps.GetAt(0, key); MFError.ThrowExceptionForHR(hr); Debug.Assert(key.pID == 3); hr = m_ps.GetValue(key, var); MFError.ThrowExceptionForHR(hr); Debug.Assert(var.GetString() == "asdf"); }
public void DoTests() { byte [] b = new byte[] {1, 2, 3}; double d = 2.3; Guid g = Guid.NewGuid(); string s = "hello there"; int i = 123; long l = 456; string[] sa = new string[] { "a", "b", "c" }; string[] sa2 = new string[] { "a", "b", "c" }; PropVariant p1 = new PropVariant(); PropVariant p2 = new PropVariant(b); PropVariant p3 = new PropVariant(d); PropVariant p4 = new PropVariant(g); PropVariant p5 = new PropVariant(s); PropVariant p6 = new PropVariant(i); PropVariant p7 = new PropVariant(l); PropVariant p8 = new PropVariant(sa); PropVariant p9 = new PropVariant(this as object); Debug.Assert(p1.ToString() == "<Empty>"); Debug.Assert(p2.ToString() == "01,02,03"); Debug.Assert(p3.ToString() == d.ToString()); Debug.Assert(p4.ToString() == g.ToString()); Debug.Assert(p5.ToString() == s); Debug.Assert(p6.ToString() == i.ToString()); Debug.Assert(p7.ToString() == l.ToString()); Debug.Assert(p8.ToString() == "\"a\",\"b\",\"c\""); Debug.Assert(p9.ToString() == "Testv10.TestPropVariant"); int i1 = p1.GetHashCode(); int i2 = p2.GetHashCode(); int i3 = p3.GetHashCode(); int i4 = p4.GetHashCode(); int i5 = p5.GetHashCode(); int i6 = p6.GetHashCode(); int i7 = p7.GetHashCode(); int i8 = p8.GetHashCode(); int i9 = p9.GetHashCode(); bool bret = p2.Equals(new PropVariant(b)); bool bret2 = p8.Equals(new PropVariant(sa2)); }
private void GetInterface() { m_iCount = 0; IMFSourceResolver pSourceResolver; object ppSource; IPropertyStore pProp; int hr = MFExtern.CreatePropertyStore(out pProp); MFError.ThrowExceptionForHR(hr); PropVariant var = new PropVariant(this); hr = MFExtern.MFCreateSourceResolver(out pSourceResolver); MFError.ThrowExceptionForHR(hr); // Set the event source property value. hr = pProp.SetValue(MFPKEY.SourceOpenMonitor, var); MFError.ThrowExceptionForHR(hr); MFObjectType ObjectType = MFObjectType.Invalid; try { hr = pSourceResolver.CreateObjectFromURL( @"http://moo.local", // URL of the source. MFResolution.MediaSource, // Create a source object. pProp, // Optional property store. out ObjectType, // Receives the created object type. out ppSource); // Receives a pointer to the media source. MFError.ThrowExceptionForHR(hr); } catch { // Since there is no moo.local domain } Debug.Assert(m_iCount > 0); }
//////////////////////////////////////////////////////////////////////////////////////// // Name: CPlayer::Skip (Public) // Description: // Skips to the specified segment in the sequencer source // Parameter: // SegmentID: [in] The segment identifier /////////////////////////////////////////////////////////////////////////////////////////// public int Skip(int SegmentID) { Debug.WriteLine("\nCPlayer::Skip"); int hr = 0; PropVariant var = new PropVariant(); try { hr = m_pMediaSession.Stop(); MFError.ThrowExceptionForHR(hr); hr = MFExtern.MFCreateSequencerSegmentOffset(SegmentID, 0, var); MFError.ThrowExceptionForHR(hr); hr = m_pMediaSession.Start(CLSID.MF_TIME_FORMAT_SEGMENT_OFFSET, var); MFError.ThrowExceptionForHR(hr); } catch (Exception e) { hr = Marshal.GetHRForException(e); } finally { var.Clear(); } return hr; }
//////////////////////////////////////////////////////////////////////////////////////// // Name: CPlayer::Play (Public) // Description: // Starts the media session with the current topology /////////////////////////////////////////////////////////////////////////////////////////// public int Play() { Debug.WriteLine("\nCPlayer::Play"); int hr = 0; try { // Create the starting position parameter PropVariant var = new PropVariant(); hr = m_pMediaSession.Start(Guid.Empty, var); MFError.ThrowExceptionForHR(hr); } catch (Exception e) { hr = Marshal.GetHRForException(e); } return hr; }
////////////////////////////////////////////////////////////////////////// // Name: CPlayer::Invoke // Description: // Implementation of CAsyncCallback::Invoke. // Callback for asynchronous BeginGetEvent method. // Parameter: // pAsyncResult: Pointer to the result. // ///////////////////////////////////////////////////////////////////////// int IMFAsyncCallback.Invoke(IMFAsyncResult pAsyncResult) { MediaEventType eventType = MediaEventType.MEUnknown; IMFMediaEvent pEvent; PropVariant eventData = null; Exception excpt = null; int hr = S_Ok; try { int eventStatus = 0; // Event status eventData = new PropVariant(); // Event data // Get the event from the event queue. hr = m_pMediaSession.EndGetEvent(pAsyncResult, out pEvent); MFError.ThrowExceptionForHR(hr); // Get the event type. hr = pEvent.GetType(out eventType); MFError.ThrowExceptionForHR(hr); // Get the event data hr = pEvent.GetValue(eventData); MFError.ThrowExceptionForHR(hr); // Get the event status. If the operation that triggered the event // did not succeed, the status is a failure code. hr = pEvent.GetStatus(out eventStatus); MFError.ThrowExceptionForHR(hr); // Switch on the event type. Update the internal state of the CPlayer // as needed. switch (eventType) { // Session events case MediaEventType.MESessionStarted: { Debug.WriteLine(string.Format("{0}: MESessionStarted, Status: 0x{1:x}", eventType.ToString(), eventStatus)); m_State = PlayerState.Playing; PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr((int)m_State)); break; } case MediaEventType.MESessionPaused: { Debug.WriteLine(string.Format("{0}: MESessionPaused, Status: 0x{1:x}", eventType.ToString(), eventStatus)); m_State = PlayerState.Paused; PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr((int)m_State)); break; } case MediaEventType.MESessionStopped: { Debug.WriteLine(string.Format("{0}: MESessionStopped, Status: 0x{1:x}", eventType.ToString(), eventStatus)); m_State = PlayerState.Stopped; PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr((int)m_State)); break; } case MediaEventType.MESessionTopologyStatus: { Debug.WriteLine(string.Format("{0}: MESessionTopologyStatus, Status: 0x{1:x}", eventType.ToString(), eventStatus)); int value = 0; hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_TOPOLOGY_STATUS, out value); MFError.ThrowExceptionForHR(hr); int SegmentID = 0; long ID; //Get information about the new segment IMFTopology pTopology; pTopology = (IMFTopology)eventData.GetIUnknown(); try { hr = pTopology.GetTopologyID(out ID); MFError.ThrowExceptionForHR(hr); m_Segments.GetSegmentIDByTopoID(ID, out SegmentID); topostat.iTopologyStatusType = (MFTopoStatus)value; topostat.iSegmentId = SegmentID; switch (topostat.iTopologyStatusType) { case MFTopoStatus.StartedSource: m_ActiveSegment = SegmentID; break; case MFTopoStatus.Ended: m_ActiveSegment = -1; break; } GCHandle gc = GCHandle.Alloc(topostat); PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)MediaEventType.MESessionTopologyStatus), GCHandle.ToIntPtr(gc)); } finally { SafeRelease(pTopology); } break; } case MediaEventType.MENewPresentation: { Debug.WriteLine(string.Format("{0}: MENewPresentation, Status: 0x{1:x}", eventType.ToString(), eventStatus)); IMFPresentationDescriptor pPresentationDescriptor; int SegmentId = 0; pPresentationDescriptor = (IMFPresentationDescriptor)eventData.GetIUnknown(); try { //Queue the next segment on the media session QueueNextSegment(pPresentationDescriptor, out SegmentId); } finally { SafeRelease(pPresentationDescriptor); } PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr(SegmentId)); break; } case MediaEventType.MEEndOfPresentation: { Debug.WriteLine(string.Format("{0}: MEEndOfPresentation, Status: 0x{1:x}", eventType.ToString(), eventStatus)); int value = 0; try { hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_SOURCE_TOPOLOGY_CANCELED, out value); MFError.ThrowExceptionForHR(hr); } catch { } PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr(value)); break; } case MediaEventType.MEEndOfPresentationSegment: { Debug.WriteLine(string.Format("{0}: MEEndOfPresentationSegment, Status: 0x{1:x}", eventType.ToString(), eventStatus)); int value = 0; try { hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_SOURCE_TOPOLOGY_CANCELED, out value); MFError.ThrowExceptionForHR(hr); } catch { } PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr(value)); break; } case MediaEventType.MESessionNotifyPresentationTime: { Debug.WriteLine(string.Format("{0}: MESessionNotifyPresentationTime, Status: 0x{1:x}", eventType.ToString(), eventStatus)); HandleNotifyPresentationTime(pEvent); break; } case MediaEventType.MESessionClosed: { Debug.WriteLine(string.Format("{0}: MESessionClosed, Status: 0x{1:x}", eventType.ToString(), eventStatus)); m_hCloseEvent.Set(); break; } default: Debug.WriteLine(string.Format("{0}: Event", eventType.ToString())); break; } } catch (Exception e) { excpt = e; } finally { if (eventData != null) { eventData.Clear(); } } // Request another event. if (eventType != MediaEventType.MESessionClosed) { hr = m_pMediaSession.BeginGetEvent(this, null); MFError.ThrowExceptionForHR(hr); } if (excpt == null) { hr = S_Ok; } else { hr = Marshal.GetHRForException(excpt); } return hr; }
private void TestGetItemByIndex() { Guid g; PropVariant o = new PropVariant(); int iCnt1, iCnt2; bool bRes; int hr = m_attr.GetCount(out iCnt1); MFError.ThrowExceptionForHR(hr); hr = m_attr.GetItemByIndex(0, out g, o); MFError.ThrowExceptionForHR(hr); hr = m_attr.CompareItem(g, o, out bRes); MFError.ThrowExceptionForHR(hr); Debug.Assert(bRes); hr = m_attr.DeleteItem(g); MFError.ThrowExceptionForHR(hr); hr = m_attr.GetCount(out iCnt2); MFError.ThrowExceptionForHR(hr); Debug.Assert(iCnt2 == iCnt1 - 1); }
//------------------------------------------------------------------- // Name: SendMarkerEvent // Description: Saned a marker event. // // pMarker: Pointer to our custom IMarker interface, which holds // the marker information. //------------------------------------------------------------------- void SendMarkerEvent(IMarker pMarker, FlushState fs) { int hrStatus = 0; // Status code for marker event. if (fs == FlushState.DropSamples) { hrStatus = E_Abort; } PropVariant var = new PropVariant(); // Get the context data. pMarker.GetContext(var); QueueEvent(MediaEventType.MEStreamSinkMarker, Guid.Empty, hrStatus, var); var.Clear(); }
public void Copy(PropVariant pval) { if (pval == null) { throw new Exception("Null PropVariant sent to Copy"); } pval.Clear(); PropVariantCopy(pval, this); }
// Called just after invoking the COM method. The IntPtr is the same one that just got returned // from MarshalManagedToNative. The return value is unused. public object MarshalNativeToManaged(IntPtr pNativeData) { Marshal.PtrToStructure(pNativeData, m_prop); m_prop = null; return m_prop; }
public void CleanUpManagedData(object ManagedObj) { m_prop = null; }
public IntPtr MarshalManagedToNative(object managedObj) { IntPtr p; // Cast the object back to a PropVariant m_prop = managedObj as PropVariant; if (m_prop != null) { // Release any memory currently allocated m_prop.Clear(); // Create an appropriately sized buffer, blank it, and send it to // the marshaler to make the COM call with. int iSize = GetNativeDataSize(); p = Marshal.AllocCoTaskMem(iSize); if (IntPtr.Size == 4) { Marshal.WriteInt64(p, 0); Marshal.WriteInt64(p, 8, 0); } else { Marshal.WriteInt64(p, 0); Marshal.WriteInt64(p, 8, 0); Marshal.WriteInt64(p, 16, 0); } } else { p = IntPtr.Zero; } return p; }
///////////////////////////////////////////////////////////////////// // Name: DisplayKeyFrames // // Parses the video stream and displays information about the // samples that contain key frames. // // pStream: Pointer to a byte stream. The byte stream's current // read position must be at the start of the ASF Data // Object. // pSplitter: Pointer to the ASF splitter. ///////////////////////////////////////////////////////////////////// void DisplayKeyFrames( IMFASFIndexer ai, IMFByteStream pStream, IMFASFSplitter pSplitter ) { const int cbReadSize = 2048; // Read size (arbitrary value) int cbData; // Amount of data read ASFStatusFlags dwStatus; // Parsing status short wStreamID; // Stream identifier bool bIsKeyFrame = false; // Is the sample a key frame? int cBuffers; // Buffer count int cbTotalLength; // Buffer length long hnsTime; // Time stamp IMFMediaBuffer pBuffer; IMFSample pSample; IMFByteStream[] aia = new IMFByteStream[1]; aia[0] = pStream; int hr = ai.SetIndexByteStreams(aia, 1); MFError.ThrowExceptionForHR(hr); ASFIndexIdentifier ii = new ASFIndexIdentifier(); ii.guidIndexType = Guid.Empty; ii.wStreamNumber = 2; bool b; int i1 = 100; IntPtr ip = Marshal.AllocCoTaskMem(i1); ai.GetIndexStatus(ii, out b, ip, ref i1); long l; PropVariant pv = new PropVariant(50000000L); hr = ai.GetSeekPositionForValue(pv, ii, out l, IntPtr.Zero, out i1); MFError.ThrowExceptionForHR(hr); while (true) { // Read data into the buffer. ReadDataIntoBuffer(pStream, cbReadSize, out pBuffer); try { hr = pBuffer.GetCurrentLength(out cbData); MFError.ThrowExceptionForHR(hr); if (cbData == 0) { break; // End of file. } // Send the data to the ASF splitter. hr = pSplitter.ParseData(pBuffer, 0, 0); MFError.ThrowExceptionForHR(hr); // Pull samples from the splitter. do { hr = pSplitter.GetNextSample(out dwStatus, out wStreamID, out pSample); MFError.ThrowExceptionForHR(hr); if (pSample == null) { // No samples yet. Parse more data. break; } try { // We received a sample from the splitter. Check to see // if it's a key frame. The default is FALSE. try { int i; hr = pSample.GetUINT32(MFAttributesClsid.MFSampleExtension_CleanPoint, out i); MFError.ThrowExceptionForHR(hr); bIsKeyFrame = i != 0; } catch { bIsKeyFrame = false; } if (bIsKeyFrame) { // Print various information about the key frame. hr = pSample.GetBufferCount(out cBuffers); MFError.ThrowExceptionForHR(hr); hr = pSample.GetTotalLength(out cbTotalLength); MFError.ThrowExceptionForHR(hr); Console.WriteLine(string.Format("Buffer count: {0}", cBuffers)); Console.WriteLine(string.Format("Length: {0} bytes", cbTotalLength)); hr = pSample.GetSampleTime(out hnsTime); MFError.ThrowExceptionForHR(hr); // Convert the time stamp to seconds. double sec = (double)(hnsTime / 10000) / 1000; Console.WriteLine(string.Format("Time stamp: {0} sec.", sec)); } } finally { SafeRelease(pSample); } } while ((dwStatus & ASFStatusFlags.Incomplete) > 0); } finally { SafeRelease(pBuffer); } } Console.WriteLine("Done"); }
/////////////////////////////////////////////////////////////////////// // Name: RunMediaSession // Description: // Queues the specified topology on the media session and runs the // media session until the MESessionEnded event is received. /////////////////////////////////////////////////////////////////////// static void RunMediaSession(IMFTopology pTopology) { int hr; IMFMediaSession pSession; bool bGetAnotherEvent = true; PropVariant varStartPosition = new PropVariant(); hr = MFExtern.MFCreateMediaSession(null, out pSession); MFError.ThrowExceptionForHR(hr); try { hr = pSession.SetTopology(0, pTopology); MFError.ThrowExceptionForHR(hr); while (bGetAnotherEvent) { int hrStatus = 0; IMFMediaEvent pEvent; MediaEventType meType = MediaEventType.MEUnknown; int TopoStatus = (int)MFTopoStatus.Invalid; // Used with MESessionTopologyStatus event. hr = pSession.GetEvent(MFEventFlag.None, out pEvent); MFError.ThrowExceptionForHR(hr); try { hr = pEvent.GetStatus(out hrStatus); MFError.ThrowExceptionForHR(hr); hr = pEvent.GetType(out meType); MFError.ThrowExceptionForHR(hr); if (hrStatus >= 0) { switch (meType) { case MediaEventType.MESessionTopologySet: Debug.WriteLine("MESessionTopologySet"); break; case MediaEventType.MESessionTopologyStatus: // Get the status code. hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_TOPOLOGY_STATUS, out TopoStatus); MFError.ThrowExceptionForHR(hr); switch ((MFTopoStatus)TopoStatus) { case MFTopoStatus.Ready: Debug.WriteLine("MESessionTopologyStatus: MF_TOPOSTATUS_READY"); pSession.Start(Guid.Empty, varStartPosition); break; case MFTopoStatus.Ended: Debug.WriteLine("MESessionTopologyStatus: MF_TOPOSTATUS_ENDED"); break; } break; case MediaEventType.MESessionStarted: Debug.WriteLine("MESessionStarted"); break; case MediaEventType.MESessionEnded: Debug.WriteLine("MESessionEnded"); hr = pSession.Stop(); break; case MediaEventType.MESessionStopped: Debug.WriteLine("MESessionStopped"); Console.WriteLine("Attempting to close the media session."); hr = pSession.Close(); MFError.ThrowExceptionForHR(hr); break; case MediaEventType.MESessionClosed: Debug.WriteLine("MESessionClosed"); bGetAnotherEvent = false; break; default: Debug.WriteLine(string.Format("Media session event: {0}", meType)); break; } } else { Debug.WriteLine(string.Format("HRStatus: {0}", hrStatus)); bGetAnotherEvent = false; } } finally { if (pEvent != null) { Marshal.ReleaseComObject(pEvent); } } } Debug.WriteLine("Shutting down the media session."); hr = pSession.Shutdown(); MFError.ThrowExceptionForHR(hr); } finally { if (pSession != null) { Marshal.ReleaseComObject(pSession); } } }
void TestQueueEventParamVar() { IMFMediaEvent pEvent; Guid g = Guid.NewGuid(); PropVariant p = new PropVariant(); int hr = m_meq.QueueEventParamVar(MediaEventType.MESessionClosed, g, 0, new PropVariant("asdf")); MFError.ThrowExceptionForHR(hr); hr = m_meq.GetEvent(MFEventFlag.None, out pEvent); MFError.ThrowExceptionForHR(hr); hr = pEvent.GetValue(p); MFError.ThrowExceptionForHR(hr); Debug.Assert(p.GetString() == "asdf"); }
public void Dispose() { TRACE("CMarker::Dispose"); if (m_varMarkerValue != null) { m_varMarkerValue.Clear(); m_varMarkerValue = null; } if (m_varContextValue != null) { m_varContextValue.Clear(); m_varContextValue = null; } GC.SuppressFinalize(this); }
private static int CopyAttribute(IMFAttributes pSrc, IMFAttributes pDest, Guid key) { var variant = new PropVariant(); var hr = pSrc.GetItem(key, variant); if (Succeeded(hr)) hr = pDest.SetItem(key, variant); return hr; }
private void PlayMovieInWindow(string filename) { WindowsMediaLib.IWMReaderAdvanced2 wmReader = null; IBaseFilter sourceFilter = null; try { FileLogger.Log("PlayMovieInWindow: {0}", filename); lastJump = 0; int hr = 0; if (filename == string.Empty) return; this.graphBuilder = (IGraphBuilder)new FilterGraph(); FileLogger.Log("PlayMovieInWindow: Create Graph"); this.evrRenderer = FilterGraphTools.AddFilterFromClsid(this.graphBuilder, new Guid("{FA10746C-9B63-4B6C-BC49-FC300EA5F256}"), "EVR"); if (evrRenderer != null) { FileLogger.Log("PlayMovieInWindow: Add EVR"); SetupEvrDisplay(); //#if DEBUG if (ps.PublishGraph) rot = new DsROTEntry(this.graphBuilder); //#endif IObjectWithSite grfSite = graphBuilder as IObjectWithSite; if (grfSite != null) grfSite.SetSite(new FilterBlocker(filename)); string fileExt = Path.GetExtension(filename).ToLower(); if (ps.PreferredDecoders != null) { foreach (string pa in ps.PreferredDecoders) { string[] pvA = pa.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); if (pvA[0].ToLower() == fileExt) { for (int i = 1; i < pvA.Length; i++) { string strFilter = pvA[i].Trim(); IBaseFilter filter = null; try { if (Regex.IsMatch(strFilter, @"{?\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}?")) filter = FilterGraphTools.AddFilterFromClsid(graphBuilder, new Guid(strFilter), strFilter); else filter = FilterGraphTools.AddFilterByName(graphBuilder, FilterCategory.LegacyAmFilterCategory, strFilter); if (filter != null) { FileLogger.Log("Added {0} to the graph", strFilter); } else FileLogger.Log("{0} not added to the graph", strFilter); } finally { if (filter != null) Marshal.ReleaseComObject(filter); filter = null; } } } } } // Have the graph builder construct its the appropriate graph automatically //hr = this.graphBuilder.RenderFile(filename, null); if (ps.UseCustomAudioRenderer) { m_audioRendererClsid = new Guid(ps.CustomAudioRender); } audioRenderer = FilterGraphTools.AddFilterFromClsid(graphBuilder, m_audioRendererClsid, "Audio Renderer"); //IAVSyncClock wtf = audioRenderer as IAVSyncClock; //double cap; //hr = wtf.GetBias(out cap); //IMPAudioSettings arSett = audioRenderer as IMPAudioSettings; //if (arSett != null) //{ // AC3Encoding ac3Mode; // hr = arSett.GetAC3EncodingMode(out ac3Mode); // SpeakerConfig sc; // hr = arSett.GetSpeakerConfig(out sc); // AUDCLNT_SHAREMODE sm; // hr = arSett.GetWASAPIMode(out sm); // bool em; // hr = arSett.GetUseWASAPIEventMode(out em); // /*DeviceDefinition[] */IntPtr dc; // //int count; // //hr = arSett.GetAvailableAudioDevices(out dc, out count); // //DsError.ThrowExceptionForHR(hr); // ////DeviceDefinition[] dd = new DeviceDefinition[count]; // //AudioDeviceDefinition dd = (AudioDeviceDefinition)Marshal.PtrToStructure(dc, typeof(AudioDeviceDefinition)); // //if (dc != null) // // Marshal.ReleaseComObject(dc); // hr = arSett.SetAudioDeviceById(null); // //arSett.SetSpeakerMatchOutput(true); // arSett.SetUseWASAPIEventMode(true); // arSett.SetUseFilters((int)MPARUseFilters.ALL); // arSett.SetAllowBitStreaming(true); // arSett.SetAC3EncodingMode(AC3Encoding.DISABLED); // arSett.SetUseTimeStretching(false); //} IMPAudioRendererConfig arSett = audioRenderer as IMPAudioRendererConfig; if (arSett != null) { int ac3Mode; hr = arSett.GetInt(MPARSetting.AC3_ENCODING, out ac3Mode); int sc; hr = arSett.GetInt(MPARSetting.SPEAKER_CONFIG, out sc); int sm; hr = arSett.GetInt(MPARSetting.WASAPI_MODE, out sm); bool em; hr = arSett.GetBool(MPARSetting.WASAPI_EVENT_DRIVEN, out em); /*DeviceDefinition[] */ IntPtr dc; //int count; //hr = arSett.GetAvailableAudioDevices(out dc, out count); //DsError.ThrowExceptionForHR(hr); ////DeviceDefinition[] dd = new DeviceDefinition[count]; //AudioDeviceDefinition dd = (AudioDeviceDefinition)Marshal.PtrToStructure(dc, typeof(AudioDeviceDefinition)); //if (dc != null) // Marshal.ReleaseComObject(dc); hr = arSett.SetString(MPARSetting.SETTING_AUDIO_DEVICE, ps.AudioPlaybackDevice); //arSett.SetSpeakerMatchOutput(true); arSett.SetBool(MPARSetting.WASAPI_EVENT_DRIVEN, true); arSett.SetInt(MPARSetting.USE_FILTERS, (int)MPARUseFilters.ALL); arSett.SetBool(MPARSetting.ALLOW_BITSTREAMING, true); arSett.SetInt(MPARSetting.AC3_ENCODING, (int)AC3Encoding.DISABLED); arSett.SetBool(MPARSetting.ENABLE_TIME_STRETCHING, false); } //try //{ hr = graphBuilder.AddSourceFilter(filename, "Source", out sourceFilter); if (hr < 0) { //if it doesn't work before failing try to load it with the WMV reader sourceFilter = (IBaseFilter)new WMAsfReader(); hr = graphBuilder.AddFilter(sourceFilter, "WM/ASF Reader"); DsError.ThrowExceptionForHR(hr); hr = ((IFileSourceFilter)sourceFilter).Load(filename, null); DsError.ThrowExceptionForHR(hr); wmReader = sourceFilter as WindowsMediaLib.IWMReaderAdvanced2; } IPin outPin = DsFindPin.ByConnectionStatus(sourceFilter, PinConnectedStatus.Unconnected, 0); while (outPin != null) { try { hr = graphBuilder.Render(outPin); DsError.ThrowExceptionForHR(hr); } finally { if (outPin != null) Marshal.ReleaseComObject(outPin); outPin = null; } outPin = DsFindPin.ByConnectionStatus(sourceFilter, PinConnectedStatus.Unconnected, 0); } if (ps.MultiChannelWMA) { FileLogger.Log("Set multichannel mode for WMA"); IBaseFilter wmaDec = FilterGraphTools.FindFilterByName(graphBuilder, "WMAudio Decoder DMO"); if (wmaDec != null) { try { //http://msdn.microsoft.com/en-us/library/aa390550(VS.85).aspx IPropertyBag bag = wmaDec as IPropertyBag; if (bag != null) { object pVar; hr = bag.Read("_HIRESOUTPUT", out pVar, null); DsError.ThrowExceptionForHR(hr); bool bVar = (bool)pVar; FileLogger.Log("_HIRESOUTPUT = {0}", bVar); if (!bVar) { IPin wmaOut = DsFindPin.ByDirection(wmaDec, PinDirection.Output, 0); IPin cPin = null; try { hr = wmaOut.ConnectedTo(out cPin); DsError.ThrowExceptionForHR(hr); if (cPin != null) //cpin should never be null at this point, but lets be safe { hr = wmaOut.Disconnect(); DsError.ThrowExceptionForHR(hr); List<Guid> oldFilters = new List<Guid>(); IBaseFilter oFilt = FilterGraphTools.GetFilterFromPin(cPin); try { while (oFilt != null) { IBaseFilter cFilter = null; try { Guid clsid; hr = oFilt.GetClassID(out clsid); DsError.ThrowExceptionForHR(hr); if (clsid != DSOUND_RENDERER) { oldFilters.Add(clsid); cFilter = FilterGraphTools.GetConnectedFilter(oFilt, PinDirection.Output, 0); } hr = graphBuilder.RemoveFilter(oFilt); DsError.ThrowExceptionForHR(hr); } finally { if (oFilt != null) Marshal.ReleaseComObject(oFilt); oFilt = null; } oFilt = cFilter; } } finally { if (oFilt != null) Marshal.ReleaseComObject(oFilt); oFilt = null; } foreach (Guid addFilt in oldFilters) { IBaseFilter addMe = FilterGraphTools.AddFilterFromClsid(graphBuilder, addFilt, addFilt.ToString()); if (addMe != null) Marshal.ReleaseComObject(addMe); } } pVar = true; hr = bag.Write("_HIRESOUTPUT", ref pVar); DsError.ThrowExceptionForHR(hr); hr = graphBuilder.Render(wmaOut); DsError.ThrowExceptionForHR(hr); } finally { if (wmaOut != null) Marshal.ReleaseComObject(wmaOut); if (cPin != null) Marshal.ReleaseComObject(cPin); } } } } catch (Exception ex) { FileLogger.Log("Error setting multichannel mode for WMA: {0}", ex.Message); } finally { while(Marshal.ReleaseComObject(wmaDec) > 0); } } } //} //finally //{ // if (sourceFilter != null) // Marshal.ReleaseComObject(sourceFilter); //} if (ps.DXVAWMV) { FileLogger.Log("Set DXVA for WMV"); IBaseFilter wmvDec = FilterGraphTools.FindFilterByName(graphBuilder, "WMVideo Decoder DMO"); if (wmvDec != null) { try { MediaFoundation.Misc.IPropertyStore config = wmvDec as MediaFoundation.Misc.IPropertyStore; if (config != null) { MediaFoundation.Misc.PropVariant pv = new MediaFoundation.Misc.PropVariant(); //config.GetValue(MediaFoundation.Misc.WMVConst.MFPKEY_DXVA_ENABLED, pv); } } catch (Exception ex) { FileLogger.Log("Error setting DXVA mode for WMV: {0}", ex.Message); } finally { while (Marshal.ReleaseComObject(wmvDec) > 0) ; } } } SetEvrVideoMode(); // QueryInterface for DirectShow interfaces this.mediaControl = (IMediaControl)this.graphBuilder; this.mediaEventEx = (IMediaEventEx)this.graphBuilder; this.mediaSeeking = (IMediaSeeking)this.graphBuilder; this.mediaPosition = (IMediaPosition)this.graphBuilder; // Query for video interfaces, which may not be relevant for audio files //this.videoWindow = this.graphBuilder as IVideoWindow; //this.basicVideo = this.graphBuilder as IBasicVideo; // Query for audio interfaces, which may not be relevant for video-only files this.basicAudio = this.graphBuilder as IBasicAudio; // Is this an audio-only file (no video component)? CheckVisibility(); // Have the graph signal event via window callbacks for performance hr = this.mediaEventEx.SetNotifyWindow(this.Handle, WM.GRAPH_NOTIFY, IntPtr.Zero); DsError.ThrowExceptionForHR(hr); if (!this.isAudioOnly) { // Setup the video window //hr = this.videoWindow.put_Owner(this.Handle); //DsError.ThrowExceptionForHR(hr); //this.evrDisplay.SetVideoWindow(this.Handle); //hr = this.videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings | WindowStyle.ClipChildren); //DsError.ThrowExceptionForHR(hr); hr = InitVideoWindow();//1, 1); DsError.ThrowExceptionForHR(hr); GetFrameStepInterface(); } else { // Initialize the default player size and enable playback menu items hr = InitPlayerWindow(); DsError.ThrowExceptionForHR(hr); EnablePlaybackMenu(true, MediaType.Audio); } // Complete window initialization //CheckSizeMenu(menuFileSizeNormal); //this.isFullScreen = false; this.currentPlaybackRate = 1.0; UpdateMainTitle(); this.Activate(); //pre-roll the graph hr = this.mediaControl.Pause(); DsError.ThrowExceptionForHR(hr); if (wmReader != null) { WindowsMediaLib.PlayMode pMode; hr = wmReader.GetPlayMode(out pMode); DsError.ThrowExceptionForHR(hr); if (pMode == WindowsMediaLib.PlayMode.Streaming) { int pdwPercent = 0; long pcnsBuffering; while (pdwPercent < 100) { hr = wmReader.GetBufferProgress(out pdwPercent, out pcnsBuffering); DsError.ThrowExceptionForHR(hr); if (pdwPercent >= 100) break; int sleepFor = Convert.ToInt32(pcnsBuffering / 1000); Thread.Sleep(100); } } } // Run the graph to play the media file hr = this.mediaControl.Run(); DsError.ThrowExceptionForHR(hr); if (commWatcher != null) commWatcher.Dispose(); string commPath = string.Empty; if (ps.UseDtbXml) { commWatcher = new FileSystemWatcher(Commercials.XmlDirectory, Commercials.GetXmlFilename(filename)); commPath = Path.Combine(Commercials.XmlDirectory, Commercials.GetXmlFilename(filename)); } else { commWatcher = new FileSystemWatcher(Path.GetDirectoryName(filename), Commercials.GetEdlFilename(filename)); commPath = Path.Combine(Path.GetDirectoryName(filename), Commercials.GetEdlFilename(filename)); } ReadComm(commPath); commWatcher.Changed += new FileSystemEventHandler(commWatcher_Changed); commWatcher.Created += new FileSystemEventHandler(commWatcher_Changed); //commWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size; commWatcher.EnableRaisingEvents = true; MoveToBookmark(); this.currentState = PlayState.Running; if (isFullScreen) tmMouseMove.Enabled = true; } else { //MessageBox.Show("EVR cannot be loaded on this PC"); using (EPDialog ed = new EPDialog()) ed.ShowDialog("Error", "The Enhanced Video Renderer cannot be loaded", 20, this); } } finally { //if (wmReader != null) // Marshal.ReleaseComObject(wmReader); if (sourceFilter != null) while(Marshal.ReleaseComObject(sourceFilter)>0); } }
int CopyAttribute(IMFAttributes pSrc, IMFAttributes pDest, Guid key) { PropVariant var = new PropVariant(); int hr = S_Ok; hr = pSrc.GetItem(key, var); if (Succeeded(hr)) { hr = pDest.SetItem(key, var); } return hr; }
/////////////////////////////////////////////////////////////////////// // Name: Invoke // Description: Callback for asynchronous BeginGetEvent method. // // pAsyncResult: Pointer to the result. ///////////////////////////////////////////////////////////////////////// int IMFAsyncCallback.Invoke(IMFAsyncResult pAsyncResult) { // Make sure we *never* leave this entry point with an exception try { int hr; IMFMediaEvent pEvent; MediaEventType meType = MediaEventType.MEUnknown; // Event type PropVariant varEventData = new PropVariant(); // Event data // Get the event from the event queue. hr = m_pMEG.EndGetEvent(pAsyncResult, out pEvent); MFError.ThrowExceptionForHR(hr); // Get the event type. hr = pEvent.GetType(out meType); MFError.ThrowExceptionForHR(hr); // Get the event status. If the operation that triggered the event did // not succeed, the status is a failure code. hr = pEvent.GetStatus(out m_hrStatus); MFError.ThrowExceptionForHR(hr); if (m_hrStatus == 862022) // NS_S_DRM_MONITOR_CANCELLED { m_hrStatus = MFError.MF_E_OPERATION_CANCELLED; m_state = Enabler.Complete; } // Get the event data. hr = pEvent.GetValue(varEventData); MFError.ThrowExceptionForHR(hr); // For the MEEnablerCompleted action, notify the application. // Otherwise, request another event. Debug.WriteLine(string.Format("Content enabler event: {0}", meType.ToString())); if (meType == MediaEventType.MEEnablerCompleted) { PostMessage(m_hwnd, WM_APP_CONTENT_ENABLER, IntPtr.Zero, IntPtr.Zero); } else { if (meType == MediaEventType.MEEnablerProgress) { if (varEventData.GetVariantType() == PropVariant.VariantType.String) { Debug.WriteLine(string.Format("Progress: {0}", varEventData.GetString())); } } hr = m_pMEG.BeginGetEvent(this, null); MFError.ThrowExceptionForHR(hr); } // Clean up. varEventData.Clear(); SafeRelease(pEvent); return S_Ok; } catch (Exception e) { return Marshal.GetHRForException(e); } }
public CMarker( MFStreamSinkMarkerType eMarkerType, ConstPropVariant pvarMarkerValue, // Can be null. ConstPropVariant pvarContextValue // Can be null. ) { TRACE("CMarker::MFStreamSinkMarkerType"); m_eMarkerType = eMarkerType; // Copy the marker data. if (pvarMarkerValue != null) { m_varMarkerValue = new PropVariant(pvarMarkerValue); } else { m_varMarkerValue = new PropVariant(); } if (pvarContextValue != null) { m_varContextValue = new PropVariant(pvarContextValue); } else { m_varContextValue = new PropVariant(); } }
private PropVariant TestGetItem2(PropVariant o) { MFAttributeType pType; PropVariant o2 = new PropVariant(); Guid g = Guid.NewGuid(); int hr; hr = m_attr.SetItem(g, o); MFError.ThrowExceptionForHR(hr); hr = m_attr.GetItem(g, o2); MFError.ThrowExceptionForHR(hr); hr = m_attr.GetItemType(g, out pType); MFError.ThrowExceptionForHR(hr); Debug.Assert(o2.GetMFAttributeType() == o.GetMFAttributeType() && o2.GetMFAttributeType() == pType); return o2; }
public void GetMarkerValue(PropVariant pvar) { TRACE("CMarker::GetMarkerValue"); if (pvar == null) { throw new COMException("null variant", E_Pointer); } m_varMarkerValue.Copy(pvar); }
//------------------------------------------------------------------- // Name: Start // Description: Switches to running state. //------------------------------------------------------------------- public int Start( IMFPresentationDescriptor pPresentationDescriptor, Guid pguidTimeFormat, ConstPropVariant pvarStartPosition ) { // Make sure we *never* leave this entry point with an exception try { int hr; m_Log.WriteLine("-Start"); lock (this) { PropVariant var; long llStartOffset = 0; bool bIsSeek = false; bool bIsRestartFromCurrentPosition = false; // Fail if the source is shut down. CheckShutdown(); // Check parameters. // Start position and presentation descriptor cannot be null. if (pPresentationDescriptor == null) // pvarStartPosition == null || { throw new COMException("null presentation descriptor", E_InvalidArgument); } // Check the time format. Must be "reference time" units. if ((pguidTimeFormat != null) && (pguidTimeFormat != Guid.Empty)) { // Unrecognized time format GUID. throw new COMException("unrecognized time format guid", MFError.MF_E_UNSUPPORTED_TIME_FORMAT); } // Check the start position. if ((pvarStartPosition == null) || (pvarStartPosition.GetMFAttributeType() == MFAttributeType.None)) { // Start position is "current position". // For stopped, that means 0. Otherwise, use the current position. if (m_state == State.Stopped) { llStartOffset = 0; } else { llStartOffset = GetCurrentPosition(); bIsRestartFromCurrentPosition = true; } } else if (pvarStartPosition.GetMFAttributeType() == MFAttributeType.Uint64) { // Start position is given in pvarStartPosition in 100-ns units. llStartOffset = (long)pvarStartPosition; if (m_state != State.Stopped) { // Source is running or paused, so this is a seek. bIsSeek = true; } } else { // We don't support this time format. throw new COMException("We don't support this time format", MFError.MF_E_UNSUPPORTED_TIME_FORMAT); } // Validate the caller's presentation descriptor. ValidatePresentationDescriptor(pPresentationDescriptor); // Sends the MENewStream or MEUpdatedStream event. QueueNewStreamEvent(pPresentationDescriptor); // Notify the stream of the new start time. m_pStream.SetPosition(llStartOffset); // Send Started or Seeked events. We will send them // 1. from the media source // 2. from each stream var = new PropVariant(llStartOffset); // (1) Send the source event. if (bIsSeek) { QueueEvent(MediaEventType.MESourceSeeked, Guid.Empty, S_Ok, var); } else { // For starting, if we are RESTARTING from the current position and our // previous state was running/paused, then we need to add the // MF_EVENT_SOURCE_ACTUAL_START attribute to the event. This requires // creating the event object first. IMFMediaEvent pEvent = null; // Create the event. hr = MFExtern.MFCreateMediaEvent( MediaEventType.MESourceStarted, Guid.Empty, S_Ok, var, out pEvent ); MFError.ThrowExceptionForHR(hr); // For restarts, set the actual start time as an attribute. if (bIsRestartFromCurrentPosition) { hr = pEvent.SetUINT64(MFAttributesClsid.MF_EVENT_SOURCE_ACTUAL_START, llStartOffset); MFError.ThrowExceptionForHR(hr); } // Now queue the event. hr = m_pEventQueue.QueueEvent(pEvent); MFError.ThrowExceptionForHR(hr); //SAFE_RELEASE(pEvent); } // 2. Send the stream event. if (m_pStream != null) { if (bIsSeek) { m_pStream.QueueEvent(MediaEventType.MEStreamSeeked, Guid.Empty, S_Ok, var); } else { m_pStream.QueueEvent(MediaEventType.MEStreamStarted, Guid.Empty, S_Ok, var); } } // Update our state. m_state = State.Started; // NOTE: If this method were implemented as an asynchronous operation // and the operation Failed asynchronously, the media source would need // to send an MESourceStarted event with the failure code. For this // sample, all operations are synchronous (which is allowed), so any // failures are also synchronous. var.Clear(); } return S_Ok; } catch (Exception e) { return Marshal.GetHRForException(e); } }