public File FileOpen(string sFile) { File cRetVal = null; try { cRetVal = new File(sFile); cRetVal.pFSSpec = Marshal.AllocCoTaskMem(266); if (QuickTimeAPI.noErr != QuickTimeAPI.FSMakeFSSpec(IntPtr.Zero, IntPtr.Zero, cRetVal.sFile, cRetVal.pFSSpec)) { throw new Exception("FSMakeFSSpec error");//TODO LANG } if (QuickTimeAPI.noErr != QuickTimeAPI.OpenMovieFile(cRetVal.pFSSpec, ref cRetVal.nFileHandle, 1)) { throw new Exception("OpenMovieFile error");//TODO LANG } if (QuickTimeAPI.noErr != QuickTimeAPI.NewMovieFromFile(out cRetVal.pMovie, cRetVal.nFileHandle, IntPtr.Zero, IntPtr.Zero, 1, IntPtr.Zero)) { throw new Exception("NewMovieFromFile error");//TODO LANG } } catch { cRetVal = null; } return(cRetVal); }
public quicktime() { if (!_bInit) { if (QuickTimeAPI.noErr != QuickTimeAPI.InitializeQTML(0)) { throw new Exception("InitializeQTML error"); //TODO LANG } if (QuickTimeAPI.noErr != QuickTimeAPI.EnterMovies()) { throw new Exception("EnterMovies error"); //TODO LANG } _bInit = true; } }
public File(string sFile) { _pHBMP = IntPtr.Zero; _pHDC = IntPtr.Zero; _pFrameBytes = IntPtr.Zero; _stFrameSize = new Size(720, 576); _nTotalFrames = 0; _nTimeScale = 0; this.sFile = new StringBuilder(sFile); QuickTimeAPI.c2pstr(this.sFile); // Convert to Pascal string nFileHandle = 0; pFSSpec = IntPtr.Zero; pMovie = IntPtr.Zero; pGWorld = IntPtr.Zero; pMAESession = IntPtr.Zero; pASBD = IntPtr.Zero; cABL = null; _aqVideoFrames = new Queue <byte[]>(); _aqAudioFrames = new Queue <byte[]>(); }
public Queue <byte[]> AudioSamplesGet(File cFile, int nFrameStart, int nFramesQty) { Queue <byte[]> aqRetVal = null; ulong nSamplingRate = 48000; ushort nChannelsQty = 2; ushort nBitsPerChannel = 16; ulong nSamplesActual; try { if (0 > nFrameStart) { nFrameStart = cFile.nAudioTimeCurrent; } cFile.nLastError = QuickTimeAPI.noErr; //char tmp = IntPtr.Zero; // Note: the "+1" makes it, of course, an (not necessarily strict) upper bound. nSamplesActual = (cFile.nTotalFrames * nSamplingRate) / cFile.nTimeScale + 1; UInt32 nFlags, nSamplesToFill = 1920, nSamplesFilled = 0; if (IntPtr.Zero == cFile.pMAESession) { cFile.nLastError = QuickTimeAPI.MovieAudioExtractionBegin(cFile.pMovie, 0, out cFile.pMAESession); if (cFile.nLastError != QuickTimeAPI.noErr) { throw new Exception("MovieAudioExtractionBegin error"); } IntPtr pAllChannelsDiscrete = IntPtr.Zero; try { pAllChannelsDiscrete = Marshal.AllocCoTaskMem(1); Marshal.WriteByte(pAllChannelsDiscrete, 1); // disable mixing of audio channels cFile.nLastError = QuickTimeAPI.MovieAudioExtractionSetProperty(cFile.pMAESession, QuickTimeAPI.kQTPropertyClass_MovieAudioExtraction_Movie, QuickTimeAPI.kQTMovieAudioExtractionMoviePropertyID_AllChannelsDiscrete, 1, pAllChannelsDiscrete); } finally { if (IntPtr.Zero != pAllChannelsDiscrete) { Marshal.FreeCoTaskMem(pAllChannelsDiscrete); } } if (cFile.nLastError != QuickTimeAPI.noErr) { throw new Exception("MovieAudioExtractionSetProperty for disable channels mixing error"); } uint nASBDSize = (uint)Marshal.SizeOf(typeof(QuickTimeAPI.AudioStreamBasicDescription)); cFile.pASBD = Marshal.AllocCoTaskMem((int)nASBDSize); cFile.nLastError = QuickTimeAPI.MovieAudioExtractionGetProperty(cFile.pMAESession, QuickTimeAPI.kQTPropertyClass_MovieAudioExtraction_Audio, QuickTimeAPI.kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription, nASBDSize, cFile.pASBD, IntPtr.Zero); if (cFile.nLastError != QuickTimeAPI.noErr) { throw new Exception(); } QuickTimeAPI.AudioStreamBasicDescription stASBD = (QuickTimeAPI.AudioStreamBasicDescription)Marshal.PtrToStructure(cFile.pASBD, typeof(QuickTimeAPI.AudioStreamBasicDescription)); // convert the ASBD to return noninterleaved PCM instead of non-interleaved Float32: stASBD.mFormatFlags = QuickTimeAPI.kAudioFormatFlagIsSignedInteger | QuickTimeAPI.kAudioFormatFlagIsPacked | QuickTimeAPI.kAudioFormatFlagsNativeEndian; stASBD.mBitsPerChannel = (uint)nBitsPerChannel; stASBD.mChannelsPerFrame = (uint)nChannelsQty; stASBD.mBytesPerFrame = (uint)(nBitsPerChannel / 8) * stASBD.mChannelsPerFrame; stASBD.mBytesPerPacket = stASBD.mBytesPerFrame; stASBD.mSampleRate = nSamplingRate; //stASBD.mFramesPerPacket = 1; Marshal.StructureToPtr(stASBD, cFile.pASBD, true); // set the new audio extraction ASBD: cFile.nLastError = QuickTimeAPI.MovieAudioExtractionSetProperty(cFile.pMAESession, QuickTimeAPI.kQTPropertyClass_MovieAudioExtraction_Audio, QuickTimeAPI.kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription, nASBDSize, cFile.pASBD); if (cFile.nLastError != QuickTimeAPI.noErr) { throw new Exception("AudioStreamBasicDescription processing error"); } cFile.cLayout = new QuickTimeAPI.AudioChannelLayout(); cFile.cLayout.mChannelLayoutTag = QuickTimeAPI.kAudioChannelLayoutTag_Stereo; cFile.cLayout.mNumberChannelDescriptions = 2; cFile.cLayout.mChannelDescriptions = new QuickTimeAPI.AudioChannelDescription[cFile.cLayout.mNumberChannelDescriptions]; cFile.cLayout.mChannelDescriptions[0] = new QuickTimeAPI.AudioChannelDescription(); cFile.cLayout.mChannelDescriptions[0].mChannelLabel = QuickTimeAPI.kAudioChannelLabel_Left; cFile.cLayout.mChannelDescriptions[1] = new QuickTimeAPI.AudioChannelDescription(); cFile.cLayout.mChannelDescriptions[1].mChannelLabel = QuickTimeAPI.kAudioChannelLabel_Right; cFile.nLastError = QuickTimeAPI.MovieAudioExtractionSetProperty(cFile.pMAESession, QuickTimeAPI.kQTPropertyClass_MovieAudioExtraction_Audio, QuickTimeAPI.kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout, cFile.cLayout.nSize, cFile.cLayout.pLayout); if (cFile.nLastError != QuickTimeAPI.noErr) { throw new Exception("MovieAudioExtractionSetProperty error"); } IntPtr pTimeRec = IntPtr.Zero; try { QuickTimeAPI.TimeRecord stTimeRec; uint nTimeRecordSize = (uint)Marshal.SizeOf(typeof(QuickTimeAPI.TimeRecord)); stTimeRec = new QuickTimeAPI.TimeRecord(); stTimeRec.scale = (int)cFile.nTimeScale; stTimeRec.pBase = IntPtr.Zero; stTimeRec.value.hi = 0; stTimeRec.value.lo = (uint)(nFrameStart * stTimeRec.scale); // for instance, to start at time 1:00.00 pTimeRec = Marshal.AllocCoTaskMem((int)nTimeRecordSize); Marshal.StructureToPtr(stTimeRec, pTimeRec, true); cFile.nLastError = QuickTimeAPI.MovieAudioExtractionSetProperty(cFile.pMAESession, QuickTimeAPI.kQTPropertyClass_MovieAudioExtraction_Movie, QuickTimeAPI.kQTMovieAudioExtractionMoviePropertyID_CurrentTime, nTimeRecordSize, pTimeRec); } finally { if (IntPtr.Zero != pTimeRec) { Marshal.FreeCoTaskMem(pTimeRec); } } if (cFile.nLastError != QuickTimeAPI.noErr) { throw new Exception("MovieAudioExtractionFillBuffer error"); } cFile.cABL = new QuickTimeAPI.AudioBufferList(); cFile.cABL.mNumberBuffers = 1; cFile.cABL.mBuffers = new QuickTimeAPI.AudioBuffer[cFile.cABL.mNumberBuffers]; cFile.cABL.mBuffers[0] = new QuickTimeAPI.AudioBuffer(); cFile.cABL.mBuffers[0].mNumberChannels = 2; cFile.cABL.mBuffers[0].mDataByteSize = (uint)(nSamplesToFill * nChannelsQty * (nBitsPerChannel / 8));//((((int)nSamplingRate * (nBitsPerChannel / 8) * nChannelsQty) / cFile.nTimeScale) * nFramesQty); } nSamplesActual = 0; //AudioBufferList bflst = { 1, { { 2, 1920 * 2 * 2, malloc(1920 * 2 * 2) } } }; aqRetVal = new Queue <byte[]>(); byte[] aSamples = null; for (int nIndx = 0; nFramesQty > nIndx; nIndx++) { nSamplesFilled = nSamplesToFill; cFile.nLastError = QuickTimeAPI.MovieAudioExtractionFillBuffer(cFile.pMAESession, ref nSamplesFilled, cFile.cABL.pABL, out nFlags); if (cFile.nLastError != QuickTimeAPI.noErr) { throw new Exception("MovieAudioExtractionFillBuffer error"); } if (0 < nSamplesFilled) { nSamplesActual += nSamplesFilled; aSamples = new byte[nSamplesFilled * nChannelsQty * (nBitsPerChannel / 8)]; Marshal.Copy(cFile.cABL.mBuffers[0].mData, aSamples, 0, aSamples.Length); aqRetVal.Enqueue(aSamples); } if (0 < (nFlags & QuickTimeAPI.kQTMovieAudioExtractionComplete)) { QuickTimeAPI.MovieAudioExtractionEnd(cFile.pMAESession); break; } } if (cFile.nLastError != QuickTimeAPI.noErr) { throw new Exception("MovieAudioExtractionFillBuffer error"); } cFile.nAudioTimeCurrent += (int)(nSamplesActual / nSamplingRate * cFile.nTimeScale); } catch { if (QuickTimeAPI.noErr == cFile.nLastError) { cFile.nLastError = 1; } } return(aqRetVal); }
public Queue <byte[]> VideoFramesGet(File cFile, int nFrameStart, int nFramesQty) { Queue <byte[]> aqRetVal = null; try { cFile.nLastError = 0; if (IntPtr.Zero == cFile.pGWorld) { //if (QuickTimeAPI.noErr != QuickTimeAPI.NewGWorldFromHBITMAP(out cFile.pGWorld, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, cFile.pHBMP, cFile.pHDC)) IntPtr pRect = Marshal.AllocCoTaskMem(8); QuickTimeAPI.MacSetRect(pRect, 0, 0, (short)cFile.nFrameWidth, (short)cFile.nFrameHeight); if (QuickTimeAPI.noErr != QuickTimeAPI.GetMoviesError()) { throw new Exception("MacSetRect error");//TODO LANG } if (QuickTimeAPI.noErr != QuickTimeAPI.NewGWorldFromPtr(out cFile.pGWorld, QuickTimeAPI.k32BGRAPixelFormat, pRect, IntPtr.Zero, IntPtr.Zero, 0, cFile.pFrameBytes, (int)(cFile.nBytesPerFrame / cFile.nFrameHeight))) { throw new Exception("NewGWorldFromPtr error");//TODO LANG } QuickTimeAPI.SetMovieGWorld(cFile.pMovie, cFile.pGWorld, IntPtr.Zero); if (QuickTimeAPI.noErr != QuickTimeAPI.GetMoviesError()) { throw new Exception("SetMovieGWorld error");//TODO LANG } Marshal.FreeCoTaskMem(pRect); } short nFlags = (short)(QuickTimeAPI.nextTimeMediaSample | QuickTimeAPI.nextTimeEdgeOK); uint[] aTypes = new uint[1]; aTypes[0] = QuickTimeAPI.VideoMediaType; int nMovieNextTime = 0, nDuration = 0, nFramesGrabbed = 0; if (0 > nFrameStart) { if (0 < cFile.nVideoTimeCurrent) { nFrameStart = cFile.nVideoTimeCurrent - 1; nFlags = (short)QuickTimeAPI.nextTimeMediaSample; } else { nFrameStart = 0; } } else if (0 < nFrameStart) { nFrameStart--; nFlags = (short)QuickTimeAPI.nextTimeMediaSample; } QuickTimeAPI.SetMovieTimeValue(cFile.pMovie, nFrameStart); byte[] aFrameBytes; aqRetVal = new Queue <byte[]>(); while (nFramesQty > nFramesGrabbed) { QuickTimeAPI.GetMovieNextInterestingTime(cFile.pMovie, nFlags, (short)aTypes.Length, aTypes, nFrameStart, 1, out nMovieNextTime, out nDuration); cFile.nLastError = QuickTimeAPI.GetMoviesError(); if (QuickTimeAPI.noErr != cFile.nLastError) { break; } QuickTimeAPI.SetMovieTimeValue(cFile.pMovie, nMovieNextTime); cFile.nLastError = QuickTimeAPI.GetMoviesError(); if (QuickTimeAPI.noErr != cFile.nLastError) { break; } nFrameStart = nMovieNextTime; QuickTimeAPI.MoviesTask(cFile.pMovie, 0); aFrameBytes = new byte[cFile.nBytesPerFrame]; Marshal.Copy(cFile.pFrameBytes, aFrameBytes, 0, aFrameBytes.Length); aqRetVal.Enqueue(aFrameBytes); nFramesGrabbed++; nFlags = QuickTimeAPI.nextTimeMediaSample; } if (-1 < nFrameStart) { cFile.nVideoTimeCurrent = nFrameStart + 1; } } catch { cFile.nLastError = 1; } return(aqRetVal); }