mirror of
https://github.com/moonlight-stream/moonlight-chrome.git
synced 2025-08-17 16:46:31 +00:00
Merge branch 'master' of github.com:abdallahsoliman/moonlight-chrome
This commit is contained in:
commit
e269b73bd3
@ -23,6 +23,11 @@ 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.
|
||||||
|
g_Instance->m_RequestIdrFrame = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoonlightInstance::MouseLockLost() {
|
void MoonlightInstance::MouseLockLost() {
|
||||||
|
@ -53,6 +53,7 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
|
|||||||
pp::MouseLock(this),
|
pp::MouseLock(this),
|
||||||
m_HasNextPicture(false),
|
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),
|
||||||
@ -122,6 +123,7 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
|
|||||||
void PictureReady(int32_t result, PP_VideoPicture picture);
|
void PictureReady(int32_t result, PP_VideoPicture picture);
|
||||||
void PaintPicture(void);
|
void PaintPicture(void);
|
||||||
void InitializeRenderingSurface(int width, int height);
|
void InitializeRenderingSurface(int width, int height);
|
||||||
|
void DidChangeFocus(bool got_focus);
|
||||||
|
|
||||||
static void VidDecSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags);
|
static void VidDecSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags);
|
||||||
static void VidDecCleanup(void);
|
static void VidDecCleanup(void);
|
||||||
@ -159,6 +161,7 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
|
|||||||
bool m_HasNextPicture;
|
bool m_HasNextPicture;
|
||||||
PP_VideoPicture m_CurrentPicture;
|
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;
|
||||||
|
@ -3,6 +3,7 @@ var hosts = [];
|
|||||||
var pairingCert;
|
var pairingCert;
|
||||||
var myUniqueid;
|
var myUniqueid;
|
||||||
var api;
|
var api;
|
||||||
|
var relaunchSourceEvent;
|
||||||
|
|
||||||
// Called by the common.js module.
|
// Called by the common.js module.
|
||||||
function attachListeners() {
|
function attachListeners() {
|
||||||
@ -104,49 +105,44 @@ function pairTo(host, onSuccess, onFailure) {
|
|||||||
snackbarLog('ERROR: cert has not been generated yet. Is NaCl initialized?');
|
snackbarLog('ERROR: cert has not been generated yet. Is NaCl initialized?');
|
||||||
console.log("User wants to pair, and we still have no cert. Problem = very yes.");
|
console.log("User wants to pair, and we still have no cert. Problem = very yes.");
|
||||||
onFailure();
|
onFailure();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!api) {
|
api = new NvHTTP(host, myUniqueid);
|
||||||
api = new NvHTTP(host, myUniqueid);
|
api.refreshServerInfo().then(function (ret) {
|
||||||
}
|
if (api.paired) {
|
||||||
|
onSuccess();
|
||||||
if(api.paired) {
|
return;
|
||||||
onSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
var randomNumber = String("0000" + (Math.random()*10000|0)).slice(-4);
|
|
||||||
var pairingDialog = document.querySelector('#pairingDialog');
|
|
||||||
$('#pairingDialogText').html('Please enter the number ' + randomNumber + ' on the GFE dialog on the computer. This dialog will be dismissed once complete');
|
|
||||||
pairingDialog.showModal();
|
|
||||||
console.log('sending pairing request to ' + host + ' with random number ' + randomNumber);
|
|
||||||
|
|
||||||
api.pair(randomNumber).then(function (paired) {
|
|
||||||
if (!paired) {
|
|
||||||
if (api.currentGame != 0) {
|
|
||||||
$('#pairingDialogText').html('Error: ' + host + ' is in app. Cannot pair until the app is stopped.');
|
|
||||||
} else {
|
|
||||||
$('#pairingDialogText').html('Error: failed to pair with ' + host + '. failure reason unknown.');
|
|
||||||
}
|
|
||||||
onFailure();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
snackbarLog('Pairing successful');
|
var randomNumber = String("0000" + (Math.random()*10000|0)).slice(-4);
|
||||||
pairingDialog.close();
|
var pairingDialog = document.querySelector('#pairingDialog');
|
||||||
|
$('#pairingDialogText').html('Please enter the number ' + randomNumber + ' on the GFE dialog on the computer. This dialog will be dismissed once complete');
|
||||||
|
pairingDialog.showModal();
|
||||||
|
console.log('sending pairing request to ' + host + ' with random number ' + randomNumber);
|
||||||
|
|
||||||
var cell = document.createElement('div');
|
api.pair(randomNumber).then(function (paired) {
|
||||||
cell.className += 'mdl-cell mdl-cell--3-col';
|
if (!paired) {
|
||||||
cell.id = 'hostgrid-' + hosts[i];
|
if (api.currentGame != 0) {
|
||||||
cell.innerHTML = hosts[i];
|
$('#pairingDialogText').html('Error: ' + host + ' is in app. Cannot pair until the app is stopped.');
|
||||||
$('#host-grid').append(cell);
|
} else {
|
||||||
cell.onclick = hostChosen;
|
$('#pairingDialogText').html('Error: failed to pair with ' + host + '. failure reason unknown.');
|
||||||
|
}
|
||||||
|
onFailure();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
saveHosts();
|
snackbarLog('Pairing successful');
|
||||||
onSuccess();
|
pairingDialog.close();
|
||||||
|
onSuccess();
|
||||||
}, function (failedPairing) {
|
}, function (failedPairing) {
|
||||||
snackbarLog('Failed pairing to: ' + host);
|
snackbarLog('Failed pairing to: ' + host);
|
||||||
console.log('pairing failed, and returned ' + failedPairing);
|
console.log('pairing failed, and returned ' + failedPairing);
|
||||||
onFailure();
|
onFailure();
|
||||||
|
});
|
||||||
|
}, function (failedRefreshInfo) {
|
||||||
|
snackbarLog('Failed to connect to ' + host + '! Are you sure the host is on?');
|
||||||
|
console.log('Returned error was: ' + failedRefreshInfo);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,24 +153,13 @@ function hostChosen(sourceEvent) {
|
|||||||
host = sourceEvent.srcElement.innerText;
|
host = sourceEvent.srcElement.innerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
api = new NvHTTP(host, myUniqueid);
|
||||||
if(!api || api.address != host) {
|
|
||||||
api = new NvHTTP(host, myUniqueid);
|
|
||||||
}
|
|
||||||
|
|
||||||
api.refreshServerInfo().then(function (ret) {
|
api.refreshServerInfo().then(function (ret) {
|
||||||
if(!api.paired) {
|
if(!api.paired) {
|
||||||
pairTo(host);
|
pairTo(host, function(){ showApps(); }, function(){});
|
||||||
|
} else {
|
||||||
|
showApps();
|
||||||
}
|
}
|
||||||
if(hosts.indexOf(host) < 0) { // we don't have this host in our list. add it, and save it.
|
|
||||||
var cell = document.createElement('div');
|
|
||||||
cell.className += 'mdl-cell mdl-cell--3-col';
|
|
||||||
cell.id = 'hostgrid-' + hosts[i];
|
|
||||||
cell.innerHTML = hosts[i];
|
|
||||||
$('#host-grid').append(cell);
|
|
||||||
cell.onclick = hostChosen;
|
|
||||||
}
|
|
||||||
showApps();
|
|
||||||
}, function (failedRefreshInfo) {
|
}, function (failedRefreshInfo) {
|
||||||
snackbarLog('Failed to connect to ' + host + '! Are you sure the host is on?');
|
snackbarLog('Failed to connect to ' + host + '! Are you sure the host is on?');
|
||||||
console.log('Returned error was: ' + failedRefreshInfo);
|
console.log('Returned error was: ' + failedRefreshInfo);
|
||||||
@ -192,14 +177,30 @@ function cancelAddHost() {
|
|||||||
document.querySelector('#addHostDialog').close();
|
document.querySelector('#addHostDialog').close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addHostToGrid(host) {
|
||||||
|
if(hosts.indexOf(host) < 0) { // we don't have this host in our list. add it, and save it.
|
||||||
|
var cell = document.createElement('div');
|
||||||
|
cell.className += 'mdl-cell mdl-cell--3-col';
|
||||||
|
cell.id = 'hostgrid-' + host;
|
||||||
|
cell.innerHTML = host;
|
||||||
|
$('#host-grid').append(cell);
|
||||||
|
cell.onclick = hostChosen;
|
||||||
|
hosts.push(host);
|
||||||
|
saveHosts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function continueAddHost() {
|
function continueAddHost() {
|
||||||
var inputHost = $('#dialogInputHost').val();
|
var inputHost = $('#dialogInputHost').val();
|
||||||
|
|
||||||
pairTo(inputHost,
|
pairTo(inputHost,
|
||||||
function() { document.querySelector('#addHostDialog').close() },
|
function() {
|
||||||
function() {snackbarLog('pairing to ' + inputHost + ' failed!');}
|
addHostToGrid(inputHost);
|
||||||
);
|
document.querySelector('#addHostDialog').close();
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
snackbarLog('pairing to ' + inputHost + ' failed!');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// locally remove the hostname/ip from the saved `hosts` array.
|
// locally remove the hostname/ip from the saved `hosts` array.
|
||||||
@ -224,14 +225,10 @@ function showApps() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if game grid is populated, empty it
|
||||||
|
$("#game-grid").empty();
|
||||||
|
|
||||||
api.getAppList().then(function (appList) {
|
api.getAppList().then(function (appList) {
|
||||||
|
|
||||||
// if game grid is populated, empty it
|
|
||||||
if($("#game-grid").children().length > 0) {
|
|
||||||
$("#game-grid").empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
appList.forEach(function (app) {
|
appList.forEach(function (app) {
|
||||||
api.getBoxArt(app.id).then(function (resolvedPromise) {
|
api.getBoxArt(app.id).then(function (resolvedPromise) {
|
||||||
var imageBlob = new Blob([resolvedPromise], {type: "image/png"});
|
var imageBlob = new Blob([resolvedPromise], {type: "image/png"});
|
||||||
@ -310,6 +307,10 @@ function startGame(sourceEvent) {
|
|||||||
api.refreshServerInfo().then(function (ret) {
|
api.refreshServerInfo().then(function (ret) {
|
||||||
if(api.currentGame != 0 && api.currentGame != appID) {
|
if(api.currentGame != 0 && api.currentGame != appID) {
|
||||||
api.getAppById(api.currentGame).then(function (currentApp) {
|
api.getAppById(api.currentGame).then(function (currentApp) {
|
||||||
|
// This event gets saved and passed back to this callback
|
||||||
|
// after the game is quit
|
||||||
|
relaunchSourceEvent = sourceEvent;
|
||||||
|
|
||||||
var quitAppDialog = document.querySelector('#quitAppDialog');
|
var quitAppDialog = document.querySelector('#quitAppDialog');
|
||||||
document.getElementById('quitAppDialogText').innerHTML =
|
document.getElementById('quitAppDialogText').innerHTML =
|
||||||
currentApp.title + ' is already running. Would you like to quit ' +
|
currentApp.title + ' is already running. Would you like to quit ' +
|
||||||
@ -337,7 +338,7 @@ function startGame(sourceEvent) {
|
|||||||
$('#loadingMessage').text('Starting ' + appName + '...');
|
$('#loadingMessage').text('Starting ' + appName + '...');
|
||||||
playGameMode();
|
playGameMode();
|
||||||
|
|
||||||
if(api.currentGame == appID) // if user wants to launch the already-running app, then we resume it.
|
if(api.currentGame == appID) { // if user wants to launch the already-running app, then we resume it.
|
||||||
return api.resumeApp(rikey, rikeyid).then(function (ret) {
|
return api.resumeApp(rikey, rikeyid).then(function (ret) {
|
||||||
sendMessage('startRequest', [host, streamWidth, streamHeight, frameRate,
|
sendMessage('startRequest', [host, streamWidth, streamHeight, frameRate,
|
||||||
bitrate.toString(), api.serverMajorVersion.toString(), rikey, rikeyid.toString()]);
|
bitrate.toString(), api.serverMajorVersion.toString(), rikey, rikeyid.toString()]);
|
||||||
@ -346,6 +347,7 @@ function startGame(sourceEvent) {
|
|||||||
console.log('Returned error was: ' + failedResumeApp);
|
console.log('Returned error was: ' + failedResumeApp);
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
api.launchApp(appID,
|
api.launchApp(appID,
|
||||||
streamWidth + "x" + streamHeight + "x" + frameRate,
|
streamWidth + "x" + streamHeight + "x" + frameRate,
|
||||||
@ -365,6 +367,7 @@ function startGame(sourceEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function cancelQuitApp() {
|
function cancelQuitApp() {
|
||||||
|
relaunchSourceEvent = null;
|
||||||
document.querySelector('#quitAppDialog').close();
|
document.querySelector('#quitAppDialog').close();
|
||||||
console.log('closing app dialog, and returning');
|
console.log('closing app dialog, and returning');
|
||||||
}
|
}
|
||||||
@ -372,7 +375,18 @@ function cancelQuitApp() {
|
|||||||
function continueQuitApp(sourceEvent) {
|
function continueQuitApp(sourceEvent) {
|
||||||
// I want the sourceEvent's sourceEvent
|
// I want the sourceEvent's sourceEvent
|
||||||
console.log('stopping game, and closing app dialog, and returning');
|
console.log('stopping game, and closing app dialog, and returning');
|
||||||
stopGame();
|
stopGame(
|
||||||
|
function() {
|
||||||
|
if (relaunchSourceEvent != null) {
|
||||||
|
// Save and null relaunchSourceEvent just in case startGame()
|
||||||
|
// wants to set it again.
|
||||||
|
var event = relaunchSourceEvent;
|
||||||
|
relaunchSourceEvent = null;
|
||||||
|
|
||||||
|
startGame(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
document.querySelector('#quitAppDialog').close();
|
document.querySelector('#quitAppDialog').close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,7 +422,6 @@ function fullscreenNaclModule() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function stopGame(callbackFunction) {
|
function stopGame(callbackFunction) {
|
||||||
|
|
||||||
api.refreshServerInfo().then(function (ret) {
|
api.refreshServerInfo().then(function (ret) {
|
||||||
api.getAppById(api.currentGame).then(function (runningApp) {
|
api.getAppById(api.currentGame).then(function (runningApp) {
|
||||||
if (!runningApp) {
|
if (!runningApp) {
|
||||||
@ -542,12 +555,7 @@ function onWindowLoad(){
|
|||||||
var ips = Object.keys(finder.byService_['_nvstream._tcp']);
|
var ips = Object.keys(finder.byService_['_nvstream._tcp']);
|
||||||
for (var ip in ips) {
|
for (var ip in ips) {
|
||||||
if (finder.byService_['_nvstream._tcp'][ip]) {
|
if (finder.byService_['_nvstream._tcp'][ip]) {
|
||||||
var cell = document.createElement('div');
|
addHostToGrid(ip);
|
||||||
cell.className += 'mdl-cell mdl-cell--3-col';
|
|
||||||
cell.id = 'hostgrid-' + ip;
|
|
||||||
cell.innerHTML = ip;
|
|
||||||
$('#host-grid').append(cell);
|
|
||||||
cell.onclick = hostChosen;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ function handleMessage(msg) {
|
|||||||
if(msg.data === 'streamTerminated') { // if it's a recognized event, notify the appropriate function
|
if(msg.data === 'streamTerminated') { // if it's a recognized event, notify the appropriate function
|
||||||
$('#loadingSpinner').css('display', 'none'); // This is a fallback for RTSP handshake failing, which immediately terminates the stream.
|
$('#loadingSpinner').css('display', 'none'); // This is a fallback for RTSP handshake failing, which immediately terminates the stream.
|
||||||
api.refreshServerInfo().then(function (ret) {
|
api.refreshServerInfo().then(function (ret) {
|
||||||
showAppsMode();
|
showApps();
|
||||||
chrome.app.window.current().restore();
|
chrome.app.window.current().restore();
|
||||||
});
|
});
|
||||||
} else if(msg.data === 'Connection Established') {
|
} else if(msg.data === 'Connection Established') {
|
||||||
|
@ -40,7 +40,6 @@ function NvHTTP(address, clientUid) {
|
|||||||
this.clientUid = clientUid;
|
this.clientUid = clientUid;
|
||||||
this._baseUrlHttps = 'https://' + address + ':47984';
|
this._baseUrlHttps = 'https://' + address + ':47984';
|
||||||
this._baseUrlHttp = 'http://' + address + ':47989';
|
this._baseUrlHttp = 'http://' + address + ':47989';
|
||||||
this._appListCache = null;
|
|
||||||
this._memCachedBoxArtArray = {};
|
this._memCachedBoxArtArray = {};
|
||||||
_self = this;
|
_self = this;
|
||||||
};
|
};
|
||||||
@ -133,13 +132,6 @@ NvHTTP.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getAppList: function () {
|
getAppList: function () {
|
||||||
if (_self._appListCache) {
|
|
||||||
console.log('Returning app list from cache');
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
resolve(_self._appListCache);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return sendMessage('openUrl', [_self._baseUrlHttps + '/applist?' + _self._buildUidStr(), false]).then(function (ret) {
|
return sendMessage('openUrl', [_self._baseUrlHttps + '/applist?' + _self._buildUidStr(), false]).then(function (ret) {
|
||||||
$xml = _self._parseXML(ret);
|
$xml = _self._parseXML(ret);
|
||||||
|
|
||||||
@ -155,9 +147,6 @@ NvHTTP.prototype = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appList)
|
|
||||||
_self._appListCache = appList;
|
|
||||||
|
|
||||||
return appList;
|
return appList;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
14
viddec.cpp
14
viddec.cpp
@ -62,6 +62,14 @@ 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;
|
||||||
@ -230,6 +238,12 @@ int MoonlightInstance::VidDecSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
|
|||||||
bool isSps = false;
|
bool isSps = false;
|
||||||
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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user