📄 real.c
字号:
/* calculate checksum */ for (i=0; i<resp_len/4; i++) chksum[i] = response[i*4];}/* * takes a MLTI-Chunk and a rule number got from match_asm_rule, * returns a pointer to selected data and number of bytes in that. */static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection, char **out) { int numrules, codec, size; int i; /* MLTI chunk should begin with MLTI */ if ((mlti_chunk[0] != 'M') ||(mlti_chunk[1] != 'L') ||(mlti_chunk[2] != 'T') ||(mlti_chunk[3] != 'I')) { lprintf("MLTI tag not detected, copying data\n"); xine_buffer_copyin(*out, 0, mlti_chunk, mlti_size); return mlti_size; } mlti_chunk+=4; /* next 16 bits are the number of rules */ numrules=_X_BE_16(mlti_chunk); if (selection >= numrules) return 0; /* now <numrules> indices of codecs follows */ /* we skip to selection */ mlti_chunk+=(selection+1)*2; /* get our index */ codec=_X_BE_16(mlti_chunk); /* skip to number of codecs */ mlti_chunk+=(numrules-selection)*2; /* get number of codecs */ numrules=_X_BE_16(mlti_chunk); if (codec >= numrules) { lprintf("codec index >= number of codecs. %i %i\n", codec, numrules); return 0; } mlti_chunk+=2; /* now seek to selected codec */ for (i=0; i<codec; i++) { size=_X_BE_32(mlti_chunk); mlti_chunk+=size+4; } size=_X_BE_32(mlti_chunk);#ifdef LOG xine_hexdump(mlti_chunk+4, size);#endif xine_buffer_copyin(*out, 0, mlti_chunk+4, size); return size;}/* * looking at stream description. */rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidth) { sdpplin_t *desc; rmff_header_t *header; char *buf; int len, i; int max_bit_rate=0; int avg_bit_rate=0; int max_packet_size=0; int avg_packet_size=0; int duration=0; if (!data) return NULL; desc=sdpplin_parse(data); if (!desc) return NULL; buf=xine_buffer_init(2048); header = xine_xmalloc(sizeof(rmff_header_t)); header->fileheader=rmff_new_fileheader(4+desc->stream_count); header->cont=rmff_new_cont( desc->title, desc->author, desc->copyright, desc->abstract); header->data=rmff_new_dataheader(0,0); header->streams = xine_xmalloc(sizeof(rmff_mdpr_t*)*(desc->stream_count+1)); lprintf("number of streams: %u\n", desc->stream_count); for (i=0; i<desc->stream_count; i++) { int j=0; int n; char b[64]; int rulematches[16]; lprintf("calling asmrp_match with:\n%s\n%u\n", desc->stream[i]->asm_rule_book, bandwidth); n=asmrp_match(desc->stream[i]->asm_rule_book, bandwidth, rulematches, sizeof(rulematches)/sizeof(rulematches[0])); for (j=0; j<n; j++) { lprintf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id); sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]); xine_buffer_strcat(*stream_rules, b); } if (!desc->stream[i]->mlti_data) { len = 0; buf = NULL; } else len=select_mlti_data(desc->stream[i]->mlti_data, desc->stream[i]->mlti_data_size, rulematches[0], &buf); header->streams[i]=rmff_new_mdpr( desc->stream[i]->stream_id, desc->stream[i]->max_bit_rate, desc->stream[i]->avg_bit_rate, desc->stream[i]->max_packet_size, desc->stream[i]->avg_packet_size, desc->stream[i]->start_time, desc->stream[i]->preroll, desc->stream[i]->duration, desc->stream[i]->stream_name, desc->stream[i]->mime_type, len, buf); duration=MAX(duration,desc->stream[i]->duration); max_bit_rate+=desc->stream[i]->max_bit_rate; avg_bit_rate+=desc->stream[i]->avg_bit_rate; max_packet_size=MAX(max_packet_size, desc->stream[i]->max_packet_size); if (avg_packet_size) avg_packet_size=(avg_packet_size + desc->stream[i]->avg_packet_size) / 2; else avg_packet_size=desc->stream[i]->avg_packet_size; } if (*stream_rules && strlen(*stream_rules) && (*stream_rules)[strlen(*stream_rules)-1] == ',') (*stream_rules)[strlen(*stream_rules)-1]=0; /* delete last ',' in stream_rules */ header->prop=rmff_new_prop( max_bit_rate, avg_bit_rate, max_packet_size, avg_packet_size, 0, duration, 0, 0, 0, desc->stream_count, desc->flags); rmff_fix_header(header); xine_buffer_free(buf); sdpplin_free(desc); return header;}int real_get_rdt_chunk(rtsp_t *rtsp_session, unsigned char **buffer) { int n=1; uint8_t header[8]; rmff_pheader_t ph; int size; int flags1; int unknown1; uint32_t ts; n=rtsp_read_data(rtsp_session, header, 8); if (n<8) return 0; if (header[0] != 0x24) { lprintf("rdt chunk not recognized: got 0x%02x\n", header[0]); return 0; } size=(header[1]<<16)+(header[2]<<8)+(header[3]); flags1=header[4]; if ((flags1!=0x40)&&(flags1!=0x42)) { lprintf("got flags1: 0x%02x\n",flags1); if (header[6]==0x06) { lprintf("got end of stream packet\n"); return 0; } header[0]=header[5]; header[1]=header[6]; header[2]=header[7]; n=rtsp_read_data(rtsp_session, header+3, 5); if (n<5) return 0; lprintf("ignoring bytes:\n");#ifdef LOG xine_hexdump(header, 8);#endif n=rtsp_read_data(rtsp_session, header+4, 4); if (n<4) return 0; flags1=header[4]; size-=9; } unknown1=(header[5]<<16)+(header[6]<<8)+(header[7]); n=rtsp_read_data(rtsp_session, header, 6); if (n<6) return 0; ts=_X_BE_32(header); lprintf("ts: %u size: %u, flags: 0x%02x, unknown values: %u 0x%02x 0x%02x\n", ts, size, flags1, unknown1, header[4], header[5]); size+=2; ph.object_version=0; ph.length=size; ph.stream_number=(flags1>>1)&1; ph.timestamp=ts; ph.reserved=0; ph.flags=0; /* TODO: determine keyframe flag and insert here? */ xine_buffer_ensure_size(*buffer, 12+size); rmff_dump_pheader(&ph, *buffer); size-=12; n=rtsp_read_data(rtsp_session, (*buffer)+12, size); return (n <= 0) ? 0 : n+12;}//! maximum size of the rtsp description, must be < INT_MAX#define MAX_DESC_BUF (20 * 1024 * 1024)rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth) { char *description=NULL; char *session_id=NULL; rmff_header_t *h; char *challenge1; char challenge2[64]; char checksum[34]; char *subscribe; char *buf=xine_buffer_init(256); char *mrl=rtsp_get_mrl(rtsp_session); unsigned int size; int status; /* get challenge */ challenge1=strdup(rtsp_search_answers(rtsp_session,"RealChallenge1")); lprintf("Challenge1: %s\n", challenge1); /* request stream description */ rtsp_schedule_field(rtsp_session, "Accept: application/sdp"); sprintf(buf, "Bandwidth: %u", bandwidth); rtsp_schedule_field(rtsp_session, buf); rtsp_schedule_field(rtsp_session, "GUID: 00000000-0000-0000-0000-000000000000"); rtsp_schedule_field(rtsp_session, "RegionData: 0"); rtsp_schedule_field(rtsp_session, "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586"); rtsp_schedule_field(rtsp_session, "SupportsMaximumASMBandwidth: 1"); rtsp_schedule_field(rtsp_session, "Language: en-US"); rtsp_schedule_field(rtsp_session, "Require: com.real.retain-entity-for-setup"); status=rtsp_request_describe(rtsp_session,NULL); if ( status<200 || status>299 ) { char *alert=rtsp_search_answers(rtsp_session,"Alert"); if (alert) { lprintf("real: got message from server:\n%s\n", alert); } rtsp_send_ok(rtsp_session); xine_buffer_free(buf); return NULL; } /* receive description */ size=0; if (!rtsp_search_answers(rtsp_session,"Content-length")) lprintf("real: got no Content-length!\n"); else size=atoi(rtsp_search_answers(rtsp_session,"Content-length")); if (size > MAX_DESC_BUF) { printf("real: Content-length for description too big (> %uMB)!\n", MAX_DESC_BUF/(1024*1024) ); xine_buffer_free(buf); return NULL; } if (!rtsp_search_answers(rtsp_session,"ETag")) lprintf("real: got no ETag!\n"); else session_id=strdup(rtsp_search_answers(rtsp_session,"ETag")); lprintf("Stream description size: %i\n", size); description = malloc(sizeof(char)*(size+1)); if( rtsp_read_data(rtsp_session, description, size) <= 0) { xine_buffer_free(buf); return NULL; } description[size]=0; /* parse sdp (sdpplin) and create a header and a subscribe string */ subscribe=xine_buffer_init(256); strcpy(subscribe, "Subscribe: "); h=real_parse_sdp(description, &subscribe, bandwidth); if (!h) { xine_buffer_free(subscribe); xine_buffer_free(buf); return NULL; } rmff_fix_header(h); lprintf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n", h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams); /* setup our streams */ real_calc_response_and_checksum (challenge2, checksum, challenge1); xine_buffer_ensure_size(buf, strlen(challenge2) + strlen(checksum) + 32); sprintf(buf, "RealChallenge2: %s, sd=%s", challenge2, checksum); rtsp_schedule_field(rtsp_session, buf); xine_buffer_ensure_size(buf, strlen(session_id) + 32); sprintf(buf, "If-Match: %s", session_id); rtsp_schedule_field(rtsp_session, buf); rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); xine_buffer_ensure_size(buf, strlen(mrl) + 32); sprintf(buf, "%s/streamid=0", mrl); rtsp_request_setup(rtsp_session,buf); if (h->prop->num_streams > 1) { rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); xine_buffer_ensure_size(buf, strlen(session_id) + 32); sprintf(buf, "If-Match: %s", session_id); rtsp_schedule_field(rtsp_session, buf); xine_buffer_ensure_size(buf, strlen(mrl) + 32); sprintf(buf, "%s/streamid=1", mrl); rtsp_request_setup(rtsp_session,buf); } /* set stream parameter (bandwidth) with our subscribe string */ rtsp_schedule_field(rtsp_session, subscribe); rtsp_request_setparameter(rtsp_session,NULL); xine_buffer_free(subscribe); xine_buffer_free(buf); return h;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -