VirtualBox

Ticket #15443: bugfix-video-rec.patch

File bugfix-video-rec.patch, 14.7 KB (added by gim, 9 years ago)

AttachFramebuffer fix

  • new file VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/Framebuffer.cpp

    From 1489c6e0226f2a2ade910d0bc3d88e768bbed52b Mon Sep 17 00:00:00 2001
    From: gim
    Date: Thu, 26 May 2016 00:01:52 +0300
    Subject: [PATCH] bugfix video rec (https://www.virtualbox.org/ticket/15443)
    
    ---
     .../VBox/Frontends/VBoxHeadless/Framebuffer.cpp    | 335 +++++++++++++++++++++
     .../src/VBox/Frontends/VBoxHeadless/Framebuffer.h  | 101 +++++++
     .../src/VBox/Frontends/VBoxHeadless/Makefile.kmk   |   1 +
     .../VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp   |  22 ++
     4 files changed, 459 insertions(+)
     create mode 100644 VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/Framebuffer.cpp
     create mode 100644 VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/Framebuffer.h
    
    diff --git a/VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/Framebuffer.cpp b/VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/Framebuffer.cpp
    new file mode 100644
    index 0000000..11585a9
    - +  
     1/** @file
     2 *
     3 * VBox Remote Desktop Framebuffer
     4 */
     5
     6/*
     7 * Copyright (C) 2010 Oracle Corporation
     8 *
     9 * This file is part of VirtualBox Open Source Edition (OSE), as
     10 * available from http://www.virtualbox.org. This file is free software;
     11 * you can redistribute it and/or modify it under the terms of the GNU
     12 * General Public License (GPL) as published by the Free Software
     13 * Foundation, in version 2 as it comes in the "COPYING" file of the
     14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
     15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
     16 */
     17
     18#include "Framebuffer.h"
     19
     20#include <VBox/com/com.h>
     21#include <VBox/com/array.h>
     22
     23#include <iprt/alloc.h>
     24
     25using namespace com;
     26
     27#define LOG_GROUP LOG_GROUP_GUI
     28#include <VBox/log.h>
     29
     30/*
     31 * VRDP server frame buffer
     32 */
     33
     34#ifdef VBOX_WITH_XPCOM
     35#include <nsMemory.h>
     36NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VRDPFramebuffer, IFramebuffer)
     37NS_DECL_CLASSINFO(VRDPFramebuffer)
     38#endif
     39
     40VRDPFramebuffer::VRDPFramebuffer()
     41{
     42#if defined (RT_OS_WINDOWS)
     43    refcnt = 0;
     44#endif /* RT_OS_WINDOWS */
     45
     46    mBuffer = NULL;
     47
     48    RTCritSectInit (&m_CritSect);
     49
     50    // start with a standard size
     51    RequestResize(0, 0,
     52                  (ULONG) NULL, 0, 0, 640, 480, NULL);
     53}
     54
     55VRDPFramebuffer::~VRDPFramebuffer()
     56{
     57    if (mBuffer)
     58    {
     59        RTMemFree (mBuffer);
     60    }
     61
     62    RTCritSectDelete (&m_CritSect);
     63}
     64
     65STDMETHODIMP VRDPFramebuffer::COMGETTER(Width)(ULONG *width)
     66{
     67    if (!width)
     68        return E_INVALIDARG;
     69    *width = mWidth;
     70    return S_OK;
     71}
     72
     73STDMETHODIMP VRDPFramebuffer::COMGETTER(Height)(ULONG *height)
     74{
     75    if (!height)
     76        return E_INVALIDARG;
     77    *height = mHeight;
     78    return S_OK;
     79}
     80
     81STDMETHODIMP VRDPFramebuffer::Lock()
     82{
     83    RTCritSectEnter (&m_CritSect);
     84    return S_OK;
     85}
     86
     87STDMETHODIMP VRDPFramebuffer::Unlock()
     88{
     89    RTCritSectLeave (&m_CritSect);
     90    return S_OK;
     91}
     92
     93STDMETHODIMP VRDPFramebuffer::COMGETTER(Address)(BYTE **address)
     94{
     95    if (!address)
     96        return E_INVALIDARG;
     97    *address = mScreen;
     98    return S_OK;
     99}
     100
     101STDMETHODIMP VRDPFramebuffer::COMGETTER(BitsPerPixel)(ULONG *bitsPerPixel)
     102{
     103    if (!bitsPerPixel)
     104        return E_INVALIDARG;
     105    *bitsPerPixel = mBitsPerPixel;
     106    return S_OK;
     107}
     108
     109STDMETHODIMP VRDPFramebuffer::COMGETTER(BytesPerLine)(ULONG *bytesPerLine)
     110{
     111    if (!bytesPerLine)
     112        return E_INVALIDARG;
     113    *bytesPerLine = mBytesPerLine;
     114    return S_OK;
     115}
     116
     117STDMETHODIMP VRDPFramebuffer::COMGETTER(PixelFormat) (ULONG *pixelFormat)
     118{
     119    if (!pixelFormat)
     120        return E_POINTER;
     121    *pixelFormat = mPixelFormat;
     122    return S_OK;
     123}
     124
     125STDMETHODIMP VRDPFramebuffer::COMGETTER(UsesGuestVRAM) (BOOL *usesGuestVRAM)
     126{
     127    if (!usesGuestVRAM)
     128        return E_POINTER;
     129    *usesGuestVRAM = mUsesGuestVRAM;
     130    return S_OK;
     131}
     132
     133STDMETHODIMP VRDPFramebuffer::COMGETTER(HeightReduction) (ULONG *heightReduction)
     134{
     135    if (!heightReduction)
     136        return E_POINTER;
     137    /* no reduction at all */
     138    *heightReduction = 0;
     139    return S_OK;
     140}
     141
     142STDMETHODIMP VRDPFramebuffer::COMGETTER(Overlay) (IFramebufferOverlay **aOverlay)
     143{
     144    if (!aOverlay)
     145        return E_POINTER;
     146    /* overlays are not yet supported */
     147    *aOverlay = 0;
     148    return S_OK;
     149}
     150
     151STDMETHODIMP VRDPFramebuffer::COMGETTER(WinId) (LONG64 *winId)
     152{
     153    if (!winId)
     154        return E_POINTER;
     155    *winId = 0;
     156    return S_OK;
     157}
     158
     159STDMETHODIMP VRDPFramebuffer::COMGETTER(Capabilities)(ComSafeArrayOut(FramebufferCapabilities_T, aCapabilities))
     160{
     161    if (ComSafeArrayOutIsNull(aCapabilities))
     162        return E_POINTER;
     163
     164    com::SafeArray<FramebufferCapabilities_T> caps;
     165    caps.resize(1);
     166    caps[0] = FramebufferCapabilities_UpdateImage;
     167    caps.detachTo(ComSafeArrayOutArg(aCapabilities));
     168    return S_OK;
     169}
     170
     171STDMETHODIMP VRDPFramebuffer::NotifyUpdate(ULONG x, ULONG y,
     172                                           ULONG w, ULONG h)
     173{
     174    return S_OK;
     175}
     176
     177STDMETHODIMP VRDPFramebuffer::NotifyUpdateImage(ULONG aX,
     178                                          ULONG aY,
     179                                          ULONG aWidth,
     180                                          ULONG aHeight,
     181                                          ComSafeArrayIn(BYTE, aImage))
     182{
     183    return S_OK;
     184}
     185
     186STDMETHODIMP VRDPFramebuffer::NotifyChange(ULONG aScreenId,
     187                                     ULONG aXOrigin,
     188                                     ULONG aYOrigin,
     189                                     ULONG aWidth,
     190                                     ULONG aHeight)
     191{
     192    return S_OK;
     193}
     194
     195STDMETHODIMP VRDPFramebuffer::RequestResize(ULONG aScreenId, ULONG pixelFormat, BYTE *vram,
     196                                            ULONG bitsPerPixel, ULONG bytesPerLine,
     197                                            ULONG w, ULONG h,
     198                                            BOOL *finished)
     199{
     200    /* Agree to requested format for LFB modes and use guest VRAM directly, thus avoiding
     201     * unnecessary memcpy in VGA device.
     202     */
     203
     204    Log(("pixelFormat = %08X, vram = %p, bpp = %d, bpl = 0x%08X, %dx%d\n",
     205         pixelFormat, vram, bitsPerPixel, bytesPerLine, w, h));
     206
     207    /* Free internal buffer. */
     208    if (mBuffer)
     209    {
     210        RTMemFree (mBuffer);
     211        mBuffer = NULL;
     212    }
     213
     214    mUsesGuestVRAM = FALSE;
     215
     216    mWidth = w;
     217    mHeight = h;
     218
     219    if (pixelFormat == BitmapFormat_BGR)
     220    {
     221        switch (bitsPerPixel)
     222        {
     223            case 32:
     224            case 24:
     225            case 16:
     226                mUsesGuestVRAM = TRUE;
     227                break;
     228
     229            default:
     230                break;
     231        }
     232    }
     233
     234    if (mUsesGuestVRAM)
     235    {
     236        mScreen = vram;
     237        mBitsPerPixel = bitsPerPixel;
     238        mBytesPerLine = bytesPerLine;
     239        mPixelFormat = BitmapFormat_BGR;
     240
     241        Log (("Using guest VRAM directly, %d BPP\n", mBitsPerPixel));
     242    }
     243    else
     244    {
     245        mBitsPerPixel = 32;
     246        mBytesPerLine = w * 4; /* Here we have 32 BPP */
     247
     248        if (mBytesPerLine > 0 && h > 0) /* Check for nul dimensions. */
     249        {
     250            mBuffer = RTMemAllocZ(mBytesPerLine * h);
     251        }
     252
     253        mScreen = (uint8_t *)mBuffer;
     254
     255        Log(("Using internal buffer, %d BPP\n", mBitsPerPixel));
     256    }
     257
     258    if (!mScreen)
     259    {
     260        Log(("No screen. BPP = %d, w = %d, h = %d!!!\n", mBitsPerPixel, w, h));
     261
     262        /* Just reset everything. */
     263        mPixelFormat = 0;
     264
     265        mWidth = 0;
     266        mHeight = 0;
     267        mBitsPerPixel = 0;
     268        mBytesPerLine = 0;
     269        mUsesGuestVRAM = FALSE;
     270    }
     271
     272    /* Inform the caller that the operation was successful. */
     273
     274    if (finished)
     275        *finished = TRUE;
     276
     277    return S_OK;
     278}
     279
     280/**
     281 * Returns whether we like the given video mode.
     282 *
     283 * @returns COM status code
     284 * @param   width     video mode width in pixels
     285 * @param   height    video mode height in pixels
     286 * @param   bpp       video mode bit depth in bits per pixel
     287 * @param   supported pointer to result variable
     288 */
     289STDMETHODIMP VRDPFramebuffer::VideoModeSupported(ULONG width, ULONG height, ULONG bpp, BOOL *supported)
     290{
     291    if (!supported)
     292        return E_POINTER;
     293    *supported = TRUE;
     294    return S_OK;
     295}
     296
     297STDMETHODIMP VRDPFramebuffer::GetVisibleRegion(BYTE *aRectangles, ULONG aCount,
     298                                               ULONG *aCountCopied)
     299{
     300    PRTRECT rects = (PRTRECT)aRectangles;
     301
     302    if (!rects)
     303        return E_POINTER;
     304
     305    /// @todo
     306
     307    NOREF(aCount);
     308    NOREF(aCountCopied);
     309
     310    return S_OK;
     311}
     312
     313STDMETHODIMP VRDPFramebuffer::SetVisibleRegion(BYTE *aRectangles, ULONG aCount)
     314{
     315    PRTRECT rects = (PRTRECT)aRectangles;
     316
     317    if (!rects)
     318        return E_POINTER;
     319
     320    /// @todo
     321
     322    NOREF(aCount);
     323
     324    return S_OK;
     325}
     326
     327STDMETHODIMP VRDPFramebuffer::ProcessVHWACommand(BYTE *pCommand)
     328{
     329    return E_NOTIMPL;
     330}
     331
     332STDMETHODIMP VRDPFramebuffer::Notify3DEvent(ULONG uType, ComSafeArrayIn(BYTE, aData))
     333{
     334    return E_NOTIMPL;
     335}
     336 No newline at end of file
  • new file VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/Framebuffer.h

    diff --git a/VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/Framebuffer.h b/VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/Framebuffer.h
    new file mode 100644
    index 0000000..5bbd725
    - +  
     1/** @file
     2 *
     3 * VBox Remote Desktop Framebuffer.
     4 */
     5
     6/*
     7 * Copyright (C) 2010-2012 Oracle Corporation
     8 *
     9 * This file is part of VirtualBox Open Source Edition (OSE), as
     10 * available from http://www.virtualbox.org. This file is free software;
     11 * you can redistribute it and/or modify it under the terms of the GNU
     12 * General Public License (GPL) as published by the Free Software
     13 * Foundation, in version 2 as it comes in the "COPYING" file of the
     14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
     15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
     16 */
     17
     18#ifndef __VRDP__FRAMEBUFFER__H
     19#define __VRDP__FRAMEBUFFER__H
     20
     21#include <VBox/com/VirtualBox.h>
     22
     23#include <iprt/critsect.h>
     24
     25class VRDPFramebuffer :
     26    VBOX_SCRIPTABLE_IMPL(IFramebuffer)
     27{
     28public:
     29    VRDPFramebuffer();
     30    virtual ~VRDPFramebuffer();
     31
     32#ifndef VBOX_WITH_XPCOM
     33    STDMETHOD_(ULONG, AddRef)() {
     34        return ::InterlockedIncrement (&refcnt);
     35    }
     36    STDMETHOD_(ULONG, Release)()
     37    {
     38        long cnt = ::InterlockedDecrement (&refcnt);
     39        if (cnt == 0)
     40            delete this;
     41        return cnt;
     42    }
     43#endif
     44    VBOX_SCRIPTABLE_DISPATCH_IMPL(IFramebuffer)
     45
     46    NS_DECL_ISUPPORTS
     47
     48    STDMETHOD(COMGETTER(Width))(ULONG *width);
     49    STDMETHOD(COMGETTER(Height))(ULONG *height);
     50    STDMETHOD(Lock)();
     51    STDMETHOD(Unlock)();
     52    STDMETHOD(COMGETTER(Address))(BYTE **address);
     53    STDMETHOD(COMGETTER(BitsPerPixel))(ULONG *bitsPerPixel);
     54    STDMETHOD(COMGETTER(BytesPerLine))(ULONG *bytesPerLine);
     55    STDMETHOD(COMGETTER(PixelFormat)) (ULONG *pixelFormat);
     56    STDMETHOD(COMGETTER(UsesGuestVRAM)) (BOOL *usesGuestVRAM);
     57    STDMETHOD(COMGETTER(HeightReduction)) (ULONG *heightReduction);
     58    STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **aOverlay);
     59    STDMETHOD(COMGETTER(WinId)) (LONG64 *winId);
     60    STDMETHOD(COMGETTER(Capabilities))(ComSafeArrayOut(FramebufferCapabilities_T, aCapabilities));
     61
     62    STDMETHOD(NotifyUpdate)(ULONG x, ULONG y, ULONG w, ULONG h);
     63    STDMETHOD(NotifyUpdateImage)(ULONG aX, ULONG aY, ULONG aWidth, ULONG aHeight, ComSafeArrayIn(BYTE, aImage));
     64    STDMETHOD(NotifyChange)(ULONG aScreenId, ULONG aXOrigin, ULONG aYOrigin, ULONG aWidth, ULONG aHeight);
     65
     66    STDMETHOD(RequestResize)(ULONG aScreenId, ULONG pixelFormat, BYTE *vram,
     67                             ULONG bitsPerPixel, ULONG bytesPerLine, ULONG w, ULONG h,
     68                             BOOL *finished);
     69    STDMETHOD(VideoModeSupported)(ULONG width, ULONG height, ULONG bpp, BOOL *supported);
     70
     71    STDMETHOD(GetVisibleRegion)(BYTE *aRectangles, ULONG aCount, ULONG *aCountCopied);
     72    STDMETHOD(SetVisibleRegion)(BYTE *aRectangles, ULONG aCount);
     73
     74    STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
     75
     76    STDMETHOD(Notify3DEvent)(ULONG uType, ComSafeArrayIn(BYTE, aData));
     77private:
     78    /* If the format is Opaque, then internal memory buffer is used.
     79     * Otherwise guest VRAM is used directly.
     80     */
     81    ULONG mPixelFormat;
     82
     83    void *mBuffer;
     84
     85    uint8_t *mScreen;
     86    ULONG mWidth;
     87    ULONG mHeight;
     88    ULONG mBitsPerPixel;
     89    ULONG mBytesPerLine;
     90
     91    BOOL mUsesGuestVRAM;
     92
     93    RTCRITSECT m_CritSect;
     94
     95#ifndef VBOX_WITH_XPCOM
     96    long refcnt;
     97#endif
     98};
     99
     100
     101#endif /* __VRDP__FRAMEBUFFER__H */
  • VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/Makefile.kmk

    diff --git a/VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/Makefile.kmk b/VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/Makefile.kmk
    index 2a73793..8f0e482 100644
    a b VBoxHeadlessHardened_NAME = VBoxHeadless  
    4646VBoxHeadless_TEMPLATE  := $(if $(VBOX_WITH_HARDENING),VBOXMAINCLIENTDLL,VBOXMAINCLIENTEXE)
    4747VBoxHeadless_DEFS      += $(if $(VBOX_WITH_VPX),VBOX_WITH_VPX,)
    4848VBoxHeadless_SOURCES    = VBoxHeadless.cpp
     49VBoxHeadless_SOURCES  += Framebuffer.cpp
    4950ifdef VBOX_WITH_GUEST_PROPS
    5051 VBoxHeadless_DEFS     += VBOX_WITH_GUEST_PROPS
    5152endif
  • VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp

    diff --git a/VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp b/VirtualBox-5.0.20/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
    index dc0ea5e..578f63a 100644
    a b using namespace com;  
    5959#include <signal.h>
    6060#endif
    6161
     62#include "Framebuffer.h"
     63
    6264////////////////////////////////////////////////////////////////////////////////
    6365
    6466#define LogError(m,rc) \
    extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)  
    966968            CHECK_ERROR_BREAK(machine, COMSETTER(VideoCaptureEnabled)(TRUE));
    967969        }
    968970#endif /* defined(VBOX_WITH_VPX) */
     971        ULONG cMonitors = 1;
     972        machine->COMGETTER(MonitorCount)(&cMonitors);
     973
     974        unsigned uScreenId;
     975        for (uScreenId = 0; uScreenId < cMonitors; uScreenId++)
     976        {
     977            VRDPFramebuffer *pVRDPFramebuffer = new VRDPFramebuffer();
     978            Bstr VRDPFramebufferId;
     979            if (!pVRDPFramebuffer)
     980            {
     981                RTPrintf("Error: could not create framebuffer object %d\n", uScreenId);
     982                break;
     983            }
     984            pVRDPFramebuffer->AddRef();
     985            display->AttachFramebuffer(uScreenId, pVRDPFramebuffer, VRDPFramebufferId.asOutParam());
     986        }
     987        if (uScreenId < cMonitors)
     988        {
     989            break;
     990        }
    969991
    970992        /* get the machine debugger (isn't necessarily available) */
    971993        ComPtr <IMachineDebugger> machineDebugger;

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette