void CPlayerSession::add_media (CPlayerMedia *m) 
{
  CPlayerMedia *p;
  if (m_my_media == NULL) {
    m_my_media = m;
  } else {
    p = m_my_media;
    while (p->get_next() != NULL) {
      if (p == m) return;
      p = p->get_next();
    }
    p->set_next(m);
  }
}
Example #2
0
void CPlayerSession::display_status (void)
{
  sync_message(LOG_DEBUG, "*******************************************************************");
  sync_message(LOG_DEBUG, "current time "U64, m_current_time);
  CPlayerMedia *p = m_my_media;
  while (p != NULL) {
    p->display_status();
    p = p->get_next();
  }
}
/*
 * Matches a url with the corresponding media. 
 * Return the media, or NULL if no match. 
 */
CPlayerMedia *CPlayerSession::rtsp_url_to_media (const char *url)
{
  CPlayerMedia *p = m_my_media;
  while (p != NULL) {
	rtsp_session_t *session = p->get_rtsp_session();
	if (rtsp_is_url_my_stream(session, url, m_content_base, 
							  m_session_name) == 1) 
	  return p;
    p = p->get_next();
  }
  return (NULL);
}
int CPlayerSession::session_has_video (void)
{
  CPlayerMedia *p;
  p = m_my_media;
  while (p != NULL) {
    if (p->is_video() != FALSE) {
      return (1);
    }
    p = p->get_next();
  }
  return (0);
}
void CPlayerSession::syncronize_rtp_bytestreams (rtcp_sync_t *sync)
{
  if (sync != NULL) {
    m_audio_rtcp_sync = *sync;
    m_have_audio_rtcp_sync = true;
  } else {
    if (!m_have_audio_rtcp_sync) 
      return;
  }
  CPlayerMedia *mptr = m_my_media;
  while (mptr != NULL) {
    if (mptr->is_video()) {
      mptr->syncronize_rtp_bytestreams(&m_audio_rtcp_sync);
    }
    mptr = mptr->get_next();
  }
}
/*
 * set_up_sync_thread.  Creates the sync thread, and a sync class
 * for each media
 */
void CPlayerSession::set_up_sync_thread(void) 
{
  CPlayerMedia *media;

  media = m_my_media;
  while (media != NULL) {
    if (media->is_video()) {
      media->set_video_sync(set_up_video_sync());
    } else {
       media->set_audio_sync(set_up_audio_sync());
    }
    media= media->get_next();
  }
  m_sync_sem = SDL_CreateSemaphore(0);
#ifndef NEED_SDL_VIDEO_IN_MAIN_THREAD
  m_sync_thread = SDL_CreateThread(c_sync_thread, this);
#endif
}
double CPlayerSession::get_max_time (void)
{
  CPlayerMedia *p;
  double max = 0.0;
  p = m_my_media;
  while (p != NULL) {
    double temp = p->get_max_playtime();
    if (temp > max) max = temp;
    p = p->get_next();
  }
  if (max == 0.0 && m_set_end_time) {
    max = (double)
#ifdef _WIN32
		(int64_t)
#endif
		m_end_time;
    max /= 1000.0;
  }
    
  return (max);
}
/*
 * pause_all_media - do a spin loop until the sync thread indicates it's
 * paused.
 */
int CPlayerSession::pause_all_media (void) 
{
  int ret;
  CPlayerMedia *p;
  m_session_state = SESSION_PAUSED;
  if (session_control_is_aggregate()) {
    rtsp_command_t cmd;
    rtsp_decode_t *decode;

    memset(&cmd, 0, sizeof(rtsp_command_t));
    if (rtsp_send_aggregate_pause(m_rtsp_client,
				  m_session_control_url,
				  &cmd,
				  &decode) != 0) {
      player_debug_message("RTSP aggregate pause command failed");
      free_decode_response(decode);
      return (-1);
    }
    free_decode_response(decode);
  }
  p = m_my_media;
  while (p != NULL) {
    ret = p->do_pause();
    if (ret != 0) return (ret);
    p = p->get_next();
  }
  m_sync_pause_done = 0;
  send_sync_thread_a_message(MSG_PAUSE_SESSION);
#ifndef NEED_SDL_VIDEO_IN_MAIN_THREAD
  do {
#endif
    SDL_Delay(100);
#ifndef NEED_SDL_VIDEO_IN_MAIN_THREAD
  } while (m_sync_pause_done == 0);
#endif
  m_paused = 1;
  return (0);
}
CPlayerSession::~CPlayerSession ()
{
  int hadthread = 0;
#ifndef NEED_SDL_VIDEO_IN_MAIN_THREAD
  if (m_sync_thread) {
    send_sync_thread_a_message(MSG_STOP_THREAD);
    SDL_WaitThread(m_sync_thread, NULL);
    m_sync_thread = NULL;
    hadthread = 1;
  }
#else
  send_sync_thread_a_message(MSG_STOP_THREAD);
  hadthread = 1;
#endif



  if (m_streaming_media_set_up != 0 &&
      session_control_is_aggregate()) {
    rtsp_command_t cmd;
    rtsp_decode_t *decode;
    memset(&cmd, 0, sizeof(rtsp_command_t));
    rtsp_send_aggregate_teardown(m_rtsp_client,
				 m_session_control_url,
				 &cmd,
				 &decode);
    free_decode_response(decode);
  }


  if (m_rtsp_client) {
    free_rtsp_client(m_rtsp_client);
    m_rtsp_client = NULL;
  }

  while (m_my_media != NULL) {
    CPlayerMedia *p;
    p = m_my_media;
    m_my_media = p->get_next();
    delete p;
  }  

  if (m_sdp_info) {
    sdp_free_session_desc(m_sdp_info);
    m_sdp_info = NULL;
  }

  if (m_sync_sem) {
    SDL_DestroySemaphore(m_sync_sem);
    m_sync_sem = NULL;
  }

  int quit_sdl = 1;
  if (m_video_sync != NULL) {
    // we need to know if we should quit SDL or not.  If the control
    // code has grabbed the persistence, we don't want to quit
    if (m_video_sync->grabbed_video_persistence() != 0) {
      quit_sdl = 0;
    }
    delete m_video_sync;
    m_video_sync = NULL;
  }

  if (m_audio_sync != NULL) {
    delete m_audio_sync;
    m_audio_sync = NULL;
  }
  if (m_session_name) {
    free((void *)m_session_name);
    m_session_name = NULL;
  }
  if (m_content_base) {
    free((void *) m_content_base);
    m_content_base = NULL;
  }
  for (int ix = 0; ix < SESSION_DESC_COUNT; ix++) {
    if (m_session_desc[ix] != NULL) 
      free((void *)m_session_desc[ix]);
    m_session_desc[ix] = NULL;
  }
  
  if (m_media_close_callback != NULL) {
    m_media_close_callback(m_media_close_callback_data);
  }

  while (m_unused_ports != NULL) {
    CIpPort *first;
    first = m_unused_ports;
    m_unused_ports = first->get_next();
    delete first;
  }
  if (hadthread != 0 && quit_sdl != 0) {
    SDL_Quit();
  }
}
/*
 * play_all_media - get all media to play
 */
