コード例 #1
0
 public void SetVideoPosition(GDI.RECT rcDest)
 {
     if (_filterGraph != null)
     {
         _filterGraph.Renderer.SetVideoPosition(_filterGraph.SourceRect, rcDest);
     }
 }
コード例 #2
0
        public void Move(GDI.RECT rcDest)
        {
            if (_clientRect == null)
            {
                GDI.RECT rect;
                WindowsManagement.GetClientRect(_hMediaWindow, out rect);
                _clientRect = rect;
            }

            if (_windowRect == null)
            {
                GDI.RECT rect;
                WindowsManagement.GetWindowRect(_hMediaWindow, out rect);
                _windowRect = rect;
            }

            if ((_clientRect.Value.right - _clientRect.Value.left) != (rcDest.right - rcDest.left) ||
                (_clientRect.Value.bottom - _clientRect.Value.top) != (rcDest.bottom - rcDest.top))
            {
                GDI.RECT rect;
                rect.left   = rect.top = 0;
                rect.right  = (rcDest.right - rcDest.left) + ((_windowRect.Value.right - _windowRect.Value.left) - (_clientRect.Value.right - _clientRect.Value.left));
                rect.bottom = (rcDest.bottom - rcDest.top) + ((_windowRect.Value.bottom - _windowRect.Value.top) - (_clientRect.Value.bottom - _clientRect.Value.top));

                if (WindowsManagement.MoveWindow(_hMediaWindow, rect.left, rect.top, rect.right, rect.bottom, false) != 0)
                {
                    _windowRect = rect;
                    _clientRect = rcDest;
                }
            }
        }
コード例 #3
0
 public void Move(GDI.RECT rcDest)
 {
     if (_hwnd != null)
     {
         WindowsManagement.MoveWindow(_hwnd, rcDest.left, rcDest.top, rcDest.right - rcDest.left, rcDest.bottom - rcDest.top, true);
     }
 }
コード例 #4
0
ファイル: EVR.cs プロジェクト: jeason0813/power-video-player
        public EVR()
        {
            _renderer = Renderer.EVR;

            _rcSrc       = new MFVideoNormalizedRect();
            _rcSrc.left  = _rcSrc.top = 0.0f;
            _rcSrc.right = _rcSrc.bottom = 1.0f;

            _rcDest      = new GDI.RECT();
            _rcDest.left = _rcDest.top = 0;
        }
コード例 #5
0
        public override void SetVideoPosition(GDI.RECT rcSrc, GDI.RECT rcDest)
        {
            if (!_initialized)
            {
                Initialize(GraphBuilder, MediaWindowHandle);
                _initialized = true;
            }

            VideoWindow.SetWindowPosition(rcDest.left, rcDest.top,
                                          rcDest.right - rcDest.left,
                                          rcDest.bottom - rcDest.top);
            BasicVideo2.SetDefaultDestinationPosition();
        }
コード例 #6
0
 public override void SetVideoPosition(GDI.RECT rcSrc, GDI.RECT rcDest)
 {
     // in EVR default source rectangle is {0.0, 0.0, 1.0, 1.0}, these are so-called normalized coordinates
     // however VMR, VMR9 and PVP consider the source rectangle as the video size
     // so we will just pass the default one to display the whole video frame
     // When we set video frame to be less than our windows EVR starts flickering in the surrounding areas, looks like some old content from
     // back buffers is being drawn
     // To overcme this issue we set our media window (nwnd) to be of the size of the video we want to show, in other words EVR should paint the whole window area
     // EVR's default destination rectangle is {0, 0, 0, 0} so we need to adjust it to {0, 0, width, height}
     _rcDest.right  = rcDest.right - rcDest.left;
     _rcDest.bottom = rcDest.bottom - rcDest.top;
     _pMFVideoDisplayControl.SetVideoPosition(ref _rcSrc, ref _rcDest);
 }
