VirtualBox

Changeset 75251 in vbox


Ignore:
Timestamp:
Nov 5, 2018 5:55:29 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126353
Message:

Capturing: Separated capturing settings into new interfaces ICaptureSettings and ICaptureScreenSettings to unload stuff from IMachine; a lot of internal interface / code cleanups. Also see #9286. Work in progress.

Location:
trunk
Files:
4 added
44 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/log.h

    r74761 r75251  
    354354    /** Main group, IBIOSSettings. */
    355355    LOG_GROUP_MAIN_BIOSSETTINGS,
     356    /** Main group, ICaptureChangedEvent. */
     357    LOG_GROUP_MAIN_CAPTURECHANGEDEVENT,
     358    /** Main group, ICaptureSettings. */
     359    LOG_GROUP_MAIN_CAPTURESETTINGS,
     360    /** Main group, ICaptureScreenSettings. */
     361    LOG_GROUP_MAIN_CAPTURESCREENSETTINGS,
    356362    /** Main group, ICanShowWindowEvent. */
    357363    LOG_GROUP_MAIN_CANSHOWWINDOWEVENT,
     
    662668    /** Main group, IVFSExplorer. */
    663669    LOG_GROUP_MAIN_VFSEXPLORER,
    664     /** Main group, IVideoCaptureChangedEvent. */
    665     LOG_GROUP_MAIN_VIDEOCAPTURECHANGEDEVENT,
    666670    /** Main group, IVirtualBox. */
    667671    LOG_GROUP_MAIN_VIRTUALBOX,
     
    10001004    "MAIN_BANDWIDTHGROUPCHANGEDEVENT", \
    10011005    "MAIN_BIOSSETTINGS", \
     1006    "MAIN_CAPTURECHANGEDEVENT", \
     1007    "MAIN_CAPTURESETTINGS", \
     1008    "MAIN_CAPTURESCREENSETTINGS", \
    10021009    "MAIN_CANSHOWWINDOWEVENT", \
    10031010    "MAIN_CERTIFICATE", \
  • trunk/include/VBox/settings.h

    r74431 r75251  
    1818
    1919/*
    20  * Copyright (C) 2007-2017 Oracle Corporation
     20 * Copyright (C) 2007-2018 Oracle Corporation
    2121 *
    2222 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    481481};
    482482
     483/** List for keeping a capturing feature list. */
     484typedef std::map<CaptureFeature_T, bool> CaptureFeatureMap;
     485
     486class CaptureScreenSettings
     487{
     488public:
     489
     490    CaptureScreenSettings();
     491
     492    virtual ~CaptureScreenSettings();
     493
     494    void applyDefaults(void);
     495
     496    bool areDefaultSettings(void) const;
     497
     498    bool isFeatureEnabled(CaptureFeature_T enmFeature) const;
     499
     500    bool operator==(const CaptureScreenSettings &d) const;
     501
     502    bool                 fEnabled;       // requires settings version 1.14 (VirtualBox 4.3)
     503    CaptureDestination_T enmDest;        // new since VirtualBox 6.0.
     504    CaptureFeatureMap    featureMap;     // new since VirtualBox 6.0.
     505    uint32_t             ulMaxTimeS;     // requires settings version 1.14 (VirtualBox 4.3)
     506    com::Utf8Str         strOptions;     // new since VirtualBox 5.2.
     507
     508    struct Audio
     509    {
     510        Audio()
     511            : enmAudioCodec(CaptureAudioCodec_Opus)
     512            , uHz(22050)
     513            , cBits(16)
     514            , cChannels(2) { }
     515
     516        /** The audio codec type to use. */
     517        CaptureAudioCodec_T enmAudioCodec; // new since VirtualBox 6.0.
     518        /** Hz rate. */
     519        uint16_t            uHz;           // new since VirtualBox 6.0.
     520        /** Bits per sample. */
     521        uint8_t             cBits;         // new since VirtualBox 6.0.
     522        /** Number of audio channels. */
     523        uint8_t             cChannels;     // new since VirtualBox 6.0.
     524    } Audio;
     525
     526    struct Video
     527    {
     528        Video()
     529            : enmCodec(CaptureVideoCodec_VP8)
     530            , ulWidth(1024)
     531            , ulHeight(768)
     532            , ulRate(512)
     533            , ulFPS(25) { }
     534
     535        CaptureVideoCodec_T  enmCodec;  // new since VirtualBox 6.0.
     536        uint32_t             ulWidth;   // requires settings version 1.14 (VirtualBox 4.3)
     537        uint32_t             ulHeight;  // requires settings version 1.14 (VirtualBox 4.3)
     538        uint32_t             ulRate;    // requires settings version 1.14 (VirtualBox 4.3)
     539        uint32_t             ulFPS;     // requires settings version 1.14 (VirtualBox 4.3)
     540    } Video;
     541
     542    struct File
     543    {
     544        File()
     545            : ulMaxSizeMB(0) { }
     546
     547        uint32_t     ulMaxSizeMB; // requires settings version 1.14 (VirtualBox 4.3)
     548        com::Utf8Str strName;     // requires settings version 1.14 (VirtualBox 4.3)
     549    } File;
     550};
     551
     552/** Map for keeping settings per virtual screen. */
     553typedef std::map<unsigned long, CaptureScreenSettings> CaptureScreenMap;
     554
     555/**
     556 * NOTE: If you add any fields in here, you must update a) the constructor and b)
     557 * the operator== which is used by MachineConfigFile::operator==(), or otherwise
     558 * your settings might never get saved.
     559 */
     560struct CaptureSettings
     561{
     562    CaptureSettings();
     563
     564    void applyDefaults(void);
     565
     566    bool areDefaultSettings(void) const;
     567
     568    bool operator==(const CaptureSettings &d) const;
     569
     570    bool             fEnabled;       // requires settings version 1.14 (VirtualBox 4.3)
     571    CaptureScreenMap mapScreens;
     572};
     573
    483574/**
    484575 * NOTE: If you add any fields in here, you must update a) the constructor and b)
     
    890981    bool areBootOrderDefaultSettings() const;
    891982    bool areDisplayDefaultSettings() const;
    892     bool areVideoCaptureDefaultSettings() const;
    893983    bool areAllNetworkAdaptersDefaultSettings(SettingsVersion_T sv) const;
    894984
     
    9371027                        fAccelerate2DVideo;     // requires settings version 1.8 (VirtualBox 3.1)
    9381028
    939     uint32_t            ulVideoCaptureHorzRes;  // requires settings version 1.14 (VirtualBox 4.3)
    940     uint32_t            ulVideoCaptureVertRes;  // requires settings version 1.14 (VirtualBox 4.3)
    941     uint32_t            ulVideoCaptureRate;     // requires settings version 1.14 (VirtualBox 4.3)
    942     uint32_t            ulVideoCaptureFPS;      // requires settings version 1.14 (VirtualBox 4.3)
    943     uint32_t            ulVideoCaptureMaxTime;  // requires settings version 1.14 (VirtualBox 4.3)
    944     uint32_t            ulVideoCaptureMaxSize;  // requires settings version 1.14 (VirtualBox 4.3)
    945     bool                fVideoCaptureEnabled;   // requires settings version 1.14 (VirtualBox 4.3)
    946     uint64_t            u64VideoCaptureScreens; // requires settings version 1.14 (VirtualBox 4.3)
    947     com::Utf8Str        strVideoCaptureFile;    // requires settings version 1.14 (VirtualBox 4.3)
    948     com::Utf8Str        strVideoCaptureOptions; // new since VirtualBox 5.2.
    949 
    9501029    FirmwareType_T      firmwareType;           // requires settings version 1.9 (VirtualBox 3.1)
    9511030
     
    9621041
    9631042    BIOSSettings        biosSettings;
     1043    CaptureSettings     captureSettings;
    9641044    USB                 usbSettings;
    9651045    NetworkAdaptersList llNetworkAdapters;
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp

    r72826 r75251  
    55
    66/*
    7  * Copyright (C) 2006-2017 Oracle Corporation
     7 * Copyright (C) 2006-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    395395        /* get the associated console */
    396396        CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
     397        if (!console)
     398            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Machine '%s' is not currently running", a->argv[0]);
     399
    397400        /* ... and session machine */
    398401        CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
    399 
    400         if (!console)
    401             return RTMsgErrorExit(RTEXITCODE_FAILURE, "Machine '%s' is not currently running", a->argv[0]);
    402402
    403403        /* which command? */
     
    18551855        }
    18561856#ifdef VBOX_WITH_VIDEOREC
    1857         /*
    1858          * Note: Commands starting with "vcp" are the deprecated versions and are
    1859          *       kept to ensure backwards compatibility.
    1860          */
    1861         else if (   !strcmp(a->argv[1], "videocap")
    1862                  || !strcmp(a->argv[1], "vcpenabled"))
    1863         {
    1864             if (a->argc != 3)
     1857        else if (!strcmp(a->argv[1], "capture"))
     1858        {
     1859            if (a->argc < 3)
    18651860            {
    18661861                errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
     
    18681863                break;
    18691864            }
    1870             if (!strcmp(a->argv[2], "on"))
    1871             {
    1872                 CHECK_ERROR_RET(sessionMachine, COMSETTER(VideoCaptureEnabled)(TRUE), RTEXITCODE_FAILURE);
    1873             }
    1874             else if (!strcmp(a->argv[2], "off"))
    1875             {
    1876                 CHECK_ERROR_RET(sessionMachine, COMSETTER(VideoCaptureEnabled)(FALSE), RTEXITCODE_FAILURE);
    1877             }
    1878             else
    1879             {
    1880                 errorArgument("Invalid state '%s'", Utf8Str(a->argv[2]).c_str());
    1881                 rc = E_FAIL;
    1882                 break;
    1883             }
    1884         }
    1885         else if (   !strcmp(a->argv[1], "videocapscreens")
    1886                  || !strcmp(a->argv[1], "vcpscreens"))
    1887         {
    1888             ULONG cMonitors = 64;
    1889             CHECK_ERROR_BREAK(machine, COMGETTER(MonitorCount)(&cMonitors));
    1890             com::SafeArray<BOOL> saScreens(cMonitors);
    1891             if (   a->argc == 3
    1892                 && !strcmp(a->argv[2], "all"))
    1893             {
    1894                 /* enable all screens */
    1895                 for (unsigned i = 0; i < cMonitors; i++)
    1896                     saScreens[i] = true;
    1897             }
    1898             else if (   a->argc == 3
    1899                      && !strcmp(a->argv[2], "none"))
    1900             {
    1901                 /* disable all screens */
    1902                 for (unsigned i = 0; i < cMonitors; i++)
    1903                     saScreens[i] = false;
    1904 
    1905                 /** @todo r=andy What if this is specified? */
    1906             }
    1907             else
    1908             {
    1909                 /* enable selected screens */
    1910                 for (unsigned i = 0; i < cMonitors; i++)
    1911                     saScreens[i] = false;
    1912                 for (int i = 2; SUCCEEDED(rc) && i < a->argc; i++)
    1913                 {
    1914                     uint32_t iScreen;
    1915                     int vrc = RTStrToUInt32Ex(a->argv[i], NULL, 0, &iScreen);
    1916                     if (vrc != VINF_SUCCESS)
    1917                     {
    1918                         errorArgument("Error parsing display number '%s'", a->argv[i]);
    1919                         rc = E_FAIL;
    1920                         break;
    1921                     }
    1922                     if (iScreen >= cMonitors)
    1923                     {
    1924                         errorArgument("Invalid screen ID specified '%u'", iScreen);
    1925                         rc = E_FAIL;
    1926                         break;
    1927                     }
    1928                     saScreens[iScreen] = true;
    1929                 }
    1930             }
    1931 
    1932             CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureScreens)(ComSafeArrayAsInParam(saScreens)));
    1933         }
    1934         else if (   !strcmp(a->argv[1], "videocapfile")
    1935                  || !strcmp(a->argv[1], "vcpfile"))
    1936         {
    1937             if (a->argc != 3)
    1938             {
    1939                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    1940                 rc = E_FAIL;
    1941                 break;
    1942             }
    1943 
    1944             CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureFile)(Bstr(a->argv[2]).raw()));
    1945         }
    1946         else if (!strcmp(a->argv[1], "videocapres"))
    1947         {
    1948             if (a->argc != 4)
    1949             {
    1950                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    1951                 rc = E_FAIL;
    1952                 break;
    1953             }
    1954 
    1955             uint32_t uVal;
    1956             int vrc = RTStrToUInt32Ex(a->argv[2], NULL, 0, &uVal);
    1957             if (RT_FAILURE(vrc))
    1958             {
    1959                 errorArgument("Error parsing width '%s'", a->argv[2]);
    1960                 rc = E_FAIL;
    1961                 break;
    1962             }
    1963             CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureWidth)(uVal));
    1964 
    1965             vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &uVal);
    1966             if (RT_FAILURE(vrc))
    1967             {
    1968                 errorArgument("Error parsing height '%s'", a->argv[3]);
    1969                 rc = E_FAIL;
    1970                 break;
    1971             }
    1972             CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureHeight)(uVal));
    1973         }
    1974         else if (!strcmp(a->argv[1], "vcpwidth")) /* Deprecated; keeping for compatibility. */
    1975         {
    1976             uint32_t uVal;
    1977             int vrc = RTStrToUInt32Ex(a->argv[2], NULL, 0, &uVal);
    1978             if (RT_FAILURE(vrc))
    1979             {
    1980                 errorArgument("Error parsing width '%s'", a->argv[2]);
    1981                 rc = E_FAIL;
    1982                 break;
    1983             }
    1984             CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureWidth)(uVal));
    1985         }
    1986         else if (!strcmp(a->argv[1], "vcpheight")) /* Deprecated; keeping for compatibility. */
    1987         {
    1988             uint32_t uVal;
    1989             int vrc = RTStrToUInt32Ex(a->argv[2], NULL, 0, &uVal);
    1990             if (RT_FAILURE(vrc))
    1991             {
    1992                 errorArgument("Error parsing height '%s'", a->argv[2]);
    1993                 rc = E_FAIL;
    1994                 break;
    1995             }
    1996             CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureHeight)(uVal));
    1997         }
    1998         else if (   !strcmp(a->argv[1], "videocaprate")
    1999                  || !strcmp(a->argv[1], "vcprate"))
    2000         {
    2001             if (a->argc != 3)
    2002             {
    2003                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    2004                 rc = E_FAIL;
    2005                 break;
    2006             }
    2007 
    2008             uint32_t uVal;
    2009             int vrc = RTStrToUInt32Ex(a->argv[2], NULL, 0, &uVal);
    2010             if (RT_FAILURE(vrc))
    2011             {
    2012                 errorArgument("Error parsing rate '%s'", a->argv[2]);
    2013                 rc = E_FAIL;
    2014                 break;
    2015             }
    2016             CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureRate)(uVal));
    2017         }
    2018         else if (   !strcmp(a->argv[1], "videocapfps")
    2019                  || !strcmp(a->argv[1], "vcpfps"))
    2020         {
    2021             if (a->argc != 3)
    2022             {
    2023                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    2024                 rc = E_FAIL;
    2025                 break;
    2026             }
    2027 
    2028             uint32_t uVal;
    2029             int vrc = RTStrToUInt32Ex(a->argv[2], NULL, 0, &uVal);
    2030             if (RT_FAILURE(vrc))
    2031             {
    2032                 errorArgument("Error parsing FPS '%s'", a->argv[2]);
    2033                 rc = E_FAIL;
    2034                 break;
    2035             }
    2036             CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureFPS)(uVal));
    2037         }
    2038         else if (   !strcmp(a->argv[1], "videocapmaxtime")
    2039                  || !strcmp(a->argv[1], "vcpmaxtime"))
    2040         {
    2041             if (a->argc != 3)
    2042             {
    2043                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    2044                 rc = E_FAIL;
    2045                 break;
    2046             }
    2047 
    2048             uint32_t uVal;
    2049             int vrc = RTStrToUInt32Ex(a->argv[2], NULL, 0, &uVal);
    2050             if (RT_FAILURE(vrc))
    2051             {
    2052                 errorArgument("Error parsing maximum time '%s'", a->argv[2]);
    2053                 rc = E_FAIL;
    2054                 break;
    2055             }
    2056             CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureMaxTime)(uVal));
    2057         }
    2058         else if (   !strcmp(a->argv[1], "videocapmaxsize")
    2059                  || !strcmp(a->argv[1], "vcpmaxsize"))
    2060         {
    2061             if (a->argc != 3)
    2062             {
    2063                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    2064                 rc = E_FAIL;
    2065                 break;
    2066             }
    2067 
    2068             uint32_t uVal;
    2069             int vrc = RTStrToUInt32Ex(a->argv[2], NULL, 0, &uVal);
    2070             if (RT_FAILURE(vrc))
    2071             {
    2072                 errorArgument("Error parsing maximum file size '%s'", a->argv[2]);
    2073                 rc = E_FAIL;
    2074                 break;
    2075             }
    2076             CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureMaxFileSize)(uVal));
    2077         }
    2078         else if (   !strcmp(a->argv[1], "videocapopts")
    2079                  || !strcmp(a->argv[1], "vcpoptions"))
    2080         {
    2081             if (a->argc != 3)
    2082             {
    2083                 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
    2084                 rc = E_FAIL;
    2085                 break;
    2086             }
    2087 
    2088             CHECK_ERROR_BREAK(sessionMachine, COMSETTER(VideoCaptureOptions)(Bstr(a->argv[3]).raw()));
     1865
     1866            ComPtr<ICaptureSettings> captureSettings;
     1867            CHECK_ERROR_BREAK(machine, COMGETTER(CaptureSettings)(captureSettings.asOutParam()));
     1868
     1869            SafeIfaceArray <ICaptureScreenSettings> saCaptureScreenScreens;
     1870            CHECK_ERROR_BREAK(captureSettings, COMGETTER(Screens)(ComSafeArrayAsOutParam(saCaptureScreenScreens)));
     1871
     1872            /* Note: For now all screens have the same configuration. */
     1873
     1874            /*
     1875             * Note: Commands starting with "vcp" are the deprecated versions and are
     1876             *       kept to ensure backwards compatibility.
     1877             */
     1878            if (!strcmp(a->argv[2], "enable"))
     1879            {
     1880                CHECK_ERROR_RET(captureSettings, COMSETTER(Enabled)(TRUE), RTEXITCODE_FAILURE);
     1881            }
     1882            else if (!strcmp(a->argv[2], "disable"))
     1883            {
     1884                CHECK_ERROR_RET(captureSettings, COMSETTER(Enabled)(FALSE), RTEXITCODE_FAILURE);
     1885            }
     1886            else if (!strcmp(a->argv[2], "screens"))
     1887            {
     1888                ULONG cMonitors = 64;
     1889                CHECK_ERROR_BREAK(machine, COMGETTER(MonitorCount)(&cMonitors));
     1890                com::SafeArray<BOOL> saScreens(cMonitors);
     1891                if (   a->argc == 4
     1892                    && !strcmp(a->argv[3], "all"))
     1893                {
     1894                    /* enable all screens */
     1895                    for (unsigned i = 0; i < cMonitors; i++)
     1896                        saScreens[i] = true;
     1897                }
     1898                else if (   a->argc == 4
     1899                         && !strcmp(a->argv[3], "none"))
     1900                {
     1901                    /* disable all screens */
     1902                    for (unsigned i = 0; i < cMonitors; i++)
     1903                        saScreens[i] = false;
     1904
     1905                    /** @todo r=andy What if this is specified? */
     1906                }
     1907                else
     1908                {
     1909                    /* enable selected screens */
     1910                    for (unsigned i = 0; i < cMonitors; i++)
     1911                        saScreens[i] = false;
     1912                    for (int i = 3; SUCCEEDED(rc) && i < a->argc; i++)
     1913                    {
     1914                        uint32_t iScreen;
     1915                        int vrc = RTStrToUInt32Ex(a->argv[i], NULL, 0, &iScreen);
     1916                        if (vrc != VINF_SUCCESS)
     1917                        {
     1918                            errorArgument("Error parsing display number '%s'", a->argv[i]);
     1919                            rc = E_FAIL;
     1920                            break;
     1921                        }
     1922                        if (iScreen >= cMonitors)
     1923                        {
     1924                            errorArgument("Invalid screen ID specified '%u'", iScreen);
     1925                            rc = E_FAIL;
     1926                            break;
     1927                        }
     1928                        saScreens[iScreen] = true;
     1929                    }
     1930                }
     1931
     1932                for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     1933                    CHECK_ERROR_BREAK(saCaptureScreenScreens[i], COMSETTER(Enabled)(saScreens[i]));
     1934            }
     1935            else if (!strcmp(a->argv[2], "filename"))
     1936            {
     1937                if (a->argc != 3)
     1938                {
     1939                    errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
     1940                    rc = E_FAIL;
     1941                    break;
     1942                }
     1943
     1944                for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     1945                    CHECK_ERROR_BREAK(saCaptureScreenScreens[i], COMSETTER(FileName)(Bstr(a->argv[2]).raw()));
     1946            }
     1947            else if (   !strcmp(a->argv[2], "res")
     1948                     || !strcmp(a->argv[2], "resolution"))
     1949            {
     1950                if (a->argc != 5)
     1951                {
     1952                    errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
     1953                    rc = E_FAIL;
     1954                    break;
     1955                }
     1956
     1957                uint32_t uVal;
     1958                int vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &uVal);
     1959                if (RT_FAILURE(vrc))
     1960                {
     1961                    errorArgument("Error parsing width '%s'", a->argv[3]);
     1962                    rc = E_FAIL;
     1963                    break;
     1964                }
     1965
     1966                vrc = RTStrToUInt32Ex(a->argv[4], NULL, 0, &uVal);
     1967                if (RT_FAILURE(vrc))
     1968                {
     1969                    errorArgument("Error parsing height '%s'", a->argv[4]);
     1970                    rc = E_FAIL;
     1971                    break;
     1972                }
     1973
     1974                for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     1975                {
     1976                    CHECK_ERROR_BREAK(saCaptureScreenScreens[i], COMSETTER(VideoWidth)(uVal));
     1977                    CHECK_ERROR_BREAK(saCaptureScreenScreens[i], COMSETTER(VideoHeight)(uVal));
     1978                }
     1979            }
     1980            else if (!strcmp(a->argv[2], "videorate"))
     1981            {
     1982                if (a->argc != 4)
     1983                {
     1984                    errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
     1985                    rc = E_FAIL;
     1986                    break;
     1987                }
     1988
     1989                uint32_t uVal;
     1990                int vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &uVal);
     1991                if (RT_FAILURE(vrc))
     1992                {
     1993                    errorArgument("Error parsing rate '%s'", a->argv[3]);
     1994                    rc = E_FAIL;
     1995                    break;
     1996                }
     1997
     1998                for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     1999                    CHECK_ERROR_BREAK(saCaptureScreenScreens[i], COMSETTER(VideoRate)(uVal));
     2000            }
     2001            else if (!strcmp(a->argv[2], "videofps"))
     2002            {
     2003                if (a->argc != 4)
     2004                {
     2005                    errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
     2006                    rc = E_FAIL;
     2007                    break;
     2008                }
     2009
     2010                uint32_t uVal;
     2011                int vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &uVal);
     2012                if (RT_FAILURE(vrc))
     2013                {
     2014                    errorArgument("Error parsing FPS '%s'", a->argv[3]);
     2015                    rc = E_FAIL;
     2016                    break;
     2017                }
     2018
     2019                for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     2020                    CHECK_ERROR_BREAK(saCaptureScreenScreens[i], COMSETTER(VideoFPS)(uVal));
     2021            }
     2022            else if (!strcmp(a->argv[2], "maxtime"))
     2023            {
     2024                if (a->argc != 4)
     2025                {
     2026                    errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
     2027                    rc = E_FAIL;
     2028                    break;
     2029                }
     2030
     2031                uint32_t uVal;
     2032                int vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &uVal);
     2033                if (RT_FAILURE(vrc))
     2034                {
     2035                    errorArgument("Error parsing maximum time '%s'", a->argv[3]);
     2036                    rc = E_FAIL;
     2037                    break;
     2038                }
     2039
     2040                for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     2041                    CHECK_ERROR_BREAK(saCaptureScreenScreens[i], COMSETTER(MaxTime)(uVal));
     2042            }
     2043            else if (!strcmp(a->argv[2], "maxfilesize"))
     2044            {
     2045                if (a->argc != 4)
     2046                {
     2047                    errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
     2048                    rc = E_FAIL;
     2049                    break;
     2050                }
     2051
     2052                uint32_t uVal;
     2053                int vrc = RTStrToUInt32Ex(a->argv[3], NULL, 0, &uVal);
     2054                if (RT_FAILURE(vrc))
     2055                {
     2056                    errorArgument("Error parsing maximum file size '%s'", a->argv[3]);
     2057                    rc = E_FAIL;
     2058                    break;
     2059                }
     2060
     2061                for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     2062                    CHECK_ERROR_BREAK(saCaptureScreenScreens[i], COMSETTER(MaxFileSize)(uVal));
     2063            }
     2064            else if (!strcmp(a->argv[2], "opts"))
     2065            {
     2066                if (a->argc != 4)
     2067                {
     2068                    errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
     2069                    rc = E_FAIL;
     2070                    break;
     2071                }
     2072
     2073                for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     2074                    CHECK_ERROR_BREAK(saCaptureScreenScreens[i], COMSETTER(Options)(Bstr(a->argv[3]).raw()));
     2075            }
    20892076        }
    20902077#endif /* VBOX_WITH_VIDEOREC */
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp

    r74474 r75251  
    713713#endif
    714714#ifdef VBOX_WITH_VIDEOREC
    715                      "                            [--videocap on|off]\n"
    716                      "                            [--videocapscreens all|<screen ID> [<screen ID> ...]]\n"
    717                      "                            [--videocapfile <filename>]\n"
    718                      "                            [--videocapres <width> <height>]\n"
    719                      "                            [--videocaprate <rate>]\n"
    720                      "                            [--videocapfps <fps>]\n"
    721                      "                            [--videocapmaxtime <ms>]\n"
    722                      "                            [--videocapmaxsize <MB>]\n"
    723                      "                            [--videocapopts <key=value> [,<key=value> ...]]\n"
     715                     "                            [--capture on|off]\n"
     716                     "                            [--capture screens all|<screen ID> [<screen ID> ...]]\n"
     717                     "                            [--capture filename <filename>]\n"
     718                     "                            [--capture resolution <width> <height>]\n"
     719                     "                            [--capture videorate <rate>]\n"
     720                     "                            [--capture videofps <fps>]\n"
     721                     "                            [--capture maxtime <ms>]\n"
     722                     "                            [--capture maxfilesize <MB>]\n"
     723                     "                            [--capture opts <key=value> [,<key=value> ...]]\n"
    724724#endif
    725725                     "                            [--defaultfrontend default|<name>]\n"
     
    831831                     "                            setscreenlayout <display> on|primary <xorigin> <yorigin> <xres> <yres> <bpp> | off\n"
    832832                     "                            screenshotpng <file> [display] |\n"
    833                      "                            videocap on|off |\n"
    834                      "                            videocapscreens all|none|<screen>,[<screen>...] |\n"
    835                      "                            videocapfile <file>\n"
    836                      "                            videocapres <width>x<height>\n"
    837                      "                            videocaprate <rate>\n"
    838                      "                            videocapfps <fps>\n"
    839                      "                            videocapmaxtime <ms>\n"
    840                      "                            videocapmaxsize <MB>\n"
     833#ifdef VBOX_WITH_VIDEOREC
     834                     "                            capture on|off |\n"
     835                     "                            capture screens all|none|<screen>,[<screen>...] |\n"
     836                     "                            capture filename <file> |\n"
     837                     "                            capture resolution <width>x<height> |\n"
     838                     "                            capture videorate <rate> |\n"
     839                     "                            capture videofps <fps> |\n"
     840                     "                            capture maxtime <s> |\n"
     841                     "                            capture maxfilesize <MB> |\n"
     842#endif /* VBOX_WITH_VIDEOREC */
    841843                     "                            setcredentials <username>\n"
    842844                     "                                           --passwordfile <file> | <password>\n"
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp

    r73768 r75251  
    23792379# endif
    23802380
    2381         CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureEnabled)(&fCaptureVideo), rc);
    2382         com::SafeArray<BOOL> screens;
    2383         CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureScreens)(ComSafeArrayAsOutParam(screens)), rc);
     2381        ComPtr<ICaptureSettings> captureSettings;
     2382        CHECK_ERROR_RET(machine, COMGETTER(CaptureSettings)(captureSettings.asOutParam()), rc);
     2383
     2384        SafeIfaceArray <ICaptureScreenSettings> saCaptureScreenScreens;
     2385        CHECK_ERROR_RET(captureSettings, COMGETTER(Screens)(ComSafeArrayAsOutParam(saCaptureScreenScreens)), rc);
     2386
     2387        /* For now all screens have the same configuration; so take screen 0 and work with that. */
     2388        ULONG fFeatures;
     2389        CHECK_ERROR_RET(saCaptureScreenScreens[0], COMGETTER(Features)(&fFeatures), rc);
    23842390        ULONG Width;
    2385         CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureWidth)(&Width), rc);
     2391        CHECK_ERROR_RET(saCaptureScreenScreens[0], COMGETTER(VideoWidth)(&Width), rc);
    23862392        ULONG Height;
    2387         CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureHeight)(&Height), rc);
     2393        CHECK_ERROR_RET(saCaptureScreenScreens[0], COMGETTER(VideoHeight)(&Height), rc);
    23882394        ULONG Rate;
    2389         CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureRate)(&Rate), rc);
     2395        CHECK_ERROR_RET(saCaptureScreenScreens[0], COMGETTER(VideoRate)(&Rate), rc);
    23902396        ULONG Fps;
    2391         CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFPS)(&Fps), rc);
     2397        CHECK_ERROR_RET(saCaptureScreenScreens[0], COMGETTER(VideoFPS)(&Fps), rc);
    23922398        Bstr  bstrFile;
    2393         CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureFile)(bstrFile.asOutParam()), rc);
     2399        CHECK_ERROR_RET(saCaptureScreenScreens[0], COMGETTER(FileName)(bstrFile.asOutParam()), rc);
    23942400        Bstr  bstrOptions;
    2395         CHECK_ERROR_RET(machine, COMGETTER(VideoCaptureOptions)(bstrOptions.asOutParam()), rc);
     2401        CHECK_ERROR_RET(saCaptureScreenScreens[0], COMGETTER(Options)(bstrOptions.asOutParam()), rc);
    23962402
    23972403        Utf8Str strOptions(bstrOptions);
     
    24172423# endif
    24182424        szValue[0] = '\0';
    2419         for (size_t i = 0, off = 0; i < screens.size(); i++)
    2420             if (screens[i] && off < sizeof(szValue) - 3)
     2425        for (size_t i = 0, off = 0; i < saCaptureScreenScreens.size(); i++)
     2426        {
     2427            BOOL fEnabled;
     2428            CHECK_ERROR_RET(saCaptureScreenScreens[i], COMGETTER(Enabled)(&fEnabled), rc);
     2429            if (fEnabled && off < sizeof(szValue) - 3)
    24212430                off += RTStrPrintf(&szValue[off], sizeof(szValue) - off, off ? ",%zu" : "%zu", i);
    2422         SHOW_UTF8_STRING("videocapscreens", "Capture screens:", szValue);
    2423         SHOW_BSTR_STRING("videocapfile", "Capture file:", bstrFile);
     2431        }
     2432        SHOW_UTF8_STRING("capturescreens", "Capture screens:", szValue);
     2433        SHOW_BSTR_STRING("capturefilename", "Capture file:", bstrFile);
    24242434        RTStrPrintf(szValue, sizeof(szValue), "%ux%u", Width, Height);
    2425         SHOW_UTF8_STRING("videocapres", "Capture dimensions:", szValue);
    2426         SHOW_ULONG_VALUE("videocaprate", "Capture rate:", Rate, "kbps");
    2427         SHOW_ULONG_VALUE("videocapfps", "Capture FPS:", Fps, "kbps");
    2428         SHOW_BSTR_STRING("videocapopts", "Capture options:", bstrOptions);
     2435        SHOW_UTF8_STRING("captureres", "Capture dimensions:", szValue);
     2436        SHOW_ULONG_VALUE("capturevideorate", "Capture rate:", Rate, "kbps");
     2437        SHOW_ULONG_VALUE("capturevideofps", "Capture FPS:", Fps, "kbps");
     2438        SHOW_BSTR_STRING("captureopts", "Capture options:", bstrOptions);
    24292439
    24302440        if (details != VMINFO_MACHINEREADABLE)
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp

    r75138 r75251  
    29292929#ifdef VBOX_WITH_VIDEOREC
    29302930            case MODIFYVM_CAPTURE:
    2931             {
    2932                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureEnabled)(ValueUnion.f));
    2933                 break;
    2934             }
     2931                RT_FALL_THROUGH();
    29352932            case MODIFYVM_CAPTURE_SCREENS:
    2936             {
    2937                 ULONG cMonitors = 64;
    2938                 CHECK_ERROR(sessionMachine, COMGETTER(MonitorCount)(&cMonitors));
    2939                 com::SafeArray<BOOL> screens(cMonitors);
    2940                 if (parseScreens(ValueUnion.psz, &screens))
    2941                 {
    2942                     errorArgument("Invalid list of screens specified\n");
    2943                     rc = E_FAIL;
    2944                     break;
    2945                 }
    2946                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureScreens)(ComSafeArrayAsInParam(screens)));
    2947                 break;
    2948             }
     2933                RT_FALL_THROUGH();
    29492934            case MODIFYVM_CAPTURE_FILENAME:
    2950             {
    2951                 Bstr bstr;
    2952                 /* empty string will fall through, leaving bstr empty */
    2953                 if (*ValueUnion.psz)
    2954                 {
    2955                     char szVCFileAbs[RTPATH_MAX] = "";
    2956                     int vrc = RTPathAbs(ValueUnion.psz, szVCFileAbs, sizeof(szVCFileAbs));
    2957                     if (RT_FAILURE(vrc))
    2958                     {
    2959                         errorArgument("Cannot convert filename \"%s\" to absolute path\n", ValueUnion.psz);
    2960                         rc = E_FAIL;
     2935                RT_FALL_THROUGH();
     2936            case MODIFYVM_CAPTURE_WIDTH:
     2937                RT_FALL_THROUGH();
     2938            case MODIFYVM_CAPTURE_HEIGHT:
     2939                RT_FALL_THROUGH();
     2940            case MODIFYVM_CAPTURE_VIDEO_RES:
     2941                RT_FALL_THROUGH();
     2942            case MODIFYVM_CAPTURE_VIDEO_RATE:
     2943                RT_FALL_THROUGH();
     2944            case MODIFYVM_CAPTURE_VIDEO_FPS:
     2945                RT_FALL_THROUGH();
     2946            case MODIFYVM_CAPTURE_MAXTIME:
     2947                RT_FALL_THROUGH();
     2948            case MODIFYVM_CAPTURE_MAXSIZE:
     2949                RT_FALL_THROUGH();
     2950            case MODIFYVM_CAPTURE_OPTIONS:
     2951            {
     2952                ComPtr<ICaptureSettings> captureSettings;
     2953                CHECK_ERROR_BREAK(machine, COMGETTER(CaptureSettings)(captureSettings.asOutParam()));
     2954                SafeIfaceArray <ICaptureScreenSettings> saCaptureScreenScreens;
     2955                CHECK_ERROR_BREAK(captureSettings, COMGETTER(Screens)(ComSafeArrayAsOutParam(saCaptureScreenScreens)));
     2956
     2957                switch (c)
     2958                {
     2959                    case MODIFYVM_CAPTURE:
     2960                    {
     2961                        CHECK_ERROR(captureSettings, COMSETTER(Enabled)(ValueUnion.f));
    29612962                        break;
    29622963                    }
    2963                     bstr = szVCFileAbs;
    2964                 }
    2965                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureFile)(bstr.raw()));
    2966                 break;
    2967             }
    2968             case MODIFYVM_CAPTURE_WIDTH:
    2969             {
    2970                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureWidth)(ValueUnion.u32));
    2971                 break;
    2972             }
    2973             case MODIFYVM_CAPTURE_HEIGHT:
    2974             {
    2975                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureHeight)(ValueUnion.u32));
    2976                 break;
    2977             }
    2978             case MODIFYVM_CAPTURE_VIDEO_RES:
    2979             {
    2980                 uint32_t uWidth = 0;
    2981                 char *pszNext;
    2982                 int vrc = RTStrToUInt32Ex(ValueUnion.psz, &pszNext, 0, &uWidth);
    2983                 if (RT_FAILURE(vrc) || vrc != VWRN_TRAILING_CHARS || !pszNext || *pszNext != 'x')
    2984                 {
    2985                     errorArgument("Error parsing geomtry '%s' (expected <width>x<height>)", ValueUnion.psz);
    2986                     rc = E_FAIL;
    2987                     break;
    2988                 }
    2989                 uint32_t uHeight = 0;
    2990                 vrc = RTStrToUInt32Ex(pszNext+1, NULL, 0, &uHeight);
    2991                 if (vrc != VINF_SUCCESS)
    2992                 {
    2993                     errorArgument("Error parsing geomtry '%s' (expected <width>x<height>)", ValueUnion.psz);
    2994                     rc = E_FAIL;
    2995                     break;
    2996                 }
    2997                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureWidth)(uWidth));
    2998                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureHeight)(uHeight));
    2999                 break;
    3000             }
    3001             case MODIFYVM_CAPTURE_VIDEO_RATE:
    3002             {
    3003                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureRate)(ValueUnion.u32));
    3004                 break;
    3005             }
    3006             case MODIFYVM_CAPTURE_VIDEO_FPS:
    3007             {
    3008                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureFPS)(ValueUnion.u32));
    3009                 break;
    3010             }
    3011             case MODIFYVM_CAPTURE_MAXTIME:
    3012             {
    3013                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureMaxTime)(ValueUnion.u32));
    3014                 break;
    3015             }
    3016             case MODIFYVM_CAPTURE_MAXSIZE:
    3017             {
    3018                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureMaxFileSize)(ValueUnion.u32));
    3019                 break;
    3020             }
    3021             case MODIFYVM_CAPTURE_OPTIONS:
    3022             {
    3023                 Bstr bstr(ValueUnion.psz);
    3024                 CHECK_ERROR(sessionMachine, COMSETTER(VideoCaptureOptions)(bstr.raw()));
     2964                    case MODIFYVM_CAPTURE_SCREENS:
     2965                    {
     2966                        ULONG cMonitors = 64;
     2967                        CHECK_ERROR(sessionMachine, COMGETTER(MonitorCount)(&cMonitors));
     2968                        com::SafeArray<BOOL> screens(cMonitors);
     2969                        if (parseScreens(ValueUnion.psz, &screens))
     2970                        {
     2971                            errorArgument("Invalid list of screens specified\n");
     2972                            rc = E_FAIL;
     2973                            break;
     2974                        }
     2975
     2976                        if (cMonitors > saCaptureScreenScreens.size()) /* Paranoia. */
     2977                            cMonitors = saCaptureScreenScreens.size();
     2978
     2979                        for (size_t i = 0; i < cMonitors; ++i)
     2980                            CHECK_ERROR_BREAK(saCaptureScreenScreens[i], COMSETTER(Enabled)(screens[i]));
     2981                        break;
     2982                    }
     2983                    case MODIFYVM_CAPTURE_FILENAME:
     2984                    {
     2985                        Bstr bstr;
     2986                        /* empty string will fall through, leaving bstr empty */
     2987                        if (*ValueUnion.psz)
     2988                        {
     2989                            char szVCFileAbs[RTPATH_MAX] = "";
     2990                            int vrc = RTPathAbs(ValueUnion.psz, szVCFileAbs, sizeof(szVCFileAbs));
     2991                            if (RT_FAILURE(vrc))
     2992                            {
     2993                                errorArgument("Cannot convert filename \"%s\" to absolute path\n", ValueUnion.psz);
     2994                                rc = E_FAIL;
     2995                                break;
     2996                            }
     2997                            bstr = szVCFileAbs;
     2998                        }
     2999
     3000                        for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     3001                            CHECK_ERROR(saCaptureScreenScreens[i], COMSETTER(FileName)(bstr.raw()));
     3002                        break;
     3003                    }
     3004                    case MODIFYVM_CAPTURE_WIDTH:
     3005                    {
     3006                        for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     3007                            CHECK_ERROR(saCaptureScreenScreens[i], COMSETTER(VideoWidth)(ValueUnion.u32));
     3008                        break;
     3009                    }
     3010                    case MODIFYVM_CAPTURE_HEIGHT:
     3011                    {
     3012                        for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     3013                            CHECK_ERROR(saCaptureScreenScreens[i], COMSETTER(VideoHeight)(ValueUnion.u32));
     3014                        break;
     3015                    }
     3016                    case MODIFYVM_CAPTURE_VIDEO_RES:
     3017                    {
     3018                        uint32_t uWidth = 0;
     3019                        char *pszNext;
     3020                        int vrc = RTStrToUInt32Ex(ValueUnion.psz, &pszNext, 0, &uWidth);
     3021                        if (RT_FAILURE(vrc) || vrc != VWRN_TRAILING_CHARS || !pszNext || *pszNext != 'x')
     3022                        {
     3023                            errorArgument("Error parsing geomtry '%s' (expected <width>x<height>)", ValueUnion.psz);
     3024                            rc = E_FAIL;
     3025                            break;
     3026                        }
     3027                        uint32_t uHeight = 0;
     3028                        vrc = RTStrToUInt32Ex(pszNext+1, NULL, 0, &uHeight);
     3029                        if (vrc != VINF_SUCCESS)
     3030                        {
     3031                            errorArgument("Error parsing geomtry '%s' (expected <width>x<height>)", ValueUnion.psz);
     3032                            rc = E_FAIL;
     3033                            break;
     3034                        }
     3035
     3036                        for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     3037                        {
     3038                            CHECK_ERROR(saCaptureScreenScreens[i], COMSETTER(VideoWidth)(uWidth));
     3039                            CHECK_ERROR(saCaptureScreenScreens[i], COMSETTER(VideoHeight)(uHeight));
     3040                        }
     3041                        break;
     3042                    }
     3043                    case MODIFYVM_CAPTURE_VIDEO_RATE:
     3044                    {
     3045                        for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     3046                            CHECK_ERROR(saCaptureScreenScreens[i], COMSETTER(VideoRate)(ValueUnion.u32));
     3047                        break;
     3048                    }
     3049                    case MODIFYVM_CAPTURE_VIDEO_FPS:
     3050                    {
     3051                        for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     3052                            CHECK_ERROR(saCaptureScreenScreens[i], COMSETTER(VideoFPS)(ValueUnion.u32));
     3053                        break;
     3054                    }
     3055                    case MODIFYVM_CAPTURE_MAXTIME:
     3056                    {
     3057                        for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     3058                            CHECK_ERROR(saCaptureScreenScreens[i], COMSETTER(MaxTime)(ValueUnion.u32));
     3059                        break;
     3060                    }
     3061                    case MODIFYVM_CAPTURE_MAXSIZE:
     3062                    {
     3063                        for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     3064                            CHECK_ERROR(saCaptureScreenScreens[i], COMSETTER(MaxFileSize)(ValueUnion.u32));
     3065                        break;
     3066                    }
     3067                    case MODIFYVM_CAPTURE_OPTIONS:
     3068                    {
     3069                        Bstr bstr(ValueUnion.psz);
     3070                        for (size_t i = 0; i < saCaptureScreenScreens.size(); ++i)
     3071                            CHECK_ERROR(saCaptureScreenScreens[i], COMSETTER(Options)(bstr.raw()));
     3072                        break;
     3073                    }
     3074                }
     3075
    30253076                break;
    30263077            }
  • trunk/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendGlobal.cpp

    r75087 r75251  
    14031403        case IndicatorType_SharedFolders: strResult = "SharedFolders"; break;
    14041404        case IndicatorType_Display:       strResult = "Display"; break;
    1405         case IndicatorType_VideoCapture:  strResult = "VideoCapture"; break;
     1405        case IndicatorType_Capture:       strResult = "VideoCapture"; break;
    14061406        case IndicatorType_Features:      strResult = "Features"; break;
    14071407        case IndicatorType_Mouse:         strResult = "Mouse"; break;
     
    14301430    keys << "SharedFolders"; values << IndicatorType_SharedFolders;
    14311431    keys << "Display";       values << IndicatorType_Display;
    1432     keys << "VideoCapture";  values << IndicatorType_VideoCapture;
     1432    keys << "VideoCapture";  values << IndicatorType_Capture;
    14331433    keys << "Features";      values << IndicatorType_Features;
    14341434    keys << "Mouse";         values << IndicatorType_Mouse;
     
    14551455        case IndicatorType_SharedFolders: strResult = QApplication::translate("VBoxGlobal", "Shared Folders", "IndicatorType"); break;
    14561456        case IndicatorType_Display:       strResult = QApplication::translate("VBoxGlobal", "Display", "IndicatorType"); break;
    1457         case IndicatorType_VideoCapture:  strResult = QApplication::translate("VBoxGlobal", "Video Capture", "IndicatorType"); break;
     1457        case IndicatorType_Capture:  strResult = QApplication::translate("VBoxGlobal", "Video Capture", "IndicatorType"); break;
    14581458        case IndicatorType_Features:      strResult = QApplication::translate("VBoxGlobal", "Features", "IndicatorType"); break;
    14591459        case IndicatorType_Mouse:         strResult = QApplication::translate("VBoxGlobal", "Mouse", "IndicatorType"); break;
     
    14811481        case IndicatorType_SharedFolders: return UIIconPool::iconSet(":/sf_16px.png");
    14821482        case IndicatorType_Display:       return UIIconPool::iconSet(":/display_software_16px.png");
    1483         case IndicatorType_VideoCapture:  return UIIconPool::iconSet(":/video_capture_16px.png");
     1483        case IndicatorType_Capture:  return UIIconPool::iconSet(":/video_capture_16px.png");
    14841484        case IndicatorType_Features:      return UIIconPool::iconSet(":/vtx_amdv_16px.png");
    14851485        case IndicatorType_Mouse:         return UIIconPool::iconSet(":/mouse_16px.png");
  • trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.h

    r75224 r75251  
    765765    IndicatorType_SharedFolders,
    766766    IndicatorType_Display,
    767     IndicatorType_VideoCapture,
     767    IndicatorType_Capture,
    768768    IndicatorType_Features,
    769769    IndicatorType_Mouse,
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIActionPoolRuntime.cpp

    r75209 r75251  
    33073307    m_pool[UIActionIndexRT_M_View_S_TakeScreenshot] = new UIActionSimpleRuntimePerformTakeScreenshot(this);
    33083308    m_pool[UIActionIndexRT_M_View_M_VideoCapture] = new UIActionMenuRuntimeVideoCapture(this);
    3309     m_pool[UIActionIndexRT_M_View_M_VideoCapture_S_Settings] = new UIActionSimpleRuntimeShowVideoCaptureSettings(this);
    3310     m_pool[UIActionIndexRT_M_View_M_VideoCapture_T_Start] = new UIActionToggleRuntimeVideoCapture(this);
     3309    m_pool[UIActionIndexRT_M_View_M_Capture_S_Settings] = new UIActionSimpleRuntimeShowVideoCaptureSettings(this);
     3310    m_pool[UIActionIndexRT_M_View_M_Capture_T_Start] = new UIActionToggleRuntimeVideoCapture(this);
    33113311    m_pool[UIActionIndexRT_M_View_T_VRDEServer] = new UIActionToggleRuntimeVRDEServer(this);
    33123312    m_pool[UIActionIndexRT_M_View_M_MenuBar] = new UIActionMenuRuntimeMenuBar(this);
     
    36623662    updateMenuViewVideoCapture();
    36633663    /* 'Video Capture Start' action: */
    3664     fSeparator = addAction(pMenu, action(UIActionIndexRT_M_View_M_VideoCapture_T_Start)) || fSeparator;
     3664    fSeparator = addAction(pMenu, action(UIActionIndexRT_M_View_M_Capture_T_Start)) || fSeparator;
    36653665    /* 'VRDE Server' action: */
    36663666    fSeparator = addAction(pMenu, action(UIActionIndexRT_M_View_T_VRDEServer)) || fSeparator;
     
    37773777
    37783778    /* 'Video Capture Settings' action: */
    3779     fSeparator = addAction(pMenu, action(UIActionIndexRT_M_View_M_VideoCapture_S_Settings)) || fSeparator;
     3779    fSeparator = addAction(pMenu, action(UIActionIndexRT_M_View_M_Capture_S_Settings)) || fSeparator;
    37803780
    37813781    /* Separator: */
     
    37873787
    37883788    /* 'Start Video Capture' action: */
    3789     fSeparator = addAction(pMenu, action(UIActionIndexRT_M_View_M_VideoCapture_T_Start)) || fSeparator;
     3789    fSeparator = addAction(pMenu, action(UIActionIndexRT_M_View_M_Capture_T_Start)) || fSeparator;
    37903790
    37913791    /* Mark menu as valid: */
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIActionPoolRuntime.h

    r75207 r75251  
    6565    UIActionIndexRT_M_View_S_TakeScreenshot,
    6666    UIActionIndexRT_M_View_M_VideoCapture,
    67     UIActionIndexRT_M_View_M_VideoCapture_S_Settings,
    68     UIActionIndexRT_M_View_M_VideoCapture_T_Start,
     67    UIActionIndexRT_M_View_M_Capture_S_Settings,
     68    UIActionIndexRT_M_View_M_Capture_T_Start,
    6969    UIActionIndexRT_M_View_T_VRDEServer,
    7070    UIActionIndexRT_M_View_M_MenuBar,
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.cpp

    r73469 r75251  
    375375            break;
    376376        }
    377         case KVBoxEventType_OnVideoCaptureChanged:
    378         {
    379             emit sigVideoCaptureChange();
     377        case KVBoxEventType_OnCaptureChanged:
     378        {
     379            emit sigCaptureChange();
    380380            break;
    381381        }
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMainEventListener.h

    r74942 r75251  
    124124        /** Notifies about VRDE device state change. */
    125125        void sigVRDEChange();
    126         /** Notifies about Video Capture device state change. */
    127         void sigVideoCaptureChange();
     126        /** Notifies about capture state change. */
     127        void sigCaptureChange();
    128128        /** Notifies about USB controller state change. */
    129129        void sigUSBControllerChange();
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIPopupCenter.cpp

    r73953 r75251  
    570570}
    571571
    572 void UIPopupCenter::cannotToggleVideoCapture(QWidget *pParent, const CMachine &comMachine, bool fEnable)
     572void UIPopupCenter::cannotToggleCapture(QWidget *pParent, const CMachine &comMachine, bool fEnable)
    573573{
    574574    /* Get machine-name preserving error-info: */
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIPopupCenter.h

    r73953 r75251  
    162162    void cannotDetachWebCam(QWidget *pParent, const CEmulatedUSB &comDispatcher,
    163163                            const QString &strWebCamName, const QString &strMachineName);
    164     void cannotToggleVideoCapture(QWidget *pParent, const CMachine &comMachine, bool fEnable);
     164    void cannotToggleCapture(QWidget *pParent, const CMachine &comMachine, bool fEnable);
    165165    void cannotToggleVRDEServer(QWidget *pParent,  const CVRDEServer &comServer,
    166166                                const QString &strMachineName, bool fEnable);
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/details/UIDetailsElements.cpp

    r74049 r75251  
    55
    66/*
    7  * Copyright (C) 2012-2017 Oracle Corporation
     7 * Copyright (C) 2012-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4444# include "CMediumAttachment.h"
    4545# include "CAudioAdapter.h"
     46# include "CCaptureSettings.h"
     47# include "CCaptureScreenSettings.h"
    4648# include "CNetworkAdapter.h"
    4749# include "CSerialPort.h"
     
    447449        }
    448450
    449         /* Video Capture info: */
    450         if (machine.GetVideoCaptureEnabled())
    451         {
     451        /* Capture info: */
     452        CCaptureSettings captureSettings = machine.GetCaptureSettings();
     453        if (captureSettings.GetEnabled())
     454        {
     455            /* For now all screens have the same config: */
     456            CCaptureScreenSettings captureScreen0Settings = captureSettings.GetScreenSettings(0);
     457
     458            /** @todo r=andy Refine these texts (wrt audio and/or video). */
    452459            table << UITextTableLine(QApplication::translate("UIDetails", "Video Capture File", "details (display/video capture)"),
    453                                      machine.GetVideoCaptureFile());
     460                                     captureScreen0Settings.GetFileName());
    454461            table << UITextTableLine(QApplication::translate("UIDetails", "Video Capture Attributes", "details (display/video capture)"),
    455462                                     QApplication::translate("UIDetails", "Frame Size: %1x%2, Frame Rate: %3fps, Bit Rate: %4kbps")
    456                                          .arg(machine.GetVideoCaptureWidth()).arg(machine.GetVideoCaptureHeight())
    457                                          .arg(machine.GetVideoCaptureFPS()).arg(machine.GetVideoCaptureRate()));
     463                                         .arg(captureScreen0Settings.GetVideoWidth()).arg(captureScreen0Settings.GetVideoHeight())
     464                                         .arg(captureScreen0Settings.GetVideoFPS()).arg(captureScreen0Settings.GetVideoRate()));
    458465        }
    459466        else
    460467        {
     468            /** @todo r=andy Refine these texts (wrt audio and/or video). */
    461469            table << UITextTableLine(QApplication::translate("UIDetails", "Video Capture", "details (display/video capture)"),
    462470                                     QApplication::translate("UIDetails", "Disabled", "details (display/video capture)"));
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIConsoleEventHandler.cpp

    r70075 r75251  
    188188        << KVBoxEventType_OnVRDEServerChanged
    189189        << KVBoxEventType_OnVRDEServerInfoChanged
    190         << KVBoxEventType_OnVideoCaptureChanged
     190        << KVBoxEventType_OnCaptureChanged
    191191        << KVBoxEventType_OnUSBControllerChanged
    192192        << KVBoxEventType_OnUSBDeviceStateChanged
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.cpp

    r74942 r75251  
    55
    66/*
    7  * Copyright (C) 2010-2017 Oracle Corporation
     7 * Copyright (C) 2010-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4343/* COM includes: */
    4444# include "CAudioAdapter.h"
     45# include "CCaptureSettings.h"
     46# include "CCaptureScreenSettings.h"
    4547# include "CConsole.h"
    4648# include "CMachine.h"
     
    781783
    782784/** UISessionStateStatusBarIndicator extension for Runtime UI: Video-capture indicator. */
    783 class UIIndicatorVideoCapture : public UISessionStateStatusBarIndicator
     785class UIIndicatorCapture : public UISessionStateStatusBarIndicator
    784786{
    785787    Q_OBJECT;
     
    788790    Q_PROPERTY(double rotationAngle READ rotationAngle WRITE setRotationAngle);
    789791
    790     /** Video-capture states. */
    791     enum UIIndicatorStateVideoCapture
    792     {
    793         UIIndicatorStateVideoCapture_Disabled = 0,
    794         UIIndicatorStateVideoCapture_Enabled  = 1,
    795         UIIndicatorStateVideoCapture_Paused   = 2
     792    /** Capture states. */
     793    enum UIIndicatorStateCapture
     794    {
     795        UIIndicatorStateCapture_Disabled = 0,
     796        UIIndicatorStateCapture_Enabled  = 1,
     797        UIIndicatorStateCapture_Paused   = 2
    796798    };
    797799
    798     /** Video-capture modes. */
    799     enum UIIndicatorStateVideoCaptureMode
    800     {
    801         UIIndicatorStateVideoCaptureMode_None   = RT_BIT(0),
    802         UIIndicatorStateVideoCaptureMode_Video  = RT_BIT(1),
    803         UIIndicatorStateVideoCaptureMode_Audio  = RT_BIT(2)
     800    /** Capture modes. */
     801    enum UIIndicatorStateCaptureMode
     802    {
     803        UIIndicatorStateCaptureMode_None   = RT_BIT(0),
     804        UIIndicatorStateCaptureMode_Video  = RT_BIT(1),
     805        UIIndicatorStateCaptureMode_Audio  = RT_BIT(2)
    804806    };
    805807
     
    807809
    808810    /** Constructor, passes @a pSession to the UISessionStateStatusBarIndicator constructor. */
    809     UIIndicatorVideoCapture(UISession *pSession)
    810         : UISessionStateStatusBarIndicator(IndicatorType_VideoCapture, pSession)
     811    UIIndicatorCapture(UISession *pSession)
     812        : UISessionStateStatusBarIndicator(IndicatorType_Capture, pSession)
    811813        , m_pAnimation(0)
    812814        , m_dRotationAngle(0)
    813         , m_eCaptureMode(UIIndicatorStateVideoCaptureMode_None)
     815        , m_eCaptureMode(UIIndicatorStateCaptureMode_None)
    814816    {
    815817        /* Assign state-icons: */
    816         setStateIcon(UIIndicatorStateVideoCapture_Disabled, UIIconPool::iconSet(":/video_capture_16px.png"));
    817         setStateIcon(UIIndicatorStateVideoCapture_Enabled,  UIIconPool::iconSet(":/movie_reel_16px.png"));
    818         setStateIcon(UIIndicatorStateVideoCapture_Paused,   UIIconPool::iconSet(":/movie_reel_16px.png"));
     818        setStateIcon(UIIndicatorStateCapture_Disabled, UIIconPool::iconSet(":/video_capture_16px.png"));
     819        setStateIcon(UIIndicatorStateCapture_Enabled,  UIIconPool::iconSet(":/movie_reel_16px.png"));
     820        setStateIcon(UIIndicatorStateCapture_Paused,   UIIconPool::iconSet(":/movie_reel_16px.png"));
    819821        /* Create *enabled* state animation: */
    820822        m_pAnimation = UIAnimationLoop::installAnimationLoop(this, "rotationAngle",
     
    833835        switch (iState)
    834836        {
    835             case UIIndicatorStateVideoCapture_Disabled:
     837            case UIIndicatorStateCapture_Disabled:
    836838                m_pAnimation->stop();
    837839                m_dRotationAngle = 0;
    838840                break;
    839             case UIIndicatorStateVideoCapture_Enabled:
     841            case UIIndicatorStateCapture_Enabled:
    840842                m_pAnimation->start();
    841843                break;
    842             case UIIndicatorStateVideoCapture_Paused:
     844            case UIIndicatorStateCapture_Paused:
    843845                m_pAnimation->stop();
    844846                break;
     
    858860        QPainter painter(this);
    859861        /* Configure painter for *enabled* state: */
    860         if (state() == UIIndicatorStateVideoCapture_Enabled)
     862        if (state() == UIIndicatorStateCapture_Enabled)
    861863        {
    862864            /* Configure painter for smooth animation: */
     
    882884
    883885        /* Update indicator state early: */
    884         if (!machine.GetVideoCaptureEnabled())
    885             setState(UIIndicatorStateVideoCapture_Disabled);
     886        CCaptureSettings captureSettings = machine.GetCaptureSettings();
     887        /* For now all screens have the same config: */
     888        CCaptureScreenSettings captureScreen0Settings = captureSettings.GetScreenSettings(0);
     889        if (!captureScreen0Settings.GetEnabled())
     890            setState(UIIndicatorStateCapture_Disabled);
    886891        else if (!fMachinePaused)
    887             setState(UIIndicatorStateVideoCapture_Enabled);
     892            setState(UIIndicatorStateCapture_Enabled);
    888893        else
    889             setState(UIIndicatorStateVideoCapture_Paused);
     894            setState(UIIndicatorStateCapture_Paused);
    890895
    891896        updateCaptureMode();
     
    895900        switch (state())
    896901        {
    897             case UIIndicatorStateVideoCapture_Disabled:
     902            case UIIndicatorStateCapture_Disabled:
    898903            {
    899                 strFullData += s_strTableRow1
     904                strFullData += s_strTableRow1 /** @todo r=andy Refine this tooltip (audio and/or video). */
    900905                    .arg(QApplication::translate("UIIndicatorsPool", "Video capture disabled", "Video capture tooltip"));
    901906                break;
    902907            }
    903             case UIIndicatorStateVideoCapture_Enabled:
    904             case UIIndicatorStateVideoCapture_Paused:
     908            case UIIndicatorStateCapture_Enabled:
     909            case UIIndicatorStateCapture_Paused:
    905910            {
    906911                QString strToolTip;
    907                 if ( m_eCaptureMode & UIIndicatorStateVideoCaptureMode_Audio &&
    908                     m_eCaptureMode & UIIndicatorStateVideoCaptureMode_Video)
     912                if ( m_eCaptureMode & UIIndicatorStateCaptureMode_Audio &&
     913                    m_eCaptureMode & UIIndicatorStateCaptureMode_Video)
    909914                    strToolTip = "Video/audio capture file";
    910                 else if (m_eCaptureMode & UIIndicatorStateVideoCaptureMode_Audio)
     915                else if (m_eCaptureMode & UIIndicatorStateCaptureMode_Audio)
    911916                    strToolTip = "Audio capture file";
    912                 else if (m_eCaptureMode & UIIndicatorStateVideoCaptureMode_Video)
     917                else if (m_eCaptureMode & UIIndicatorStateCaptureMode_Video)
    913918                    strToolTip = "Video capture file";
    914919
    915                 strFullData += s_strTableRow2
     920                strFullData += s_strTableRow2 /** @todo r=andy Refine this tooltip (audio and/or video). */
    916921                    .arg(QApplication::translate("UIIndicatorsPool", strToolTip.toLatin1().constData(), "Video capture tooltip"))
    917                     .arg(machine.GetVideoCaptureFile());
     922                    .arg(captureScreen0Settings.GetFileName());
    918923                break;
    919924            }
     
    935940    void setRotationAngle(double dRotationAngle) { m_dRotationAngle = dRotationAngle; update(); }
    936941
    937     /* Parses CMachine::videoCaptureOptions and updates m_eCaptureMode accordingly. */
     942    /* Parses CaptureScreenSettings::Options and updates m_eCaptureMode accordingly. */
    938943    void updateCaptureMode()
    939944    {
    940         m_eCaptureMode = UIIndicatorStateVideoCaptureMode_None;
     945        m_eCaptureMode = UIIndicatorStateCaptureMode_None;
    941946
    942947        /* Get machine: */
     
    946951        if (machine.isNull())
    947952            return;
    948         QStringList strOptionsPairList = machine.GetVideoCaptureOptions().split(",", QString::SkipEmptyParts);
     953
     954        CCaptureSettings captureSettings = machine.GetCaptureSettings();
     955        /* For now all screens have the same config: */
     956        CCaptureScreenSettings captureScreen0Settings = captureSettings.GetScreenSettings(0);
     957
     958        QStringList strOptionsPairList = captureScreen0Settings.GetOptions().split(",", QString::SkipEmptyParts);
    949959
    950960        for (int i = 0; i < strOptionsPairList.size(); ++i)
     
    952962            if (strOptionsPairList.at(i).contains("vc_enabled", Qt::CaseInsensitive) &&
    953963                strOptionsPairList.at(i).contains("true", Qt::CaseInsensitive))
    954                 m_eCaptureMode = (UIIndicatorStateVideoCaptureMode)((int)m_eCaptureMode | (int)UIIndicatorStateVideoCaptureMode_Video);
     964                m_eCaptureMode = (UIIndicatorStateCaptureMode)((int)m_eCaptureMode | (int)UIIndicatorStateCaptureMode_Video);
    955965
    956966            if (strOptionsPairList.at(i).contains("ac_enabled", Qt::CaseInsensitive) &&
    957967                strOptionsPairList.at(i).contains("true", Qt::CaseInsensitive))
    958                 m_eCaptureMode = (UIIndicatorStateVideoCaptureMode)((int)m_eCaptureMode | (int)UIIndicatorStateVideoCaptureMode_Audio);
     968                m_eCaptureMode = (UIIndicatorStateCaptureMode)((int)m_eCaptureMode | (int)UIIndicatorStateCaptureMode_Audio);
    959969        }
    960970    }
     
    965975    double m_dRotationAngle;
    966976
    967     UIIndicatorStateVideoCaptureMode m_eCaptureMode;
     977    UIIndicatorStateCaptureMode m_eCaptureMode;
    968978};
    969979
     
    14641474                case IndicatorType_SharedFolders:     m_pool[indicatorType] = new UIIndicatorSharedFolders(m_pSession); break;
    14651475                case IndicatorType_Display:           m_pool[indicatorType] = new UIIndicatorDisplay(m_pSession);       break;
    1466                 case IndicatorType_VideoCapture:      m_pool[indicatorType] = new UIIndicatorVideoCapture(m_pSession);  break;
     1476                case IndicatorType_Capture:      m_pool[indicatorType] = new UIIndicatorCapture(m_pSession);  break;
    14671477                case IndicatorType_Features:          m_pool[indicatorType] = new UIIndicatorFeatures(m_pSession);      break;
    14681478                case IndicatorType_Mouse:             m_pool[indicatorType] = new UIIndicatorMouse(m_pSession);         break;
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp

    r75158 r75251  
    55
    66/*
    7  * Copyright (C) 2010-2017 Oracle Corporation
     7 * Copyright (C) 2010-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    7777/* COM includes: */
    7878# include "CAudioAdapter.h"
     79# include "CCaptureSettings.h"
    7980# include "CVirtualBoxErrorInfo.h"
    8081# include "CMachineDebugger.h"
     
    10521053    m_pRunningOrPausedActions->addAction(actionPool()->action(UIActionIndexRT_M_View_S_TakeScreenshot));
    10531054    m_pRunningOrPausedActions->addAction(actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture));
    1054     m_pRunningOrPausedActions->addAction(actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_S_Settings));
    1055     m_pRunningOrPausedActions->addAction(actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start));
     1055    m_pRunningOrPausedActions->addAction(actionPool()->action(UIActionIndexRT_M_View_M_Capture_S_Settings));
     1056    m_pRunningOrPausedActions->addAction(actionPool()->action(UIActionIndexRT_M_View_M_Capture_T_Start));
    10561057    m_pRunningOrPausedActions->addAction(actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer));
    10571058    m_pRunningOrPausedActions->addAction(actionPool()->action(UIActionIndexRT_M_View_M_MenuBar));
     
    11361137    connect(actionPool()->action(UIActionIndexRT_M_View_S_TakeScreenshot), SIGNAL(triggered()),
    11371138            this, SLOT(sltTakeScreenshot()));
    1138     connect(actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_S_Settings), SIGNAL(triggered()),
    1139             this, SLOT(sltOpenVideoCaptureOptions()));
    1140     connect(actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start), SIGNAL(toggled(bool)),
    1141             this, SLOT(sltToggleVideoCapture(bool)));
     1139    connect(actionPool()->action(UIActionIndexRT_M_View_M_Capture_S_Settings), SIGNAL(triggered()),
     1140            this, SLOT(sltOpenCaptureOptions()));
     1141    connect(actionPool()->action(UIActionIndexRT_M_View_M_Capture_T_Start), SIGNAL(toggled(bool)),
     1142            this, SLOT(sltToggleCapture(bool)));
    11421143    connect(actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer), SIGNAL(toggled(bool)),
    11431144            this, SLOT(sltToggleVRDE(bool)));
     
    20902091}
    20912092
    2092 void UIMachineLogic::sltOpenVideoCaptureOptions()
     2093void UIMachineLogic::sltOpenCaptureOptions()
    20932094{
    20942095    /* Open VM settings : Display page : Video Capture tab: */
     
    20962097}
    20972098
    2098 void UIMachineLogic::sltToggleVideoCapture(bool fEnabled)
     2099void UIMachineLogic::sltToggleCapture(bool fEnabled)
    20992100{
    21002101    /* Do not process if window(s) missed! */
     
    21032104
    21042105    /* Make sure something had changed: */
    2105     if (machine().GetVideoCaptureEnabled() == static_cast<BOOL>(fEnabled))
     2106    CCaptureSettings captureSettings = machine().GetCaptureSettings();
     2107    if (captureSettings.GetEnabled() == static_cast<BOOL>(fEnabled))
    21062108        return;
    21072109
    21082110    /* Update Video Capture state: */
    2109     machine().SetVideoCaptureEnabled(fEnabled);
    2110     if (!machine().isOk())
     2111    captureSettings.SetEnabled(fEnabled);
     2112    if (!captureSettings.isOk())
    21112113    {
    21122114        /* Make sure action is updated: */
    2113         uisession()->updateStatusVideoCapture();
     2115        uisession()->updateStatusCapture();
    21142116        /* Notify about the error: */
    2115         return popupCenter().cannotToggleVideoCapture(activeMachineWindow(), machine(), fEnabled);
     2117        return popupCenter().cannotToggleCapture(activeMachineWindow(), machine(), fEnabled);
    21162118    }
    21172119
     
    21212123    {
    21222124        /* Make sure action is updated: */
    2123         uisession()->updateStatusVideoCapture();
     2125        uisession()->updateStatusCapture();
    21242126        /* Notify about the error: */
    21252127        return msgCenter().cannotSaveMachineSettings(machine());
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h

    r75158 r75251  
    291291    void sltToggleGuestAutoresize(bool fEnabled);
    292292    void sltTakeScreenshot();
    293     void sltOpenVideoCaptureOptions();
    294     void sltToggleVideoCapture(bool fEnabled);
     293    void sltOpenCaptureOptions();
     294    void sltToggleCapture(bool fEnabled);
    295295    void sltToggleVRDE(bool fEnabled);
    296296
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp

    r75211 r75251  
    6060/* COM includes: */
    6161# include "CAudioAdapter.h"
     62# include "CCaptureSettings.h"
    6263# include "CSystemProperties.h"
    6364# include "CStorageController.h"
     
    721722}
    722723
    723 void UISession::sltVideoCaptureChange()
    724 {
    725     /* Check/Uncheck Video Capture action depending on feature status: */
    726     actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start)->blockSignals(true);
    727     actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start)->setChecked(machine().GetVideoCaptureEnabled());
    728     actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start)->blockSignals(false);
    729 
    730     /* Notify listeners about Video Capture change: */
    731     emit sigVideoCaptureChange();
     724void UISession::sltCaptureChange()
     725{
     726    CCaptureSettings captureSettings = machine().GetCaptureSettings();
     727
     728    /* Check/Uncheck Capture action depending on feature status: */
     729    actionPool()->action(UIActionIndexRT_M_View_M_Capture_T_Start)->blockSignals(true);
     730    actionPool()->action(UIActionIndexRT_M_View_M_Capture_T_Start)->setChecked(captureSettings.GetEnabled());
     731    actionPool()->action(UIActionIndexRT_M_View_M_Capture_T_Start)->blockSignals(false);
     732
     733    /* Notify listeners about Capture change: */
     734    emit sigCaptureChange();
    732735}
    733736
     
    11311134
    11321135    connect(gConsoleEvents, SIGNAL(sigVideoCaptureChange()),
    1133             this, SLOT(sltVideoCaptureChange()));
     1136            this, SLOT(sltCaptureChange()));
    11341137
    11351138    connect(gConsoleEvents, SIGNAL(sigNetworkAdapterChange(CNetworkAdapter)),
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h

    r74942 r75251  
    259259    void updateStatusVRDE() { sltVRDEChange(); }
    260260    /** Updates Video Capture action state. */
    261     void updateStatusVideoCapture() { sltVideoCaptureChange(); }
     261    void updateStatusCapture() { sltCaptureChange(); }
    262262    /** Updates Audio output action state. */
    263263    void updateAudioOutput() { sltAudioAdapterChange(); }
     
    305305    void sigMediumChange(const CMediumAttachment &mediumAttachment);
    306306    void sigVRDEChange();
    307     void sigVideoCaptureChange();
     307    void sigCaptureChange();
    308308    void sigUSBControllerChange();
    309309    void sigUSBDeviceStateChange(const CUSBDevice &device, bool bIsAttached, const CVirtualBoxErrorInfo &error);
     
    357357    void sltAdditionsChange();
    358358    void sltVRDEChange();
    359     void sltVideoCaptureChange();
     359    void sltCaptureChange();
    360360    void sltGuestMonitorChange(KGuestMonitorChangedEventType changeType, ulong uScreenId, QRect screenGeo);
    361361    /** Handles storage device change for @a attachment, which was @a fRemoved and it was @a fSilent for guest. */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp

    r75211 r75251  
    219219        case IndicatorType_SharedFolders: pAction = actionPool()->action(UIActionIndexRT_M_Devices_M_SharedFolders);  break;
    220220        case IndicatorType_Display:       pAction = actionPool()->action(UIActionIndexRT_M_ViewPopup);                break;
    221         case IndicatorType_VideoCapture:  pAction = actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture);      break;
     221        case IndicatorType_Capture:  pAction = actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture);      break;
    222222        case IndicatorType_Mouse:         pAction = actionPool()->action(UIActionIndexRT_M_Input_M_Mouse);            break;
    223223        case IndicatorType_Keyboard:      pAction = actionPool()->action(UIActionIndexRT_M_Input_M_Keyboard);         break;
     
    640640        {
    641641            if (iElement & UIVisualElement_VideoCapture)
    642                 m_pIndicatorsPool->updateAppearance(IndicatorType_VideoCapture);
     642                m_pIndicatorsPool->updateAppearance(IndicatorType_Capture);
    643643        }
    644644    }
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp

    r75080 r75251  
    55
    66/*
    7  * Copyright (C) 2008-2017 Oracle Corporation
     7 * Copyright (C) 2008-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3131
    3232/* COM includes: */
     33# include "CCaptureSettings.h"
     34# include "CCaptureScreenSettings.h"
    3335# include "CExtPack.h"
    3436# include "CExtPackManager.h"
     
    380382    }
    381383
    382     /* Gather old 'Video Capture' data: */
    383     oldDisplayData.m_fVideoCaptureEnabled = m_machine.GetVideoCaptureEnabled();
    384     oldDisplayData.m_strVideoCaptureFolder = QFileInfo(m_machine.GetSettingsFilePath()).absolutePath();
    385     oldDisplayData.m_strVideoCaptureFilePath = m_machine.GetVideoCaptureFile();
    386     oldDisplayData.m_iVideoCaptureFrameWidth = m_machine.GetVideoCaptureWidth();
    387     oldDisplayData.m_iVideoCaptureFrameHeight = m_machine.GetVideoCaptureHeight();
    388     oldDisplayData.m_iVideoCaptureFrameRate = m_machine.GetVideoCaptureFPS();
    389     oldDisplayData.m_iVideoCaptureBitRate = m_machine.GetVideoCaptureRate();
    390     oldDisplayData.m_screens = m_machine.GetVideoCaptureScreens();
    391     oldDisplayData.m_strVideoCaptureOptions = m_machine.GetVideoCaptureOptions();
     384    /* Gather old 'Capture' data: */
     385    CCaptureSettings captureSettings = m_machine.GetCaptureSettings();
     386    oldDisplayData.m_fVideoCaptureEnabled = captureSettings.GetEnabled();
     387
     388    /* For now we're using the same settings for all screens; so get settings from screen 0 and work with that. */
     389    CCaptureScreenSettings captureScreen0Settings = captureSettings.GetScreenSettings(0);
     390    if (!captureScreen0Settings.isNull())
     391    {
     392        oldDisplayData.m_strVideoCaptureFolder = QFileInfo(m_machine.GetSettingsFilePath()).absolutePath();
     393        oldDisplayData.m_strVideoCaptureFilePath = captureScreen0Settings.GetFileName();
     394        oldDisplayData.m_iVideoCaptureFrameWidth = captureScreen0Settings.GetVideoWidth();
     395        oldDisplayData.m_iVideoCaptureFrameHeight = captureScreen0Settings.GetVideoHeight();
     396        oldDisplayData.m_iVideoCaptureFrameRate = captureScreen0Settings.GetVideoFPS();
     397        oldDisplayData.m_iVideoCaptureBitRate = captureScreen0Settings.GetVideoRate();
     398        oldDisplayData.m_strVideoCaptureOptions = captureScreen0Settings.GetOptions();
     399    }
     400
     401    CCaptureScreenSettingsVector captureScreenSettingsVector = captureSettings.GetScreens();
     402    for (int iScreenIndex = 0; iScreenIndex < captureScreenSettingsVector.size(); ++iScreenIndex)
     403    {
     404        CCaptureScreenSettings captureScreenSettings = captureScreenSettingsVector.at(iScreenIndex);
     405        oldDisplayData.m_screens[iScreenIndex] = captureScreenSettings.GetEnabled();
     406    }
    392407
    393408    /* Gather other old display data: */
     
    14931508        const UIDataSettingsMachineDisplay &newDisplayData = m_pCache->data();
    14941509
     1510        CCaptureSettings captureSettings = m_machine.GetCaptureSettings();
     1511
    14951512        /* Save new 'Video Capture' data for online case: */
    14961513        if (isMachineOnline())
     
    14991516            if (oldDisplayData.m_fVideoCaptureEnabled)
    15001517            {
     1518                /* Save whether capture is enabled: */
     1519                if (fSuccess && newDisplayData.m_fVideoCaptureEnabled != oldDisplayData.m_fVideoCaptureEnabled)
     1520                {
     1521                    captureSettings.SetEnabled(newDisplayData.m_fVideoCaptureEnabled);
     1522                    fSuccess = captureSettings.isOk();
     1523                }
     1524
    15011525                // We can still save the *screens* option.
    1502                 // And finally we should *disable* 'Video Capture' if necessary.
    15031526                /* Save video capture screens: */
    15041527                if (fSuccess && newDisplayData.m_screens != oldDisplayData.m_screens)
    15051528                {
    1506                     m_machine.SetVideoCaptureScreens(newDisplayData.m_screens);
    1507                     fSuccess = m_machine.isOk();
    1508                 }
    1509                 /* Save whether video capture is enabled: */
    1510                 if (fSuccess && newDisplayData.m_fVideoCaptureEnabled != oldDisplayData.m_fVideoCaptureEnabled)
    1511                 {
    1512                     m_machine.SetVideoCaptureEnabled(newDisplayData.m_fVideoCaptureEnabled);
    1513                     fSuccess = m_machine.isOk();
     1529                    CCaptureScreenSettingsVector captureScreenSettingsVector = captureSettings.GetScreens();
     1530                    for (int iScreenIndex = 0; fSuccess && iScreenIndex < captureScreenSettingsVector.size(); ++iScreenIndex)
     1531                    {
     1532                        CCaptureScreenSettings captureScreenSettings = captureScreenSettingsVector.at(iScreenIndex);
     1533                        captureScreenSettings.SetEnabled(newDisplayData.m_screens[iScreenIndex]);
     1534                        fSuccess = captureScreenSettings.isOk();
     1535                    }
    15141536                }
    15151537            }
     
    15171539            else
    15181540            {
    1519                 // We should save all the options *before* 'Video Capture' activation.
    1520                 // And finally we should *enable* Video Capture if necessary.
     1541                /* Save whether capture is enabled: */
     1542                if (fSuccess && newDisplayData.m_fVideoCaptureEnabled != oldDisplayData.m_fVideoCaptureEnabled)
     1543                {
     1544                    captureSettings.SetEnabled(newDisplayData.m_fVideoCaptureEnabled);
     1545                    fSuccess = captureSettings.isOk();
     1546                }
     1547
     1548                CCaptureScreenSettingsVector captureScreenSettingsVector = captureSettings.GetScreens();
     1549                for (int iScreenIndex = 0; fSuccess && iScreenIndex < captureScreenSettingsVector.size(); ++iScreenIndex)
     1550                {
     1551                    CCaptureScreenSettings captureScreenSettings = captureScreenSettingsVector.at(iScreenIndex);
     1552
     1553                    // We should save all the options *before* 'Video Capture' activation.
     1554                    // And finally we should *enable* Video Capture if necessary.
     1555                    /* Save video capture file path: */
     1556                    if (fSuccess && newDisplayData.m_strVideoCaptureFilePath != oldDisplayData.m_strVideoCaptureFilePath)
     1557                    {
     1558                        captureScreenSettings.SetFileName(newDisplayData.m_strVideoCaptureFilePath);
     1559                        fSuccess = captureScreenSettings.isOk();
     1560                    }
     1561                    /* Save video capture frame width: */
     1562                    if (fSuccess && newDisplayData.m_iVideoCaptureFrameWidth != oldDisplayData.m_iVideoCaptureFrameWidth)
     1563                    {
     1564                        captureScreenSettings.SetVideoWidth(newDisplayData.m_iVideoCaptureFrameWidth);
     1565                        fSuccess = captureScreenSettings.isOk();
     1566                    }
     1567                    /* Save video capture frame height: */
     1568                    if (fSuccess && newDisplayData.m_iVideoCaptureFrameHeight != oldDisplayData.m_iVideoCaptureFrameHeight)
     1569                    {
     1570                        captureScreenSettings.SetVideoHeight(newDisplayData.m_iVideoCaptureFrameHeight);
     1571                        fSuccess = captureScreenSettings.isOk();
     1572                    }
     1573                    /* Save video capture frame rate: */
     1574                    if (fSuccess && newDisplayData.m_iVideoCaptureFrameRate != oldDisplayData.m_iVideoCaptureFrameRate)
     1575                    {
     1576                        captureScreenSettings.SetVideoFPS(newDisplayData.m_iVideoCaptureFrameRate);
     1577                        fSuccess = captureScreenSettings.isOk();
     1578                    }
     1579                    /* Save video capture frame bit rate: */
     1580                    if (fSuccess && newDisplayData.m_iVideoCaptureBitRate != oldDisplayData.m_iVideoCaptureBitRate)
     1581                    {
     1582                        captureScreenSettings.SetVideoRate(newDisplayData.m_iVideoCaptureBitRate);
     1583                        fSuccess = captureScreenSettings.isOk();
     1584                    }
     1585                    /* Save video capture screens: */
     1586                    if (fSuccess && newDisplayData.m_screens != oldDisplayData.m_screens)
     1587                    {
     1588                        captureScreenSettings.SetEnabled(newDisplayData.m_screens[iScreenIndex]);
     1589                        fSuccess = captureScreenSettings.isOk();
     1590                    }
     1591                    /* Save video capture options: */
     1592                    if (fSuccess && newDisplayData.m_strVideoCaptureOptions != oldDisplayData.m_strVideoCaptureOptions)
     1593                    {
     1594                        captureScreenSettings.SetOptions(newDisplayData.m_strVideoCaptureOptions);
     1595                        fSuccess = captureScreenSettings.isOk();
     1596                    }
     1597                }
     1598            }
     1599        }
     1600        /* Save new 'Video Capture' data for offline case: */
     1601        else
     1602        {
     1603            // For 'offline', 'powered off' and 'saved' states the order is irrelevant.
     1604            /* Save whether video capture is enabled: */
     1605            if (fSuccess && newDisplayData.m_fVideoCaptureEnabled != oldDisplayData.m_fVideoCaptureEnabled)
     1606            {
     1607                captureSettings.SetEnabled(newDisplayData.m_fVideoCaptureEnabled);
     1608                fSuccess = captureSettings.isOk();
     1609            }
     1610
     1611            CCaptureScreenSettingsVector captureScreenSettingsVector = captureSettings.GetScreens();
     1612            for (int iScreenIndex = 0; fSuccess && iScreenIndex < captureScreenSettingsVector.size(); ++iScreenIndex)
     1613            {
     1614                CCaptureScreenSettings captureScreenSettings = captureScreenSettingsVector.at(iScreenIndex);
     1615
    15211616                /* Save video capture file path: */
    15221617                if (fSuccess && newDisplayData.m_strVideoCaptureFilePath != oldDisplayData.m_strVideoCaptureFilePath)
    15231618                {
    1524                     m_machine.SetVideoCaptureFile(newDisplayData.m_strVideoCaptureFilePath);
    1525                     fSuccess = m_machine.isOk();
     1619                    captureScreenSettings.SetFileName(newDisplayData.m_strVideoCaptureFilePath);
     1620                    fSuccess = captureScreenSettings.isOk();
    15261621                }
    15271622                /* Save video capture frame width: */
    15281623                if (fSuccess && newDisplayData.m_iVideoCaptureFrameWidth != oldDisplayData.m_iVideoCaptureFrameWidth)
    15291624                {
    1530                     m_machine.SetVideoCaptureWidth(newDisplayData.m_iVideoCaptureFrameWidth);
    1531                     fSuccess = m_machine.isOk();
     1625                    captureScreenSettings.SetVideoWidth(newDisplayData.m_iVideoCaptureFrameWidth);
     1626                    fSuccess = captureScreenSettings.isOk();
    15321627                }
    15331628                /* Save video capture frame height: */
    15341629                if (fSuccess && newDisplayData.m_iVideoCaptureFrameHeight != oldDisplayData.m_iVideoCaptureFrameHeight)
    15351630                {
    1536                     m_machine.SetVideoCaptureHeight(newDisplayData.m_iVideoCaptureFrameHeight);
    1537                     fSuccess = m_machine.isOk();
     1631                    captureScreenSettings.SetVideoHeight(newDisplayData.m_iVideoCaptureFrameHeight);
     1632                    fSuccess = captureScreenSettings.isOk();
    15381633                }
    15391634                /* Save video capture frame rate: */
    15401635                if (fSuccess && newDisplayData.m_iVideoCaptureFrameRate != oldDisplayData.m_iVideoCaptureFrameRate)
    15411636                {
    1542                     m_machine.SetVideoCaptureFPS(newDisplayData.m_iVideoCaptureFrameRate);
    1543                     fSuccess = m_machine.isOk();
     1637                    captureScreenSettings.SetVideoFPS(newDisplayData.m_iVideoCaptureFrameRate);
     1638                    fSuccess = captureScreenSettings.isOk();
    15441639                }
    15451640                /* Save video capture frame bit rate: */
    15461641                if (fSuccess && newDisplayData.m_iVideoCaptureBitRate != oldDisplayData.m_iVideoCaptureBitRate)
    15471642                {
    1548                     m_machine.SetVideoCaptureRate(newDisplayData.m_iVideoCaptureBitRate);
    1549                     fSuccess = m_machine.isOk();
     1643                    captureScreenSettings.SetVideoRate(newDisplayData.m_iVideoCaptureBitRate);
     1644                    fSuccess = captureScreenSettings.isOk();
    15501645                }
    1551                 /* Save video capture screens: */
     1646                /* Save capture options: */
     1647                if (fSuccess && newDisplayData.m_strVideoCaptureOptions != oldDisplayData.m_strVideoCaptureOptions)
     1648                {
     1649                    captureScreenSettings.SetOptions(newDisplayData.m_strVideoCaptureOptions);
     1650                    fSuccess = captureScreenSettings.isOk();
     1651                }
     1652                /* Save screen enabled state: */
    15521653                if (fSuccess && newDisplayData.m_screens != oldDisplayData.m_screens)
    15531654                {
    1554                     m_machine.SetVideoCaptureScreens(newDisplayData.m_screens);
    1555                     fSuccess = m_machine.isOk();
     1655                    captureScreenSettings.SetEnabled(newDisplayData.m_screens[iScreenIndex]);
     1656                    fSuccess = captureScreenSettings.isOk();
    15561657                }
    1557                 /* Save video capture options: */
    1558                 if (fSuccess && newDisplayData.m_strVideoCaptureOptions != oldDisplayData.m_strVideoCaptureOptions)
    1559                 {
    1560                     m_machine.SetVideoCaptureOptions(newDisplayData.m_strVideoCaptureOptions);
    1561                     fSuccess = m_machine.isOk();
    1562                 }
    1563                 /* Save whether video capture is enabled: */
    1564                 if (fSuccess && newDisplayData.m_fVideoCaptureEnabled != oldDisplayData.m_fVideoCaptureEnabled)
    1565                 {
    1566                     m_machine.SetVideoCaptureEnabled(newDisplayData.m_fVideoCaptureEnabled);
    1567                     fSuccess = m_machine.isOk();
    1568                 }
    1569             }
    1570         }
    1571         /* Save new 'Video Capture' data for offline case: */
    1572         else
    1573         {
    1574             // For 'offline', 'powered off' and 'saved' states the order is irrelevant.
    1575             /* Save whether video capture is enabled: */
    1576             if (fSuccess && newDisplayData.m_fVideoCaptureEnabled != oldDisplayData.m_fVideoCaptureEnabled)
    1577             {
    1578                 m_machine.SetVideoCaptureEnabled(newDisplayData.m_fVideoCaptureEnabled);
    1579                 fSuccess = m_machine.isOk();
    1580             }
    1581             /* Save video capture file path: */
    1582             if (fSuccess && newDisplayData.m_strVideoCaptureFilePath != oldDisplayData.m_strVideoCaptureFilePath)
    1583             {
    1584                 m_machine.SetVideoCaptureFile(newDisplayData.m_strVideoCaptureFilePath);
    1585                 fSuccess = m_machine.isOk();
    1586             }
    1587             /* Save video capture frame width: */
    1588             if (fSuccess && newDisplayData.m_iVideoCaptureFrameWidth != oldDisplayData.m_iVideoCaptureFrameWidth)
    1589             {
    1590                 m_machine.SetVideoCaptureWidth(newDisplayData.m_iVideoCaptureFrameWidth);
    1591                 fSuccess = m_machine.isOk();
    1592             }
    1593             /* Save video capture frame height: */
    1594             if (fSuccess && newDisplayData.m_iVideoCaptureFrameHeight != oldDisplayData.m_iVideoCaptureFrameHeight)
    1595             {
    1596                 m_machine.SetVideoCaptureHeight(newDisplayData.m_iVideoCaptureFrameHeight);
    1597                 fSuccess = m_machine.isOk();
    1598             }
    1599             /* Save video capture frame rate: */
    1600             if (fSuccess && newDisplayData.m_iVideoCaptureFrameRate != oldDisplayData.m_iVideoCaptureFrameRate)
    1601             {
    1602                 m_machine.SetVideoCaptureFPS(newDisplayData.m_iVideoCaptureFrameRate);
    1603                 fSuccess = m_machine.isOk();
    1604             }
    1605             /* Save video capture frame bit rate: */
    1606             if (fSuccess && newDisplayData.m_iVideoCaptureBitRate != oldDisplayData.m_iVideoCaptureBitRate)
    1607             {
    1608                 m_machine.SetVideoCaptureRate(newDisplayData.m_iVideoCaptureBitRate);
    1609                 fSuccess = m_machine.isOk();
    1610             }
    1611             /* Save video capture screens: */
    1612             if (fSuccess && newDisplayData.m_screens != oldDisplayData.m_screens)
    1613             {
    1614                 m_machine.SetVideoCaptureScreens(newDisplayData.m_screens);
    1615                 fSuccess = m_machine.isOk();
    1616             }
    1617             /* Save video capture options: */
    1618             if (fSuccess && newDisplayData.m_strVideoCaptureOptions != oldDisplayData.m_strVideoCaptureOptions)
    1619             {
    1620                 m_machine.SetVideoCaptureOptions(newDisplayData.m_strVideoCaptureOptions);
    1621                 fSuccess = m_machine.isOk();
    16221658            }
    16231659        }
  • trunk/src/VBox/Frontends/VirtualBox/src/snapshots/UISnapshotDetailsWidget.cpp

    r72856 r75251  
    55
    66/*
    7  * Copyright (C) 2008-2017 Oracle Corporation
     7 * Copyright (C) 2008-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4848/* COM includes: */
    4949# include "CAudioAdapter.h"
     50# include "CCaptureSettings.h"
     51# include "CCaptureScreenSettings.h"
    5052# include "CMachine.h"
    5153# include "CMedium.h"
     
    17451747    /* Prepare report: */
    17461748    QStringList aReport;
    1747     /* Acquire video capture status: */
    1748     if (comMachine.GetVideoCaptureEnabled())
     1749    /* Acquire capture status: */
     1750    CCaptureSettings captureSettings = comMachine.GetCaptureSettings();
     1751    /* For now all screens have the same config: */
     1752    CCaptureScreenSettings captureScreen0Settings = captureSettings.GetScreenSettings(0);
     1753    if (captureScreen0Settings.GetEnabled())
    17491754    {
    17501755        /* Video Capture File: */
    1751         aReport << comMachine.GetVideoCaptureFile();
     1756        aReport << captureScreen0Settings.GetFileName();
    17521757        /* Video Capture Attributes: */
    17531758        aReport << QApplication::translate("UIGDetails", "Frame Size: %1x%2, Frame Rate: %3fps, Bit Rate: %4kbps")
    1754                                            .arg(comMachine.GetVideoCaptureWidth())
    1755                                            .arg(comMachine.GetVideoCaptureHeight())
    1756                                            .arg(comMachine.GetVideoCaptureFPS())
    1757                                            .arg(comMachine.GetVideoCaptureRate());
     1759                                           .arg(captureScreen0Settings.GetVideoWidth())
     1760                                           .arg(captureScreen0Settings.GetVideoHeight())
     1761                                           .arg(captureScreen0Settings.GetVideoFPS())
     1762                                           .arg(captureScreen0Settings.GetVideoRate());
    17581763    }
    17591764    /* Return report: */
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIMenuBarEditorWindow.cpp

    r74942 r75251  
    13041304        pMenu->addSeparator();
    13051305        prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_S_TakeScreenshot));
    1306         prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_M_VideoCapture_T_Start));
     1306        prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_M_Capture_T_Start));
    13071307        prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer));
    13081308        pMenu->addSeparator();
  • trunk/src/VBox/Main/Makefile.kmk

    r75038 r75251  
    457457        src-server/BandwidthGroupImpl.cpp \
    458458        src-server/BIOSSettingsImpl.cpp \
     459        src-server/CaptureSettingsImpl.cpp \
     460        src-server/CaptureScreenSettingsImpl.cpp \
    459461        src-server/ClientWatcher.cpp \
    460462        src-server/ClientToken.cpp \
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r75044 r75251  
    46894689  </interface>
    46904690
     4691  <enum
     4692    name="CaptureDestination"
     4693    uuid="E54603A9-6751-4255-93F8-C69E61693391"
     4694    >
     4695    <desc>
     4696      Capturing destination enumeration.
     4697    </desc>
     4698
     4699    <const name="None"                  value="0">
     4700      <desc>No destination.</desc>
     4701    </const>
     4702    <const name="File"                  value="1">
     4703      <desc>Destination is a regular file.</desc>
     4704    </const>
     4705  </enum>
     4706
     4707  <enum
     4708    name="CaptureFeature"
     4709    uuid="F606CDDB-91B2-4E41-9DFE-4713D4DBA96F"
     4710    >
     4711    <desc>
     4712      Capturing features enumeration.
     4713    </desc>
     4714
     4715    <const name="None"                  value="0">
     4716      <desc>No feature set.</desc>
     4717    </const>
     4718    <const name="Video"                 value="1">
     4719      <desc>Video capturing.</desc>
     4720    </const>
     4721    <const name="Audio"                 value="2">
     4722      <desc>Audio capturing.</desc>
     4723    </const>
     4724  </enum>
     4725
     4726  <enum
     4727    name="CaptureAudioCodec"
     4728    uuid="9B80C37F-7984-412C-A755-C18FE5859554"
     4729    >
     4730    <desc>
     4731      Capturing audio codec enumeration.
     4732    </desc>
     4733
     4734    <const name="None"                  value="0">
     4735      <desc>No codec set.</desc>
     4736    </const>
     4737    <const name="WavPCM"                value="1">
     4738      <desc>WAV format, linear PCM, uncompressed.
     4739        Not implemented yet.</desc>
     4740    </const>
     4741    <const name="Opus"                  value="2">
     4742      <desc>Opus Audio.</desc>
     4743    </const>
     4744  </enum>
     4745
     4746  <enum
     4747    name="CaptureVideoCodec"
     4748    uuid="98BBC021-E119-497D-8C66-4336D539A8D6"
     4749    >
     4750    <desc>
     4751      Capturing video codec enumeration.
     4752    </desc>
     4753
     4754    <const name="None"                  value="0">
     4755      <desc>No codec set.</desc>
     4756    </const>
     4757    <const name="VP8"                   value="1">
     4758      <desc>VP8 codec.</desc>
     4759    </const>
     4760    <const name="VP9"                   value="2">
     4761      <desc>VP9 codec. Not implemented yet.</desc>
     4762    </const>
     4763    <const name="AV1"                   value="3">
     4764      <desc>AV1 codec. Not implemented yet.</desc>
     4765    </const>
     4766  </enum>
     4767
     4768  <interface
     4769    name="ICaptureScreenSettings" extends="$unknown"
     4770    uuid="9C8FE192-DD9A-45E9-B17B-2BA23B5951F7"
     4771    wsmap="managed"
     4772    >
     4773
     4774    <desc>
     4775      The ICaptureScreenSettings interface represents capturing settings of a
     4776      singke virtual screen. This is used only in the <link to="ICaptureSettings" />
     4777      interface.
     4778    </desc>
     4779
     4780    <method name="isFeatureEnabled">
     4781      <desc>TODO</desc>
     4782      <param name="feature" type="CaptureFeature" dir="in">
     4783        <desc>TODO</desc>
     4784      </param>
     4785      <param name="enabled" type="boolean" dir="return">
     4786        <desc>TODO</desc>
     4787      </param>
     4788    </method>
     4789
     4790    <attribute name="enabled" type="boolean" default="false">
     4791      <desc>
     4792        This setting determines whether this screen is enabled while capturing.
     4793      </desc>
     4794    </attribute>
     4795
     4796    <attribute name="features" type="unsigned long">
     4797      <desc>This setting determines all enabled capturing features for this
     4798        screen.</desc>
     4799    </attribute>
     4800
     4801    <attribute name="destination" type="CaptureDestination">
     4802      <desc>This setting determines the capturing destination for this
     4803        screen.</desc>
     4804    </attribute>
     4805
     4806    <attribute name="fileName" type="wstring">
     4807      <desc>
     4808        This setting determines the filename VirtualBox uses to save
     4809        the recorded content. This setting cannot be changed while video
     4810        capturing is enabled.
     4811        <note>
     4812          When setting this attribute, the specified path has to be
     4813          absolute (full path). When reading this attribute, a full path is
     4814          always returned.
     4815        </note>
     4816      </desc>
     4817    </attribute>
     4818
     4819    <attribute name="maxTime" type="unsigned long" default="0">
     4820      <desc>
     4821        This setting defines the maximum amount of time in milliseconds
     4822        to capture. Capturing will stop as soon as the defined time
     4823        interval has elapsed. If this value is zero, capturing will not be
     4824        limited by time. This setting cannot be changed while capturing is
     4825        enabled.
     4826      </desc>
     4827    </attribute>
     4828
     4829    <attribute name="maxFileSize" type="unsigned long" default="0">
     4830      <desc>
     4831        This setting determines the maximal number of captured file
     4832        size in MB. Capturing will stop as soon as the file size has
     4833        reached the defined value. If this value is zero, capturing
     4834        will not be limited by the file size. This setting cannot be changed
     4835        while capturing is enabled.
     4836      </desc>
     4837    </attribute>
     4838
     4839    <attribute name="options" type="wstring">
     4840      <desc>
     4841        This setting contains any additional capturing options
     4842        required in comma-separated key=value format. This setting
     4843        cannot be changed while capturing is enabled.
     4844
     4845        The following keys and their corresponding values are available:
     4846
     4847        <table>
     4848          <tr>
     4849            <td>ac_enabled</td>
     4850            <td>Enables audio recording when set to <pre>true</pre>, otherwise
     4851                set to <pre>false</pre> to disable.
     4852
     4853                <b>This feature is considered being experimental.</b></td>
     4854          </tr>
     4855        </table>
     4856
     4857      </desc>
     4858    </attribute>
     4859
     4860    <attribute name="videoWidth" type="unsigned long" default="1024">
     4861      <desc>
     4862        This setting determines the horizontal resolution of the recorded
     4863        video. This setting cannot be changed while capturing is enabled.
     4864      </desc>
     4865    </attribute>
     4866
     4867    <attribute name="videoHeight" type="unsigned long" default="768">
     4868      <desc>
     4869        This setting determines the vertical resolution of the recorded
     4870        video. This setting cannot be changed while capturing is enabled.
     4871      </desc>
     4872    </attribute>
     4873
     4874    <attribute name="videoRate" type="unsigned long" default="512">
     4875      <desc>
     4876        This setting determines the bitrate in kilobits per second.
     4877        Increasing this value makes the video look better for the
     4878        cost of an increased file size. This setting cannot be changed
     4879        while capturing is enabled.
     4880      </desc>
     4881    </attribute>
     4882
     4883    <attribute name="videoFPS" type="unsigned long" default="25">
     4884      <desc>
     4885        This setting determines the maximum number of frames per second.
     4886        Frames with a higher frequency will be skipped. Reducing this
     4887        value increases the number of skipped frames and reduces the
     4888        file size. This setting cannot be changed while capturing
     4889        is enabled.
     4890      </desc>
     4891    </attribute>
     4892
     4893  </interface>
     4894
     4895  <interface
     4896    name="ICaptureSettings" extends="$unknown"
     4897    uuid="F35B5C06-F6F0-475D-908A-F5FECC820043"
     4898    wsmap="managed"
     4899    >
     4900
     4901    <desc>
     4902      The ICaptureSettings interface represents capturing settings of the virtual
     4903      machine. This is used only in the <link to="IMachine::CaptureSettings" />
     4904      attribute.
     4905    </desc>
     4906
     4907    <method name="getScreenSettings">
     4908      <desc>TODO</desc>
     4909      <param name="screenId" type="unsigned long" dir="in">
     4910        <desc>TODO</desc>
     4911      </param>
     4912      <param name="captureScreenSettings" type="ICaptureScreenSettings" dir="return">
     4913        <desc>TODO</desc>
     4914      </param>
     4915    </method>
     4916
     4917    <attribute name="enabled" type="boolean" default="false">
     4918      <desc>
     4919        This setting determines whether VirtualBox uses capturing to record a
     4920        VM session.</desc>
     4921    </attribute>
     4922
     4923    <attribute name="screens" type="ICaptureScreenSettings" readonly="yes" safearray="yes">
     4924      <desc>
     4925        This setting returns an array for capturing settings of all configured
     4926        virtual screens.</desc>
     4927    </attribute>
     4928
     4929  </interface>
     4930
    46914931  <interface
    46924932    name="IPCIAddress" extends="$unknown"
     
    48835123  <interface
    48845124    name="IMachine" extends="$unknown"
    4885     uuid="fecae8e8-46da-44cf-8fc0-2ba9aeb796a7"
     5125    uuid="316A9802-03A5-44BE-B2A6-51261A021353"
    48865126    wsmap="managed"
    48875127    wrap-hint-server-addinterfaces="IInternalMachineControl"
     
    51645404    </attribute>
    51655405
    5166     <attribute name="videoCaptureEnabled" type="boolean" default="false">
    5167       <desc>
    5168         This setting determines whether VirtualBox uses video capturing to
    5169         record a VM session.</desc>
    5170     </attribute>
    5171 
    5172     <attribute name="videoCaptureScreens" type="boolean" safearray="yes">
    5173       <desc>
    5174         This setting determines for which screens video capturing is
    5175         enabled.</desc>
    5176     </attribute>
    5177 
    5178     <attribute name="videoCaptureFile" type="wstring">
    5179       <desc>
    5180         This setting determines the filename VirtualBox uses to save
    5181         the recorded content. This setting cannot be changed while video
    5182         capturing is enabled.
    5183         <note>
    5184           When setting this attribute, the specified path has to be
    5185           absolute (full path). When reading this attribute, a full path is
    5186           always returned.
    5187         </note>
    5188       </desc>
    5189     </attribute>
    5190 
    5191     <attribute name="videoCaptureWidth" type="unsigned long" default="640">
    5192       <desc>
    5193         This setting determines the horizontal resolution of the recorded
    5194         video. This setting cannot be changed while video capturing is
    5195         enabled.
    5196       </desc>
    5197     </attribute>
    5198 
    5199     <attribute name="videoCaptureHeight" type="unsigned long" default="480">
    5200       <desc>
    5201         This setting determines the vertical resolution of the recorded
    5202         video. This setting cannot be changed while video capturing is
    5203         enabled.
    5204       </desc>
    5205     </attribute>
    5206 
    5207     <attribute name="videoCaptureRate" type="unsigned long" default="512">
    5208       <desc>
    5209         This setting determines the bitrate in kilobits per second.
    5210         Increasing this value makes the video look better for the
    5211         cost of an increased file size. This setting cannot be changed
    5212         while video capturing is enabled.
    5213       </desc>
    5214     </attribute>
    5215 
    5216     <attribute name="videoCaptureFPS" type="unsigned long" default="25">
    5217       <desc>
    5218         This setting determines the maximum number of frames per second.
    5219         Frames with a higher frequency will be skipped. Reducing this
    5220         value increases the number of skipped frames and reduces the
    5221         file size. This setting cannot be changed while video capturing
    5222         is enabled.
    5223       </desc>
    5224     </attribute>
    5225 
    5226     <attribute name="videoCaptureMaxTime" type="unsigned long" default="0">
    5227       <desc>
    5228         This setting determines the maximum amount of time in milliseconds
    5229         the video capture will work for. The capture stops as the defined time
    5230         interval  has elapsed. If this value is zero the capturing will not be
    5231         limited by time. This setting cannot be changed while video capturing is
    5232         enabled.
    5233       </desc>
    5234     </attribute>
    5235 
    5236     <attribute name="videoCaptureMaxFileSize" type="unsigned long" default="0">
    5237       <desc>
    5238         This setting determines the maximal number of captured video file
    5239         size in MB. The capture stops as the captured video file size
    5240         has reached the defined. If this value is zero the capturing
    5241         will not be limited by file size. This setting cannot be changed
    5242         while video capturing is enabled.
    5243       </desc>
    5244     </attribute>
    5245 
    5246     <attribute name="videoCaptureOptions" type="wstring">
    5247       <desc>
    5248         This setting contains any additional video capture options
    5249         required in comma-separated key=value format. This setting
    5250         cannot be changed while video capturing is enabled.
    5251 
    5252         The following keys and their corresponding values are available:
    5253 
    5254         <table>
    5255           <tr>
    5256             <td>ac_enabled</td>
    5257             <td>Enables audio recording when set to <pre>true</pre>, otherwise
    5258                 set to <pre>false</pre> to disable.
    5259 
    5260                 <b>This feature is considered being experimental.</b></td>
    5261           </tr>
    5262         </table>
    5263 
    5264       </desc>
    5265     </attribute>
    5266 
    52675406    <attribute name="BIOSSettings" type="IBIOSSettings" readonly="yes">
    52685407      <desc>Object containing all BIOS settings.</desc>
     5408    </attribute>
     5409
     5410    <attribute name="captureSettings" type="ICaptureSettings" readonly="yes">
     5411      <desc>Object containing all capturing settings.</desc>
    52695412    </attribute>
    52705413
     
    2041120554  <interface
    2041220555    name="IInternalSessionControl" extends="$unknown"
    20413     uuid="747e397e-69c8-45a0-88d9-f7f070960718"
     20556    uuid="96BDA9B7-92E6-402F-AA8C-2E77818DAE6E"
    2041420557    internal="yes"
    2041520558    wsmap="suppress"
     
    2071120854    </method>
    2071220855
    20713     <method name="onVideoCaptureChange">
    20714       <desc>
    20715         Triggered when video capture settings have changed.
     20856    <method name="onCaptureChange">
     20857      <desc>
     20858        Triggered when capture settings have changed.
    2071620859      </desc>
    2071720860    </method>
     
    2289523038      </desc>
    2289623039    </const>
    22897     <const name="OnVideoCaptureChanged" value="91">
    22898       <desc>
    22899         See <link to="IVideoCaptureChangedEvent">IVideoCapturedChangeEvent</link>.
     23040    <const name="OnCaptureChanged" value="91">
     23041      <desc>
     23042        See <link to="ICaptureChangedEvent">ICapturedChangeEvent</link>.
    2290023043      </desc>
    2290123044    </const>
     
    2428224425
    2428324426  <interface
    24284     name="IVideoCaptureChangedEvent" extends="IEvent"
    24285     uuid="6215d169-25dd-4719-ab34-c908701efb58"
    24286     wsmap="managed" autogen="VBoxEvent" id="OnVideoCaptureChanged"
     24427    name="ICaptureChangedEvent" extends="IEvent"
     24428    uuid="C694687C-F432-4435-B457-F2E55B845C81"
     24429    wsmap="managed" autogen="VBoxEvent" id="OnCaptureChanged"
    2428724430    >
    2428824431    <desc>
    24289       Notification when video capture settings have changed.
     24432      Notification when capture settings have changed.
    2429024433    </desc>
    2429124434    <attribute name="midlDoesNotLikeEmptyInterfaces" readonly="yes" type="boolean"/>
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r74765 r75251  
    2424#include "SecretKeyStore.h"
    2525#include "ConsoleWrap.h"
     26#ifdef VBOX_WITH_VIDEOREC
     27# include "VideoRec.h"
     28#endif
    2629
    2730class Guest;
     
    139142#endif
    140143#ifdef VBOX_WITH_AUDIO_VIDEOREC
    141     AudioVideoRec *i_getAudioVideoRec() const { return mAudioVideoRec; }
    142     HRESULT i_audioVideoRecSendAudio(const void *pvData, size_t cbData, uint64_t uDurationMs);
     144    int i_videoRecLoad(settings::CaptureSettings &Settings);
     145    int i_videoRecStart(void);
     146    int i_videoRecStop(void);
     147    AudioVideoRec *i_videoRecGetAudioDrv(void) const { return Capture.mAudioVideoRec; }
     148    CaptureContext *i_videoRecGetContext(void) const { return Capture.mpVideoRecCtx; }
     149    HRESULT i_videoRecSendAudio(const void *pvData, size_t cbData, uint64_t uDurationMs);
    143150#endif
    144151
     
    169176    HRESULT i_onDnDModeChange(DnDMode_T aDnDMode);
    170177    HRESULT i_onVRDEServerChange(BOOL aRestart);
    171     HRESULT i_onVideoCaptureChange();
     178    HRESULT i_onCaptureChange();
    172179    HRESULT i_onUSBControllerChange();
    173180    HRESULT i_onSharedFolderChange(BOOL aGlobal);
     
    939946    VMMDev *                    m_pVMMDev;
    940947    AudioVRDE * const           mAudioVRDE;
    941 #ifdef VBOX_WITH_AUDIO_VIDEOREC
    942     /** The video recording audio backend. */
    943     AudioVideoRec * const       mAudioVideoRec;
    944 #endif
    945948    Nvram   * const             mNvram;
    946949#ifdef VBOX_WITH_USB_CARDREADER
     
    10281031    ComPtr<IEventListener> mVmListener;
    10291032
     1033#ifdef VBOX_WITH_VIDEOREC
     1034    struct Capture
     1035    {
     1036        Capture()
     1037            : mpVideoRecCtx(NULL)
     1038            , mAudioVideoRec(NULL) { }
     1039
     1040        /** The capturing context. */
     1041        CaptureContext       *mpVideoRecCtx;
     1042# ifdef VBOX_WITH_AUDIO_VIDEOREC
     1043        /** Pointer to capturing audio backend. */
     1044        AudioVideoRec * const mAudioVideoRec;
     1045# endif
     1046    } Capture;
     1047#endif /* VBOX_WITH_VIDEOREC */
     1048
    10301049    friend class VMTask;
    10311050    friend class ConsoleVRDPServer;
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r75072 r75251  
    3232#endif
    3333
    34 #ifdef VBOX_WITH_VIDEOREC
    35 # include "VideoRec.h"
    36 struct VIDEORECCONTEXT;
    37 #endif
    38 
    3934#include "DisplaySourceBitmapWrap.h"
    4035#include "GuestScreenInfoWrap.h"
     
    184179                                          uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBitsPerPixel,
    185180                                          uint32_t uBytesPerLine, uint32_t uGuestWidth, uint32_t uGuestHeight,
    186                                           uint8_t *pu8BufferAddress, uint64_t u64TimeStamp);
    187     /** @todo r=bird: u64TimeStamp - using the 'u64' prefix add nothing.
    188      *        However, using one of the prefixes indicating the timestamp unit
    189      *        would be very valuable!  */
    190     bool i_handleCrVRecScreenshotBegin(uint32_t uScreen, uint64_t u64TimeStamp);
    191     void i_handleCrVRecScreenshotEnd(uint32_t uScreen, uint64_t u64TimeStamp);
     181                                          uint8_t *pu8BufferAddress, uint64_t uTimestampMs);
     182    bool i_handleCrVRecScreenshotBegin(uint32_t uScreen, uint64_t uTimestampMs);
     183    void i_handleCrVRecScreenshotEnd(uint32_t uScreen, uint64_t uTimestampMs);
    192184    void i_handleVRecCompletion();
    193185#endif
     
    209201
    210202#ifdef VBOX_WITH_VIDEOREC
    211     PVIDEORECCFG             i_videoRecGetConfig(void) { return &mVideoRecCfg; }
    212     VIDEORECFEATURES         i_videoRecGetFeatures(void);
    213     bool                     i_videoRecStarted(void);
    214     void                     i_videoRecInvalidate();
    215     int                      i_videoRecSendAudio(const void *pvData, size_t cbData, uint64_t uTimestampMs);
    216     int                      i_videoRecStart(void);
    217     void                     i_videoRecStop(void);
    218     void                     i_videoRecScreenChanged(unsigned uScreenId);
     203    int  i_videoRecInvalidate(void);
     204    void i_videoRecScreenChanged(unsigned uScreenId);
    219205#endif
    220206
     
    486472    /* Serializes access to video recording source bitmaps. */
    487473    RTCRITSECT           mVideoRecLock;
    488     /** The current video recording configuration being used. */
    489     VIDEORECCFG          mVideoRecCfg;
    490     /** The video recording context. */
    491     VIDEORECCONTEXT     *mpVideoRecCtx;
    492     /** Array which defines which screens are being enabled for recording. */
     474    /** Array which defines which screens are being enabled for capturing. */
    493475    bool                 maVideoRecEnabled[SchemaDefs::MaxGuestMonitors];
    494476#endif
  • trunk/src/VBox/Main/include/DrvAudioVideoRec.h

    r74955 r75251  
    2020
    2121#include <VBox/com/ptr.h>
     22#include <VBox/settings.h>
    2223#include <VBox/vmm/pdmdrv.h>
    2324#include <VBox/vmm/pdmifs.h>
     
    4445public:
    4546
    46     int applyConfiguration(const PVIDEORECCFG pVideoRecCfg);
     47    int applyConfiguration(const settings::CaptureSettings &a_Settings);
    4748
    4849public:
     
    5859
    5960    /** Pointer to the associated video recording audio driver. */
    60     struct DRVAUDIOVIDEOREC *mpDrv;
    61     /** Video recording configuration used for configuring the driver. */
    62     struct VIDEORECCFG      mVideoRecCfg;
     61    struct DRVAUDIOVIDEOREC         *mpDrv;
     62    /** Capturing configuration used for configuring the driver. */
     63    struct settings::CaptureSettings mVideoRecCfg;
    6364};
    6465
  • trunk/src/VBox/Main/include/MachineImpl.h

    r72919 r75251  
    55
    66/*
    7  * Copyright (C) 2006-2017 Oracle Corporation
     7 * Copyright (C) 2006-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3232#include "ParallelPortImpl.h"
    3333#include "BIOSSettingsImpl.h"
     34#include "CaptureSettingsImpl.h"
    3435#include "StorageControllerImpl.h"          // required for MachineImpl.h to compile on Windows
    3536#include "USBControllerImpl.h"              // required for MachineImpl.h to compile on Windows
     
    265266        GraphicsControllerType_T mGraphicsControllerType;
    266267        ULONG               mVRAMSize;
    267         ULONG               mVideoCaptureWidth;
    268         ULONG               mVideoCaptureHeight;
    269         ULONG               mVideoCaptureRate;
    270         ULONG               mVideoCaptureFPS;
    271         ULONG               mVideoCaptureMaxTime;
    272         ULONG               mVideoCaptureMaxFileSize;
    273         Utf8Str             mVideoCaptureOptions;
    274         Utf8Str             mVideoCaptureFile;
    275         BOOL                mVideoCaptureEnabled;
    276         BOOL                maVideoCaptureScreens[SchemaDefs::MaxGuestMonitors];
     268        settings::CaptureSettings mCaptureSettings;
    277269        ULONG               mMonitorCount;
    278270        BOOL                mHWVirtExEnabled;
     
    484476        IsModified_SharedFolders        = 0x0400,
    485477        IsModified_Snapshots            = 0x0800,
    486         IsModified_BandwidthControl     = 0x1000
     478        IsModified_BandwidthControl     = 0x1000,
     479        IsModified_Capture              = 0x2000
    487480    };
    488481
     
    528521    virtual HRESULT i_onStorageDeviceChange(IMediumAttachment * /* mediumAttachment */, BOOL /* remove */,
    529522                                            BOOL /* silent */) { return S_OK; }
    530     virtual HRESULT i_onVideoCaptureChange() { return S_OK; }
     523    virtual HRESULT i_onCaptureChange() { return S_OK; }
    531524
    532525    HRESULT i_saveRegistryEntry(settings::MachineRegistryEntry &data);
     
    540533
    541534    void i_composeSavedStateFilename(Utf8Str &strStateFilePath);
    542 
    543     void i_getDefaultVideoCaptureFile(Utf8Str &strFile);
    544535
    545536    bool i_isUSBControllerPresent();
     
    783774    const ComObjPtr<USBDeviceFilters>  mUSBDeviceFilters;
    784775    const ComObjPtr<BIOSSettings>      mBIOSSettings;
     776    const ComObjPtr<CaptureSettings>   mCaptureSettings;
    785777    const ComObjPtr<BandwidthControl>  mBandwidthControl;
    786778
     
    829821    void i_deleteConfigHandler(DeleteConfigTask &task);
    830822
     823    friend class Appliance;
     824    friend class CaptureSettings;
     825    friend class CaptureScreenSettings;
    831826    friend class SessionMachine;
    832827    friend class SnapshotMachine;
    833     friend class Appliance;
    834828    friend class VirtualBox;
    835829
     
    882876    HRESULT getMonitorCount(ULONG *aMonitorCount);
    883877    HRESULT setMonitorCount(ULONG aMonitorCount);
    884     HRESULT getVideoCaptureEnabled(BOOL *aVideoCaptureEnabled);
    885     HRESULT setVideoCaptureEnabled(BOOL aVideoCaptureEnabled);
    886     HRESULT getVideoCaptureScreens(std::vector<BOOL> &aVideoCaptureScreens);
    887     HRESULT setVideoCaptureScreens(const std::vector<BOOL> &aVideoCaptureScreens);
    888     HRESULT getVideoCaptureFile(com::Utf8Str &aVideoCaptureFile);
    889     HRESULT setVideoCaptureFile(const com::Utf8Str &aVideoCaptureFile);
    890     HRESULT getVideoCaptureWidth(ULONG *aVideoCaptureWidth);
    891     HRESULT setVideoCaptureWidth(ULONG aVideoCaptureWidth);
    892     HRESULT getVideoCaptureHeight(ULONG *aVideoCaptureHeight);
    893     HRESULT setVideoCaptureHeight(ULONG aVideoCaptureHeight);
    894     HRESULT getVideoCaptureRate(ULONG *aVideoCaptureRate);
    895     HRESULT setVideoCaptureRate(ULONG aVideoCaptureRate);
    896     HRESULT getVideoCaptureFPS(ULONG *aVideoCaptureFPS);
    897     HRESULT setVideoCaptureFPS(ULONG aVideoCaptureFPS);
    898     HRESULT getVideoCaptureMaxTime(ULONG *aVideoCaptureMaxTime);
    899     HRESULT setVideoCaptureMaxTime(ULONG aVideoCaptureMaxTime);
    900     HRESULT getVideoCaptureMaxFileSize(ULONG *aVideoCaptureMaxFileSize);
    901     HRESULT setVideoCaptureMaxFileSize(ULONG aVideoCaptureMaxFileSize);
    902     HRESULT getVideoCaptureOptions(com::Utf8Str &aVideoCaptureOptions);
    903     HRESULT setVideoCaptureOptions(const com::Utf8Str &aVideoCaptureOptions);
    904878    HRESULT getBIOSSettings(ComPtr<IBIOSSettings> &aBIOSSettings);
     879    HRESULT getCaptureSettings(ComPtr<ICaptureSettings> &aCaptureSettings);
    905880    HRESULT getFirmwareType(FirmwareType_T *aFirmwareType);
    906881    HRESULT setFirmwareType(FirmwareType_T aFirmwareType);
     
    13481323    HRESULT i_onCPUChange(ULONG aCPU, BOOL aRemove);
    13491324    HRESULT i_onVRDEServerChange(BOOL aRestart);
    1350     HRESULT i_onVideoCaptureChange();
     1325    HRESULT i_onCaptureChange();
    13511326    HRESULT i_onUSBControllerChange();
    13521327    HRESULT i_onUSBDeviceAttach(IUSBDevice *aDevice,
  • trunk/src/VBox/Main/include/SessionImpl.h

    r68986 r75251  
    102102    HRESULT onCPUExecutionCapChange(ULONG aExecutionCap);
    103103    HRESULT onVRDEServerChange(BOOL aRestart);
    104     HRESULT onVideoCaptureChange();
     104    HRESULT onCaptureChange();
    105105    HRESULT onUSBControllerChange();
    106106    HRESULT onSharedFolderChange(BOOL aGlobal);
  • trunk/src/VBox/Main/include/VideoRec.h

    r75067 r75251  
    2323#include <VBox/com/VirtualBox.h>
    2424#include <VBox/err.h>
     25#include <VBox/settings.h>
    2526
    2627using namespace com;
     
    2930#include "VideoRecStream.h"
    3031
     32#if 0
    3133/**
    3234 * Enumeration for definining a video / audio
     
    5456
    5557/**
    56  * Structure for keeping a video recording configuration.
    57  */
    58 typedef struct VIDEORECCFG
     58 * Structure for keeping a screen recording configuration.
     59 */
     60typedef struct VIDEORECSCREENCFG
    5961{
    60     VIDEORECCFG(void)
    61         :  enmDst(VIDEORECDEST_INVALID)
     62    VIDEORECSCREENCFG(void)
     63        : enmDst(VIDEORECDEST_INVALID)
    6264        , uMaxTimeS(0)
    6365    {
     
    6870    }
    6971
    70     /** Array of all screens containing whether they're enabled
    71      *  for recording or not.  */
    72     com::SafeArray<BOOL>    aScreens;
     72    VIDEORECSCREENCFG& operator=(const VIDEORECSCREENCFG &that)
     73    {
     74        enmDst          = that.enmDst;
     75
     76        File.strName    = that.File.strName;
     77        File.uMaxSizeMB = that.File.uMaxSizeMB;
     78#ifdef VBOX_WITH_AUDIO_VIDEOREC
     79        Audio           = that.Audio;
     80#endif
     81        Video           = that.Video;
     82        uMaxTimeS       = that.uMaxTimeS;
     83        return *this;
     84    }
     85
     86    unsigned long           uScreenId;
    7387    /** Destination where to write the stream to. */
    7488    VIDEORECDEST            enmDst;
     
    135149
    136150    } Video;
     151
    137152    /** Maximum time (in s) to record.
    138153     *  Specify 0 to disable this check. */
    139154    uint32_t                uMaxTimeS;
    140 
    141     VIDEORECCFG& operator=(const VIDEORECCFG &that)
    142     {
    143         aScreens.resize(that.aScreens.size());
    144         for (size_t i = 0; i < that.aScreens.size(); ++i)
    145             aScreens[i] = that.aScreens[i];
    146 
    147         enmDst   = that.enmDst;
    148 
    149         File.strName    = that.File.strName;
    150         File.uMaxSizeMB = that.File.uMaxSizeMB;
    151 #ifdef VBOX_WITH_AUDIO_VIDEOREC
    152         Audio           = that.Audio;
    153 #endif
    154         Video           = that.Video;
    155         uMaxTimeS       = that.uMaxTimeS;
    156         return *this;
    157     }
    158 
    159 } VIDEORECCFG, *PVIDEORECCFG;
     155} VIDEORECSCREENCFG, *PVIDEORECSCREENCFG;
     156#endif
     157
     158class Console;
    160159
    161160/**
    162  * Structure for keeping a video recording context.
    163  */
    164 typedef struct VIDEORECCONTEXT
     161 * Class for managing a capturing context.
     162 */
     163class CaptureContext
    165164{
     165public:
     166
     167    CaptureContext(Console *pConsole);
     168
     169    CaptureContext(Console *pConsole, const settings::CaptureSettings &a_Settings);
     170
     171    virtual ~CaptureContext(void);
     172
     173public:
     174
     175    const settings::CaptureSettings &GetConfig(void) const;
     176    CaptureStream *GetStream(unsigned uScreen) const;
     177    size_t GetStreamCount(void) const;
     178
     179    int Create(const settings::CaptureSettings &a_Settings);
     180    int Destroy(void);
     181
     182    int SendAudioFrame(const void *pvData, size_t cbData, uint64_t uTimestampMs);
     183    int SendVideoFrame(uint32_t uScreen,
     184                       uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP,
     185                       uint32_t uBytesPerLine, uint32_t uSrcWidth, uint32_t uSrcHeight,
     186                       uint8_t *puSrcData, uint64_t uTimeStampMs);
     187public:
     188
     189    bool IsFeatureEnabled(CaptureFeature_T enmFeature) const;
     190    bool IsReady(void) const;
     191    bool IsReady(uint32_t uScreen, uint64_t uTimeStampMs) const;
     192    bool IsStarted(void) const;
     193    bool IsLimitReached(uint32_t uScreen, uint64_t tsNowMs) const;
     194
     195protected:
     196
     197    int createInternal(const settings::CaptureSettings &a_Settings);
     198
     199    int destroyInternal(void);
     200
     201    CaptureStream *getStreamInternal(unsigned uScreen) const;
     202
     203    static DECLCALLBACK(int) threadMain(RTTHREAD hThreadSelf, void *pvUser);
     204
     205    int threadNotify(void);
     206
     207protected:
     208
     209    /** Pointer to the console object. */
     210    Console                  *pConsole;
    166211    /** Used recording configuration. */
    167     VIDEORECCFG         Cfg;
     212    settings::CaptureSettings Settings;
    168213    /** The current state. */
    169     uint32_t            enmState;
     214    uint32_t                  enmState;
    170215    /** Critical section to serialize access. */
    171     RTCRITSECT          CritSect;
     216    RTCRITSECT                CritSect;
    172217    /** Semaphore to signal the encoding worker thread. */
    173     RTSEMEVENT          WaitEvent;
    174     /** Whether this conext is in started state or not. */
    175     bool                fStarted;
     218    RTSEMEVENT                WaitEvent;
     219    /** Whether this context is in started state or not. */
     220    bool                      fStarted;
    176221    /** Shutdown indicator. */
    177     bool                fShutdown;
     222    bool                      fShutdown;
    178223    /** Worker thread. */
    179     RTTHREAD            Thread;
     224    RTTHREAD                  Thread;
    180225    /** Vector of current recording streams.
    181226     *  Per VM screen (display) one recording stream is being used. */
    182     VideoRecStreams     vecStreams;
     227    VideoRecStreams           vecStreams;
    183228    /** Timestamp (in ms) of when recording has been started. */
    184     uint64_t            tsStartMs;
     229    uint64_t                  tsStartMs;
    185230    /** Block map of common blocks which need to get multiplexed
    186231     *  to all recording streams. This common block maps should help
     
    190235     *  For now this only affects audio, e.g. all recording streams
    191236     *  need to have the same audio data at a specific point in time. */
    192     VideoRecBlockMap    mapBlocksCommon;
    193 } VIDEORECCONTEXT, *PVIDEORECCONTEXT;
    194 
    195 int VideoRecContextCreate(uint32_t cScreens, PVIDEORECCFG pVideoRecCfg, PVIDEORECCONTEXT *ppCtx);
    196 int VideoRecContextDestroy(PVIDEORECCONTEXT pCtx);
    197 
    198 VIDEORECFEATURES VideoRecGetFeatures(PVIDEORECCFG pCfg);
    199 PVIDEORECSTREAM VideoRecGetStream(PVIDEORECCONTEXT pCtx, uint32_t uScreen);
    200 
    201 int VideoRecSendAudioFrame(PVIDEORECCONTEXT pCtx, const void *pvData, size_t cbData, uint64_t uTimestampMs);
    202 int VideoRecSendVideoFrame(PVIDEORECCONTEXT pCtx, uint32_t uScreen,
    203                             uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP,
    204                             uint32_t uBytesPerLine, uint32_t uSrcWidth, uint32_t uSrcHeight,
    205                             uint8_t *puSrcData, uint64_t uTimeStampMs);
    206 bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t uTimeStampMs);
    207 bool VideoRecIsStarted(PVIDEORECCONTEXT pCtx);
    208 bool VideoRecIsLimitReached(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t tsNowMs);
    209 
     237    VideoRecBlockMap          mapBlocksCommon;
     238};
    210239#endif /* !____H_VIDEOREC */
    211240
  • trunk/src/VBox/Main/include/VideoRecInternals.h

    r75005 r75251  
    3030
    3131/**
    32  * Enumeration for video recording destinations.
    33  */
    34 typedef enum VIDEORECDEST
    35 {
    36     /** Invalid destination, do not use. */
    37     VIDEORECDEST_INVALID = 0,
    38     /** Write to a file. */
    39     VIDEORECDEST_FILE    = 1
    40 } VIDEORECDEST;
    41 
    42 /**
    43  * Enumeration for the video recording video codec type.
    44  */
    45 typedef enum VIDEORECVIDEOCODECTYPE
    46 {
    47     /** Unknown codec type, do not use. */
    48     VIDEORECVIDEOCODECTYPE_UNKNOWN,
    49     /** Codec is VP8. */
    50     VIDEORECVIDEOCODECTYPE_VP8,
    51 # ifdef VBOX_WITH_LIBVPX_VP9
    52     /** Codec is VP9. */
    53     VIDEORECVIDEOCODECTYPE_VP9
    54 #endif
    55 } VIDEORECVIDEOCODECTYPE;
    56 
    57 /**
    5832 * Structure for keeping specific video recording codec data.
    5933 */
    6034typedef struct VIDEORECVIDEOCODEC
    6135{
    62     /** Used codec type. */
    63     VIDEORECVIDEOCODECTYPE enmType;
    6436#ifdef VBOX_WITH_LIBVPX
    6537    union
     
    7547            /** Pointer to the codec's internal YUV buffer. */
    7648            uint8_t            *pu8YuvBuf;
     49            unsigned int        uEncoderDeadline;
    7750        } VPX;
    7851    };
  • trunk/src/VBox/Main/include/VideoRecStream.h

    r75067 r75251  
    2727#include <VBox/com/VirtualBox.h>
    2828#include <VBox/err.h>
     29#include <VBox/settings.h>
    2930
    3031#include "VideoRecInternals.h"
     
    3233class WebMWriter;
    3334
    34 struct VIDEORECCFG;
    35 typedef struct VIDEORECCFG *PVIDEORECCFG;
    36 
    37 struct VIDEORECCONTEXT;
    38 typedef struct VIDEORECCONTEXT *PVIDEORECCONTEXT;
     35struct CaptureContext;
     36typedef struct CaptureContext *PVIDEORECCONTEXT;
    3937
    4038
    4139/** Structure for queuing all blocks bound to a single timecode.
    4240 *  This can happen if multiple tracks are being involved. */
    43 struct VideoRecBlocks
     41struct CaptureBlocks
    4442{
    45     virtual ~VideoRecBlocks()
     43    virtual ~CaptureBlocks()
    4644    {
    4745        Clear();
     
    7169 *  The key specifies a unique timecode, whereas the value
    7270 *  is a list of blocks which all correlate to the same key (timecode). */
    73 typedef std::map<uint64_t, VideoRecBlocks *> VideoRecBlockMap;
     71typedef std::map<uint64_t, CaptureBlocks *> VideoRecBlockMap;
    7472
    7573/**
    76  * Structure for holding a set of video recording (data) blocks.
    77  */
    78 struct VideoRecBlockSet
     74 * Structure for holding a set of recording (data) blocks.
     75 */
     76struct CaptureBlockSet
    7977{
    80     virtual ~VideoRecBlockSet()
     78    virtual ~CaptureBlockSet()
    8179    {
    8280        Clear();
     
    8482
    8583    /**
    86      * Resets a video recording block set by removing (destroying)
     84     * Resets a recording block set by removing (destroying)
    8785     * all current elements.
    8886     */
    89     void Clear()
     87    void Clear(void)
    9088    {
    9189        VideoRecBlockMap::iterator it = Map.begin();
     
    108106
    109107/**
    110  * Structure for maintaining a video recording stream.
    111  */
    112 typedef struct VIDEORECSTREAM
     108 * Class for managing a recording stream.
     109 */
     110class CaptureStream
    113111{
    114     /** Video recording context this stream is associated to. */
    115     PVIDEORECCONTEXT            pCtx;
    116     /** Destination where to write the stream to. */
    117     VIDEORECDEST                enmDst;
     112public:
     113
     114    CaptureStream(void);
     115
     116    CaptureStream(uint32_t a_uScreen, const settings::CaptureScreenSettings &a_Settings);
     117
     118    virtual ~CaptureStream(void);
     119
     120public:
     121
     122    int Init(uint32_t a_uScreen, const settings::CaptureScreenSettings &a_Settings);
     123    int Uninit(void);
     124
     125    int Process(VideoRecBlockMap &mapBlocksCommon);
     126    int SendVideoFrame(uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP, uint32_t uBytesPerLine,
     127                       uint32_t uSrcWidth, uint32_t uSrcHeight, uint8_t *puSrcData, uint64_t uTimeStampMs);
     128
     129    const settings::CaptureScreenSettings &GetConfig(void) const;
     130    bool IsLimitReached(uint64_t tsNowMs) const;
     131    bool IsReady(void) const;
     132
     133protected:
     134
     135    int open(void);
     136    int close(void);
     137
     138    int initInternal(uint32_t a_uScreen, const settings::CaptureScreenSettings &a_Settings);
     139    int uninitInternal(void);
     140
     141    int initVideo(void);
     142    int unitVideo(void);
     143
     144    int initAudio(void);
     145
     146#ifdef VBOX_WITH_LIBVPX
     147    int initVideoVPX(void);
     148    int uninitVideoVPX(void);
     149    int writeVideoVPX(uint64_t uTimeStampMs, PVIDEORECVIDEOFRAME pFrame);
     150#endif
     151    void lock(void);
     152    void unlock(void);
     153
     154    int parseOptionsString(const com::Utf8Str &strOptions);
     155
     156protected:
     157
     158    /** Recording context this stream is associated to. */
     159    CaptureContext             *pCtx;
    118160    union
    119161    {
     
    123165            RTFILE              hFile;
    124166            /** File name being used for this stream. */
    125             char               *pszFile;
     167            Utf8Str             strName;
    126168            /** Pointer to WebM writer instance being used. */
    127169            WebMWriter         *pWEBM;
    128170        } File;
    129171    };
     172    bool                fEnabled;
    130173#ifdef VBOX_WITH_AUDIO_VIDEOREC
    131174    /** Track number of audio stream. */
     
    136179    /** Screen ID. */
    137180    uint16_t            uScreenID;
    138     /** Whether video recording is enabled or not. */
    139     bool                fEnabled;
    140181    /** Critical section to serialize access. */
    141182    RTCRITSECT          CritSect;
     183    /** Timestamp (in ms) of when recording has been start. */
     184    uint64_t            tsStartMs;
    142185
    143186    struct
    144187    {
    145         /** Codec-specific data. */
    146         VIDEORECVIDEOCODEC  Codec;
    147188        /** Minimal delay (in ms) between two video frames.
    148189         *  This value is based on the configured FPS rate. */
    149190        uint32_t            uDelayMs;
    150         /** Target X resolution (in pixels). */
    151         uint32_t            uWidth;
    152         /** Target Y resolution (in pixels). */
    153         uint32_t            uHeight;
    154191        /** Time stamp (in ms) of the last video frame we encoded. */
    155192        uint64_t            uLastTimeStampMs;
    156193        /** Number of failed attempts to encode the current video frame in a row. */
    157194        uint16_t            cFailedEncodingFrames;
     195        VIDEORECVIDEOCODEC  Codec;
    158196    } Video;
    159197
     198    settings::CaptureScreenSettings Settings;
    160199    /** Common set of video recording (data) blocks, needed for
    161200     *  multiplexing to all recording streams. */
    162     VideoRecBlockSet Blocks;
    163 } VIDEORECSTREAM, *PVIDEORECSTREAM;
     201    CaptureBlockSet                Blocks;
     202};
    164203
    165204/** Vector of video recording streams. */
    166 typedef std::vector <PVIDEORECSTREAM> VideoRecStreams;
    167 
    168 int VideoRecStreamClose(PVIDEORECSTREAM pStream);
    169 int VideoRecStreamOpen(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg);
    170 int VideoRecStreamProcess(PVIDEORECSTREAM pStream);
    171 int VideoRecStreamInit(PVIDEORECSTREAM pStream, PVIDEORECCONTEXT pCtx, uint32_t uScreen);
    172 int VideoRecStreamUninit(PVIDEORECSTREAM pStream);
    173 int VideoRecStreamUnitVideo(PVIDEORECSTREAM pStream);
    174 int VideoRecStreamInitVideo(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg);
    175 #ifdef VBOX_WITH_LIBVPX
    176 int VideoRecStreamInitVideoVPX(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg);
    177 int VideoRecStreamUninitVideoVPX(PVIDEORECSTREAM pStream);
    178 int VideoRecStreamWriteVideoVPX(PVIDEORECSTREAM pStream, uint64_t uTimeStampMs, PVIDEORECVIDEOFRAME pFrame);
    179 #endif
    180 void VideoRecStreamLock(PVIDEORECSTREAM pStream);
    181 void VideoRecStreamUnlock(PVIDEORECSTREAM pStream);
     205typedef std::vector <CaptureStream *> VideoRecStreams;
    182206
    183207#endif /* ____H_VIDEOREC_STREAM */
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r75167 r75251  
    402402    , m_pVMMDev(NULL)
    403403    , mAudioVRDE(NULL)
    404 #ifdef VBOX_WITH_AUDIO_VIDEOREC
    405     , mAudioVideoRec(NULL)
    406 #endif
    407404    , mNvram(NULL)
    408405#ifdef VBOX_WITH_USB_CARDREADER
     
    590587#endif
    591588#ifdef VBOX_WITH_AUDIO_VIDEOREC
    592         unconst(mAudioVideoRec) = new AudioVideoRec(this);
    593         AssertReturn(mAudioVideoRec, E_FAIL);
     589        unconst(Capture.mAudioVideoRec) = new AudioVideoRec(this);
     590        AssertReturn(Capture.mAudioVideoRec, E_FAIL);
    594591#endif
    595592        FirmwareType_T enmFirmwareType;
     
    738735
    739736#ifdef VBOX_WITH_AUDIO_VIDEOREC
    740     if (mAudioVideoRec)
    741     {
    742         delete mAudioVideoRec;
    743         unconst(mAudioVideoRec) = NULL;
     737    if (Capture.mAudioVideoRec)
     738    {
     739        delete Capture.mAudioVideoRec;
     740        unconst(Capture.mAudioVideoRec) = NULL;
    744741    }
    745742#endif
     
    56195616    if (pDisplay)
    56205617    {
    5621         if (RT_BOOL(fEnable) != pDisplay->i_videoRecStarted())
     5618        if (RT_BOOL(fEnable) != Capture.mpVideoRecCtx->IsStarted())
    56225619        {
    56235620            LogRel(("VideoRec: %s\n", fEnable ? "Enabling" : "Disabling"));
     
    56295626# ifdef VBOX_WITH_AUDIO_VIDEOREC
    56305627                /* Attach the video recording audio driver if required. */
    5631                 if (   pDisplay->i_videoRecGetFeatures() & VIDEORECFEATURE_AUDIO
    5632                     && mAudioVideoRec)
     5628                if (   Capture.mpVideoRecCtx->IsFeatureEnabled(CaptureFeature_Audio)
     5629                    && Capture.mAudioVideoRec)
    56335630                {
    5634                     vrc = mAudioVideoRec->applyConfiguration(pDisplay->i_videoRecGetConfig());
     5631                    vrc = Capture.mAudioVideoRec->applyConfiguration(Capture.mpVideoRecCtx->GetConfig());
    56355632                    if (RT_SUCCESS(vrc))
    5636                         vrc = mAudioVideoRec->doAttachDriverViaEmt(mpUVM, pAutoLock);
     5633                        vrc = Capture.mAudioVideoRec->doAttachDriverViaEmt(mpUVM, pAutoLock);
    56375634                }
    56385635# endif
    56395636                if (   RT_SUCCESS(vrc)
    5640                     && pDisplay->i_videoRecGetFeatures()) /* Any video recording (audio and/or video) feature enabled? */
     5637                    && Capture.mpVideoRecCtx->IsReady()) /* Any video recording (audio and/or video) feature enabled? */
    56415638                {
    5642                     vrc = pDisplay->i_videoRecStart();
     5639                    vrc = i_videoRecStart();
    56435640                }
    56445641            }
    56455642            else
    56465643            {
    5647                 mDisplay->i_videoRecStop();
     5644                i_videoRecStop();
    56485645# ifdef VBOX_WITH_AUDIO_VIDEOREC
    5649                 mAudioVideoRec->doDetachDriverViaEmt(mpUVM, pAutoLock);
     5646                Capture.mAudioVideoRec->doDetachDriverViaEmt(mpUVM, pAutoLock);
    56505647# endif
    56515648            }
     
    56625659#endif /* VBOX_WITH_VIDEOREC */
    56635660
    5664 HRESULT Console::i_onVideoCaptureChange()
     5661HRESULT Console::i_onCaptureChange()
    56655662{
    56665663    AutoCaller autoCaller(this);
     
    56755672    if (ptrVM.isOk())
    56765673    {
     5674        ComPtr<ICaptureSettings> CaptureSettings;
     5675        rc = mMachine->COMGETTER(CaptureSettings)(CaptureSettings.asOutParam());
     5676        AssertComRCReturnRC(rc);
     5677
    56775678        BOOL fEnabled;
    5678         rc = mMachine->COMGETTER(VideoCaptureEnabled)(&fEnabled);
     5679        rc = CaptureSettings->COMGETTER(Enabled)(&fEnabled);
    56795680        AssertComRCReturnRC(rc);
    56805681
     
    56835684        {
    56845685            alock.release();
    5685             fireVideoCaptureChangedEvent(mEventSource);
     5686            fireCaptureChangedEvent(mEventSource);
    56865687        }
    56875688
     
    68676868 * @param   uTimestampMs        Timestamp (in ms) of audio data.
    68686869 */
    6869 HRESULT Console::i_audioVideoRecSendAudio(const void *pvData, size_t cbData, uint64_t uTimestampMs)
    6870 {
    6871     if (mDisplay)
    6872     {
    6873         int rc2 = mDisplay->i_videoRecSendAudio(pvData, cbData, uTimestampMs);
    6874         AssertRC(rc2);
     6870HRESULT Console::i_videoRecSendAudio(const void *pvData, size_t cbData, uint64_t uTimestampMs)
     6871{
     6872    if (!Capture.mpVideoRecCtx)
     6873        return S_OK;
     6874
     6875    if (   Capture.mpVideoRecCtx->IsStarted()
     6876        && Capture.mpVideoRecCtx->IsFeatureEnabled(CaptureFeature_Audio))
     6877    {
     6878        return Capture.mpVideoRecCtx->SendAudioFrame(pvData, cbData, uTimestampMs);
    68756879    }
    68766880
     
    68786882}
    68796883#endif /* VBOX_WITH_AUDIO_VIDEOREC */
     6884
     6885#ifdef VBOX_WITH_VIDEOREC
     6886int Console::i_videoRecLoad(settings::CaptureSettings &Settings)
     6887{
     6888    Assert(mMachine.isNotNull());
     6889
     6890    ComPtr<ICaptureSettings> pCaptureSettings;
     6891    HRESULT hrc = mMachine->COMGETTER(CaptureSettings)(pCaptureSettings.asOutParam());
     6892    AssertComRCReturn(hrc, VERR_INVALID_PARAMETER);
     6893
     6894    SafeIfaceArray<ICaptureScreenSettings> paCaptureScreens;
     6895    hrc = pCaptureSettings->GetScreens(ComSafeArrayAsOutParam(paCaptureScreens));
     6896    AssertComRCReturn(hrc, VERR_INVALID_PARAMETER);
     6897
     6898    Settings.mapScreens.clear();
     6899
     6900    for (size_t i = 0; i < paCaptureScreens.size(); ++i)
     6901    {
     6902        settings::CaptureScreenSettings CaptureScreenSettings;
     6903        ComPtr<ICaptureScreenSettings> pCaptureScreenSettings = paCaptureScreens[i];
     6904
     6905        hrc = pCaptureScreenSettings->COMGETTER(MaxTime)((ULONG *)&CaptureScreenSettings.ulMaxTimeS);
     6906        AssertComRCReturn(hrc, VERR_INVALID_PARAMETER);
     6907        hrc = pCaptureScreenSettings->COMGETTER(MaxFileSize)((ULONG *)&CaptureScreenSettings.File.ulMaxSizeMB);
     6908        AssertComRCReturn(hrc, VERR_INVALID_PARAMETER);
     6909        Bstr bstrTemp;
     6910        hrc = pCaptureScreenSettings->COMGETTER(FileName)(bstrTemp.asOutParam());
     6911        AssertComRCReturn(hrc, VERR_INVALID_PARAMETER);
     6912        CaptureScreenSettings.File.strName = bstrTemp;
     6913        hrc = pCaptureScreenSettings->COMGETTER(Options)(bstrTemp.asOutParam());
     6914        AssertComRCReturn(hrc, VERR_INVALID_PARAMETER);
     6915        CaptureScreenSettings.strOptions = bstrTemp;
     6916        hrc = pCaptureScreenSettings->COMGETTER(VideoWidth)((ULONG *)&CaptureScreenSettings.Video.ulWidth);
     6917        AssertComRCReturn(hrc, VERR_INVALID_PARAMETER);
     6918        hrc = pCaptureScreenSettings->COMGETTER(VideoHeight)((ULONG *)&CaptureScreenSettings.Video.ulHeight);
     6919        AssertComRCReturn(hrc, VERR_INVALID_PARAMETER);
     6920        hrc = pCaptureScreenSettings->COMGETTER(VideoRate)((ULONG *)&CaptureScreenSettings.Video.ulRate);
     6921        AssertComRCReturn(hrc, VERR_INVALID_PARAMETER);
     6922        hrc = pCaptureScreenSettings->COMGETTER(VideoFPS)((ULONG *)&CaptureScreenSettings.Video.ulFPS);
     6923        AssertComRCReturn(hrc, VERR_INVALID_PARAMETER);
     6924
     6925        Settings.mapScreens[i] = CaptureScreenSettings;
     6926    }
     6927
     6928    return VINF_SUCCESS;
     6929}
     6930
     6931/**
     6932 * Starts capturing. Does nothing if capturing is already active.
     6933 *
     6934 * @returns IPRT status code.
     6935 */
     6936int Console::i_videoRecStart(void)
     6937{
     6938    if (Capture.mpVideoRecCtx && Capture.mpVideoRecCtx->IsStarted())
     6939        return VINF_SUCCESS;
     6940
     6941    LogRel(("VideoRec: Starting ...\n"));
     6942
     6943    try
     6944    {
     6945        Capture.mpVideoRecCtx = new CaptureContext(this);
     6946    }
     6947    catch (std::bad_alloc &)
     6948    {
     6949        return VERR_NO_MEMORY;
     6950    }
     6951    catch (int &rc)
     6952    {
     6953        return rc;
     6954    }
     6955
     6956    settings::CaptureSettings Settings;
     6957    int rc = i_videoRecLoad(Settings);
     6958    if (RT_SUCCESS(rc))
     6959    {
     6960        rc = Capture.mpVideoRecCtx->Create(Settings);
     6961        if (RT_SUCCESS(rc))
     6962        {
     6963            for (unsigned uScreen = 0; uScreen < Capture.mpVideoRecCtx->GetStreamCount(); uScreen++)
     6964                mDisplay->i_videoRecScreenChanged(uScreen);
     6965        }
     6966    }
     6967
     6968    if (RT_FAILURE(rc))
     6969        LogRel(("VideoRec: Failed to start video recording (%Rrc)\n", rc));
     6970
     6971    return rc;
     6972}
     6973
     6974/**
     6975 * Stops capturing. Does nothing if capturing is not active.
     6976 */
     6977int Console::i_videoRecStop(void)
     6978{
     6979    if (Capture.mpVideoRecCtx && Capture.mpVideoRecCtx->IsStarted())
     6980        return VINF_SUCCESS;
     6981
     6982    LogRel(("VideoRec: Stopping ...\n"));
     6983
     6984    const size_t cStreams = Capture.mpVideoRecCtx->GetStreamCount();
     6985
     6986    for (unsigned uScreen = 0; uScreen < cStreams; ++uScreen)
     6987        mDisplay->i_videoRecScreenChanged(uScreen);
     6988
     6989    delete Capture.mpVideoRecCtx;
     6990    Capture.mpVideoRecCtx = NULL;
     6991
     6992    ComPtr<ICaptureSettings> pCaptureSettings;
     6993    HRESULT hrc = mMachine->COMGETTER(CaptureSettings)(pCaptureSettings.asOutParam());
     6994    ComAssertComRC(hrc);
     6995    hrc = pCaptureSettings->COMSETTER(Enabled)(false);
     6996    ComAssertComRC(hrc);
     6997
     6998    LogRel(("VideoRec: Stopped\n"));
     6999
     7000    return VINF_SUCCESS;
     7001}
     7002#endif /* VBOX_WITH_VIDEOREC */
    68807003
    68817004/**
     
    996610089
    996710090#ifdef VBOX_WITH_VIDEOREC
    9968         BOOL fVideoRecEnabled = FALSE;
    9969         rc = pConsole->mMachine->COMGETTER(VideoCaptureEnabled)(&fVideoRecEnabled);
     10091        ComPtr<ICaptureSettings> CaptureSettings;
     10092        rc = pConsole->mMachine->COMGETTER(CaptureSettings)(CaptureSettings.asOutParam());
    997010093        AssertComRCReturnVoid(rc);
    997110094
    9972         if (fVideoRecEnabled)
    9973         {
    9974             int vrc2 = pConsole->i_videoCaptureEnable(fVideoRecEnabled, &alock);
     10095        BOOL fCaptureEnabled;
     10096        rc = CaptureSettings->COMGETTER(Enabled)(&fCaptureEnabled);
     10097        AssertComRCReturnVoid(rc);
     10098
     10099        if (fCaptureEnabled)
     10100        {
     10101            int vrc2 = pConsole->i_videoCaptureEnable(fCaptureEnabled, &alock);
    997510102            if (RT_SUCCESS(vrc2))
    997610103            {
    9977                 fireVideoCaptureChangedEvent(pConsole->mEventSource);
     10104                fireCaptureChangedEvent(pConsole->mEventSource);
    997810105            }
    997910106            else
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r74474 r75251  
    29982998                InsertConfigString(pLunL0, "Driver", "AUDIO");
    29992999            AudioDriverCfg DrvCfgVideoRec(strAudioDevice, 0 /* Instance */, uAudioLUN, "AudioVideoRec");
    3000             rc = mAudioVideoRec->InitializeConfig(&DrvCfgVideoRec);
     3000            rc = Capture.mAudioVideoRec->InitializeConfig(&DrvCfgVideoRec);
    30013001            if (RT_SUCCESS(rc))
    30023002                uAudioLUN++;
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r75067 r75251  
    150150    AssertRC(rc);
    151151
    152     mpVideoRecCtx = NULL;
    153152    for (unsigned i = 0; i < RT_ELEMENTS(maVideoRecEnabled); i++)
    154153        maVideoRecEnabled[i] = true;
     
    24082407#ifdef VBOX_WITH_VIDEOREC
    24092408/**
    2410  * Returns the currently enabled video capturing features.
     2409 * Invalidates the capturing configuration.
    24112410 *
    2412  * @returns Enables video capturing features.
     2411 * @returns IPRT status code.
    24132412 */
    2414 VIDEORECFEATURES Display::i_videoRecGetFeatures(void)
    2415 {
    2416     return VideoRecGetFeatures(&mVideoRecCfg);
    2417 }
    2418 
    2419 /**
    2420  * Returns whether video capturing is currently is active or not.
    2421  *
    2422  * @returns True if video capturing is active, false if not.
    2423  */
    2424 bool Display::i_videoRecStarted(void)
    2425 {
    2426     return VideoRecIsStarted(mpVideoRecCtx);
    2427 }
    2428 
    2429 /**
    2430  * Invalidates the video recording configuration.
    2431  */
    2432 void Display::i_videoRecInvalidate(void)
    2433 {
    2434     AssertPtr(mParent);
    2435     ComPtr<IMachine> pMachine = mParent->i_machine();
    2436     Assert(pMachine.isNotNull());
    2437 
    2438     mVideoRecCfg.enmDst = VIDEORECDEST_FILE; /** @todo Make this configurable once we have more variations. */
    2439 
    2440     /*
    2441      * Cache parameters from API.
    2442      */
    2443     com::SafeArray<BOOL> aScreens;
    2444     HRESULT hrc = pMachine->COMGETTER(VideoCaptureScreens)(ComSafeArrayAsOutParam(aScreens));
    2445     AssertComRCReturnVoid(hrc);
    2446 
    2447     mVideoRecCfg.aScreens.resize(aScreens.size());
    2448     for (size_t i = 0; i < aScreens.size(); ++i)
    2449         mVideoRecCfg.aScreens[i] = aScreens[i];
    2450 
    2451     hrc = pMachine->COMGETTER(VideoCaptureWidth)((ULONG *)&mVideoRecCfg.Video.uWidth);
    2452     AssertComRCReturnVoid(hrc);
    2453     hrc = pMachine->COMGETTER(VideoCaptureHeight)((ULONG *)&mVideoRecCfg.Video.uHeight);
    2454     AssertComRCReturnVoid(hrc);
    2455     hrc = pMachine->COMGETTER(VideoCaptureRate)((ULONG *)&mVideoRecCfg.Video.uRate);
    2456     AssertComRCReturnVoid(hrc);
    2457     hrc = pMachine->COMGETTER(VideoCaptureFPS)((ULONG *)&mVideoRecCfg.Video.uFPS);
    2458     AssertComRCReturnVoid(hrc);
    2459     hrc = pMachine->COMGETTER(VideoCaptureFile)(mVideoRecCfg.File.strName.asOutParam());
    2460     AssertComRCReturnVoid(hrc);
    2461     hrc = pMachine->COMGETTER(VideoCaptureMaxFileSize)((ULONG *)&mVideoRecCfg.File.uMaxSizeMB);
    2462     AssertComRCReturnVoid(hrc);
    2463     hrc = pMachine->COMGETTER(VideoCaptureMaxTime)((ULONG *)&mVideoRecCfg.uMaxTimeS);
    2464     AssertComRCReturnVoid(hrc);
    2465     BSTR bstrOptions;
    2466     hrc = pMachine->COMGETTER(VideoCaptureOptions)(&bstrOptions);
    2467     AssertComRCReturnVoid(hrc);
    2468 
    2469     /*
    2470      * Set sensible defaults.
    2471      */
    2472     mVideoRecCfg.Video.fEnabled = true; /* Enabled by default. */
    2473 
    2474     if (!mVideoRecCfg.Video.uFPS) /* Prevent division by zero. */
    2475         mVideoRecCfg.Video.uFPS = 15;
    2476 
    2477 #ifdef VBOX_WITH_LIBVPX
    2478     mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = 1000000 / mVideoRecCfg.Video.uFPS;
    2479 #endif
    2480 
    2481 #ifdef VBOX_WITH_AUDIO_VIDEOREC
    2482     mVideoRecCfg.Audio.fEnabled  = false; /* Disabled by default, unless set otherwise below. */
    2483     /* By default we use 22,5kHz, 16-bit, stereo for the audio track. */
    2484     mVideoRecCfg.Audio.uHz       = 22050;
    2485     mVideoRecCfg.Audio.cBits     = 16;
    2486     mVideoRecCfg.Audio.cChannels = 2;
    2487 #endif
    2488 
    2489     /*
    2490      * Parse options string.
    2491      */
    2492     com::Utf8Str strOptions(bstrOptions);
    2493     size_t pos = 0;
    2494     com::Utf8Str key, value;
    2495     while ((pos = strOptions.parseKeyValue(key, value, pos)) != com::Utf8Str::npos)
    2496     {
    2497         if (key.compare("vc_quality", Utf8Str::CaseInsensitive) == 0)
    2498         {
    2499 #ifdef VBOX_WITH_LIBVPX
    2500             if (value.compare("realtime", Utf8Str::CaseInsensitive) == 0)
    2501                 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = VPX_DL_REALTIME;
    2502             else if (value.compare("good", Utf8Str::CaseInsensitive) == 0)
    2503                 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = 1000000 / mVideoRecCfg.Video.uFPS;
    2504             else if (value.compare("best", Utf8Str::CaseInsensitive) == 0)
    2505                 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = VPX_DL_BEST_QUALITY;
    2506             else
    2507             {
    2508                 LogRel(("VideoRec: Setting quality deadline to '%s'\n", value.c_str()));
    2509                 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = value.toUInt32();
    2510 #endif
    2511             }
    2512         }
    2513         else if (key.compare("vc_enabled", Utf8Str::CaseInsensitive) == 0)
    2514         {
    2515             if (value.compare("false", Utf8Str::CaseInsensitive) == 0)
    2516             {
    2517                 mVideoRecCfg.Video.fEnabled = false;
    2518 #ifdef VBOX_WITH_AUDIO_VIDEOREC
    2519                 LogRel(("VideoRec: Only audio will be recorded\n"));
    2520 #endif
    2521             }
    2522         }
    2523         else if (key.compare("ac_enabled", Utf8Str::CaseInsensitive) == 0)
    2524         {
    2525 #ifdef VBOX_WITH_AUDIO_VIDEOREC
    2526             if (value.compare("true", Utf8Str::CaseInsensitive) == 0)
    2527             {
    2528                 mVideoRecCfg.Audio.fEnabled = true;
    2529 
    2530             }
    2531             else
    2532                 LogRel(("VideoRec: Only video will be recorded\n"));
    2533 #endif
    2534         }
    2535         else if (key.compare("ac_profile", Utf8Str::CaseInsensitive) == 0)
    2536         {
    2537 #ifdef VBOX_WITH_AUDIO_VIDEOREC
    2538             if (value.compare("low", Utf8Str::CaseInsensitive) == 0)
    2539             {
    2540                 mVideoRecCfg.Audio.uHz       = 8000;
    2541                 mVideoRecCfg.Audio.cBits     = 16;
    2542                 mVideoRecCfg.Audio.cChannels = 1;
    2543             }
    2544             else if (value.startsWith("med" /* "med[ium]" */, Utf8Str::CaseInsensitive) == 0)
    2545             {
    2546                 /* Stay with the default set above. */
    2547             }
    2548             else if (value.compare("high", Utf8Str::CaseInsensitive) == 0)
    2549             {
    2550                 mVideoRecCfg.Audio.uHz       = 48000;
    2551                 mVideoRecCfg.Audio.cBits     = 16;
    2552                 mVideoRecCfg.Audio.cChannels = 2;
    2553             }
    2554 #endif
    2555         }
    2556         else
    2557             LogRel(("VideoRec: Unknown option '%s' (value '%s'), skipping\n", key.c_str(), value.c_str()));
    2558 
    2559     } /* while */
     2413int Display::i_videoRecInvalidate(void)
     2414{
     2415    CaptureContext *pCtx = mParent->i_videoRecGetContext();
     2416    if (!pCtx || !pCtx->IsStarted())
     2417        return VINF_SUCCESS;
    25602418
    25612419    /*
    25622420     * Invalidate screens.
    25632421     */
    2564     for (unsigned i = 0; i < mVideoRecCfg.aScreens.size(); i++)
    2565     {
    2566         bool fChanged = maVideoRecEnabled[i] != RT_BOOL(mVideoRecCfg.aScreens[i]);
    2567 
    2568         maVideoRecEnabled[i] = RT_BOOL(mVideoRecCfg.aScreens[i]);
    2569 
    2570         if (fChanged && i < mcMonitors)
    2571             i_videoRecScreenChanged(i);
    2572 
    2573     }
    2574 }
    2575 
    2576 /**
    2577  * Sends belonging audio samples to the video capturing code.
    2578  * Does nothing if capturing is disabled or if audio support for video capturing is disabled.
    2579  *
    2580  * @returns IPRT status code.
    2581  * @param   pvData              Audio data.
    2582  * @param   cbData              Size (in bytes) of audio data.
    2583  * @param   uTimestampMs        Timestamp (in ms) of the audio data.
    2584  */
    2585 int Display::i_videoRecSendAudio(const void *pvData, size_t cbData, uint64_t uTimestampMs)
    2586 {
    2587     if (   VideoRecIsStarted(mpVideoRecCtx)
    2588         && VideoRecGetFeatures(&mVideoRecCfg) & VIDEORECFEATURE_AUDIO)
    2589     {
    2590         return VideoRecSendAudioFrame(mpVideoRecCtx, pvData, cbData, uTimestampMs);
     2422    for (unsigned uScreen = 0; uScreen < mcMonitors; uScreen++)
     2423    {
     2424        CaptureStream *pCaptureStream = pCtx->GetStream(uScreen);
     2425
     2426        const bool fStreamEnabled = pCaptureStream->IsReady();
     2427              bool fChanged       = maVideoRecEnabled[uScreen] != fStreamEnabled;
     2428
     2429        maVideoRecEnabled[uScreen] = fStreamEnabled;
     2430
     2431        if (fChanged && uScreen < mcMonitors)
     2432            i_videoRecScreenChanged(uScreen);
    25912433    }
    25922434
     
    25942436}
    25952437
    2596 /**
    2597  * Start video capturing. Does nothing if capturing is already active.
    2598  *
    2599  * @param   pVideoRecCfg        Video recording configuration to use.
    2600  * @returns IPRT status code.
    2601  */
    2602 int Display::i_videoRecStart(void)
    2603 {
    2604     if (VideoRecIsStarted(mpVideoRecCtx))
    2605         return VINF_SUCCESS;
    2606 
    2607     LogRel(("VideoRec: Starting ...\n"));
    2608 
    2609     int rc = VideoRecContextCreate(mcMonitors, &mVideoRecCfg, &mpVideoRecCtx);
    2610     if (RT_SUCCESS(rc))
    2611     {
    2612         for (unsigned uScreen = 0; uScreen < mcMonitors; uScreen++)
    2613         {
    2614             int rc2 = VideoRecStreamInit(VideoRecGetStream(mpVideoRecCtx, uScreen), mpVideoRecCtx, uScreen);
    2615             if (RT_SUCCESS(rc2))
    2616             {
    2617                 i_videoRecScreenChanged(uScreen);
    2618             }
    2619             else
    2620                 LogRel(("VideoRec: Failed to initialize video recording context #%u (%Rrc)\n", uScreen, rc2));
    2621 
    2622             if (RT_SUCCESS(rc))
    2623                 rc = rc2;
    2624         }
    2625     }
    2626 
    2627     if (RT_FAILURE(rc))
    2628         LogRel(("VideoRec: Failed to start video recording (%Rrc)\n", rc));
    2629 
    2630     return rc;
    2631 }
    2632 
    2633 /**
    2634  * Stops video capturing. Does nothing if video capturing is not active.
    2635  */
    2636 void Display::i_videoRecStop(void)
    2637 {
    2638     if (!VideoRecIsStarted(mpVideoRecCtx))
    2639         return;
    2640 
    2641     LogRel(("VideoRec: Stopping ...\n"));
    2642 
    2643     VideoRecContextDestroy(mpVideoRecCtx);
    2644     mpVideoRecCtx = NULL;
    2645 
    2646     unsigned uScreenId;
    2647     for (uScreenId = 0; uScreenId < mcMonitors; ++uScreenId)
    2648         i_videoRecScreenChanged(uScreenId);
    2649 }
    2650 
    26512438void Display::i_videoRecScreenChanged(unsigned uScreenId)
    26522439{
    2653     if (   !VideoRecIsStarted(mpVideoRecCtx)
    2654         || !maVideoRecEnabled[uScreenId])
     2440    CaptureContext *pCtx = mParent->i_videoRecGetContext();
     2441
     2442    if (   RT_LIKELY(!maVideoRecEnabled[uScreenId])
     2443        || !pCtx || !pCtx->IsStarted())
    26552444    {
    26562445        /* Skip recording this screen. */
     
    35993388
    36003389#ifdef VBOX_WITH_VIDEOREC
    3601     if (   VideoRecIsStarted(pDisplay->mpVideoRecCtx)
    3602         && VideoRecGetFeatures(&pDisplay->mVideoRecCfg) & VIDEORECFEATURE_VIDEO)
     3390    AssertPtr(pDisplay->mParent);
     3391    CaptureContext *pCtx = pDisplay->mParent->i_videoRecGetContext();
     3392
     3393    if (   pCtx
     3394        && pCtx->IsStarted()
     3395        && pCtx->IsFeatureEnabled(CaptureFeature_Video))
    36033396    {
    36043397        do {
     
    36383431# endif /* VBOX_WITH_HGCM && VBOX_WITH_CROGL */
    36393432
    3640             uint64_t u64Now = RTTimeProgramMilliTS();
     3433            uint64_t tsNowMs = RTTimeProgramMilliTS();
    36413434            for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++)
    36423435            {
     
    36443437                    continue;
    36453438
    3646                 if (VideoRecIsLimitReached(pDisplay->mpVideoRecCtx, uScreenId, u64Now))
     3439                if (pCtx->IsLimitReached(uScreenId, tsNowMs))
    36473440                {
    3648                     pDisplay->i_videoRecStop();
    3649                     pDisplay->mParent->i_machine()->COMSETTER(VideoCaptureEnabled)(false);
     3441                    pDisplay->mParent->i_videoRecStop();
    36503442                    break;
    36513443                }
     
    36773469                                                                    &bitmapFormat);
    36783470                        if (SUCCEEDED(hr) && pbAddress)
    3679                             rc = VideoRecSendVideoFrame(pDisplay->mpVideoRecCtx, uScreenId, 0, 0,
    3680                                                         BitmapFormat_BGR,
    3681                                                         ulBitsPerPixel, ulBytesPerLine, ulWidth, ulHeight,
    3682                                                         pbAddress, u64Now);
     3471                            rc = pCtx->SendVideoFrame(uScreenId, 0, 0, BitmapFormat_BGR,
     3472                                                      ulBitsPerPixel, ulBytesPerLine, ulWidth, ulHeight,
     3473                                                      pbAddress, tsNowMs);
    36833474                        else
    36843475                            rc = VERR_NOT_SUPPORTED;
     
    40393830}
    40403831
    4041 bool  Display::i_handleCrVRecScreenshotBegin(uint32_t uScreen, uint64_t u64Timestamp)
    4042 {
    4043     /** @todo r=bird: u64Timestamp - using the 'u64' prefix add nothing.
    4044      *        However, using one of the prefixes indicating the timestamp unit
    4045      *        would be very valuable!  */
     3832bool  Display::i_handleCrVRecScreenshotBegin(uint32_t uScreen, uint64_t uTimestampMs)
     3833{
    40463834# ifdef VBOX_WITH_VIDEOREC
    4047     return VideoRecIsReady(mpVideoRecCtx, uScreen, u64Timestamp);
     3835    CaptureContext *pCtx = mParent->i_videoRecGetContext();
     3836    return (      pCtx
     3837               && pCtx->IsReady(uScreen, uTimestampMs));
    40483838# else
    4049     RT_NOREF(uScreen, u64Timestamp);
     3839    RT_NOREF(uScreen, uTimestampMs);
    40503840    return false;
    40513841# endif
    40523842}
    40533843
    4054 void  Display::i_handleCrVRecScreenshotEnd(uint32_t uScreen, uint64_t u64Timestamp)
    4055 {
    4056     RT_NOREF(uScreen, u64Timestamp);
     3844void  Display::i_handleCrVRecScreenshotEnd(uint32_t uScreen, uint64_t uTimestampMs)
     3845{
     3846    RT_NOREF(uScreen, uTimestampMs);
    40573847}
    40583848
     
    40613851                                               uint32_t uBitsPerPixel, uint32_t uBytesPerLine,
    40623852                                               uint32_t uGuestWidth, uint32_t uGuestHeight,
    4063                                                uint8_t *pu8BufferAddress, uint64_t u64Timestamp)
     3853                                               uint8_t *pu8BufferAddress, uint64_t uTimestampMs)
    40643854{
    40653855    Assert(mfCrOglVideoRecState == CRVREC_STATE_SUBMITTED);
    40663856# ifdef VBOX_WITH_VIDEOREC
    4067     if (   VideoRecIsStarted(mpVideoRecCtx)
    4068         && VideoRecGetFeatures(&mVideoRecCfg) & VIDEORECFEATURE_VIDEO)
    4069     {
    4070         int rc2 = VideoRecSendVideoFrame(mpVideoRecCtx, uScreen, x, y,
    4071                                          uPixelFormat,
    4072                                          uBitsPerPixel, uBytesPerLine,
    4073                                          uGuestWidth, uGuestHeight,
    4074                                          pu8BufferAddress, u64Timestamp);
     3857    CaptureContext *pCtx = mParent->i_videoRecGetContext();
     3858
     3859    if (   pCtx
     3860        && pCtx->IsStarted()
     3861        && pCtx->IsFeatureEnabled(CaptureFeature_Video))
     3862    {
     3863        int rc2 = pCtx->SendVideoFrame(uScreen, x, y,
     3864                                       uPixelFormat,
     3865                                       uBitsPerPixel, uBytesPerLine,
     3866                                       uGuestWidth, uGuestHeight,
     3867                                       pu8BufferAddress, uTimestampMs);
    40753868        RT_NOREF(rc2);
    40763869        Assert(rc2 == VINF_SUCCESS /* || rc == VERR_TRY_AGAIN || rc == VINF_TRY_AGAIN*/);
     
    40783871# else
    40793872    RT_NOREF(uScreen, x, y, uPixelFormat, \
    4080              uBitsPerPixel, uBytesPerLine, uGuestWidth, uGuestHeight, pu8BufferAddress, u64Timestamp);
     3873             uBitsPerPixel, uBytesPerLine, uGuestWidth, uGuestHeight, pu8BufferAddress, uTimestampMs);
    40813874# endif /* VBOX_WITH_VIDEOREC */
    40823875}
     
    47064499        AutoWriteLock displayLock(pThis->pDisplay COMMA_LOCKVAL_SRC_POS);
    47074500#ifdef VBOX_WITH_VIDEOREC
    4708         pThis->pDisplay->i_videoRecStop();
     4501        pThis->pDisplay->mParent->i_videoRecStop();
    47094502#endif
    47104503#ifdef VBOX_WITH_CRHGSMI
  • trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp

    r75083 r75251  
    828828                case AVRECCONTAINERTYPE_MAIN_CONSOLE:
    829829                {
    830                     HRESULT hr = pSink->Con.Main.pConsole->i_audioVideoRecSendAudio(pStreamAV->pvDstBuf, cbDst, uPTSMs);
     830                    HRESULT hr = pSink->Con.Main.pConsole->i_videoRecSendAudio(pStreamAV->pvDstBuf, cbDst, uPTSMs);
    831831                    Assert(hr == S_OK);
    832832                    RT_NOREF(hr);
     
    10861086 *
    10871087 * @returns IPRT status code.
    1088  * @param   pVideoRecCfg        Pointer to video recording configuration to apply.
    1089  */
    1090 int AudioVideoRec::applyConfiguration(const PVIDEORECCFG pVideoRecCfg)
     1088 * @param   Settings        Capturing configuration to apply.
     1089 */
     1090int AudioVideoRec::applyConfiguration(const settings::CaptureSettings &a_Settings)
    10911091{
    10921092    /** @todo Do some validation here. */
    1093     mVideoRecCfg = *pVideoRecCfg; /* Note: Does have an own copy operator. */
     1093    mVideoRecCfg = a_Settings; /* Note: Does have an own copy operator. */
    10941094    return VINF_SUCCESS;
    10951095}
     
    11011101int AudioVideoRec::configureDriver(PCFGMNODE pLunCfg)
    11021102{
    1103     int rc = CFGMR3InsertInteger(pLunCfg, "Object",    (uintptr_t)mpConsole->i_getAudioVideoRec());
     1103    int rc = CFGMR3InsertInteger(pLunCfg, "Object",    (uintptr_t)mpConsole->i_videoRecGetAudioDrv());
    11041104    AssertRCReturn(rc, rc);
    11051105    rc = CFGMR3InsertInteger(pLunCfg, "ObjectConsole", (uintptr_t)mpConsole);
    11061106    AssertRCReturn(rc, rc);
    11071107
    1108     rc = CFGMR3InsertInteger(pLunCfg, "ContainerType", (uint64_t)mVideoRecCfg.enmDst);
     1108    /** @todo For now we're using the configuration of the first screen here audio-wise. */
     1109    Assert(mVideoRecCfg.mapScreens.size() >= 1);
     1110    const settings::CaptureScreenSettings &Screen0Settings = mVideoRecCfg.mapScreens[0];
     1111
     1112    rc = CFGMR3InsertInteger(pLunCfg, "ContainerType", (uint64_t)Screen0Settings.enmDest);
    11091113    AssertRCReturn(rc, rc);
    1110     if (mVideoRecCfg.enmDst == VIDEORECDEST_FILE)
    1111     {
    1112         rc = CFGMR3InsertString(pLunCfg, "ContainerFileName", Utf8Str(mVideoRecCfg.File.strName).c_str());
     1114    if (Screen0Settings.enmDest == CaptureDestination_File)
     1115    {
     1116        rc = CFGMR3InsertString(pLunCfg, "ContainerFileName", Utf8Str(Screen0Settings.File.strName).c_str());
    11131117        AssertRCReturn(rc, rc);
    11141118    }
    1115     rc = CFGMR3InsertInteger(pLunCfg, "CodecHz", mVideoRecCfg.Audio.uHz);
     1119    rc = CFGMR3InsertInteger(pLunCfg, "CodecHz", Screen0Settings.Audio.uHz);
    11161120    AssertRCReturn(rc, rc);
    1117     rc = CFGMR3InsertInteger(pLunCfg, "CodecBits", mVideoRecCfg.Audio.cBits);
     1121    rc = CFGMR3InsertInteger(pLunCfg, "CodecBits", Screen0Settings.Audio.cBits);
    11181122    AssertRCReturn(rc, rc);
    1119     rc = CFGMR3InsertInteger(pLunCfg, "CodecChannels", mVideoRecCfg.Audio.cChannels);
     1123    rc = CFGMR3InsertInteger(pLunCfg, "CodecChannels", Screen0Settings.Audio.cChannels);
    11201124    AssertRCReturn(rc, rc);
    11211125    rc = CFGMR3InsertInteger(pLunCfg, "CodecBitrate", 0); /* Let Opus decide for now. */
  • trunk/src/VBox/Main/src-client/SessionImpl.cpp

    r68986 r75251  
    725725}
    726726
    727 HRESULT Session::onVideoCaptureChange()
    728 {
    729     LogFlowThisFunc(("\n"));
    730 
    731     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    732     AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    733     AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    734 #ifndef VBOX_COM_INPROC_API_CLIENT
    735     AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE);
    736 
    737     return mConsole->i_onVideoCaptureChange();
     727HRESULT Session::onCaptureChange()
     728{
     729    LogFlowThisFunc(("\n"));
     730
     731    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     732    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
     733    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
     734#ifndef VBOX_COM_INPROC_API_CLIENT
     735    AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE);
     736
     737    return mConsole->i_onCaptureChange();
    738738#else
    739739    return S_OK;
  • trunk/src/VBox/Main/src-client/VideoRec.cpp

    r75068 r75251  
    4343#include <VBox/com/VirtualBox.h>
    4444
    45 #include "WebMWriter.h"
     45#include "ConsoleImpl.h"
    4646#include "VideoRec.h"
    4747#include "VideoRecInternals.h"
    4848#include "VideoRecStream.h"
    4949#include "VideoRecUtils.h"
     50#include "WebMWriter.h"
    5051
    5152using namespace com;
     
    103104
    104105
     106CaptureContext::CaptureContext(Console *a_pConsole)
     107    : pConsole(a_pConsole) { }
     108
     109CaptureContext::CaptureContext(Console *a_pConsole, const settings::CaptureSettings &a_Settings)
     110    : pConsole(a_pConsole)
     111{
     112    int rc = CaptureContext::createInternal(a_Settings);
     113    if (RT_FAILURE(rc))
     114        throw rc;
     115}
     116
     117CaptureContext::~CaptureContext(void)
     118{
     119    destroyInternal();
     120}
     121
    105122/**
    106123 * Worker thread for all streams of a video recording context.
     
    108125 * For video frames, this also does the RGB/YUV conversion and encoding.
    109126 */
    110 static DECLCALLBACK(int) videoRecThread(RTTHREAD hThreadSelf, void *pvUser)
    111 {
    112     PVIDEORECCONTEXT pCtx = (PVIDEORECCONTEXT)pvUser;
     127DECLCALLBACK(int) CaptureContext::threadMain(RTTHREAD hThreadSelf, void *pvUser)
     128{
     129    CaptureContext *pThis = (CaptureContext *)pvUser;
    113130
    114131    /* Signal that we're up and rockin'. */
     
    119136    for (;;)
    120137    {
    121         int rc = RTSemEventWait(pCtx->WaitEvent, RT_INDEFINITE_WAIT);
     138        int rc = RTSemEventWait(pThis->WaitEvent, RT_INDEFINITE_WAIT);
    122139        AssertRCBreak(rc);
    123140
    124         Log2Func(("Processing %zu streams\n", pCtx->vecStreams.size()));
     141        Log2Func(("Processing %zu streams\n", pThis->vecStreams.size()));
    125142
    126143        /** @todo r=andy This is inefficient -- as we already wake up this thread
    127144         *               for every screen from Main, we here go again (on every wake up) through
    128145         *               all screens.  */
    129         VideoRecStreams::iterator itStream = pCtx->vecStreams.begin();
    130         while (itStream != pCtx->vecStreams.end())
    131         {
    132             PVIDEORECSTREAM pStream = (*itStream);
    133 
    134             rc = VideoRecStreamProcess(pStream);
     146        VideoRecStreams::iterator itStream = pThis->vecStreams.begin();
     147        while (itStream != pThis->vecStreams.end())
     148        {
     149            CaptureStream *pStream = (*itStream);
     150
     151            rc = pStream->Process(pThis->mapBlocksCommon);
    135152            if (RT_FAILURE(rc))
    136153                break;
     
    144161        /* Keep going in case of errors. */
    145162
    146         if (ASMAtomicReadBool(&pCtx->fShutdown))
     163        if (ASMAtomicReadBool(&pThis->fShutdown))
    147164        {
    148165            LogFunc(("Thread is shutting down ...\n"));
     
    160177 *
    161178 * @returns IPRT status code.
    162  * @param   pCtx                Video recording context to notify thread for.
    163  */
    164 static int videoRecThreadNotify(PVIDEORECCONTEXT pCtx)
    165 {
    166     AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
    167 
    168     return RTSemEventSignal(pCtx->WaitEvent);
     179 */
     180int CaptureContext::threadNotify(void)
     181{
     182    return RTSemEventSignal(this->WaitEvent);
    169183}
    170184
     
    175189 * @param   cScreens            Number of screens to create context for.
    176190 * @param   pVideoRecCfg        Pointer to video recording configuration to use.
    177  * @param   ppCtx               Pointer to created video recording context on success.
    178  */
    179 int VideoRecContextCreate(uint32_t cScreens, PVIDEORECCFG pVideoRecCfg, PVIDEORECCONTEXT *ppCtx)
    180 {
    181     AssertReturn(cScreens,        VERR_INVALID_PARAMETER);
    182     AssertPtrReturn(pVideoRecCfg, VERR_INVALID_POINTER);
    183     AssertPtrReturn(ppCtx,        VERR_INVALID_POINTER);
    184 
    185     VIDEORECCONTEXT *pCtx = NULL;
    186     try
    187     {
    188         pCtx = new VIDEORECCONTEXT();
    189     }
    190     catch (std::bad_alloc &)
    191     {
    192         return VERR_NO_MEMORY;
    193     }
    194 
    195     int rc = RTCritSectInit(&pCtx->CritSect);
     191 */
     192int CaptureContext::createInternal(const settings::CaptureSettings &a_Settings)
     193{
     194    int rc = RTCritSectInit(&this->CritSect);
    196195    if (RT_FAILURE(rc))
    197     {
    198         delete pCtx;
    199196        return rc;
    200     }
    201 
    202     for (uint32_t uScreen = 0; uScreen < cScreens; uScreen++)
    203     {
    204         VIDEORECSTREAM *pStream = NULL;
     197
     198    settings::CaptureScreenMap::const_iterator itScreen = a_Settings.mapScreens.begin();
     199    while (itScreen != a_Settings.mapScreens.end())
     200    {
     201        CaptureStream *pStream = NULL;
    205202        try
    206203        {
    207             pStream = new VIDEORECSTREAM();
     204            pStream = new CaptureStream(itScreen->first /* Screen ID */, itScreen->second);
     205            this->vecStreams.push_back(pStream);
    208206        }
    209207        catch (std::bad_alloc &)
     
    212210            break;
    213211        }
    214 
    215         rc = RTCritSectInit(&pStream->CritSect);
    216         if (RT_FAILURE(rc))
    217             break;
    218 
    219         try
    220         {
    221             pStream->uScreenID = uScreen;
    222 
    223             pCtx->vecStreams.push_back(pStream);
    224 
    225             pStream->File.pWEBM = new WebMWriter();
    226         }
    227         catch (std::bad_alloc &)
    228         {
    229             rc = VERR_NO_MEMORY;
    230             break;
    231         }
    232212    }
    233213
    234214    if (RT_SUCCESS(rc))
    235215    {
    236         pCtx->tsStartMs = RTTimeMilliTS();
    237         pCtx->enmState  = VIDEORECSTS_UNINITIALIZED;
    238         pCtx->fStarted  = false;
    239         pCtx->fShutdown = false;
    240 
    241         /* Copy the configuration to our context. */
    242         pCtx->Cfg       = *pVideoRecCfg;
    243 
    244         rc = RTSemEventCreate(&pCtx->WaitEvent);
     216        this->tsStartMs = RTTimeMilliTS();
     217        this->enmState  = VIDEORECSTS_UNINITIALIZED;
     218        this->fStarted  = false;
     219        this->fShutdown = false;
     220
     221        /* Copy the settings to our context. */
     222        this->Settings  = a_Settings;
     223
     224        rc = RTSemEventCreate(&this->WaitEvent);
    245225        AssertRCReturn(rc, rc);
    246226
    247         rc = RTThreadCreate(&pCtx->Thread, videoRecThread, (void *)pCtx, 0,
     227        rc = RTThreadCreate(&this->Thread, CaptureContext::threadMain, (void *)this, 0,
    248228                            RTTHREADTYPE_MAIN_WORKER, RTTHREADFLAGS_WAITABLE, "VideoRec");
    249229
    250230        if (RT_SUCCESS(rc)) /* Wait for the thread to start. */
    251             rc = RTThreadUserWait(pCtx->Thread, 30 * RT_MS_1SEC /* 30s timeout */);
     231            rc = RTThreadUserWait(this->Thread, 30 * RT_MS_1SEC /* 30s timeout */);
    252232
    253233        if (RT_SUCCESS(rc))
    254234        {
    255             pCtx->enmState = VIDEORECSTS_INITIALIZED;
    256             pCtx->fStarted = true;
    257 
    258             if (ppCtx)
    259                 *ppCtx = pCtx;
     235            this->enmState = VIDEORECSTS_INITIALIZED;
     236            this->fStarted = true;
    260237        }
    261238    }
     
    263240    if (RT_FAILURE(rc))
    264241    {
    265         int rc2 = VideoRecContextDestroy(pCtx);
     242        int rc2 = destroyInternal();
    266243        AssertRC(rc2);
    267244    }
     
    272249/**
    273250 * Destroys a video recording context.
    274  *
    275  * @param pCtx                  Video recording context to destroy.
    276  */
    277 int VideoRecContextDestroy(PVIDEORECCONTEXT pCtx)
    278 {
    279     if (!pCtx)
    280         return VINF_SUCCESS;
    281 
     251 */
     252int CaptureContext::destroyInternal(void)
     253{
    282254    int rc = VINF_SUCCESS;
    283255
    284     if (pCtx->enmState == VIDEORECSTS_INITIALIZED)
     256    if (this->enmState == VIDEORECSTS_INITIALIZED)
    285257    {
    286258        LogFunc(("Shutting down thread ...\n"));
    287259
    288260        /* Set shutdown indicator. */
    289         ASMAtomicWriteBool(&pCtx->fShutdown, true);
     261        ASMAtomicWriteBool(&this->fShutdown, true);
    290262
    291263        /* Signal the thread and wait for it to shut down. */
    292         rc = videoRecThreadNotify(pCtx);
     264        rc = threadNotify();
    293265        if (RT_SUCCESS(rc))
    294             rc = RTThreadWait(pCtx->Thread, 30 * 1000 /* 10s timeout */, NULL);
     266            rc = RTThreadWait(this->Thread, 30 * 1000 /* 10s timeout */, NULL);
    295267
    296268        if (RT_SUCCESS(rc))
    297269        {
    298270            /* Disable the context. */
    299             ASMAtomicWriteBool(&pCtx->fStarted, false);
    300 
    301             int rc2 = RTSemEventDestroy(pCtx->WaitEvent);
     271            ASMAtomicWriteBool(&this->fStarted, false);
     272
     273            int rc2 = RTSemEventDestroy(this->WaitEvent);
    302274            AssertRC(rc2);
    303275
    304             pCtx->WaitEvent = NIL_RTSEMEVENT;
     276            this->WaitEvent = NIL_RTSEMEVENT;
    305277        }
    306278    }
     
    312284    }
    313285
    314     rc = RTCritSectEnter(&pCtx->CritSect);
     286    rc = RTCritSectEnter(&this->CritSect);
    315287    if (RT_SUCCESS(rc))
    316288    {
    317         VideoRecStreams::iterator it = pCtx->vecStreams.begin();
    318         while (it != pCtx->vecStreams.end())
    319         {
    320             PVIDEORECSTREAM pStream = (*it);
    321 
    322             VideoRecStreamLock(pStream);
    323 
    324             int rc2 = VideoRecStreamClose(pStream);
     289        VideoRecStreams::iterator it = this->vecStreams.begin();
     290        while (it != this->vecStreams.end())
     291        {
     292            CaptureStream *pStream = (*it);
     293
     294            int rc2 = pStream->Uninit();
    325295            if (RT_SUCCESS(rc))
    326296                rc = rc2;
    327297
    328             rc2 = VideoRecStreamUninit(pStream);
    329             if (RT_SUCCESS(rc))
    330                 rc = rc2;
    331 
    332             pCtx->vecStreams.erase(it);
    333             it = pCtx->vecStreams.begin();
    334 
    335             VideoRecStreamUnlock(pStream);
    336 
    337             RTCritSectDelete(&pStream->CritSect);
    338 
    339298            delete pStream;
    340299            pStream = NULL;
     300
     301            this->vecStreams.erase(it);
     302            it = this->vecStreams.begin();
     303
     304            delete pStream;
     305            pStream = NULL;
    341306        }
    342307
    343308        /* Sanity. */
    344         Assert(pCtx->vecStreams.empty());
    345         Assert(pCtx->mapBlocksCommon.size() == 0);
    346 
    347         int rc2 = RTCritSectLeave(&pCtx->CritSect);
     309        Assert(this->vecStreams.empty());
     310        Assert(this->mapBlocksCommon.size() == 0);
     311
     312        int rc2 = RTCritSectLeave(&this->CritSect);
    348313        AssertRC(rc2);
    349314
    350         RTCritSectDelete(&pCtx->CritSect);
    351 
    352         delete pCtx;
    353         pCtx = NULL;
     315        RTCritSectDelete(&this->CritSect);
    354316    }
    355317
     
    357319}
    358320
    359 /**
    360  * Returns which recording features currently are enabled for a given configuration.
    361  *
    362  * @returns Enabled video recording features.
    363  * @param   pCfg                Pointer to recording configuration.
    364  */
    365 VIDEORECFEATURES VideoRecGetFeatures(PVIDEORECCFG pCfg)
    366 {
    367     if (!pCfg)
    368         return VIDEORECFEATURE_NONE;
    369 
    370     VIDEORECFEATURES fFeatures = VIDEORECFEATURE_NONE;
    371 
    372     if (pCfg->Video.fEnabled)
    373         fFeatures |= VIDEORECFEATURE_VIDEO;
    374 
    375 #ifdef VBOX_WITH_AUDIO_VIDEOREC
    376     if (pCfg->Audio.fEnabled)
    377         fFeatures |= VIDEORECFEATURE_AUDIO;
    378 #endif
    379 
    380     return fFeatures;
     321const settings::CaptureSettings &CaptureContext::GetConfig(void) const
     322{
     323    return this->Settings;
     324}
     325
     326CaptureStream *CaptureContext::getStreamInternal(unsigned uScreen) const
     327{
     328    CaptureStream *pStream;
     329
     330    try
     331    {
     332        pStream = this->vecStreams.at(uScreen);
     333    }
     334    catch (std::out_of_range &)
     335    {
     336        pStream = NULL;
     337    }
     338
     339    return pStream;
    381340}
    382341
     
    385344 *
    386345 * @returns Pointer to recording stream if found, or NULL if not found.
    387  * @param   pCtx                Recording context to look up stream for.
    388346 * @param   uScreen             Screen number of recording stream to look up.
    389347 */
    390 PVIDEORECSTREAM VideoRecGetStream(PVIDEORECCONTEXT pCtx, uint32_t uScreen)
    391 {
    392     AssertPtrReturn(pCtx, NULL);
    393 
    394     PVIDEORECSTREAM pStream;
    395 
    396     try
    397     {
    398         pStream = pCtx->vecStreams.at(uScreen);
    399     }
    400     catch (std::out_of_range &)
    401     {
    402         pStream = NULL;
    403     }
    404 
    405     return pStream;
     348CaptureStream *CaptureContext::GetStream(unsigned uScreen) const
     349{
     350    return getStreamInternal(uScreen);
     351}
     352
     353size_t CaptureContext::GetStreamCount(void) const
     354{
     355    return this->vecStreams.size();
     356}
     357
     358int CaptureContext::Create(const settings::CaptureSettings &a_Settings)
     359{
     360    return createInternal(a_Settings);
     361}
     362
     363int CaptureContext::Destroy(void)
     364{
     365    return destroyInternal();
     366}
     367
     368bool CaptureContext::IsFeatureEnabled(CaptureFeature_T enmFeature) const
     369{
     370    VideoRecStreams::const_iterator itStream = this->vecStreams.begin();
     371    while (itStream != this->vecStreams.end())
     372    {
     373        if ((*itStream)->GetConfig().isFeatureEnabled(enmFeature))
     374            return true;
     375        ++itStream;
     376    }
     377
     378    return false;
     379}
     380
     381bool CaptureContext::IsReady(void) const
     382{
     383    return this->fStarted;
    406384}
    407385
     
    410388 *
    411389 * @returns true if recording engine is ready, false if not.
    412  * @param   pCtx                Pointer to video recording context.
    413390 * @param   uScreen             Screen ID.
    414391 * @param   uTimeStampMs        Current time stamp (in ms). Currently not being used.
    415392 */
    416 bool VideoRecIsReady(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t uTimeStampMs)
    417 {
    418     AssertPtrReturn(pCtx, false);
     393bool CaptureContext::IsReady(uint32_t uScreen, uint64_t uTimeStampMs) const
     394{
    419395    RT_NOREF(uTimeStampMs);
    420396
    421     if (ASMAtomicReadU32(&pCtx->enmState) != VIDEORECSTS_INITIALIZED)
     397    if (this->enmState != VIDEORECSTS_INITIALIZED)
    422398        return false;
    423399
    424400    bool fIsReady = false;
    425401
    426     PVIDEORECSTREAM pStream = VideoRecGetStream(pCtx, uScreen);
     402    const CaptureStream *pStream = GetStream(uScreen);
    427403    if (pStream)
    428     {
    429         VideoRecStreamLock(pStream);
    430         fIsReady = pStream->fEnabled;
    431         VideoRecStreamUnlock(pStream);
    432     }
     404        fIsReady = pStream->IsReady();
    433405
    434406    /* Note: Do not check for other constraints like the video FPS rate here,
     
    443415 *
    444416 * @returns true if active, false if not.
    445  * @param   pCtx                 Pointer to video recording context.
    446  */
    447 bool VideoRecIsStarted(PVIDEORECCONTEXT pCtx)
    448 {
    449     if (!pCtx)
    450         return false;
    451 
    452     return ASMAtomicReadBool(&pCtx->fStarted);
     417 */
     418bool CaptureContext::IsStarted(void) const
     419{
     420    return this->fStarted;
    453421}
    454422
     
    457425 *
    458426 * @returns true if any limit has been reached.
    459  * @param   pCtx                Pointer to video recording context.
    460427 * @param   uScreen             Screen ID.
    461428 * @param   tsNowMs             Current time stamp (in ms).
    462429 */
    463 bool VideoRecIsLimitReached(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint64_t tsNowMs)
    464 {
    465     PVIDEORECSTREAM pStream = VideoRecGetStream(pCtx, uScreen);
     430bool CaptureContext::IsLimitReached(uint32_t uScreen, uint64_t tsNowMs) const
     431{
     432    const CaptureStream *pStream = GetStream(uScreen);
    466433    if (   !pStream
    467         || !pStream->fEnabled)
    468     {
    469         return false;
    470     }
    471 
    472     const PVIDEORECCFG pCfg = &pCtx->Cfg;
    473 
    474     if (   pCfg->uMaxTimeS
    475         && tsNowMs >= pCtx->tsStartMs + (pCfg->uMaxTimeS * RT_MS_1SEC))
     434        || pStream->IsLimitReached(tsNowMs))
    476435    {
    477436        return true;
    478437    }
    479438
    480     if (pCfg->enmDst == VIDEORECDEST_FILE)
    481     {
    482 
    483         if (pCfg->File.uMaxSizeMB)
    484         {
    485             uint64_t sizeInMB = pStream->File.pWEBM->GetFileSize() / _1M;
    486             if(sizeInMB >= pCfg->File.uMaxSizeMB)
    487                 return true;
    488         }
    489 
    490         /* Check for available free disk space */
    491         if (   pStream->File.pWEBM
    492             && pStream->File.pWEBM->GetAvailableSpace() < 0x100000) /** @todo r=andy WTF? Fix this. */
    493         {
    494             LogRel(("VideoRec: Not enough free storage space available, stopping video capture\n"));
    495             return true;
    496         }
    497     }
    498 
    499439    return false;
    500440}
     
    506446 *
    507447 * @returns IPRT status code.
    508  * @param   pCtx                Pointer to the video recording context.
    509448 * @param   pvData              Audio frame data to send.
    510449 * @param   cbData              Size (in bytes) of (encoded) audio frame data.
    511450 * @param   uTimeStampMs        Time stamp (in ms) of audio playback.
    512451 */
    513 int VideoRecSendAudioFrame(PVIDEORECCONTEXT pCtx, const void *pvData, size_t cbData, uint64_t uTimeStampMs)
     452int CaptureContext::SendAudioFrame(const void *pvData, size_t cbData, uint64_t uTimeStampMs)
    514453{
    515454#ifdef VBOX_WITH_AUDIO_VIDEOREC
     
    537476    pBlock->pvData       = pFrame;
    538477    pBlock->cbData       = sizeof(VIDEORECAUDIOFRAME) + cbData;
    539     pBlock->cRefs        = (uint16_t)pCtx->vecStreams.size(); /* All streams need the same audio data. */
     478    pBlock->cRefs        = (uint16_t)this->vecStreams.size(); /* All streams need the same audio data. */
    540479    pBlock->uTimeStampMs = uTimeStampMs;
    541480
    542     int rc = RTCritSectEnter(&pCtx->CritSect);
     481    int rc = RTCritSectEnter(&this->CritSect);
    543482    if (RT_FAILURE(rc))
    544483        return rc;
     
    546485    try
    547486    {
    548         VideoRecBlockMap::iterator itBlocks = pCtx->mapBlocksCommon.find(uTimeStampMs);
    549         if (itBlocks == pCtx->mapBlocksCommon.end())
    550         {
    551             VideoRecBlocks *pVideoRecBlocks = new VideoRecBlocks();
     487        VideoRecBlockMap::iterator itBlocks = this->mapBlocksCommon.find(uTimeStampMs);
     488        if (itBlocks == this->mapBlocksCommon.end())
     489        {
     490            CaptureBlocks *pVideoRecBlocks = new CaptureBlocks();
    552491            pVideoRecBlocks->List.push_back(pBlock);
    553492
    554             pCtx->mapBlocksCommon.insert(std::make_pair(uTimeStampMs, pVideoRecBlocks));
     493            this->mapBlocksCommon.insert(std::make_pair(uTimeStampMs, pVideoRecBlocks));
    555494        }
    556495        else
     
    563502    }
    564503
    565     int rc2 = RTCritSectLeave(&pCtx->CritSect);
     504    int rc2 = RTCritSectLeave(&this->CritSect);
    566505    AssertRC(rc2);
    567506
    568507    if (RT_SUCCESS(rc))
    569         rc = videoRecThreadNotify(pCtx);
     508        rc = threadNotify();
    570509
    571510    return rc;
     
    583522 *
    584523 * @returns IPRT status code.
    585  * @param   pCtx               Pointer to the video recording context.
    586  * @param   uScreen            Screen number.
     524 * @param   uScreen            Screen number to send video frame to.
    587525 * @param   x                  Starting x coordinate of the video frame.
    588526 * @param   y                  Starting y coordinate of the video frame.
     
    595533 * @param   uTimeStampMs       Time stamp (in ms).
    596534 */
    597 int VideoRecSendVideoFrame(PVIDEORECCONTEXT pCtx, uint32_t uScreen, uint32_t x, uint32_t y,
    598                            uint32_t uPixelFormat, uint32_t uBPP, uint32_t uBytesPerLine,
    599                            uint32_t uSrcWidth, uint32_t uSrcHeight, uint8_t *puSrcData,
    600                            uint64_t uTimeStampMs)
    601 {
    602     AssertPtrReturn(pCtx,    VERR_INVALID_POINTER);
     535int CaptureContext::SendVideoFrame(uint32_t uScreen, uint32_t x, uint32_t y,
     536                                   uint32_t uPixelFormat, uint32_t uBPP, uint32_t uBytesPerLine,
     537                                   uint32_t uSrcWidth, uint32_t uSrcHeight, uint8_t *puSrcData,
     538                                   uint64_t uTimeStampMs)
     539{
    603540    AssertReturn(uSrcWidth,  VERR_INVALID_PARAMETER);
    604541    AssertReturn(uSrcHeight, VERR_INVALID_PARAMETER);
    605542    AssertReturn(puSrcData,  VERR_INVALID_POINTER);
    606543
    607     int rc = RTCritSectEnter(&pCtx->CritSect);
     544    int rc = RTCritSectEnter(&this->CritSect);
    608545    AssertRC(rc);
    609546
    610     PVIDEORECSTREAM pStream = VideoRecGetStream(pCtx, uScreen);
     547    CaptureStream *pStream = GetStream(uScreen);
    611548    if (!pStream)
    612549    {
    613         rc = RTCritSectLeave(&pCtx->CritSect);
     550        rc = RTCritSectLeave(&this->CritSect);
    614551        AssertRC(rc);
    615552
     
    617554    }
    618555
    619     VideoRecStreamLock(pStream);
    620 
    621     PVIDEORECVIDEOFRAME pFrame = NULL;
    622 
    623     do
    624     {
    625         if (!pStream->fEnabled)
    626         {
    627             rc = VINF_TRY_AGAIN; /* Not (yet) enabled. */
    628             break;
    629         }
    630 
    631         if (uTimeStampMs < pStream->Video.uLastTimeStampMs + pStream->Video.uDelayMs)
    632         {
    633             rc = VINF_TRY_AGAIN; /* Respect maximum frames per second. */
    634             break;
    635         }
    636 
    637         pStream->Video.uLastTimeStampMs = uTimeStampMs;
    638 
    639         int xDiff = ((int)pStream->Video.uWidth - (int)uSrcWidth) / 2;
    640         uint32_t w = uSrcWidth;
    641         if ((int)w + xDiff + (int)x <= 0)  /* Nothing visible. */
    642         {
    643             rc = VERR_INVALID_PARAMETER;
    644             break;
    645         }
    646 
    647         uint32_t destX;
    648         if ((int)x < -xDiff)
    649         {
    650             w += xDiff + x;
    651             x = -xDiff;
    652             destX = 0;
    653         }
    654         else
    655             destX = x + xDiff;
    656 
    657         uint32_t h = uSrcHeight;
    658         int yDiff = ((int)pStream->Video.uHeight - (int)uSrcHeight) / 2;
    659         if ((int)h + yDiff + (int)y <= 0)  /* Nothing visible. */
    660         {
    661             rc = VERR_INVALID_PARAMETER;
    662             break;
    663         }
    664 
    665         uint32_t destY;
    666         if ((int)y < -yDiff)
    667         {
    668             h += yDiff + (int)y;
    669             y = -yDiff;
    670             destY = 0;
    671         }
    672         else
    673             destY = y + yDiff;
    674 
    675         if (   destX > pStream->Video.uWidth
    676             || destY > pStream->Video.uHeight)
    677         {
    678             rc = VERR_INVALID_PARAMETER;  /* Nothing visible. */
    679             break;
    680         }
    681 
    682         if (destX + w > pStream->Video.uWidth)
    683             w = pStream->Video.uWidth - destX;
    684 
    685         if (destY + h > pStream->Video.uHeight)
    686             h = pStream->Video.uHeight - destY;
    687 
    688         pFrame = (PVIDEORECVIDEOFRAME)RTMemAllocZ(sizeof(VIDEORECVIDEOFRAME));
    689         AssertBreakStmt(pFrame, rc = VERR_NO_MEMORY);
    690 
    691         /* Calculate bytes per pixel and set pixel format. */
    692         const unsigned uBytesPerPixel = uBPP / 8;
    693         if (uPixelFormat == BitmapFormat_BGR)
    694         {
    695             switch (uBPP)
    696             {
    697                 case 32:
    698                     pFrame->uPixelFormat = VIDEORECPIXELFMT_RGB32;
    699                     break;
    700                 case 24:
    701                     pFrame->uPixelFormat = VIDEORECPIXELFMT_RGB24;
    702                     break;
    703                 case 16:
    704                     pFrame->uPixelFormat = VIDEORECPIXELFMT_RGB565;
    705                     break;
    706                 default:
    707                     AssertMsgFailed(("Unknown color depth (%RU32)\n", uBPP));
    708                     break;
    709             }
    710         }
    711         else
    712             AssertMsgFailed(("Unknown pixel format (%RU32)\n", uPixelFormat));
    713 
    714         const size_t cbRGBBuf =   pStream->Video.uWidth
    715                                 * pStream->Video.uHeight
    716                                 * uBytesPerPixel;
    717         AssertBreakStmt(cbRGBBuf, rc = VERR_INVALID_PARAMETER);
    718 
    719         pFrame->pu8RGBBuf = (uint8_t *)RTMemAlloc(cbRGBBuf);
    720         AssertBreakStmt(pFrame->pu8RGBBuf, rc = VERR_NO_MEMORY);
    721         pFrame->cbRGBBuf  = cbRGBBuf;
    722         pFrame->uWidth    = uSrcWidth;
    723         pFrame->uHeight   = uSrcHeight;
    724 
    725         /* If the current video frame is smaller than video resolution we're going to encode,
    726          * clear the frame beforehand to prevent artifacts. */
    727         if (   uSrcWidth  < pStream->Video.uWidth
    728             || uSrcHeight < pStream->Video.uHeight)
    729         {
    730             RT_BZERO(pFrame->pu8RGBBuf, pFrame->cbRGBBuf);
    731         }
    732 
    733         /* Calculate start offset in source and destination buffers. */
    734         uint32_t offSrc = y * uBytesPerLine + x * uBytesPerPixel;
    735         uint32_t offDst = (destY * pStream->Video.uWidth + destX) * uBytesPerPixel;
    736 
    737 #ifdef VBOX_VIDEOREC_DUMP
    738         VIDEORECBMPHDR bmpHdr;
    739         RT_ZERO(bmpHdr);
    740 
    741         VIDEORECBMPDIBHDR bmpDIBHdr;
    742         RT_ZERO(bmpDIBHdr);
    743 
    744         bmpHdr.u16Magic   = 0x4d42; /* Magic */
    745         bmpHdr.u32Size    = (uint32_t)(sizeof(VIDEORECBMPHDR) + sizeof(VIDEORECBMPDIBHDR) + (w * h * uBytesPerPixel));
    746         bmpHdr.u32OffBits = (uint32_t)(sizeof(VIDEORECBMPHDR) + sizeof(VIDEORECBMPDIBHDR));
    747 
    748         bmpDIBHdr.u32Size          = sizeof(VIDEORECBMPDIBHDR);
    749         bmpDIBHdr.u32Width         = w;
    750         bmpDIBHdr.u32Height        = h;
    751         bmpDIBHdr.u16Planes        = 1;
    752         bmpDIBHdr.u16BitCount      = uBPP;
    753         bmpDIBHdr.u32XPelsPerMeter = 5000;
    754         bmpDIBHdr.u32YPelsPerMeter = 5000;
    755 
    756         char szFileName[RTPATH_MAX];
    757         RTStrPrintf2(szFileName, sizeof(szFileName), "/tmp/VideoRecFrame-%RU32.bmp", uScreen);
    758 
    759         RTFILE fh;
    760         int rc2 = RTFileOpen(&fh, szFileName,
    761                              RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    762         if (RT_SUCCESS(rc2))
    763         {
    764             RTFileWrite(fh, &bmpHdr,    sizeof(bmpHdr),    NULL);
    765             RTFileWrite(fh, &bmpDIBHdr, sizeof(bmpDIBHdr), NULL);
    766         }
    767 #endif
    768         Assert(pFrame->cbRGBBuf >= w * h * uBytesPerPixel);
    769 
    770         /* Do the copy. */
    771         for (unsigned int i = 0; i < h; i++)
    772         {
    773             /* Overflow check. */
    774             Assert(offSrc + w * uBytesPerPixel <= uSrcHeight * uBytesPerLine);
    775             Assert(offDst + w * uBytesPerPixel <= pStream->Video.uHeight * pStream->Video.uWidth * uBytesPerPixel);
    776 
    777             memcpy(pFrame->pu8RGBBuf + offDst, puSrcData + offSrc, w * uBytesPerPixel);
    778 
    779 #ifdef VBOX_VIDEOREC_DUMP
    780             if (RT_SUCCESS(rc2))
    781                 RTFileWrite(fh, pFrame->pu8RGBBuf + offDst, w * uBytesPerPixel, NULL);
    782 #endif
    783             offSrc += uBytesPerLine;
    784             offDst += pStream->Video.uWidth * uBytesPerPixel;
    785         }
    786 
    787 #ifdef VBOX_VIDEOREC_DUMP
    788         if (RT_SUCCESS(rc2))
    789             RTFileClose(fh);
    790 #endif
    791 
    792     } while (0);
    793 
    794     if (rc == VINF_SUCCESS) /* Note: Also could be VINF_TRY_AGAIN. */
    795     {
    796         PVIDEORECBLOCK pBlock = (PVIDEORECBLOCK)RTMemAlloc(sizeof(VIDEORECBLOCK));
    797         if (pBlock)
    798         {
    799             AssertPtr(pFrame);
    800 
    801             pBlock->enmType = VIDEORECBLOCKTYPE_VIDEO;
    802             pBlock->pvData  = pFrame;
    803             pBlock->cbData  = sizeof(VIDEORECVIDEOFRAME) + pFrame->cbRGBBuf;
    804 
    805             try
    806             {
    807                 VideoRecBlocks *pVideoRecBlocks = new VideoRecBlocks();
    808                 pVideoRecBlocks->List.push_back(pBlock);
    809 
    810                 Assert(pStream->Blocks.Map.find(uTimeStampMs) == pStream->Blocks.Map.end());
    811                 pStream->Blocks.Map.insert(std::make_pair(uTimeStampMs, pVideoRecBlocks));
    812             }
    813             catch (const std::exception &ex)
    814             {
    815                 RT_NOREF(ex);
    816 
    817                 RTMemFree(pBlock);
    818                 rc = VERR_NO_MEMORY;
    819             }
    820         }
    821         else
    822             rc = VERR_NO_MEMORY;
    823     }
    824 
    825     if (RT_FAILURE(rc))
    826         VideoRecVideoFrameFree(pFrame);
    827 
    828     VideoRecStreamUnlock(pStream);
    829 
    830     int rc2 = RTCritSectLeave(&pCtx->CritSect);
     556    rc = pStream->SendVideoFrame(x, y, uPixelFormat, uBPP, uBytesPerLine, uSrcWidth, uSrcHeight, puSrcData, uTimeStampMs);
     557
     558    int rc2 = RTCritSectLeave(&this->CritSect);
    831559    AssertRC(rc2);
    832560
     
    834562        && rc != VINF_TRY_AGAIN) /* Only signal the thread if operation was successful. */
    835563    {
    836         videoRecThreadNotify(pCtx);
     564        threadNotify();
    837565    }
    838566
  • trunk/src/VBox/Main/src-client/VideoRecStream.cpp

    r75069 r75251  
    4242
    4343
    44 /**
    45  * Locks a recording stream.
    46  *
    47  * @param   pStream             Recording stream to lock.
    48  */
    49 void VideoRecStreamLock(PVIDEORECSTREAM pStream)
    50 {
    51     int rc = RTCritSectEnter(&pStream->CritSect);
    52     AssertRC(rc);
    53 }
    54 
    55 /**
    56  * Unlocks a locked recording stream.
    57  *
    58  * @param   pStream             Recording stream to unlock.
    59  */
    60 void VideoRecStreamUnlock(PVIDEORECSTREAM pStream)
    61 {
    62     int rc = RTCritSectLeave(&pStream->CritSect);
    63     AssertRC(rc);
     44CaptureStream::CaptureStream(void)
     45    : tsStartMs(0)
     46{
     47}
     48
     49CaptureStream::CaptureStream(uint32_t a_uScreen, const settings::CaptureScreenSettings &a_Settings)
     50    : tsStartMs(0)
     51{
     52    int rc2 = initInternal(a_uScreen, a_Settings);
     53    if (RT_FAILURE(rc2))
     54        throw rc2;
     55}
     56
     57CaptureStream::~CaptureStream(void)
     58{
     59    int rc2 = uninitInternal();
     60    AssertRC(rc2);
    6461}
    6562
     
    6865 *
    6966 * @returns IPRT status code.
    70  * @param   pStream             Recording stream to open.
    71  * @param   pCfg                Recording configuration to use.
    72  */
    73 int VideoRecStreamOpen(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg)
    74 {
    75     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    76     AssertPtrReturn(pCfg,    VERR_INVALID_POINTER);
    77 
    78     Assert(pStream->enmDst == VIDEORECDEST_INVALID);
     67 */
     68int CaptureStream::open(void)
     69{
     70    Assert(Settings.enmDest == CaptureDestination_None);
    7971
    8072    int rc;
    8173
    82     switch (pCfg->enmDst)
    83     {
    84         case VIDEORECDEST_FILE:
    85         {
    86             Assert(pCfg->File.strName.isNotEmpty());
    87 
    88             char *pszAbsPath = RTPathAbsDup(com::Utf8Str(pCfg->File.strName).c_str());
     74    switch (Settings.enmDest)
     75    {
     76        case CaptureDestination_File:
     77        {
     78            Assert(Settings.File.strName.isNotEmpty());
     79
     80            char *pszAbsPath = RTPathAbsDup(Settings.File.strName.c_str());
    8981            AssertPtrReturn(pszAbsPath, VERR_NO_MEMORY);
    9082
     
    10193            char *pszFile = NULL;
    10294
    103             if (pCfg->aScreens.size() > 1)
    104                 rc = RTStrAPrintf(&pszFile, "%s-%u%s", pszAbsPath, pStream->uScreenID + 1, pszSuff);
     95            if (this->uScreenID > 0)
     96                rc = RTStrAPrintf(&pszFile, "%s-%u%s", pszAbsPath, this->uScreenID + 1, pszSuff);
    10597            else
    10698                rc = RTStrAPrintf(&pszFile, "%s%s", pszAbsPath, pszSuff);
     
    127119                    RTTimeExplode(&time, &ts);
    128120
    129                     if (pCfg->aScreens.size() > 1)
     121                    if (this->uScreenID > 0)
    130122                        rc = RTStrAPrintf(&pszFile, "%s-%04d-%02u-%02uT%02u-%02u-%02u-%09uZ-%u%s",
    131123                                          pszAbsPath, time.i32Year, time.u8Month, time.u8MonthDay,
    132124                                          time.u8Hour, time.u8Minute, time.u8Second, time.u32Nanosecond,
    133                                           pStream->uScreenID + 1, pszSuff);
     125                                          this->uScreenID + 1, pszSuff);
    134126                    else
    135127                        rc = RTStrAPrintf(&pszFile, "%s-%04d-%02u-%02uT%02u-%02u-%02u-%09uZ%s",
     
    144136                if (RT_SUCCESS(rc))
    145137                {
    146                     pStream->enmDst       = VIDEORECDEST_FILE;
    147                     pStream->File.hFile   = hFile;
    148                     pStream->File.pszFile = pszFile; /* Assign allocated string to our stream's config. */
     138                    this->File.hFile   = hFile;
     139                    this->File.strName = pszFile;
    149140                }
    150141            }
     
    156147            {
    157148                LogRel(("VideoRec: Failed to open file '%s' for screen %RU32, rc=%Rrc\n",
    158                         pszFile ? pszFile : "<Unnamed>", pStream->uScreenID, rc));
    159                 RTStrFree(pszFile);
    160             }
    161 
     149                        pszFile ? pszFile : "<Unnamed>", this->uScreenID, rc));
     150            }
     151
     152            RTStrFree(pszFile);
    162153            break;
    163154        }
     
    170161    LogFlowFuncLeaveRC(rc);
    171162    return rc;
     163}
     164
     165int CaptureStream::parseOptionsString(const com::Utf8Str &strOptions)
     166{
     167    size_t pos = 0;
     168    com::Utf8Str key, value;
     169    while ((pos = strOptions.parseKeyValue(key, value, pos)) != com::Utf8Str::npos)
     170    {
     171        if (key.compare("vc_quality", Utf8Str::CaseInsensitive) == 0)
     172        {
     173#ifdef VBOX_WITH_LIBVPX
     174            Assert(this->Settings.Video.ulFPS);
     175            if (value.compare("realtime", Utf8Str::CaseInsensitive) == 0)
     176                this->Video.Codec.VPX.uEncoderDeadline = VPX_DL_REALTIME;
     177            else if (value.compare("good", Utf8Str::CaseInsensitive) == 0)
     178                this->Video.Codec.VPX.uEncoderDeadline = 1000000 / this->Settings.Video.ulFPS;
     179            else if (value.compare("best", Utf8Str::CaseInsensitive) == 0)
     180                this->Video.Codec.VPX.uEncoderDeadline = VPX_DL_BEST_QUALITY;
     181            else
     182            {
     183                LogRel(("VideoRec: Setting encoder deadline to '%s'\n", value.c_str()));
     184                this->Video.Codec.VPX.uEncoderDeadline = value.toUInt32();
     185#endif
     186            }
     187        }
     188        else if (key.compare("vc_enabled", Utf8Str::CaseInsensitive) == 0)
     189        {
     190            if (value.compare("false", Utf8Str::CaseInsensitive) == 0)
     191            {
     192                this->Settings.featureMap[CaptureFeature_Video] = false;
     193#ifdef VBOX_WITH_AUDIO_VIDEOREC
     194                LogRel(("VideoRec: Only audio will be recorded\n"));
     195#endif
     196            }
     197        }
     198        else if (key.compare("ac_enabled", Utf8Str::CaseInsensitive) == 0)
     199        {
     200#ifdef VBOX_WITH_AUDIO_VIDEOREC
     201            if (value.compare("true", Utf8Str::CaseInsensitive) == 0)
     202            {
     203                this->Settings.featureMap[CaptureFeature_Audio] = true;
     204            }
     205            else
     206                LogRel(("VideoRec: Only video will be recorded\n"));
     207#endif
     208        }
     209        else if (key.compare("ac_profile", Utf8Str::CaseInsensitive) == 0)
     210        {
     211#ifdef VBOX_WITH_AUDIO_VIDEOREC
     212            if (value.compare("low", Utf8Str::CaseInsensitive) == 0)
     213            {
     214                this->Settings.Audio.uHz       = 8000;
     215                this->Settings.Audio.cBits     = 16;
     216                this->Settings.Audio.cChannels = 1;
     217            }
     218            else if (value.startsWith("med" /* "med[ium]" */, Utf8Str::CaseInsensitive) == 0)
     219            {
     220                /* Stay with the default set above. */
     221            }
     222            else if (value.compare("high", Utf8Str::CaseInsensitive) == 0)
     223            {
     224                this->Settings.Audio.uHz       = 48000;
     225                this->Settings.Audio.cBits     = 16;
     226                this->Settings.Audio.cChannels = 2;
     227            }
     228#endif
     229        }
     230        else
     231            LogRel(("VideoRec: Unknown option '%s' (value '%s'), skipping\n", key.c_str(), value.c_str()));
     232
     233    } /* while */
     234
     235    return VINF_SUCCESS;
     236}
     237
     238const settings::CaptureScreenSettings &CaptureStream::GetConfig(void) const
     239{
     240    return this->Settings;
     241}
     242
     243/**
     244 * Checks if a specified limit for recording has been reached.
     245 *
     246 * @returns true if any limit has been reached.
     247 * @param   tsNowMs             Current time stamp (in ms).
     248 */
     249bool CaptureStream::IsLimitReached(uint64_t tsNowMs) const
     250{
     251    if (!IsReady())
     252        return true;
     253
     254    if (   Settings.ulMaxTimeS
     255        && tsNowMs >= this->tsStartMs + (Settings.ulMaxTimeS * RT_MS_1SEC))
     256    {
     257        return true;
     258    }
     259
     260    if (Settings.enmDest == CaptureDestination_File)
     261    {
     262
     263        if (Settings.File.ulMaxSizeMB)
     264        {
     265            uint64_t sizeInMB = this->File.pWEBM->GetFileSize() / _1M;
     266            if(sizeInMB >= Settings.File.ulMaxSizeMB)
     267                return true;
     268        }
     269
     270        /* Check for available free disk space */
     271        if (   this->File.pWEBM
     272            && this->File.pWEBM->GetAvailableSpace() < 0x100000) /** @todo r=andy WTF? Fix this. */
     273        {
     274            LogRel(("VideoRec: Not enough free storage space available, stopping video capture\n"));
     275            return true;
     276        }
     277    }
     278
     279    return false;
     280}
     281
     282bool CaptureStream::IsReady(void) const
     283{
     284    return this->fEnabled;
    172285}
    173286
     
    178291 *
    179292 * @returns IPRT status code.
    180  * @param   pStream             Recording stream to process.
    181  */
    182 int VideoRecStreamProcess(PVIDEORECSTREAM pStream)
    183 {
    184     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    185 
    186     VideoRecStreamLock(pStream);
    187 
    188     if (!pStream->fEnabled)
    189     {
    190         VideoRecStreamUnlock(pStream);
     293 * @param   mapBlocksCommon     Map of common block to process for this stream.
     294 */
     295int CaptureStream::Process(VideoRecBlockMap &mapBlocksCommon)
     296{
     297    lock();
     298
     299    if (!Settings.fEnabled)
     300    {
     301        unlock();
    191302        return VINF_SUCCESS;
    192303    }
     
    194305    int rc = VINF_SUCCESS;
    195306
    196     const PVIDEORECCONTEXT pCtx = pStream->pCtx;
    197     AssertPtr(pCtx);
    198 
    199     VideoRecBlockMap::iterator itStreamBlocks = pStream->Blocks.Map.begin();
    200     while (itStreamBlocks != pStream->Blocks.Map.end())
     307    VideoRecBlockMap::iterator itStreamBlocks = Blocks.Map.begin();
     308    while (itStreamBlocks != Blocks.Map.end())
    201309    {
    202310        const uint64_t        uTimeStampMs = itStreamBlocks->first;
    203               VideoRecBlocks *pBlocks      = itStreamBlocks->second;
     311              CaptureBlocks *pBlocks       = itStreamBlocks->second;
    204312
    205313        AssertPtr(pBlocks);
     
    217325                rc = videoRecRGBToYUV(pVideoFrame->uPixelFormat,
    218326                                      /* Destination */
    219                                       pStream->Video.Codec.VPX.pu8YuvBuf, pVideoFrame->uWidth, pVideoFrame->uHeight,
     327                                      this->Video.Codec.VPX.pu8YuvBuf, pVideoFrame->uWidth, pVideoFrame->uHeight,
    220328                                      /* Source */
    221                                       pVideoFrame->pu8RGBBuf, pStream->Video.uWidth, pStream->Video.uHeight);
     329                                      pVideoFrame->pu8RGBBuf, this->Settings.Video.ulWidth, this->Settings.Video.ulHeight);
    222330                if (RT_SUCCESS(rc))
    223331                {
    224                     rc = VideoRecStreamWriteVideoVPX(pStream, uTimeStampMs, pVideoFrame);
     332                    rc = writeVideoVPX(uTimeStampMs, pVideoFrame);
    225333                }
    226334                else
     
    238346
    239347#ifdef VBOX_WITH_AUDIO_VIDEOREC
     348    AssertPtr(pCtx);
     349
    240350    /* As each (enabled) screen has to get the same audio data, look for common (audio) data which needs to be
    241351     * written to the screen's assigned recording stream. */
    242     VideoRecBlockMap::iterator itCommonBlocks = pCtx->mapBlocksCommon.begin();
    243     while (itCommonBlocks != pCtx->mapBlocksCommon.end())
     352    VideoRecBlockMap::iterator itCommonBlocks = mapBlocksCommon.begin();
     353    while (itCommonBlocks != mapBlocksCommon.end())
    244354    {
    245355        VideoRecBlockList::iterator itBlock = itCommonBlocks->second->List.begin();
     
    258368                    WebMWriter::BlockData_Opus blockData = { pAudioFrame->pvBuf, pAudioFrame->cbBuf,
    259369                                                             pBlockCommon->uTimeStampMs };
    260                     AssertPtr(pStream->File.pWEBM);
    261                     rc = pStream->File.pWEBM->WriteBlock(pStream->uTrackAudio, &blockData, sizeof(blockData));
     370                    AssertPtr(this->File.pWEBM);
     371                    rc = this->File.pWEBM->WriteBlock(this->uTrackAudio, &blockData, sizeof(blockData));
    262372                    break;
    263373                }
     
    287397        {
    288398            delete itCommonBlocks->second;
    289             pCtx->mapBlocksCommon.erase(itCommonBlocks);
    290             itCommonBlocks = pCtx->mapBlocksCommon.begin();
     399            mapBlocksCommon.erase(itCommonBlocks);
     400            itCommonBlocks = mapBlocksCommon.begin();
    291401        }
    292402        else
    293403            ++itCommonBlocks;
    294404
    295         LogFunc(("Common blocks: %zu\n", pCtx->mapBlocksCommon.size()));
     405        LogFunc(("Common blocks: %zu\n", mapBlocksCommon.size()));
    296406
    297407        if (RT_FAILURE(rc))
     
    300410#endif
    301411
    302     VideoRecStreamUnlock(pStream);
     412    unlock();
    303413
    304414    return rc;
    305415}
    306416
     417int CaptureStream::SendVideoFrame(uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP, uint32_t uBytesPerLine,
     418                                  uint32_t uSrcWidth, uint32_t uSrcHeight, uint8_t *puSrcData, uint64_t uTimeStampMs)
     419{
     420    lock();
     421
     422    PVIDEORECVIDEOFRAME pFrame = NULL;
     423
     424    int rc = VINF_SUCCESS;
     425
     426    do
     427    {
     428        if (!this->fEnabled)
     429        {
     430            rc = VINF_TRY_AGAIN; /* Not (yet) enabled. */
     431            break;
     432        }
     433
     434        if (uTimeStampMs < this->Video.uLastTimeStampMs + this->Video.uDelayMs)
     435        {
     436            rc = VINF_TRY_AGAIN; /* Respect maximum frames per second. */
     437            break;
     438        }
     439
     440        this->Video.uLastTimeStampMs = uTimeStampMs;
     441
     442        int xDiff = ((int)this->Settings.Video.ulWidth - (int)uSrcWidth) / 2;
     443        uint32_t w = uSrcWidth;
     444        if ((int)w + xDiff + (int)x <= 0)  /* Nothing visible. */
     445        {
     446            rc = VERR_INVALID_PARAMETER;
     447            break;
     448        }
     449
     450        uint32_t destX;
     451        if ((int)x < -xDiff)
     452        {
     453            w += xDiff + x;
     454            x = -xDiff;
     455            destX = 0;
     456        }
     457        else
     458            destX = x + xDiff;
     459
     460        uint32_t h = uSrcHeight;
     461        int yDiff = ((int)this->Settings.Video.ulHeight - (int)uSrcHeight) / 2;
     462        if ((int)h + yDiff + (int)y <= 0)  /* Nothing visible. */
     463        {
     464            rc = VERR_INVALID_PARAMETER;
     465            break;
     466        }
     467
     468        uint32_t destY;
     469        if ((int)y < -yDiff)
     470        {
     471            h += yDiff + (int)y;
     472            y = -yDiff;
     473            destY = 0;
     474        }
     475        else
     476            destY = y + yDiff;
     477
     478        if (   destX > this->Settings.Video.ulWidth
     479            || destY > this->Settings.Video.ulHeight)
     480        {
     481            rc = VERR_INVALID_PARAMETER;  /* Nothing visible. */
     482            break;
     483        }
     484
     485        if (destX + w > this->Settings.Video.ulWidth)
     486            w = this->Settings.Video.ulWidth - destX;
     487
     488        if (destY + h > this->Settings.Video.ulHeight)
     489            h = this->Settings.Video.ulHeight - destY;
     490
     491        pFrame = (PVIDEORECVIDEOFRAME)RTMemAllocZ(sizeof(VIDEORECVIDEOFRAME));
     492        AssertBreakStmt(pFrame, rc = VERR_NO_MEMORY);
     493
     494        /* Calculate bytes per pixel and set pixel format. */
     495        const unsigned uBytesPerPixel = uBPP / 8;
     496        if (uPixelFormat == BitmapFormat_BGR)
     497        {
     498            switch (uBPP)
     499            {
     500                case 32:
     501                    pFrame->uPixelFormat = VIDEORECPIXELFMT_RGB32;
     502                    break;
     503                case 24:
     504                    pFrame->uPixelFormat = VIDEORECPIXELFMT_RGB24;
     505                    break;
     506                case 16:
     507                    pFrame->uPixelFormat = VIDEORECPIXELFMT_RGB565;
     508                    break;
     509                default:
     510                    AssertMsgFailedBreakStmt(("Unknown color depth (%RU32)\n", uBPP), rc = VERR_NOT_SUPPORTED);
     511                    break;
     512            }
     513        }
     514        else
     515            AssertMsgFailedBreakStmt(("Unknown pixel format (%RU32)\n", uPixelFormat), rc = VERR_NOT_SUPPORTED);
     516
     517        const size_t cbRGBBuf =   this->Settings.Video.ulWidth
     518                                * this->Settings.Video.ulHeight
     519                                * uBytesPerPixel;
     520        AssertBreakStmt(cbRGBBuf, rc = VERR_INVALID_PARAMETER);
     521
     522        pFrame->pu8RGBBuf = (uint8_t *)RTMemAlloc(cbRGBBuf);
     523        AssertBreakStmt(pFrame->pu8RGBBuf, rc = VERR_NO_MEMORY);
     524        pFrame->cbRGBBuf  = cbRGBBuf;
     525        pFrame->uWidth    = uSrcWidth;
     526        pFrame->uHeight   = uSrcHeight;
     527
     528        /* If the current video frame is smaller than video resolution we're going to encode,
     529         * clear the frame beforehand to prevent artifacts. */
     530        if (   uSrcWidth  < this->Settings.Video.ulWidth
     531            || uSrcHeight < this->Settings.Video.ulHeight)
     532        {
     533            RT_BZERO(pFrame->pu8RGBBuf, pFrame->cbRGBBuf);
     534        }
     535
     536        /* Calculate start offset in source and destination buffers. */
     537        uint32_t offSrc = y * uBytesPerLine + x * uBytesPerPixel;
     538        uint32_t offDst = (destY * this->Settings.Video.ulWidth + destX) * uBytesPerPixel;
     539
     540#ifdef VBOX_VIDEOREC_DUMP
     541        VIDEORECBMPHDR bmpHdr;
     542        RT_ZERO(bmpHdr);
     543
     544        VIDEORECBMPDIBHDR bmpDIBHdr;
     545        RT_ZERO(bmpDIBHdr);
     546
     547        bmpHdr.u16Magic   = 0x4d42; /* Magic */
     548        bmpHdr.u32Size    = (uint32_t)(sizeof(VIDEORECBMPHDR) + sizeof(VIDEORECBMPDIBHDR) + (w * h * uBytesPerPixel));
     549        bmpHdr.u32OffBits = (uint32_t)(sizeof(VIDEORECBMPHDR) + sizeof(VIDEORECBMPDIBHDR));
     550
     551        bmpDIBHdr.u32Size          = sizeof(VIDEORECBMPDIBHDR);
     552        bmpDIBHdr.u32Width         = w;
     553        bmpDIBHdr.u32Height        = h;
     554        bmpDIBHdr.u16Planes        = 1;
     555        bmpDIBHdr.u16BitCount      = uBPP;
     556        bmpDIBHdr.u32XPelsPerMeter = 5000;
     557        bmpDIBHdr.u32YPelsPerMeter = 5000;
     558
     559        char szFileName[RTPATH_MAX];
     560        RTStrPrintf2(szFileName, sizeof(szFileName), "/tmp/VideoRecFrame-%RU32.bmp", this->uScreenID);
     561
     562        RTFILE fh;
     563        int rc2 = RTFileOpen(&fh, szFileName,
     564                             RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
     565        if (RT_SUCCESS(rc2))
     566        {
     567            RTFileWrite(fh, &bmpHdr,    sizeof(bmpHdr),    NULL);
     568            RTFileWrite(fh, &bmpDIBHdr, sizeof(bmpDIBHdr), NULL);
     569        }
     570#endif
     571        Assert(pFrame->cbRGBBuf >= w * h * uBytesPerPixel);
     572
     573        /* Do the copy. */
     574        for (unsigned int i = 0; i < h; i++)
     575        {
     576            /* Overflow check. */
     577            Assert(offSrc + w * uBytesPerPixel <= uSrcHeight * uBytesPerLine);
     578            Assert(offDst + w * uBytesPerPixel <= this->Settings.Video.ulHeight * this->Settings.Video.ulWidth * uBytesPerPixel);
     579
     580            memcpy(pFrame->pu8RGBBuf + offDst, puSrcData + offSrc, w * uBytesPerPixel);
     581
     582#ifdef VBOX_VIDEOREC_DUMP
     583            if (RT_SUCCESS(rc2))
     584                RTFileWrite(fh, pFrame->pu8RGBBuf + offDst, w * uBytesPerPixel, NULL);
     585#endif
     586            offSrc += uBytesPerLine;
     587            offDst += this->Settings.Video.ulWidth * uBytesPerPixel;
     588        }
     589
     590#ifdef VBOX_VIDEOREC_DUMP
     591        if (RT_SUCCESS(rc2))
     592            RTFileClose(fh);
     593#endif
     594
     595    } while (0);
     596
     597    if (rc == VINF_SUCCESS) /* Note: Also could be VINF_TRY_AGAIN. */
     598    {
     599        PVIDEORECBLOCK pBlock = (PVIDEORECBLOCK)RTMemAlloc(sizeof(VIDEORECBLOCK));
     600        if (pBlock)
     601        {
     602            AssertPtr(pFrame);
     603
     604            pBlock->enmType = VIDEORECBLOCKTYPE_VIDEO;
     605            pBlock->pvData  = pFrame;
     606            pBlock->cbData  = sizeof(VIDEORECVIDEOFRAME) + pFrame->cbRGBBuf;
     607
     608            try
     609            {
     610                CaptureBlocks *pVideoRecBlocks = new CaptureBlocks();
     611                pVideoRecBlocks->List.push_back(pBlock);
     612
     613                Assert(this->Blocks.Map.find(uTimeStampMs) == this->Blocks.Map.end());
     614                this->Blocks.Map.insert(std::make_pair(uTimeStampMs, pVideoRecBlocks));
     615            }
     616            catch (const std::exception &ex)
     617            {
     618                RT_NOREF(ex);
     619
     620                RTMemFree(pBlock);
     621                rc = VERR_NO_MEMORY;
     622            }
     623        }
     624        else
     625            rc = VERR_NO_MEMORY;
     626    }
     627
     628    if (RT_FAILURE(rc))
     629        VideoRecVideoFrameFree(pFrame);
     630
     631    lock();
     632
     633    return rc;
     634}
     635
     636int CaptureStream::Init(uint32_t a_uScreen, const settings::CaptureScreenSettings &a_Settings)
     637{
     638    return initInternal(a_uScreen, a_Settings);
     639}
     640
    307641/**
    308642 * Initializes a recording stream.
    309643 *
    310644 * @returns IPRT status code.
    311  * @param   pStream             Recording stream to initialize.
    312  * @param   pCtx                Recording context to use for initialization.
    313  * @param   uScreen             Screen number to record.
    314  */
    315 int VideoRecStreamInit(PVIDEORECSTREAM pStream, PVIDEORECCONTEXT pCtx, uint32_t uScreen)
    316 {
    317     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    318     AssertPtrReturn(pCtx,    VERR_INVALID_POINTER);
    319 
    320     PVIDEORECCFG pCfg = &pCtx->Cfg;
    321 
    322 #ifdef VBOX_WITH_AUDIO_VIDEOREC
    323     if (pCfg->Audio.fEnabled)
    324     {
    325         /* Sanity. */
    326         AssertReturn(pCfg->Audio.uHz,       VERR_INVALID_PARAMETER);
    327         AssertReturn(pCfg->Audio.cBits,     VERR_INVALID_PARAMETER);
    328         AssertReturn(pCfg->Audio.cChannels, VERR_INVALID_PARAMETER);
    329     }
    330 #endif
    331 
    332     int rc = VideoRecStreamOpen(pStream, pCfg);
     645 * @param   uScreen             Screen number to use for this recording stream.
     646 * @param   Cfg                 Recording screen configuration to use for initialization.
     647 */
     648int CaptureStream::initInternal(uint32_t a_uScreen, const settings::CaptureScreenSettings &a_Settings)
     649{
     650    int rc = parseOptionsString(a_Settings.strOptions);
    333651    if (RT_FAILURE(rc))
    334652        return rc;
    335653
    336     if (pCfg->Video.fEnabled)
    337         rc = VideoRecStreamInitVideo(pStream, pCfg);
    338 
    339     switch (pStream->enmDst)
    340     {
    341         case VIDEORECDEST_FILE:
    342         {
    343             rc = pStream->File.pWEBM->OpenEx(pStream->File.pszFile, &pStream->File.hFile,
     654    rc = RTCritSectInit(&this->CritSect);
     655    if (RT_FAILURE(rc))
     656        return rc;
     657
     658    rc = open();
     659    if (RT_FAILURE(rc))
     660        return rc;
     661
     662    const bool fVideoEnabled = a_Settings.isFeatureEnabled(CaptureFeature_Video);
     663    const bool fAudioEnabled = a_Settings.isFeatureEnabled(CaptureFeature_Audio);
     664
     665    if (fVideoEnabled)
     666        rc = initVideo();
     667
     668    if (fAudioEnabled)
     669        rc = initAudio();
     670
     671    switch (this->Settings.enmDest)
     672    {
     673        case CaptureDestination_File:
     674        {
     675            const char *pszFile = this->Settings.File.strName.c_str();
     676
     677            rc = File.pWEBM->OpenEx(pszFile, &this->File.hFile,
    344678#ifdef VBOX_WITH_AUDIO_VIDEOREC
    345                                              pCfg->Audio.fEnabled ? WebMWriter::AudioCodec_Opus : WebMWriter::AudioCodec_None,
     679                                      a_Settings.isFeatureEnabled(CaptureFeature_Audio)
     680                                    ? WebMWriter::AudioCodec_Opus : WebMWriter::AudioCodec_None,
    346681#else
    347                                              WebMWriter::AudioCodec_None,
    348 #endif
    349                                              pCfg->Video.fEnabled ? WebMWriter::VideoCodec_VP8 : WebMWriter::VideoCodec_None);
     682                                      WebMWriter::AudioCodec_None,
     683#endif
     684                                      a_Settings.isFeatureEnabled(CaptureFeature_Video)
     685                                    ? WebMWriter::VideoCodec_VP8 : WebMWriter::VideoCodec_None);
    350686            if (RT_FAILURE(rc))
    351687            {
    352                 LogRel(("VideoRec: Failed to create the capture output file '%s' (%Rrc)\n", pStream->File.pszFile, rc));
     688                LogRel(("VideoRec: Failed to create the capture output file '%s' (%Rrc)\n", pszFile, rc));
    353689                break;
    354690            }
    355691
    356             const char *pszFile = pStream->File.pszFile;
    357 
    358             if (pCfg->Video.fEnabled)
    359             {
    360                 rc = pStream->File.pWEBM->AddVideoTrack(pCfg->Video.uWidth, pCfg->Video.uHeight, pCfg->Video.uFPS,
    361                                                         &pStream->uTrackVideo);
     692            if (fVideoEnabled)
     693            {
     694                rc = this->File.pWEBM->AddVideoTrack(a_Settings.Video.ulWidth, a_Settings.Video.ulHeight,
     695                                                     a_Settings.Video.ulFPS, &this->uTrackVideo);
    362696                if (RT_FAILURE(rc))
    363697                {
     
    367701
    368702                LogRel(("VideoRec: Recording video of screen #%u with %RU32x%RU32 @ %RU32 kbps, %RU32 FPS (track #%RU8)\n",
    369                         uScreen, pCfg->Video.uWidth, pCfg->Video.uHeight, pCfg->Video.uRate, pCfg->Video.uFPS,
    370                         pStream->uTrackVideo));
     703                        this->uScreenID, a_Settings.Video.ulWidth, a_Settings.Video.ulHeight, a_Settings.Video.ulRate,
     704                        a_Settings.Video.ulFPS, this->uTrackVideo));
    371705            }
    372706
    373707#ifdef VBOX_WITH_AUDIO_VIDEOREC
    374             if (pCfg->Audio.fEnabled)
    375             {
    376                 rc = pStream->File.pWEBM->AddAudioTrack(pCfg->Audio.uHz, pCfg->Audio.cChannels, pCfg->Audio.cBits,
    377                                                         &pStream->uTrackAudio);
     708            if (fAudioEnabled)
     709            {
     710                rc = this->File.pWEBM->AddAudioTrack(a_Settings.Audio.uHz, a_Settings.Audio.cChannels, a_Settings.Audio.cBits,
     711                                                     &this->uTrackAudio);
    378712                if (RT_FAILURE(rc))
    379713                {
     
    383717
    384718                LogRel(("VideoRec: Recording audio in %RU16Hz, %RU8 bit, %RU8 %s (track #%RU8)\n",
    385                         pCfg->Audio.uHz, pCfg->Audio.cBits, pCfg->Audio.cChannels, pCfg->Audio.cChannels ? "channels" : "channel",
    386                         pStream->uTrackAudio));
    387             }
    388 #endif
    389 
    390             if (   pCfg->Video.fEnabled
     719                        a_Settings.Audio.uHz, a_Settings.Audio.cBits, a_Settings.Audio.cChannels,
     720                        a_Settings.Audio.cChannels ? "channels" : "channel", this->uTrackAudio));
     721            }
     722#endif
     723
     724            if (   fVideoEnabled
    391725#ifdef VBOX_WITH_AUDIO_VIDEOREC
    392                 || pCfg->Audio.fEnabled
     726                || fAudioEnabled
    393727#endif
    394728               )
    395729            {
    396730                char szWhat[32] = { 0 };
    397                 if (pCfg->Video.fEnabled)
     731                if (fVideoEnabled)
    398732                    RTStrCat(szWhat, sizeof(szWhat), "video");
    399733#ifdef VBOX_WITH_AUDIO_VIDEOREC
    400                 if (pCfg->Audio.fEnabled)
     734                if (fAudioEnabled)
    401735                {
    402                     if (pCfg->Video.fEnabled)
     736                    if (fVideoEnabled)
    403737                        RTStrCat(szWhat, sizeof(szWhat), " + ");
    404738                    RTStrCat(szWhat, sizeof(szWhat), "audio");
     
    419753    if (RT_SUCCESS(rc))
    420754    {
    421         pStream->pCtx     = pCtx;
    422         pStream->fEnabled = true;
     755        this->pCtx      = pCtx;
     756        this->fEnabled  = true;
     757        this->uScreenID = a_uScreen;
     758        this->tsStartMs = RTTimeMilliTS();
     759        this->Settings  = a_Settings;
    423760    }
    424761    else
    425762    {
    426         int rc2 = VideoRecStreamClose(pStream);
     763        int rc2 = uninitInternal();
    427764        AssertRC(rc2);
    428765        return rc;
     
    438775 *
    439776 * @returns IPRT status code.
    440  * @param   pStream             Recording stream to close.
    441  *
    442  */
    443 int VideoRecStreamClose(PVIDEORECSTREAM pStream)
     777 */
     778int CaptureStream::close(void)
    444779{
    445780    int rc = VINF_SUCCESS;
    446781
    447     if (pStream->fEnabled)
    448     {
    449         switch (pStream->enmDst)
    450         {
    451             case VIDEORECDEST_FILE:
    452             {
    453                 if (pStream->File.pWEBM)
    454                     rc = pStream->File.pWEBM->Close();
     782    if (this->fEnabled)
     783    {
     784        switch (this->Settings.enmDest)
     785        {
     786            case CaptureDestination_File:
     787            {
     788                if (this->File.pWEBM)
     789                    rc = this->File.pWEBM->Close();
    455790                break;
    456791            }
     
    461796        }
    462797
    463         pStream->Blocks.Clear();
    464 
    465         LogRel(("VideoRec: Recording screen #%u stopped\n", pStream->uScreenID));
     798        this->Blocks.Clear();
     799
     800        LogRel(("VideoRec: Recording screen #%u stopped\n", this->uScreenID));
    466801    }
    467802
    468803    if (RT_FAILURE(rc))
    469804    {
    470         LogRel(("VideoRec: Error stopping recording screen #%u, rc=%Rrc\n", pStream->uScreenID, rc));
     805        LogRel(("VideoRec: Error stopping recording screen #%u, rc=%Rrc\n", this->uScreenID, rc));
    471806        return rc;
    472807    }
    473808
    474     switch (pStream->enmDst)
    475     {
    476         case VIDEORECDEST_FILE:
    477         {
    478             AssertPtr(pStream->File.pszFile);
    479             if (RTFileIsValid(pStream->File.hFile))
    480             {
    481                 rc = RTFileClose(pStream->File.hFile);
     809    switch (this->Settings.enmDest)
     810    {
     811        case CaptureDestination_File:
     812        {
     813            if (RTFileIsValid(this->File.hFile))
     814            {
     815                rc = RTFileClose(this->File.hFile);
    482816                if (RT_SUCCESS(rc))
    483817                {
    484                     LogRel(("VideoRec: Closed file '%s'\n", pStream->File.pszFile));
     818                    LogRel(("VideoRec: Closed file '%s'\n", this->Settings.File.strName.c_str()));
    485819                }
    486820                else
    487821                {
    488                     LogRel(("VideoRec: Error closing file '%s', rc=%Rrc\n", pStream->File.pszFile, rc));
     822                    LogRel(("VideoRec: Error closing file '%s', rc=%Rrc\n", this->Settings.File.strName.c_str(), rc));
    489823                    break;
    490824                }
    491825            }
    492826
    493             RTStrFree(pStream->File.pszFile);
    494             pStream->File.pszFile = NULL;
    495 
    496             if (pStream->File.pWEBM)
    497             {
    498                 delete pStream->File.pWEBM;
    499                 pStream->File.pWEBM = NULL;
     827            if (this->File.pWEBM)
     828            {
     829                delete this->File.pWEBM;
     830                this->File.pWEBM = NULL;
    500831            }
    501832            break;
     
    507838    }
    508839
    509     if (RT_SUCCESS(rc))
    510     {
    511         pStream->enmDst = VIDEORECDEST_INVALID;
    512     }
    513 
    514840    LogFlowFuncLeaveRC(rc);
    515841    return rc;
     
    520846 *
    521847 * @returns IPRT status code.
    522  * @param   pStream             Recording stream to uninitialize.
    523  */
    524 int VideoRecStreamUninit(PVIDEORECSTREAM pStream)
    525 {
    526     int rc = VINF_SUCCESS;
    527 
    528     if (pStream->pCtx->Cfg.Video.fEnabled)
    529     {
    530         int rc2 = VideoRecStreamUnitVideo(pStream);
     848 */
     849int CaptureStream::Uninit(void)
     850{
     851    return uninitInternal();
     852}
     853
     854int CaptureStream::uninitInternal(void)
     855{
     856    int rc = close();
     857    if (RT_FAILURE(rc))
     858        return rc;
     859
     860    if (this->Settings.isFeatureEnabled(CaptureFeature_Video))
     861    {
     862        int rc2 = unitVideo();
    531863        if (RT_SUCCESS(rc))
    532864            rc = rc2;
    533865    }
    534866
     867    RTCritSectDelete(&this->CritSect);
     868
     869    this->fEnabled = false;
     870
    535871    return rc;
    536872}
     
    540876 *
    541877 * @returns IPRT status code.
    542  * @param   pStream             Recording stream to uninitialize video recording for.
    543  */
    544 int VideoRecStreamUnitVideo(PVIDEORECSTREAM pStream)
     878 */
     879int CaptureStream::unitVideo(void)
    545880{
    546881#ifdef VBOX_WITH_LIBVPX
    547882    /* At the moment we only have VPX. */
    548     return VideoRecStreamUninitVideoVPX(pStream);
     883    return uninitVideoVPX();
    549884#else
    550885    return VERR_NOT_SUPPORTED;
     
    557892 *
    558893 * @returns IPRT status code.
    559  * @param   pStream             Recording stream to uninitialize VPX codec for.
    560  */
    561 int VideoRecStreamUninitVideoVPX(PVIDEORECSTREAM pStream)
    562 {
    563     vpx_img_free(&pStream->Video.Codec.VPX.RawImage);
    564     vpx_codec_err_t rcv = vpx_codec_destroy(&pStream->Video.Codec.VPX.Ctx);
     894 */
     895int CaptureStream::uninitVideoVPX(void)
     896{
     897    vpx_img_free(&this->Video.Codec.VPX.RawImage);
     898    vpx_codec_err_t rcv = vpx_codec_destroy(&this->Video.Codec.VPX.Ctx);
    565899    Assert(rcv == VPX_CODEC_OK); RT_NOREF(rcv);
    566900
     
    573907 *
    574908 * @returns IPRT status code.
    575  * @param   pStream             Recording stream to initialize video recording for.
    576  * @param   pCfg                Video recording configuration to use for initialization.
    577  */
    578 int VideoRecStreamInitVideo(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg)
    579 {
     909 */
     910int CaptureStream::initVideo(void)
     911{
     912    /* Sanity. */
     913    AssertReturn(this->Settings.Video.ulRate,   VERR_INVALID_PARAMETER);
     914    AssertReturn(this->Settings.Video.ulWidth,  VERR_INVALID_PARAMETER);
     915    AssertReturn(this->Settings.Video.ulHeight, VERR_INVALID_PARAMETER);
     916    AssertReturn(this->Settings.Video.ulFPS,    VERR_INVALID_PARAMETER);
     917
     918    this->Video.cFailedEncodingFrames = 0;
     919    this->Video.uDelayMs = RT_MS_1SEC / this->Settings.Video.ulFPS;
     920
    580921#ifdef VBOX_WITH_LIBVPX
    581922    /* At the moment we only have VPX. */
    582     return VideoRecStreamInitVideoVPX(pStream, pCfg);
     923    return initVideoVPX();
    583924#else
    584     return VERR_NOT_SUPPORTED;
     925    return VINF_SUCCESS;
    585926#endif
    586927}
     
    591932 *
    592933 * @returns IPRT status code.
    593  * @param   pStream             Recording stream to initialize VPX codec for.
    594  * @param   pCfg                Video recording configuration to use for initialization.
    595  */
    596 int VideoRecStreamInitVideoVPX(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg)
    597 {
    598     pStream->Video.uWidth                = pCfg->Video.uWidth;
    599     pStream->Video.uHeight               = pCfg->Video.uHeight;
    600     pStream->Video.cFailedEncodingFrames = 0;
    601 
    602     PVIDEORECVIDEOCODEC pVC = &pStream->Video.Codec;
    603 
    604     pStream->Video.uDelayMs = RT_MS_1SEC / pCfg->Video.uFPS;
    605 
    606     pVC->enmType = VIDEORECVIDEOCODECTYPE_VP8; /** @todo Make this configurable. */
    607 
     934 */
     935int CaptureStream::initVideoVPX(void)
     936{
    608937# ifdef VBOX_WITH_LIBVPX_VP9
    609938    vpx_codec_iface_t *pCodecIface = vpx_codec_vp9_cx();
     
    612941# endif
    613942
    614     vpx_codec_err_t rcv = vpx_codec_enc_config_default(pCodecIface, &pVC->VPX.Cfg, 0 /* Reserved */);
     943    PVIDEORECVIDEOCODEC pCodec = &this->Video.Codec;
     944
     945    vpx_codec_err_t rcv = vpx_codec_enc_config_default(pCodecIface, &pCodec->VPX.Cfg, 0 /* Reserved */);
    615946    if (rcv != VPX_CODEC_OK)
    616947    {
     
    620951
    621952    /* Target bitrate in kilobits per second. */
    622     pVC->VPX.Cfg.rc_target_bitrate = pCfg->Video.uRate;
     953    pCodec->VPX.Cfg.rc_target_bitrate = this->Settings.Video.ulRate;
    623954    /* Frame width. */
    624     pVC->VPX.Cfg.g_w = pCfg->Video.uWidth;
     955    pCodec->VPX.Cfg.g_w = this->Settings.Video.ulWidth;
    625956    /* Frame height. */
    626     pVC->VPX.Cfg.g_h = pCfg->Video.uHeight;
     957    pCodec->VPX.Cfg.g_h = this->Settings.Video.ulHeight;
    627958    /* 1ms per frame. */
    628     pVC->VPX.Cfg.g_timebase.num = 1;
    629     pVC->VPX.Cfg.g_timebase.den = 1000;
     959    pCodec->VPX.Cfg.g_timebase.num = 1;
     960    pCodec->VPX.Cfg.g_timebase.den = 1000;
    630961    /* Disable multithreading. */
    631     pVC->VPX.Cfg.g_threads = 0;
     962    pCodec->VPX.Cfg.g_threads = 0;
    632963
    633964    /* Initialize codec. */
    634     rcv = vpx_codec_enc_init(&pVC->VPX.Ctx, pCodecIface, &pVC->VPX.Cfg, 0 /* Flags */);
     965    rcv = vpx_codec_enc_init(&pCodec->VPX.Ctx, pCodecIface, &pCodec->VPX.Cfg, 0 /* Flags */);
    635966    if (rcv != VPX_CODEC_OK)
    636967    {
     
    639970    }
    640971
    641     if (!vpx_img_alloc(&pVC->VPX.RawImage, VPX_IMG_FMT_I420, pCfg->Video.uWidth, pCfg->Video.uHeight, 1))
    642     {
    643         LogRel(("VideoRec: Failed to allocate image %RU32x%RU32\n", pCfg->Video.uWidth, pCfg->Video.uHeight));
     972    if (!vpx_img_alloc(&pCodec->VPX.RawImage, VPX_IMG_FMT_I420,
     973                       this->Settings.Video.ulWidth, this->Settings.Video.ulHeight, 1))
     974    {
     975        LogRel(("VideoRec: Failed to allocate image %RU32x%RU32\n",
     976                this->Settings.Video.ulWidth, this->Settings.Video.ulHeight));
    644977        return VERR_NO_MEMORY;
    645978    }
    646979
    647980    /* Save a pointer to the first raw YUV plane. */
    648     pStream->Video.Codec.VPX.pu8YuvBuf = pVC->VPX.RawImage.planes[0];
     981    pCodec->VPX.pu8YuvBuf = pCodec->VPX.RawImage.planes[0];
    649982
    650983    return VINF_SUCCESS;
     
    652985#endif
    653986
     987int CaptureStream::initAudio(void)
     988{
     989#ifdef VBOX_WITH_AUDIO_VIDEOREC
     990    if (this->Settings.isFeatureEnabled(CaptureFeature_Audio))
     991    {
     992        /* Sanity. */
     993        AssertReturn(this->Settings.Audio.uHz,       VERR_INVALID_PARAMETER);
     994        AssertReturn(this->Settings.Audio.cBits,     VERR_INVALID_PARAMETER);
     995        AssertReturn(this->Settings.Audio.cChannels, VERR_INVALID_PARAMETER);
     996    }
     997#endif
     998
     999    return VINF_SUCCESS;
     1000}
     1001
    6541002#ifdef VBOX_WITH_LIBVPX
    6551003/**
     
    6571005 *
    6581006 * @returns IPRT status code.
    659  * @param   pStream             Stream to encode and submit to.
    6601007 * @param   uTimeStampMs        Absolute timestamp (PTS) of frame (in ms) to encode.
    6611008 * @param   pFrame              Frame to encode and submit.
    6621009 */
    663 int VideoRecStreamWriteVideoVPX(PVIDEORECSTREAM pStream, uint64_t uTimeStampMs, PVIDEORECVIDEOFRAME pFrame)
    664 {
    665     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    666     AssertPtrReturn(pFrame,  VERR_INVALID_POINTER);
     1010int CaptureStream::writeVideoVPX(uint64_t uTimeStampMs, PVIDEORECVIDEOFRAME pFrame)
     1011{
     1012    AssertPtrReturn(pFrame, VERR_INVALID_POINTER);
    6671013
    6681014    int rc;
    6691015
    670     AssertPtr(pStream->pCtx);
    671     PVIDEORECCFG        pCfg = &pStream->pCtx->Cfg;
    672     PVIDEORECVIDEOCODEC pVC  = &pStream->Video.Codec;
     1016    PVIDEORECVIDEOCODEC pCodec = &this->Video.Codec;
    6731017
    6741018    /* Presentation Time Stamp (PTS). */
    6751019    vpx_codec_pts_t pts = uTimeStampMs;
    676     vpx_codec_err_t rcv = vpx_codec_encode(&pVC->VPX.Ctx,
    677                                            &pVC->VPX.RawImage,
    678                                            pts                                    /* Time stamp */,
    679                                            pStream->Video.uDelayMs                /* How long to show this frame */,
    680                                            0                                      /* Flags */,
    681                                            pCfg->Video.Codec.VPX.uEncoderDeadline /* Quality setting */);
     1020    vpx_codec_err_t rcv = vpx_codec_encode(&pCodec->VPX.Ctx,
     1021                                           &pCodec->VPX.RawImage,
     1022                                           pts                          /* Time stamp */,
     1023                                           this->Video.uDelayMs         /* How long to show this frame */,
     1024                                           0                            /* Flags */,
     1025                                           pCodec->VPX.uEncoderDeadline /* Quality setting */);
    6821026    if (rcv != VPX_CODEC_OK)
    6831027    {
    684         if (pStream->Video.cFailedEncodingFrames++ < 64)
     1028        if (this->Video.cFailedEncodingFrames++ < 64) /** @todo Make this configurable. */
    6851029        {
    6861030            LogRel(("VideoRec: Failed to encode video frame: %s\n", vpx_codec_err_to_string(rcv)));
     
    6891033    }
    6901034
    691     pStream->Video.cFailedEncodingFrames = 0;
     1035    this->Video.cFailedEncodingFrames = 0;
    6921036
    6931037    vpx_codec_iter_t iter = NULL;
     
    6951039    for (;;)
    6961040    {
    697         const vpx_codec_cx_pkt_t *pPacket = vpx_codec_get_cx_data(&pVC->VPX.Ctx, &iter);
     1041        const vpx_codec_cx_pkt_t *pPacket = vpx_codec_get_cx_data(&pCodec->VPX.Ctx, &iter);
    6981042        if (!pPacket)
    6991043            break;
     
    7031047            case VPX_CODEC_CX_FRAME_PKT:
    7041048            {
    705                 WebMWriter::BlockData_VP8 blockData = { &pVC->VPX.Cfg, pPacket };
    706                 rc = pStream->File.pWEBM->WriteBlock(pStream->uTrackVideo, &blockData, sizeof(blockData));
     1049                WebMWriter::BlockData_VP8 blockData = { &pCodec->VPX.Cfg, pPacket };
     1050                rc = this->File.pWEBM->WriteBlock(this->uTrackVideo, &blockData, sizeof(blockData));
    7071051                break;
    7081052            }
     
    7191063#endif /* VBOX_WITH_LIBVPX */
    7201064
     1065/**
     1066 * Locks a recording stream.
     1067 *
     1068 * @param   pStream             Recording stream to lock.
     1069 */
     1070void CaptureStream::lock(void)
     1071{
     1072    int rc = RTCritSectEnter(&CritSect);
     1073    AssertRC(rc);
     1074}
     1075
     1076/**
     1077 * Unlocks a locked recording stream.
     1078 *
     1079 * @param   pStream             Recording stream to unlock.
     1080 */
     1081void CaptureStream::unlock(void)
     1082{
     1083    int rc = RTCritSectLeave(&CritSect);
     1084    AssertRC(rc);
     1085}
     1086
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r74804 r75251  
    55
    66/*
    7  * Copyright (C) 2004-2017 Oracle Corporation
     7 * Copyright (C) 2004-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    168168    mAccelerate2DVideoEnabled = false;
    169169    mMonitorCount = 1;
    170     mVideoCaptureWidth = 1024;
    171     mVideoCaptureHeight = 768;
    172     mVideoCaptureRate = 512;
    173     mVideoCaptureFPS = 25;
    174     mVideoCaptureMaxTime = 0;
    175     mVideoCaptureMaxFileSize = 0;
    176     mVideoCaptureEnabled = false;
    177     for (unsigned i = 0; i < RT_ELEMENTS(maVideoCaptureScreens); ++i)
    178         maVideoCaptureScreens[i] = true;
    179 
    180170    mHWVirtExEnabled = true;
    181171    mHWVirtExNestedPagingEnabled = true;
     
    365355        }
    366356
    367         /* Apply BIOS defaults */
     357        /* Apply BIOS defaults. */
    368358        mBIOSSettings->i_applyDefaults(aOsType);
     359
     360        /* Apply capture defaults. */
     361        mCaptureSettings->i_applyDefaults();
    369362
    370363        /* Apply network adapters defaults */
     
    17321725}
    17331726
    1734 HRESULT Machine::getVideoCaptureEnabled(BOOL *aVideoCaptureEnabled)
    1735 {
    1736     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1737 
    1738     *aVideoCaptureEnabled = mHWData->mVideoCaptureEnabled;
    1739     return S_OK;
    1740 }
    1741 
    1742 HRESULT Machine::setVideoCaptureEnabled(BOOL aVideoCaptureEnabled)
    1743 {
    1744     HRESULT rc = S_OK;
    1745 
    1746     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1747 
    1748     i_setModified(IsModified_MachineData);
    1749     mHWData.backup();
    1750     mHWData->mVideoCaptureEnabled = aVideoCaptureEnabled;
    1751 
    1752     alock.release();
    1753     rc = i_onVideoCaptureChange();
    1754     alock.acquire();
    1755     if (FAILED(rc))
    1756     {
    1757         /*
    1758          * Normally we would do the actual change _after_ i_onVideoCaptureChange() succeeded.
    1759          * We cannot do this because that function uses Machine::GetVideoCaptureEnabled to
    1760          * determine if it should start or stop capturing. Therefore we need to manually
    1761          * undo change.
    1762          */
    1763         mHWData->mVideoCaptureEnabled = mHWData.backedUpData()->mVideoCaptureEnabled;
    1764         return rc;
    1765     }
    1766 
    1767     /** Save settings if online - @todo why is this required? -- @bugref{6818} */
    1768     if (Global::IsOnline(mData->mMachineState))
    1769         i_saveSettings(NULL);
    1770 
    1771     return rc;
    1772 }
    1773 
    1774 HRESULT Machine::getVideoCaptureScreens(std::vector<BOOL> &aVideoCaptureScreens)
    1775 {
    1776     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1777     aVideoCaptureScreens.resize(mHWData->mMonitorCount);
    1778     for (unsigned i = 0; i < mHWData->mMonitorCount; ++i)
    1779         aVideoCaptureScreens[i] = mHWData->maVideoCaptureScreens[i];
    1780     return S_OK;
    1781 }
    1782 
    1783 HRESULT Machine::setVideoCaptureScreens(const std::vector<BOOL> &aVideoCaptureScreens)
    1784 {
    1785     AssertReturn(aVideoCaptureScreens.size() <= RT_ELEMENTS(mHWData->maVideoCaptureScreens), E_INVALIDARG);
    1786     bool fChanged = false;
    1787 
    1788     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1789 
    1790     for (unsigned i = 0; i < aVideoCaptureScreens.size(); ++i)
    1791     {
    1792         if (mHWData->maVideoCaptureScreens[i] != RT_BOOL(aVideoCaptureScreens[i]))
    1793         {
    1794             mHWData->maVideoCaptureScreens[i] = RT_BOOL(aVideoCaptureScreens[i]);
    1795             fChanged = true;
    1796         }
    1797     }
    1798     if (fChanged)
    1799     {
    1800         alock.release();
    1801         HRESULT rc = i_onVideoCaptureChange();
    1802         alock.acquire();
    1803         if (FAILED(rc)) return rc;
    1804         i_setModified(IsModified_MachineData);
    1805 
    1806         /** Save settings if online - @todo why is this required? -- @bugref{6818} */
    1807         if (Global::IsOnline(mData->mMachineState))
    1808             i_saveSettings(NULL);
    1809     }
    1810 
    1811     return S_OK;
    1812 }
    1813 
    1814 HRESULT Machine::getVideoCaptureFile(com::Utf8Str &aVideoCaptureFile)
    1815 {
    1816     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1817     if (mHWData->mVideoCaptureFile.isEmpty())
    1818         i_getDefaultVideoCaptureFile(aVideoCaptureFile);
    1819     else
    1820         aVideoCaptureFile = mHWData->mVideoCaptureFile;
    1821     return S_OK;
    1822 }
    1823 
    1824 HRESULT Machine::setVideoCaptureFile(const com::Utf8Str &aVideoCaptureFile)
    1825 {
    1826     Utf8Str strFile(aVideoCaptureFile);
    1827     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1828 
    1829     if (   Global::IsOnline(mData->mMachineState)
    1830         && mHWData->mVideoCaptureEnabled)
    1831         return setError(E_INVALIDARG, tr("Cannot change parameters while capturing is enabled"));
    1832 
    1833     if (!RTPathStartsWithRoot(strFile.c_str()))
    1834         return setError(E_INVALIDARG, tr("Video capture file name '%s' is not absolute"), strFile.c_str());
    1835 
    1836     if (!strFile.isEmpty())
    1837     {
    1838         Utf8Str defaultFile;
    1839         i_getDefaultVideoCaptureFile(defaultFile);
    1840         if (!RTPathCompare(strFile.c_str(), defaultFile.c_str()))
    1841             strFile.setNull();
    1842     }
    1843 
    1844     i_setModified(IsModified_MachineData);
    1845     mHWData.backup();
    1846     mHWData->mVideoCaptureFile = strFile;
    1847 
    1848     return S_OK;
    1849 }
    1850 
    1851 HRESULT Machine::getVideoCaptureWidth(ULONG *aVideoCaptureWidth)
    1852 {
    1853     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1854     *aVideoCaptureWidth = mHWData->mVideoCaptureWidth;
    1855     return S_OK;
    1856 }
    1857 
    1858 HRESULT Machine::setVideoCaptureWidth(ULONG aVideoCaptureWidth)
    1859 {
    1860     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1861 
    1862     if (   Global::IsOnline(mData->mMachineState)
    1863         && mHWData->mVideoCaptureEnabled)
    1864         return setError(E_INVALIDARG, tr("Cannot change parameters while capturing is enabled"));
    1865 
    1866     i_setModified(IsModified_MachineData);
    1867     mHWData.backup();
    1868     mHWData->mVideoCaptureWidth = aVideoCaptureWidth;
    1869 
    1870     return S_OK;
    1871 }
    1872 
    1873 HRESULT Machine::getVideoCaptureHeight(ULONG *aVideoCaptureHeight)
    1874 {
    1875     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1876     *aVideoCaptureHeight = mHWData->mVideoCaptureHeight;
    1877     return S_OK;
    1878 }
    1879 
    1880 HRESULT Machine::setVideoCaptureHeight(ULONG aVideoCaptureHeight)
    1881 {
    1882     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1883 
    1884     if (   Global::IsOnline(mData->mMachineState)
    1885         && mHWData->mVideoCaptureEnabled)
    1886         return setError(E_INVALIDARG, tr("Cannot change parameters while capturing is enabled"));
    1887 
    1888     i_setModified(IsModified_MachineData);
    1889     mHWData.backup();
    1890     mHWData->mVideoCaptureHeight = aVideoCaptureHeight;
    1891 
    1892     return S_OK;
    1893 }
    1894 
    1895 HRESULT Machine::getVideoCaptureRate(ULONG *aVideoCaptureRate)
    1896 {
    1897     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1898     *aVideoCaptureRate = mHWData->mVideoCaptureRate;
    1899     return S_OK;
    1900 }
    1901 
    1902 HRESULT Machine::setVideoCaptureRate(ULONG aVideoCaptureRate)
    1903 {
    1904     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1905 
    1906     if (   Global::IsOnline(mData->mMachineState)
    1907         && mHWData->mVideoCaptureEnabled)
    1908         return setError(E_INVALIDARG, tr("Cannot change parameters while capturing is enabled"));
    1909 
    1910     i_setModified(IsModified_MachineData);
    1911     mHWData.backup();
    1912     mHWData->mVideoCaptureRate = aVideoCaptureRate;
    1913 
    1914     return S_OK;
    1915 }
    1916 
    1917 HRESULT Machine::getVideoCaptureFPS(ULONG *aVideoCaptureFPS)
    1918 {
    1919     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1920     *aVideoCaptureFPS = mHWData->mVideoCaptureFPS;
    1921     return S_OK;
    1922 }
    1923 
    1924 HRESULT Machine::setVideoCaptureFPS(ULONG aVideoCaptureFPS)
    1925 {
    1926     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1927 
    1928     if (   Global::IsOnline(mData->mMachineState)
    1929         && mHWData->mVideoCaptureEnabled)
    1930         return setError(E_INVALIDARG, tr("Cannot change parameters while capturing is enabled"));
    1931 
    1932     i_setModified(IsModified_MachineData);
    1933     mHWData.backup();
    1934     mHWData->mVideoCaptureFPS = aVideoCaptureFPS;
    1935 
    1936     return S_OK;
    1937 }
    1938 
    1939 HRESULT Machine::getVideoCaptureMaxTime(ULONG *aVideoCaptureMaxTime)
    1940 {
    1941     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1942     *aVideoCaptureMaxTime = mHWData->mVideoCaptureMaxTime;
    1943     return S_OK;
    1944 }
    1945 
    1946 HRESULT Machine::setVideoCaptureMaxTime(ULONG aVideoCaptureMaxTime)
    1947 {
    1948     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1949 
    1950     if (   Global::IsOnline(mData->mMachineState)
    1951         && mHWData->mVideoCaptureEnabled)
    1952         return setError(E_INVALIDARG, tr("Cannot change parameters while capturing is enabled"));
    1953 
    1954     i_setModified(IsModified_MachineData);
    1955     mHWData.backup();
    1956     mHWData->mVideoCaptureMaxTime = aVideoCaptureMaxTime;
    1957 
    1958     return S_OK;
    1959 }
    1960 
    1961 HRESULT Machine::getVideoCaptureMaxFileSize(ULONG *aVideoCaptureMaxFileSize)
    1962 {
    1963     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1964     *aVideoCaptureMaxFileSize = mHWData->mVideoCaptureMaxFileSize;
    1965     return S_OK;
    1966 }
    1967 
    1968 HRESULT Machine::setVideoCaptureMaxFileSize(ULONG aVideoCaptureMaxFileSize)
    1969 {
    1970     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1971 
    1972     if (   Global::IsOnline(mData->mMachineState)
    1973         && mHWData->mVideoCaptureEnabled)
    1974         return setError(E_INVALIDARG, tr("Cannot change parameters while capturing is enabled"));
    1975 
    1976     i_setModified(IsModified_MachineData);
    1977     mHWData.backup();
    1978     mHWData->mVideoCaptureMaxFileSize = aVideoCaptureMaxFileSize;
    1979 
    1980     return S_OK;
    1981 }
    1982 
    1983 HRESULT Machine::getVideoCaptureOptions(com::Utf8Str &aVideoCaptureOptions)
    1984 {
    1985     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1986 
    1987     aVideoCaptureOptions = mHWData->mVideoCaptureOptions;
    1988     return S_OK;
    1989 }
    1990 
    1991 HRESULT Machine::setVideoCaptureOptions(const com::Utf8Str &aVideoCaptureOptions)
    1992 {
    1993     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1994 
    1995     if (   Global::IsOnline(mData->mMachineState)
    1996         && mHWData->mVideoCaptureEnabled)
    1997         return setError(E_INVALIDARG, tr("Cannot change parameters while capturing is enabled"));
    1998 
    1999     i_setModified(IsModified_MachineData);
    2000     mHWData.backup();
    2001     mHWData->mVideoCaptureOptions = aVideoCaptureOptions;
    2002 
    2003     return S_OK;
    2004 }
    2005 
    20061727HRESULT Machine::getGraphicsControllerType(GraphicsControllerType_T *aGraphicsControllerType)
    20071728{
     
    22151936    /* mBIOSSettings is constant during life time, no need to lock */
    22161937    aBIOSSettings = mBIOSSettings;
     1938
     1939    return S_OK;
     1940}
     1941
     1942HRESULT Machine::getCaptureSettings(ComPtr<ICaptureSettings> &aCaptureSettings)
     1943{
     1944    /* mCaptureSettings is constant during life time, no need to lock */
     1945    aCaptureSettings = mCaptureSettings;
    22171946
    22181947    return S_OK;
     
    76547383
    76557384/**
    7656  *  Returns the full path to the default video capture file.
    7657  */
    7658 void Machine::i_getDefaultVideoCaptureFile(Utf8Str &strFile)
    7659 {
    7660     AutoCaller autoCaller(this);
    7661     AssertComRCReturnVoid(autoCaller.rc());
    7662 
    7663     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    7664 
    7665     strFile = mData->m_strConfigFileFull;       // path/to/machinesfolder/vmname/vmname.vbox
    7666     strFile.stripSuffix();                      // path/to/machinesfolder/vmname/vmname
    7667     strFile.append(".webm");                    // path/to/machinesfolder/vmname/vmname.webm
    7668 }
    7669 
    7670 /**
    76717385 * Returns whether at least one USB controller is present for the VM.
    76727386 */
     
    85458259    mBIOSSettings->init(this);
    85468260
     8261    /* create associated capture settings object */
     8262    unconst(mCaptureSettings).createObject();
     8263    mCaptureSettings->init(this);
     8264
    85478265    /* create an associated VRDE object (default is disabled) */
    85488266    unconst(mVRDEServer).createObject();
     
    86588376        mBIOSSettings->uninit();
    86598377        unconst(mBIOSSettings).setNull();
     8378    }
     8379
     8380    if (mCaptureSettings)
     8381    {
     8382        mCaptureSettings->uninit();
     8383        unconst(mCaptureSettings).setNull();
    86608384    }
    86618385
     
    91578881        mHWData->mAccelerate3DEnabled = data.fAccelerate3D;
    91588882        mHWData->mAccelerate2DVideoEnabled = data.fAccelerate2DVideo;
    9159         mHWData->mVideoCaptureWidth = data.ulVideoCaptureHorzRes;
    9160         mHWData->mVideoCaptureHeight = data.ulVideoCaptureVertRes;
    9161         mHWData->mVideoCaptureEnabled = data.fVideoCaptureEnabled;
    9162         for (unsigned i = 0; i < RT_ELEMENTS(mHWData->maVideoCaptureScreens); ++i)
    9163             mHWData->maVideoCaptureScreens[i] = ASMBitTest(&data.u64VideoCaptureScreens, i);
    9164         AssertCompile(RT_ELEMENTS(mHWData->maVideoCaptureScreens) == sizeof(data.u64VideoCaptureScreens) * 8);
    9165         mHWData->mVideoCaptureRate = data.ulVideoCaptureRate;
    9166         mHWData->mVideoCaptureFPS = data.ulVideoCaptureFPS;
    9167         if (!data.strVideoCaptureFile.isEmpty())
    9168             i_calculateFullPath(data.strVideoCaptureFile, mHWData->mVideoCaptureFile);
    9169         else
    9170             mHWData->mVideoCaptureFile.setNull();
    9171         mHWData->mVideoCaptureOptions = data.strVideoCaptureOptions;
    91728883        mHWData->mFirmwareType = data.firmwareType;
    91738884        mHWData->mPointingHIDType = data.pointingHIDType;
     
    91878898        if (FAILED(rc)) return rc;
    91888899
     8900        /* Capture settings */
     8901        rc = mCaptureSettings->i_loadSettings(data.captureSettings);
     8902        if (FAILED(rc)) return rc;
     8903
    91898904        // Bandwidth control (must come before network adapters)
    91908905        rc = mBandwidthControl->i_loadSettings(data.ioSettings);
    91918906        if (FAILED(rc)) return rc;
    91928907
    9193         /* Shared folders */
     8908        /* USB controllers */
    91948909        for (settings::USBControllerList::const_iterator
    91958910             it = data.usbSettings.llUSBControllers.begin();
     
    1049310208        data.fAccelerate3D = !!mHWData->mAccelerate3DEnabled;
    1049410209        data.fAccelerate2DVideo = !!mHWData->mAccelerate2DVideoEnabled;
    10495         data.ulVideoCaptureHorzRes = mHWData->mVideoCaptureWidth;
    10496         data.ulVideoCaptureVertRes = mHWData->mVideoCaptureHeight;
    10497         data.ulVideoCaptureRate = mHWData->mVideoCaptureRate;
    10498         data.ulVideoCaptureFPS = mHWData->mVideoCaptureFPS;
    10499         data.fVideoCaptureEnabled  = !!mHWData->mVideoCaptureEnabled;
    10500         for (unsigned i = 0; i < sizeof(data.u64VideoCaptureScreens) * 8; ++i)
    10501         {
    10502             if (mHWData->maVideoCaptureScreens[i])
    10503                 ASMBitSet(&data.u64VideoCaptureScreens, i);
    10504             else
    10505                 ASMBitClear(&data.u64VideoCaptureScreens, i);
    10506         }
    10507         /* store relative video capture file if possible */
    10508         i_copyPathRelativeToMachine(mHWData->mVideoCaptureFile, data.strVideoCaptureFile);
    10509         data.strVideoCaptureOptions = mHWData->mVideoCaptureOptions;
    1051010210
    1051110211        /* VRDEServer settings (optional) */
     
    1051310213        if (FAILED(rc)) throw rc;
    1051410214
    10515         /* BIOS (required) */
     10215        /* BIOS settings (required) */
    1051610216        rc = mBIOSSettings->i_saveSettings(data.biosSettings);
     10217        if (FAILED(rc)) throw rc;
     10218
     10219        /* Capture settings (required) */
     10220        rc = mCaptureSettings->i_saveSettings(data.captureSettings);
    1051710221        if (FAILED(rc)) throw rc;
    1051810222
     
    1201911723        mBIOSSettings->i_rollback();
    1202011724
     11725    if (mCaptureSettings && (mData->flModifications & IsModified_Capture))
     11726        mCaptureSettings->i_rollback();
     11727
    1202111728    if (mVRDEServer && (mData->flModifications & IsModified_VRDEServer))
    1202211729        mVRDEServer->i_rollback();
     
    1212911836
    1213011837    mBIOSSettings->i_commit();
     11838    mCaptureSettings->i_commit();
    1213111839    mVRDEServer->i_commit();
    1213211840    mAudioAdapter->i_commit();
     
    1238112089
    1238212090    mBIOSSettings->i_copyFrom(aThat->mBIOSSettings);
     12091    mCaptureSettings->i_copyFrom(aThat->mCaptureSettings);
    1238312092    mVRDEServer->i_copyFrom(aThat->mVRDEServer);
    1238412093    mAudioAdapter->i_copyFrom(aThat->mAudioAdapter);
     
    1275412463    unconst(mBIOSSettings).createObject();
    1275512464    mBIOSSettings->init(this, aMachine->mBIOSSettings);
     12465    unconst(mCaptureSettings).createObject();
     12466    mCaptureSettings->init(this, aMachine->mCaptureSettings);
    1275612467    /* create another VRDEServer object that will be mutable */
    1275712468    unconst(mVRDEServer).createObject();
     
    1438714098 * @note Locks this object for reading.
    1438814099 */
    14389 HRESULT SessionMachine::i_onVideoCaptureChange()
     14100HRESULT SessionMachine::i_onCaptureChange()
    1439014101{
    1439114102    LogFlowThisFunc(("\n"));
     
    1440514116        return S_OK;
    1440614117
    14407     return directControl->OnVideoCaptureChange();
     14118    return directControl->OnCaptureChange();
    1440814119}
    1440914120
     
    1533915050    mBIOSSettings->i_applyDefaults(osType);
    1534015051
     15052    /* Initialize default capture settings. */
     15053    mCaptureSettings->i_applyDefaults();
     15054
    1534115055    /* Initialize default BIOS settings here */
    1534215056    mHWData->mAPIC = osType->i_recommendedIOAPIC();
  • trunk/src/VBox/Main/xml/Settings.cpp

    r74474 r75251  
    23712371}
    23722372
     2373CaptureScreenSettings::CaptureScreenSettings(void)
     2374{
     2375    applyDefaults();
     2376}
     2377
     2378CaptureScreenSettings::~CaptureScreenSettings()
     2379{
     2380
     2381}
     2382
     2383void CaptureScreenSettings::applyDefaults(void)
     2384{
     2385    /*
     2386     * Set sensible defaults.
     2387     */
     2388
     2389    fEnabled            = true;
     2390    enmDest             = CaptureDestination_File;
     2391    ulMaxTimeS          = 0;
     2392    strOptions          = "";
     2393    File.ulMaxSizeMB    = 0;
     2394    Video.enmCodec      = CaptureVideoCodec_VP8;
     2395    Video.ulWidth       = 1024;
     2396    Video.ulHeight      = 768;
     2397    Video.ulRate        = 512;
     2398    Video.ulFPS         = 25;
     2399    Audio.enmAudioCodec = CaptureAudioCodec_Opus;
     2400    Audio.cBits         = 16;
     2401    Audio.cChannels     = 2;
     2402    Audio.uHz           = 22050;
     2403
     2404    featureMap[CaptureFeature_Video] = true;
     2405    featureMap[CaptureFeature_Audio] = false;
     2406
     2407    //i_calculateFullPath
     2408}
     2409
     2410/**
     2411 * Check if all settings have default values.
     2412 */
     2413bool CaptureScreenSettings::areDefaultSettings(void) const
     2414{
     2415    const bool fDefault =    fEnabled            == true
     2416                          && enmDest             == CaptureDestination_File
     2417                          && ulMaxTimeS          == 0
     2418                          && strOptions          == ""
     2419                          && File.ulMaxSizeMB    == 0
     2420                          && Video.enmCodec      == CaptureVideoCodec_VP8
     2421                          && Video.ulWidth       == 1024
     2422                          && Video.ulHeight      == 768
     2423                          && Video.ulRate        == 512
     2424                          && Video.ulFPS         == 25
     2425                          && Audio.enmAudioCodec == CaptureAudioCodec_Opus
     2426                          && Audio.cBits         == 16
     2427                          && Audio.cChannels     == 2
     2428                          && Audio.uHz           == 22050;
     2429
     2430    return fDefault;
     2431}
     2432
     2433bool CaptureScreenSettings::isFeatureEnabled(CaptureFeature_T enmFeature) const
     2434{
     2435    CaptureFeatureMap::const_iterator itFeature = featureMap.find(enmFeature);
     2436    if (itFeature != featureMap.end())
     2437        return itFeature->second;
     2438
     2439    return false;
     2440}
     2441
     2442/**
     2443 * Comparison operator. This gets called from MachineConfigFile::operator==,
     2444 * which in turn gets called from Machine::saveSettings to figure out whether
     2445 * machine settings have really changed and thus need to be written out to disk.
     2446 */
     2447bool CaptureScreenSettings::operator==(const CaptureScreenSettings &d) const
     2448{
     2449    return    fEnabled            == d.fEnabled
     2450           && enmDest             == d.enmDest
     2451           && featureMap          == d.featureMap
     2452           && ulMaxTimeS          == d.ulMaxTimeS
     2453           && strOptions          == d.strOptions
     2454           && File.ulMaxSizeMB    == d.File.ulMaxSizeMB
     2455           && Video.enmCodec      == d.Video.enmCodec
     2456           && Video.ulWidth       == d.Video.ulWidth
     2457           && Video.ulHeight      == d.Video.ulHeight
     2458           && Video.ulRate        == d.Video.ulRate
     2459           && Video.ulFPS         == d.Video.ulFPS
     2460           && Audio.enmAudioCodec == d.Audio.enmAudioCodec
     2461           && Audio.cBits         == d.Audio.cBits
     2462           && Audio.cChannels     == d.Audio.cChannels
     2463           && Audio.uHz           == d.Audio.uHz;
     2464}
     2465
     2466/**
     2467 * Constructor. Needs to set sane defaults which stand the test of time.
     2468 */
     2469CaptureSettings::CaptureSettings()
     2470{
     2471    applyDefaults();
     2472}
     2473
     2474void CaptureSettings::applyDefaults(void)
     2475{
     2476    fEnabled = false;
     2477
     2478    mapScreens.clear();
     2479
     2480    CaptureScreenSettings screenSettings; /* Apply default settings. */
     2481    for (unsigned long l = 0; l < SchemaDefs::MaxGuestMonitors; l++)
     2482    {
     2483        mapScreens[l] = screenSettings;
     2484    }
     2485}
     2486
     2487/**
     2488 * Check if all settings have default values.
     2489 */
     2490bool CaptureSettings::areDefaultSettings() const
     2491{
     2492    CaptureScreenMap::const_iterator itScreen = mapScreens.begin();
     2493    while (itScreen != mapScreens.end())
     2494    {
     2495        if (!itScreen->second.areDefaultSettings())
     2496            return false;
     2497
     2498        ++itScreen;
     2499    }
     2500
     2501    return true;
     2502}
     2503
     2504/**
     2505 * Comparison operator. This gets called from MachineConfigFile::operator==,
     2506 * which in turn gets called from Machine::saveSettings to figure out whether
     2507 * machine settings have really changed and thus need to be written out to disk.
     2508 */
     2509bool CaptureSettings::operator==(const CaptureSettings &d) const
     2510{
     2511    if (this == &d)
     2512        return true;
     2513
     2514    if (   fEnabled          != d.fEnabled
     2515        || mapScreens.size() != d.mapScreens.size())
     2516        return false;
     2517
     2518    CaptureScreenMap::const_iterator itScreen = mapScreens.begin();
     2519    size_t i = 0;
     2520    while (itScreen != mapScreens.end())
     2521    {
     2522        CaptureScreenMap::const_iterator itScreenThat = d.mapScreens.find(i);
     2523        if (itScreen->second == itScreenThat->second)
     2524        {
     2525            /* Nothing to do in here (yet). */
     2526        }
     2527        else
     2528            return false;
     2529
     2530        ++itScreen;
     2531        ++i;
     2532    }
     2533
     2534    return true;
     2535}
     2536
    23732537/**
    23742538 * Constructor. Needs to set sane defaults which stand the test of time.
     
    29013065    fAccelerate3D(false),
    29023066    fAccelerate2DVideo(false),
    2903     ulVideoCaptureHorzRes(1024),
    2904     ulVideoCaptureVertRes(768),
    2905     ulVideoCaptureRate(512),
    2906     ulVideoCaptureFPS(25),
    2907     ulVideoCaptureMaxTime(0),
    2908     ulVideoCaptureMaxSize(0),
    2909     fVideoCaptureEnabled(false),
    2910     u64VideoCaptureScreens(UINT64_C(0xffffffffffffffff)),
    2911     strVideoCaptureFile(""),
    29123067    firmwareType(FirmwareType_BIOS),
    29133068    pointingHIDType(PointingHIDType_PS2Mouse),
     
    29863141        && !fAccelerate3D
    29873142        && !fAccelerate2DVideo;
    2988 }
    2989 
    2990 /**
    2991  * Check if all Video Capture settings have default values.
    2992  */
    2993 bool Hardware::areVideoCaptureDefaultSettings() const
    2994 {
    2995     return    !fVideoCaptureEnabled
    2996            && u64VideoCaptureScreens == UINT64_C(0xffffffffffffffff)
    2997            && strVideoCaptureFile.isEmpty()
    2998            && ulVideoCaptureHorzRes == 1024
    2999            && ulVideoCaptureVertRes == 768
    3000            && ulVideoCaptureRate == 512
    3001            && ulVideoCaptureFPS == 25
    3002            && ulVideoCaptureMaxTime == 0
    3003            && ulVideoCaptureMaxSize == 0
    3004            && strVideoCaptureOptions.isEmpty();
    30053143}
    30063144
     
    30623200            && fAccelerate3D             == h.fAccelerate3D
    30633201            && fAccelerate2DVideo        == h.fAccelerate2DVideo
    3064             && fVideoCaptureEnabled      == h.fVideoCaptureEnabled
    3065             && u64VideoCaptureScreens    == h.u64VideoCaptureScreens
    3066             && strVideoCaptureFile       == h.strVideoCaptureFile
    3067             && ulVideoCaptureHorzRes     == h.ulVideoCaptureHorzRes
    3068             && ulVideoCaptureVertRes     == h.ulVideoCaptureVertRes
    3069             && ulVideoCaptureRate        == h.ulVideoCaptureRate
    3070             && ulVideoCaptureFPS         == h.ulVideoCaptureFPS
    3071             && ulVideoCaptureMaxTime     == h.ulVideoCaptureMaxTime
    3072             && ulVideoCaptureMaxSize     == h.ulVideoCaptureMaxTime
    3073             && strVideoCaptureOptions    == h.strVideoCaptureOptions
    30743202            && firmwareType              == h.firmwareType
    30753203            && pointingHIDType           == h.pointingHIDType
     
    42764404        else if (pelmHwChild->nameEquals("VideoCapture"))
    42774405        {
    4278             pelmHwChild->getAttributeValue("enabled",   hw.fVideoCaptureEnabled);
    4279             pelmHwChild->getAttributeValue("screens",   hw.u64VideoCaptureScreens);
    4280             pelmHwChild->getAttributeValuePath("file",  hw.strVideoCaptureFile);
    4281             pelmHwChild->getAttributeValue("horzRes",   hw.ulVideoCaptureHorzRes);
    4282             pelmHwChild->getAttributeValue("vertRes",   hw.ulVideoCaptureVertRes);
    4283             pelmHwChild->getAttributeValue("rate",      hw.ulVideoCaptureRate);
    4284             pelmHwChild->getAttributeValue("fps",       hw.ulVideoCaptureFPS);
    4285             pelmHwChild->getAttributeValue("maxTime",   hw.ulVideoCaptureMaxTime);
    4286             pelmHwChild->getAttributeValue("maxSize",   hw.ulVideoCaptureMaxSize);
    4287             pelmHwChild->getAttributeValue("options",   hw.strVideoCaptureOptions);
     4406            pelmHwChild->getAttributeValue("enabled",   hw.captureSettings.fEnabled);
     4407
     4408            /* Right now I don't want to bump the settings version, so just convert the enabled
     4409             * screens to the former uint6t_t bit array and vice versa. */
     4410            uint64_t u64VideoCaptureScreens;
     4411            pelmHwChild->getAttributeValue("screens",   u64VideoCaptureScreens);
     4412
     4413            /* At the moment we only support one capturing configuration, that is, all screens
     4414             * have the same configuration. So load/save to/from screen 0. */
     4415            CaptureScreenSettings &screen0Settings = hw.captureSettings.mapScreens[0];
     4416
     4417            pelmHwChild->getAttributeValue("maxTime",   screen0Settings.ulMaxTimeS);
     4418            pelmHwChild->getAttributeValue("options",   screen0Settings.strOptions);
     4419            pelmHwChild->getAttributeValuePath("file",  screen0Settings.File.strName);
     4420            pelmHwChild->getAttributeValue("maxSize",   screen0Settings.File.ulMaxSizeMB);
     4421            pelmHwChild->getAttributeValue("horzRes",   screen0Settings.Video.ulWidth);
     4422            pelmHwChild->getAttributeValue("vertRes",   screen0Settings.Video.ulHeight);
     4423            pelmHwChild->getAttributeValue("rate",      screen0Settings.Video.ulRate);
     4424            pelmHwChild->getAttributeValue("fps",       screen0Settings.Video.ulFPS);
     4425
     4426            for (unsigned i = 0; i < 64; i++)
     4427            {
     4428                if (u64VideoCaptureScreens & RT_BIT(i)) /* Screen i enabled? */
     4429                {
     4430                    hw.captureSettings.mapScreens[i] = screen0Settings;
     4431                    hw.captureSettings.mapScreens[i].fEnabled = true;
     4432                }
     4433            }
    42884434        }
    42894435        else if (pelmHwChild->nameEquals("RemoteDisplay"))
     
    56685814    }
    56695815
    5670     if (m->sv >= SettingsVersion_v1_14 && !hw.areVideoCaptureDefaultSettings())
     5816    if (m->sv >= SettingsVersion_v1_14 && !hw.captureSettings.areDefaultSettings())
    56715817    {
    56725818        xml::ElementNode *pelmVideoCapture = pelmHardware->createChild("VideoCapture");
    5673         if (hw.fVideoCaptureEnabled)
    5674             pelmVideoCapture->setAttribute("enabled",      hw.fVideoCaptureEnabled);
    5675         if (hw.u64VideoCaptureScreens != UINT64_C(0xffffffffffffffff))
    5676             pelmVideoCapture->setAttribute("screens",      hw.u64VideoCaptureScreens);
    5677         if (!hw.strVideoCaptureFile.isEmpty())
    5678             pelmVideoCapture->setAttributePath("file",     hw.strVideoCaptureFile);
    5679         if (hw.ulVideoCaptureHorzRes != 1024 || hw.ulVideoCaptureVertRes != 768)
    5680         {
    5681             pelmVideoCapture->setAttribute("horzRes",      hw.ulVideoCaptureHorzRes);
    5682             pelmVideoCapture->setAttribute("vertRes",      hw.ulVideoCaptureVertRes);
    5683         }
    5684         if (hw.ulVideoCaptureRate != 512)
    5685             pelmVideoCapture->setAttribute("rate",         hw.ulVideoCaptureRate);
    5686         if (hw.ulVideoCaptureFPS)
    5687             pelmVideoCapture->setAttribute("fps",          hw.ulVideoCaptureFPS);
    5688         if (hw.ulVideoCaptureMaxTime)
    5689             pelmVideoCapture->setAttribute("maxTime",      hw.ulVideoCaptureMaxTime);
    5690         if (hw.ulVideoCaptureMaxSize)
    5691             pelmVideoCapture->setAttribute("maxSize",      hw.ulVideoCaptureMaxSize);
    5692         if (!hw.strVideoCaptureOptions.isEmpty())
    5693             pelmVideoCapture->setAttributePath("options",  hw.strVideoCaptureOptions);
     5819
     5820        if (hw.captureSettings.fEnabled)
     5821            pelmVideoCapture->setAttribute("enabled", hw.captureSettings.fEnabled);
     5822
     5823        /* Right now I don't want to bump the settings version, so just convert the enabled
     5824         * screens to the former uint6t_t bit array and vice versa. */
     5825        uint64_t u64VideoCaptureScreens = 0;
     5826        CaptureScreenMap::const_iterator itScreen = hw.captureSettings.mapScreens.begin();
     5827        while (itScreen != hw.captureSettings.mapScreens.end())
     5828        {
     5829            if (itScreen->second.fEnabled)
     5830               u64VideoCaptureScreens |= RT_BIT(itScreen->first);
     5831            ++itScreen;
     5832        }
     5833
     5834        if (u64VideoCaptureScreens)
     5835            pelmVideoCapture->setAttribute("screens",      u64VideoCaptureScreens);
     5836
     5837        /* At the moment we only support one capturing configuration, that is, all screens
     5838         * have the same configuration. So load/save to/from screen 0. */
     5839        Assert(hw.captureSettings.mapScreens.size());
     5840        const CaptureScreenMap::const_iterator itScreen0Settings = hw.captureSettings.mapScreens.find(0);
     5841
     5842        if (itScreen0Settings->second.ulMaxTimeS)
     5843            pelmVideoCapture->setAttribute("maxTime",      itScreen0Settings->second.ulMaxTimeS);
     5844        if (itScreen0Settings->second.strOptions.isNotEmpty())
     5845            pelmVideoCapture->setAttributePath("options",  itScreen0Settings->second.strOptions);
     5846
     5847        if (!itScreen0Settings->second.File.strName.isEmpty())
     5848            pelmVideoCapture->setAttributePath("file",     itScreen0Settings->second.File.strName);
     5849        if (itScreen0Settings->second.File.ulMaxSizeMB)
     5850            pelmVideoCapture->setAttribute("maxSize",      itScreen0Settings->second.File.ulMaxSizeMB);
     5851
     5852        if (   itScreen0Settings->second.Video.ulWidth  != 1024
     5853            || itScreen0Settings->second.Video.ulHeight != 768)
     5854        {
     5855            pelmVideoCapture->setAttribute("horzRes",      itScreen0Settings->second.Video.ulWidth);
     5856            pelmVideoCapture->setAttribute("vertRes",      itScreen0Settings->second.Video.ulHeight);
     5857        }
     5858        if (itScreen0Settings->second.Video.ulRate != 512)
     5859            pelmVideoCapture->setAttribute("rate",         itScreen0Settings->second.Video.ulRate);
     5860        if (itScreen0Settings->second.Video.ulFPS)
     5861            pelmVideoCapture->setAttribute("fps",          itScreen0Settings->second.Video.ulFPS);
    56945862    }
    56955863
     
    72627430    {
    72637431        // VirtualBox 4.3 adds default frontend setting, graphics controller
    7264         // setting, explicit long mode setting, video capturing and NAT networking.
     7432        // setting, explicit long mode setting, (video) capturing and NAT networking.
    72657433        if (   !hardwareMachine.strDefaultFrontend.isEmpty()
    72667434            || hardwareMachine.graphicsControllerType != GraphicsControllerType_VBoxVGA
    72677435            || hardwareMachine.enmLongMode != Hardware::LongMode_Legacy
    72687436            || machineUserData.ovIcon.size() > 0
    7269             || hardwareMachine.fVideoCaptureEnabled)
     7437            || hardwareMachine.captureSettings.fEnabled)
    72707438        {
    72717439            m->sv = SettingsVersion_v1_14;
Note: See TracChangeset for help on using the changeset viewer.

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