///////////////////////////////////////////////////////////////////// // Name: CreateASFSplitter // // Creates the ASF splitter. // // pContentInfo: Pointer to an initialized instance of the ASF // content information object. // ppSplitter: Receives a pointer to the ASF splitter. ///////////////////////////////////////////////////////////////////// void CreateASFSplitter(IMFASFContentInfo pContentInfo, out IMFASFSplitter ppSplitter) { MFASFSplitterFlags f; HResult hr; hr = MFExtern.MFCreateASFSplitter(out ppSplitter); MFError.ThrowExceptionForHR(hr); hr = ppSplitter.Initialize(pContentInfo); MFError.ThrowExceptionForHR(hr); hr = ppSplitter.GetFlags(out f); MFError.ThrowExceptionForHR(hr); Console.WriteLine(string.Format("Splitter flags: {0}", f)); }
public void DoSplit() { HResult hr; bool bHasVideo = false; IMFByteStream pStream = null; IMFASFContentInfo pContentInfo = null; IMFASFSplitter pSplitter = null; Console.WriteLine(string.Format("Opening {0}.", m_sFileName)); try { // Start the Media Foundation platform. hr = MFExtern.MFStartup(0x10070, MFStartup.Full); MFError.ThrowExceptionForHR(hr); // Open the file. OpenFile(m_sFileName, out pStream); // Read the ASF header. CreateContentInfo(pStream, out pContentInfo); // Create the ASF splitter. CreateASFSplitter(pContentInfo, out pSplitter); // Select the first video stream. SelectVideoStream(pContentInfo, pSplitter, out bHasVideo); // Parse the ASF file. if (bHasVideo) { DisplayKeyFrames(pStream, pSplitter); } else { Console.WriteLine("No video stream."); } } catch (Exception e) { hr = (HResult)Marshal.GetHRForException(e); string s = MFError.GetErrorText(hr); if (s == null) { s = e.Message; } else { s = string.Format("{0} ({1})", s, e.Message); } Console.WriteLine(string.Format("Exception 0x{0:x}: {1}", hr, s)); } finally { // Clean up. SafeRelease(pSplitter); SafeRelease(pContentInfo); SafeRelease(pStream); } // Shut down the Media Foundation platform. hr = MFExtern.MFShutdown(); MFError.ThrowExceptionForHR(hr); }
///////////////////////////////////////////////////////////////////// // 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( 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 HResult hr; IMFMediaBuffer pBuffer; IMFSample pSample; 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: SelectVideoStream // // Selects the first video stream for parsing with the ASF splitter. // // pContentInfo: Pointer to an initialized instance of the ASF // content information object. // pSplitter: Pointer to the ASF splitter. // pbHasVideo: Receives TRUE if there is a video stream, or FALSE // otherwise. ///////////////////////////////////////////////////////////////////// void SelectVideoStream( IMFASFContentInfo pContentInfo, IMFASFSplitter pSplitter, out bool pbHasVideo ) { int cStreams; short wStreamID = 33; short[] wStreamIDs = new short[1]; Guid streamType; bool bFoundVideo = false; HResult hr; IMFASFProfile pProfile; IMFASFStreamConfig pStream; // Get the ASF profile from the content information object. hr = pContentInfo.GetProfile(out pProfile); MFError.ThrowExceptionForHR(hr); try { // Loop through all of the streams in the profile. hr = pProfile.GetStreamCount(out cStreams); MFError.ThrowExceptionForHR(hr); for (int i = 0; i < cStreams; i++) { // Get the stream type and stream identifier. hr = pProfile.GetStream(i, out wStreamID, out pStream); MFError.ThrowExceptionForHR(hr); try { hr = pStream.GetStreamType(out streamType); MFError.ThrowExceptionForHR(hr); if (streamType == MFMediaType.Video) { bFoundVideo = true; break; } } finally { SafeRelease(pStream); } } } finally { SafeRelease(pProfile); } // Select the video stream, if found. if (bFoundVideo) { // SelectStreams takes an array of stream identifiers. wStreamIDs[0] = wStreamID; hr = pSplitter.SelectStreams(wStreamIDs, 1); MFError.ThrowExceptionForHR(hr); } pbHasVideo = bFoundVideo; }
public static extern void MFCreateASFSplitter( out IMFASFSplitter ppISplitter);
///////////////////////////////////////////////////////////////////// // Name: SelectVideoStream // // Selects the first video stream for parsing with the ASF splitter. // // pContentInfo: Pointer to an initialized instance of the ASF // content information object. // pSplitter: Pointer to the ASF splitter. // pbHasVideo: Receives TRUE if there is a video stream, or FALSE // otherwise. ///////////////////////////////////////////////////////////////////// void SelectVideoStream( IMFASFContentInfo pContentInfo, IMFASFSplitter pSplitter, out bool pbHasVideo ) { int cStreams; short wStreamID = 33; short[] wStreamIDs = new short[1]; Guid streamType; bool bFoundVideo = false; IMFASFProfile pProfile; IMFASFStreamConfig pStream; // Get the ASF profile from the content information object. int hr = pContentInfo.GetProfile(out pProfile); MFError.ThrowExceptionForHR(hr); try { // Loop through all of the streams in the profile. hr = pProfile.GetStreamCount(out cStreams); MFError.ThrowExceptionForHR(hr); for (int i = 0; i < cStreams; i++) { // Get the stream type and stream identifier. hr = pProfile.GetStream(i, out wStreamID, out pStream); MFError.ThrowExceptionForHR(hr); try { hr = pStream.GetStreamType(out streamType); MFError.ThrowExceptionForHR(hr); if (streamType == MFMediaType.Video) { bFoundVideo = true; break; } } finally { SafeRelease(pStream); } } } finally { SafeRelease(pProfile); } // Select the video stream, if found. if (bFoundVideo) { // SelectStreams takes an array of stream identifiers. wStreamIDs[0] = wStreamID; hr = pSplitter.SelectStreams(wStreamIDs, 1); MFError.ThrowExceptionForHR(hr); } pbHasVideo = bFoundVideo; }
///////////////////////////////////////////////////////////////////// // 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: CreateASFSplitter // // Creates the ASF splitter. // // pContentInfo: Pointer to an initialized instance of the ASF // content information object. // ppSplitter: Receives a pointer to the ASF splitter. ///////////////////////////////////////////////////////////////////// void CreateASFSplitter(IMFASFContentInfo pContentInfo, out IMFASFSplitter ppSplitter) { MFASFSplitterFlags f; int hr = MFExtern.MFCreateASFSplitter(out ppSplitter); MFError.ThrowExceptionForHR(hr); hr = ppSplitter.Initialize(pContentInfo); MFError.ThrowExceptionForHR(hr); hr = ppSplitter.GetFlags(out f); MFError.ThrowExceptionForHR(hr); Console.WriteLine(string.Format("Splitter flags: {0}", f)); }
///////////////////////////////////////////////////////////////////// // 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( 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 int hr; IMFMediaBuffer pBuffer; IMFSample pSample; 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"); }