コード例 #7
0
        public EVRRenderer(IPvpPresenterHook pvpPresenterHook)
        {
            _pvpPresenterHook = pvpPresenterHook;
            _renderer         = MediaEngine.Renderer.EVR;

            _rcSrc = new MFVideoNormalizedRect {
                left = _rcSrc.top = 0.0f, right = _rcSrc.bottom = 1.0f
            };

            _rcDest = new GDI.RECT {
                left = _rcDest.top = 0
            };
        }
コード例 #8
0
 public override void SetVideoPosition(GDI.RECT rcSrc, GDI.RECT rcDest)
 {
     _pVMRWindowlessControl9.SetVideoPosition(/*ref rcSrc*/ IntPtr.Zero, ref rcDest);
 }
コード例 #9
0
        unsafe GlyphRect GetGlyph(uint fontHash, FontFace fontFace, short glyphIndex, float fontSize)
        {
            var       glyphHash = GlyphHash(fontFace, fontHash, glyphIndex);
            GlyphRect grect;

            if (!glyphs.TryGetValue(glyphHash, out grect))
            {
                var metrics      = fontFace.Metrics;
                var glyphMetrics = fontFace.GetDesignGlyphMetrics(new short[] { glyphIndex }, false)[0];
                var run          = new GlyphRun();
                run.FontFace = fontFace;
                run.FontSize = fontSize;
                run.Indices  = new short[] { glyphIndex };
                run.Advances = new float[] { 0 };
                run.Offsets  = new GlyphOffset[] { new GlyphOffset() };
                var gdata    = new ComputedSize(fontSize, metrics, glyphMetrics);
                var fillRect = new GDI.RECT()
                {
                    left   = 0,
                    top    = 0,
                    right  = 2 + gdata.maxWidth + 5,
                    bottom = 2 + gdata.maxHeight + 5
                };
                GDI.FillRect(hdc, ref fillRect, hBrush);
                RawRectangle rect;
                renderTarget.DrawGlyphRun(2.0f - gdata.offsetX, 2.0f - gdata.offsetY, D2D1.MeasuringMode.Natural, run, renderParams, new RawColorBGRA(255, 255, 255, 255), out rect);
                var left   = rect.Left < 0 ? 0 : rect.Left;
                var right  = rect.Right > MAX_GLYPH_SIZE ? MAX_GLYPH_SIZE : rect.Right;
                var top    = rect.Top < 0 ? 0 : rect.Top;
                var bottom = rect.Bottom > MAX_GLYPH_SIZE ? MAX_GLYPH_SIZE : rect.Bottom;
                var r      = new Rectangle(0, 0, right - left, bottom - top);
                //Construct grayscale image from GDI
                byte[] data    = new byte[r.Width * r.Height * 4];
                byte * srcData = (byte *)bmBits;
                for (int y = 0; y < r.Height; y++)
                {
                    for (int x = 0; x < r.Width; x++)
                    {
                        var destP = (y * r.Width * 4) + (x * 4);
                        var pixel = srcData[(top + y) * bytesPerPixel * MAX_GLYPH_SIZE + (left + x) * bytesPerPixel];
                        data[destP]     = data[destP + 1] = data[destP + 2] = 255;
                        data[destP + 3] = pixel;
                    }
                }
                //
                if (currentX + r.Width > MAX_GLYPH_SIZE)
                {
                    currentX      = 0;
                    currentY     += maxLineHeight;
                    maxLineHeight = 0;
                }
                if (currentY + r.Height > MAX_GLYPH_SIZE)
                {
                    pages.Add(new Texture2D(TEXT_PAGE_SIZE, TEXT_PAGE_SIZE, false, SurfaceFormat.Color));
                    currentX = currentY = maxLineHeight = 0;
                }
                r.X           = currentX;
                r.Y           = currentY;
                maxLineHeight = Math.Max(maxLineHeight, r.Height);
                currentX     += r.Width;
                var page = pages[pages.Count - 1];
                page.SetData(0, r, data, 0, data.Length);
                grect.Texture   = page;
                grect.OffsetX   = (int)(gdata.offsetX + left - 2);
                grect.OffsetY   = (int)(gdata.offsetY + top - 2);
                grect.Rectangle = r;
                glyphs.Add(glyphHash, grect);
            }
            return(grect);
        }
