//============================================================================ // BDInfo - Blu-ray Video and Audio Analysis Tool // Copyright © 2010 Cinema Squid // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //============================================================================= #undef DEBUG namespace BDInfo { public abstract class TSCodecMPEG2 { public static void Scan( TSVideoStream stream, TSStreamBuffer buffer, ref string tag) { int parse = 0; int pictureParse = 0; int sequenceHeaderParse = 0; int extensionParse = 0; int sequenceExtensionParse = 0; for (int i = 0; i < buffer.Length; i++) { parse = (parse << 8) + buffer.ReadByte(); if (parse == 0x00000100) { pictureParse = 2; } else if (parse == 0x000001B3) { sequenceHeaderParse = 7; } else if (sequenceHeaderParse > 0) { --sequenceHeaderParse; switch (sequenceHeaderParse) { #if DEBUG case 6: break; case 5: break; case 4: stream.Width = (int)((parse & 0xFFF000) >> 12); stream.Height = (int)(parse & 0xFFF); break; case 3: stream.AspectRatio = (TSAspectRatio)((parse & 0xF0) >> 4); switch ((parse & 0xF0) >> 4) { case 0: // Forbidden break; case 1: // Square break; case 2: // 4:3 break; case 3: // 16:9 break; case 4: // 2.21:1 break; default: // Reserved break; } switch (parse & 0xF) { case 0: // Forbidden break; case 1: // 23.976 stream.FrameRateEnumerator = 24000; stream.FrameRateDenominator = 1001; break; case 2: // 24 stream.FrameRateEnumerator = 24000; stream.FrameRateDenominator = 1000; break; case 3: // 25 stream.FrameRateEnumerator = 25000; stream.FrameRateDenominator = 1000; break; case 4: // 29.97 stream.FrameRateEnumerator = 30000; stream.FrameRateDenominator = 1001; break; case 5: // 30 stream.FrameRateEnumerator = 30000; stream.FrameRateDenominator = 1000; break; case 6: // 50 stream.FrameRateEnumerator = 50000; stream.FrameRateDenominator = 1000; break; case 7: // 59.94 stream.FrameRateEnumerator = 60000; stream.FrameRateDenominator = 1001; break; case 8: // 60 stream.FrameRateEnumerator = 60000; stream.FrameRateDenominator = 1000; break; default: // Reserved stream.FrameRateEnumerator = 0; stream.FrameRateDenominator = 0; break; } break; case 2: break; case 1: break; #endif case 0: #if DEBUG stream.BitRate = (((parse & 0xFFFFC0) >> 6) * 200); #endif stream.IsVBR = true; stream.IsInitialized = true; break; } } else if (pictureParse > 0) { --pictureParse; if (pictureParse == 0) { switch ((parse & 0x38) >> 3) { case 1: tag = "I"; break; case 2: tag = "P"; break; case 3: tag = "B"; break; default: break; } if (stream.IsInitialized) return; } } else if (parse == 0x000001B5) { extensionParse = 1; } else if (extensionParse > 0) { --extensionParse; if (extensionParse == 0) { if ((parse & 0xF0) == 0x10) { sequenceExtensionParse = 1; } } } else if (sequenceExtensionParse > 0) { --sequenceExtensionParse; #if DEBUG if (sequenceExtensionParse == 0) { uint sequenceExtension = ((parse & 0x8) >> 3); if (sequenceExtension == 0) { stream.IsInterlaced = true; } else { stream.IsInterlaced = false; } } #endif } } } } }