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

📄 player_media.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  }
  if (m_audio_sync == NULL) return -1;

  m_audio_info = audio;
  m_plugin = p;
  m_plugin_data = (p->ac_create)(sdp_media,
				 audio,
				 user_data,
				 userdata_size,
				 get_audio_vft(),
				 m_audio_sync);
  if (m_plugin_data == NULL) return -1;

  if (user_data != NULL)
    set_user_data(user_data, userdata_size);
  return 0;
}

/*
 * CPlayerMedia::do_play - get play command
 */
int CPlayerMedia::do_play (double start_time_offset)
{

  if (m_streaming != 0) {
    if (m_stream_ondemand != 0) {
      /*
       * We're streaming - send the RTSP play command
       */
      if (m_parent->session_control_is_aggregate() == 0) {
	char buffer[80];
	rtsp_command_t cmd;
	rtsp_decode_t *decode;
	range_desc_t *range;
	memset(&cmd, 0, sizeof(rtsp_command_t));

	// only do range if we're not paused
	range = get_range_from_media(m_media_info);
	if (range == NULL) {
	  return (-1);
	}
	if (start_time_offset < range->range_start || 
	    start_time_offset > range->range_end) 
	  start_time_offset = range->range_start;
	// need to check for smpte
	sprintf(buffer, "npt=%g-%g", start_time_offset, range->range_end);
	cmd.range = buffer;

	if (rtsp_send_play(m_rtsp_session, &cmd, &decode) != 0) {
	  media_message(LOG_ERR, "RTSP play command failed");
	  free_decode_response(decode);
	  return (-1);
	}

	/*
	 * process the return information
	 */
	int ret = process_rtsp_rtpinfo(decode->rtp_info, m_parent, this);
	if (ret < 0) {
	  media_message(LOG_ERR, "rtsp rtpinfo failed");
	  free_decode_response(decode);
	  return (-1);
	}
	free_decode_response(decode);
      }
      if (m_source_addr == NULL) {
	// get the ip address of the server from the rtsp stack
	m_source_addr = strdup(inet_ntoa(get_server_ip_address(m_rtsp_session)));
	media_message(LOG_INFO, "Setting source address from rtsp - %s", 
		      m_source_addr);
      }
      // ASDF - probably need to do some stuff here for no rtpinfo...
      /*
       * set the various play times, and send a message to the recv task
       * that it needs to start
       */
      m_play_start_time = start_time_offset;
      if (m_rtp_byte_stream != NULL) {
	m_rtp_byte_stream->set_start_time((uint64_t)(start_time_offset * 1000.0));
      }
    }
    m_paused = 0;
    if (m_rtp_use_rtsp) {
      rtsp_thread_perform_callback(m_parent->get_rtsp_client(),
				   c_rtp_start, 
				   this);
    } else {
      m_rtp_msg_queue.send_message(MSG_START_SESSION);
    }
  } else {
    /*
     * File (or other) playback.
     */
    if (m_paused == 0 || start_time_offset == 0.0) {
      m_byte_stream->reset();
    }
    m_byte_stream->set_start_time((uint64_t)(start_time_offset * 1000.0));
    m_play_start_time = start_time_offset;
    m_paused = 0;
    start_decoding();
  }
  return (0);
}

/*
 * CPlayerMedia::do_pause - stop what we're doing
 */
int CPlayerMedia::do_pause (void)
{

  if (m_streaming != 0) {
    if (m_stream_ondemand != 0) {
      /*
     * streaming - send RTSP pause
     */
      if (m_parent->session_control_is_aggregate() == 0) {
	rtsp_command_t cmd;
	rtsp_decode_t *decode;
	memset(&cmd, 0, sizeof(rtsp_command_t));

	if (rtsp_send_pause(m_rtsp_session, &cmd, &decode) != 0) {
	  media_message(LOG_ERR, "RTSP play command failed");
	  free_decode_response(decode);
	  return (-1);
	}
	free_decode_response(decode);
      }
    }
    m_rtp_msg_queue.send_message(MSG_PAUSE_SESSION);
    if (m_rtp_byte_stream) m_rtp_byte_stream->reset();
  }
  
  /*
   * Pause the various threads
   */
  m_decode_msg_queue.send_message(MSG_PAUSE_SESSION, 
				  NULL, 
				  0, 
				  m_decode_thread_sem);
  m_paused = 1;
  return (0);
}

double CPlayerMedia::get_max_playtime (void) 
{
  if (m_byte_stream) {
    return (m_byte_stream->get_max_playtime());
  }
  return (0.0);
}

/***************************************************************************
 * Transport and RTP-Info RTSP header line parsing.
 ***************************************************************************/
