1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
/* $Id: Recording.h $ */
/** @file
* Recording code header.
*/
/*
* Copyright (C) 2012-2019 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#ifndef MAIN_INCLUDED_Recording_h
#define MAIN_INCLUDED_Recording_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif
#include <VBox/com/array.h>
#include <VBox/com/string.h>
#include <VBox/com/VirtualBox.h>
#include <VBox/settings.h>
using namespace com;
#include "RecordingInternals.h"
#include "RecordingStream.h"
class Console;
/**
* Class for managing a recording context.
*/
class RecordingContext
{
public:
RecordingContext(Console *pConsole, const settings::RecordingSettings &a_Settings);
virtual ~RecordingContext(void);
public:
const settings::RecordingSettings &GetConfig(void) const;
RecordingStream *GetStream(unsigned uScreen) const;
size_t GetStreamCount(void) const;
int Create(const settings::RecordingSettings &a_Settings);
void Destroy(void);
int Start(void);
int Stop(void);
int SendAudioFrame(const void *pvData, size_t cbData, uint64_t uTimestampMs);
int SendVideoFrame(uint32_t uScreen,
uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP,
uint32_t uBytesPerLine, uint32_t uSrcWidth, uint32_t uSrcHeight,
uint8_t *puSrcData, uint64_t msTimestamp);
public:
bool IsFeatureEnabled(RecordingFeature_T enmFeature);
bool IsReady(void);
bool IsReady(uint32_t uScreen, uint64_t msTimestamp);
bool IsStarted(void);
bool IsLimitReached(void);
bool IsLimitReached(uint32_t uScreen, uint64_t msTimestamp);
DECLCALLBACK(int) OnLimitReached(uint32_t uScreen, int rc);
protected:
int createInternal(const settings::RecordingSettings &a_Settings);
int startInternal(void);
int stopInternal(void);
void destroyInternal(void);
RecordingStream *getStreamInternal(unsigned uScreen) const;
int lock(void);
int unlock(void);
static DECLCALLBACK(int) threadMain(RTTHREAD hThreadSelf, void *pvUser);
int threadNotify(void);
protected:
/**
* Enumeration for a recording context state.
*/
enum RECORDINGSTS
{
/** Context not initialized. */
RECORDINGSTS_UNINITIALIZED = 0,
/** Context was created. */
RECORDINGSTS_CREATED = 1,
/** Context was started. */
RECORDINGSTS_STARTED = 2,
/** The usual 32-bit hack. */
RECORDINGSTS_32BIT_HACK = 0x7fffffff
};
/** Pointer to the console object. */
Console *pConsole;
/** Used recording configuration. */
settings::RecordingSettings Settings;
/** The current state. */
RECORDINGSTS enmState;
/** Critical section to serialize access. */
RTCRITSECT CritSect;
/** Semaphore to signal the encoding worker thread. */
RTSEMEVENT WaitEvent;
/** Shutdown indicator. */
bool fShutdown;
/** Worker thread. */
RTTHREAD Thread;
/** Vector of current recording streams.
* Per VM screen (display) one recording stream is being used. */
RecordingStreams vecStreams;
/** Number of streams in vecStreams which currently are enabled for recording. */
uint16_t cStreamsEnabled;
/** Timestamp (in ms) of when recording has been started. */
uint64_t tsStartMs;
/** Block map of common blocks which need to get multiplexed
* to all recording streams. This common block maps should help
* reducing the time spent in EMT and avoid doing the (expensive)
* multiplexing work in there.
*
* For now this only affects audio, e.g. all recording streams
* need to have the same audio data at a specific point in time. */
RecordingBlockMap mapBlocksCommon;
};
#endif /* !MAIN_INCLUDED_Recording_h */
|