示例#1
0
        //-------------------------------------------------------------------
        // Name: ValidStateMatrix
        // Description: Class-static matrix of operations vs states.
        //
        // If an entry is TRUE, the operation is valid from that state.
        //-------------------------------------------------------------------
        bool ValidStateMatrix(State stat, CAsyncOperation.StreamOperation so)
        {
            if (m_ValidStateMatrix == null)
            {
                m_ValidStateMatrix = new bool[(int)State.Count, (int)CAsyncOperation.StreamOperation.Op_Count];

                // Note about states:
                // 1. OnClockRestart should only be called from paused state.
                // 2. While paused, the sink accepts samples but does not process them.

                m_ValidStateMatrix[(int)State.TypeNotSet, (int)CAsyncOperation.StreamOperation.OpSetMediaType] = true;
                m_ValidStateMatrix[(int)State.TypeNotSet, (int)CAsyncOperation.StreamOperation.OpStart] = false;
                m_ValidStateMatrix[(int)State.TypeNotSet, (int)CAsyncOperation.StreamOperation.OpRestart] = false;
                m_ValidStateMatrix[(int)State.TypeNotSet, (int)CAsyncOperation.StreamOperation.OpPause] = false;
                m_ValidStateMatrix[(int)State.TypeNotSet, (int)CAsyncOperation.StreamOperation.OpStop] = false;
                m_ValidStateMatrix[(int)State.TypeNotSet, (int)CAsyncOperation.StreamOperation.OpProcessSample] = false;
                m_ValidStateMatrix[(int)State.TypeNotSet, (int)CAsyncOperation.StreamOperation.OpPlaceMarker] = false;
                m_ValidStateMatrix[(int)State.TypeNotSet, (int)CAsyncOperation.StreamOperation.OpFinalize] = false;

                m_ValidStateMatrix[(int)State.Ready, (int)CAsyncOperation.StreamOperation.OpSetMediaType] = true;
                m_ValidStateMatrix[(int)State.Ready, (int)CAsyncOperation.StreamOperation.OpStart] = true;
                m_ValidStateMatrix[(int)State.Ready, (int)CAsyncOperation.StreamOperation.OpRestart] = false;
                m_ValidStateMatrix[(int)State.Ready, (int)CAsyncOperation.StreamOperation.OpPause] = true;
                m_ValidStateMatrix[(int)State.Ready, (int)CAsyncOperation.StreamOperation.OpStop] = true;
                m_ValidStateMatrix[(int)State.Ready, (int)CAsyncOperation.StreamOperation.OpProcessSample] = false;
                m_ValidStateMatrix[(int)State.Ready, (int)CAsyncOperation.StreamOperation.OpPlaceMarker] = true;
                m_ValidStateMatrix[(int)State.Ready, (int)CAsyncOperation.StreamOperation.OpFinalize] = true;

                m_ValidStateMatrix[(int)State.Started, (int)CAsyncOperation.StreamOperation.OpSetMediaType] = false;
                m_ValidStateMatrix[(int)State.Started, (int)CAsyncOperation.StreamOperation.OpStart] = true;
                m_ValidStateMatrix[(int)State.Started, (int)CAsyncOperation.StreamOperation.OpRestart] = false;
                m_ValidStateMatrix[(int)State.Started, (int)CAsyncOperation.StreamOperation.OpPause] = true;
                m_ValidStateMatrix[(int)State.Started, (int)CAsyncOperation.StreamOperation.OpStop] = true;
                m_ValidStateMatrix[(int)State.Started, (int)CAsyncOperation.StreamOperation.OpProcessSample] = true;
                m_ValidStateMatrix[(int)State.Started, (int)CAsyncOperation.StreamOperation.OpPlaceMarker] = true;
                m_ValidStateMatrix[(int)State.Started, (int)CAsyncOperation.StreamOperation.OpFinalize] = true;

                m_ValidStateMatrix[(int)State.Paused, (int)CAsyncOperation.StreamOperation.OpSetMediaType] = false;
                m_ValidStateMatrix[(int)State.Paused, (int)CAsyncOperation.StreamOperation.OpStart] = true;
                m_ValidStateMatrix[(int)State.Paused, (int)CAsyncOperation.StreamOperation.OpRestart] = true;
                m_ValidStateMatrix[(int)State.Paused, (int)CAsyncOperation.StreamOperation.OpPause] = true;
                m_ValidStateMatrix[(int)State.Paused, (int)CAsyncOperation.StreamOperation.OpStop] = true;
                m_ValidStateMatrix[(int)State.Paused, (int)CAsyncOperation.StreamOperation.OpProcessSample] = true;
                m_ValidStateMatrix[(int)State.Paused, (int)CAsyncOperation.StreamOperation.OpPlaceMarker] = true;
                m_ValidStateMatrix[(int)State.Paused, (int)CAsyncOperation.StreamOperation.OpFinalize] = true;

                m_ValidStateMatrix[(int)State.Stopped, (int)CAsyncOperation.StreamOperation.OpSetMediaType] = false;
                m_ValidStateMatrix[(int)State.Stopped, (int)CAsyncOperation.StreamOperation.OpStart] = true;
                m_ValidStateMatrix[(int)State.Stopped, (int)CAsyncOperation.StreamOperation.OpRestart] = false;
                m_ValidStateMatrix[(int)State.Stopped, (int)CAsyncOperation.StreamOperation.OpPause] = false;
                m_ValidStateMatrix[(int)State.Stopped, (int)CAsyncOperation.StreamOperation.OpStop] = true;
                m_ValidStateMatrix[(int)State.Stopped, (int)CAsyncOperation.StreamOperation.OpProcessSample] = false;
                m_ValidStateMatrix[(int)State.Stopped, (int)CAsyncOperation.StreamOperation.OpPlaceMarker] = true;
                m_ValidStateMatrix[(int)State.Stopped, (int)CAsyncOperation.StreamOperation.OpFinalize] = true;

                m_ValidStateMatrix[(int)State.Finalized, (int)CAsyncOperation.StreamOperation.OpSetMediaType] = false;
                m_ValidStateMatrix[(int)State.Finalized, (int)CAsyncOperation.StreamOperation.OpStart] = false;
                m_ValidStateMatrix[(int)State.Finalized, (int)CAsyncOperation.StreamOperation.OpRestart] = false;
                m_ValidStateMatrix[(int)State.Finalized, (int)CAsyncOperation.StreamOperation.OpPause] = false;
                m_ValidStateMatrix[(int)State.Finalized, (int)CAsyncOperation.StreamOperation.OpStop] = false;
                m_ValidStateMatrix[(int)State.Finalized, (int)CAsyncOperation.StreamOperation.OpProcessSample] = false;
                m_ValidStateMatrix[(int)State.Finalized, (int)CAsyncOperation.StreamOperation.OpPlaceMarker] = false;
                m_ValidStateMatrix[(int)State.Finalized, (int)CAsyncOperation.StreamOperation.OpFinalize] = false;
            }

            return m_ValidStateMatrix[(int)stat, (int)so];
        }