int CPlayerSession::play_all_media (int start_from_begin, 
				    double start_time,
				    char *errmsg, 
				    uint32_t errlen)
{
  int ret;
  CPlayerMedia *p;

  if (m_set_end_time == 0) {
    range_desc_t *range;
    if (m_sdp_info && m_sdp_info->session_range.have_range != FALSE) {
      range = &m_sdp_info->session_range;
    } else {
      range = NULL;
      p = m_my_media;
      while (range == NULL && p != NULL) {
	media_desc_t *media;
	media = p->get_sdp_media_desc();
	if (media && media->media_range.have_range) {
	  range = &media->media_range;
	}
	p = p->get_next();
      }
    }
    if (range != NULL) {
      m_end_time = (uint64_t)(range->range_end * 1000.0);
      m_set_end_time = 1;
    }
  }
  p = m_my_media;
  m_session_state = SESSION_BUFFERING;
  if (m_paused == 1 && start_time == 0.0 && start_from_begin == FALSE) {
    /*
     * we were paused.  Continue.
     */
    m_play_start_time = m_current_time;
    start_time = UINT64_TO_DOUBLE(m_current_time);
    start_time /= 1000.0;
    player_debug_message("Restarting at " U64 ", %g", m_current_time, start_time);
  } else {
    /*
     * We might have been paused, but we're told to seek
     */
    // Indicate what time we're starting at for sync task.
    m_play_start_time = (uint64_t)(start_time * 1000.0);
  }
  m_paused = 0;

  send_sync_thread_a_message(MSG_START_SESSION);
  // If we're doing aggregate rtsp, send the play command...

  if (session_control_is_aggregate() &&
      m_dont_send_first_rtsp_play == 0) {
    char buffer[80];
    rtsp_command_t cmd;
    rtsp_decode_t *decode;

    memset(&cmd, 0, sizeof(rtsp_command_t));
    if (m_set_end_time != 0) {
      uint64_t stime = (uint64_t)(start_time * 1000.0);
      sprintf(buffer, "npt="U64"."U64"-"U64"."U64, 
	      stime / 1000, stime % 1000, m_end_time / 1000, m_end_time % 1000);
      cmd.range = buffer;
    }
    if (rtsp_send_aggregate_play(m_rtsp_client,
				 m_session_control_url,
				 &cmd,
				 &decode) != 0) {
      if (errmsg != NULL) {
	snprintf(errmsg, errlen, "RTSP Aggregate Play Error %s-%s", 
		 decode->retcode,
		 decode->retresp != NULL ? decode->retresp : "");
      }
      player_debug_message("RTSP aggregate play command failed");
      free_decode_response(decode);
      return (-1);
    }
    if (decode->rtp_info == NULL) {
      player_error_message("No rtp info field");
    } else {
      player_debug_message("rtp info is \'%s\'", decode->rtp_info);
    }
    int ret = process_rtsp_rtpinfo(decode->rtp_info, this, NULL);
    free_decode_response(decode);
    if (ret < 0) {
      if (errmsg != NULL) {
	snprintf(errmsg, errlen, "RTSP aggregate RtpInfo response failure");
      }
      player_debug_message("rtsp aggregate rtpinfo failed");
      return (-1);
    }
  }
  m_dont_send_first_rtsp_play = 0;

  while (p != NULL) {
    ret = p->do_play(start_time, errmsg, errlen);
    if (ret != 0) return (ret);
    p = p->get_next();
  }
  return (0);
}