Permalink
Browse files

Implement fallback to software when hardware decoding is unavailable

  • Loading branch information...
1 parent f2d9bce commit 1f3f4bd0aa6075759673df70975ce2722def4f62 @cgutman cgutman committed Jun 9, 2016
Showing with 44 additions and 15 deletions.
  1. +5 −5 connectionlistener.cpp
  2. +1 −1 moonlight-common-c
  3. +5 −2 moonlight.hpp
  4. +3 −1 static/js/messages.js
  5. +30 −6 viddec.cpp
@@ -28,13 +28,13 @@ void MoonlightInstance::ClConnectionTerminated(long errorCode) {
g_Instance->m_CallbackFactory.NewCallback(&MoonlightInstance::OnConnectionStopped), (uint32_t)errorCode);
}
-void MoonlightInstance::ClDisplayMessage(char* message) {
- pp::Var response(message);
+void MoonlightInstance::ClDisplayMessage(const char* message) {
+ pp::Var response(std::string("DialogMsg: ") + std::string(message));
g_Instance->PostMessage(response);
}
-void MoonlightInstance::ClDisplayTransientMessage(char* message) {
- pp::Var response(message);
+void MoonlightInstance::ClDisplayTransientMessage(const char* message) {
+ pp::Var response(std::string("TransientMsg: ") + std::string(message));
g_Instance->PostMessage(response);
}
@@ -46,4 +46,4 @@ CONNECTION_LISTENER_CALLBACKS MoonlightInstance::s_ClCallbacks = {
MoonlightInstance::ClConnectionTerminated,
MoonlightInstance::ClDisplayMessage,
MoonlightInstance::ClDisplayTransientMessage
-};
+};
View
@@ -35,6 +35,9 @@
// 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() {}
@@ -108,8 +111,8 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
static void ClStageFailed(int stage, long errorCode);
static void ClConnectionStarted(void);
static void ClConnectionTerminated(long errorCode);
- static void ClDisplayMessage(char* message);
- static void ClDisplayTransientMessage(char* message);
+ static void ClDisplayMessage(const char* message);
+ static void ClDisplayTransientMessage(const char* message);
static Shader CreateProgram(const char* vertexShader, const char* fragmentShader);
static void CreateShader(GLuint program, GLenum type, const char* source, int size);
@@ -30,6 +30,8 @@ function handleMessage(msg) {
$('#loadingSpinner').css('display', 'none');
} else if(msg.data.indexOf('ProgressMsg: ') === 0) {
$('#loadingMessage').text(msg.data.replace('ProgressMsg: ', ''));
+ } else if(msg.data.indexOf('TransientMsg: ') === 0) {
+ snackbarLog(msg.data.replace('TransientMsg: ', ''));
}
}
-}
+}
View
@@ -133,11 +133,35 @@ void MoonlightInstance::VidDecSetup(int videoFormat, int width, int height, int
s_LastSpsLength = 0;
s_LastPpsLength = 0;
- g_Instance->m_VideoDecoder->Initialize(g_Instance->m_Graphics3D,
- PP_VIDEOPROFILE_H264HIGH,
- PP_HARDWAREACCELERATION_ONLY,
- 0,
- pp::BlockUntilComplete());
+ int32_t err;
+
+ if (!(drFlags & DR_FLAG_FORCE_SW_DECODE)) {
+ // Try to initialize hardware decoding only
+ err = g_Instance->m_VideoDecoder->Initialize(
+ g_Instance->m_Graphics3D,
+ PP_VIDEOPROFILE_H264HIGH,
+ PP_HARDWAREACCELERATION_ONLY,
+ 0,
+ pp::BlockUntilComplete());
+ }
+ else {
+ err = PP_ERROR_NOTSUPPORTED;
+ }
+
+ if (err == PP_ERROR_NOTSUPPORTED) {
+ // Fallback to software decoding
+ err = g_Instance->m_VideoDecoder->Initialize(
+ g_Instance->m_Graphics3D,
+ PP_VIDEOPROFILE_H264HIGH,
+ PP_HARDWAREACCELERATION_NONE,
+ 0,
+ pp::BlockUntilComplete());
+
+ if (!(drFlags & DR_FLAG_FORCE_SW_DECODE)) {
+ // Tell the user we had to fall back
+ ClDisplayTransientMessage("Hardware decoding is unavailable. Falling back to CPU decoding");
+ }
+ }
pp::Module::Get()->core()->CallOnMainThread(0,
g_Instance->m_CallbackFactory.NewCallback(&MoonlightInstance::DispatchGetPicture));
@@ -432,4 +456,4 @@ DECODER_RENDERER_CALLBACKS MoonlightInstance::s_DrCallbacks = {
MoonlightInstance::VidDecCleanup,
MoonlightInstance::VidDecSubmitDecodeUnit,
CAPABILITY_SLICES_PER_FRAME(4) | CAPABILITY_DIRECT_SUBMIT
-};
+};

0 comments on commit 1f3f4bd

Please sign in to comment.