Пример #1
0
 internal void Prepare(byte[] source, int offset, int encodedlength, ushort stride, ushort height, ushort width, byte[] destination, int destinationoffset, int returnint, FrameControlFlags flags, Action <FrameTask, int> taskComplete)
 {
     this.isComplete        = false;
     this.source            = source;
     this.offset            = offset;
     this.encodedlength     = encodedlength;
     this.stride            = stride;
     this.height            = height;
     this.width             = width;
     this.destination       = destination;
     this.destinationoffset = destinationoffset;
     this.returnint         = returnint;
     if (flags.HasFlag(videoCodecs[0].EncodingFlag))
     {
         currentCodec = videoCodecs[0];
     }
     if (flags.HasFlag(videoCodecs[1].EncodingFlag))
     {
         currentCodec = videoCodecs[1];
     }
     completionCallback = taskComplete;
     if (flags.HasFlag(FrameControlFlags.IsKeyFrame))
     {
         isKeyFrame = true;
     }
     else
     {
         isKeyFrame = false;
     }
 }
Пример #2
0
        internal void AddToVideoBuffer(byte[] obj, int length)
        {
            //int offset = 0;

            if (length < VIDEOHEADERSIZE)
            {
                return;
            }
            FrameControlFlags control   = (FrameControlFlags)BitConverter.ToUInt32(obj, 0);
            ushort            stride    = BitConverter.ToUInt16(obj, sizeof(int));
            ushort            height    = BitConverter.ToUInt16(obj, sizeof(int) + sizeof(ushort));
            ushort            width     = BitConverter.ToUInt16(obj, sizeof(int) + sizeof(ushort) * 2);
            ushort            framerate = BitConverter.ToUInt16(obj, sizeof(int) + sizeof(ushort) * 3);
            int framesize = BitConverter.ToInt32(obj, sizeof(int) + sizeof(ushort) * 4);

            //MyLog.Default.WriteLine($"Packet Header: c {control} w {width} s {stride} h {height} f {framerate} fs {framesize} l {length}");


            if (stride * height * framerate > videoStride * videoHeight * videoFramerate)
            {
                videoFrameSize = framesize;
                videoStride    = stride;
                videoHeight    = height;
                videoFramerate = framerate;

                //TODO pause tasks

                InitializeVideoBuffer();                //remap
            }


            int writebytes = stride * height + VIDEOHEADERSIZE - sizeof(int);

            //MyLog.Default.WriteLine($"Writing to Video buffer? {writebytes} {offset} {length}");
            if (framesize + VIDEOHEADERSIZE <= length)
            {
                if (control.HasFlag(FrameControlFlags.IsKeyFrame))
                {
                    try
                    {
                        gotfirstvideokeyframe = true;
                        videosize++;
                        if (writevideoposition != -1)
                        {
                            if (maxframes[writevideoposition] != framecounter[writevideoposition])
                            {
                                maxframes[writevideoposition] = framecounter[writevideoposition];
                                if (taskQueue[writevideoposition] == 0 && completeQueue[writevideoposition] == maxframes[writevideoposition])
                                {
                                    decodevideosize++;
                                }
                            }
                        }


                        if (videosize >= 9)
                        {
                            decodevideosize--;
                            videosize--;
                        }
                        else
                        {
                            writevideoposition += 1;
                        }
                        writevideoposition               %= 10;
                        maxframes[writevideoposition]     = framerate;
                        completeQueue[writevideoposition] = 0;
                        framecounter[writevideoposition]  = 0;
                        hasKeyFrame[writevideoposition]   = false;
                        keyFrame[writevideoposition]      = null;
                        taskQueue[writevideoposition]     = 0;
                        vptr[writevideoposition]          = 0;
                        if (paused && audiosize >= 2 && videosize >= 2)
                        {
                            paused = false;
                        }
                    }
                    catch (Exception ex)
                    {
                        MyLog.Default.WriteLine(ex.ToString());
                    }
                }
                else if (!gotfirstvideokeyframe)
                {
                    return;
                }
                if (writevideoposition == -1 || vptr[writevideoposition] + writebytes > videostorage[writevideoposition].Length)
                {
                    return;                    //discard
                }
                framecounter[writevideoposition]++;
                FrameTask task;
                lock (taskPool)
                {
                    if (taskPool.Count > 0)
                    {
                        task = taskPool.Pop();
                    }
                    else
                    {
                        task = new FrameTask();
                    }
                }
                taskQueue[writevideoposition]++;
                //MyLog.Default.WriteLine($"Preparing Task {writevideoposition} {taskQueue[writevideoposition]} ");
                task.Prepare(obj, VIDEOHEADERSIZE, framesize, stride, height, width, videostorage[writevideoposition], vptr[writevideoposition] + VIDEOHEADERSIZE - sizeof(int), writevideoposition, control, TaskComplete);
                if (task.IsKeyFrame || hasKeyFrame[writevideoposition])
                {
                    task.StartBackground(keyFrame[writevideoposition]);
                }
                else
                {
                    lock (waitingOnKeyframe)
                    {
                        waitingOnKeyframe.Push(task);
                    }
                }

                //MyLog.Default.WriteLine($"Read {offset} {writebytes}  {obj.Length}");
                //MyLog.Default.WriteLine($"Write {vptr[writevideoposition]} {writebytes} {videostorage[writevideoposition].Length}");
                Buffer.BlockCopy(obj, 0, videostorage[writevideoposition], vptr[writevideoposition], VIDEOHEADERSIZE - sizeof(int));
                vptr[writevideoposition] += writebytes;
            }
        }