コード例 #10
0
        private void ResizeNormal(bool initial = false)
        {
            if (!initial && MediaEngine.GraphState == GraphState.Reset)
            {
                return;
            }

            GDI.RECT rect;
            WindowsManagement.GetWindowRect(_hwndHost.Handle, out rect);
            int clientWidth  = rect.right - rect.left;
            int clientHeight = rect.bottom - rect.top;

            double w     = clientWidth;
            double h     = clientHeight;
            double ratio = w / h;
            double dAspectRatio;

            _rcDest = rect;

            switch (_aspectRatio)
            {
            case AspectRatio.AR_ORIGINAL:
                dAspectRatio = _nativeAspectRatio;
                break;

            case AspectRatio.AR_16x9:
                dAspectRatio = 16.0 / 9.0;
                break;

            case AspectRatio.AR_4x3:
                dAspectRatio = 4.0 / 3.0;
                break;

            case AspectRatio.AR_47x20:
                dAspectRatio = 47.0 / 20.0;
                break;

            case AspectRatio.AR_1x1:
                dAspectRatio = 1.0;
                break;

            case AspectRatio.AR_5x4:
                dAspectRatio = 5.0 / 4.0;
                break;

            case AspectRatio.AR_16x10:
                dAspectRatio = 16.0 / 10.0;
                break;

            default:
            {
                // free aspect ratio
                ApplyDestinationRect();
                return;
            }
            }

            int hor;
            int vert;

            if (_isFixed)
            {
                int fixedSize = (int)_fixedSize;
                if (ratio >= dAspectRatio)
                {
                    vert           = (_rcSrc.cy * fixedSize / _divideSize) - clientHeight;
                    _rcDest.top   += (vert >= 0) ? 0 : -vert / 2;
                    _rcDest.bottom = (vert >= 0) ? _rcDest.bottom : _rcDest.top + (_rcSrc.cy * fixedSize / _divideSize);
                    h             = _rcDest.bottom - _rcDest.top;
                    w             = h * dAspectRatio;
                    hor           = clientWidth - (int)w;
                    _rcDest.left += (hor <= 0) ? 0 : hor / 2;
                    _rcDest.right = _rcDest.left + (int)w;
                }
                else
                {
                    hor = (_rcSrc.cx * fixedSize / _divideSize) - clientWidth;
                    // hor>=0 - client area is smaller than video hor size
                    _rcDest.left  += (hor >= 0) ? 0 : -hor / 2;
                    _rcDest.right  = (hor >= 0) ? _rcDest.right : _rcDest.left + (_rcSrc.cx * fixedSize / _divideSize);
                    w              = _rcDest.right - _rcDest.left;
                    h              = w / dAspectRatio;
                    vert           = clientHeight - (int)h;
                    _rcDest.top   += (vert <= 0) ? 0 : vert / 2;
                    _rcDest.bottom = _rcDest.top + (int)h;
                }
            }
            else
            {
                if (ratio >= dAspectRatio)
                {
                    h             = _rcDest.bottom - _rcDest.top;
                    w             = h * dAspectRatio;
                    hor           = clientWidth - (int)w;
                    _rcDest.left += (hor <= 0) ? 0 : hor / 2;
                    _rcDest.right = _rcDest.left + (int)w;
                }
                else
                {
                    w              = _rcDest.right - _rcDest.left;
                    h              = w / dAspectRatio;
                    vert           = clientHeight - (int)h;
                    _rcDest.top   += (vert <= 0) ? 0 : vert / 2;
                    _rcDest.bottom = _rcDest.top + (int)h;
                }
            }

            ApplyDestinationRect();
        }
コード例 #11
0
 public abstract void SetVideoPosition(GDI.RECT rcSrc, GDI.RECT rcDest);
