Ejemplo n.º 1
0
        private void TranscodeWorker()
        {
            while (true)
            {
                MediaSample sample = null;

                lock (sync)
                {
                    if (samples.Count > 0)
                    {
                        sample = samples.Dequeue();
                    }
                }

                if (sample != null)
                {
                    if (!transcoder.Push(0, sample))
                    {
                        var error = transcoder.Error.Clone() as ErrorInfo;
                        LogError("Transcoder.Push", error);
                        transcoder.Close();
                        transcoder.Dispose();
                        Dispatcher.BeginInvoke(new Action <ErrorInfo>(SingalEncodeError), error);
                        return;
                    }
                }
                else
                {
                    if (stopEncodeThread)
                    {
                        transcoder.Flush();
                        transcoder.Close();
                        transcoder.Dispose();
                        return;
                    }
                    else
                    {
                        Thread.Sleep(1);
                    }
                }
            }
        }
        public int SampleCB(double SampleTime, IMediaSample pSample)
        {
            if (!bProcess)
            {
                lastSampleTime = SampleTime;
                return(WinAPI.E_FAIL);
            }

            // internal stats
            ++sampleIndex;
            long tStart, tEnd;

            pSample.GetMediaTime(out tStart, out tEnd);
            Debug.Assert(tStart < tEnd);
            Debug.Assert(tStart > lastMediaTime);
            sampleProcessed += tEnd - tStart;
            sampleDropped   += tStart - lastMediaTime - 1;
            lastMediaTime    = tEnd - 1;

            int    dataLen = pSample.GetActualDataLength();
            IntPtr bufPtr;
            int    hr = pSample.GetPointer(out bufPtr);

            Debug.Assert(0 == hr);

            // BEGIN TRACE

            int bufSize = pSample.GetSize();

            long timeStart, timeEnd;

            pSample.GetTime(out timeStart, out timeEnd);

            string msg = string.Format(
                "SampleCB ({0}) {1}, sampleTime:{2} datalen:{3} bufsize:{4} mediaTime:{5}-{6} time:{7}-{8}",
                name, sampleIndex, SampleTime, dataLen, bufSize, tStart, tEnd, timeStart, timeEnd);

            Trace.WriteLine(msg);

            if (tStart - lastMediaTime - 1 > 0)
            {
                msg = string.Format("!!! Frame drop: {0}", tStart - lastMediaTime - 1 > 0);
                Trace.WriteLine(msg);
            }

            //END TRACE

            byte[] buf = new byte[dataLen];
            Marshal.Copy(bufPtr, buf, 0, dataLen);

            if (file != null)
            {
                file.Write(buf, 0, dataLen);
            }

            //DBG - simulate encoding error
            //if (sampleIndex > 100)
            //    goto STOP_CAPTURE;

            if (mediaState != null && mediaState.mpeg2Enc != null)
            {
                PrimoSoftware.AVBlocks.Transcoder enc = mediaState.mpeg2Enc;
                MediaSample inputSample = new MediaSample();
                inputSample.Buffer    = new MediaBuffer(buf);
                inputSample.StartTime = Math.Max(SampleTime, 0);
                //TODO: end time

                try
                {
                    bool pushed = false;

                    // transcoder.Push() is not threads safe.
                    // lock (enc){ } ensure that only one thread is calling transcoder.Push()
                    lock (enc)
                    {
                        pushed = enc.Push(StreamNumber, inputSample);
                    }

                    if (pushed)
                    {
                        return(0);
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.WriteLine(ex.ToString());
                }

                Trace.WriteLine("PushSample FAILED");
            }

            //STOP_CAPTURE:

            Trace.WriteLine("SampleCB: Before Post STOP_CAPTURE");
            WinAPI.PostMessage(MainWindow, Util.WM_STOP_CAPTURE, new IntPtr(streamNumber), IntPtr.Zero);
            Trace.WriteLine("SampleCB: After Post STOP_CAPTURE");
            bProcess = false;
            return(WinAPI.E_FAIL);
        } // end of SampleCB