#define ADV_SPACE(a) {while (isspace(*(a)) && (*(a) != '\0'))(a)++;}

#define TTYPE(a,b) {a, sizeof(a), b}

static char *transport_parse_unicast (char *transport, CPlayerMedia *m)
{
  ADV_SPACE(transport);
  if (*transport == '\0') return (transport);

  if (*transport != ';')
    return (NULL);
  transport++;
  ADV_SPACE(transport);
  return (transport);
}

static char *transport_parse_multicast (char *transport, CPlayerMedia *m)
{
  media_message(LOG_ERR,"Received multicast indication during SETUP");
  return (NULL);
}

static char *convert_number (char *transport, uint32_t &value)
{
  value = 0;
  while (isdigit(*transport)) {
    value *= 10;
    value += *transport - '0';
    transport++;
  }
  return (transport);
}

static char *convert_hex (char *transport, uint32_t &value)
{
  value = 0;
  while (isxdigit(*transport)) {
    value *= 16;
    if (isdigit(*transport))
      value += *transport - '0';
    else
      value += tolower(*transport) - 'a' + 10;
    transport++;
  }
  return (transport);
}

static char *transport_parse_client_port (char *transport, CPlayerMedia *m)
{
  uint32_t port;
  uint16_t our_port, our_port_max;
  if (*transport++ != '=') {
    return (NULL);
  }
  ADV_SPACE(transport);
  transport = convert_number(transport, port);
  ADV_SPACE(transport);
  our_port = m->get_our_port();
  our_port_max = our_port + 1;

  if (port != our_port) {
    media_message(LOG_ERR, "Returned client port %u doesn't match sent %u",
		  port, our_port);
    return (NULL);
  }
  if (*transport == ';') {
    transport++;
    return (transport);
  }
  if (*transport == '\0') {
    return (transport);
  }
  if (*transport != '-') {
    return (NULL);
  }
  transport++;
  ADV_SPACE(transport);
  transport = convert_number(transport, port);
  if ((port < our_port) || 
      (port > our_port_max)) {
    media_message(LOG_ERR, "Illegal client to port %u, range %u to %u",
			 port, our_port, our_port_max);
    return (NULL);
  }
  ADV_SPACE(transport);
  if (*transport == ';') {
    transport++;
  }
  return(transport);
}

static char *transport_parse_server_port (char *transport, CPlayerMedia *m)
{
  uint32_t fromport, toport;

  if (*transport++ != '=') {
    return (NULL);
  }
  ADV_SPACE(transport);
  transport = convert_number(transport, fromport);
  ADV_SPACE(transport);

  m->set_server_port((uint16_t)fromport);

  if (*transport == ';') {
    transport++;
    return (transport);
  }
  if (*transport == '\0') {
    return (transport);
  }
  if (*transport != '-') {
    return (NULL);
  }
  transport++;
  ADV_SPACE(transport);
  transport = convert_number(transport, toport);
  if (toport < fromport || toport > fromport + 1) {
    media_message(LOG_ERR, "Illegal server to port %u, from is %u",
			 toport, fromport);
    return (NULL);
  }
  ADV_SPACE(transport);
  if (*transport == ';') {
    transport++;
  }
  return(transport);
}

static char *transport_parse_source (char *transport, CPlayerMedia *m)
{
  char *ptr, *newone;
  uint32_t addrlen;

  if (*transport != '=') {
    return (NULL);
  }
  transport++;
  ADV_SPACE(transport);
  ptr = transport;
  while (*transport != ';' && *transport != '\0') transport++;
  addrlen = transport - ptr;
  if (addrlen == 0) {
    return (NULL);
  }
  newone = (char *)malloc(addrlen + 1);
  if (newone == NULL) {
    media_message(LOG_ERR, "Can't alloc memory for transport source");
    return (NULL);
  }
  strncpy(newone, ptr, addrlen);
  newone[addrlen] = '\0';
  m->set_source_addr(newone);
  if (*transport == ';') transport++;
  return (transport);
}

static char *transport_parse_ssrc (char *transport, CPlayerMedia *m)
{
  uint32_t ssrc;
  if (*transport != '=') {
    return (NULL);
  }
  transport++;
  ADV_SPACE(transport);
  transport = convert_hex(transport, ssrc);
  ADV_SPACE(transport);
  if (*transport != '\0') {
    if (*transport != ';') {
      return (NULL);
    }
    transport++;
  }
  m->set_rtp_ssrc(ssrc);
  return (transport);
}

