///////////////////////////////////////////////////////////////////// // 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"); }
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); }