示例#2
0
        //-------------------------------------------------------------------
        // Name: ValidateOperation
        // Description: Checks if an operation is valid in the current state.
        //-------------------------------------------------------------------
        void ValidateOperation(CAsyncOperation.StreamOperation op)
        {
            Debug.Assert(!m_IsShutdown);

            bool bTransitionAllowed = ValidStateMatrix(m_state, op);
            if (!bTransitionAllowed)
            {
                throw new COMException("Not valid from current state", MFError.MF_E_INVALIDREQUEST);
            }
        }
示例#3
0
        //-------------------------------------------------------------------
        // Name: DispatchProcessSample
        // Description: Complete a ProcessSample or PlaceMarker request.
        //-------------------------------------------------------------------
        void DispatchProcessSample(CAsyncOperation pOp)
        {
            Debug.Assert(pOp != null);

            try
            {
                ProcessSamplesFromQueue(FlushState.WriteSamples);

                // Ask for another sample
                if (pOp.m_op == CAsyncOperation.StreamOperation.OpProcessSample)
                {
                    QueueEvent(MediaEventType.MEStreamSinkRequestSample, Guid.Empty, 0, null);
                }
            }
            catch (Exception e)
            {
                int hr = Marshal.GetHRForException(e);

                // We are in the middle of an asynchronous operation, so if something failed, send an error.
                QueueEvent(MediaEventType.MEError, Guid.Empty, hr, null);
            }
        }