static char *transport_parse_interleave (char *transport, CPlayerMedia *m)
{
  uint32_t chan, chan2;
  if (*transport != '=') {
    return (NULL);
  }
  transport++;
  ADV_SPACE(transport);
  transport = convert_number(transport, chan);
  chan2 = m->get_rtp_media_number() * 2;
  if (chan != chan2) {
    media_message(LOG_ERR, "Transport interleave not what was requested %d %d", 
			 chan, chan2);
    return NULL;
  }
  ADV_SPACE(transport);
  if (*transport != '\0') {
    if (*transport != '-') {
      return (NULL);
    }
    transport++;
    transport = convert_number(transport, chan2);
    if (chan + 1 != chan2) {
      media_message(LOG_ERR, "Error in transport interleaved field");
      return (NULL);
    }
    
    if (*transport == '\0') return (transport);
  }
  if (*transport != ';') return (NULL);
  transport++;
  return (transport);
}

static char *rtpinfo_parse_ssrc (char *transport, CPlayerMedia *m, int &end)
{
  uint32_t ssrc;
  if (*transport != '=') {
    return (NULL);
  }
  transport++;
  ADV_SPACE(transport);
  transport = convert_hex(transport, ssrc);
  ADV_SPACE(transport);
  if (*transport != '\0') {
    if (*transport == ',') {
      end = 1;
    } else if (*transport != ';') {
      return (NULL);
    }
    transport++;
  }
  m->set_rtp_ssrc(ssrc);
  return (transport);
}

static char *rtpinfo_parse_seq (char *rtpinfo, CPlayerMedia *m, int &endofurl)
{
  uint32_t seq;
  if (*rtpinfo != '=') {
    return (NULL);
  }
  rtpinfo++;
  ADV_SPACE(rtpinfo);
  rtpinfo = convert_number(rtpinfo, seq);
  ADV_SPACE(rtpinfo);
  if (*rtpinfo != '\0') {
    if (*rtpinfo == ',') {
      endofurl = 1;
    } else if (*rtpinfo != ';') {
      return (NULL);
    }
    rtpinfo++;
  }
  m->set_rtp_base_seq(seq);
  return (rtpinfo);
}

static char *rtpinfo_parse_rtptime (char *rtpinfo, 
				    CPlayerMedia *m, 
				    int &endofurl)
{
  uint32_t rtptime;
  int neg = 0;
  if (*rtpinfo != '=') {
    return (NULL);
  }
  rtpinfo++;
  ADV_SPACE(rtpinfo);
  if (*rtpinfo == '-') {
    neg = 1;
    rtpinfo++;
    ADV_SPACE(rtpinfo);
  }
  rtpinfo = convert_number(rtpinfo, rtptime);
  ADV_SPACE(rtpinfo);
  if (*rtpinfo != '\0') {
    if (*rtpinfo == ',') {
      endofurl = 1;
    } else if (*rtpinfo != ';') {
      return (NULL);
    }
    rtpinfo++;
  }
  if (neg != 0) {
    player_error_message("Warning - negative time returned in rtpinfo");
    rtptime = 0 - rtptime;
  }
  m->set_rtp_base_ts(rtptime);
  return (rtpinfo);
}
struct {
  const char *name;
  uint32_t namelen;
  char *(*routine)(char *transport, CPlayerMedia *);
} transport_types[] = 
{
  TTYPE("unicast", transport_parse_unicast),
  TTYPE("multicast", transport_parse_multicast),
  TTYPE("client_port", transport_parse_client_port),
  TTYPE("server_port", transport_parse_server_port),
  TTYPE("source", transport_parse_source),
  TTYPE("ssrc", transport_parse_ssrc),
  TTYPE("interleaved", transport_parse_interleave),
  {NULL, 0, NULL},
}; 

int CPlayerMedia::process_rtsp_transport (char *transport)
{
  uint32_t protolen;
  int ix;

  if (transport == NULL) 
    return (-1);

  protolen = strlen(m_media_info->proto);
  
  if (strncasecmp(transport, m_media_info->proto, protolen) != 0) {
    media_message(LOG_ERR, "transport %s doesn't match %s", transport, 
			 m_media_info->proto);
    return (-1);
  }
  transport += protolen;
  if (*transport == '/') {
    transport++;
    if (m_rtp_use_rtsp) {
      if (strncasecmp(transport, "TCP", strlen("TCP")) != 0) {
	media_message(LOG_ERR, "Transport is not TCP");
	return (-1);
      }
      transport += strlen("TCP");
    } else {
      if (strncasecmp(transport, "UDP", strlen("UDP")) != 0) {
	media_message(LOG_ERR, "Transport is not UDP");
	return (-1);
      }
      transport += strlen("UDP");
    }
  }
  if (*transport != ';') {
    return (-1);
  }
  transport++;
  do {
    ADV_SPACE(transport);
    for (ix = 0; transport_types[ix].name != NULL; ix++) {

⌨️ 快捷键说明

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