This source file includes following definitions.
- SampleCallBack
- PNC_Init_SceneGenerator
- PNC_SendInitScene
- PNC_Close_SceneGenerator
- findCommand
- processSend
- processRapReset
- processRap
- processSendCritical
- eat_buffer_to_bs
- PNC_processBIFSGenerator
#include <assert.h>
#include <string.h>
#include <errno.h>
#include "RTP_serv_generator.h"
#include "debug.h"
GF_Err SampleCallBack(void *calling_object, u16 ESID, char *au, u32 size, u64 ts)
{
PNC_CallbackData *data = (PNC_CallbackData *)calling_object;
PNC_ProcessData(data, au, size, ts);
return GF_OK;
}
GF_Err (*MySampleCallBack)(void *, u16, char *data, u32 size, u64 ts) = &SampleCallBack;
PNC_CallbackData *PNC_Init_SceneGenerator(GF_RTPChannel *p_chan, GF_RTPHeader *p_hdr, char *default_scene,
u32 socketType, u16 socketPort, int debug)
{
GF_Err e;
PNC_CallbackData *data = gf_malloc(sizeof(PNC_CallbackData));
int *i;
data->chan = p_chan;
data->hdr = p_hdr;
data->debug = debug;
memset( (void*) (data->buffer), '\0', RECV_BUFFER_SIZE_FOR_COMMANDS);
data->bufferPosition = 0;
data->codec = gf_seng_init((void*)data, default_scene);
if (!data->codec) {
fprintf(stderr, "Cannot create BIFS Engine from %s\n", default_scene);
gf_free(data);
return NULL;
}
data->server_socket = NULL;
data->socket = NULL;
if (socketType == GF_SOCK_TYPE_TCP)
{
data->server_socket = gf_sk_new(socketType);
e = gf_sk_bind(data->server_socket, NULL, (u16) socketPort, NULL, 0, 0);
if (e)
fprintf(stderr, "Failed to bind : %s\n", gf_error_to_string(e));
e |= gf_sk_listen(data->server_socket, 1);
if (e)
fprintf(stderr, "Failed to listen : %s\n", gf_error_to_string(e));
e |= gf_sk_set_block_mode(data->server_socket, 0);
if (e)
fprintf(stderr, "Failed to set block mode : %s\n", gf_error_to_string(e));
e |= gf_sk_server_mode(data->server_socket, 0);
if (e)
fprintf(stderr, "Failed to set server mode : %s\n", gf_error_to_string(e));
} else {
data->socket = gf_sk_new(socketType);
e = gf_sk_bind(data->socket, NULL, (u16) socketPort, NULL, 0, 0);
}
if (e) {
fprintf(stderr, "Cannot bind socket to port %d (%s)\n", socketPort, gf_error_to_string(e));
if (data->socket)
gf_sk_del(data->socket);
if (data->server_socket)
gf_sk_del(data->server_socket);
gf_free(data);
return NULL;
}
data->extension = gf_malloc(sizeof(PNC_CallbackExt));
((PNC_CallbackExt * )data->extension)->i = 0;
((PNC_CallbackExt * )data->extension)->lastTS = 0;
i = &((PNC_CallbackExt*)data->extension)->i;
return data;
}
void PNC_SendInitScene(PNC_CallbackData * data)
{
data->RAP = 1;
data->SAUN_inc = 1;
gf_seng_encode_context(data->codec, MySampleCallBack);
}
void PNC_Close_SceneGenerator(PNC_CallbackData * data)
{
if (data->extension) gf_free(data->extension);
gf_seng_terminate(data->codec);
gf_rtp_del(data->chan);
PNC_ClosePacketizer(data);
gf_free(data);
}
static int findCommand(const char * buffer, int searchFrom)
{
char * sstr;
assert( buffer );
assert( searchFrom >= 0);
if (searchFrom < 30) {
searchFrom = 0;
} else {
searchFrom-= 30;
}
sstr = strstr(&(buffer[searchFrom]), "#_RTP_STREAM_");
if (sstr) {
return (sstr - buffer);
}
return -1;
}
static GF_Err processSend(PNC_CallbackData * data, char * bsBuffer)
{
GF_Err error;
assert( data );
assert( bsBuffer );
assert( data->codec );
dprintf(DEBUG_RTP_serv_generator, "RTP STREAM SEND\n");
gf_mx_p(data->carrousel_mutex);
error = gf_seng_encode_from_string(data->codec, 0, 0, bsBuffer, MySampleCallBack);
gf_mx_v(data->carrousel_mutex);
gf_free( bsBuffer );
return error;
}
static GF_Err processRapReset(PNC_CallbackData * data, char * bsBuffer)
{
GF_Err error;
dprintf(DEBUG_RTP_serv_generator, "RTP STREAM RAP RESET\n");
gf_mx_p(data->carrousel_mutex);
data->RAP = 1;
data->RAPsent++;
data->SAUN_inc = 1;
error = gf_seng_aggregate_context(data->codec, 0);
if (error == GF_OK)
error = gf_seng_encode_context(data->codec, MySampleCallBack);
gf_mx_v(data->carrousel_mutex);
gf_free( bsBuffer );
return error;
}
static GF_Err processRap(PNC_CallbackData * data, char * bsBuffer)
{
GF_Err error;
dprintf(DEBUG_RTP_serv_generator, "RTP STREAM RAP\n");
gf_mx_p(data->carrousel_mutex);
data->SAUN_inc = 1;
data->RAP = 1;
data->RAPsent++;
error = gf_seng_aggregate_context(data->codec, 0);
if (GF_OK == error)
error = gf_seng_encode_context(data->codec, MySampleCallBack);
gf_mx_v(data->carrousel_mutex);
gf_free( bsBuffer );
return error;
}
static GF_Err processSendCritical(PNC_CallbackData * data, char * bsBuffer)
{
GF_Err error;
dprintf(DEBUG_RTP_serv_generator, "RTP STREAM SEND CRITICAL\n");
gf_mx_p(data->carrousel_mutex);
data->SAUN_inc = 1;
error = gf_seng_encode_from_string(data->codec, 0, 0, bsBuffer, MySampleCallBack);
gf_mx_v(data->carrousel_mutex);
gf_free( bsBuffer );
return error;
}
static char * eat_buffer_to_bs(char * data, int newStart, int upToPosition, int dataFullSize)
{
char * newBuffer;
assert(data);
assert(newStart >= 0);
assert(upToPosition >= 0);
assert(dataFullSize > 0);
assert(newStart < upToPosition);
data[upToPosition] = '\0';
newBuffer = NULL;
assert(dataFullSize >= upToPosition-newStart+2);
newBuffer = (char*)gf_malloc(dataFullSize);
memcpy(newBuffer, data, dataFullSize);
memcpy(data, newBuffer+newStart, upToPosition-newStart+1);
data[upToPosition-newStart+1]='\0';
dprintf(DEBUG_RTP_serv_generator, "Generated : '%s'\n", newBuffer);
return newBuffer;
}
GF_Err PNC_processBIFSGenerator(PNC_CallbackData * data)
{
const int tmpBufferSize = 2048;
char *tmpBuffer = (char*)alloca(tmpBufferSize);
int byteRead=0;
char *bsBuffer;
int retour=0;
GF_Err e;
if (data->server_socket)
{
data->socket = NULL;
e = gf_sk_accept(data->server_socket, &(data->socket));
if (e) {
return GF_OK;
} else {
dprintf(DEBUG_RTP_serv_generator, "New TCP client connected !\n");
}
}
do
{
if (data->socket == NULL)
return GF_OK;
e = gf_sk_receive(data->socket, tmpBuffer, tmpBufferSize, 0, & byteRead);
switch (e) {
case GF_IP_NETWORK_EMPTY:
e = GF_OK;
break;
case GF_OK:
if (byteRead > 0) {
dprintf(DEBUG_RTP_serv_generator, "Received %d bytes\n", byteRead);
memcpy( &(data->buffer[data->bufferPosition]), tmpBuffer, byteRead );
data->buffer[data->bufferPosition + byteRead] = '\0';
retour = findCommand( data->buffer, data->bufferPosition);
data->bufferPosition += byteRead;
if (retour >= 0) {
if (strncmp(&(data->buffer[retour+13]),
"SEND_CRITICAL", 13)==0) {
bsBuffer = eat_buffer_to_bs( data->buffer, retour, retour + 26, RECV_BUFFER_SIZE_FOR_COMMANDS);
data->bufferPosition = 0;
return processSendCritical(data, bsBuffer);
}
if (strncmp(&(data->buffer[retour+13]), "SEND", 4)==0) {
bsBuffer = eat_buffer_to_bs( data->buffer, retour, retour + 17, RECV_BUFFER_SIZE_FOR_COMMANDS);
data->bufferPosition = 0;
return processSend(data, bsBuffer);
}
if (strncmp(&(data->buffer[retour+13]), "RAP", 3)==0) {
bsBuffer = eat_buffer_to_bs( data->buffer, retour, retour + 16, RECV_BUFFER_SIZE_FOR_COMMANDS);
data->bufferPosition = 0;
return processRap(data, bsBuffer);
}
if (strncmp(&(data->buffer[retour+13]), "RAP_RESET", 9)==0) {
bsBuffer = eat_buffer_to_bs( data->buffer, retour, retour + 22, RECV_BUFFER_SIZE_FOR_COMMANDS);
data->bufferPosition = 0;
return processRapReset(data, bsBuffer);
}
break;
}
}
break;
default:
fprintf(stderr, "Socket error while receiving BIFS data %s\n", gf_error_to_string(e));
if (data->socket != NULL) {
gf_sk_del(data->socket);
data->socket = NULL;
}
return e;
}
} while (e == GF_OK);
return GF_OK;
}