using DirectShow; using Sonic; using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; using VideoPlayLib.MadVR; namespace VideoPlayLib { internal class VideoInControl : BaseObject, IDisposable { private const int OaTrue = -1; private const int OaFalse = 0; private readonly Control _ctl; private readonly object _flt; private readonly Size _szOrignal; private readonly float _vdoRatio; private readonly IVideoWindow _ivw; private readonly IBasicVideo2 _ibv2; private readonly IMadVRInfo _imvr; public VideoInControl(DSFilter madVr, Control ctl, bool fitWindow = true) { _ctl = ctl; _flt = madVr.Value; _imvr = (IMadVRInfo)_flt; _ivw = (IVideoWindow)_flt; _ibv2 = (IBasicVideo2)_flt; _ivw.put_Owner(_ctl.Handle); _ivw.put_MessageDrain(_ctl.Handle); _ivw.put_FullScreenMode(OaFalse); _ivw.put_WindowStyle(0x40000000 | 0x4000000); CheckError(_imvr.GetSize("originalVideoSize", out _szOrignal)); //TODO: 按媒体信息AR计算宽高比 _vdoRatio = (float)_szOrignal.Width / _szOrignal.Height; if (fitWindow) { _ctl.ClientSize = _szOrignal; } ctl.Resize += EventHandler; EventHandler(null, null); } public VideoInControl(Graph graph, Control ctl) { _ctl = ctl; _flt = graph.Value; _ivw = (IVideoWindow)_flt; _ibv2 = (IBasicVideo2)_flt; _ivw.put_Owner(_ctl.Handle); _ivw.put_MessageDrain(_ctl.Handle); _ivw.put_FullScreenMode(OaFalse); _ivw.put_WindowStyle(0x40000000 | 0x4000000); ctl.Resize += EventHandler; EventHandler(null, null); } private void EventHandler(object sender, EventArgs e) { var ctl = sender as Control ?? _ctl; _ivw.SetWindowPosition(0, 0, ctl.ClientSize.Width, ctl.ClientSize.Height); if(_szOrignal==Size.Empty) return; int resultWidth, resultHeight, marginV, marginH; //calc lettel box var ctlRatio = (float)ctl.ClientSize.Width / ctl.ClientSize.Height; if (_vdoRatio > ctlRatio) { //width based resultWidth = ctl.ClientSize.Width; marginH = 0; resultHeight = (int)(((float)ctl.Width / _szOrignal.Width) * _szOrignal.Height); marginV = (ctl.ClientSize.Height - resultHeight) / 2; } else { //height based resultHeight = ctl.ClientSize.Height; marginV = 0; resultWidth = (int)(((float)ctl.Height / _szOrignal.Height) * _szOrignal.Width); marginH = (ctl.ClientSize.Width - resultWidth) / 2; } _ibv2.SetDestinationPosition(marginH, marginV, resultWidth, resultHeight); } public void Dispose() { Marshal.ReleaseComObject(_ivw); Marshal.ReleaseComObject(_ibv2); Marshal.ReleaseComObject(_imvr); } } }