root/RetroCASC/CASC-Lancelot/Pages/RoomPage/Streaming/VideoPrivateData.cs
Show/hide line numbers
using System; namespace CASC.Camlann.Lancelot { /// <summary> /// Class for WMV Codec Private Data. /// </summary> public class VideoPrivateData { /// <summary> /// Size of the data, in bytes. /// </summary> /// <remarks> /// I'm not sure if it's always 45 bytes, but don't tell anyone! /// </remarks> private const int Size = 45; // these I found in the ASF specification (cf. section 9.2) private uint EncodedImageWidth; private uint EncodedImageHeight; private byte ReservedFlags; private ushort FormatDataSize; // the BITMAPINFOHEADER structure [offset] private uint biSize; // 0 private int biWidth; // 4 private int biHeight; // 8 private ushort biPlanes; // 12 private ushort biBitCount; // 14 private uint biCompression; // 16 private uint biSizeImage; // 20 private int biXPelsPerMeter; // 24 private int biYPelsPerMeter; // 28 private uint biClrUsed; // 32 private uint biClrImportant; // 36 private byte[] CodecSpecificData = null; // 40 /// <summary> /// Image width. /// </summary> public int Width { get { return this.biWidth; } } /// <summary> /// Image height. /// </summary> public int Height { get { return this.biHeight; } } /// <summary> /// Creates VideoPrivateData from raw bytes. /// </summary> /// <param name="data">The data to be parsed.</param> public VideoPrivateData( byte[] data ) { // check buffer size if ( data.Length != VideoPrivateData.Size ) { throw new Exception( "Wrong buffer size." ); } // read stuff this.biSize = BitConverter.ToUInt32( data, 0 ); this.biWidth = BitConverter.ToInt32( data, 4 ); this.biHeight = BitConverter.ToInt32( data, 8 ); this.biPlanes = BitConverter.ToUInt16( data, 12 ); this.biBitCount = BitConverter.ToUInt16( data, 14 ); this.biCompression = BitConverter.ToUInt32( data, 16 ); this.biSizeImage = BitConverter.ToUInt32( data, 20 ); this.biXPelsPerMeter = BitConverter.ToInt32( data, 24 ); this.biYPelsPerMeter = BitConverter.ToInt32( data, 28 ); this.biClrUsed = BitConverter.ToUInt32( data, 32 ); this.biClrImportant = BitConverter.ToUInt32( data, 36 ); this.CodecSpecificData = new byte[data.Length - 40]; Array.Copy( data, 40, this.CodecSpecificData, 0, this.CodecSpecificData.Length ); // set some ASF stuff this.ReservedFlags = 2; // this should always be 2 this.FormatDataSize = (ushort)data.Length; // HACK: I have no idea why, but if I set those two // to anything except 320x240, the whole thing just doesn't work. this.EncodedImageWidth = 320; this.EncodedImageHeight = 240; return; } /// <summary> /// Returns a base16-encoded (little-endian order) string containing the private data. /// </summary> /// <returns>A base16-encoded (little-endian order) string containing the private data.</returns> public string ToBase16() { string hex = ""; hex += Encoder.ToBase16( this.EncodedImageWidth ); hex += Encoder.ToBase16( this.EncodedImageHeight ); hex += Encoder.ToBase16( this.ReservedFlags ); hex += Encoder.ToBase16( this.FormatDataSize ); hex += Encoder.ToBase16( this.biSize ); hex += Encoder.ToBase16( this.biWidth ); hex += Encoder.ToBase16( this.biHeight ); hex += Encoder.ToBase16( this.biPlanes ); hex += Encoder.ToBase16( this.biBitCount ); hex += Encoder.ToBase16( this.biCompression ); hex += Encoder.ToBase16( this.biSizeImage ); hex += Encoder.ToBase16( this.biXPelsPerMeter ); hex += Encoder.ToBase16( this.biYPelsPerMeter ); hex += Encoder.ToBase16( this.biClrUsed ); hex += Encoder.ToBase16( this.biClrImportant ); // Now, if someone could tell me WHAT these bytes are, // and in what order I should write them... foreach ( byte b in this.CodecSpecificData ) { hex += Encoder.ToBase16( b ); } return hex; } } } |
View as a web page
Download