VirtualBox

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

Last change on this file since 96407 was 96407, checked in by vboxsync, 21 months ago

scm copyright and license note update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.4 KB
Line 
1/* $Id: RecordingInternals.h 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
3 * Recording internals header.
4 */
5
6/*
7 * Copyright (C) 2012-2022 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 * Structure for keeping a single recording video frame.
338 */
339typedef struct RECORDINGVIDEOFRAME
340{
341 /** X resolution of this frame. */
342 uint32_t uWidth;
343 /** Y resolution of this frame. */
344 uint32_t uHeight;
345 /** Pixel format of this frame. */
346 uint32_t uPixelFormat;
347 /** RGB buffer containing the unmodified frame buffer data from Main's display. */
348 uint8_t *pu8RGBBuf;
349 /** Size (in bytes) of the RGB buffer. */
350 size_t cbRGBBuf;
351} RECORDINGVIDEOFRAME, *PRECORDINGVIDEOFRAME;
352
353/**
354 * Structure for keeping a single recording audio frame.
355 */
356typedef struct RECORDINGAUDIOFRAME
357{
358 /** Pointer to audio data. */
359 uint8_t *pvBuf;
360 /** Size (in bytes) of audio data. */
361 size_t cbBuf;
362} RECORDINGAUDIOFRAME, *PRECORDINGAUDIOFRAME;
363
364/**
365 * Structure for keeping a single recording audio frame.
366 */
367typedef struct RECORDINGFRAME
368{
369 /** Timestamp (PTS, in ms). */
370 uint64_t msTimestamp;
371 union
372 {
373#ifdef VBOX_WITH_AUDIO_RECORDING
374 RECORDINGAUDIOFRAME Audio;
375#endif
376 RECORDINGVIDEOFRAME Video;
377 RECORDINGVIDEOFRAME *VideoPtr;
378 };
379} RECORDINGFRAME, *PRECORDINGFRAME;
380
381/**
382 * Enumeration for specifying a video recording block type.
383 */
384typedef enum RECORDINGBLOCKTYPE
385{
386 /** Uknown block type, do not use. */
387 RECORDINGBLOCKTYPE_UNKNOWN = 0,
388 /** The block is a video frame. */
389 RECORDINGBLOCKTYPE_VIDEO,
390 /** The block is an audio frame. */
391 RECORDINGBLOCKTYPE_AUDIO
392} RECORDINGBLOCKTYPE;
393
394#ifdef VBOX_WITH_AUDIO_RECORDING
395void RecordingAudioFrameFree(PRECORDINGAUDIOFRAME pFrame);
396#endif
397void RecordingVideoFrameFree(PRECORDINGVIDEOFRAME pFrame);
398
399/**
400 * Generic structure for keeping a single video recording (data) block.
401 */
402struct RecordingBlock
403{
404 RecordingBlock()
405 : enmType(RECORDINGBLOCKTYPE_UNKNOWN)
406 , cRefs(0)
407 , uFlags(RECORDINGCODEC_ENC_F_NONE)
408 , pvData(NULL)
409 , cbData(0) { }
410
411 virtual ~RecordingBlock()
412 {
413 Reset();
414 }
415
416 void Reset(void)
417 {
418 switch (enmType)
419 {
420 case RECORDINGBLOCKTYPE_UNKNOWN:
421 break;
422
423 case RECORDINGBLOCKTYPE_VIDEO:
424 RecordingVideoFrameFree((PRECORDINGVIDEOFRAME)pvData);
425 break;
426
427#ifdef VBOX_WITH_AUDIO_RECORDING
428 case RECORDINGBLOCKTYPE_AUDIO:
429 RecordingAudioFrameFree((PRECORDINGAUDIOFRAME)pvData);
430 break;
431#endif
432 default:
433 AssertFailed();
434 break;
435 }
436
437 enmType = RECORDINGBLOCKTYPE_UNKNOWN;
438 cRefs = 0;
439 pvData = NULL;
440 cbData = 0;
441 }
442
443 /** The block's type. */
444 RECORDINGBLOCKTYPE enmType;
445 /** Number of references held of this block. */
446 uint16_t cRefs;
447 /** Block flags of type RECORDINGCODEC_ENC_F_XXX. */
448 uint64_t uFlags;
449 /** The (absolute) timestamp (in ms, PTS) of this block. */
450 uint64_t msTimestamp;
451 /** Opaque data block to the actual block data, depending on the block's type. */
452 void *pvData;
453 /** Size (in bytes) of the (opaque) data block. */
454 size_t cbData;
455};
456
457/** List for keeping video recording (data) blocks. */
458typedef std::list<RecordingBlock *> RecordingBlockList;
459
460int recordingCodecCreateAudio(PRECORDINGCODEC pCodec, RecordingAudioCodec_T enmAudioCodec);
461int recordingCodecCreateVideo(PRECORDINGCODEC pCodec, RecordingVideoCodec_T enmVideoCodec);
462int recordingCodecInit(const PRECORDINGCODEC pCodec, const PRECORDINGCODECCALLBACKS pCallbacks, const settings::RecordingScreenSettings &Settings);
463int recordingCodecDestroy(PRECORDINGCODEC pCodec);
464int recordingCodecEncode(PRECORDINGCODEC pCodec, const PRECORDINGFRAME pFrame, size_t *pcEncoded, size_t *pcbEncoded);
465int recordingCodecFinalize(PRECORDINGCODEC pCodec);
466bool recordingCodecIsInitialized(const PRECORDINGCODEC pCodec);
467uint32_t recordingCodecGetWritable(const PRECORDINGCODEC pCodec, uint64_t msTimestamp);
468#endif /* !MAIN_INCLUDED_RecordingInternals_h */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use