Video decoding is partially working

This commit is contained in:
Cameron Gutman 2016-02-13 09:12:41 -05:00
parent 7ea534c692
commit 9a38318210
4 changed files with 115 additions and 12 deletions

View File

@ -23,6 +23,7 @@ SOURCES = \
input.cpp \ input.cpp \
gamepad.cpp \ gamepad.cpp \
connectionlistener.cpp \ connectionlistener.cpp \
viddec.cpp \
# Build rules generated by macros from common.mk: # Build rules generated by macros from common.mk:

View File

@ -23,8 +23,6 @@ class MoonlightModule : public pp::Module {
}; };
void MoonlightInstance::OnConnectionStarted(uint32_t unused) { void MoonlightInstance::OnConnectionStarted(uint32_t unused) {
printf("Connection started\n");
// Start receiving input events // Start receiving input events
g_Instance->RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE); g_Instance->RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
g_Instance->RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_WHEEL | PP_INPUTEVENT_CLASS_KEYBOARD); g_Instance->RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_WHEEL | PP_INPUTEVENT_CLASS_KEYBOARD);
@ -45,7 +43,8 @@ void* MoonlightInstance::ConnectionThreadFunc(void* context) {
err = LiStartConnection(s_Host, err = LiStartConnection(s_Host,
&s_StreamConfig, &s_StreamConfig,
&MoonlightInstance::s_ClCallbacks, &MoonlightInstance::s_ClCallbacks,
NULL, NULL, &MoonlightInstance::s_DrCallbacks,
NULL,
NULL, 0, 4); NULL, 0, 4);
if (err != 0) { if (err != 0) {
pp::Var response("Starting connection failed"); pp::Var response("Starting connection failed");
@ -94,6 +93,24 @@ bool MoonlightInstance::Init(uint32_t argc,
const char* argn[], const char* argn[],
const char* argv[]) { const char* argv[]) {
g_Instance = this; g_Instance = this;
int32_t context_attributes[] = {
PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8,
PP_GRAPHICS3DATTRIB_RED_SIZE, 8,
PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0,
PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0,
PP_GRAPHICS3DATTRIB_SAMPLES, 0,
PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0,
PP_GRAPHICS3DATTRIB_WIDTH, 500,
PP_GRAPHICS3DATTRIB_HEIGHT, 500,
PP_GRAPHICS3DATTRIB_NONE,
};
m_Graphics3D = new pp::Graphics3D(this, context_attributes);
assert(!m_Graphics3D->is_null());
assert(BindGraphics(*m_Graphics3D));
return true; return true;
} }

View File

@ -2,6 +2,8 @@
#include "ppapi/cpp/module.h" #include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h" #include "ppapi/cpp/var.h"
#include "ppapi/cpp/mouse_lock.h" #include "ppapi/cpp/mouse_lock.h"
#include "ppapi/cpp/graphics_3d.h"
#include "ppapi/cpp/video_decoder.h"
#include "ppapi/c/ppb_gamepad.h" #include "ppapi/c/ppb_gamepad.h"
@ -13,7 +15,7 @@
class MoonlightInstance : public pp::Instance, public pp::MouseLock { class MoonlightInstance : public pp::Instance, public pp::MouseLock {
public: public:
explicit MoonlightInstance(PP_Instance instance) : MoonlightInstance(PP_Instance instance) :
pp::Instance(instance), pp::Instance(instance),
pp::MouseLock(this), pp::MouseLock(this),
m_CallbackFactory(this), m_CallbackFactory(this),
@ -35,31 +37,35 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
void PollGamepads(); void PollGamepads();
void DidLockMouse(int32_t result); void DidLockMouse(int32_t result);
void MouseLockLost(); void MouseLockLost();
void OnConnectionStopped(uint32_t unused); void OnConnectionStopped(uint32_t unused);
void OnConnectionStarted(uint32_t error); void OnConnectionStarted(uint32_t error);
static void* ConnectionThreadFunc(void* context); static void* ConnectionThreadFunc(void* context);
static void ClStageStarting(int stage); static void ClStageStarting(int stage);
static void ClStageFailed(int stage, long errorCode); static void ClStageFailed(int stage, long errorCode);
static void ClConnectionStarted(void); static void ClConnectionStarted(void);
static void ClConnectionTerminated(long errorCode); static void ClConnectionTerminated(long errorCode);
static void ClDisplayMessage(char* message); static void ClDisplayMessage(char* message);
static void ClDisplayTransientMessage(char* message); static void ClDisplayTransientMessage(char* message);
void DispatchGetPicture(uint32_t unused);
void PictureReady(int32_t result, PP_VideoPicture picture);
static void VidDecSetup(int width, int height, int redrawRate, void* context, int drFlags);
static void VidDecCleanup(void);
static int VidDecSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
private: private:
static CONNECTION_LISTENER_CALLBACKS s_ClCallbacks;
static DECODER_RENDERER_CALLBACKS s_DrCallbacks;
pp::Graphics3D* m_Graphics3D;
pp::VideoDecoder* m_VideoDecoder;
double m_LastPadTimestamps[4]; double m_LastPadTimestamps[4];
const PPB_Gamepad* m_GamepadApi; const PPB_Gamepad* m_GamepadApi;
static CONNECTION_LISTENER_CALLBACKS s_ClCallbacks;
pp::CompletionCallbackFactory<MoonlightInstance> m_CallbackFactory; pp::CompletionCallbackFactory<MoonlightInstance> m_CallbackFactory;
bool m_MouseLocked; bool m_MouseLocked;
}; };

79
viddec.cpp Normal file
View File

@ -0,0 +1,79 @@
#include "moonlight.hpp"
#define INITIAL_DECODE_BUFFER_LEN 128 * 1024
static unsigned char* s_DecodeBuffer;
static unsigned int s_DecodeBufferLength;
void MoonlightInstance::VidDecSetup(int width, int height, int redrawRate, void* context, int drFlags) {
g_Instance->m_VideoDecoder = new pp::VideoDecoder(g_Instance);
s_DecodeBufferLength = INITIAL_DECODE_BUFFER_LEN;
s_DecodeBuffer = (unsigned char *)malloc(s_DecodeBufferLength);
g_Instance->m_VideoDecoder->Initialize(*g_Instance->m_Graphics3D,
PP_VIDEOPROFILE_H264HIGH,
PP_HARDWAREACCELERATION_ONLY,
0,
pp::BlockUntilComplete());
pp::Module::Get()->core()->CallOnMainThread(0,
g_Instance->m_CallbackFactory.NewCallback(&MoonlightInstance::DispatchGetPicture));
}
void MoonlightInstance::DispatchGetPicture(uint32_t unused) {
// Queue the initial GetPicture callback on the main thread
g_Instance->m_VideoDecoder->GetPicture(
g_Instance->m_CallbackFactory.NewCallbackWithOutput(&MoonlightInstance::PictureReady));
}
void MoonlightInstance::VidDecCleanup(void) {
free(s_DecodeBuffer);
delete g_Instance->m_VideoDecoder;
}
int MoonlightInstance::VidDecSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
PLENTRY entry;
unsigned int offset;
// Resize the decode buffer if needed
if (decodeUnit->fullLength > s_DecodeBufferLength) {
free(s_DecodeBuffer);
s_DecodeBufferLength = decodeUnit->fullLength;
s_DecodeBuffer = (unsigned char *)malloc(s_DecodeBufferLength);
}
entry = decodeUnit->bufferList;
offset = 0;
while (entry != NULL) {
memcpy(&s_DecodeBuffer[offset], entry->data, entry->length);
offset += entry->length;
entry = entry->next;
}
// Start the decoding
g_Instance->m_VideoDecoder->Decode(0, offset, s_DecodeBuffer, pp::BlockUntilComplete());
return DR_OK;
}
void MoonlightInstance::PictureReady(int32_t result, PP_VideoPicture picture) {
if (result == PP_ERROR_ABORTED) {
return;
}
// FIXME: Draw video
g_Instance->m_VideoDecoder->RecyclePicture(picture);
// Queue another callback
g_Instance->m_VideoDecoder->GetPicture(
g_Instance->m_CallbackFactory.NewCallbackWithOutput(&MoonlightInstance::PictureReady));
}
DECODER_RENDERER_CALLBACKS MoonlightInstance::s_DrCallbacks = {
MoonlightInstance::VidDecSetup,
MoonlightInstance::VidDecCleanup,
MoonlightInstance::VidDecSubmitDecodeUnit
};