VirtualBox

source: vbox/trunk/src/VBox/Main/include/RecordingInternals.h

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.7 KB
Line 
1/* $Id: RecordingInternals.h 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * Recording internals header.
4 */
5
6/*
7 * Copyright (C) 2012-2023 Oracle and/or its affiliates.
8 *
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
26 */
27
28#ifndef MAIN_INCLUDED_RecordingInternals_h
29#define MAIN_INCLUDED_RecordingInternals_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include <list>
35
36#include <iprt/assert.h>
37#include <iprt/types.h> /* drag in stdint.h before vpx does it. */
38
39#include "VBox/com/string.h"
40#include "VBox/com/VirtualBox.h"
41#include "VBox/settings.h"
42#include <VBox/vmm/pdmaudioifs.h>
43
44#ifdef VBOX_WITH_LIBVPX
45# define VPX_CODEC_DISABLE_COMPAT 1
46# include "vpx/vp8cx.h"
47# include "vpx/vpx_image.h"
48# include "vpx/vpx_encoder.h"
49#endif /* VBOX_WITH_LIBVPX */
50
51#ifdef VBOX_WITH_LIBVORBIS
52# include "vorbis/vorbisenc.h"
53#endif
54
55
56/*********************************************************************************************************************************
57* Defines *
58*********************************************************************************************************************************/
59#define VBOX_RECORDING_VORBIS_HZ_MAX 48000 /**< Maximum sample rate (in Hz) Vorbis can handle. */
60#define VBOX_RECORDING_VORBIS_FRAME_MS_DEFAULT 20 /**< Default Vorbis frame size (in ms). */
61
62
63/*********************************************************************************************************************************
64* Prototypes *
65*********************************************************************************************************************************/
66struct RECORDINGCODEC;
67typedef RECORDINGCODEC *PRECORDINGCODEC;
68
69struct RECORDINGFRAME;
70typedef RECORDINGFRAME *PRECORDINGFRAME;
71
72
73/*********************************************************************************************************************************
74* Internal structures, defines and APIs *
75*********************************************************************************************************************************/
76
77/**
78 * Enumeration for specifying a (generic) codec type.
79 */
80typedef enum RECORDINGCODECTYPE
81{
82 /** Invalid codec type. Do not use. */
83 RECORDINGCODECTYPE_INVALID = 0,
84 /** Video codec. */
85 RECORDINGCODECTYPE_VIDEO,
86 /** Audio codec. */
87 RECORDINGCODECTYPE_AUDIO
88} RECORDINGCODECTYPE;
89
90/**
91 * Structure for keeping a codec operations table.
92 */
93typedef struct RECORDINGCODECOPS
94{
95 /**
96 * Initializes a codec.
97 *
98 * @returns VBox status code.
99 * @param pCodec Codec instance to initialize.
100 */
101 DECLCALLBACKMEMBER(int, pfnInit, (PRECORDINGCODEC pCodec));
102
103 /**
104 * Destroys a codec.
105 *
106 * @returns VBox status code.
107 * @param pCodec Codec instance to destroy.
108 */
109 DECLCALLBACKMEMBER(int, pfnDestroy, (PRECORDINGCODEC pCodec));
110
111 /**
112 * Parses an options string to configure advanced / hidden / experimental features of a recording stream.
113 * Unknown values will be skipped. Optional.
114 *
115 * @returns VBox status code.
116 * @param pCodec Codec instance to parse options for.
117 * @param strOptions Options string to parse.
118 */
119 DECLCALLBACKMEMBER(int, pfnParseOptions, (PRECORDINGCODEC pCodec, const com::Utf8Str &strOptions));
120
121 /**
122 * Feeds the codec encoder with data to encode.
123 *
124 * @returns VBox status code.
125 * @param pCodec Codec instance to use.
126 * @param pFrame Pointer to frame data to encode.
127 * @param pcEncoded Where to return the number of encoded blocks in \a pvDst on success. Optional.
128 * @param pcbEncoded Where to return the number of encoded bytes in \a pvDst on success. Optional.
129 */
130 DECLCALLBACKMEMBER(int, pfnEncode, (PRECORDINGCODEC pCodec, const PRECORDINGFRAME pFrame, size_t *pcEncoded, size_t *pcbEncoded));
131
132 /**
133 * Tells the codec to finalize the current stream. Optional.
134 *
135 * @returns VBox status code.
136 * @param pCodec Codec instance to finalize stream for.
137 */
138 DECLCALLBACKMEMBER(int, pfnFinalize, (PRECORDINGCODEC pCodec));
139} RECORDINGCODECOPS, *PRECORDINGCODECOPS;
140
141/** No encoding flags set. */
142#define RECORDINGCODEC_ENC_F_NONE UINT32_C(0)
143/** Data block is a key block. */
144#define RECORDINGCODEC_ENC_F_BLOCK_IS_KEY RT_BIT_32(0)
145/** Data block is invisible. */
146#define RECORDINGCODEC_ENC_F_BLOCK_IS_INVISIBLE RT_BIT_32(1)
147/** Encoding flags valid mask. */
148#define RECORDINGCODEC_ENC_F_VALID_MASK 0x1
149
150/**
151 * Structure for keeping a codec callback table.
152 */
153typedef struct RECORDINGCODECCALLBACKS
154{
155 /**
156 * Callback for notifying that encoded data has been written.
157 *
158 * @returns VBox status code.
159 * @param pCodec Pointer to codec instance which has written the data.
160 * @param pvData Pointer to written data (encoded).
161 * @param cbData Size (in bytes) of \a pvData.
162 * @param msAbsPTS Absolute PTS (in ms) of the written data.
163 * @param uFlags Encoding flags of type RECORDINGCODEC_ENC_F_XXX.
164 * @param pvUser User-supplied pointer.
165 */
166 DECLCALLBACKMEMBER(int, pfnWriteData, (PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags, void *pvUser));
167 /** User-supplied data pointer. */
168 void *pvUser;
169} RECORDINGCODECCALLBACKS, *PRECORDINGCODECCALLBACKS;
170
171/**
172 * Structure for keeping generic codec parameters.
173 */
174typedef struct RECORDINGCODECPARMS
175{
176 /** The generic codec type. */
177 RECORDINGCODECTYPE enmType;
178 /** The specific codec type, based on \a enmType. */
179 union
180 {
181 /** The container's video codec to use. */
182 RecordingVideoCodec_T enmVideoCodec;
183 /** The container's audio codec to use. */
184 RecordingAudioCodec_T enmAudioCodec;
185 };
186 union
187 {
188 struct
189 {
190 /** Frames per second. */
191 uint8_t uFPS;
192 /** Target width (in pixels) of encoded video image. */
193 uint16_t uWidth;
194 /** Target height (in pixels) of encoded video image. */
195 uint16_t uHeight;
196 /** Minimal delay (in ms) between two video frames.
197 * This value is based on the configured FPS rate. */
198 uint32_t uDelayMs;
199 } Video;
200 struct
201 {
202 /** The codec's used PCM properties. */
203 PDMAUDIOPCMPROPS PCMProps;
204 } Audio;
205 };
206 /** Desired (average) bitrate (in kbps) to use, for codecs which support bitrate management.
207 * Set to 0 to use a variable bit rate (VBR) (if available, otherwise fall back to CBR). */
208 uint32_t uBitrate;
209 /** Time (in ms) the encoder expects us to send data to encode.
210 *
211 * For Vorbis, valid frame sizes are powers of two from 64 to 8192 bytes.
212 */
213 uint32_t msFrame;
214 /** The frame size in bytes (based on \a msFrame). */
215 uint32_t cbFrame;
216 /** The frame size in samples per frame (based on \a msFrame). */
217 uint32_t csFrame;
218} RECORDINGCODECPARMS, *PRECORDINGCODECPARMS;
219
220#ifdef VBOX_WITH_LIBVPX
221/**
222 * VPX encoder state (needs libvpx).
223 */
224typedef struct RECORDINGCODECVPX
225{
226 /** VPX codec context. */
227 vpx_codec_ctx_t Ctx;
228 /** VPX codec configuration. */
229 vpx_codec_enc_cfg_t Cfg;
230 /** VPX image context. */
231 vpx_image_t RawImage;
232 /** Pointer to the codec's internal YUV buffer. */
233 uint8_t *pu8YuvBuf;
234 /** The encoder's deadline (in ms).
235 * The more time the encoder is allowed to spend encoding, the better the encoded
236 * result, in exchange for higher CPU usage and time spent encoding. */
237 unsigned int uEncoderDeadline;
238} RECORDINGCODECVPX;
239/** Pointer to a VPX encoder state. */
240typedef RECORDINGCODECVPX *PRECORDINGCODECVPX;
241#endif /* VBOX_WITH_LIBVPX */
242
243#ifdef VBOX_WITH_LIBVORBIS
244/**
245 * Vorbis encoder state (needs libvorbis + libogg).
246 */
247typedef struct RECORDINGCODECVORBIS
248{
249 /** Basic information about the audio in a Vorbis bitstream. */
250 vorbis_info info;
251 /** Encoder state. */
252 vorbis_dsp_state dsp_state;
253 /** Current block being worked on. */
254 vorbis_block block_cur;
255} RECORDINGCODECVORBIS;
256/** Pointer to a Vorbis encoder state. */
257typedef RECORDINGCODECVORBIS *PRECORDINGCODECVORBIS;
258#endif /* VBOX_WITH_LIBVORBIS */
259
260/**
261 * Structure for keeping a codec's internal state.
262 */
263typedef struct RECORDINGCODECSTATE
264{
265 /** Timestamp Timestamp (PTS, in ms) of the last frame was encoded. */
266 uint64_t tsLastWrittenMs;
267 /** Number of encoding errors. */
268 uint64_t cEncErrors;
269} RECORDINGCODECSTATE;
270/** Pointer to an internal encoder state. */
271typedef RECORDINGCODECSTATE *PRECORDINGCODECSTATE;
272
273/**
274 * Structure for keeping codec-specific data.
275 */
276typedef struct RECORDINGCODEC
277{
278 /** Callback table for codec operations. */
279 RECORDINGCODECOPS Ops;
280 /** Table for user-supplied callbacks. */
281 RECORDINGCODECCALLBACKS Callbacks;
282 /** Generic codec parameters. */
283 RECORDINGCODECPARMS Parms;
284 /** Generic codec parameters. */
285 RECORDINGCODECSTATE State;
286
287#ifdef VBOX_WITH_LIBVPX
288 union
289 {
290 RECORDINGCODECVPX VPX;
291 } Video;
292#endif
293
294#ifdef VBOX_WITH_AUDIO_RECORDING
295 union
296 {
297# ifdef VBOX_WITH_LIBVORBIS
298 RECORDINGCODECVORBIS Vorbis;
299# endif /* VBOX_WITH_LIBVORBIS */
300 } Audio;
301#endif /* VBOX_WITH_AUDIO_RECORDING */
302
303 /** Internal scratch buffer for en-/decoding steps. */
304 void *pvScratch;
305 /** Size (in bytes) of \a pvScratch. */
306 uint32_t cbScratch;
307
308#ifdef VBOX_WITH_STATISTICS /** @todo Register these values with STAM. */
309 struct
310 {
311 /** Number of frames encoded. */
312 uint64_t cEncBlocks;
313 /** Total time (in ms) of already encoded audio data. */
314 uint64_t msEncTotal;
315 } STAM;
316#endif
317} RECORDINGCODEC, *PRECORDINGCODEC;
318
319/**
320 * Enumeration for supported pixel formats.
321 */
322enum RECORDINGPIXELFMT
323{
324 /** Unknown pixel format. */
325 RECORDINGPIXELFMT_UNKNOWN = 0,
326 /** RGB 24. */
327 RECORDINGPIXELFMT_RGB24 = 1,
328 /** RGB 24. */
329 RECORDINGPIXELFMT_RGB32 = 2,
330 /** RGB 565. */
331 RECORDINGPIXELFMT_RGB565 = 3,
332 /** The usual 32-bit hack. */
333 RECORDINGPIXELFMT_32BIT_HACK = 0x7fffffff
334};
335
336/**
337 * Enumeration for a recording frame type.
338 */
339enum RECORDINGFRAME_TYPE
340{
341 /** Invalid frame type; do not use. */
342 RECORDINGFRAME_TYPE_INVALID = 0,
343 /** Frame is an audio frame. */
344 RECORDINGFRAME_TYPE_AUDIO = 1,
345 /** Frame is an video frame. */
346 RECORDINGFRAME_TYPE_VIDEO = 2,
347 /** Frame contains a video frame pointer. */
348 RECORDINGFRAME_TYPE_VIDEO_PTR = 3
349};
350
351/**
352 * Structure for keeping a single recording video frame.
353 */
354typedef struct RECORDINGVIDEOFRAME
355{
356 /** X origin (in pixel) of this frame. */
357 uint16_t uX;
358 /** X origin (in pixel) of this frame. */
359 uint16_t uY;
360 /** X resolution (in pixel) of this frame. */
361 uint16_t uWidth;
362 /** Y resolution (in pixel) of this frame. */
363 uint16_t uHeight;
364 /** Bits per pixel (BPP). */
365 uint8_t uBPP;
366 /** Pixel format of this frame. */
367 RECORDINGPIXELFMT enmPixelFmt;
368 /** Bytes per scan line. */
369 uint16_t uBytesPerLine;
370 /** RGB buffer containing the unmodified frame buffer data from Main's display. */
371 uint8_t *pu8RGBBuf;
372 /** Size (in bytes) of the RGB buffer. */
373 size_t cbRGBBuf;
374} RECORDINGVIDEOFRAME, *PRECORDINGVIDEOFRAME;
375
376/**
377 * Structure for keeping a single recording audio frame.
378 */
379typedef struct RECORDINGAUDIOFRAME
380{
381 /** Pointer to audio data. */
382 uint8_t *pvBuf;
383 /** Size (in bytes) of audio data. */
384 size_t cbBuf;
385} RECORDINGAUDIOFRAME, *PRECORDINGAUDIOFRAME;
386
387/**
388 * Structure for keeping a single recording audio frame.
389 */
390typedef struct RECORDINGFRAME
391{
392 /** List node. */
393 RTLISTNODE Node;
394 /** Stream index (hint) where this frame should go to.
395 * Specify UINT16_MAX to broadcast to all streams. */
396 uint16_t idStream;
397 /** The frame type. */
398 RECORDINGFRAME_TYPE enmType;
399 /** Timestamp (PTS, in ms). */
400 uint64_t msTimestamp;
401 union
402 {
403#ifdef VBOX_WITH_AUDIO_RECORDING
404 /** Audio frame data. */
405 RECORDINGAUDIOFRAME Audio;
406#endif
407 /** Video frame data. */
408 RECORDINGVIDEOFRAME Video;
409 /** A (weak) pointer to a video frame. */
410 RECORDINGVIDEOFRAME *VideoPtr;
411 };
412} RECORDINGFRAME, *PRECORDINGFRAME;
413
414/**
415 * Enumeration for specifying a video recording block type.
416 */
417typedef enum RECORDINGBLOCKTYPE
418{
419 /** Uknown block type, do not use. */
420 RECORDINGBLOCKTYPE_UNKNOWN = 0,
421 /** The block is a video frame. */
422 RECORDINGBLOCKTYPE_VIDEO,
423 /** The block is an audio frame. */
424 RECORDINGBLOCKTYPE_AUDIO
425} RECORDINGBLOCKTYPE;
426
427#ifdef VBOX_WITH_AUDIO_RECORDING
428int RecordingVideoFrameInit(PRECORDINGVIDEOFRAME pFrame, int w, int h, uint8_t uBPP, RECORDINGPIXELFMT enmPixelFmt);
429void RecordingVideoFrameDestroy(PRECORDINGVIDEOFRAME pFrame);
430void RecordingAudioFrameFree(PRECORDINGAUDIOFRAME pFrame);
431#endif
432void RecordingVideoFrameFree(PRECORDINGVIDEOFRAME pFrame);
433void RecordingFrameFree(PRECORDINGFRAME pFrame);
434
435/**
436 * Generic structure for keeping a single video recording (data) block.
437 */
438struct RecordingBlock
439{
440 RecordingBlock()
441 : enmType(RECORDINGBLOCKTYPE_UNKNOWN)
442 , cRefs(0)
443 , uFlags(RECORDINGCODEC_ENC_F_NONE)
444 , pvData(NULL)
445 , cbData(0) { }
446
447 virtual ~RecordingBlock()
448 {
449 Reset();
450 }
451
452 void Reset(void)
453 {
454 switch (enmType)
455 {
456 case RECORDINGBLOCKTYPE_UNKNOWN:
457 break;
458
459 case RECORDINGBLOCKTYPE_VIDEO:
460 RecordingVideoFrameFree((PRECORDINGVIDEOFRAME)pvData);
461 break;
462
463#ifdef VBOX_WITH_AUDIO_RECORDING
464 case RECORDINGBLOCKTYPE_AUDIO:
465 RecordingAudioFrameFree((PRECORDINGAUDIOFRAME)pvData);
466 break;
467#endif
468 default:
469 AssertFailed();
470 break;
471 }
472
473 enmType = RECORDINGBLOCKTYPE_UNKNOWN;
474 cRefs = 0;
475 pvData = NULL;
476 cbData = 0;
477 }
478
479 /** The block's type. */
480 RECORDINGBLOCKTYPE enmType;
481 /** Number of references held of this block. */
482 uint16_t cRefs;
483 /** Block flags of type RECORDINGCODEC_ENC_F_XXX. */
484 uint64_t uFlags;
485 /** The (absolute) timestamp (in ms, PTS) of this block. */
486 uint64_t msTimestamp;
487 /** Opaque data block to the actual block data, depending on the block's type. */
488 void *pvData;
489 /** Size (in bytes) of the (opaque) data block. */
490 size_t cbData;
491};
492
493/** List for keeping video recording (data) blocks. */
494typedef std::list<RecordingBlock *> RecordingBlockList;
495
496int recordingCodecCreateAudio(PRECORDINGCODEC pCodec, RecordingAudioCodec_T enmAudioCodec);
497int recordingCodecCreateVideo(PRECORDINGCODEC pCodec, RecordingVideoCodec_T enmVideoCodec);
498int recordingCodecInit(const PRECORDINGCODEC pCodec, const PRECORDINGCODECCALLBACKS pCallbacks, const settings::RecordingScreenSettings &Settings);
499int recordingCodecDestroy(PRECORDINGCODEC pCodec);
500int recordingCodecEncode(PRECORDINGCODEC pCodec, const PRECORDINGFRAME pFrame, size_t *pcEncoded, size_t *pcbEncoded);
501int recordingCodecFinalize(PRECORDINGCODEC pCodec);
502bool recordingCodecIsInitialized(const PRECORDINGCODEC pCodec);
503uint32_t recordingCodecGetWritable(const PRECORDINGCODEC pCodec, uint64_t msTimestamp);
504#endif /* !MAIN_INCLUDED_RecordingInternals_h */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use