123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- using DirectShow;
- using DirectShow.BaseClasses;
- using Sonic;
- using System;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Drawing.Imaging;
- using System.Drawing.Text;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Windows.Forms;
- namespace VideoPlayLib
- {
- public class VideoCapture : IDisposable
- {
- //[ComVisible(true)]
- //[Guid("8AF6F710-1AF5-4952-AAFF-ACCD0DB2C9BB")]
- [AMovieSetup(true)]
- //[PropPageSetup(typeof(AboutForm))]
- private abstract class OsdFilter : TransformFilter
- {
- #region Constructor
- protected OsdFilter()
- : base("OSD Filter")
- {
- }
- #endregion Constructor
- #region Overridden Methods
- public override int CheckInputType(AMMediaType pmt)
- {
- if (pmt.majorType != MediaType.Video)
- {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- if (pmt.subType != MediaSubType.RGB32)
- {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- if (pmt.formatType != FormatType.VideoInfo)
- {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- if (pmt.formatPtr == IntPtr.Zero)
- {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- return NOERROR;
- }
- [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
- private static extern void CopyMemory(IntPtr dest, IntPtr src, int count);
- public override int Transform(ref IMediaSampleImpl input, ref IMediaSampleImpl sample)
- {
- var lDataLength = input.GetActualDataLength();
- sample.SetActualDataLength(lDataLength);
- IntPtr ptrIn;
- IntPtr ptrOut;
- input.GetPointer(out ptrIn);
- sample.GetPointer(out ptrOut);
- var bmiIn = (BitmapInfoHeader)Input.CurrentMediaType;
- var bmiOut = (BitmapInfoHeader)Output.CurrentMediaType;
- using (var bmpIn = new Bitmap(bmiIn.Width, bmiIn.Height, bmiIn.Width * 4, PixelFormat.Format32bppRgb, ptrIn))
- {
- bmpIn.RotateFlip(RotateFlipType.RotateNoneFlipY);
- BurnOsd(bmpIn);
- bmpIn.RotateFlip(RotateFlipType.RotateNoneFlipY);
- var data = bmpIn.LockBits(new Rectangle(Point.Empty, bmpIn.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
- CopyMemory(ptrOut, data.Scan0, bmiIn.Width * bmiIn.Height * 4);
- bmpIn.UnlockBits(data);
- bmpIn.Dispose();
- }
- return S_OK;
- }
- protected abstract void BurnOsd(Bitmap frame);
- public override int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop)
- {
- if (!Output.IsConnected) return VFW_E_NOT_CONNECTED;
- if (Output.CurrentMediaType.majorType != MediaType.Video) return VFW_E_INVALIDMEDIATYPE;
- var actual = new AllocatorProperties();
- var bmi = (BitmapInfoHeader)Output.CurrentMediaType;
- if (bmi == null) return VFW_E_INVALIDMEDIATYPE;
- prop.cbBuffer = bmi.GetBitmapSize();
- if (prop.cbBuffer < bmi.ImageSize)
- {
- prop.cbBuffer = bmi.ImageSize;
- }
- prop.cBuffers = 1;
- var hr = pAlloc.SetProperties(prop, actual);
- return hr;
- }
- public override int GetMediaType(int iPosition, ref AMMediaType pMediaType)
- {
- if (iPosition > 0) return VFW_S_NO_MORE_ITEMS;
- if (pMediaType == null) return E_INVALIDARG;
- if (!Input.IsConnected) return VFW_E_NOT_CONNECTED;
- AMMediaType.Copy(Input.CurrentMediaType, ref pMediaType);
- return NOERROR;
- }
- public override int CheckTransform(AMMediaType mtIn, AMMediaType mtOut)
- {
- return AMMediaType.AreEquals(mtIn, mtOut) ? NOERROR : VFW_E_INVALIDMEDIATYPE;
- }
- #endregion Overridden Methods
- }
- private class TimeOsdFilter : OsdFilter
- {
- private readonly int _channel;
- private const bool VideoOsdHighQuality = true;
- private static readonly Font VideoOsdFont = new Font("微软雅黑", 20);
- public TimeOsdFilter(int channel)
- {
- _channel = channel;
- }
- protected override void BurnOsd(Bitmap frame)
- {
- var osdText = string.Format("{0:yyyy年MM月dd日 dddd HH:mm:ss.ff}{1}CAM#{2} - {3}", DateTime.Now, Environment.NewLine, _channel + 1, "");
- var loc = Point.Empty;
- var locT = new PointF(loc.X, loc.Y - 1);
- var locB = new PointF(loc.X, loc.Y + 1);
- var locL = new PointF(loc.X - 1, loc.Y);
- var locR = new PointF(loc.X + 1, loc.Y);
- using (Graphics dc = Graphics.FromImage(frame))
- {
- if (VideoOsdHighQuality)
- {
- dc.CompositingQuality = CompositingQuality.HighQuality;
- dc.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
- dc.SmoothingMode = SmoothingMode.HighQuality;
- dc.InterpolationMode = InterpolationMode.HighQualityBicubic;
- }
- else
- {
- dc.CompositingQuality = CompositingQuality.HighSpeed;
- dc.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
- dc.SmoothingMode = SmoothingMode.HighSpeed;
- dc.InterpolationMode = InterpolationMode.NearestNeighbor;
- }
- dc.DrawString(osdText, VideoOsdFont, Brushes.Black, locT);
- dc.DrawString(osdText, VideoOsdFont, Brushes.Black, locB);
- dc.DrawString(osdText, VideoOsdFont, Brushes.Black, locL);
- dc.DrawString(osdText, VideoOsdFont, Brushes.Black, locR);
- dc.DrawString(osdText, VideoOsdFont, Brushes.White, loc);
- }
- }
- }
- private readonly int _deviceIndex;
- private readonly Control[] _displayContainer;
- public VideoCapture(int deviceIndex, params Control[] displayContainer)
- {
- _deviceIndex = deviceIndex;
- _displayContainer = displayContainer;
- }
- public bool IsRuning { get; private set; }
- public void Run()
- {
- var devices = new DSVideoCaptureCategory().Objects.OrderBy(p => p.Name).ToArray();
- var graph = new Graph();
- var cd = graph.AddDeviceFilter(devices[_deviceIndex]);
- var av = graph.AddFilter(new DSFilter(KnownGuid.Misc.AviDecompressor), "av");
- var to = graph.AddFilter(new DSFilter(new TimeOsdFilter(_deviceIndex)), "to");
- var vr = graph.AddFilter(new DSFilter(KnownGuid.VideoRender.VideoMixingRenderer7), "vr");
- graph.Connect(cd.OutputPin, av.InputPin);
- graph.Connect(av.OutputPin, to.InputPin);
- graph.Connect(to.OutputPin, vr.InputPin);
- _displayContainer.ToList().ForEach(p => new VideoInControl(graph, p));
- graph.Run();
- }
- public void Dispose()
- {
- throw new NotImplementedException();
- }
- }
- }
|