From 7f85f91d7351dc81870cc5565252aa817961a783 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1s=C3=A1ry=20D=C3=A1niel?= Date: Fri, 20 Oct 2017 15:33:56 +0000 Subject: [PATCH] git-tfs-id: [http://tfs.userrendszerhaz.hu:8080/tfs/DefaultCollection]$/MediaCube;C30662 --- client/DxPlay/DxPlay.csproj | 8 ++ client/DxPlay/MediaDetectorLight.cs | 178 ++++++++++++++++++++++++++++ client/DxPlay/PlayerForm.cs | 2 +- 3 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 client/DxPlay/MediaDetectorLight.cs diff --git a/client/DxPlay/DxPlay.csproj b/client/DxPlay/DxPlay.csproj index 101cba4a..9057acb4 100644 --- a/client/DxPlay/DxPlay.csproj +++ b/client/DxPlay/DxPlay.csproj @@ -152,6 +152,10 @@ False lib\DirectShowLib.dll + + False + .\MXFFileParser.dll + ..\packages\NLog.4.4.12\lib\net45\NLog.dll @@ -183,6 +187,7 @@ + @@ -222,6 +227,9 @@ PlayerForm.cs + + PreserveNewest + ResXFileCodeGenerator StringResource.Designer.cs diff --git a/client/DxPlay/MediaDetectorLight.cs b/client/DxPlay/MediaDetectorLight.cs new file mode 100644 index 00000000..5b220a16 --- /dev/null +++ b/client/DxPlay/MediaDetectorLight.cs @@ -0,0 +1,178 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +using DirectShowLib; +using DirectShowLib.DES; +using MediaInfoLib; +using System.Diagnostics; +using System.Globalization; +using NLog; + +namespace DxPlay { + /// + /// A wrapper class around the DirectShow's MediaDet object. + /// + public sealed class MediaDetectorLight { + private static Logger logger = LogManager.GetCurrentClassLogger(); + + public static MediaDescription GetDescription(string fileName) { + int hr = 0; + MediaDescription mediaDesc = new MediaDescription(); + IMediaDet mediaDet = null; + + try { + // Create the DirectShow's MediaDet + mediaDet = (IMediaDet)new MediaDet(); + + hr = mediaDet.put_Filename(fileName); + if (hr < 0) { + MessageBox.Show("This file is not supprted by MediaDet", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + DsError.ThrowExceptionForHR(hr); + } + + mediaDesc.fileName = fileName; + + int streamCount; + hr = mediaDet.get_OutputStreams(out streamCount); + DsError.ThrowExceptionForHR(hr); + + for (int i = 0; i < streamCount; i++) { + hr = mediaDet.put_CurrentStream(i); + DsError.ThrowExceptionForHR(hr); + + Guid streamType; + hr = mediaDet.get_StreamType(out streamType); + DsError.ThrowExceptionForHR(hr); + + if (streamType == MediaType.Audio) + UpdateAudioPart(mediaDet, mediaDesc); + else if (streamType == MediaType.Video) + UpdateVideoPart(mediaDet, mediaDesc); + else + continue; + } + + if (mediaDesc.videoSubType != Guid.Empty) + mediaDesc.snapshot = GetSnapshot(mediaDet, mediaDesc.resolution.Width, mediaDesc.resolution.Height, mediaDesc.videoLength.TotalSeconds / 2); + } + finally { + if (mediaDet != null) + Marshal.ReleaseComObject(mediaDet); + } + + return mediaDesc; + } + + private static void UpdateAudioPart(IMediaDet mediaDet, MediaDescription mediaDesc) { + int hr = 0; + AMMediaType mediaType = new AMMediaType(); + + hr = mediaDet.get_StreamMediaType(mediaType); + DsError.ThrowExceptionForHR(hr); + + mediaDesc.audioSubType = mediaType.subType; + + double streamLength; + hr = mediaDet.get_StreamLength(out streamLength); + DsError.ThrowExceptionForHR(hr); + + mediaDesc.audioLength = TimeSpan.FromSeconds(streamLength); + + if (mediaType.formatType == FormatType.WaveEx) { + WaveFormatEx waveFormatEx = (WaveFormatEx)Marshal.PtrToStructure(mediaType.formatPtr, typeof(WaveFormatEx)); + mediaDesc.channels = waveFormatEx.nChannels; + mediaDesc.samplesPerSec = ((float)waveFormatEx.nSamplesPerSec) / 1000; + mediaDesc.bitsPerSample = waveFormatEx.wBitsPerSample; + } + } + + private static void UpdateVideoPart(IMediaDet mediaDet, MediaDescription mediaDesc) { + int hr = 0; + AMMediaType mediaType = new AMMediaType(); + + hr = mediaDet.get_StreamMediaType(mediaType); + DsError.ThrowExceptionForHR(hr); + + mediaDesc.videoSubType = mediaType.subType; + + double streamLength; + hr = mediaDet.get_StreamLength(out streamLength); + DsError.ThrowExceptionForHR(hr); + + mediaDesc.videoLength = TimeSpan.FromSeconds(streamLength); + + if (mediaType.formatType == FormatType.VideoInfo) { + VideoInfoHeader videoHeader = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader)); + + mediaDesc.resolution = new Size(videoHeader.BmiHeader.Width, videoHeader.BmiHeader.Height); + mediaDesc.bitsPerPixel = videoHeader.BmiHeader.BitCount; + mediaDesc.fourCC = FourCCToString(videoHeader.BmiHeader.Compression); + //TODO!!!! + mediaDesc.firstFrame = new Timecode(); + } + } + + private static string FourCCToString(int fourcc) { + byte[] bytes = new byte[4]; + + bytes[0] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8; + bytes[1] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8; + bytes[2] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8; + bytes[3] = (byte)(fourcc & 0x000000ff); + + return Encoding.ASCII.GetString(bytes); + } + + private static Bitmap GetSnapshot(IMediaDet mediaDet, int width, int height, double position) { + int hr = 0; + Bitmap bitmap = null; + int bufferSize = 0; + IntPtr buffer = IntPtr.Zero; + + try { + hr = mediaDet.GetBitmapBits(position, out bufferSize, IntPtr.Zero, width, height); + if (hr == 0) { + buffer = Marshal.AllocCoTaskMem(bufferSize); + hr = mediaDet.GetBitmapBits(position, out bufferSize, buffer, width, height); + + BitmapInfoHeader bitmapHeader = (BitmapInfoHeader)Marshal.PtrToStructure(buffer, typeof(BitmapInfoHeader)); + IntPtr bitmapData; + + if (IntPtr.Size == 4) + bitmapData = new IntPtr(buffer.ToInt32() + bitmapHeader.Size); + else + bitmapData = new IntPtr(buffer.ToInt64() + bitmapHeader.Size); + + bitmap = new Bitmap(bitmapHeader.Width, bitmapHeader.Height, PixelFormat.Format24bppRgb); + BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmapHeader.Width, bitmapHeader.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); + + /* + for (int i = 0; i < width * height * 3 ; i++) + { + byte b = Marshal.ReadByte(bitmapData, i); + Marshal.WriteByte(bmpData.Scan0, i, b); + } + */ + + CopyMemory(bmpData.Scan0, bitmapData, width * height * 3); + bitmap.UnlockBits(bmpData); + + bitmap.RotateFlip(RotateFlipType.Rotate180FlipX); + } + } + finally { + if (buffer != IntPtr.Zero) + Marshal.FreeCoTaskMem(buffer); + } + return bitmap; + } + + [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")] + private static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length); + + } +} diff --git a/client/DxPlay/PlayerForm.cs b/client/DxPlay/PlayerForm.cs index b26d3bc0..fb0d603e 100644 --- a/client/DxPlay/PlayerForm.cs +++ b/client/DxPlay/PlayerForm.cs @@ -60,7 +60,7 @@ namespace DxPlay { private void cueue() { m_play = null; try { - m_mediaDescription = MediaDetector.GetDescription(selectedFile); + m_mediaDescription = MediaDetectorLight.GetDescription(selectedFile); trackBar1.Value = 0; trackBar1.Minimum = 0; -- 2.54.0