Esempio n. 1
0
        /// <summary>
        /// Scan matroska file and fill MkvTracks
        /// </summary>
        public void GetInfo()
        {
            // Debug
            log.Info("\r\nFile path: " + mpegFilePath + "\r\n" +
                     "File name: " + mpegFileName + "\r\n" +
                     "File size: " + mpegFileSize.ToString("#,##0"));

            streamManager = new MpegStreamManager(mpegFilePath);
            vStream = new MpegVideoStream();
            aStream = new MpegAudioStream();

            bool isVideo = mvp.Parse(ref streamManager);

            if (isVideo)
            {
                vStream = mvp.VideoStream;
            }

            bool isAudio = map.Parse(ref streamManager);

            if (isAudio)
            {
                aStream = map.AudioStream;
            }

            streamManager.Close();

            return;
        }
        /// <summary>
        /// Search audio stream using passed MpegStreamManager
        /// </summary>
        public bool Parse(ref MpegStreamManager msManager)
        {
            audioStream = new MpegAudioStream();
            long offset = 0;

            // Search 0x00 0x00 0x01 0xC0 marker [Audio Stream]
            bool isAudioContains =
                msManager.SearchMarker(ref offset, new byte[4]{0x00, 0x00, 0x01, 0xC0});

            if (!isAudioContains)
            {
                // there isn't audio
                return false;
            }

            offset += 13;

            bool isAudio = false;

            while (!isAudio && offset < (msManager.StreamSize - 10))
            {
                if ((msManager.GetByte(offset) == 0xFF) &&
                    (msManager.GetByte(offset + 1) & 0xF0) == 0xF0)
                {
                    isAudio = ParseAudioStream(ref msManager, offset);
                }
                offset ++;
            }

            if (isAudio)
            {
                // Audio information added
                return true;
            }

            return false;
        }
        /// <summary>
        /// Search video stream using passed MpegStreamManager
        /// </summary>
        public bool Parse(ref MpegStreamManager msManager)
        {
            videoStream = new MpegVideoStream();
            long offset = 0;

            // Search 0x00 0x00 0x01 0xB3 marker [Sequence header]
            bool isSeqHeader = msManager.SearchMarker(ref offset,
                                                      new byte[4]{0x00, 0x00, 0x01, 0xB3});

            if (!isSeqHeader)
            {
                // Sequence header not founded
                return false;
            }

            // skip marker bytes
            offset += 4;

            // read height and width
            videoStream.Width = msManager.GetSize(offset) >> 4;
            videoStream.Height = msManager.GetSize(offset + 1) & 0x0FFF;
            offset += 3;

            // read framerate
            int frameRateIndex = msManager.GetByte(offset) & 0x0F;

            if (frameRateIndex > 8)
            {
                // Reserved
                videoStream.FrameRate = 0.0d;
            }
            else
            {
                // Retrieve value from table
                videoStream.FrameRate = MpegConstants.FrameRateTable[frameRateIndex];
            }

            // read aspectratio
            int aspectRatioIndex = (msManager.GetByte(offset) & 0xF0) >> 4;

            if (aspectRatioIndex <=4)
            {
                videoStream.AspectRatio = MpegConstants.AspectRatio[aspectRatioIndex];
            }
            else
            {
                videoStream.AspectRatio = "Unknow";
            }

            offset += 1;

            // read BitRate
            int bitRate = ((msManager.GetByte(offset) * 0x10000) +
                           (msManager.GetByte(offset + 1) * 0x100) +
                            msManager.GetByte(offset + 2) ) >> 6;

            videoStream.BitRate = bitRate;

            // calculate Duration
            videoStream.Duration = msManager.StreamSize / ((bitRate * 400) / 8.0);

            // Extract video format and chroma format
            GetVideoFormat(ref msManager, offset);

            return true;
        }
        private void ParseExtension(long offset, ref MpegStreamManager msManager)
        {
            offset += 4;

            int ext = msManager.GetByte(offset) >> 4;

            if (ext == 1)
            {
                videoStream.Version = 2;
                videoStream.VideoFormat = (msManager.GetByte(offset + 1) & 0x06) >> 1;

            }
            else if (ext == 2)
            {

                videoStream.VideoFormat = (msManager.GetByte(offset) & 0x0E) >> 1;

            }
        }
        /// <summary>
        /// Extract Video format and Chroma format
        /// </summary>
        private void GetVideoFormat(ref MpegStreamManager msManager, long offset)
        {
            byte marker = new byte();
            bool isFounded = false;
            long _offset = offset;

            // search marker 0xB5 or 0xB8 was founded
            isFounded = msManager.FindNextMarker(ref _offset, ref marker);

            if (isFounded)
            {
                // founded one marker
            //				if (marker == 0xB8)
            //				{
            //					// [Group of pictures] founded...
            //					return;
            //				}

                if (marker == 0xB5)
                {
                    // [extension]
                    ParseExtension(_offset, ref msManager);
                }
                else
                {
                    // in all other cases
                    return;
                }

            }
            else
            {
                // marker not founded
                return;
            }

            // Get Chroma Format Text

            if (videoStream.ChromaFormat >= 1 &&
                videoStream.ChromaFormat <= 3)
            {
                // Get chroma format text from chroma format table
                videoStream.ChromaFormatText = MpegConstants.ChromaFormat[videoStream.ChromaFormat];
            }
            else
            {
                // Unknow chroma format
                videoStream.ChromaFormatText = "Unknow";
            }

            // Get Video Format Text

            if (videoStream.VideoFormat >= 0 &&
                videoStream.VideoFormat <= 5)
            {
                // Get video format text from video format table
                videoStream.VideoFormatText = MpegConstants.VideoFormat[videoStream.VideoFormat];
            }
            else
            {
                // Unknow video format
                videoStream.VideoFormatText = "Unknow";
            }
        }
        private bool ParseAudioStream(ref MpegStreamManager msManager, long offset)
        {
            if (Convert.ToBoolean((msManager.GetByte(offset + 1) & 0x08)))
            {
                audioStream.Version = 1.0d;
            }
            else
            {
                audioStream.Version = 2.0d;
            }

            audioStream.Layer = (msManager.GetByte(offset + 1) & 0x06) >> 1;

            if (audioStream.Layer < 1 || audioStream.Layer > 3)
            {
                return false;
            }

            audioStream.Protected = Convert.ToBoolean(msManager.GetByte(offset + 1) & 0x01);

            int bitrateIndex = msManager.GetByte(offset + 2) >> 4;
            int samplingIndex = (msManager.GetByte(offset + 2) & 0x0F) >> 2;

            if (samplingIndex >= 3 || bitrateIndex == 15)
            {
                return false;
            }

            audioStream.BitRate = MpegConstants.BitRateIndex[(int)audioStream.Version -1,
                                                             audioStream.Layer -1,
                                                             bitrateIndex];
            audioStream.ByteRate = (float)((audioStream.BitRate * 1000) / 8.0d);

            audioStream.SamplingRate =
                MpegConstants.SamplingIndex[(int)audioStream.Version - 1, samplingIndex];

            if (audioStream.BitRate <= 0 ||
                audioStream.ByteRate <= 0 ||
                audioStream.SamplingRate <= 0)
            {
                return false;
            }

            if (Convert.ToBoolean(msManager.GetByte(offset + 2) & 0x02))
            {
                audioStream.Padding = true;
            }
            else
            {
                audioStream.Padding = false;
            }

            audioStream.ModeCode = msManager.GetByte(offset + 3) >> 6;

            // int modeExt = (msManager.GetByte(offset + 3) >> 4) & 0x03;

            if (Convert.ToBoolean(msManager.GetByte(offset + 3) & 0x08))
            {
                audioStream.Copyright = true;
            }
            else
            {
                audioStream.Copyright = false;
            }

            if (Convert.ToBoolean(msManager.GetByte(offset + 3) & 0x04))
            {
                audioStream.Original = true;
            }
            else
            {
                audioStream.Original = false;
            }

            audioStream.EmphasisIndex = msManager.GetByte(offset + 3) & 0x03;

            if (audioStream.Version == 1)
            {
                if (audioStream.Layer == 1)
                {
                    audioStream.FrameLength =
                        ((48000 * audioStream.BitRate) / audioStream.SamplingRate)
                        + 4 * Convert.ToInt32(audioStream.Padding);
                }
                else
                {
                    audioStream.FrameLength =
                        ((144000 * audioStream.BitRate) / audioStream.SamplingRate)
                   		+ Convert.ToInt32(audioStream.Padding);
                }

            }
            else if (audioStream.Version == 2)
            {
                if (audioStream.Layer == 1)
                {
                    audioStream.FrameLength =
                        ((24000 * audioStream.BitRate) / audioStream.SamplingRate)
                        + 4 * Convert.ToInt32(audioStream.Padding);
                }
                else
                {
                    audioStream.FrameLength =
                        ((72000 * audioStream.BitRate) / audioStream.SamplingRate)
                   		+ Convert.ToInt32(audioStream.Padding);
                }

            }
            else
            {
                return false;
            }

            if (audioStream.Protected)
            {
                // frame length sometimes gets offset by +- 2,
                // got to find out why its happening,
                // most likely its the protection switch (see above)
                audioStream.FrameLength += 2;
            }

            audioStream.Duration = ((msManager.StreamSize * 1.0d) / audioStream.BitRate) * 0.008d;

            return true;
        }