Update for GFE 2.2.2+

This commit is contained in:
Cameron Gutman 2015-01-22 16:55:08 -05:00
parent 8671e4e7ae
commit 41d823923b
5 changed files with 20 additions and 102 deletions

View File

@ -20,21 +20,21 @@ static PCONNECTION_LISTENER_CALLBACKS listenerCallbacks;
static int lossCountSinceLastReport = 0; static int lossCountSinceLastReport = 0;
static long currentFrame = 0; static long currentFrame = 0;
#define PTYPE_START_STREAM_A 0x140b #define PTYPE_START_STREAM_A 0x0606
#define PPAYLEN_START_STREAM_A 1 #define PPAYLEN_START_STREAM_A 2
static const char PPAYLOAD_START_STREAM_A[1] = { 0 }; static const char PPAYLOAD_START_STREAM_A[PPAYLEN_START_STREAM_A] = { 0, 0 };
#define PTYPE_START_STREAM_B 0x1410 #define PTYPE_START_STREAM_B 0x0609
#define PPAYLEN_START_STREAM_B 16 #define PPAYLEN_START_STREAM_B 1
static const int PPAYLOAD_START_STREAM_B[4] = { 0, 0, 0, 0xa }; // FIXME: Little endian static const char PPAYLOAD_START_STREAM_B[PPAYLEN_START_STREAM_B] = { 0 };
#define PTYPE_RESYNC 0x1404 #define PTYPE_RESYNC 0x0604
#define PPAYLEN_RESYNC 24 #define PPAYLEN_RESYNC 24
#define PTYPE_LOSS_STATS 0x140c #define PTYPE_LOSS_STATS 0x060a
#define PPAYLEN_LOSS_STATS 32 #define PPAYLEN_LOSS_STATS 32
#define PTYPE_FRAME_STATS 0x1417 #define PTYPE_FRAME_STATS 0x0611
#define PPAYLEN_FRAME_STATS 64 #define PPAYLEN_FRAME_STATS 64
#define LOSS_REPORT_INTERVAL_MS 50 #define LOSS_REPORT_INTERVAL_MS 50

View File

@ -6,6 +6,10 @@
#include "PlatformThreads.h" #include "PlatformThreads.h"
#include "Video.h" #include "Video.h"
/* GFE 2.2.2+ RTSP/SDP version code */
#define RTSP_CLIENT_VERSION 11
#define RTSP_CLIENT_VERSION_S "11"
char* getSdpPayloadForStreamConfig(PSTREAM_CONFIGURATION streamConfig, struct in_addr targetAddress, int *length); char* getSdpPayloadForStreamConfig(PSTREAM_CONFIGURATION streamConfig, struct in_addr targetAddress, int *length);
int initializeControlStream(IP_ADDRESS host, PSTREAM_CONFIGURATION streamConfig, PCONNECTION_LISTENER_CALLBACKS clCallbacks); int initializeControlStream(IP_ADDRESS host, PSTREAM_CONFIGURATION streamConfig, PCONNECTION_LISTENER_CALLBACKS clCallbacks);

View File

@ -11,10 +11,6 @@ static char sessionIdString[16];
static int hasSessionId; static int hasSessionId;
static char responseBuffer[RTSP_MAX_RESP_SIZE]; static char responseBuffer[RTSP_MAX_RESP_SIZE];
/* GFE 2.1.1 */
#define RTSP_CLIENT_VERSION 10
#define RTSP_CLIENT_VERSION_S "10"
/* Create RTSP Option */ /* Create RTSP Option */
static POPTION_ITEM createOptionItem(char* option, char* content) static POPTION_ITEM createOptionItem(char* option, char* content)
{ {

View File

@ -5,8 +5,6 @@
#define MAX_SDP_HEADER_LEN 128 #define MAX_SDP_HEADER_LEN 128
#define MAX_SDP_TAIL_LEN 128 #define MAX_SDP_TAIL_LEN 128
#define RTSP_CLIENT_VERSION_S "10"
typedef struct _SDP_OPTION { typedef struct _SDP_OPTION {
char name[MAX_OPTION_NAME_LEN+1]; char name[MAX_OPTION_NAME_LEN+1];
void* payload; void* payload;
@ -92,19 +90,14 @@ static int addAttributeString(PSDP_OPTION *head, char* name, const char* payload
static PSDP_OPTION getAttributesList(PSTREAM_CONFIGURATION streamConfig, struct in_addr targetAddress) { static PSDP_OPTION getAttributesList(PSTREAM_CONFIGURATION streamConfig, struct in_addr targetAddress) {
PSDP_OPTION optionHead; PSDP_OPTION optionHead;
int payloadInt; char payloadStr[92];
char payloadStr[64];
int err; int err;
optionHead = NULL; optionHead = NULL;
err = 0; err = 0;
err |= addAttributeString(&optionHead, "x-nv-general.serverAddress",
inet_ntoa(targetAddress)); sprintf(payloadStr, "rtsp://%s:48010", inet_ntoa(targetAddress));
err |= addAttributeString(&optionHead, "x-nv-general.serverAddress", payloadStr);
payloadInt = htonl(0x42774141);
err |= addAttributeBinary(&optionHead,
"x-nv-general.featureFlags", &payloadInt, sizeof(payloadInt));
sprintf(payloadStr, "%d", streamConfig->width); sprintf(payloadStr, "%d", streamConfig->width);
err |= addAttributeString(&optionHead, "x-nv-video[0].clientViewportWd", payloadStr); err |= addAttributeString(&optionHead, "x-nv-video[0].clientViewportWd", payloadStr);
@ -117,26 +110,7 @@ static PSDP_OPTION getAttributesList(PSTREAM_CONFIGURATION streamConfig, struct
sprintf(payloadStr, "%d", streamConfig->packetSize); sprintf(payloadStr, "%d", streamConfig->packetSize);
err |= addAttributeString(&optionHead, "x-nv-video[0].packetSize", payloadStr); err |= addAttributeString(&optionHead, "x-nv-video[0].packetSize", payloadStr);
payloadInt = htonl(0x41514141); err |= addAttributeString(&optionHead, "x-nv-video[0].rateControlMode", "4");
err |= addAttributeBinary(&optionHead,
"x-nv-video[0].transferProtocol", &payloadInt, sizeof(payloadInt));
err |= addAttributeBinary(&optionHead,
"x-nv-video[1].transferProtocol", &payloadInt, sizeof(payloadInt));
err |= addAttributeBinary(&optionHead,
"x-nv-video[2].transferProtocol", &payloadInt, sizeof(payloadInt));
err |= addAttributeBinary(&optionHead,
"x-nv-video[3].transferProtocol", &payloadInt, sizeof(payloadInt));
payloadInt = htonl(0x42414141);
err |= addAttributeBinary(&optionHead,
"x-nv-video[0].rateControlMode", &payloadInt, sizeof(payloadInt));
payloadInt = htonl(0x42514141);
err |= addAttributeBinary(&optionHead,
"x-nv-video[1].rateControlMode", &payloadInt, sizeof(payloadInt));
err |= addAttributeBinary(&optionHead,
"x-nv-video[2].rateControlMode", &payloadInt, sizeof(payloadInt));
err |= addAttributeBinary(&optionHead,
"x-nv-video[3].rateControlMode", &payloadInt, sizeof(payloadInt));
// FIXME: Remote optimizations // FIXME: Remote optimizations
if (streamConfig->bitrate <= 13000) { if (streamConfig->bitrate <= 13000) {
@ -148,7 +122,7 @@ static PSDP_OPTION getAttributesList(PSTREAM_CONFIGURATION streamConfig, struct
err |= addAttributeString(&optionHead, "x-nv-video[0].framesWithInvalidRefThreshold", "0"); err |= addAttributeString(&optionHead, "x-nv-video[0].framesWithInvalidRefThreshold", "0");
// This flags value will mean that resolution won't change as bitrate falls // This flags value will mean that resolution won't change as bitrate falls
err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.flags", "14083"); err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.flags", "51");
// Lock the bitrate since we're not scaling resolution so the picture doesn't get too bad // Lock the bitrate since we're not scaling resolution so the picture doesn't get too bad
if (streamConfig->height >= 1080 && streamConfig->fps >= 60) { if (streamConfig->height >= 1080 && streamConfig->fps >= 60) {
@ -192,13 +166,6 @@ static PSDP_OPTION getAttributesList(PSTREAM_CONFIGURATION streamConfig, struct
// FIXME: Remote optimizations // FIXME: Remote optimizations
err |= addAttributeString(&optionHead, "x-nv-vqos[0].qosTrafficType", "5"); err |= addAttributeString(&optionHead, "x-nv-vqos[0].qosTrafficType", "5");
err |= addAttributeString(&optionHead, "x-nv-vqos[0].videoQosMaxConsecutiveDrops", "0");
err |= addAttributeString(&optionHead, "x-nv-vqos[1].videoQosMaxConsecutiveDrops", "0");
err |= addAttributeString(&optionHead, "x-nv-vqos[2].videoQosMaxConsecutiveDrops", "0");
err |= addAttributeString(&optionHead, "x-nv-vqos[3].videoQosMaxConsecutiveDrops", "0");
// FIXME: Remote optimizations
err |= addAttributeString(&optionHead, "x-nv-aqos.qosTrafficType", "4"); err |= addAttributeString(&optionHead, "x-nv-aqos.qosTrafficType", "4");
if (err == 0) { if (err == 0) {
@ -221,7 +188,7 @@ static int fillSdpHeader(char* buffer, struct in_addr targetAddress) {
static int fillSdpTail(char* buffer) { static int fillSdpTail(char* buffer) {
return sprintf(buffer, return sprintf(buffer,
"t=0 0\r\n" "t=0 0\r\n"
"m=video 47996 \r\n"); "m=video 47998 \r\n");
} }
/* Get the SDP attributes for the stream config */ /* Get the SDP attributes for the stream config */

View File

@ -6,7 +6,6 @@
#define FIRST_FRAME_MAX 1500 #define FIRST_FRAME_MAX 1500
#define RTP_PORT 47998 #define RTP_PORT 47998
#define FIRST_FRAME_PORT 47996
static DECODER_RENDERER_CALLBACKS callbacks; static DECODER_RENDERER_CALLBACKS callbacks;
static STREAM_CONFIGURATION configuration; static STREAM_CONFIGURATION configuration;
@ -14,7 +13,6 @@ static IP_ADDRESS remoteHost;
static PCONNECTION_LISTENER_CALLBACKS listenerCallbacks; static PCONNECTION_LISTENER_CALLBACKS listenerCallbacks;
static SOCKET rtpSocket = INVALID_SOCKET; static SOCKET rtpSocket = INVALID_SOCKET;
static SOCKET firstFrameSocket = INVALID_SOCKET;
static PLT_THREAD udpPingThread; static PLT_THREAD udpPingThread;
static PLT_THREAD receiveThread; static PLT_THREAD receiveThread;
@ -110,37 +108,6 @@ static void DecoderThreadProc(void* context) {
} }
} }
/* Read the first frame of the video stream */
int readFirstFrame(void) {
char* firstFrame;
SOCK_RET err;
int offset = 0;
firstFrame = (char*) malloc(FIRST_FRAME_MAX);
if (firstFrame == NULL) {
return -1;
}
Limelog("Waiting for first frame\n");
for (;;) {
err = recv(firstFrameSocket, &firstFrame[offset], FIRST_FRAME_MAX - offset, 0);
if (err <= 0) {
break;
}
offset += err;
}
Limelog("Read %d bytes\n", offset);
// We can just ignore this data for now. It's the act of reading
// it that matters. If this changes, we'll need to move this call before
// starting the receive thread to avoid state corruption in the depacketizer.
free(firstFrame);
return 0;
}
/* Terminate the video stream */ /* Terminate the video stream */
void stopVideoStream(void) { void stopVideoStream(void) {
callbacks.stop(); callbacks.stop();
@ -149,10 +116,6 @@ void stopVideoStream(void) {
PltInterruptThread(&receiveThread); PltInterruptThread(&receiveThread);
PltInterruptThread(&decoderThread); PltInterruptThread(&decoderThread);
if (firstFrameSocket != INVALID_SOCKET) {
closesocket(firstFrameSocket);
firstFrameSocket = INVALID_SOCKET;
}
if (rtpSocket != INVALID_SOCKET) { if (rtpSocket != INVALID_SOCKET) {
closesocket(rtpSocket); closesocket(rtpSocket);
rtpSocket = INVALID_SOCKET; rtpSocket = INVALID_SOCKET;
@ -193,21 +156,9 @@ int startVideoStream(void* rendererContext, int drFlags) {
return err; return err;
} }
// Connect this socket to open port 47998 for our ping thread
firstFrameSocket = connectTcpSocket(remoteHost, FIRST_FRAME_PORT);
if (firstFrameSocket == INVALID_SOCKET) {
return LastSocketError();
}
// Start pinging before reading the first frame so GFE knows where // Start pinging before reading the first frame so GFE knows where
// to send UDP data // to send UDP data
err = PltCreateThread(UdpPingThreadProc, NULL, &udpPingThread); err = PltCreateThread(UdpPingThreadProc, NULL, &udpPingThread);
if (err != 0) {
return err;
}
// Read the first frame to start the flow of video
err = readFirstFrame();
if (err != 0) { if (err != 0) {
return err; return err;
} }