mirror of
https://github.com/moonlight-stream/moonlight-chrome.git
synced 2025-08-18 00:56:38 +00:00
Decouple renderer from decoder and remove associated workarounds
This commit is contained in:
parent
25062b99b1
commit
21dd55566e
@ -27,11 +27,6 @@ static int ConvertPPButtonToLiButton(PP_InputEvent_MouseButton ppButton) {
|
|||||||
|
|
||||||
void MoonlightInstance::DidLockMouse(int32_t result) {
|
void MoonlightInstance::DidLockMouse(int32_t result) {
|
||||||
m_MouseLocked = (result == PP_OK);
|
m_MouseLocked = (result == PP_OK);
|
||||||
if (m_MouseLocked) {
|
|
||||||
// Request an IDR frame to dump the frame queue that may have
|
|
||||||
// built up from the GL pipeline being stalled.
|
|
||||||
m_RequestIdrFrame = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoonlightInstance::MouseLockLost() {
|
void MoonlightInstance::MouseLockLost() {
|
||||||
|
@ -41,8 +41,8 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
|
|||||||
explicit MoonlightInstance(PP_Instance instance) :
|
explicit MoonlightInstance(PP_Instance instance) :
|
||||||
pp::Instance(instance),
|
pp::Instance(instance),
|
||||||
pp::MouseLock(this),
|
pp::MouseLock(this),
|
||||||
|
m_HasNextPicture(false),
|
||||||
m_IsPainting(false),
|
m_IsPainting(false),
|
||||||
m_RequestIdrFrame(false),
|
|
||||||
m_OpusDecoder(NULL),
|
m_OpusDecoder(NULL),
|
||||||
m_CallbackFactory(this),
|
m_CallbackFactory(this),
|
||||||
m_MouseLocked(false),
|
m_MouseLocked(false),
|
||||||
@ -81,7 +81,6 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
|
|||||||
|
|
||||||
void MouseLockLost();
|
void MouseLockLost();
|
||||||
void DidLockMouse(int32_t result);
|
void DidLockMouse(int32_t result);
|
||||||
void DidChangeFocus(bool got_focus);
|
|
||||||
|
|
||||||
void OnConnectionStopped(uint32_t unused);
|
void OnConnectionStopped(uint32_t unused);
|
||||||
void OnConnectionStarted(uint32_t error);
|
void OnConnectionStarted(uint32_t error);
|
||||||
@ -139,9 +138,10 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
|
|||||||
Shader m_Texture2DShader;
|
Shader m_Texture2DShader;
|
||||||
Shader m_RectangleArbShader;
|
Shader m_RectangleArbShader;
|
||||||
Shader m_ExternalOesShader;
|
Shader m_ExternalOesShader;
|
||||||
std::queue<PP_VideoPicture> m_PendingPictureQueue;
|
PP_VideoPicture m_NextPicture;
|
||||||
|
bool m_HasNextPicture;
|
||||||
|
PP_VideoPicture m_CurrentPicture;
|
||||||
bool m_IsPainting;
|
bool m_IsPainting;
|
||||||
bool m_RequestIdrFrame;
|
|
||||||
|
|
||||||
OpusMSDecoder* m_OpusDecoder;
|
OpusMSDecoder* m_OpusDecoder;
|
||||||
pp::Audio m_AudioPlayer;
|
pp::Audio m_AudioPlayer;
|
||||||
|
84
viddec.cpp
84
viddec.cpp
@ -13,8 +13,6 @@ static unsigned char* s_DecodeBuffer;
|
|||||||
static unsigned int s_DecodeBufferLength;
|
static unsigned int s_DecodeBufferLength;
|
||||||
static int s_LastTextureType;
|
static int s_LastTextureType;
|
||||||
static int s_LastTextureId;
|
static int s_LastTextureId;
|
||||||
static int s_NextDecodeFrameNumber;
|
|
||||||
static int s_LastDisplayFrameNumber;
|
|
||||||
static unsigned char s_LastSps[256];
|
static unsigned char s_LastSps[256];
|
||||||
static unsigned char s_LastPps[256];
|
static unsigned char s_LastPps[256];
|
||||||
static unsigned int s_LastSpsLength;
|
static unsigned int s_LastSpsLength;
|
||||||
@ -62,14 +60,6 @@ static const char k_FragmentShaderExternal[] =
|
|||||||
" gl_FragColor = texture2D(s_texture, v_texCoord); \n"
|
" gl_FragColor = texture2D(s_texture, v_texCoord); \n"
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
void MoonlightInstance::DidChangeFocus(bool got_focus) {
|
|
||||||
// Request an IDR frame to dump the frame queue that may have
|
|
||||||
// built up from the GL pipeline being stalled.
|
|
||||||
if (got_focus) {
|
|
||||||
g_Instance->m_RequestIdrFrame = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MoonlightInstance::InitializeRenderingSurface(int width, int height) {
|
void MoonlightInstance::InitializeRenderingSurface(int width, int height) {
|
||||||
if (!glInitializePPAPI(pp::Module::Get()->get_browser_interface())) {
|
if (!glInitializePPAPI(pp::Module::Get()->get_browser_interface())) {
|
||||||
return;
|
return;
|
||||||
@ -136,8 +126,6 @@ void MoonlightInstance::VidDecSetup(int videoFormat, int width, int height, int
|
|||||||
s_LastTextureId = 0;
|
s_LastTextureId = 0;
|
||||||
s_LastSpsLength = 0;
|
s_LastSpsLength = 0;
|
||||||
s_LastPpsLength = 0;
|
s_LastPpsLength = 0;
|
||||||
s_NextDecodeFrameNumber = 0;
|
|
||||||
s_LastDisplayFrameNumber = 0;
|
|
||||||
|
|
||||||
g_Instance->m_VideoDecoder->Initialize(g_Instance->m_Graphics3D,
|
g_Instance->m_VideoDecoder->Initialize(g_Instance->m_Graphics3D,
|
||||||
PP_VIDEOPROFILE_H264HIGH,
|
PP_VIDEOPROFILE_H264HIGH,
|
||||||
@ -206,12 +194,6 @@ int MoonlightInstance::VidDecSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
|
|||||||
bool isPps = false;
|
bool isPps = false;
|
||||||
bool isIframe = false;
|
bool isIframe = false;
|
||||||
|
|
||||||
// Request an IDR frame if needed
|
|
||||||
if (g_Instance->m_RequestIdrFrame) {
|
|
||||||
g_Instance->m_RequestIdrFrame = false;
|
|
||||||
return DR_NEED_IDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look at the NALU type
|
// Look at the NALU type
|
||||||
if (decodeUnit->bufferList->length > 5) {
|
if (decodeUnit->bufferList->length > 5) {
|
||||||
switch (decodeUnit->bufferList->data[4]) {
|
switch (decodeUnit->bufferList->data[4]) {
|
||||||
@ -279,7 +261,7 @@ int MoonlightInstance::VidDecSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start the decoding
|
// Start the decoding
|
||||||
g_Instance->m_VideoDecoder->Decode(s_NextDecodeFrameNumber++, offset, s_DecodeBuffer, pp::BlockUntilComplete());
|
g_Instance->m_VideoDecoder->Decode(0, offset, s_DecodeBuffer, pp::BlockUntilComplete());
|
||||||
|
|
||||||
return DR_OK;
|
return DR_OK;
|
||||||
}
|
}
|
||||||
@ -324,20 +306,13 @@ Shader MoonlightInstance::CreateProgram(const char* vertexShader, const char* fr
|
|||||||
void MoonlightInstance::PaintPicture(void) {
|
void MoonlightInstance::PaintPicture(void) {
|
||||||
m_IsPainting = true;
|
m_IsPainting = true;
|
||||||
|
|
||||||
// Free and skip all frames except the latest one
|
// Take the next picture into our ownership
|
||||||
PP_VideoPicture picture;
|
m_CurrentPicture = m_NextPicture;
|
||||||
while (m_PendingPictureQueue.size() > 1) {
|
m_HasNextPicture = false;
|
||||||
picture = m_PendingPictureQueue.front();
|
|
||||||
m_PendingPictureQueue.pop();
|
|
||||||
g_Instance->m_VideoDecoder->RecyclePicture(picture);
|
|
||||||
}
|
|
||||||
|
|
||||||
picture = m_PendingPictureQueue.front();
|
|
||||||
|
|
||||||
// Recycle bogus pictures immediately
|
// Recycle bogus pictures immediately
|
||||||
if (picture.texture_target == 0) {
|
if (m_CurrentPicture.texture_target == 0) {
|
||||||
g_Instance->m_VideoDecoder->RecyclePicture(picture);
|
m_VideoDecoder->RecyclePicture(m_CurrentPicture);
|
||||||
m_PendingPictureQueue.pop();
|
|
||||||
m_IsPainting = false;
|
m_IsPainting = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -349,23 +324,23 @@ void MoonlightInstance::PaintPicture(void) {
|
|||||||
int originalTextureTarget = s_LastTextureType;
|
int originalTextureTarget = s_LastTextureType;
|
||||||
|
|
||||||
// Only make these state changes if we've changed from the last texture type
|
// Only make these state changes if we've changed from the last texture type
|
||||||
if (picture.texture_target != s_LastTextureType) {
|
if (m_CurrentPicture.texture_target != s_LastTextureType) {
|
||||||
if (picture.texture_target == GL_TEXTURE_2D) {
|
if (m_CurrentPicture.texture_target == GL_TEXTURE_2D) {
|
||||||
if (!g_Instance->m_Texture2DShader.program) {
|
if (!g_Instance->m_Texture2DShader.program) {
|
||||||
g_Instance->m_Texture2DShader = CreateProgram(k_VertexShader, k_FragmentShader2D);
|
g_Instance->m_Texture2DShader = CreateProgram(k_VertexShader, k_FragmentShader2D);
|
||||||
}
|
}
|
||||||
glUseProgram(g_Instance->m_Texture2DShader.program);
|
glUseProgram(g_Instance->m_Texture2DShader.program);
|
||||||
glUniform2f(g_Instance->m_Texture2DShader.texcoord_scale_location, 1.0, 1.0);
|
glUniform2f(g_Instance->m_Texture2DShader.texcoord_scale_location, 1.0, 1.0);
|
||||||
}
|
}
|
||||||
else if (picture.texture_target == GL_TEXTURE_RECTANGLE_ARB) {
|
else if (m_CurrentPicture.texture_target == GL_TEXTURE_RECTANGLE_ARB) {
|
||||||
if (!g_Instance->m_RectangleArbShader.program) {
|
if (!g_Instance->m_RectangleArbShader.program) {
|
||||||
g_Instance->m_RectangleArbShader = CreateProgram(k_VertexShader, k_FragmentShaderRectangle);
|
g_Instance->m_RectangleArbShader = CreateProgram(k_VertexShader, k_FragmentShaderRectangle);
|
||||||
}
|
}
|
||||||
glUseProgram(g_Instance->m_RectangleArbShader.program);
|
glUseProgram(g_Instance->m_RectangleArbShader.program);
|
||||||
glUniform2f(g_Instance->m_RectangleArbShader.texcoord_scale_location,
|
glUniform2f(g_Instance->m_RectangleArbShader.texcoord_scale_location,
|
||||||
picture.texture_size.width, picture.texture_size.height);
|
m_CurrentPicture.texture_size.width, m_CurrentPicture.texture_size.height);
|
||||||
}
|
}
|
||||||
else if (picture.texture_target == GL_TEXTURE_EXTERNAL_OES) {
|
else if (m_CurrentPicture.texture_target == GL_TEXTURE_EXTERNAL_OES) {
|
||||||
if (!g_Instance->m_ExternalOesShader.program) {
|
if (!g_Instance->m_ExternalOesShader.program) {
|
||||||
g_Instance->m_ExternalOesShader = CreateProgram(k_VertexShader, k_FragmentShaderExternal);
|
g_Instance->m_ExternalOesShader = CreateProgram(k_VertexShader, k_FragmentShaderExternal);
|
||||||
}
|
}
|
||||||
@ -375,32 +350,31 @@ void MoonlightInstance::PaintPicture(void) {
|
|||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
s_LastTextureType = picture.texture_target;
|
s_LastTextureType = m_CurrentPicture.texture_target;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only rebind our texture if we've changed since last time
|
// Only rebind our texture if we've changed since last time
|
||||||
if (picture.texture_id != s_LastTextureId || picture.texture_target != originalTextureTarget) {
|
if (m_CurrentPicture.texture_id != s_LastTextureId || m_CurrentPicture.texture_target != originalTextureTarget) {
|
||||||
glBindTexture(picture.texture_target, picture.texture_id);
|
glBindTexture(m_CurrentPicture.texture_target, m_CurrentPicture.texture_id);
|
||||||
s_LastTextureId = picture.texture_id;
|
s_LastTextureId = m_CurrentPicture.texture_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the image
|
// Draw the image
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
// Swap buffers
|
// Swap buffers
|
||||||
g_Instance->m_Graphics3D.SwapBuffers(
|
m_Graphics3D.SwapBuffers(
|
||||||
g_Instance->m_CallbackFactory.NewCallback(&MoonlightInstance::PaintFinished));
|
m_CallbackFactory.NewCallback(&MoonlightInstance::PaintFinished));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoonlightInstance::PaintFinished(int32_t result) {
|
void MoonlightInstance::PaintFinished(int32_t result) {
|
||||||
m_IsPainting = false;
|
m_IsPainting = false;
|
||||||
|
|
||||||
// Recycle the picture now that it's been painted
|
// Recycle the picture now that it's been painted
|
||||||
g_Instance->m_VideoDecoder->RecyclePicture(m_PendingPictureQueue.front());
|
m_VideoDecoder->RecyclePicture(m_CurrentPicture);
|
||||||
m_PendingPictureQueue.pop();
|
|
||||||
|
|
||||||
// Keep painting if we still have frames
|
// Keep painting if we still have frames
|
||||||
if (!m_PendingPictureQueue.empty()) {
|
if (m_HasNextPicture) {
|
||||||
PaintPicture();
|
PaintPicture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,21 +384,21 @@ void MoonlightInstance::PictureReady(int32_t result, PP_VideoPicture picture) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure we only push newer frames onto the display queue
|
// Free a picture if there's one the renderer hasn't consumed yet
|
||||||
if (picture.decode_id > s_LastDisplayFrameNumber) {
|
if (m_HasNextPicture) {
|
||||||
m_PendingPictureQueue.push(picture);
|
m_VideoDecoder->RecyclePicture(m_NextPicture);
|
||||||
s_LastDisplayFrameNumber = picture.decode_id;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// This picture is older than the last one we displayed. Discard
|
|
||||||
// it without displaying.
|
|
||||||
g_Instance->m_VideoDecoder->RecyclePicture(picture);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Put the latest picture in the slot for rendering next
|
||||||
|
m_NextPicture = picture;
|
||||||
|
m_HasNextPicture = true;
|
||||||
|
|
||||||
|
// Queue another call to get another picture
|
||||||
g_Instance->m_VideoDecoder->GetPicture(
|
g_Instance->m_VideoDecoder->GetPicture(
|
||||||
g_Instance->m_CallbackFactory.NewCallbackWithOutput(&MoonlightInstance::PictureReady));
|
g_Instance->m_CallbackFactory.NewCallbackWithOutput(&MoonlightInstance::PictureReady));
|
||||||
|
|
||||||
if (!m_IsPainting && !m_PendingPictureQueue.empty()) {
|
// Start painting if we aren't now
|
||||||
|
if (!m_IsPainting) {
|
||||||
PaintPicture();
|
PaintPicture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user