⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 real.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* * 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'))  {#ifdef LOG    printf("libreal: MLTI tag not detected, copying data\n");#endif    *out = xbuffer_copyin(*out, 0, mlti_chunk, mlti_size);    return mlti_size;  }  mlti_chunk+=4;  /* next 16 bits are the number of rules */  numrules=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=BE_16(mlti_chunk);  /* skip to number of codecs */  mlti_chunk+=(numrules-selection)*2;  /* get number of codecs */  numrules=BE_16(mlti_chunk);  if (codec >= numrules) {    printf("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=BE_32(mlti_chunk);    mlti_chunk+=size+4;  }    size=BE_32(mlti_chunk);#ifdef LOG  hexdump(mlti_chunk+4, size);#endif  *out = xbuffer_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 = xbuffer_init(2048);  header=calloc(1,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=calloc(1,sizeof(rmff_mdpr_t*)*(desc->stream_count+1));#ifdef LOG    printf("number of streams: %u\n", desc->stream_count);#endif  for (i=0; i<desc->stream_count; i++) {    int j=0;    int n;    char b[64];    int rulematches[16];#ifdef LOG    printf("calling asmrp_match with:\n%s\n%u\n", desc->stream[i]->asm_rule_book, bandwidth);#endif    n=asmrp_match(desc->stream[i]->asm_rule_book, bandwidth, rulematches);    for (j=0; j<n; j++) {#ifdef LOG      printf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id);#endif      sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]);      *stream_rules = xbuffer_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);  buf = xbuffer_free(buf);  return header;}int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer) {  int n=1;  uint8_t header[8];  rmff_pheader_t ph;  int size;  int flags1, flags2;  int unknown1;  uint32_t ts;  static uint32_t prev_ts = -1;  static int prev_stream_number = -1;  n=rtsp_read_data(rtsp_session, header, 8);  if (n<8) return 0;  if (header[0] != 0x24)  {    printf("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))  {#ifdef LOG    printf("got flags1: 0x%02x\n",flags1);#endif    if(header[6] == 0x06) {      printf("Stream EOF detected\n");      return -1;    }    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;#ifdef LOG    printf("ignoring bytes:\n");    hexdump(header, 8);#endif    n=rtsp_read_data(rtsp_session, header+4, 4);    if (n<4) return 0;    flags1=header[4];    size-=9;  }  flags2=header[7];  // header[5..6] == frame number in stream  unknown1=(header[5]<<16)+(header[6]<<8)+(header[7]);  n=rtsp_read_data(rtsp_session, header, 6);  if (n<6) return 0;  ts=BE_32(header);  #ifdef LOG  printf("ts: %u, size: %u, flags: 0x%02x, unknown values: 0x%06x 0x%02x 0x%02x\n",           ts, size, flags1, unknown1, header[4], header[5]);#endif  size+=2;    ph.object_version=0;  ph.length=size;  ph.stream_number=(flags1>>1)&1;  ph.timestamp=ts;  ph.reserved=0;  if ((flags2&1) == 0 && (prev_ts != ts || prev_stream_number != ph.stream_number))  {    prev_ts = ts;    prev_stream_number = ph.stream_number;    ph.flags=2;  }  else    ph.flags=0;  *buffer = xbuffer_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;}int convert_timestamp(char *str, int *sec, int *msec) {  int hh, mm, ss, ms = 0;  if (sscanf(str, "%d:%d:%d.%d", &hh, &mm, &ss, &ms) < 3) {    hh = 0;    if (sscanf(str, "%d:%d.%d", &mm, &ss, &ms) < 2) {      mm = 0;      if (sscanf(str, "%d.%d", &ss, &ms) < 1) {	ss = 0;	ms = 0;      }    }  }  if (sec)    *sec = hh * 3600 + mm * 60 + ss;  if (msec)    *msec = ms;  return 1;}//! 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 = xbuffer_init(256);  char *mrl=rtsp_get_mrl(rtsp_session);  unsigned int size;  int status;    /* get challenge */  challenge1=strdup(rtsp_search_answers(rtsp_session,"RealChallenge1"));#ifdef LOG  printf("real: Challenge1: %s\n", challenge1);#endif    /* 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) {      printf("real: got message from server:\n%s\n", alert);    }    rtsp_send_ok(rtsp_session);    buf = xbuffer_free(buf);    return NULL;  }  /* receive description */  size=0;  if (!rtsp_search_answers(rtsp_session,"Content-length"))    printf("real: got no Content-length!\n");  else    size=atoi(rtsp_search_answers(rtsp_session,"Content-length"));  // as size is unsigned this also catches the case (size < 0)  if (size > MAX_DESC_BUF) {    printf("real: Content-length for description too big (> %uMB)!\n",            MAX_DESC_BUF/(1024*1024) );    xbuffer_free(buf);    return NULL;  }  if (!rtsp_search_answers(rtsp_session,"ETag"))    printf("real: got no ETag!\n");  else    session_id=strdup(rtsp_search_answers(rtsp_session,"ETag"));    #ifdef LOG  printf("real: Stream description size: %u\n", size);#endif  description=malloc(sizeof(char)*(size+1));  if( rtsp_read_data(rtsp_session, description, size) <= 0) {    buf = xbuffer_free(buf);    return NULL;  }  description[size]=0;  /* parse sdp (sdpplin) and create a header and a subscribe string */  subscribe = xbuffer_init(256);  strcpy(subscribe, "Subscribe: ");  h=real_parse_sdp(description, &subscribe, bandwidth);  if (!h) {    subscribe = xbuffer_free(subscribe);    buf = xbuffer_free(buf);    return NULL;  }  rmff_fix_header(h);#ifdef LOG  printf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n",    h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams);#endif    /* setup our streams */  real_calc_response_and_checksum (challenge2, checksum, challenge1);  buf = xbuffer_ensure_size(buf, strlen(challenge2) + strlen(checksum) + 32);  sprintf(buf, "RealChallenge2: %s, sd=%s", challenge2, checksum);  rtsp_schedule_field(rtsp_session, buf);  buf = xbuffer_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");  buf = xbuffer_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");    buf = xbuffer_ensure_size(buf, strlen(session_id) + 32);    sprintf(buf, "If-Match: %s", session_id);    rtsp_schedule_field(rtsp_session, buf);    buf = xbuffer_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);  {    int s_ss = 0, s_ms = 0, e_ss = 0, e_ms = 0;    char *str;    if ((str = rtsp_get_param(rtsp_session, "start"))) {      convert_timestamp(str, &s_ss, &s_ms);      free(str);    }    if ((str = rtsp_get_param(rtsp_session, "end"))) {      convert_timestamp(str, &e_ss, &e_ms);      free(str);    }    str = buf + sprintf(buf, s_ms ? "%s%d.%d-" : "%s%d-", "Range: npt=", s_ss, s_ms);    if (e_ss || e_ms)      sprintf(str, e_ms ? "%d.%d" : "%d", e_ss, e_ms);  }  rtsp_schedule_field(rtsp_session, buf);  /* and finally send a play request */  rtsp_request_play(rtsp_session,NULL);  subscribe = xbuffer_free(subscribe);  buf = xbuffer_free(buf);  return h;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -