void ts_amux_del(GF_AbstractTSMuxer * ts) { if (!ts) return; if ( ts->ts_output_udp_sk ) { gf_sk_del ( ts->ts_output_udp_sk ); ts->ts_output_udp_sk = NULL; } }
Bool is_connected(){ GF_Err e; GF_Socket* sock; sock = gf_sk_new(GF_SOCK_TYPE_UDP); if (sock == NULL) { return 0; } e = gf_sk_connect(sock, "www.google.fr", 4096, NULL); gf_sk_del(sock); if(e){ return 0; }else{ return 1; } }
static void gf_dm_disconnect(GF_DownloadSession *sess) { #ifdef GPAC_HAS_SSL if (sess->ssl) { SSL_shutdown(sess->ssl); SSL_free(sess->ssl); sess->ssl = NULL; } #endif if (sess->sock) { gf_sk_del(sess->sock); sess->sock = NULL; } if (sess->cache) fclose(sess->cache); sess->cache = NULL; sess->status = GF_NETIO_DISCONNECTED; if (sess->num_retry) sess->num_retry--; }
GF_EXPORT GF_Err gf_rtsp_get_command(GF_RTSPSession *sess, GF_RTSPCommand *com) { GF_Err e; u32 BodyStart, size; if (!sess || !com) return GF_BAD_PARAM; //reset the command gf_rtsp_command_reset(com); //if no connection, we have sent a "Connection: Close" if (!sess->connection) return GF_IP_CONNECTION_CLOSED; //lock gf_mx_p(sess->mx); //fill TCP buffer e = gf_rtsp_fill_buffer(sess); if (e) goto exit; //this is upcoming, interleaved data if (strncmp(sess->TCPBuffer+sess->CurrentPos, "RTSP", 4)) { e = GF_IP_NETWORK_EMPTY; goto exit; } e = gf_rtsp_read_reply(sess); if (e) goto exit; gf_rtsp_get_body_info(sess, &BodyStart, &size); e = RTSP_ParseCommandHeader(sess, com, BodyStart); //before returning an error we MUST reset the TCP buffer //copy the body if any if (!e && com->Content_Length) { com->body = (char *) gf_malloc(sizeof(char) * (com->Content_Length)); memcpy(com->body, sess->TCPBuffer+sess->CurrentPos + BodyStart, com->Content_Length); } //reset TCP buffer sess->CurrentPos += BodyStart + com->Content_Length; if (!com->CSeq) com->StatusCode = NC_RTSP_Bad_Request; if (e || (com->StatusCode != NC_RTSP_OK)) goto exit; //NB: there is no "session state" in our lib when acting at the server side, as it depends //on the server implementation. We cannot block responses / announcement to be sent //dynamically, nor reset the session ourselves as we don't know the details of the session //(eg TEARDOWN may keep resources up or not, ...) //we also have the same pb for CSeq, as nothing forbids a server to buffer commands (and it //happens during aggregation of PLAY/PAUSE with overlapping ranges) //however store the last CSeq in case for client checking if (!sess->CSeq) { sess->CSeq = com->CSeq; } //check we're in the right range else { if (sess->CSeq >= com->CSeq) com->StatusCode = NC_RTSP_Header_Field_Not_Valid; else sess->CSeq = com->CSeq; } // //if a connection closed is signal, check this is the good session // and reset it (the client is no longer connected) if (sess->last_session_id && com->Session && !strcmp(com->Session, sess->last_session_id) && com->Connection && !stricmp(com->Connection, "Close")) { gf_rtsp_session_reset(sess, 0); //destroy the socket if (sess->connection) gf_sk_del(sess->connection); sess->connection = NULL; //destroy the http tunnel if any if (sess->HasTunnel && sess->http) { gf_sk_del(sess->http); sess->http = NULL; } } exit: gf_mx_v(sess->mx); return e; }
int live_session(int argc, char **argv) { GF_Err e; int i; char *filename = NULL; char *dst = NULL; char *ifce_addr = NULL; char *sdp_name = "session.sdp"; u16 dst_port = 7000; u32 load_type=0; u32 check; u32 ttl = 1; u32 path_mtu = 1450; s32 next_time; u64 last_src_modif, mod_time; char *src_name = NULL; Bool run, has_carousel, no_rap; Bool udp = 0; u16 sk_port=0; GF_Socket *sk = NULL; LiveSession livesess; RTPChannel *ch; char *update_buffer = NULL; u32 update_buffer_size = 0; u16 aggregate_on_stream; Bool adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, version_inc; Bool update_context; u32 period, ts_delta, signal_critical; u16 es_id; e = GF_OK; aggregate_au = 1; es_id = 0; no_rap = 0; gf_sys_init(0); memset(&livesess, 0, sizeof(LiveSession)); gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_INFO); for (i=1; i<argc; i++) { char *arg = argv[i]; if (arg[0] != '-') filename = arg; else if (!strnicmp(arg, "-dst=", 5)) dst = arg+5; else if (!strnicmp(arg, "-port=", 6)) dst_port = atoi(arg+6); else if (!strnicmp(arg, "-sdp=", 5)) sdp_name = arg+5; else if (!strnicmp(arg, "-mtu=", 5)) path_mtu = atoi(arg+5); else if (!strnicmp(arg, "-ttl=", 5)) ttl = atoi(arg+5); else if (!strnicmp(arg, "-ifce=", 6)) ifce_addr = arg+6; else if (!strnicmp(arg, "-no-rap", 7)) no_rap = 1; else if (!strnicmp(arg, "-dims", 5)) load_type = GF_SM_LOAD_DIMS; else if (!strnicmp(arg, "-src=", 5)) src_name = arg+5; else if (!strnicmp(arg, "-udp=", 5)) { sk_port = atoi(arg+5); udp = 1; } else if (!strnicmp(arg, "-tcp=", 5)) { sk_port = atoi(arg+5); udp = 0; } } if (!filename) { fprintf(stderr, "Missing filename\n"); PrintLiveUsage(); return 1; } if (dst_port && dst) livesess.streams = gf_list_new(); livesess.seng = gf_seng_init(&livesess, filename, load_type, NULL, (load_type == GF_SM_LOAD_DIMS) ? 1 : 0); if (!livesess.seng) { fprintf(stderr, "Cannot create scene engine\n"); return 1; } if (livesess.streams) live_session_setup(&livesess, dst, dst_port, path_mtu, ttl, ifce_addr, sdp_name); has_carousel = 0; last_src_modif = src_name ? gf_file_modification_time(src_name) : 0; if (sk_port) { sk = gf_sk_new(udp ? GF_SOCK_TYPE_UDP : GF_SOCK_TYPE_TCP); if (udp) { e = gf_sk_bind(sk, NULL, sk_port, NULL, 0, 0); if (e != GF_OK) { if (sk) gf_sk_del(sk); sk = NULL; } } else { } } for (i=0; i<argc; i++) { char *arg = argv[i]; if (!strnicmp(arg, "-rap=", 5)) { u32 period, id, j; RTPChannel *ch; period = id = 0; if (strchr(arg, ':')) { sscanf(arg, "-rap=ESID=%u:%u", &id, &period); e = gf_seng_enable_aggregation(livesess.seng, id, 1); if (e) { fprintf(stderr, "Cannot enable aggregation on stream %u: %s\n", id, gf_error_to_string(e)); goto exit; } } else { sscanf(arg, "-rap=%u", &period); } j=0; while (NULL != (ch = gf_list_enum(livesess.streams, &j))) { if (!id || (ch->ESID==id)) ch->carousel_period = period; } has_carousel = 1; } } i=0; while (NULL != (ch = gf_list_enum(livesess.streams, &i))) { if (ch->carousel_period) { has_carousel = 1; break; } } update_context = 0; if (has_carousel || !no_rap) { livesess.carousel_generation = 1; gf_seng_encode_context(livesess.seng, live_session_callback); livesess.carousel_generation = 0; } live_session_send_carousel(&livesess, NULL); check = 10; run = 1; while (run) { check--; if (!check) { check = 10; if (gf_prompt_has_input()) { char c = gf_prompt_get_char(); switch (c) { case 'q': run=0; break; case 'U': livesess.critical = 1; case 'u': { GF_Err e; char szCom[8192]; fprintf(stderr, "Enter command to send:\n"); szCom[0] = 0; if (1 > scanf("%[^\t\n]", szCom)){ fprintf(stderr, "No command entered properly, aborting.\n"); break; } /*stdin flush bug*/ while (getchar()!='\n') {} e = gf_seng_encode_from_string(livesess.seng, 0, 0, szCom, live_session_callback); if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); e = gf_seng_aggregate_context(livesess.seng, 0); livesess.critical = 0; update_context = 1; } break; case 'E': livesess.critical = 1; case 'e': { GF_Err e; char szCom[8192]; fprintf(stderr, "Enter command to send:\n"); szCom[0] = 0; if (1 > scanf("%[^\t\n]", szCom)){ printf("No command entered properly, aborting.\n"); break; } /*stdin flush bug*/ while (getchar()!='\n') {} e = gf_seng_encode_from_string(livesess.seng, 0, 1, szCom, live_session_callback); if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); livesess.critical = 0; e = gf_seng_aggregate_context(livesess.seng, 0); } break; case 'p': { char rad[GF_MAX_PATH]; fprintf(stderr, "Enter output file name - \"std\" for stderr: "); if (1 > scanf("%s", rad)){ fprintf(stderr, "No ouput file name entered, aborting.\n"); break; } e = gf_seng_save_context(livesess.seng, !strcmp(rad, "std") ? NULL : rad); fprintf(stderr, "Dump done (%s)\n", gf_error_to_string(e)); } break; case 'F': update_context = 1; case 'f': livesess.force_carousel = 1; break; } e = GF_OK; } } /*process updates from file source*/ if (src_name) { mod_time = gf_file_modification_time(src_name); if (mod_time != last_src_modif) { FILE *srcf; char flag_buf[201], *flag; fprintf(stderr, "Update file modified - processing\n"); last_src_modif = mod_time; srcf = gf_f64_open(src_name, "rt"); if (!srcf) continue; /*checks if we have a broadcast config*/ if (!fgets(flag_buf, 200, srcf)) flag_buf[0] = '\0'; fclose(srcf); aggregate_on_stream = (u16) -1; adjust_carousel_time = force_rap = discard_pending = signal_rap = signal_critical = 0; aggregate_au = version_inc = 1; period = -1; ts_delta = 0; es_id = 0; /*find our keyword*/ flag = strstr(flag_buf, "gpac_broadcast_config "); if (flag) { flag += strlen("gpac_broadcast_config "); /*move to next word*/ while (flag && (flag[0]==' ')) flag++; while (1) { char *sep = strchr(flag, ' '); if (sep) sep[0] = 0; if (!strnicmp(flag, "esid=", 5)) es_id = atoi(flag+5); else if (!strnicmp(flag, "period=", 7)) period = atoi(flag+7); else if (!strnicmp(flag, "ts=", 3)) ts_delta = atoi(flag+3); else if (!strnicmp(flag, "carousel=", 9)) aggregate_on_stream = atoi(flag+9); else if (!strnicmp(flag, "restamp=", 8)) adjust_carousel_time = atoi(flag+8); else if (!strnicmp(flag, "discard=", 8)) discard_pending = atoi(flag+8); else if (!strnicmp(flag, "aggregate=", 10)) aggregate_au = atoi(flag+10); else if (!strnicmp(flag, "force_rap=", 10)) force_rap = atoi(flag+10); else if (!strnicmp(flag, "rap=", 4)) signal_rap = atoi(flag+4); else if (!strnicmp(flag, "critical=", 9)) signal_critical = atoi(flag+9); else if (!strnicmp(flag, "vers_inc=", 9)) version_inc = atoi(flag+9); if (sep) { sep[0] = ' '; flag = sep+1; } else { break; } } set_broadcast_params(&livesess, es_id, period, ts_delta, aggregate_on_stream, adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, signal_critical, version_inc); } e = gf_seng_encode_from_file(livesess.seng, es_id, aggregate_au ? 0 : 1, src_name, live_session_callback); if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); e = gf_seng_aggregate_context(livesess.seng, 0); update_context = no_rap ? 0 : 1; } } /*process updates from socket source*/ if (sk) { char buffer[2049]; u32 bytes_read; u32 update_length; u32 bytes_received; e = gf_sk_receive(sk, buffer, 2048, 0, &bytes_read); if (e == GF_OK) { u32 hdr_length = 0; u8 cmd_type = buffer[0]; bytes_received = 0; switch (cmd_type) { case 0: { GF_BitStream *bs = gf_bs_new(buffer, bytes_read, GF_BITSTREAM_READ); gf_bs_read_u8(bs); es_id = gf_bs_read_u16(bs); aggregate_on_stream = gf_bs_read_u16(bs); if (aggregate_on_stream==0xFFFF) aggregate_on_stream = -1; adjust_carousel_time = gf_bs_read_int(bs, 1); force_rap = gf_bs_read_int(bs, 1); aggregate_au = gf_bs_read_int(bs, 1); discard_pending = gf_bs_read_int(bs, 1); signal_rap = gf_bs_read_int(bs, 1); signal_critical = gf_bs_read_int(bs, 1); version_inc = gf_bs_read_int(bs, 1); gf_bs_read_int(bs, 1); period = gf_bs_read_u16(bs); if (period==0xFFFF) period = -1; ts_delta = gf_bs_read_u16(bs); update_length = gf_bs_read_u32(bs); hdr_length = 12; gf_bs_del(bs); } set_broadcast_params(&livesess, es_id, period, ts_delta, aggregate_on_stream, adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, signal_critical, version_inc); break; default: update_length = 0; break; } if (update_buffer_size <= update_length) { update_buffer = gf_realloc(update_buffer, update_length+1); update_buffer_size = update_length+1; } if (update_length && (bytes_read>hdr_length) ) { memcpy(update_buffer, buffer+hdr_length, bytes_read-hdr_length); bytes_received = bytes_read-hdr_length; } while (bytes_received<update_length) { e = gf_sk_receive(sk, buffer, 2048, 0, &bytes_read); switch (e) { case GF_IP_NETWORK_EMPTY: break; case GF_OK: memcpy(update_buffer+bytes_received, buffer, bytes_read); bytes_received += bytes_read; break; default: fprintf(stderr, "Error with UDP socket : %s\n", gf_error_to_string(e)); break; } } update_buffer[update_length] = 0; if (update_length) { e = gf_seng_encode_from_string(livesess.seng, es_id, aggregate_au ? 0 : 1, update_buffer, live_session_callback); if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); e = gf_seng_aggregate_context(livesess.seng, 0); update_context = 1; } } } if (update_context) { livesess.carousel_generation=1; e = gf_seng_encode_context(livesess.seng, live_session_callback ); livesess.carousel_generation=0; update_context = 0; } if (livesess.force_carousel) { live_session_send_carousel(&livesess, NULL); livesess.force_carousel = 0; continue; } if (!has_carousel) { gf_sleep(10); continue; } ch = next_carousel(&livesess, &next_time); if ((ch==NULL) || (next_time > 20)) { gf_sleep(20); continue; } if (next_time) gf_sleep(next_time); live_session_send_carousel(&livesess, ch); } exit: live_session_shutdown(&livesess); if (update_buffer) gf_free(update_buffer); if (sk) gf_sk_del(sk); gf_sys_close(); return e ? 1 : 0; }
GF_EXPORT GF_Err gf_rtsp_get_response(GF_RTSPSession *sess, GF_RTSPResponse *rsp) { GF_Err e; Bool force_reset = GF_FALSE; u32 BodyStart, size; if (!sess || !rsp) return GF_BAD_PARAM; gf_rtsp_response_reset(rsp); //LOCK gf_mx_p(sess->mx); e = gf_rtsp_check_connection(sess); if (e) goto exit; //push data in our queue e = gf_rtsp_fill_buffer(sess); if (e) goto exit; //this is interleaved data if (!IsRTSPMessage(sess->TCPBuffer+sess->CurrentPos) ) { gf_rtsp_session_read(sess); e = GF_IP_NETWORK_EMPTY; goto exit; } e = gf_rtsp_read_reply(sess); if (e) goto exit; //get the reply gf_rtsp_get_body_info(sess, &BodyStart, &size); e = RTSP_ParseResponseHeader(sess, rsp, BodyStart); //copy the body if any if (!e && rsp->Content_Length) { rsp->body = (char *)gf_malloc(sizeof(char) * (rsp->Content_Length)); memcpy(rsp->body, sess->TCPBuffer+sess->CurrentPos + BodyStart, rsp->Content_Length); } GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTSP] Got Response:\n%s\n", sess->TCPBuffer+sess->CurrentPos)); //reset TCP buffer sess->CurrentPos += BodyStart + rsp->Content_Length; if (e) goto exit; //update RTSP aggreagation info if (sess->NbPending) sess->NbPending -= 1; if (sess->RTSP_State == GF_RTSP_STATE_WAITING) sess->RTSP_State = GF_RTSP_STATE_INIT; //control, and everything is received else if (sess->RTSP_State == GF_RTSP_STATE_WAIT_FOR_CONTROL) { if (!sess->NbPending) sess->RTSP_State = GF_RTSP_STATE_INIT; } //this is a late reply to an aggregated control - signal nothing if (!strcmp(sess->RTSPLastRequest, "RESET") && sess->CSeq > rsp->CSeq) { e = GF_IP_NETWORK_EMPTY; goto exit; } //reset last request if (sess->RTSP_State == GF_RTSP_STATE_INIT) strcpy(sess->RTSPLastRequest, ""); //check the CSeq is in the right range. The server should ALWAYS reply in sequence //to an aggreagated sequence of requests //if we have reseted the connection (due to an APP error) return empty if (rsp->CSeq && sess->CSeq > rsp->CSeq + sess->NbPending) { gf_mx_v(sess->mx); return gf_rtsp_get_response(sess, rsp); } if (sess->CSeq != rsp->CSeq + sess->NbPending) { GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[RTSP] Invalid sequence number - got %d but expected %d\n", sess->CSeq, rsp->CSeq + sess->NbPending)); e = GF_REMOTE_SERVICE_ERROR; goto exit; } /*check session ID*/ if (rsp->Session && sess->last_session_id && strcmp(sess->last_session_id, rsp->Session)) { e = GF_REMOTE_SERVICE_ERROR; goto exit; } //destroy sessionID if needed - real doesn't close the connection when destroying //session if (!strcmp(sess->RTSPLastRequest, GF_RTSP_TEARDOWN)) { sess->last_session_id = NULL; } exit: if (rsp->Connection && !stricmp(rsp->Connection, "Close")) force_reset = GF_TRUE; else if (e && (e != GF_IP_NETWORK_EMPTY)) force_reset = GF_TRUE; if (force_reset) { gf_rtsp_session_reset(sess, GF_FALSE); //destroy the socket if (sess->connection) gf_sk_del(sess->connection); sess->connection = NULL; //destroy the http tunnel if any if (sess->HasTunnel && sess->http) { gf_sk_del(sess->http); sess->http = NULL; } } gf_mx_v(sess->mx); return e; }
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); /* We copy data in buffer */ 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){ /** OK, it means we found a command ! */ 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); } /** If we are here, it means probably we did not received fully the command */ break; } } /* No bytes were received */ 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; }
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; /* Loading the initial scene as the encoding context */ 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); } /* char buffIp[1024]; u16 port = 0; u32 socket_type = 0; e |= gf_sk_get_local_ip(data->socket, buffIp); e |= gf_sk_get_local_info(data->socket, &port, &socket_type); dprintf(DEBUG_RTP_serv_generator, "RTS_serv_generator %s:%d %s\n", buffIp, port, socket_type==GF_SOCK_TYPE_UDP?"UDP":"TCP", e==GF_OK?"OK":"ERROR"); */ 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; }
u32 tcp_server(void *par) { TCP_Input *input = par; u32 *timer = input->RAPtimer; char buffer[MAX_BUF]; unsigned char temp[MAX_BUF]; FILE *fp; u32 byte_read; int ret; GF_Config *gf_config_file; GF_Socket *TCP_socket; GF_Socket *conn_socket; GF_Err e; int debug = input->debug; input->status = 1; TCP_socket = gf_sk_new(GF_SOCK_TYPE_TCP); e = gf_sk_bind(TCP_socket, NULL, input->port, NULL, 0, 0); e = gf_sk_listen(TCP_socket, 1); e = gf_sk_set_block_mode(TCP_socket, 1); e = gf_sk_server_mode(TCP_socket, 0); while(input->status == 1) { memset(buffer, 0, sizeof(buffer)); e = gf_sk_accept(TCP_socket, &conn_socket); if (e == GF_OK) { memset(buffer, 0, sizeof(buffer)); e = gf_sk_receive(conn_socket, buffer, MAX_BUF, 0, &byte_read); } switch (e) { case GF_IP_NETWORK_EMPTY: gf_sleep(33); continue; case GF_OK: break; default: fprintf(stderr, "Error with TCP socket : %s\n", gf_error_to_string(e)); exit(1); break; } if((*(input->config_flag)) == 0) { u32 num_retry; fp = fopen("temp.cfg", "w+"); if (!fp) { fprintf(stderr, "Error opening temp file for the configuration\n"); exit(1); } ret = fwrite(buffer, 1, byte_read, fp); fclose(fp); /* parsing config info */ gf_config_file = gf_cfg_new(".", "temp.cfg"); if (!gf_config_file) { fprintf(stderr, "Error opening the config file %s\n", gf_error_to_string(e)); exit(-1); } parse_config(gf_config_file, input->config, debug); /* Acknowledging the configuration */ gf_sk_send(conn_socket, "OK\n", 3); memset(temp, 0, sizeof(temp)); fp = fopen(input->config->scene_init_file, "w+"); if (!fp) { fprintf(stderr, "Error opening temp file for reception of the initial scene\n"); exit(1); } num_retry=10; while (1) { GF_Err e = gf_sk_receive(conn_socket, temp, sizeof(temp), 0, &byte_read); if (e == GF_OK) { fwrite(temp, 1, byte_read, fp); } else if (e==GF_IP_NETWORK_EMPTY) { num_retry--; if (!num_retry) break; gf_sleep(1); } else { fprintf(stderr, "Error receiving initial scene: %s\n", gf_error_to_string(e)); break; } } fclose(fp); *(input->config_flag) = 1; } /* we only wait now for the config updates */ if ( (*(input->config_flag)) == 1) { ret = sscanf(buffer, "DelaiMax=%d\n", timer); fprintf(stdout, "RAP timer changed, now : %d\n", *timer); } gf_sk_del(conn_socket); } input->status = 2; return GF_OK; }
u32 grab_live_m2ts(const char *grab_m2ts, const char *outName) { char data[0x80000]; u32 check = 50; u64 nb_pck; Bool first_run, is_rtp; FILE *output; #ifndef GPAC_DISABLE_STREAMING u16 seq_num; GF_RTPReorder *ch = NULL; #endif GF_Socket *sock; GF_Err e = gf_m2ts_get_socket(grab_m2ts, NULL, 0x80000, &sock); if (e) { fprintf(stderr, "Cannot open %s: %s\n", grab_m2ts, gf_error_to_string(e)); return 1; } output = gf_f64_open(outName, "wb"); if (!output) { fprintf(stderr, "Cannot open %s: check path and rights\n", outName); gf_sk_del(sock); return 1; } fprintf(stderr, "Dumping %s stream to %s - press q to abort\n", grab_m2ts, outName); first_run = 1; is_rtp = 0; while (1) { u32 size = 0; check--; if (!check) { if (gf_prompt_has_input()) { char c = (char) gf_prompt_get_char(); if (c=='q') break; } check = 50; } /*m2ts chunks by chunks*/ e = gf_sk_receive(sock, data, 0x40000, 0, &size); if (!size || e) { gf_sleep(1); continue; } if (first_run) { first_run = 0; /*FIXME: we assume only simple RTP packaging (no CSRC nor extensions)*/ if ((data[0] != 0x47) && ((data[1] & 0x7F) == 33) ) { is_rtp = 1; #ifndef GPAC_DISABLE_STREAMING ch = gf_rtp_reorderer_new(100, 500); #endif } } /*process chunk*/ if (is_rtp) { #ifndef GPAC_DISABLE_STREAMING char *pck; seq_num = ((data[2] << 8) & 0xFF00) | (data[3] & 0xFF); gf_rtp_reorderer_add(ch, (void *) data, size, seq_num); pck = (char *) gf_rtp_reorderer_get(ch, &size); if (pck) { fwrite(pck+12, size-12, 1, output); gf_free(pck); } #else fwrite(data+12, size-12, 1, output); #endif } else { fwrite(data, size, 1, output); } } nb_pck = gf_f64_tell(output); nb_pck /= 188; fprintf(stderr, "Captured "LLU" TS packets\n", nb_pck ); fclose(output); gf_sk_del(sock); #ifndef GPAC_DISABLE_STREAMING if (ch) gf_rtp_reorderer_del(ch); #endif return 0; }