コード例 #12
0
        public override void BuildUp(FilterGraphBuilderParameters parameters)
        {
            // Create filter graph manager
            InitializeGraphBuilder(() =>
            {
                object comobj = null;
                try
                {
                    var type         = Type.GetTypeFromCLSID(Clsid.FilterGraph, true);
                    comobj           = Activator.CreateInstance(type);
                    var graphBuilder = (IGraphBuilder)comobj;
                    comobj           = null;                  // important! (see the finally block)

                    return(graphBuilder);
                }
                catch (Exception e)
                {
                    throw new FilterGraphBuilderException(GraphBuilderError.FilterGraphManager, e);
                }
                finally
                {
                    if (comobj != null)
                    {
                        Marshal.FinalReleaseComObject(comobj);
                    }
                }
            });


            // Adding a source filter for a specific video file
            _sourceFilterHandler = SourceFilterHandlerFactory.AddSourceFilter(GraphBuilder, parameters.Source);

            // QUERY the filter graph interfaces
            InitializeMediaEventEx(parameters.MediaWindowHandle);
            InitializeFilterGraph2();
            InitializeMediaControl();
            InitializeMediaSeeking();
            InitializeBasicAudio();

            // create a renderer
            ThrowExceptionForHRPointer errorFunc = delegate(int hrCode, GraphBuilderError error)
            {
                hrCode.ThrowExceptionForHR(error);
            };

            Renderer = RendererBase.AddRenderer(GraphBuilder, parameters.PreferredVideoRenderer, errorFunc, parameters.MediaWindowHandle);

            DoBuildGraph();

            SeekingCapabilities caps = SeekingCapabilities.CanGetDuration;
            int hr = MediaSeeking.CheckCapabilities(ref caps);

            if (hr == DsHlp.S_OK)
            {
                _isGraphSeekable = true;

                long rtDuration;
                MediaSeeking.GetDuration(out rtDuration);

                _duration = rtDuration;
            }

            // MEDIA SIZE
            int height, arWidth;
            int width, arHeight;

            Renderer.GetNativeVideoSize(out width, out height, out arWidth, out arHeight);

            double w = arWidth;
            double h = arHeight;

            _aspectRatio = w / h;

            _sourceRect = new GDI.RECT {
                left = 0, top = 0, right = width, bottom = height
            };

//            if (FindSplitter(pFilterGraph))
//                ReportUnrenderedPins(pFilterGraph); // then we can raise OnFailedStreamsAvailable
            GatherMediaInfo(parameters.Source);
        }
コード例 #13
0
 public void Move(GDI.RECT rcDest)
 {
     WindowsManagement.MoveWindow(Handle, rcDest.left, rcDest.top, rcDest.right - rcDest.left, rcDest.bottom - rcDest.top, true);
 }
 public DestinationRectangleChangedEventArgs(GDI.RECT newRect)
 {
     _newRect = newRect;
 }
