Example #1
0
        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);
        }
Example #2
0
 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;
     }
 }
Example #3
0
            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[]>();
            }
Example #4
0
        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);
        }
Example #5
0
        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);
        }