Esempio n. 1
0
/**
 * Update the present timestamp value of a ticker.
 */
static void update_present_time(const ticker_data_t *const ticker)
{ 
    ticker->queue->present_time = convert_timestamp(
        ticker->queue->present_time, 
        ticker->interface->read()
    );
}
Esempio n. 2
0
void ticker_insert_event(const ticker_data_t *const ticker, ticker_event_t *obj, timestamp_t timestamp, uint32_t id)
{
    core_util_critical_section_enter();

    // update the current timestamp
    update_present_time(ticker);
    us_timestamp_t absolute_timestamp = convert_timestamp(
        ticker->queue->present_time, 
        timestamp
    );
    core_util_critical_section_exit();

    // defer to ticker_insert_event_us
    ticker_insert_event_us(
        ticker, 
        obj, absolute_timestamp, id
    );
}
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 = NULL;
  char *challenge1 = NULL;
  char challenge2[41];
  char checksum[9];
  char *subscribe = NULL;
  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=rtsp_search_answers(rtsp_session,"RealChallenge1");
  if (!challenge1)
      goto out;
  challenge1=strdup(challenge1);
#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);
    goto out;
  }

  /* 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) );
    goto out;
  }

  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) {
    goto out;
  }
  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) {
    goto out;
  }
  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);

out:
  subscribe = xbuffer_free(subscribe);
  buf = xbuffer_free(buf);
  free(description);
  free(session_id);
  free(challenge1);
  return h;
}