예제 #1
0
        private IEnumerator <Nalu> GetAllNalus(Stream fs)
        {
            fs.Seek(0, SeekOrigin.Begin);

            uint offset = 0;

            ReadHeader(fs, ref offset);

            for (; ;)
            {
                long   fsPos = fs.Position;
                FLVTag tag   = ReadTag(fs, ref offset);
                if (tag != null)
                {
                    var x = GetNalus(tag, fsPos);
                    while (x.MoveNext())
                    {
                        yield return(x.Current);
                    }
                }
                else
                {
                    break;
                }
            }

            yield break;
        }
예제 #2
0
        //tag type, tag size, tag data
        private FLVTag ReadTag(Stream fs, ref uint offset)
        {
            try
            {
                FLVTag result = new FLVTag();

                //prev tag size
                if (fs.ReadBlock(4) == null)
                {
                    return(null);
                }
                offset += 4;

                result.tagType = fs.ReadU8();
                offset        += 1;
                result.tagSize = fs.ReadU24BE();
                offset        += 3;

                //timestamp
                fs.ReadU24BE();
                offset += 3;
                //timestamp ext
                fs.ReadU8();
                offset += 1;

                //stream id
                fs.ReadU24BE();
                offset += 3;

                result.tagDataOffset = offset;

                // tag > 10M, maybe parse in wrong position
                if (result.tagSize > 10485760)
                {
                    throw new FLVToolException(fs.Position, "Tag data > 10M, maybe an error.");
                }
                result.tagData = fs.ReadBlock(result.tagSize);
                offset        += result.tagSize;

                return(result);
            }
            catch (EndOfStreamException)
            {
                return(null);
            }
        }
예제 #3
0
        private IEnumerator <Nalu> GetNalus(FLVTag tag, long fsPos)
        {
            if (tag.tagType == 9)
            {
                MemoryStream ms     = new MemoryStream(tag.tagData);
                uint         offset = tag.tagDataOffset;

                //frame type and codec id
                uint tmp = ms.ReadU8();
                offset += 1;

                if ((tmp & 0xf) == 7)
                {
                    uint avcpkttype = ms.ReadU8();
                    offset += 1;

                    if (avcpkttype == 1) //nalu
                    {
                        //composition time
                        ms.ReadU24BE();
                        offset += 3;

                        //avcc to annex-b
                        while (ms.Position < ms.Length)
                        {
                            Nalu nalu = new Nalu();
                            nalu.type   = Nalu.NaluType.OTHER;
                            nalu.offset = offset;

                            uint len = ms.ReadU32BE();
                            offset   += 4;
                            nalu.len  = len;
                            nalu.data = startcode.Append(ms.ReadBlock(len));
                            offset   += len;
                            yield return(nalu);
                        }
                    }
                    else if (avcpkttype == 0) //sps pps
                    {
                        //???
                        ms.ReadU24BE();
                        offset += 3;

                        //conf ver
                        ms.ReadU8();
                        offset += 1;

                        //avc profile
                        ms.ReadU8();
                        offset += 1;

                        //profile compatibility
                        ms.ReadU8();
                        offset += 1;

                        //avc level
                        ms.ReadU8();
                        offset += 1;

                        //length size - 1
                        uint len_minus_one = ms.ReadU8();
                        if (len_minus_one != 0xff)
                        {
                            throw new FLVToolException(fsPos + ms.Position - 1, "lengthSizeMinusOne != 3 in SPS, not supported");
                        }
                        offset += 1;

                        //sps count | 11100000
                        uint spsCntRaw = ms.ReadU8();
                        int  spscount  = (int)(spsCntRaw) & 0x1f;
                        offset += 1;

                        //sps
                        for (int i = 0; i < spscount; ++i)
                        {
                            Nalu nalu = new Nalu();
                            nalu.type   = Nalu.NaluType.SPS;
                            nalu.offset = offset;

                            uint spslen = ms.ReadU16BE();
                            offset   += 2;
                            nalu.len  = spslen + 2;
                            nalu.data = startcode.Append(ms.ReadBlock(spslen));
                            offset   += spslen;
                            yield return(nalu);
                        }

                        //pps count
                        int ppscount = (int)(ms.ReadU8());
                        offset += 1;

                        //pps
                        for (int i = 0; i < ppscount; ++i)
                        {
                            Nalu nalu = new Nalu();
                            nalu.type   = Nalu.NaluType.PPS;
                            nalu.offset = offset;

                            uint ppslen = ms.ReadU16BE();
                            offset   += 2;
                            nalu.len  = ppslen + 2;
                            nalu.data = startcode.Append(ms.ReadBlock(ppslen));
                            offset   += ppslen;
                            yield return(nalu);
                        }
                    }
                }
            }
        }