CSharpRTMP.Core.Streaming.FLVDocument.BuildFrames C# (CSharp) Method

BuildFrames() protected method

protected BuildFrames ( ) : bool
return bool
        protected override bool BuildFrames()
        {
            var binaryHeaders = new List<MediaFrame>();
            //1. Go to the beginning of the file
            if (!MediaFile.SeekBegin())
            {
                Logger.FATAL("Unable to seek in file");
                return false;
            }

            //2. Ignore the flv header
            if (!MediaFile.SeekAhead(9))
            {
                Logger.FATAL("Unable to seek in file");
                return false;
            }

            //3. We are not interested in the previous tag size
            if (!MediaFile.SeekAhead(4))
            {
                Logger.FATAL("Unable to seek in file");
                return false;
            }

            //4. Build the frames
            while (MediaFile.Position != MediaFile.Length)
            {
                //5. Read the tag type
                byte tagType;
                if (!MediaFile.ReadUInt8(out tagType))
                {
                    Logger.WARN("Unable to read data");
                    break;
                }

                //6. Set the frame type based on the tag type
                //Also set the iskeyFrame property here
                var mustBreak = false;
                var frame = new MediaFrame();
                switch (tagType)
                {
                    case 8: //audio data
                        _audioSamplesCount++;
                        frame.Type = MediaFrameType.Audio;
                        break;
                    case 9: //video data
                        _videoSamplesCount++;
                        frame.Type = MediaFrameType.Video;
                        break;
                    case 15://message data
                        frame.Type = MediaFrameType.Message;
                        break;
                    case 18: //info data
                        frame.Type = MediaFrameType.Data;
                        break;
                    default:
                        Logger.WARN("Invalid tag type: {0} at cursor {1}", tagType, MediaFile.Position);
                        mustBreak = true;
                        break;
                }
                if (mustBreak) break;

                //7. Read the frame length
                uint tempLength = MediaFile.Br.ReadU24();
                //if (!MediaFile.ReadUInt24(out tempLength))
                //{
                //    Logger.WARN("Unable to read data");
                //    break;
                //}
                frame.Length = tempLength;

                //8. read the timestamp and set the timing on the frame
                var timestamp = MediaFile.Br.ReadSU32();
                //if (!MediaFile.ReadSUI32(out timestamp))
                //{
                //    Logger.WARN("Unable to read data");
                //    break;
                //}
                //TODO: correctly compute delta time
                frame.DeltaTime = 0;
                frame.AbsoluteTime = timestamp;

                //9. Ignore the stream ID
                if (!MediaFile.SeekAhead(3))
                {
                    Logger.WARN("Unable to seek in file");
                    break;
                }

                //10. Save the start of the data
                frame.Start = (uint)MediaFile.Position;

                //11. Set the isKeyFrame flag and the isBinary flag
                byte _byte;
                switch (frame.Type)
                {
                    case MediaFrameType.Video:
                        if (!MediaFile.PeekByte(out _byte))
                        {
                            Logger.FATAL("Unable to peek byte");
                            return false;
                        }
                        frame.IsKeyFrame = ((_byte >> 4) == 1);
                        if (frame.IsKeyFrame)
                        {
                            frame.IsBinaryHeader = ((_byte & 0x0f) == 7);
                            if (frame.IsBinaryHeader)
                            {
                                ulong dword;
                                if (!MediaFile.PeekUInt64(out dword))
                                {
                                    Logger.FATAL("Unable to peek byte");
                                    return false;
                                }
                                frame.IsBinaryHeader = (((dword >> 48) & 0xff) == 0);
                            }
                        }
                        else
                        {
                            frame.IsBinaryHeader = false;
                        }
                    
                        break;
                    case MediaFrameType.Audio:
                        frame.IsKeyFrame = true;
                        if (!MediaFile.PeekByte(out _byte))
                        {
                            Logger.FATAL("Unable to peek byte");
                            return false;
                        }
                        frame.IsBinaryHeader = ((_byte >> 4) == 10);
                        if (frame.IsBinaryHeader)
                        {
                            ushort word;
                            if (!MediaFile.PeekUInt16(out word))
                            {
                                Logger.FATAL("Unable to peek byte");
                                return false;
                            }
                            frame.IsBinaryHeader = ((word & 0x00ff) == 0);
                        }
                    
                        break;
                }
                if (frame.IsBinaryHeader)
                    Logger.WARN("frame: {0}", frame);

                if (!MediaFile.SeekAhead(frame.Length))
                {
                    Logger.WARN("Unable to seek in file");
                    break;
                }


                //13. We are not interested in the previous tag size
                //if (!MediaFile.SeekAhead(4))
                //{
                //    Logger.WARN("Unable to seek in file");
                //    break;
                //}
                var preTagSize = MediaFile.Br.ReadInt32();
                //14. Store it in the proper location and adjust the timestamp accordingly
                //if (frame.IsBinaryHeader)
                //{
                    //frame.AbsoluteTime = 0;
                    binaryHeaders.Insert(0, frame);
                    //binaryHeaders.Add(frame);

                //}
                //else
               // {
                    _frames.Add(frame);

               // }
            }
            //_frames.Sort(CompareFrames);

            //15. Add the binary headers
            //_frames.InsertRange(0, binaryHeaders);
            //for (var i = 0; i < binaryHeaders.Count; i++) {
            //    _frames.Insert(0, binaryHeaders[i]);

            //}

            return true;
        }