<SpecificVersion>False</SpecificVersion>\r
<HintPath>lib\DirectShowLib.dll</HintPath>\r
</Reference>\r
+ <Reference Include="MXFFileParser, Version=2.2.0.4, Culture=neutral, processorArchitecture=AMD64">\r
+ <SpecificVersion>False</SpecificVersion>\r
+ <HintPath>.\MXFFileParser.dll</HintPath>\r
+ </Reference>\r
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">\r
<HintPath>..\packages\NLog.4.4.12\lib\net45\NLog.dll</HintPath>\r
</Reference>\r
<Compile Include="FlexibleMessageBox.cs" />\r
<Compile Include="InterceptKeys.cs" />\r
<Compile Include="MediaDescription.cs" />\r
+ <Compile Include="MediaDetectorLight.cs" />\r
<Compile Include="MediaDetector.cs" />\r
<Compile Include="MediaInfoDLL.cs" />\r
<Compile Include="MenuButton.cs">\r
<DependentUpon>PlayerForm.cs</DependentUpon>\r
</Compile>\r
<Content Include="DirectShowLib.dll" />\r
+ <Content Include="MXFFileParser.dll">\r
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r
+ </Content>\r
<EmbeddedResource Include="StringResource.resx">\r
<Generator>ResXFileCodeGenerator</Generator>\r
<LastGenOutput>StringResource.Designer.cs</LastGenOutput>\r
--- /dev/null
+using System;\r
+using System.Drawing;\r
+using System.Drawing.Imaging;\r
+using System.Runtime.InteropServices;\r
+using System.Text;\r
+using System.Windows.Forms;\r
+\r
+using DirectShowLib;\r
+using DirectShowLib.DES;\r
+using MediaInfoLib;\r
+using System.Diagnostics;\r
+using System.Globalization;\r
+using NLog;\r
+\r
+namespace DxPlay {\r
+ /// <summary>\r
+ /// A wrapper class around the DirectShow's MediaDet object.\r
+ /// </summary>\r
+ public sealed class MediaDetectorLight {\r
+ private static Logger logger = LogManager.GetCurrentClassLogger();\r
+\r
+ public static MediaDescription GetDescription(string fileName) {\r
+ int hr = 0;\r
+ MediaDescription mediaDesc = new MediaDescription();\r
+ IMediaDet mediaDet = null;\r
+\r
+ try {\r
+ // Create the DirectShow's MediaDet\r
+ mediaDet = (IMediaDet)new MediaDet();\r
+\r
+ hr = mediaDet.put_Filename(fileName);\r
+ if (hr < 0) {\r
+ MessageBox.Show("This file is not supprted by MediaDet", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
+ DsError.ThrowExceptionForHR(hr);\r
+ }\r
+\r
+ mediaDesc.fileName = fileName;\r
+\r
+ int streamCount;\r
+ hr = mediaDet.get_OutputStreams(out streamCount);\r
+ DsError.ThrowExceptionForHR(hr);\r
+\r
+ for (int i = 0; i < streamCount; i++) {\r
+ hr = mediaDet.put_CurrentStream(i);\r
+ DsError.ThrowExceptionForHR(hr);\r
+\r
+ Guid streamType;\r
+ hr = mediaDet.get_StreamType(out streamType);\r
+ DsError.ThrowExceptionForHR(hr);\r
+\r
+ if (streamType == MediaType.Audio)\r
+ UpdateAudioPart(mediaDet, mediaDesc);\r
+ else if (streamType == MediaType.Video)\r
+ UpdateVideoPart(mediaDet, mediaDesc);\r
+ else\r
+ continue;\r
+ }\r
+\r
+ if (mediaDesc.videoSubType != Guid.Empty)\r
+ mediaDesc.snapshot = GetSnapshot(mediaDet, mediaDesc.resolution.Width, mediaDesc.resolution.Height, mediaDesc.videoLength.TotalSeconds / 2);\r
+ }\r
+ finally {\r
+ if (mediaDet != null)\r
+ Marshal.ReleaseComObject(mediaDet);\r
+ }\r
+\r
+ return mediaDesc;\r
+ }\r
+\r
+ private static void UpdateAudioPart(IMediaDet mediaDet, MediaDescription mediaDesc) {\r
+ int hr = 0;\r
+ AMMediaType mediaType = new AMMediaType();\r
+\r
+ hr = mediaDet.get_StreamMediaType(mediaType);\r
+ DsError.ThrowExceptionForHR(hr);\r
+\r
+ mediaDesc.audioSubType = mediaType.subType;\r
+\r
+ double streamLength;\r
+ hr = mediaDet.get_StreamLength(out streamLength);\r
+ DsError.ThrowExceptionForHR(hr);\r
+\r
+ mediaDesc.audioLength = TimeSpan.FromSeconds(streamLength);\r
+\r
+ if (mediaType.formatType == FormatType.WaveEx) {\r
+ WaveFormatEx waveFormatEx = (WaveFormatEx)Marshal.PtrToStructure(mediaType.formatPtr, typeof(WaveFormatEx));\r
+ mediaDesc.channels = waveFormatEx.nChannels;\r
+ mediaDesc.samplesPerSec = ((float)waveFormatEx.nSamplesPerSec) / 1000;\r
+ mediaDesc.bitsPerSample = waveFormatEx.wBitsPerSample;\r
+ }\r
+ }\r
+\r
+ private static void UpdateVideoPart(IMediaDet mediaDet, MediaDescription mediaDesc) {\r
+ int hr = 0;\r
+ AMMediaType mediaType = new AMMediaType();\r
+\r
+ hr = mediaDet.get_StreamMediaType(mediaType);\r
+ DsError.ThrowExceptionForHR(hr);\r
+\r
+ mediaDesc.videoSubType = mediaType.subType;\r
+\r
+ double streamLength;\r
+ hr = mediaDet.get_StreamLength(out streamLength);\r
+ DsError.ThrowExceptionForHR(hr);\r
+\r
+ mediaDesc.videoLength = TimeSpan.FromSeconds(streamLength);\r
+\r
+ if (mediaType.formatType == FormatType.VideoInfo) {\r
+ VideoInfoHeader videoHeader = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader));\r
+\r
+ mediaDesc.resolution = new Size(videoHeader.BmiHeader.Width, videoHeader.BmiHeader.Height);\r
+ mediaDesc.bitsPerPixel = videoHeader.BmiHeader.BitCount;\r
+ mediaDesc.fourCC = FourCCToString(videoHeader.BmiHeader.Compression);\r
+ //TODO!!!!\r
+ mediaDesc.firstFrame = new Timecode();\r
+ }\r
+ }\r
+\r
+ private static string FourCCToString(int fourcc) {\r
+ byte[] bytes = new byte[4];\r
+\r
+ bytes[0] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8;\r
+ bytes[1] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8;\r
+ bytes[2] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8;\r
+ bytes[3] = (byte)(fourcc & 0x000000ff);\r
+\r
+ return Encoding.ASCII.GetString(bytes);\r
+ }\r
+\r
+ private static Bitmap GetSnapshot(IMediaDet mediaDet, int width, int height, double position) {\r
+ int hr = 0;\r
+ Bitmap bitmap = null;\r
+ int bufferSize = 0;\r
+ IntPtr buffer = IntPtr.Zero;\r
+\r
+ try {\r
+ hr = mediaDet.GetBitmapBits(position, out bufferSize, IntPtr.Zero, width, height);\r
+ if (hr == 0) {\r
+ buffer = Marshal.AllocCoTaskMem(bufferSize);\r
+ hr = mediaDet.GetBitmapBits(position, out bufferSize, buffer, width, height);\r
+\r
+ BitmapInfoHeader bitmapHeader = (BitmapInfoHeader)Marshal.PtrToStructure(buffer, typeof(BitmapInfoHeader));\r
+ IntPtr bitmapData;\r
+\r
+ if (IntPtr.Size == 4)\r
+ bitmapData = new IntPtr(buffer.ToInt32() + bitmapHeader.Size);\r
+ else\r
+ bitmapData = new IntPtr(buffer.ToInt64() + bitmapHeader.Size);\r
+\r
+ bitmap = new Bitmap(bitmapHeader.Width, bitmapHeader.Height, PixelFormat.Format24bppRgb);\r
+ BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmapHeader.Width, bitmapHeader.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);\r
+\r
+ /*\r
+ for (int i = 0; i < width * height * 3 ; i++)\r
+ {\r
+ byte b = Marshal.ReadByte(bitmapData, i);\r
+ Marshal.WriteByte(bmpData.Scan0, i, b);\r
+ }\r
+ */\r
+\r
+ CopyMemory(bmpData.Scan0, bitmapData, width * height * 3);\r
+ bitmap.UnlockBits(bmpData);\r
+\r
+ bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);\r
+ }\r
+ }\r
+ finally {\r
+ if (buffer != IntPtr.Zero)\r
+ Marshal.FreeCoTaskMem(buffer);\r
+ }\r
+ return bitmap;\r
+ }\r
+\r
+ [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]\r
+ private static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);\r
+\r
+ }\r
+}\r