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(); } }
public int QueueEvent(MediaEventType met, Guid guidExtendedType, int hrStatus, ConstPropVariant pvValue) { int hr; TRACE(string.Format("CWavStream::QueueEvent ({0})", met.ToString())); lock (this) { CheckShutdown(); hr = m_pEventQueue.QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue); MFError.ThrowExceptionForHR(hr); } return S_Ok; }
//------------------------------------------------------------------- // Name: PlaceMarker // Description: Receives a marker. [Asynchronous] // // Note: The client can call PlaceMarker at any time. In response, // we need to queue an MEStreamSinkMarer event, but not until // *after* we have processed all samples that we have received // up to this point. // // Also, in general you might need to handle specific marker // types, although this sink does not. //------------------------------------------------------------------- public int PlaceMarker( MFStreamSinkMarkerType eMarkerType, ConstPropVariant pvarMarkerValue, ConstPropVariant pvarContextValue) { TRACE("CWavStream::PlaceMarker"); lock (this) { IMarker pMarker = null; CheckShutdown(); ValidateOperation(CAsyncOperation.StreamOperation.OpPlaceMarker); // Create a marker object and put it on the sample queue. pMarker = new CMarker( eMarkerType, pvarMarkerValue, pvarContextValue); m_SampleQueue.Enqueue(pMarker); // Unless we are paused, start an async operation to dispatch the next sample/marker. if (m_state != State.Paused) { // Queue the operation. QueueAsyncOperation(CAsyncOperation.StreamOperation.OpPlaceMarker); // Increments ref count on pOp. } } return S_Ok; }
public PropVariant(ConstPropVariant value) { if (value != null) { PropVariantCopy(this, value); } else { throw new NullReferenceException("null passed to PropVariant constructor"); } }
//------------------------------------------------------------------- // 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); } }
public int QueueEvent(MediaEventType met, Guid guidExtendedType, int hrStatus, ConstPropVariant pvValue) { // Make sure we *never* leave this entry point with an exception try { int hr; m_Log.WriteLine("-QueueEvent"); lock (this) { CheckShutdown(); hr = m_pEventQueue.QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue); MFError.ThrowExceptionForHR(hr); } return S_Ok; } catch (Exception e) { return Marshal.GetHRForException(e); } }