VirtualBox

source: vbox/trunk/src/VBox/Main/include/RecordingStream.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: 7.0 KB
Line 
1/* $Id: RecordingStream.h 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * Recording stream code 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_RecordingStream_h
29#define MAIN_INCLUDED_RecordingStream_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include <map>
35#include <vector>
36
37#include <iprt/critsect.h>
38
39#include "RecordingInternals.h"
40
41class WebMWriter;
42class RecordingContext;
43
44/** Structure for queuing all blocks bound to a single timecode.
45 * This can happen if multiple tracks are being involved. */
46struct RecordingBlocks
47{
48 virtual ~RecordingBlocks()
49 {
50 Clear();
51 }
52
53 /**
54 * Resets a recording block list by removing (destroying)
55 * all current elements.
56 */
57 void Clear()
58 {
59 while (!List.empty())
60 {
61 RecordingBlock *pBlock = List.front();
62 List.pop_front();
63 delete pBlock;
64 }
65
66 Assert(List.size() == 0);
67 }
68
69 /** The actual block list for this timecode. */
70 RecordingBlockList List;
71};
72
73/** A block map containing all currently queued blocks.
74 * The key specifies a unique timecode, whereas the value
75 * is a list of blocks which all correlate to the same key (timecode). */
76typedef std::map<uint64_t, RecordingBlocks *> RecordingBlockMap;
77
78/**
79 * Structure for holding a set of recording (data) blocks.
80 */
81struct RecordingBlockSet
82{
83 virtual ~RecordingBlockSet()
84 {
85 Clear();
86 }
87
88 /**
89 * Resets a recording block set by removing (destroying)
90 * all current elements.
91 */
92 void Clear(void)
93 {
94 RecordingBlockMap::iterator it = Map.begin();
95 while (it != Map.end())
96 {
97 it->second->Clear();
98 delete it->second;
99 Map.erase(it);
100 it = Map.begin();
101 }
102
103 Assert(Map.size() == 0);
104 }
105
106 /** Timestamp (in ms) when this set was last processed. */
107 uint64_t tsLastProcessedMs;
108 /** All blocks related to this block set. */
109 RecordingBlockMap Map;
110};
111
112/**
113 * Class for managing a recording stream.
114 *
115 * A recording stream represents one entity to record (e.g. on screen / monitor),
116 * so there is a 1:1 mapping (stream <-> monitors).
117 */
118class RecordingStream
119{
120public:
121
122 RecordingStream(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreenSettings &Settings);
123
124 virtual ~RecordingStream(void);
125
126public:
127
128 int Init(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreenSettings &Settings);
129 int Uninit(void);
130
131 int Process(RecordingBlockMap &mapBlocksCommon);
132 int SendAudioFrame(const void *pvData, size_t cbData, uint64_t msTimestamp);
133 int SendVideoFrame(uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP, uint32_t uBytesPerLine,
134 uint32_t uSrcWidth, uint32_t uSrcHeight, uint8_t *puSrcData, uint64_t msTimestamp);
135
136 const settings::RecordingScreenSettings &GetConfig(void) const;
137 uint16_t GetID(void) const { return this->m_uScreenID; };
138#ifdef VBOX_WITH_AUDIO_RECORDING
139 PRECORDINGCODEC GetAudioCodec(void) { return this->m_pCodecAudio; };
140#endif
141 PRECORDINGCODEC GetVideoCodec(void) { return &this->m_CodecVideo; };
142
143 bool IsLimitReached(uint64_t msTimestamp) const;
144 bool IsReady(void) const;
145 bool NeedsUpdate(uint64_t msTimestamp) const;
146
147public:
148
149 static DECLCALLBACK(int) codecWriteDataCallback(PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags, void *pvUser);
150
151protected:
152
153 int open(const settings::RecordingScreenSettings &screenSettings);
154 int close(void);
155
156 int initInternal(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreenSettings &screenSettings);
157 int uninitInternal(void);
158
159 int initVideo(const settings::RecordingScreenSettings &screenSettings);
160 int unitVideo(void);
161
162 bool isLimitReachedInternal(uint64_t msTimestamp) const;
163 int iterateInternal(uint64_t msTimestamp);
164
165 int codecWriteToWebM(PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags);
166
167 void lock(void);
168 void unlock(void);
169
170protected:
171
172 /**
173 * Enumeration for a recording stream state.
174 */
175 enum RECORDINGSTREAMSTATE
176 {
177 /** Stream not initialized. */
178 RECORDINGSTREAMSTATE_UNINITIALIZED = 0,
179 /** Stream was initialized. */
180 RECORDINGSTREAMSTATE_INITIALIZED = 1,
181 /** The usual 32-bit hack. */
182 RECORDINGSTREAMSTATE_32BIT_HACK = 0x7fffffff
183 };
184
185 /** Recording context this stream is associated to. */
186 RecordingContext *m_pCtx;
187 /** The current state. */
188 RECORDINGSTREAMSTATE m_enmState;
189 struct
190 {
191 /** File handle to use for writing. */
192 RTFILE m_hFile;
193 /** Pointer to WebM writer instance being used. */
194 WebMWriter *m_pWEBM;
195 } File;
196 bool m_fEnabled;
197 /** Track number of audio stream.
198 * Set to UINT8_MAX if not being used. */
199 uint8_t m_uTrackAudio;
200 /** Track number of video stream.
201 * Set to UINT8_MAX if not being used. */
202 uint8_t m_uTrackVideo;
203 /** Screen ID. */
204 uint16_t m_uScreenID;
205 /** Critical section to serialize access. */
206 RTCRITSECT m_CritSect;
207 /** Timestamp (in ms) of when recording has been started. */
208 uint64_t m_tsStartMs;
209#ifdef VBOX_WITH_AUDIO_RECORDING
210 /** Pointer to audio codec instance data to use.
211 *
212 * We multiplex audio data from the recording context to all streams,
213 * to avoid encoding the same audio data for each stream. We ASSUME that
214 * all audio data of a VM will be the same for each stream at a given
215 * point in time.
216 *
217 * Might be NULL if not being used. */
218 PRECORDINGCODEC m_pCodecAudio;
219#endif /* VBOX_WITH_AUDIO_RECORDING */
220 /** Video codec instance data to use. */
221 RECORDINGCODEC m_CodecVideo;
222 /** Screen settings to use. */
223 settings::RecordingScreenSettings
224 m_ScreenSettings;
225 /** Common set of recording (data) blocks, needed for
226 * multiplexing to all recording streams. */
227 RecordingBlockSet m_Blocks;
228};
229
230/** Vector of recording streams. */
231typedef std::vector <RecordingStream *> RecordingStreams;
232
233#endif /* !MAIN_INCLUDED_RecordingStream_h */
234
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use