VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/RecordingInternals.cpp

Last change on this file was 105095, checked in by vboxsync, 3 months ago

Video Recording/Main: More optimizations for recording older guests which have a slightly different screen update logic. bugref:10650

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.6 KB
RevLine 
[74992]1/* $Id: RecordingInternals.cpp 105095 2024-07-02 10:06:48Z vboxsync $ */
2/** @file
[75344]3 * Recording internals code.
[74992]4 */
5
6/*
[98103]7 * Copyright (C) 2012-2023 Oracle and/or its affiliates.
[74992]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
[74992]26 */
27
[75344]28#include "RecordingInternals.h"
[105006]29#include "RecordingUtils.h"
[74992]30
31#include <iprt/assert.h>
32#include <iprt/mem.h>
33
[105006]34#ifdef DEBUG
35# include <math.h>
36# include <iprt/file.h>
37# include <iprt/formats/bmp.h>
38#endif
[99739]39
[105006]40
41/*********************************************************************************************************************************
42* Prototypes *
43*********************************************************************************************************************************/
44DECLINLINE(int) recordingVideoFrameInit(PRECORDINGVIDEOFRAME pFrame, uint32_t fFlags, uint32_t uWidth, uint32_t uHeight, uint32_t uPosX, uint32_t uPosY,
45 uint8_t uBPP, RECORDINGPIXELFMT enmFmt);
46
47
[74992]48/**
[105006]49 * Allocates an empty video frame, inline version.
[96481]50 *
[105006]51 * @returns Allocated video frame on success, or NULL on failure.
52 */
53DECLINLINE(PRECORDINGVIDEOFRAME) recordingVideoFrameAlloc(void)
54{
55 return (PRECORDINGVIDEOFRAME)RTMemAlloc(sizeof(RECORDINGVIDEOFRAME));
56}
57
58/**
59 * Allocates an empty video frame.
60 *
61 * @returns Allocated video frame on success, or NULL on failure.
62 */
63PRECORDINGVIDEOFRAME RecordingVideoFrameAlloc(void)
64{
65 PRECORDINGVIDEOFRAME pFrame = recordingVideoFrameAlloc();
66 AssertPtrReturn(pFrame, NULL);
67 RT_BZERO(pFrame, sizeof(RECORDINGVIDEOFRAME));
68 return pFrame;
69}
70
71/**
72 * Returns an allocated video frame from given image data.
73 *
74 * @returns Allocated video frame on success, or NULL on failure.
75 * @param pvData Pointer to image data to use.
76 * @param x X location hint (in pixel) to use for allocated frame.
77 * This is *not* the offset within \a pvData!
78 * @param y X location hint (in pixel) to use for allocated frame.
79 * This is *not* the offset within \a pvData!
80 * @param w Width (in pixel) of \a pvData image data.
81 * @param h Height (in pixel) of \a pvData image data.
82 * @param uBPP Bits per pixel) of \a pvData image data.
83 * @param enmFmt Pixel format of \a pvData image data.
84 */
85PRECORDINGVIDEOFRAME RecordingVideoFrameAllocEx(const void *pvData, uint32_t x, uint32_t y, uint32_t w, uint32_t h,
86 uint8_t uBPP, RECORDINGPIXELFMT enmFmt)
87{
88 PRECORDINGVIDEOFRAME pFrame = recordingVideoFrameAlloc();
89 AssertPtrReturn(pFrame, NULL);
[105011]90 int vrc = recordingVideoFrameInit(pFrame, RECORDINGVIDEOFRAME_F_VISIBLE, w, h, x, y, uBPP, enmFmt);
91 AssertRCReturn(vrc, NULL);
[105006]92 memcpy(pFrame->pau8Buf, pvData, pFrame->cbBuf);
93
94 return VINF_SUCCESS;
95}
96
97/**
98 * Frees a recording video frame.
99 *
100 * @param pFrame Pointer to video frame to free. The pointer will be invalid after return.
101 */
102void RecordingVideoFrameFree(PRECORDINGVIDEOFRAME pFrame)
103{
104 if (!pFrame)
105 return;
106
107 RecordingVideoFrameDestroy(pFrame);
108
109 RTMemFree(pFrame);
110}
111
112/**
113 * Initializes a recording frame, inline version.
114 *
115 * @returns VBox status code.
[96481]116 * @param pFrame Pointer to video frame to initialize.
[105006]117 * @param fFlags Flags of type RECORDINGVIDEOFRAME_F_XXX.
118 * @param uWidth Width (in pixel) of video frame.
119 * @param uHeight Height (in pixel) of video frame.
120 * @param uPosX X positioning hint.
121 * @param uPosY Y positioning hint.
[96481]122 * @param uBPP Bits per pixel (BPP).
[105006]123 * @param enmFmt Pixel format to use.
[96481]124 */
[105006]125DECLINLINE(int) recordingVideoFrameInit(PRECORDINGVIDEOFRAME pFrame, uint32_t fFlags, uint32_t uWidth, uint32_t uHeight,
126 uint32_t uPosX, uint32_t uPosY, uint8_t uBPP, RECORDINGPIXELFMT enmFmt)
[96481]127{
[105006]128 AssertPtrReturn(pFrame, VERR_INVALID_POINTER);
129 AssertReturn(uWidth, VERR_INVALID_PARAMETER);
130 AssertReturn(uHeight, VERR_INVALID_PARAMETER);
131 AssertReturn(uBPP && uBPP % 8 == 0, VERR_INVALID_PARAMETER);
132
[96481]133 /* Calculate bytes per pixel and set pixel format. */
134 const unsigned uBytesPerPixel = uBPP / 8;
[105006]135
136 /* Calculate bytes per pixel and set pixel format. */
137 const size_t cbRGBBuf = uWidth * uHeight * uBytesPerPixel;
[96481]138 AssertReturn(cbRGBBuf, VERR_INVALID_PARAMETER);
139
[105006]140 pFrame->pau8Buf = (uint8_t *)RTMemAlloc(cbRGBBuf);
141 AssertPtrReturn(pFrame->pau8Buf, VERR_NO_MEMORY);
142 pFrame->cbBuf = cbRGBBuf;
[96481]143
[105006]144 pFrame->fFlags = fFlags;
145 pFrame->Info.uWidth = uWidth;
146 pFrame->Info.uHeight = uHeight;
147 pFrame->Info.uBPP = uBPP;
148 pFrame->Info.enmPixelFmt = enmFmt;
149 pFrame->Info.uBytesPerLine = uWidth * uBytesPerPixel;
150 pFrame->Pos.x = uPosX;
151 pFrame->Pos.y = uPosY;
[96481]152
153 return VINF_SUCCESS;
154}
155
156/**
[105006]157 * Initializes a recording frame.
[96481]158 *
[105006]159 * @param pFrame Pointer to video frame to initialize.
160 * @param fFlags Flags of type RECORDINGVIDEOFRAME_F_XXX.
161 * @param uWidth Width (in pixel) of video frame.
162 * @param uHeight Height (in pixel) of video frame.
163 * @param uPosX X positioning hint.
164 * @param uPosY Y positioning hint.
165 * @param uBPP Bits per pixel (BPP).
166 * @param enmFmt Pixel format to use.
[96481]167 */
[105006]168int RecordingVideoFrameInit(PRECORDINGVIDEOFRAME pFrame, uint32_t fFlags, uint32_t uWidth, uint32_t uHeight, uint32_t uPosX, uint32_t uPosY,
169 uint8_t uBPP, RECORDINGPIXELFMT enmFmt)
[96481]170{
[105006]171 return recordingVideoFrameInit(pFrame, fFlags, uWidth, uHeight, uPosX, uPosY, uBPP, enmFmt);
172}
173
174/**
175 * Destroys a recording video frame.
176 *
177 * @param pFrame Pointer to video frame to destroy.
178 */
179void RecordingVideoFrameDestroy(PRECORDINGVIDEOFRAME pFrame)
180{
181 if (!pFrame)
182 return;
183
184 if (pFrame->pau8Buf)
[96481]185 {
186 Assert(pFrame->cbBuf);
[105006]187 RTMemFree(pFrame->pau8Buf);
188 pFrame->pau8Buf = NULL;
189 pFrame->cbBuf = 0;
[96481]190 }
191}
192
193/**
[105006]194 * Duplicates a video frame.
[74992]195 *
[105006]196 * @returns Pointer to duplicated frame on success, or NULL on failure.
197 * @param pFrame Video frame to duplicate.
[74992]198 */
[105006]199PRECORDINGVIDEOFRAME RecordingVideoFrameDup(PRECORDINGVIDEOFRAME pFrame)
[74992]200{
[105006]201 PRECORDINGVIDEOFRAME pFrameDup = (PRECORDINGVIDEOFRAME)RTMemDup(pFrame, sizeof(RECORDINGVIDEOFRAME));
202 AssertPtrReturn(pFrameDup, NULL);
203 pFrameDup->pau8Buf = (uint8_t *)RTMemDup(pFrame->pau8Buf, pFrame->cbBuf);
204 AssertPtrReturnStmt(pFrameDup, RTMemFree(pFrameDup), NULL);
[74992]205
[105006]206 return pFrameDup;
207}
[96481]208
[105006]209/**
210 * Clears the content of a video recording frame, inlined version.
211 *
212 * @param pFrame Video recording frame to clear content for.
213 */
214DECLINLINE(void) recordingVideoFrameClear(PRECORDINGVIDEOFRAME pFrame)
215{
216 RT_BZERO(pFrame->pau8Buf, pFrame->cbBuf);
[74992]217}
218
[105006]219/**
220 * Clears the content of a video recording frame.
221 *
222 * @param pFrame Video recording frame to clear content for.
223 */
224void RecordingVideoFrameClear(PRECORDINGVIDEOFRAME pFrame)
225{
226 recordingVideoFrameClear(pFrame);
227}
[99739]228
[74992]229/**
[105006]230 * Simple blitting function for raw image data, inlined version.
[96481]231 *
[105006]232 * @returns VBox status code.
[105010]233 * @param pu8Dst Destination buffer.
234 * @param cbDst Size (in bytes) of \a pu8Dst.
[105006]235 * @param uDstX X destination (in pixel) within destination frame.
236 * @param uDstY Y destination (in pixel) within destination frame.
237 * @param uDstBytesPerLine Bytes per line in destination buffer.
238 * @param uDstBPP BPP of destination buffer.
239 * @param enmDstFmt Pixel format of source data. Must match \a pFrame.
240 * @param pu8Src Source data to blit. Must be in the same pixel format as \a pFrame.
241 * @param cbSrc Size (in bytes) of \a pu8Src.
242 * @param uSrcX X start (in pixel) within source data.
243 * @param uSrcY Y start (in pixel) within source data.
244 * @param uSrcWidth Width (in pixel) to blit from source data.
245 * @param uSrcHeight Height (in pixel) to blit from data.
246 * @param uSrcBytesPerLine Bytes per line in source data.
247 * @param uSrcBPP BPP of source data. Must match \a pFrame.
248 * @param enmSrcFmt Pixel format of source data. Must match \a pFrame.
[96481]249 */
[105095]250DECLINLINE(int) recordingVideoBlitRaw(uint8_t *pu8Dst, size_t cbDst, uint32_t uDstX, uint32_t uDstY,
251 uint32_t uDstBytesPerLine, uint8_t uDstBPP, RECORDINGPIXELFMT enmDstFmt,
252 const uint8_t *pu8Src, size_t cbSrc, uint32_t uSrcX, uint32_t uSrcY, uint32_t uSrcWidth, uint32_t uSrcHeight,
253 uint32_t uSrcBytesPerLine, uint8_t uSrcBPP, RECORDINGPIXELFMT enmSrcFmt)
[96481]254{
[105006]255 RT_NOREF(enmDstFmt, enmSrcFmt);
256
257 uint8_t const uDstBytesPerPixel = uDstBPP / 8;
258 uint8_t const uSrcBytesPerPixel = uSrcBPP / 8;
259
260 size_t offSrc = RT_MIN(uSrcY * uSrcBytesPerLine + uSrcX * uSrcBytesPerPixel, cbSrc);
261 size_t offDst = RT_MIN(uDstY * uDstBytesPerLine + uDstX * uDstBytesPerPixel, cbDst);
262
263 for (uint32_t y = 0; y < uSrcHeight; y++)
[96481]264 {
[105006]265 size_t const cbToCopy = RT_MIN(cbDst - offDst,
266 RT_MIN(uSrcWidth * uSrcBytesPerPixel, cbSrc - offSrc));
267 if (!cbToCopy)
268 break;
269 memcpy(pu8Dst + offDst, (const uint8_t *)pu8Src + offSrc, cbToCopy);
270 offDst = RT_MIN(offDst + uDstBytesPerLine, cbDst);
271 Assert(offDst <= cbDst);
272 offSrc = RT_MIN(offSrc + uSrcBytesPerLine, cbSrc);
273 Assert(offSrc <= cbSrc);
[96481]274 }
[105006]275
276 return VINF_SUCCESS;
[96481]277}
278
[105095]279int RecordingVideoBlitRaw(uint8_t *pu8Dst, size_t cbDst, uint32_t uDstX, uint32_t uDstY,
280 uint32_t uDstBytesPerLine, uint8_t uDstBPP, RECORDINGPIXELFMT enmDstFmt,
281 const uint8_t *pu8Src, size_t cbSrc, uint32_t uSrcX, uint32_t uSrcY, uint32_t uSrcWidth, uint32_t uSrcHeight,
282 uint32_t uSrcBytesPerLine, uint8_t uSrcBPP, RECORDINGPIXELFMT enmSrcFmt)
283{
284 return recordingVideoBlitRaw(pu8Dst, cbDst, uDstX, uDstY, uDstBytesPerLine,uDstBPP, enmDstFmt,
285 pu8Src, cbSrc, uSrcX, uSrcY, uSrcWidth, uSrcHeight,uSrcBytesPerLine, uSrcBPP, enmSrcFmt);
286}
287
[96481]288/**
[105006]289 * Simple blitting function for raw image data with alpha channel, inlined version.
[74992]290 *
[105006]291 * @returns VBox status code.
292 * @param pFrame Destination frame.
293 * @param uDstX X destination (in pixel) within destination frame.
294 * @param uDstY Y destination (in pixel) within destination frame.
295 * @param pu8Src Source data to blit. Must be in the same pixel format as \a pFrame.
296 * @param cbSrc Size (in bytes) of \a pu8Src.
297 * @param uSrcX X start (in pixel) within source data.
298 * @param uSrcY Y start (in pixel) within source data.
299 * @param uSrcWidth Width (in pixel) to blit from source data.
300 * @param uSrcHeight Height (in pixel) to blit from data.
301 * @param uSrcBytesPerLine Bytes per line in source data.
302 * @param uSrcBPP BPP of source data. Must match \a pFrame.
303 * @param enmFmt Pixel format of source data. Must match \a pFrame.
[74992]304 */
[105006]305DECLINLINE(int) recordingVideoFrameBlitRawAlpha(PRECORDINGVIDEOFRAME pFrame, uint32_t uDstX, uint32_t uDstY,
306 const uint8_t *pu8Src, size_t cbSrc, uint32_t uSrcX, uint32_t uSrcY, uint32_t uSrcWidth, uint32_t uSrcHeight,
307 uint32_t uSrcBytesPerLine, uint8_t uSrcBPP, RECORDINGPIXELFMT enmFmt)
[74992]308{
[105006]309 AssertReturn(pFrame->Info.enmPixelFmt == enmFmt, VERR_NOT_SUPPORTED);
310 AssertReturn(pFrame->Info.uBPP == uSrcBPP, VERR_NOT_SUPPORTED);
311
312 RT_NOREF(uDstX, uDstY, cbSrc, uSrcX, uSrcY, uSrcBytesPerLine);
313 uint8_t const uDstBytesPerPixel = pFrame->Info.uBPP / 8;
314 uint8_t const uSrcBytesPerPixel = uSrcBPP / 8;
315
316 for (uint32_t y = 0; y < uSrcHeight; y++)
317 {
318 size_t offSrc = RT_MIN((uSrcY + y) * uSrcBytesPerLine + uSrcX * uSrcBytesPerPixel, cbSrc);
319 size_t offDst = RT_MIN((uDstY + y) * pFrame->Info.uBytesPerLine + uDstX * uDstBytesPerPixel, pFrame->cbBuf);
320
321 for (uint32_t x = 0; x < uSrcWidth; x++)
322 {
323 /* BGRA */
324 int const idx_b = 0;
325 int const idx_g = 1;
326 int const idx_r = 2;
327 int const idx_a = 3;
328
329 unsigned int const alpha = pu8Src[offSrc + idx_a] + 1;
330 unsigned int const inv_alpha = 256 - pu8Src[offSrc + idx_a];
331 if (pu8Src[offSrc + idx_a])
332 {
333 pFrame->pau8Buf[offDst + idx_r] = (unsigned char)((alpha * pu8Src[offSrc + idx_r] + inv_alpha * pFrame->pau8Buf[offDst + idx_r]) >> 8);
334 pFrame->pau8Buf[offDst + idx_g] = (unsigned char)((alpha * pu8Src[offSrc + idx_g] + inv_alpha * pFrame->pau8Buf[offDst + idx_g]) >> 8);
335 pFrame->pau8Buf[offDst + idx_b] = (unsigned char)((alpha * pu8Src[offSrc + idx_b] + inv_alpha * pFrame->pau8Buf[offDst + idx_b]) >> 8);
336 pFrame->pau8Buf[offDst + idx_a] = 0xff;
337 }
338
339 offSrc = RT_MIN(offSrc + uSrcBytesPerPixel, cbSrc);
340 if (offSrc >= cbSrc)
341 break;
342 offDst = RT_MIN(offDst + uDstBytesPerPixel, pFrame->cbBuf);
343 if (offDst >= pFrame->cbBuf)
344 break;
345 }
346 }
347
348#if 0
349 RecordingUtilsDbgDumpImageData(pu8Src, cbSrc, "/tmp", "cursor-src", uSrcWidth, uSrcHeight, uSrcBytesPerLine, 32);
350 RecordingUtilsDbgDumpVideoFrameEx(pFrame, "/tmp", "cursor-dst");
351#endif
352
353 return VINF_SUCCESS;
354}
355
356/**
357 * Simple blitting function for raw image data.
358 *
359 * @returns VBox status code.
360 * @param pDstFrame Destination frame.
361 * @param uDstX X destination (in pixel) within destination frame.
362 * @param uDstY Y destination (in pixel) within destination frame.
363 * @param pu8Src Source data to blit. Must be in the same pixel format as \a pFrame.
364 * @param cbSrc Size (in bytes) of \a pu8Src.
365 * @param uSrcX X start (in pixel) within source data.
366 * @param uSrcY Y start (in pixel) within source data.
367 * @param uSrcWidth Width (in pixel) to blit from source data.
368 * @param uSrcHeight Height (in pixel) to blit from data.
369 * @param uSrcBytesPerLine Bytes per line in source data.
370 * @param uSrcBPP BPP of source data. Must match \a pFrame.
371 * @param enmFmt Pixel format of source data. Must match \a pFrame.
372 */
373int RecordingVideoFrameBlitRaw(PRECORDINGVIDEOFRAME pDstFrame, uint32_t uDstX, uint32_t uDstY,
374 const uint8_t *pu8Src, size_t cbSrc, uint32_t uSrcX, uint32_t uSrcY, uint32_t uSrcWidth, uint32_t uSrcHeight,
375 uint32_t uSrcBytesPerLine, uint8_t uSrcBPP, RECORDINGPIXELFMT enmFmt)
376{
[105095]377 return recordingVideoBlitRaw(/* Destination */
378 pDstFrame->pau8Buf, pDstFrame->cbBuf, uDstX, uDstY,
379 pDstFrame->Info.uBytesPerLine, pDstFrame->Info.uBPP, pDstFrame->Info.enmPixelFmt,
380 /* Source */
381 pu8Src, cbSrc, uSrcX, uSrcY, uSrcWidth, uSrcHeight, uSrcBytesPerLine, uSrcBPP, enmFmt);
[105006]382}
383
384/**
385 * Simple blitting function for raw image data with alpha channel.
386 *
387 * @returns VBox status code.
[105095]388 * @param pDstFrame Destination frame.
[105006]389 * @param uDstX X destination (in pixel) within destination frame.
390 * @param uDstY Y destination (in pixel) within destination frame.
391 * @param pu8Src Source data to blit. Must be in the same pixel format as \a pFrame.
392 * @param cbSrc Size (in bytes) of \a pu8Src.
393 * @param uSrcX X start (in pixel) within source data.
394 * @param uSrcY Y start (in pixel) within source data.
395 * @param uSrcWidth Width (in pixel) to blit from source data.
396 * @param uSrcHeight Height (in pixel) to blit from data.
397 * @param uSrcBytesPerLine Bytes per line in source data.
398 * @param uSrcBPP BPP of source data. Must match \a pFrame.
399 * @param enmFmt Pixel format of source data. Must match \a pFrame.
400 */
[105095]401int RecordingVideoFrameBlitRawAlpha(PRECORDINGVIDEOFRAME pDstFrame, uint32_t uDstX, uint32_t uDstY,
[105006]402 const uint8_t *pu8Src, size_t cbSrc, uint32_t uSrcX, uint32_t uSrcY, uint32_t uSrcWidth, uint32_t uSrcHeight,
403 uint32_t uSrcBytesPerLine, uint8_t uSrcBPP, RECORDINGPIXELFMT enmFmt)
404{
[105095]405 return recordingVideoFrameBlitRawAlpha(pDstFrame, uDstX, uDstY,
[105006]406 pu8Src, cbSrc, uSrcX, uSrcY, uSrcWidth, uSrcHeight, uSrcBytesPerLine, uSrcBPP, enmFmt);
407}
408
409/**
410 * Simple blitting function for video frames.
411 *
412 * @returns VBox status code.
413 * @param pDstFrame Destination frame.
414 * @param uDstX X destination (in pixel) within destination frame.
415 * @param uDstY Y destination (in pixel) within destination frame.
416 * @param pSrcFrame Source frame.
417 * @param uSrcX X start (in pixel) within source frame.
418 * @param uSrcY Y start (in pixel) within source frame.
419 * @param uSrcWidth Width (in pixel) to blit from source frame.
420 * @param uSrcHeight Height (in pixel) to blit from frame.
421 *
422 * @note Does NOT check for limits, so use with care!
423 */
424int RecordingVideoFrameBlitFrame(PRECORDINGVIDEOFRAME pDstFrame, uint32_t uDstX, uint32_t uDstY,
425 PRECORDINGVIDEOFRAME pSrcFrame, uint32_t uSrcX, uint32_t uSrcY, uint32_t uSrcWidth, uint32_t uSrcHeight)
426{
[105095]427 return recordingVideoBlitRaw(/* Dest */
428 pDstFrame->pau8Buf, pDstFrame->cbBuf, uDstX, uDstY,
429 pDstFrame->Info.uBytesPerLine, pDstFrame->Info.uBPP, pDstFrame->Info.enmPixelFmt,
430 /* Source */
431 pSrcFrame->pau8Buf, pSrcFrame->cbBuf, uSrcX, uSrcY, uSrcWidth, uSrcHeight,
432 pSrcFrame->Info.uBytesPerLine, pSrcFrame->Info.uBPP, pSrcFrame->Info.enmPixelFmt);
[105006]433}
434
435#ifdef VBOX_WITH_AUDIO_RECORDING
436/**
437 * Destroys a recording audio frame.
438 *
439 * @param pFrame Pointer to audio frame to destroy.
440 */
441DECLINLINE(void) recordingAudioFrameDestroy(PRECORDINGAUDIOFRAME pFrame)
442{
[74992]443 if (!pFrame)
444 return;
445
[105006]446 if (pFrame->pvBuf)
447 {
448 Assert(pFrame->cbBuf);
449 RTMemFree(pFrame->pvBuf);
450 pFrame->pvBuf = NULL;
451 pFrame->cbBuf = 0;
452 }
453}
[96481]454
[105006]455/**
456 * Frees a previously allocated recording audio frame.
457 *
458 * @param pFrame Audio frame to free. The pointer will be invalid after return.
459 */
460void RecordingAudioFrameFree(PRECORDINGAUDIOFRAME pFrame)
461{
462 if (!pFrame)
463 return;
464
465 recordingAudioFrameDestroy(pFrame);
466
[96481]467 RTMemFree(pFrame);
[105006]468 pFrame = NULL;
[96481]469}
[105006]470#endif /* VBOX_WITH_AUDIO_RECORDING */
[96481]471
472/**
473 * Frees a recording frame.
474 *
[105006]475 * @param pFrame Pointer to recording frame to free.
476 * The pointer will be invalid after return.
[96481]477 */
478void RecordingFrameFree(PRECORDINGFRAME pFrame)
479{
480 if (!pFrame)
481 return;
482
483 switch (pFrame->enmType)
[74992]484 {
[97404]485#ifdef VBOX_WITH_AUDIO_RECORDING
[96481]486 case RECORDINGFRAME_TYPE_AUDIO:
[105006]487 recordingAudioFrameDestroy(&pFrame->u.Audio);
[96481]488 break;
[97404]489#endif
[96481]490 case RECORDINGFRAME_TYPE_VIDEO:
[105006]491 RecordingVideoFrameDestroy(&pFrame->u.Video);
[96481]492 break;
493
[105006]494 case RECORDINGFRAME_TYPE_CURSOR_SHAPE:
495 RecordingVideoFrameDestroy(&pFrame->u.CursorShape);
496 break;
497
[96481]498 default:
[105006]499 /* Nothing to do here. */
[96481]500 break;
[74992]501 }
[96481]502
[74992]503 RTMemFree(pFrame);
[96481]504 pFrame = NULL;
[74992]505}
506
Note: See TracBrowser for help on using the repository browser.

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