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

📄 real.c

📁 mplayer播放器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    mp_msg(MSGT_STREAM, MSGL_WARN, "realrtsp: rdt chunk not recognized: got 0x%02x\n",      header[0]);    return 0;  }  /* header[1] is channel, normally 0, ignored */  size=(header[2]<<8)+header[3];  flags1=header[4];  if ((flags1!=0x40)&&(flags1!=0x42)&&(flags1!=0x41))  {#ifdef LOG    printf("got flags1: 0x%02x\n",flags1);#endif    if(header[6] == 0x06) { // eof packet      rtsp_read_data(rtsp_session, header, 7); // Skip the rest of the eof packet      /* Some files have short auxiliary streams, we must ignore eof packets       * for these streams to avoid premature eof.       * Now the code declares eof only if the stream with id == 0 gets eof       * (old code was: eof on the first eof packet received).       */      if(flags1 & 0x7c) // ignore eof for streams with id != 0        return 0;      mp_msg(MSGT_STREAM, MSGL_INFO, "realrtsp: 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=AV_RB32(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)&0x1f;  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);  if(rdt_rawdata) {    n=rtsp_read_data(rtsp_session, *buffer, size-12);    return (n <= 0) ? 0 : n;  }  rmff_dump_pheader(&ph, *buffer);  size-=12;  n=rtsp_read_data(rtsp_session, (*buffer)+12, size);    return (n <= 0) ? 0 : n+12;}static int convert_timestamp(char *str, int *sec, int *msec) {  int hh, mm, ss, ms = 0;  // Timestamp may be optionally quoted with ", skip it  // Since the url is escaped when we get here, we skip the string "%22"  if (!strncmp(str, "%22", 3))    str += 3;  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 *username, char *password) {  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;  uint32_t maxbandwidth = bandwidth;  char* authfield = NULL;  int i;    /* get challenge */  challenge1=strdup(rtsp_search_answers(rtsp_session,"RealChallenge1"));#ifdef LOG  printf("real: Challenge1: %s\n", challenge1);#endif  /* set a reasonable default to get the best stream, unless bandwidth given */  if (!bandwidth)      bandwidth = 10485800;    /* request stream description */rtsp_send_describe:  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");  if(authfield)    rtsp_schedule_field(rtsp_session, authfield);  status=rtsp_request_describe(rtsp_session,NULL);  if (status == 401) {    int authlen, b64_authlen;    char *authreq;    char* authstr = NULL;    if (authfield) {      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: authorization failed, check your credentials\n");      goto autherr;    }    if (!(authreq = rtsp_search_answers(rtsp_session,"WWW-Authenticate"))) {      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: 401 but no auth request, aborting\n");      goto autherr;    }    if (!username) {      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: auth required but no username supplied\n");      goto autherr;    }    if (!strstr(authreq, "Basic")) {      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: authenticator not supported (%s)\n", authreq);      goto autherr;    }    authlen = strlen(username) + (password ? strlen(password) : 0) + 2;    authstr = malloc(authlen);    sprintf(authstr, "%s:%s", username, password ? password : "");    authfield = malloc(authlen*2+22);    strcpy(authfield, "Authorization: Basic ");    b64_authlen = base64_encode(authstr, authlen, authfield+21, authlen*2);    free(authstr);    if (b64_authlen < 0) {      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: base64 output overflow, this should never happen\n");      goto autherr;    }    authfield[b64_authlen+21] = 0;    goto rtsp_send_describe;  }autherr:  if (authfield)     free(authfield);  if ( status<200 || status>299 )  {    char *alert=rtsp_search_answers(rtsp_session,"Alert");    if (alert) {      mp_msg(MSGT_STREAM, MSGL_WARN, "realrtsp: 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"))    mp_msg(MSGT_STREAM, MSGL_WARN, "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) {    mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: 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"))    mp_msg(MSGT_STREAM, MSGL_WARN, "realrtsp: 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(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,NULL);  /* Do setup for all the other streams we subscribed to */  for (i = 1; i < h->prop->num_streams; i++) {    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=%d", mrl, i);    rtsp_request_setup(rtsp_session,buf,NULL);  }  /* set stream parameter (bandwidth) with our subscribe string */  rtsp_schedule_field(rtsp_session, subscribe);  rtsp_request_setparameter(rtsp_session,NULL);  /* set delivery bandwidth */  if (maxbandwidth) {      sprintf(buf, "SetDeliveryBandwidth: Bandwidth=%u;BackOff=0", maxbandwidth);      rtsp_schedule_field(rtsp_session, buf);      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;}struct real_rtsp_session_t *init_real_rtsp_session (void){  struct real_rtsp_session_t *real_rtsp_session = NULL;  real_rtsp_session = malloc (sizeof (struct real_rtsp_session_t));  real_rtsp_session->recv = xbuffer_init (BUF_SIZE);  real_rtsp_session->rdteof = 0;  real_rtsp_session->rdt_rawdata = 0;  return real_rtsp_session;}voidfree_real_rtsp_session (struct real_rtsp_session_t* real_session){  if (!real_session)    return;    xbuffer_free (real_session->recv);  free (real_session);}

⌨️ 快捷键说明

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