VirtualBox

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

Last change on this file since 96322 was 96322, checked in by vboxsync, 22 months ago

Recording/Main: Optimization: Check if recording stream updates are needed at display implementation level already, should save quite a few unnecessary calls. bugref:10275

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

© 2023 Oracle
ContactPrivacy policyTerms of Use