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); } }
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); }