コード例 #15
0
        private unsafe GlyphData GdiCreateGlyph(GlyphIndex glyphIndex)
        {
            // Measure the size
            GDI.GLYPHMETRICS glyphMetrics;
            GDI.MAT2         matrix = new GDI.MAT2 {
                eM11 = 65536, eM12 = 0, eM21 = 0, eM22 = 65536
            };
            if (GDI.GetGlyphOutline(_gdiHdc, glyphIndex, GDI.GGO.GGO_METRICS | GDI.GGO.GGO_GLYPH_INDEX, out glyphMetrics, 0, IntPtr.Zero, ref matrix) == 0xffffffff)
            {
                throw new GDI.GDIException("GetGlyphOutline");
            }

            // Create bitmap
            GDI.BITMAPINFO bitmapInfo;
            bitmapInfo.biSize          = Marshal.SizeOf(typeof(GDI.BITMAPINFO));
            bitmapInfo.biWidth         = glyphMetrics.width + _marginInTexture * 2;
            bitmapInfo.biHeight        = glyphMetrics.height + _marginInTexture * 2;
            bitmapInfo.biPlanes        = 1;
            bitmapInfo.biBitCount      = 32;
            bitmapInfo.biCompression   = 0; //BI_RGB
            bitmapInfo.biSizeImage     = 0;
            bitmapInfo.biXPelsPerMeter = 1024;
            bitmapInfo.biYPelsPerMeter = 1024;
            bitmapInfo.biClrUsed       = 0;
            bitmapInfo.biClrImportant  = 0;
            IntPtr bitmapPtr;
            IntPtr hbitmap = GDI.CreateDIBSection(_gdiHdc, ref bitmapInfo, GDI.DIB_RGB_COLORS, out bitmapPtr, IntPtr.Zero, 0);

            if (hbitmap == IntPtr.Zero)
            {
                throw new GDI.GDIException("CreateDIBSection");
            }
            try
            {
                // Render gylph
                IntPtr selectObjectResult = GDI.SelectObject(_gdiHdc, hbitmap);
                if (selectObjectResult == IntPtr.Zero || selectObjectResult == new IntPtr(65535))
                {
                    throw new GDI.GDIException("SelectObject");
                }
                GDI.RECT rect = new GDI.RECT {
                    Left = 0, Top = 0, Right = bitmapInfo.biWidth, Bottom = bitmapInfo.biHeight
                };
                if (!GDI.ExtTextOutW(_gdiHdc, _marginInTexture - glyphMetrics.x, _marginInTexture + glyphMetrics.y - _lineAscent, GDI.ETO.ETO_OPAQUE | GDI.ETO.ETO_CLIPPED | GDI.ETO.ETO_GLYPH_INDEX, ref rect, new IntPtr(&glyphIndex), 1, IntPtr.Zero))
                {
                    throw new GDI.GDIException("ExtTextOut");
                }
                if (!GDI.GdiFlush())
                {
                    throw new GDI.GDIException("GdiFlush");
                }

                // Convert RGB GDI image to RGBA byte array
                // White color is mapped to full transparency
                byte[] imageData = new byte[bitmapInfo.biWidth * bitmapInfo.biHeight * ImageC.PixelSize];
                fixed(byte *destination2 = imageData)
                {
                    uint *source      = (uint *)bitmapPtr;
                    uint *destination = (uint *)destination2;
                    int   count       = bitmapInfo.biWidth * bitmapInfo.biHeight;

                    for (int i = 0; i < count; ++i)
                    {
                        // Optimized version of:
                        // https://stackoverflow.com/a/40862635

                        // White text
                        uint pixel  = source[i];
                        uint r      = 255 - (pixel & 0xff);
                        uint g      = 255 - ((pixel >> 8) & 0xff);
                        uint b      = 255 - ((pixel >> 16) & 0xff);
                        uint a      = 255;
                        uint factor = a == 0 ? 0xff0000 : (0xff0000 / a);
                        r = Math.Min((r * factor + 0x8000) >> 16, 255);
                        g = Math.Min((g * factor + 0x8000) >> 16, 255);
                        b = Math.Min((b * factor + 0x8000) >> 16, 255);
                        destination[i] = (a << 24) | (b << 16) | (g << 8) | r;

                        /* // Black text
                         * uint pixel = source[i];
                         * uint r = pixel & 0xff;
                         * uint g = (pixel >> 8) & 0xff;
                         * uint b = (pixel >> 16) & 0xff;
                         * uint a = 0xff - Math.Min(r, Math.Min(g, b));
                         * uint factor = a == 0 ? 0xff0000 : (0xff0000 / a);
                         * r = (0xff8000 - Math.Min(0xff8000, (255 - r) * factor)) >> 16;
                         * g = (0xff8000 - Math.Min(0xff8000, (255 - g) * factor)) >> 16;
                         * b = (0xff8000 - Math.Min(0xff8000, (255 - b) * factor)) >> 16;
                         * destination[i] = (a << 24) | (b << 16) | (g << 8) | r;
                         */
                    }
                }

                // TEST
                //ImageC.FromByteArray(imageData, bitmapInfo.biWidth, bitmapInfo.biHeight).Save("T:\\Out.png");

                // Generate output
                return(new GlyphData
                {
                    Image = ImageC.FromByteArray(imageData, bitmapInfo.biWidth, bitmapInfo.biHeight),
                    Offset = new VectorInt2(glyphMetrics.x - _marginInTexture, glyphMetrics.y + _marginInTexture)
                });
            }
            finally
            {
                GDI.DeleteObject(hbitmap);
            }
        }