Beispiel #1
0
        private uint ReadUInt32()
        {
            var x = new byte[4];

            _fs.Read(x, 0, 4);
            _fileOffset += 4;
            return(BitConverterBE.ToUInt32(x, 0));
        }
        private void ParseMP3Frames(byte[] buff)
        {
            var MPEG1BitRate     = new[] { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 };
            var MPEG2XBitRate    = new[] { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 };
            var MPEG1SampleRate  = new[] { 44100, 48000, 32000, 0 };
            var MPEG20SampleRate = new[] { 22050, 24000, 16000, 0 };
            var MPEG25SampleRate = new[] { 11025, 12000, 8000, 0 };

            var offset = 0;
            var length = buff.Length;

            while (length >= 4)
            {
                ulong header;
                int   mpegVersion, layer, bitRate, sampleRate, padding, channelMode;
                int   frameLen;

                header = (ulong)BitConverterBE.ToUInt32(buff, offset) << 32;
                if (BitHelper.Read(ref header, 11) != 0x7FF)
                {
                    break;
                }
                mpegVersion = BitHelper.Read(ref header, 2);
                layer       = BitHelper.Read(ref header, 2);
                BitHelper.Read(ref header, 1);
                bitRate    = BitHelper.Read(ref header, 4);
                sampleRate = BitHelper.Read(ref header, 2);
                padding    = BitHelper.Read(ref header, 1);
                BitHelper.Read(ref header, 1);
                channelMode = BitHelper.Read(ref header, 2);

                if (mpegVersion == 1 || layer != 1 || bitRate == 0 || bitRate == 15 || sampleRate == 3)
                {
                    break;
                }

                bitRate = (mpegVersion == 3 ? MPEG1BitRate[bitRate] : MPEG2XBitRate[bitRate]) * 1000;

                if (mpegVersion == 3)
                {
                    sampleRate = MPEG1SampleRate[sampleRate];
                }
                else if (mpegVersion == 2)
                {
                    sampleRate = MPEG20SampleRate[sampleRate];
                }
                else
                {
                    sampleRate = MPEG25SampleRate[sampleRate];
                }

                frameLen = GetFrameLength(mpegVersion, bitRate, sampleRate, padding);
                if (frameLen > length)
                {
                    break;
                }

                var isVBRHeaderFrame = false;
                if (_frameOffsets.Count == 0)
                {
                    // Check for an existing VBR header just to be safe (I haven't seen any in FLVs)
                    var o = offset + GetFrameDataOffset(mpegVersion, channelMode);
                    if (BitConverterBE.ToUInt32(buff, o) == 0x58696E67)
                    {                     // "Xing"
                        isVBRHeaderFrame = true;
                        _delayWrite      = false;
                        _hasVBRHeader    = true;
                    }
                }

                if (isVBRHeaderFrame)
                {
                }
                else if (_firstBitRate == 0)
                {
                    _firstBitRate     = bitRate;
                    _mpegVersion      = mpegVersion;
                    _sampleRate       = sampleRate;
                    _channelMode      = channelMode;
                    _firstFrameHeader = BitConverterBE.ToUInt32(buff, offset);
                }
                else if (!_isVBR && bitRate != _firstBitRate)
                {
                    _isVBR = true;
                    if (_hasVBRHeader)
                    {
                    }
                    else if (_delayWrite)
                    {
                        WriteVBRHeader(true);
                        _writeVBRHeader = true;
                        _delayWrite     = false;
                    }
                    else
                    {
                        _warnings.Add("Detected VBR too late, cannot add VBR header.");
                    }
                }

                _frameOffsets.Add(_totalFrameLength + (uint)offset);

                offset += frameLen;
                length -= frameLen;
            }

            _totalFrameLength += (uint)buff.Length;
        }
        public void WriteChunk(byte[] chunk, uint timeStamp, int frameType)
        {
            if (chunk.Length < 4)
            {
                return;
            }

            // Reference: decode_frame from libavcodec's h264.c

            if (chunk[0] == 0)
            {             // Headers
                if (chunk.Length < 10)
                {
                    return;
                }

                int offset, spsCount, ppsCount;

                offset         = 8;
                _nalLengthSize = (chunk[offset++] & 0x03) + 1;
                spsCount       = chunk[offset++] & 0x1F;
                ppsCount       = -1;

                while (offset <= chunk.Length - 2)
                {
                    if (spsCount == 0 && ppsCount == -1)
                    {
                        ppsCount = chunk[offset++];
                        continue;
                    }

                    if (spsCount > 0)
                    {
                        spsCount--;
                    }
                    else if (ppsCount > 0)
                    {
                        ppsCount--;
                    }
                    else
                    {
                        break;
                    }

                    var len = (int)BitConverterBE.ToUInt16(chunk, offset);
                    offset += 2;
                    if (offset + len > chunk.Length)
                    {
                        break;
                    }
                    _fs.Write(_startCode, 0, _startCode.Length);
                    _fs.Write(chunk, offset, len);
                    offset += len;
                }
            }
            else
            {             // Video data
                var offset = 4;

                if (_nalLengthSize != 2)
                {
                    _nalLengthSize = 4;
                }

                while (offset <= chunk.Length - _nalLengthSize)
                {
                    var len = _nalLengthSize == 2 ?
                              (int)BitConverterBE.ToUInt16(chunk, offset) :
                              (int)BitConverterBE.ToUInt32(chunk, offset);
                    offset += _nalLengthSize;
                    if (offset + len > chunk.Length)
                    {
                        break;
                    }
                    _fs.Write(_startCode, 0, _startCode.Length);
                    _fs.Write(chunk, offset, len);
                    offset += len;
                }
            }
        }
        public void WriteChunk(byte[] chunk, uint timeStamp, int frameType)
        {
            int offset, len;

            offset = 0;
            len    = chunk.Length;
            if (_codecID == 4)
            {
                offset = 1;
                len   -= 1;
            }
            if (_codecID == 5)
            {
                offset = 4;
                if (len >= 4)
                {
                    var alphaOffset = (int)BitConverterBE.ToUInt32(chunk, 0) & 0xFFFFFF;
                    if (!_isAlphaWriter)
                    {
                        len = alphaOffset;
                    }
                    else
                    {
                        offset += alphaOffset;
                        len    -= offset;
                    }
                }
                else
                {
                    len = 0;
                }
            }
            len = Math.Max(len, 0);
            len = Math.Min(len, chunk.Length - offset);

            _index.Add(frameType == 1 ? (uint)0x10 : (uint)0);
            _index.Add(_moviDataSize + 4);
            _index.Add((uint)len);

            if (_width == 0 && _height == 0)
            {
                GetFrameSize(chunk);
            }

            WriteFourCC("00dc");
            _bw.Write(len);
            _bw.Write(chunk, offset, len);

            if (len % 2 != 0)
            {
                _bw.Write((byte)0);
                len++;
            }
            _moviDataSize += (uint)len + 8;
            _frameCount++;

            if (_alphaWriter != null)
            {
                _alphaWriter.WriteChunk(chunk, timeStamp, frameType);
            }
        }