VirtualBox

Changeset 74987 in vbox


Ignore:
Timestamp:
Oct 23, 2018 8:46:05 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126011
Message:

VideoRec/Main: Split up code into more functions, separating VPX code from generic code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/VideoRec.cpp

    r74984 r74987  
    538538static void videoRecAudioFrameFree(PVIDEORECAUDIOFRAME pFrame);
    539539#endif
    540 static int videoRecEncodeAndWrite(PVIDEORECSTREAM pStream, uint64_t uTimeStampMs, PVIDEORECVIDEOFRAME pFrame);
    541540static int videoRecRGBToYUV(uint32_t uPixelFormat,
    542541                            uint8_t *paDst, uint32_t uDstWidth, uint32_t uDstHeight,
    543542                            uint8_t *paSrc, uint32_t uSrcWidth, uint32_t uSrcHeight);
    544 static int videoRecStreamCloseFile(PVIDEORECSTREAM pStream);
     543static int videoRecStreamClose(PVIDEORECSTREAM pStream);
     544static int videoRecStreamOpen(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg);
     545static int videoRecStreamUninit(PVIDEORECSTREAM pStream);
     546static int videoRecStreamUnitVideo(PVIDEORECSTREAM pStream);
     547static int videoRecStreamInitVideo(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg);
     548#ifdef VBOX_WITH_LIBVPX
     549static int videoRecStreamInitVideoVPX(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg);
     550static int videoRecStreamUninitVideoVPX(PVIDEORECSTREAM pStream);
     551static int videoRecStreamWriteVideoVPX(PVIDEORECSTREAM pStream, uint64_t uTimeStampMs, PVIDEORECVIDEOFRAME pFrame);
     552#endif
    545553static void videoRecStreamLock(PVIDEORECSTREAM pStream);
    546554static void videoRecStreamUnlock(PVIDEORECSTREAM pStream);
     
    764772                                              pVideoFrame->pu8RGBBuf, pStream->Video.uWidth, pStream->Video.uHeight);
    765773                        if (RT_SUCCESS(rc))
    766                             rc = videoRecEncodeAndWrite(pStream, uTimeStampMs, pVideoFrame);
     774                            rc = videoRecStreamWriteVideoVPX(pStream, uTimeStampMs, pVideoFrame);
    767775                    }
    768776#endif
     
    10121020            videoRecStreamLock(pStream);
    10131021
    1014             if (pStream->fEnabled)
    1015             {
    1016                 switch (pStream->enmDst)
    1017                 {
    1018                     case VIDEORECDEST_FILE:
    1019                     {
    1020                         if (pStream->File.pWEBM)
    1021                             pStream->File.pWEBM->Close();
    1022                         break;
    1023                     }
    1024 
    1025                     default:
    1026                         AssertFailed(); /* Should never happen. */
    1027                         break;
    1028                 }
    1029 
    1030                 vpx_img_free(&pStream->Video.Codec.VPX.RawImage);
    1031                 vpx_codec_err_t rcv = vpx_codec_destroy(&pStream->Video.Codec.VPX.Ctx);
    1032                 Assert(rcv == VPX_CODEC_OK); RT_NOREF(rcv);
    1033 
    1034                 pStream->Blocks.Clear();
    1035 
    1036                 LogRel(("VideoRec: Recording screen #%u stopped\n", pStream->uScreenID));
    1037             }
    1038 
    1039             switch (pStream->enmDst)
    1040             {
    1041                 case VIDEORECDEST_FILE:
    1042                 {
    1043                     int rc2 = videoRecStreamCloseFile(pStream);
    1044                     AssertRC(rc2);
    1045 
    1046                     if (pStream->File.pWEBM)
    1047                     {
    1048                         delete pStream->File.pWEBM;
    1049                         pStream->File.pWEBM = NULL;
    1050                     }
    1051                     break;
    1052                 }
    1053 
    1054                 default:
    1055                     AssertFailed(); /* Should never happen. */
    1056                     break;
    1057             }
     1022            int rc2 = videoRecStreamClose(pStream);
     1023            if (RT_SUCCESS(rc))
     1024                rc = rc2;
     1025
     1026            rc2 = videoRecStreamUninit(pStream);
     1027            if (RT_SUCCESS(rc))
     1028                rc = rc2;
    10581029
    10591030            pCtx->vecStreams.erase(it);
     
    11321103
    11331104/**
    1134  * Opens a file for a given recording stream to capture to.
     1105 * Opens a recording stream.
    11351106 *
    11361107 * @returns IPRT status code.
    1137  * @param   pStream             Recording stream to open file for.
     1108 * @param   pStream             Recording stream to open.
    11381109 * @param   pCfg                Recording configuration to use.
    11391110 */
    1140 static int videoRecStreamOpenFile(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg)
     1111static int videoRecStreamOpen(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg)
    11411112{
    11421113    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
     
    11441115
    11451116    Assert(pStream->enmDst == VIDEORECDEST_INVALID);
    1146     Assert(pCfg->enmDst    == VIDEORECDEST_FILE);
    1147 
    1148     Assert(pCfg->File.strName.isNotEmpty());
    1149 
    1150     char *pszAbsPath = RTPathAbsDup(com::Utf8Str(pCfg->File.strName).c_str());
    1151     AssertPtrReturn(pszAbsPath, VERR_NO_MEMORY);
    1152 
    1153     RTPathStripSuffix(pszAbsPath);
    1154 
    1155     char *pszSuff = RTStrDup(".webm");
    1156     if (!pszSuff)
    1157     {
    1158         RTStrFree(pszAbsPath);
    1159         return VERR_NO_MEMORY;
    1160     }
    1161 
    1162     char *pszFile = NULL;
    11631117
    11641118    int rc;
    1165     if (pCfg->aScreens.size() > 1)
    1166         rc = RTStrAPrintf(&pszFile, "%s-%u%s", pszAbsPath, pStream->uScreenID + 1, pszSuff);
    1167     else
    1168         rc = RTStrAPrintf(&pszFile, "%s%s", pszAbsPath, pszSuff);
    1169 
    1170     if (RT_SUCCESS(rc))
    1171     {
    1172         uint64_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_WRITE;
    1173 
    1174         /* Play safe: the file must not exist, overwriting is potentially
    1175          * hazardous as nothing prevents the user from picking a file name of some
    1176          * other important file, causing unintentional data loss. */
    1177         fOpen |= RTFILE_O_CREATE;
    1178 
    1179         RTFILE hFile;
    1180         rc = RTFileOpen(&hFile, pszFile, fOpen);
    1181         if (rc == VERR_ALREADY_EXISTS)
    1182         {
    1183             RTStrFree(pszFile);
    1184             pszFile = NULL;
    1185 
    1186             RTTIMESPEC ts;
    1187             RTTimeNow(&ts);
    1188             RTTIME time;
    1189             RTTimeExplode(&time, &ts);
     1119
     1120    switch (pCfg->enmDst)
     1121    {
     1122        case VIDEORECDEST_FILE:
     1123        {
     1124            Assert(pCfg->File.strName.isNotEmpty());
     1125
     1126            char *pszAbsPath = RTPathAbsDup(com::Utf8Str(pCfg->File.strName).c_str());
     1127            AssertPtrReturn(pszAbsPath, VERR_NO_MEMORY);
     1128
     1129            RTPathStripSuffix(pszAbsPath);
     1130
     1131            char *pszSuff = RTStrDup(".webm");
     1132            if (!pszSuff)
     1133            {
     1134                RTStrFree(pszAbsPath);
     1135                rc = VERR_NO_MEMORY;
     1136                break;
     1137            }
     1138
     1139            char *pszFile = NULL;
    11901140
    11911141            if (pCfg->aScreens.size() > 1)
    1192                 rc = RTStrAPrintf(&pszFile, "%s-%04d-%02u-%02uT%02u-%02u-%02u-%09uZ-%u%s",
    1193                                   pszAbsPath, time.i32Year, time.u8Month, time.u8MonthDay,
    1194                                   time.u8Hour, time.u8Minute, time.u8Second, time.u32Nanosecond,
    1195                                   pStream->uScreenID + 1, pszSuff);
     1142                rc = RTStrAPrintf(&pszFile, "%s-%u%s", pszAbsPath, pStream->uScreenID + 1, pszSuff);
    11961143            else
    1197                 rc = RTStrAPrintf(&pszFile, "%s-%04d-%02u-%02uT%02u-%02u-%02u-%09uZ%s",
    1198                                   pszAbsPath, time.i32Year, time.u8Month, time.u8MonthDay,
    1199                                   time.u8Hour, time.u8Minute, time.u8Second, time.u32Nanosecond,
    1200                                   pszSuff);
     1144                rc = RTStrAPrintf(&pszFile, "%s%s", pszAbsPath, pszSuff);
    12011145
    12021146            if (RT_SUCCESS(rc))
     1147            {
     1148                uint64_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_WRITE;
     1149
     1150                /* Play safe: the file must not exist, overwriting is potentially
     1151                 * hazardous as nothing prevents the user from picking a file name of some
     1152                 * other important file, causing unintentional data loss. */
     1153                fOpen |= RTFILE_O_CREATE;
     1154
     1155                RTFILE hFile;
    12031156                rc = RTFileOpen(&hFile, pszFile, fOpen);
    1204         }
    1205 
    1206         if (RT_SUCCESS(rc))
    1207         {
    1208             pStream->enmDst       = VIDEORECDEST_FILE;
    1209             pStream->File.hFile   = hFile;
    1210             pStream->File.pszFile = pszFile; /* Assign allocated string to our stream's config. */
    1211         }
    1212     }
    1213 
    1214     RTStrFree(pszSuff);
    1215     RTStrFree(pszAbsPath);
    1216 
    1217     if (RT_FAILURE(rc))
    1218     {
    1219         LogRel(("VideoRec: Failed to open file '%s' for screen %RU32, rc=%Rrc\n",
    1220                 pszFile ? pszFile : "<Unnamed>", pStream->uScreenID, rc));
    1221         RTStrFree(pszFile);
    1222     }
    1223 
     1157                if (rc == VERR_ALREADY_EXISTS)
     1158                {
     1159                    RTStrFree(pszFile);
     1160                    pszFile = NULL;
     1161
     1162                    RTTIMESPEC ts;
     1163                    RTTimeNow(&ts);
     1164                    RTTIME time;
     1165                    RTTimeExplode(&time, &ts);
     1166
     1167                    if (pCfg->aScreens.size() > 1)
     1168                        rc = RTStrAPrintf(&pszFile, "%s-%04d-%02u-%02uT%02u-%02u-%02u-%09uZ-%u%s",
     1169                                          pszAbsPath, time.i32Year, time.u8Month, time.u8MonthDay,
     1170                                          time.u8Hour, time.u8Minute, time.u8Second, time.u32Nanosecond,
     1171                                          pStream->uScreenID + 1, pszSuff);
     1172                    else
     1173                        rc = RTStrAPrintf(&pszFile, "%s-%04d-%02u-%02uT%02u-%02u-%02u-%09uZ%s",
     1174                                          pszAbsPath, time.i32Year, time.u8Month, time.u8MonthDay,
     1175                                          time.u8Hour, time.u8Minute, time.u8Second, time.u32Nanosecond,
     1176                                          pszSuff);
     1177
     1178                    if (RT_SUCCESS(rc))
     1179                        rc = RTFileOpen(&hFile, pszFile, fOpen);
     1180                }
     1181
     1182                if (RT_SUCCESS(rc))
     1183                {
     1184                    pStream->enmDst       = VIDEORECDEST_FILE;
     1185                    pStream->File.hFile   = hFile;
     1186                    pStream->File.pszFile = pszFile; /* Assign allocated string to our stream's config. */
     1187                }
     1188            }
     1189
     1190            RTStrFree(pszSuff);
     1191            RTStrFree(pszAbsPath);
     1192
     1193            if (RT_FAILURE(rc))
     1194            {
     1195                LogRel(("VideoRec: Failed to open file '%s' for screen %RU32, rc=%Rrc\n",
     1196                        pszFile ? pszFile : "<Unnamed>", pStream->uScreenID, rc));
     1197                RTStrFree(pszFile);
     1198            }
     1199
     1200            break;
     1201        }
     1202
     1203        default:
     1204            rc = VERR_NOT_IMPLEMENTED;
     1205            break;
     1206    }
     1207
     1208    LogFlowFuncLeaveRC(rc);
    12241209    return rc;
    1225 }
    1226 
    1227 /**
    1228  * Closes a recording stream's file again.
    1229  *
    1230  * @returns IPRT status code.
    1231  * @param   pStream             Recording stream to close file for.
    1232  */
    1233 static int videoRecStreamCloseFile(PVIDEORECSTREAM pStream)
    1234 {
    1235     Assert(pStream->enmDst == VIDEORECDEST_FILE);
    1236 
    1237     pStream->enmDst = VIDEORECDEST_INVALID;
    1238 
    1239     AssertPtr(pStream->File.pszFile);
    1240 
    1241     if (RTFileIsValid(pStream->File.hFile))
    1242     {
    1243         RTFileClose(pStream->File.hFile);
    1244         LogRel(("VideoRec: Closed file '%s'\n", pStream->File.pszFile));
    1245     }
    1246 
    1247     RTStrFree(pStream->File.pszFile);
    1248     pStream->File.pszFile = NULL;
    1249 
    1250     return VINF_SUCCESS;
    12511210}
    12521211
     
    12781237        return VERR_NOT_FOUND;
    12791238
    1280     int rc = videoRecStreamOpenFile(pStream, &pCtx->Cfg);
     1239    int rc = videoRecStreamOpen(pStream, pCfg);
    12811240    if (RT_FAILURE(rc))
    12821241        return rc;
     
    12841243    pStream->pCtx = pCtx;
    12851244
    1286     /** @todo Make the following parameters configurable on a per-stream basis? */
    1287     pStream->Video.uWidth                = pCfg->Video.uWidth;
    1288     pStream->Video.uHeight               = pCfg->Video.uHeight;
    1289     pStream->Video.cFailedEncodingFrames = 0;
    1290 
    1291     PVIDEORECVIDEOCODEC pVC = &pStream->Video.Codec;
    1292 
    1293     pStream->Video.uDelayMs = RT_MS_1SEC / pCfg->Video.uFPS;
     1245    if (pCfg->Video.fEnabled)
     1246        rc = videoRecStreamInitVideo(pStream, pCfg);
    12941247
    12951248    switch (pStream->enmDst)
     
    13221275                }
    13231276
    1324                 LogRel(("VideoRec: Recording screen #%u with %RU32x%RU32 @ %RU32 kbps, %RU32 FPS\n",
    1325                         uScreen, pCfg->Video.uWidth, pCfg->Video.uHeight, pCfg->Video.uRate, pCfg->Video.uFPS));
     1277                LogRel(("VideoRec: Recording video of screen #%u with %RU32x%RU32 @ %RU32 kbps, %RU32 FPS (track #%RU8)\n",
     1278                        uScreen, pCfg->Video.uWidth, pCfg->Video.uHeight, pCfg->Video.uRate, pCfg->Video.uFPS,
     1279                        pStream->uTrackVideo));
    13261280            }
    13271281
     
    13371291                }
    13381292
    1339                 LogRel(("VideoRec: Recording audio in %RU16Hz, %RU8 bit, %RU8 %s\n",
    1340                         pCfg->Audio.uHz, pCfg->Audio.cBits, pCfg->Audio.cChannels, pCfg->Audio.cChannels ? "channels" : "channel"));
     1293                LogRel(("VideoRec: Recording audio in %RU16Hz, %RU8 bit, %RU8 %s (track #%RU8)\n",
     1294                        pCfg->Audio.uHz, pCfg->Audio.cBits, pCfg->Audio.cChannels, pCfg->Audio.cChannels ? "channels" : "channel",
     1295                        pStream->uTrackAudio));
    13411296            }
    13421297#endif
     
    13721327
    13731328    if (RT_FAILURE(rc))
     1329    {
     1330        int rc2 = videoRecStreamClose(pStream);
     1331        AssertRC(rc2);
    13741332        return rc;
    1375 
     1333    }
     1334
     1335    pStream->fEnabled = true;
     1336
     1337    return VINF_SUCCESS;
     1338}
     1339
     1340/**
     1341 * Closes a recording stream.
     1342 * Depending on the stream's recording destination, this function closes all associated handles
     1343 * and finalizes recording.
     1344 *
     1345 * @returns IPRT status code.
     1346 * @param   pStream             Recording stream to close.
     1347 *
     1348 */
     1349static int videoRecStreamClose(PVIDEORECSTREAM pStream)
     1350{
     1351    int rc = VINF_SUCCESS;
     1352
     1353    if (pStream->fEnabled)
     1354    {
     1355        switch (pStream->enmDst)
     1356        {
     1357            case VIDEORECDEST_FILE:
     1358            {
     1359                if (pStream->File.pWEBM)
     1360                    rc = pStream->File.pWEBM->Close();
     1361                break;
     1362            }
     1363
     1364            default:
     1365                AssertFailed(); /* Should never happen. */
     1366                break;
     1367        }
     1368
     1369        pStream->Blocks.Clear();
     1370
     1371        LogRel(("VideoRec: Recording screen #%u stopped\n", pStream->uScreenID));
     1372    }
     1373
     1374    if (RT_FAILURE(rc))
     1375    {
     1376        LogRel(("VideoRec: Error stopping recording screen #%u, rc=%Rrc\n", pStream->uScreenID, rc));
     1377        return rc;
     1378    }
     1379
     1380    switch (pStream->enmDst)
     1381    {
     1382        case VIDEORECDEST_FILE:
     1383        {
     1384            AssertPtr(pStream->File.pszFile);
     1385            if (RTFileIsValid(pStream->File.hFile))
     1386            {
     1387                rc = RTFileClose(pStream->File.hFile);
     1388                if (RT_SUCCESS(rc))
     1389                {
     1390                    LogRel(("VideoRec: Closed file '%s'\n", pStream->File.pszFile));
     1391                }
     1392                else
     1393                {
     1394                    LogRel(("VideoRec: Error closing file '%s', rc=%Rrc\n", pStream->File.pszFile, rc));
     1395                    break;
     1396                }
     1397            }
     1398
     1399            RTStrFree(pStream->File.pszFile);
     1400            pStream->File.pszFile = NULL;
     1401
     1402            if (pStream->File.pWEBM)
     1403            {
     1404                delete pStream->File.pWEBM;
     1405                pStream->File.pWEBM = NULL;
     1406            }
     1407            break;
     1408        }
     1409
     1410        default:
     1411            rc = VERR_NOT_IMPLEMENTED;
     1412            break;
     1413    }
     1414
     1415    if (RT_SUCCESS(rc))
     1416    {
     1417        pStream->enmDst = VIDEORECDEST_INVALID;
     1418    }
     1419
     1420    LogFlowFuncLeaveRC(rc);
     1421    return rc;
     1422}
     1423
     1424/**
     1425 * Uninitializes a recording stream.
     1426 *
     1427 * @returns IPRT status code.
     1428 * @param   pStream             Recording stream to uninitialize.
     1429 */
     1430static int videoRecStreamUninit(PVIDEORECSTREAM pStream)
     1431{
     1432    int rc = VINF_SUCCESS;
     1433
     1434    if (pStream->pCtx->Cfg.Video.fEnabled)
     1435    {
     1436        int rc2 = videoRecStreamUnitVideo(pStream);
     1437        if (RT_SUCCESS(rc))
     1438            rc = rc2;
     1439    }
     1440
     1441    return rc;
     1442}
     1443
     1444/**
     1445 * Uninitializes video recording for a certain recording stream.
     1446 *
     1447 * @returns IPRT status code.
     1448 * @param   pStream             Recording stream to uninitialize video recording for.
     1449 */
     1450static int videoRecStreamUnitVideo(PVIDEORECSTREAM pStream)
     1451{
    13761452#ifdef VBOX_WITH_LIBVPX
     1453    /* At the moment we only have VPX. */
     1454    return videoRecStreamUninitVideoVPX(pStream);
     1455#else
     1456    return VERR_NOT_SUPPORTED;
     1457#endif
     1458}
     1459
     1460#ifdef VBOX_WITH_LIBVPX
     1461/**
     1462 * Uninitializes the VPX codec for a certain recording stream.
     1463 *
     1464 * @returns IPRT status code.
     1465 * @param   pStream             Recording stream to uninitialize VPX codec for.
     1466 */
     1467static int videoRecStreamUninitVideoVPX(PVIDEORECSTREAM pStream)
     1468{
     1469    vpx_img_free(&pStream->Video.Codec.VPX.RawImage);
     1470    vpx_codec_err_t rcv = vpx_codec_destroy(&pStream->Video.Codec.VPX.Ctx);
     1471    Assert(rcv == VPX_CODEC_OK); RT_NOREF(rcv);
     1472
     1473    return VINF_SUCCESS;
     1474}
     1475#endif
     1476
     1477/**
     1478 * Initializes the video recording for a certain recording stream.
     1479 *
     1480 * @returns IPRT status code.
     1481 * @param   pStream             Recording stream to initialize video recording for.
     1482 * @param   pCfg                Video recording configuration to use for initialization.
     1483 */
     1484static int videoRecStreamInitVideo(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg)
     1485{
     1486#ifdef VBOX_WITH_LIBVPX
     1487    /* At the moment we only have VPX. */
     1488    return videoRecStreamInitVideoVPX(pStream, pCfg);
     1489#else
     1490    return VERR_NOT_SUPPORTED;
     1491#endif
     1492}
     1493
     1494#ifdef VBOX_WITH_LIBVPX
     1495/**
     1496 * Initializes the VPX codec for a certain recording stream.
     1497 *
     1498 * @returns IPRT status code.
     1499 * @param   pStream             Recording stream to initialize VPX codec for.
     1500 * @param   pCfg                Video recording configuration to use for initialization.
     1501 */
     1502static int videoRecStreamInitVideoVPX(PVIDEORECSTREAM pStream, PVIDEORECCFG pCfg)
     1503{
     1504    pStream->Video.uWidth                = pCfg->Video.uWidth;
     1505    pStream->Video.uHeight               = pCfg->Video.uHeight;
     1506    pStream->Video.cFailedEncodingFrames = 0;
     1507
     1508    PVIDEORECVIDEOCODEC pVC = &pStream->Video.Codec;
     1509
     1510    pStream->Video.uDelayMs = RT_MS_1SEC / pCfg->Video.uFPS;
     1511
    13771512# ifdef VBOX_WITH_LIBVPX_VP9
    13781513    vpx_codec_iface_t *pCodecIface = vpx_codec_vp9_cx();
     
    14161551    /* Save a pointer to the first raw YUV plane. */
    14171552    pStream->Video.Codec.VPX.pu8YuvBuf = pVC->VPX.RawImage.planes[0];
    1418 #endif
    1419     pStream->fEnabled = true;
    14201553
    14211554    return VINF_SUCCESS;
    14221555}
     1556#endif
    14231557
    14241558/**
     
    15401674}
    15411675
     1676#ifdef VBOX_WITH_LIBVPX
    15421677/**
    15431678 * Encodes the source image and write the encoded image to the stream's destination.
     
    15481683 * @param   pFrame              Frame to encode and submit.
    15491684 */
    1550 static int videoRecEncodeAndWrite(PVIDEORECSTREAM pStream, uint64_t uTimeStampMs, PVIDEORECVIDEOFRAME pFrame)
     1685static int videoRecStreamWriteVideoVPX(PVIDEORECSTREAM pStream, uint64_t uTimeStampMs, PVIDEORECVIDEOFRAME pFrame)
    15511686{
    15521687    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
     
    15581693    PVIDEORECCFG        pCfg = &pStream->pCtx->Cfg;
    15591694    PVIDEORECVIDEOCODEC pVC  = &pStream->Video.Codec;
    1560 #ifdef VBOX_WITH_LIBVPX
     1695
    15611696    /* Presentation Time Stamp (PTS). */
    15621697    vpx_codec_pts_t pts = uTimeStampMs;
     
    16011736        }
    16021737    }
    1603 #else
    1604     RT_NOREF(pStream);
    1605     rc = VERR_NOT_SUPPORTED;
     1738
     1739    return rc;
     1740}
    16061741#endif /* VBOX_WITH_LIBVPX */
    1607     return rc;
    1608 }
    16091742
    16101743/**
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