/////////////////////////////////////////////////////////////////////
        // 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");
        }
Exemple #2
0
 public static extern void MFCreateASFIndexer(
     out IMFASFIndexer ppIIndexer);
        void CreateIndexer(IMFASFContentInfo pContentInfo, out IMFASFIndexer ai)
        {
            MFAsfIndexerFlags f;
            long l;
            int i;
            IMFMediaBuffer mb;
            int hr;

            hr = MFExtern.MFCreateASFIndexer(out ai);
            MFError.ThrowExceptionForHR(hr);
            hr = MFExtern.MFCreateMemoryBuffer(1000, out mb);
            MFError.ThrowExceptionForHR(hr);

            hr = ai.Initialize(pContentInfo);
            MFError.ThrowExceptionForHR(hr);

            hr = ai.GetIndexPosition(pContentInfo, out l);
            MFError.ThrowExceptionForHR(hr);

            hr = ai.GetFlags(out f);
            MFError.ThrowExceptionForHR(hr);

            hr = ai.SetFlags(f);
            MFError.ThrowExceptionForHR(hr);

            hr = ai.GetIndexByteStreamCount(out i);
            MFError.ThrowExceptionForHR(hr);

            hr = ai.GetCompletedIndex(mb, 0);
            MFError.ThrowExceptionForHR(hr);

            hr = ai.GetIndexWriteSpace(out l);
            MFError.ThrowExceptionForHR(hr);
        }