using System;
using System.IO;
public class Mpeg2VideoInfo
{
#region Member Variables
private TimeSpan m_startTime = TimeSpan.Zero;
private TimeSpan m_endTime = TimeSpan.Zero;
private TimeSpan m_duration = TimeSpan.Zero;
private eAspectRatios m_aspectRatio = eAspectRatios.Invalid;
private eFrameRates m_frameRate = 0;
private int m_pictureWidth = 0;
private int m_pictureHeight = 0;
#endregion
#region Constants
private const byte PADDING_PACKET = 0xBE;
private const byte VIDEO_PACKET = 0xE0;
private const byte AUDIO_PACKET = 0xC0;
private const byte SYSTEM_PACKET = 0xBB;
private const byte TIMESTAMP_PACKET = 0xB8;
private const byte HEADER_PACKET = 0xB3;
private const int BUFFER_SIZE = 8162;
private readonly static TimeSpan EMPTY_TIMESPAN = new TimeSpan(0, 0, -1);
#endregion
#region Enumerations
public enum eFrameRates
{
Invalid,
PulldownNTSC,
Film,
PAL,
NTSC,
DropFrameNTSC,
DoubleRatePAL,
DoubleRateNTSC,
DoubleRateDropFrameNTSC
}
public enum eAspectRatios
{
Invalid,
VGA,
StandardTV,
LargeTV,
Cinema
}
#endregion
#region Constructor
public Mpeg2VideoInfo(string file)
{
ParseMpeg(file);
}
#endregion
#region Public Properties
public TimeSpan StartTime
{
get { return m_startTime; }
}
public TimeSpan EndTime
{
get { return m_endTime; }
}
public TimeSpan Duration
{
get { return m_duration; }
}
public eAspectRatios AspectRatio
{
get { return m_aspectRatio; }
}
public eFrameRates FrameRate
{
get { return m_frameRate; }
}
public int PictureWidth
{
get { return m_pictureWidth; }
}
public int PictureHeight
{
get { return m_pictureHeight; }
}
#endregion
#region Private Functions
private void ParseMpeg(string file)
{
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
BinaryReader br = new BinaryReader(fs);
m_startTime = GetStartTimeStampInfo(br);
m_endTime = GetEndTimeStampInfo(br);
m_duration = m_endTime.Subtract(m_startTime);
GetHeaderInfo(br);
br.Close();
fs.Close();
}
private TimeSpan GetStartTimeStampInfo(BinaryReader br)
{
TimeSpan startTime = EMPTY_TIMESPAN;
byte[] buffer = new byte[BUFFER_SIZE];
br.BaseStream.Seek(0, SeekOrigin.Begin);
while (startTime == EMPTY_TIMESPAN && br.BaseStream.Position < br.BaseStream.Length)
{
int readBytes = br.Read(buffer, 0, BUFFER_SIZE);
for (int offset = 0; offset < readBytes - 8; offset++)
{
if (IsStreamMarker(ref buffer, offset, TIMESTAMP_PACKET))
{
offset += 4;
uint timeStampEncoded = GetData(ref buffer, offset);
startTime = DecodeTimeStamp(timeStampEncoded);
if (startTime != EMPTY_TIMESPAN)
break;
}
}
}
return startTime;
}
private TimeSpan GetEndTimeStampInfo(BinaryReader br)
{
TimeSpan endTime = EMPTY_TIMESPAN;
byte[] buffer = new byte[BUFFER_SIZE];
br.BaseStream.Seek(-BUFFER_SIZE, SeekOrigin.End);
while (endTime == EMPTY_TIMESPAN && br.BaseStream.Position > BUFFER_SIZE)
{
int readBytes = br.Read(buffer, 0, BUFFER_SIZE);
for (int offset = readBytes - 8; offset >= 0; offset--)
{
if (IsStreamMarker(ref buffer, offset, TIMESTAMP_PACKET))
{
offset += 4;
uint timeStampEncoded = GetData(ref buffer, offset);
endTime = DecodeTimeStamp(timeStampEncoded);
if (endTime != EMPTY_TIMESPAN)
break;
}
}
br.BaseStream.Seek(-BUFFER_SIZE * 2, SeekOrigin.Current);
}
return endTime;
}
private TimeSpan DecodeTimeStamp(uint timeStampEncoded)
{
TimeSpan timeStamp = EMPTY_TIMESPAN;
int hour = (int)(timeStampEncoded & 0x7C000000) >> 26;
int minute = (int)(timeStampEncoded & 0x03F00000) >> 20;
int second = (int)(timeStampEncoded & 0x0007E000) >> 13;
int frame = (int)(timeStampEncoded & 0x00001F80) >> 7;
timeStamp = new TimeSpan(hour, minute, second);
return timeStamp;
}
private void GetHeaderInfo(BinaryReader br)
{
byte[] buffer = new byte[BUFFER_SIZE];
br.BaseStream.Seek(0, SeekOrigin.Begin);
br.Read(buffer, 0, BUFFER_SIZE);
for (int offset = 0; offset < buffer.Length - 4; offset++)
{
if (IsStreamMarker(ref buffer, offset, HEADER_PACKET))
{
offset += 4;
uint headerData = GetData(ref buffer, offset);
m_pictureWidth = (int)(headerData & 0xFFF00000) >> 20;
m_pictureHeight = (int)(headerData & 0x000FFF00) >> 8;
uint aspectRatioIndex = (headerData & 0x000000F0) >> 4;
uint fpsIndex = headerData & 0x0000000F;
m_aspectRatio = (eAspectRatios)fpsIndex;
m_frameRate = (eFrameRates)fpsIndex;
break;
}
}
}
private uint GetData(ref byte[] buffer, int offset)
{
return (uint) ((buffer[offset] << 24) |
(buffer[offset + 1] << 16) |
(buffer[offset + 2] << 8) |
(buffer[offset + 3]));
}
private bool IsStreamMarker(ref byte[] buffer, int offset, byte markerType)
{
return (buffer[offset] == 0x00 &&
buffer[offset + 1] == 0x00 &&
buffer[offset + 2] == 0x01 &&
buffer[offset + 3] == markerType);
}
#endregion
public static int Main(string[] args)
{
string file1 = args[0];
Mpeg2VideoInfo info = new Mpeg2VideoInfo(file1);
System.Console.WriteLine( info.StartTime );
System.Console.WriteLine( info.EndTime );
System.Console.WriteLine( info.Duration );
System.Console.WriteLine( info.AspectRatio );
System.Console.WriteLine( info.FrameRate );
System.Console.WriteLine( info.PictureWidth );
System.Console.WriteLine( info.PictureHeight );
ImageReader r = new ImageReader();
Image image = r.GetImage();
image.SetNumberOfDimensions( 3 );
DataElement pixeldata =
new DataElement(
new gdcm.
Tag(0x7fe0,0x0010) );
System.IO.FileStream infile =
new System.IO.FileStream(file1, System.IO.FileMode.Open, System.IO.FileAccess.Read);
uint fsize =
gdcm.PosixEmulation.FileSize(file1);
byte[] jstream = new byte[fsize];
infile.Read(jstream, 0 , jstream.Length);
SmartPtrFrag sq = SequenceOfFragments.New();
Fragment frag = new Fragment();
frag.SetByteValue( jstream,
new gdcm.
VL( (uint)jstream.Length) );
sq.AddFragment( frag );
pixeldata.SetValue( sq.__ref__() );
image.SetDataElement( pixeldata );
PhotometricInterpretation pi = new PhotometricInterpretation( PhotometricInterpretation.PIType.YBR_PARTIAL_420 );
image.SetPhotometricInterpretation( pi );
PixelFormat pixeltype = new PixelFormat(3,8,8,7);
image.SetPixelFormat( pixeltype );
TransferSyntax ts = new TransferSyntax( TransferSyntax.TSType.MPEG2MainProfile);
image.SetTransferSyntax( ts );
image.SetDimension(0, (uint)info.PictureWidth);
image.SetDimension(1, (uint)info.PictureHeight);
image.SetDimension(2, 721);
ImageWriter writer = new ImageWriter();
Anonymizer anon = new Anonymizer();
anon.SetFile( file );
MediaStorage ms = new MediaStorage( MediaStorage.MSType.VideoEndoscopicImageStorage);
UIDGenerator gen = new UIDGenerator();
anon.Replace( new Tag(0x0008,0x16), ms.GetString() );
anon.Replace( new Tag(0x0018,0x40), "25" );
anon.Replace( new Tag(0x0018,0x1063), "40.000000" );
anon.Replace( new Tag(0x0028,0x34), "4\\3" );
anon.Replace( new Tag(0x0028,0x2110), "01" );
writer.SetImage( image );
writer.SetFileName( "dummy.dcm" );
if( !writer.Write() )
{
System.Console.WriteLine( "Could not write" );
return 1;
}
return 0;
}
}