VirtualBox

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

Last change on this file since 96407 was 96407, checked in by vboxsync, 22 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
RevLine 
[74992]1/* $Id: RecordingInternals.h 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
[75344]3 * Recording internals header.
[74992]4 */
5
6/*
[96407]7 * Copyright (C) 2012-2022 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
[76562]28#ifndef MAIN_INCLUDED_RecordingInternals_h
29#define MAIN_INCLUDED_RecordingInternals_h
[76487]30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
[74992]33
34#include <list>
35
[82428]36#include <iprt/assert.h>
[82422]37#include <iprt/types.h> /* drag in stdint.h before vpx does it. */
38
[96178]39#include "VBox/com/string.h"
[96175]40#include "VBox/com/VirtualBox.h"
41#include "VBox/settings.h"
42#include <VBox/vmm/pdmaudioifs.h>
43
[74992]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
[96175]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
[74992]77/**
[96175]78 * Enumeration for specifying a (generic) codec type.
[74992]79 */
[96175]80typedef enum RECORDINGCODECTYPE
[74992]81{
[96175]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 */
[96178]119 DECLCALLBACKMEMBER(int, pfnParseOptions, (PRECORDINGCODEC pCodec, const com::Utf8Str &strOptions));
[96175]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 */
[96229]130 DECLCALLBACKMEMBER(int, pfnEncode, (PRECORDINGCODEC pCodec, const PRECORDINGFRAME pFrame, size_t *pcEncoded, size_t *pcbEncoded));
[96175]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
[96229]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
[96175]150/**
151 * Structure for keeping a codec callback table.
152 */
153typedef struct RECORDINGCODECCALLBACKS
154{
[96229]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));
[96175]167 /** User-supplied data pointer. */
[96229]168 void *pvUser;
[96175]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. */
[74992]179 union
180 {
[96175]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 {
[74992]188 struct
189 {
[96175]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;
[74996]205 };
[96175]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;
[96229]209 /** Time (in ms) the encoder expects us to send data to encode.
[96175]210 *
[96229]211 * For Vorbis, valid frame sizes are powers of two from 64 to 8192 bytes.
[96175]212 */
213 uint32_t msFrame;
[96229]214 /** The frame size in bytes (based on \a msFrame). */
[96175]215 uint32_t cbFrame;
[96229]216 /** The frame size in samples per frame (based on \a msFrame). */
[96175]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;
[74992]241#endif /* VBOX_WITH_LIBVPX */
242
[96175]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/**
[96229]261 * Structure for keeping a codec's internal state.
262 */
263typedef struct RECORDINGCODECSTATE
264{
[96284]265 /** Timestamp Timestamp (PTS, in ms) of the last frame was encoded. */
[96229]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/**
[96175]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;
[96229]284 /** Generic codec parameters. */
285 RECORDINGCODECSTATE State;
[96175]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
[96229]303 /** Internal scratch buffer for en-/decoding steps. */
304 void *pvScratch;
305 /** Size (in bytes) of \a pvScratch. */
306 uint32_t cbScratch;
[96175]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;
[96229]315 } STAM;
[96175]316#endif
317} RECORDINGCODEC, *PRECORDINGCODEC;
318
319/**
[74992]320 * Enumeration for supported pixel formats.
321 */
[75354]322enum RECORDINGPIXELFMT
[74992]323{
324 /** Unknown pixel format. */
[75354]325 RECORDINGPIXELFMT_UNKNOWN = 0,
[74992]326 /** RGB 24. */
[75354]327 RECORDINGPIXELFMT_RGB24 = 1,
[74992]328 /** RGB 24. */
[75354]329 RECORDINGPIXELFMT_RGB32 = 2,
[74992]330 /** RGB 565. */
[75354]331 RECORDINGPIXELFMT_RGB565 = 3,
[74992]332 /** The usual 32-bit hack. */
[75354]333 RECORDINGPIXELFMT_32BIT_HACK = 0x7fffffff
[74992]334};
335
336/**
[75354]337 * Structure for keeping a single recording video frame.
[74992]338 */
[75354]339typedef struct RECORDINGVIDEOFRAME
[74992]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;
[75354]351} RECORDINGVIDEOFRAME, *PRECORDINGVIDEOFRAME;
[74992]352
353/**
[75354]354 * Structure for keeping a single recording audio frame.
[74992]355 */
[75354]356typedef struct RECORDINGAUDIOFRAME
[74992]357{
358 /** Pointer to audio data. */
359 uint8_t *pvBuf;
360 /** Size (in bytes) of audio data. */
361 size_t cbBuf;
[75354]362} RECORDINGAUDIOFRAME, *PRECORDINGAUDIOFRAME;
[96175]363
364/**
365 * Structure for keeping a single recording audio frame.
366 */
367typedef struct RECORDINGFRAME
368{
[96284]369 /** Timestamp (PTS, in ms). */
[96175]370 uint64_t msTimestamp;
371 union
372 {
373#ifdef VBOX_WITH_AUDIO_RECORDING
374 RECORDINGAUDIOFRAME Audio;
[74992]375#endif
[96175]376 RECORDINGVIDEOFRAME Video;
377 RECORDINGVIDEOFRAME *VideoPtr;
378 };
379} RECORDINGFRAME, *PRECORDINGFRAME;
[74992]380
381/**
382 * Enumeration for specifying a video recording block type.
383 */
[75354]384typedef enum RECORDINGBLOCKTYPE
[74992]385{
386 /** Uknown block type, do not use. */
[75354]387 RECORDINGBLOCKTYPE_UNKNOWN = 0,
[74992]388 /** The block is a video frame. */
[75354]389 RECORDINGBLOCKTYPE_VIDEO,
[74992]390 /** The block is an audio frame. */
[75354]391 RECORDINGBLOCKTYPE_AUDIO
392} RECORDINGBLOCKTYPE;
[74992]393
[75441]394#ifdef VBOX_WITH_AUDIO_RECORDING
395void RecordingAudioFrameFree(PRECORDINGAUDIOFRAME pFrame);
396#endif
397void RecordingVideoFrameFree(PRECORDINGVIDEOFRAME pFrame);
398
[74992]399/**
400 * Generic structure for keeping a single video recording (data) block.
401 */
[75441]402struct RecordingBlock
[74992]403{
[75441]404 RecordingBlock()
405 : enmType(RECORDINGBLOCKTYPE_UNKNOWN)
406 , cRefs(0)
[96229]407 , uFlags(RECORDINGCODEC_ENC_F_NONE)
[75441]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
[74992]443 /** The block's type. */
[75354]444 RECORDINGBLOCKTYPE enmType;
[74992]445 /** Number of references held of this block. */
446 uint16_t cRefs;
[96229]447 /** Block flags of type RECORDINGCODEC_ENC_F_XXX. */
448 uint64_t uFlags;
[75499]449 /** The (absolute) timestamp (in ms, PTS) of this block. */
450 uint64_t msTimestamp;
[74992]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;
[75441]455};
[74992]456
457/** List for keeping video recording (data) blocks. */
[75441]458typedef std::list<RecordingBlock *> RecordingBlockList;
[74992]459
[96175]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);
[96229]464int recordingCodecEncode(PRECORDINGCODEC pCodec, const PRECORDINGFRAME pFrame, size_t *pcEncoded, size_t *pcbEncoded);
[96175]465int recordingCodecFinalize(PRECORDINGCODEC pCodec);
[96322]466bool recordingCodecIsInitialized(const PRECORDINGCODEC pCodec);
467uint32_t recordingCodecGetWritable(const PRECORDINGCODEC pCodec, uint64_t msTimestamp);
[76562]468#endif /* !MAIN_INCLUDED_RecordingInternals_h */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use