forked from moonlight-stream/moonlight-chrome
-
Notifications
You must be signed in to change notification settings - Fork 0
/
moonlight.hpp
184 lines (142 loc) · 6.91 KB
/
moonlight.hpp
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/var_dictionary.h"
#include "ppapi/cpp/mouse_lock.h"
#include "ppapi/cpp/graphics_3d.h"
#include "ppapi/cpp/video_decoder.h"
#include "ppapi/cpp/audio.h"
#include "ppapi/cpp/text_input_controller.h"
#include "ppapi/c/ppb_gamepad.h"
#include "ppapi/c/pp_input_event.h"
#include "ppapi/c/ppb_opengles2.h"
#include "ppapi/cpp/graphics_3d.h"
#include "ppapi/cpp/graphics_3d_client.h"
#include "ppapi/utility/completion_callback_factory.h"
#include "ppapi/utility/threading/simple_thread.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include "nacl_io/nacl_io.h"
#include <queue>
#include <Limelight.h>
#include <opus_multistream.h>
// Uncomment this line to enable the profiling infrastructure
//#define ENABLE_PROFILING 1
// Use this define to choose the time threshold in milliseconds above
// which a profiling message is printed
#define PROFILING_MESSAGE_THRESHOLD 1
#define DR_FLAG_FORCE_SW_DECODE 0x01
struct Shader {
Shader() : program(0), texcoord_scale_location(0) {}
~Shader() {}
GLuint program;
GLint texcoord_scale_location;
};
class MoonlightInstance : public pp::Instance, public pp::MouseLock {
public:
explicit MoonlightInstance(PP_Instance instance) :
pp::Instance(instance),
pp::MouseLock(this),
m_HasNextPicture(false),
m_IsPainting(false),
m_RequestIdrFrame(false),
m_OpusDecoder(NULL),
m_CallbackFactory(this),
m_MouseLocked(false),
m_WaitingForAllModifiersUp(false),
m_AccumulatedTicks(0),
m_MouseDeltaX(0),
m_MouseDeltaY(0),
openHttpThread(this) {
// This function MUST be used otherwise sockets don't work (nacl_io_init() doesn't work!)
nacl_io_init_ppapi(pp_instance(), pp::Module::Get()->get_browser_interface());
LiInitializeStreamConfiguration(&m_StreamConfig);
pp::TextInputController(this).SetTextInputType(PP_TEXTINPUT_TYPE_NONE);
m_GamepadApi = static_cast<const PPB_Gamepad*>(pp::Module::Get()->GetBrowserInterface(PPB_GAMEPAD_INTERFACE));
openHttpThread.Start();
}
virtual ~MoonlightInstance();
bool Init(uint32_t argc, const char* argn[], const char* argv[]);
void HandleMessage(const pp::Var& var_message);
void HandlePair(int32_t callbackId, pp::VarArray args);
void HandleShowGames(int32_t callbackId, pp::VarArray args);
void HandleStartStream(int32_t callbackId, pp::VarArray args);
void HandleStopStream(int32_t callbackId, pp::VarArray args);
void HandleOpenURL(int32_t callbackId, pp::VarArray args);
void PairCallback(int32_t /*result*/, int32_t callbackId, pp::VarArray args);
bool HandleInputEvent(const pp::InputEvent& event);
void ReportMouseMovement();
void PollGamepads();
void MouseLockLost();
void DidLockMouse(int32_t result);
void OnConnectionStopped(uint32_t unused);
void OnConnectionStarted(uint32_t error);
void StopConnection();
static uint32_t ProfilerGetPackedMillis();
static uint64_t ProfilerGetMillis();
static uint64_t ProfilerUnpackTime(uint32_t packedTime);
static void ProfilerPrintPackedDelta(const char* message, uint32_t packedTimeA, uint32_t packedTimeB);
static void ProfilerPrintDelta(const char* message, uint64_t timeA, uint64_t timeB);
static void ProfilerPrintPackedDeltaFromNow(const char* message, uint32_t packedTime);
static void ProfilerPrintDeltaFromNow(const char* message, uint64_t time);
static void ProfilerPrintWarning(const char* message);
static void* ConnectionThreadFunc(void* context);
static void* InputThreadFunc(void* context);
static void* StopThreadFunc(void* context);
static void ClStageStarting(int stage);
static void ClStageFailed(int stage, long errorCode);
static void ClConnectionStarted(void);
static void ClConnectionTerminated(long errorCode);
static void ClDisplayMessage(const char* message);
static void ClDisplayTransientMessage(const char* message);
static void ClLogMessage(const char* format, ...);
static Shader CreateProgram(const char* vertexShader, const char* fragmentShader);
static void CreateShader(GLuint program, GLenum type, const char* source, int size);
void PaintFinished(int32_t result);
void DispatchGetPicture(uint32_t unused);
void PictureReady(int32_t result, PP_VideoPicture picture);
void PaintPicture(void);
bool InitializeRenderingSurface(int width, int height);
void DidChangeFocus(bool got_focus);
static int VidDecSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags);
static void VidDecCleanup(void);
static int VidDecSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
static int AudDecInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int flags);
static void AudDecCleanup(void);
static void AudDecDecodeAndPlaySample(char* sampleData, int sampleLength);
void MakeCert(int32_t callbackId, pp::VarArray args);
void LoadCert(const char* certStr, const char* keyStr);
void NvHTTPInit(int32_t callbackId, pp::VarArray args);
void NvHTTPRequest(int32_t, int32_t callbackId, std::string url, bool binaryResponse);
private:
static CONNECTION_LISTENER_CALLBACKS s_ClCallbacks;
static DECODER_RENDERER_CALLBACKS s_DrCallbacks;
static AUDIO_RENDERER_CALLBACKS s_ArCallbacks;
std::string m_Host;
std::string m_AppVersion;
STREAM_CONFIGURATION m_StreamConfig;
bool m_Running;
pthread_t m_ConnectionThread;
pthread_t m_InputThread;
pp::Graphics3D m_Graphics3D;
pp::VideoDecoder* m_VideoDecoder;
Shader m_Texture2DShader;
Shader m_RectangleArbShader;
Shader m_ExternalOesShader;
PP_VideoPicture m_NextPicture;
bool m_HasNextPicture;
PP_VideoPicture m_CurrentPicture;
bool m_IsPainting;
bool m_RequestIdrFrame;
OpusMSDecoder* m_OpusDecoder;
pp::Audio m_AudioPlayer;
double m_LastPadTimestamps[4];
const PPB_Gamepad* m_GamepadApi;
pp::CompletionCallbackFactory<MoonlightInstance> m_CallbackFactory;
bool m_MouseLocked;
bool m_WaitingForAllModifiersUp;
float m_AccumulatedTicks;
int32_t m_MouseDeltaX, m_MouseDeltaY;
pp::SimpleThread openHttpThread;
};
extern MoonlightInstance* g_Instance;