示例#4
0
        //-------------------------------------------------------------------
        // Name: QueueAsyncOperation
        // Description: Puts an async operation on the work queue.
        //-------------------------------------------------------------------
        void QueueAsyncOperation(CAsyncOperation.StreamOperation op)
        {
            int hr;
            CAsyncOperation pOp = new CAsyncOperation(op); // Created with ref count = 1

            hr = MFExtern.MFPutWorkItem(m_WorkQueueId, this, pOp);
            MFError.ThrowExceptionForHR(hr);

            //SAFE_RELEASE(pOp);
        }
示例#5
0
        //-------------------------------------------------------------------
        // Name: DispatchFinalize
        // Description: Complete a BeginFinalize request.
        //-------------------------------------------------------------------
        void DispatchFinalize(CAsyncOperation pOp)
        {
            int hr;
            int cbSize = 0;
            int cbWritten = 0;

            try
            {
                WAV_FILE_HEADER header = new WAV_FILE_HEADER();

                int cbFileSize = m_cbDataWritten + Marshal.SizeOf(typeof(WAV_FILE_HEADER)) - Marshal.SizeOf(typeof(RIFFCHUNK));

                // Write any samples left in the queue...
                ProcessSamplesFromQueue(FlushState.WriteSamples);

                // Now we're done writing all of the audio data.

                // Fill in the RIFF headers...
                hr = MFExtern.MFCreateWaveFormatExFromMFMediaType(m_pCurrentType, out header.WaveFormat, out cbSize, MFWaveFormatExConvertFlags.Normal);
                MFError.ThrowExceptionForHR(hr);

                header.FileHeader = new RIFFCHUNK();
                header.FileHeader.fcc = new FourCC('R', 'I', 'F', 'F');
                header.FileHeader.cb = cbFileSize;
                header.fccWaveType = new FourCC('W', 'A', 'V', 'E');

                header.WaveHeader = new RIFFCHUNK();
                header.WaveHeader.fcc = new FourCC('f', 'm', 't', ' ');
                header.WaveHeader.cb = Marshal.SizeOf(typeof(WaveFormatEx));

                header.DataHeader = new RIFFCHUNK();
                header.DataHeader.fcc = new FourCC('d', 'a', 't', 'a');
                header.DataHeader.cb = m_cbDataWritten;

                // Move the file pointer back to the start of the file and write the
                // RIFF headers.
                hr = m_pByteStream.SetCurrentPosition(0);
                MFError.ThrowExceptionForHR(hr);

                IntPtr ip = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(WAV_FILE_HEADER)));

                try
                {
                    Marshal.StructureToPtr(header, ip, false);
                    hr = m_pByteStream.Write(ip, Marshal.SizeOf(typeof(WAV_FILE_HEADER)), out cbWritten);
                    MFError.ThrowExceptionForHR(hr);
                }
                finally
                {
                    Marshal.FreeCoTaskMem(ip);
                }

                // Close the byte stream.
                hr = m_pByteStream.Close();
                MFError.ThrowExceptionForHR(hr);

                hr = 0;
            }
            catch (Exception e)
            {
                hr = Marshal.GetHRForException(e);
            }

            // Set the async status and invoke the callback.
            hr = m_pFinalizeResult.SetStatus(hr);
            MFError.ThrowExceptionForHR(hr);
            hr = MFExtern.MFInvokeCallback(m_pFinalizeResult);
            MFError.ThrowExceptionForHR(hr);
        }