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

📄 rtsp_rtp.c

📁 mplayer播放器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  err = select (s + 1, &set, NULL, NULL, &tv);  if (err < 0)  {    mp_msg (MSGT_OPEN, MSGL_ERR, "Select failed: %s\n", strerror (errno));    close (s);    return -1;  }  else if (err == 0)  {    mp_msg (MSGT_OPEN, MSGL_ERR, "Timeout! No data from host %s\n", hostname);    close (s);    return -1;  }    err_len = sizeof (err);  getsockopt (s, SOL_SOCKET, SO_ERROR, &err, (socklen_t *) &err_len);  if (err)  {    mp_msg (MSGT_OPEN, MSGL_ERR, "Socket error: %d\n", err);    close (s);    return -1;  }    return s;}static intis_multicast_address (char *addr){  struct sockaddr_in sin;  if (!addr)    return -1;    sin.sin_family = AF_INET;#ifndef HAVE_WINSOCK2#ifdef USE_ATON    inet_aton (addr, &sin.sin_addr);#else    inet_pton (AF_INET, addr, &sin.sin_addr);#endif#else    sin.sin_addr.s_addr = htonl (INADDR_ANY);#endif    if ((ntohl (sin.sin_addr.s_addr) >> 28) == 0xe)    return 1;  return 0;}struct rtp_rtsp_session_t *rtp_setup_and_play (rtsp_t *rtsp_session){  struct rtp_rtsp_session_t* rtp_session = NULL;  const fsdp_media_description_t *med_dsc = NULL;  char temp_buf[MAX_LENGTH + 1];  char npt[256];  char* answer;  char* sdp;  char *server_addr = NULL;  char *destination = NULL;  int statut;  int content_length = 0;  int is_multicast = 0;    fsdp_description_t *dsc = NULL;  fsdp_error_t result;  int client_rtp_port = -1;  int client_rtcp_port = -1;  int server_rtp_port = -1;  int server_rtcp_port = -1;  int rtp_sock = -1;  int rtcp_sock = -1;  /* 1. send a RTSP DESCRIBE request to server */  rtsp_schedule_field (rtsp_session, RTSP_ACCEPT_SDP);  statut = rtsp_request_describe (rtsp_session, NULL);  if (statut < 200 || statut > 299)    return NULL;  answer = rtsp_search_answers (rtsp_session, RTSP_CONTENT_LENGTH);  if (answer)    content_length = atoi (answer);  else    return NULL;  answer = rtsp_search_answers (rtsp_session, RTSP_CONTENT_TYPE);  if (!answer || !strstr (answer, RTSP_APPLICATION_SDP))    return NULL;  /* 2. read SDP message from server */  sdp = (char *) malloc (content_length + 1);  if (rtsp_read_data (rtsp_session, sdp, content_length) <= 0)  {    free (sdp);    return NULL;  }  sdp[content_length] = 0;    /* 3. parse SDP message */  dsc = fsdp_description_new ();  result = fsdp_parse (sdp, dsc);  if (result != FSDPE_OK)  {    free (sdp);    fsdp_description_delete (dsc);    return NULL;  }  mp_msg (MSGT_OPEN, MSGL_V, "SDP:\n%s\n", sdp);  free (sdp);  /* 4. check for number of media streams: only one is supported */  if (fsdp_get_media_count (dsc) != 1)  {    mp_msg (MSGT_OPEN, MSGL_ERR,            "A single media stream only is supported atm.\n");    fsdp_description_delete (dsc);    return NULL;  }  /* 5. set the Normal Play Time parameter   *    use range provided by server in SDP or start now if empty */  sprintf (npt, RTSP_RANGE);  if (fsdp_get_range (dsc))    strcat (npt, fsdp_get_range (dsc));  else    strcat (npt, RTSP_NPT_NOW);  /* 5. check for a valid media stream */  med_dsc = fsdp_get_media (dsc, 0);  if (!med_dsc)  {    fsdp_description_delete (dsc);    return NULL;  }  /* 6. parse the `m=<media>  <port>  <transport> <fmt list>' line */   /* check for an A/V media */  if (fsdp_get_media_type (med_dsc) != FSDP_MEDIA_VIDEO &&      fsdp_get_media_type (med_dsc) != FSDP_MEDIA_AUDIO)  {    fsdp_description_delete (dsc);    return NULL;  }    /* only RTP/AVP transport method is supported right now */  if (fsdp_get_media_transport_protocol (med_dsc) != FSDP_TP_RTP_AVP)  {    fsdp_description_delete (dsc);    return NULL;  }  /* only MPEG-TS is supported at the moment */  if (!strstr (fsdp_get_media_format (med_dsc, 0),               RTSP_MEDIA_CONTAINER_MPEG_TS))  {    fsdp_description_delete (dsc);    return NULL;  }  /* get client port (if any) advised by server */  client_rtp_port = fsdp_get_media_port (med_dsc);  if (client_rtp_port == -1)  {    fsdp_description_delete (dsc);    return NULL;  }  /* if client_rtp_port = 0 => let client randomly pick one */  if (client_rtp_port == 0)  {    /* TODO: we should check if the port is in use first */    if (rtsp_port)      client_rtp_port = rtsp_port;    else      client_rtp_port = RTSP_DEFAULT_PORT;  }  /* RTCP port generally is RTP port + 1 */  client_rtcp_port = client_rtp_port + 1;    mp_msg (MSGT_OPEN, MSGL_V,          "RTP Port from SDP appears to be: %d\n", client_rtp_port);  mp_msg (MSGT_OPEN, MSGL_V,          "RTCP Port from SDP appears to be: %d\n", client_rtcp_port);  /* 7. parse the `c=<network type> <addr type> <connection address>' line */  /* check for a valid media network type (inet) */  if (fsdp_get_media_network_type (med_dsc) != FSDP_NETWORK_TYPE_INET)  {    /* no control for media: try global one instead */    if (fsdp_get_global_conn_network_type (dsc) != FSDP_NETWORK_TYPE_INET)    {      fsdp_description_delete (dsc);      return NULL;    }  }  /* only IPv4 is supported atm. */  if (fsdp_get_media_address_type (med_dsc) != FSDP_ADDRESS_TYPE_IPV4)  {    /* no control for media: try global one instead */    if (fsdp_get_global_conn_address_type (dsc) != FSDP_ADDRESS_TYPE_IPV4)    {      fsdp_description_delete (dsc);      return NULL;    }  }  /* get the media server address to connect to */  if (fsdp_get_media_address (med_dsc))    server_addr = strdup (fsdp_get_media_address (med_dsc));  else if (fsdp_get_global_conn_address (dsc))  {    /* no control for media: try global one instead */    server_addr = strdup (fsdp_get_global_conn_address (dsc));  }      if (!server_addr)  {    fsdp_description_delete (dsc);    return NULL;  }  /* check for a UNICAST or MULTICAST address to connect to */  is_multicast = is_multicast_address (server_addr);  /* 8. initiate an RTP session */  rtp_session = rtp_session_new ();  if (!rtp_session)  {    free (server_addr);    fsdp_description_delete (dsc);    return NULL;  }  /* get the media control URL */  if (fsdp_get_media_control (med_dsc, 0))    rtp_session->control_url = strdup (fsdp_get_media_control (med_dsc, 0));  fsdp_description_delete (dsc);  if (!rtp_session->control_url)  {    free (server_addr);    rtp_session_free (rtp_session);    return NULL;  }  /* 9. create the payload for RTSP SETUP request */  memset (temp_buf, '\0', MAX_LENGTH);  snprintf (temp_buf, MAX_LENGTH,            RTSP_TRANSPORT_REQUEST,            is_multicast ? RTSP_TRANSPORT_MULTICAST : RTSP_TRANSPORT_UNICAST,            is_multicast ? RTSP_MULTICAST_PORT : RTSP_UNICAST_CLIENT_PORT,            client_rtp_port, client_rtcp_port);  mp_msg (MSGT_OPEN, MSGL_V, "RTSP Transport: %s\n", temp_buf);    rtsp_unschedule_field (rtsp_session, RTSP_SESSION);  rtsp_schedule_field (rtsp_session, temp_buf);  /* 10. check for the media control URL type and initiate RTSP SETUP */  if (!strncmp (rtp_session->control_url, "rtsp://", 7)) /* absolute URL */    statut = rtsp_request_setup (rtsp_session,                                 rtp_session->control_url, NULL);  else /* relative URL */    statut = rtsp_request_setup (rtsp_session,                                 NULL, rtp_session->control_url);      if (statut < 200 || statut > 299)  {    free (server_addr);    rtp_session_free (rtp_session);    return NULL;  }  /* 11. parse RTSP SETUP response: we need it to actually determine   *     the real address and port to connect to */  answer = rtsp_search_answers (rtsp_session, RTSP_TRANSPORT);  if (!answer)  {    free (server_addr);    rtp_session_free (rtp_session);    return NULL;  }  /* check for RTP and RTCP ports to bind according to how request was done */  is_multicast = 0;  if (strstr (answer, RTSP_TRANSPORT_MULTICAST))    is_multicast = 1;  if (is_multicast)    parse_port (answer, RTSP_MULTICAST_PORT,                &client_rtp_port, &client_rtcp_port);  else  {    parse_port (answer, RTSP_UNICAST_CLIENT_PORT,                &client_rtp_port, &client_rtcp_port);    parse_port (answer, RTSP_UNICAST_SERVER_PORT,                &server_rtp_port, &server_rtcp_port);  }  /* now check network settings as determined by server */  if (rtsp_destination)    destination = strdup (rtsp_destination);  else    destination = parse_destination (answer);  if (!destination)    destination = strdup (server_addr);  free (server_addr);  mp_msg (MSGT_OPEN, MSGL_V, "RTSP Destination: %s\n", destination);  mp_msg (MSGT_OPEN, MSGL_V, "Client RTP port : %d\n", client_rtp_port);  mp_msg (MSGT_OPEN, MSGL_V, "Client RTCP port : %d\n", client_rtcp_port);  mp_msg (MSGT_OPEN, MSGL_V, "Server RTP port : %d\n", server_rtp_port);  mp_msg (MSGT_OPEN, MSGL_V, "Server RTCP port : %d\n", server_rtcp_port);  /* 12. performs RTSP PLAY request */  rtsp_schedule_field (rtsp_session, npt);  statut = rtsp_request_play (rtsp_session, NULL);  if (statut < 200 || statut > 299)  {    free (destination);    rtp_session_free (rtp_session);    return NULL;  }  /* 13. create RTP and RTCP connections */  rtp_sock = rtp_connect (destination, client_rtp_port);  rtcp_sock = rtcp_connect (client_rtcp_port, server_rtcp_port, destination);  rtp_session_set_fd (rtp_session, rtp_sock, rtcp_sock);  free (destination);  mp_msg (MSGT_OPEN, MSGL_V, "RTP Sock : %d\nRTCP Sock : %d\n",          rtp_session->rtp_socket, rtp_session->rtcp_socket);  if (rtp_session->rtp_socket == -1)  {    rtp_session_free (rtp_session);    return NULL;  }  return rtp_session;}

⌨️ 快捷键说明

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