Пример #1
0
        /// <summary>
        /// IsNALBlockFormat
        /// Determine whether _contents have byte counts.
        /// </summary>
        /// <returns>True if byte counts are found.</returns>
        public static bool IsNALBlockFormat(BinaryReader reader, uint size, out uint totalSize)
        {
            uint count = CPUGenderDependencies.UINT(reader.ReadUInt32());

            totalSize = size; // size is unchanged
            if (count == 0)
            {
                reader.BaseStream.Position -= 4;
                return(false);
            }
            else if (count == 1)
            {
                return(false); // count cannot be 1
            }
            else if (count > size)
            {
                reader.BaseStream.Position -= 4;
                return(false);
            }
            byte b = reader.ReadByte();
            byte c = reader.ReadByte();

            if (!CheckNALUType(b, c))
            {
                reader.BaseStream.Position -= 6;
                return(false);
            }

            reader.BaseStream.Position += ((int)(count - 2)); // ignore all subsequent bytes
            totalSize = size - count;
            return(true);
        }
Пример #2
0
        /// <summary>
        /// H264Stream
        /// Used by Players to convert from blocks (which has byte counts) to a bit stream delimited by 001 or 0001.
        /// </summary>
        /// <param name="inFirst">Is this the first block? If so, insert SPS and PPS (CodecPrivateData) into the bit stream.</param>
        /// <param name="inCodecPrivateData">CodecPrivateData taken from containing MP4.</param>
        /// <param name="inStream">Input block stream.</param>
        /// <param name="inStart">Starting location in the input block stream.</param>
        /// <param name="inSize">Count of bytes to process.</param>
        /// <returns></returns>
        public static Stream H264Stream(bool inFirst, String inCodecPrivateData, Stream inStream, uint inStart, uint inSize)
        {
            Stream stream = new MemoryStream();

            // ag ag = A_0 as ag;
            //string methodName = "ProcessH264";
            if (inFirst)
            {
                string str2   = inCodecPrivateData; // ag.c()[MediaStreamAttributeKeys.CodecPrivateData];
                byte[] buffer = HexStringToBytes(str2);
                if (buffer != null)
                {
                    int index = 0;
                    stream.WriteByte(0);
                    stream.WriteByte(0);
                    stream.WriteByte(0);
                    stream.WriteByte(1);
                    //          Tracing.Trace(a, methodName, TraceArea.MediaStreamSource, TraceLevel.Verbose, "Appending sps & pps for {0}", new object[] { A_2.b() });
                    index = 4;
                    while (index < buffer.Length)
                    {
                        if (((buffer[index] == 0) && (buffer[index + 1] == 0)) && ((buffer[index + 2] == 0) && (1 == buffer[index + 3])))
                        {
                            break;
                        }
                        stream.WriteByte(buffer[index++]);
                    }
                    index += 4;
                    stream.WriteByte(0);
                    stream.WriteByte(0);
                    stream.WriteByte(0);
                    stream.WriteByte(1);
                    stream.Write(buffer, index, buffer.Length - index);
                }
            }

            ulong num2 = (ulong)inSize;

            inStream.Seek((long)inStart, SeekOrigin.Begin);
            BinaryReader reader = new BinaryReader(inStream);

            // FIXME: Need to check for occurrence of 001 within data. If found replace by data replacement token that prevents
            // false detection of start token. As it stands, there is a possibility of a false token in the data that could make the output
            // invalid.
            while (num2 > 4L)
            {
                ulong num3 = CPUGenderDependencies.UINT(reader.ReadUInt32());
                num2 -= ((ulong)4L) + num3;
                stream.WriteByte(0);
                stream.WriteByte(0);
                stream.WriteByte(0);
                stream.WriteByte(1);
                int count = (int)num3;
                stream.Write(reader.ReadBytes(count), 0, count);
            }

            return(stream);
        }
Пример #3
0
        /// <summary>
        /// IsBitStream
        /// Determine whether the input stream contains H264 bit stream (as opposed to blocks).
        /// </summary>
        /// <param name="mdatStream">Input H264 stream.</param>
        /// <returns></returns>
        public static bool IsBitStream(Stream mdatStream)
        {
            BinaryReader reader          = new BinaryReader(mdatStream);
            uint         first4ByteValue = CPUGenderDependencies.UINT(reader.ReadUInt32());

            if ((first4ByteValue < 512) && (first4ByteValue > 255) && CheckNALUType((byte)first4ByteValue, (byte)0)) // first 3 byte pattern is 001
            {
                return(true);                                                                                        // H264 bit stream
            }

            return(false);
        }
Пример #4
0
        /// <summary>
        /// InsertAccessUnitDelimiter
        /// NALU type 9 may be necessary for MediaElement to play a video stream.
        /// </summary>
        /// <param name="inStream">Input stream with Position set to beginning of a H264 block.</param>
        public static Stream InsertAccessUnitDelimiter(BinaryReader inStream, long offset, uint size)
        {
            inStream.BaseStream.Position = offset;

            uint count = 0;

            byte[] bytes      = new byte[4];
            byte[] copyBytes  = new byte[4];
            byte[] byteCount2 = new byte[4];
            byteCount2[0] = 0;
            byteCount2[1] = 0;
            byteCount2[2] = 0;
            byteCount2[3] = 2;
            byte   NALByte;
            Stream stream = new MemoryStream();

            for (; inStream.BaseStream.Position < (offset + size);)
            {
                count = CPUGenderDependencies.UINT(inStream.ReadUInt32());
                if ((count == 0) || (count > (inStream.BaseStream.Length - inStream.BaseStream.Position)))
                {
                    return(stream);
                }
                NALByte = inStream.ReadByte();
                byte NALUType  = (byte)(NALUTypeMask & NALByte);
                byte NALRefIDC = (byte)(RefIDCMask & NALByte);
                if ((MSBMask & NALByte) != 0)
                {
                    return(stream); // MSB must be zero
                }
                switch (NALUType)
                {
                case 1:
                    if (NALRefIDC == 0)
                    {
                        return(stream);
                    }
                    stream.Write(byteCount2, 0, 4);
                    stream.WriteByte((byte)9);
                    stream.WriteByte((byte)48);
                    break;

                case 2:
                case 3:
                case 4:
                    break;  // FIXME: just pass 2, 3, and 4 through?

                case 5:     // IDR
                    if (NALRefIDC == 0)
                    {
                        return(stream);
                    }
                    stream.Write(byteCount2, 0, 4);
                    stream.WriteByte((byte)9);
                    stream.WriteByte((byte)16);
                    break;

                case 6:     // supplemental enhancement information (SEI)
                case 7:     // sequence parameter set (SPS)
                case 8:     // picture parameter set (PPS)
                    if (NALRefIDC != 0)
                    {
                        return(stream);
                    }
                    break;

                case 9:     // access unit delimiter
                    // This is what we're trying to insert.
                    // It's already there, so
                    // use input stream as output, and we're done.
                    return(inStream.BaseStream);

                case 10:    // end of sequence
                    if (NALRefIDC != 0)
                    {
                        return(stream);
                    }
                    break;

                case 11:    // end of stream
                    if (NALRefIDC != 0)
                    {
                        return(stream);
                    }
                    break;

                case 12:    // filler
                    break;

                default:
                    return(stream);
                }
                stream.Write(copyBytes, 0, 4);
                stream.WriteByte(NALByte);
                stream.Write(inStream.ReadBytes((int)count - 5), 0, (int)count - 5);
            }
            return(stream);
        }