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(); } }
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); }
/* * 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); }
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::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); }
static int create_mpeg3_audio (audio_query_t * aq, mpeg2ps_t *afile, CPlayerSession *psptr, int &sdesc) { CPlayerMedia *mptr; codec_plugin_t *plugin; int ret; plugin = check_for_audio_codec(STREAM_TYPE_MPEG_FILE, NULL, NULL, aq->type, -1, NULL, 0, &config); if (plugin == NULL) { psptr->set_message("Can't find plugin for mpeg audio format %s", mpeg2ps_get_audio_stream_name(afile, aq->track_id)); return 0; } mptr = new CPlayerMedia(psptr, AUDIO_SYNC); if (mptr == NULL) { psptr->set_message("Could not create video media"); return -1; } audio_info_t *ainfo; ainfo = MALLOC_STRUCTURE(audio_info_t); ainfo->freq = aq->sampling_freq; ainfo->chans = aq->chans; ainfo->bitspersample = 16; char buffer[80]; snprintf(buffer, 80, "%s Audio, %d, %d channels", mpeg2ps_get_audio_stream_name(afile, aq->track_id), ainfo->freq, ainfo->chans); psptr->set_session_desc(sdesc, buffer); sdesc++; ret = mptr->create_audio_plugin(plugin, aq->stream_type, aq->compressor, aq->type, aq->profile, NULL, ainfo, NULL, 0); if (ret < 0) { mpeg3f_message(LOG_ERR, "Failed to create audio plugin"); psptr->set_message("Failed to create audio plugin"); free(ainfo); delete mptr; return -1; } CMpeg3AudioByteStream *abyte; abyte = new CMpeg3AudioByteStream(afile, aq->track_id); if (abyte == NULL) { psptr->set_message("Failed to create audio bytestream"); return -1; } ret = mptr->create_media("audio", abyte); if (ret != 0) { psptr->set_message("Couldn't create audio media"); return -1; } return 1; }
/* * Create the media for the quicktime file, and set up some session stuff. */ int create_media_for_avi_file (CPlayerSession *psptr, const char *name, char *errmsg, uint32_t errlen, int have_audio_driver, control_callback_vft_t *cc_vft) { CAviFile *Avifile1 = NULL; avi_t *avi; CPlayerMedia *mptr; avi = AVI_open_input_file(name, 1); if (avi == NULL) { snprintf(errmsg, errlen, "%s", AVI_strerror()); player_error_message("%s", AVI_strerror()); return (-1); } int video_count = 1; codec_plugin_t *plugin; video_query_t vq; const char *codec_name = AVI_video_compressor(avi); player_debug_message("Trying avi video codec %s", codec_name); plugin = check_for_video_codec(STREAM_TYPE_AVI_FILE, codec_name, NULL, -1, -1, NULL, 0, &config); if (plugin == NULL) { video_count = 0; } else { vq.track_id = 1; vq.stream_type = STREAM_TYPE_AVI_FILE; vq.compressor = codec_name; vq.type = -1; vq.profile = -1; vq.fptr = NULL; vq.h = AVI_video_height(avi); vq.w = AVI_video_width(avi); vq.frame_rate = AVI_video_frame_rate(avi); vq.config = NULL; vq.config_len = 0; vq.enabled = 0; vq.reference = NULL; } int have_audio = 0; int audio_count = 0; audio_query_t aq; if (AVI_audio_bytes(avi) != 0) { have_audio = 1; plugin = check_for_audio_codec(STREAM_TYPE_AVI_FILE, NULL, NULL, AVI_audio_format(avi), -1, NULL, 0, &config); if (plugin != NULL) { audio_count = 1; aq.track_id = 1; aq.stream_type = STREAM_TYPE_AVI_FILE; aq.compressor = NULL; aq.type = AVI_audio_format(avi); aq.profile = -1; aq.fptr = NULL; aq.sampling_freq = AVI_audio_rate(avi); aq.chans = AVI_audio_channels(avi); aq.config = NULL; aq.config_len = 0; aq.enabled = 0; aq.reference = NULL; } } if (cc_vft != NULL && cc_vft->media_list_query != NULL) { (cc_vft->media_list_query)(psptr, video_count, &vq, audio_count, &aq); } else { if (video_count != 0) vq.enabled = 1; if (audio_count != 0) aq.enabled = 1; } if ((video_count == 0 || vq.enabled == 0) && (audio_count == 0 || aq.enabled == 0)) { snprintf(errmsg, errlen, "No audio or video tracks enabled or playable"); AVI_close(avi); return -1; } Avifile1 = new CAviFile(name, avi, vq.enabled, audio_count); psptr->set_media_close_callback(close_avi_file, Avifile1); if (video_count != 0 && vq.enabled) { mptr = new CPlayerMedia(psptr); if (mptr == NULL) { return (-1); } video_info_t *vinfo = MALLOC_STRUCTURE(video_info_t); if (vinfo == NULL) return (-1); vinfo->height = vq.h; vinfo->width = vq.w; player_debug_message("avi file h %d w %d frame rate %g", vinfo->height, vinfo->width, vq.frame_rate); plugin = check_for_video_codec(STREAM_TYPE_AVI_FILE, codec_name, NULL, -1, -1, NULL, 0, &config); int ret; ret = mptr->create_video_plugin(plugin, STREAM_TYPE_AVI_FILE, codec_name, -1, -1, NULL, vinfo, NULL, 0); if (ret < 0) { snprintf(errmsg, errlen, "Failed to create video plugin %s", codec_name); player_error_message("Failed to create plugin data"); delete mptr; return -1; } CAviVideoByteStream *vbyte = new CAviVideoByteStream(Avifile1); if (vbyte == NULL) { delete mptr; return (-1); } vbyte->config(AVI_video_frames(avi), vq.frame_rate); ret = mptr->create(vbyte, TRUE, errmsg, errlen); if (ret != 0) { return (-1); } } int seekable = 1; if (have_audio_driver > 0 && audio_count > 0 && aq.enabled != 0) { plugin = check_for_audio_codec(STREAM_TYPE_AVI_FILE, NULL, NULL, aq.type, -1, NULL, 0, &config); CAviAudioByteStream *abyte; mptr = new CPlayerMedia(psptr); if (mptr == NULL) { return (-1); } audio_info_t *ainfo; ainfo = MALLOC_STRUCTURE(audio_info_t); ainfo->freq = aq.sampling_freq; ainfo->chans = aq.chans; ainfo->bitspersample = AVI_audio_bits(avi); int ret; ret = mptr->create_audio_plugin(plugin, aq.stream_type, aq.compressor, aq.type, aq.profile, NULL, ainfo, NULL, 0); if (ret < 0) { delete mptr; player_error_message("Couldn't create audio from plugin %s", plugin->c_name); return -1; } abyte = new CAviAudioByteStream(Avifile1); ret = mptr->create(abyte, FALSE, errmsg, errlen); if (ret != 0) { return (-1); } seekable = 0; } psptr->session_set_seekable(seekable); if (audio_count == 0 && have_audio != 0) { snprintf(errmsg, errlen, "Unknown Audio Codec in avi file "); return (1); } if (video_count != 1) { snprintf(errmsg, errlen, "Unknown Video Codec %s in avi file", codec_name); return (1); } return (0); }
int CMpeg2tFile::create_audio (CPlayerSession *psptr, mpeg2t_t *decoder, audio_query_t *aq, uint audio_offset, int &sdesc) { uint ix; CPlayerMedia *mptr; codec_plugin_t *plugin; int created = 0; for (ix = 0; ix < audio_offset; ix++) { mpeg2t_pid_t *pidptr; mpeg2t_es_t *es_pid; pidptr = mpeg2t_lookup_pid(decoder,aq[ix].track_id); if (pidptr->pak_type != MPEG2T_ES_PAK) { mpeg2f_message(LOG_CRIT, "mpeg2t video type is not es pak - pid %x", aq[ix].track_id); exit(1); } es_pid = (mpeg2t_es_t *)pidptr; if (aq[ix].enabled != 0 && created == 0) { created = 1; mptr = new CPlayerMedia(psptr, AUDIO_SYNC); if (mptr == NULL) { return (-1); } audio_info_t *ainfo; ainfo = MALLOC_STRUCTURE(audio_info_t); ainfo->freq = aq[ix].sampling_freq; ainfo->chans = aq[ix].chans; ainfo->bitspersample = 0; plugin = check_for_audio_codec(STREAM_TYPE_MPEG2_TRANSPORT_STREAM, NULL, NULL, aq[ix].type, aq[ix].profile, aq[ix].config, aq[ix].config_len, &config); int ret = mptr->create_audio_plugin(plugin, STREAM_TYPE_MPEG2_TRANSPORT_STREAM, NULL, aq[ix].type, aq[ix].profile, NULL, // sdp info ainfo, // video info aq[ix].config, aq[ix].config_len); if (ret < 0) { mpeg2f_message(LOG_ERR, "Failed to create plugin data"); psptr->set_message("Failed to start plugin"); delete mptr; return -1; } CMpeg2fAudioByteStream *abyte; abyte = new CMpeg2fAudioByteStream(this, es_pid); if (abyte == NULL) { mpeg2f_message(LOG_CRIT, "failed to create byte stream"); delete mptr; return (-1); } ret = mptr->create_media("audio", abyte, false); if (ret != 0) { mpeg2f_message(LOG_CRIT, "failed to create from file"); return (-1); } if (es_pid->info_loaded) { char buffer[80]; if (mpeg2t_write_stream_info(es_pid, buffer, 80) >= 0) { psptr->set_session_desc(sdesc, buffer); sdesc++; } } mpeg2t_set_frame_status(es_pid, MPEG2T_PID_SAVE_FRAME); } else { mpeg2t_set_frame_status(es_pid, MPEG2T_PID_NOTHING); } } return created; }
int CMpeg2tFile::create_video (CPlayerSession *psptr, mpeg2t_t *decoder, video_query_t *vq, uint video_offset, int &sdesc) { uint ix; CPlayerMedia *mptr; codec_plugin_t *plugin; int created = 0; // Loop through the vq structure, and set up a new player media for (ix = 0; ix < video_offset; ix++) { mpeg2t_pid_t *pidptr; mpeg2t_es_t *es_pid; pidptr = mpeg2t_lookup_pid(decoder,vq[ix].track_id); if (pidptr->pak_type != MPEG2T_ES_PAK) { mpeg2f_message(LOG_CRIT, "mpeg2t video type is not es pak - pid %x", vq[ix].track_id); exit(1); } es_pid = (mpeg2t_es_t *)pidptr; if (vq[ix].enabled != 0 && created == 0) { created = 1; mptr = new CPlayerMedia(psptr, VIDEO_SYNC); if (mptr == NULL) { return (-1); } video_info_t *vinfo; vinfo = MALLOC_STRUCTURE(video_info_t); vinfo->height = vq[ix].h; vinfo->width = vq[ix].w; plugin = check_for_video_codec(STREAM_TYPE_MPEG2_TRANSPORT_STREAM, NULL, NULL, vq[ix].type, vq[ix].profile, vq[ix].config, vq[ix].config_len, &config); int ret = mptr->create_video_plugin(plugin, STREAM_TYPE_MPEG2_TRANSPORT_STREAM, NULL, vq[ix].type, vq[ix].profile, NULL, // sdp info vinfo, // video info vq[ix].config, vq[ix].config_len); if (ret < 0) { mpeg2f_message(LOG_ERR, "Failed to create plugin data"); psptr->set_message("Failed to start plugin"); delete mptr; return -1; } CMpeg2fVideoByteStream *vbyte; vbyte = new CMpeg2fVideoByteStream(this, es_pid); if (vbyte == NULL) { mpeg2f_message(LOG_CRIT, "failed to create byte stream"); delete mptr; return (-1); } ret = mptr->create_media("video", vbyte, false); if (ret != 0) { mpeg2f_message(LOG_CRIT, "failed to create from file"); return (-1); } if (es_pid->info_loaded) { char buffer[80]; if (mpeg2t_write_stream_info(es_pid, buffer, 80) >= 0) { psptr->set_session_desc(sdesc, buffer); sdesc++; } } mpeg2t_set_frame_status(es_pid, MPEG2T_PID_SAVE_FRAME); } else { mpeg2t_set_frame_status(es_pid, MPEG2T_PID_NOTHING); } } return created; }
static int create_media_from_sdp (CPlayerSession *psptr, session_desc_t *sdp, char *errmsg, uint32_t errlen, int have_audio_driver, int broadcast, int only_check_first, control_callback_vft_t *cc_vft) { int err; int media_count = 0; int invalid_count = 0; int have_audio_but_no_driver = 0; char buffer[80]; codec_plugin_t *codec; format_list_t *fmt; int audio_count, video_count; int audio_offset, video_offset; int ix; if (sdp->session_name != NULL) { snprintf(buffer, sizeof(buffer), "Name: %s", sdp->session_name); psptr->set_session_desc(0, buffer); } if (sdp->session_desc != NULL) { snprintf(buffer, sizeof(buffer), "Description: %s", sdp->session_desc); psptr->set_session_desc(1, buffer); } #ifndef _WIN32 if (sdp->media != NULL && sdp->media->next == NULL && strcasecmp(sdp->media->media, "video") == 0 && sdp->media->fmt != NULL && strcmp(sdp->media->fmt->fmt, "33") == 0) { // we have a mpeg2 transport stream return (create_mpeg2t_session(psptr, NULL, sdp, errmsg, errlen, have_audio_driver, cc_vft)); } #endif media_desc_t *sdp_media; audio_count = video_count = 0; for (sdp_media = psptr->get_sdp_info()->media; sdp_media != NULL; sdp_media = sdp_media->next) { if (strcasecmp(sdp_media->media, "audio") == 0) { if (have_audio_driver == 0) { have_audio_but_no_driver = 1; } else { audio_count++; } } else if (strcasecmp(sdp_media->media, "video") == 0) { video_count++; } } video_query_t *vq; audio_query_t *aq; if (video_count > 0) { vq = (video_query_t *)malloc(sizeof(video_query_t) * video_count); } else { vq = NULL; } if (audio_count > 0) { aq = (audio_query_t *)malloc(sizeof(audio_query_t) * audio_count); } else { aq = NULL; } video_offset = audio_offset = 0; for (sdp_media = psptr->get_sdp_info()->media; sdp_media != NULL; sdp_media = sdp_media->next) { if (have_audio_driver != 0 && strcasecmp(sdp_media->media, "audio") == 0) { fmt = sdp_media->fmt; codec = NULL; while (codec == NULL && fmt != NULL) { codec = check_for_audio_codec(STREAM_TYPE_RTP, NULL, fmt, -1, -1, NULL, 0, &config); if (codec == NULL) { if (only_check_first != 0) fmt = NULL; else fmt = fmt->next; } } if (codec == NULL) { invalid_count++; continue; } else { // set up audio qualifier aq[audio_offset].track_id = audio_offset; aq[audio_offset].stream_type = STREAM_TYPE_RTP; aq[audio_offset].compressor = NULL; aq[audio_offset].type = -1; aq[audio_offset].profile = -1; aq[audio_offset].fptr = fmt; aq[audio_offset].sampling_freq = -1; aq[audio_offset].chans = -1; aq[audio_offset].enabled = 0; aq[audio_offset].reference = NULL; audio_offset++; } } else if (strcasecmp(sdp_media->media, "video") == 0) { fmt = sdp_media->fmt; codec = NULL; while (codec == NULL && fmt != NULL) { codec = check_for_video_codec(STREAM_TYPE_RTP, NULL, fmt, -1, -1, NULL, 0, &config); if (codec == NULL) { if (only_check_first != 0) fmt = NULL; else fmt = fmt->next; } } if (codec == NULL) { invalid_count++; continue; } else { vq[video_offset].track_id = video_offset; vq[video_offset].stream_type = STREAM_TYPE_RTP; vq[video_offset].compressor = NULL; vq[video_offset].type = -1; vq[video_offset].profile = -1; vq[video_offset].fptr = fmt; vq[video_offset].h = -1; vq[video_offset].w = -1; vq[video_offset].frame_rate = -1; vq[video_offset].enabled = 0; vq[video_offset].reference = NULL; video_offset++; } } else { player_error_message("Skipping media type `%s\'", sdp_media->media); continue; } } // okay - from here, write the callback call, and go ahead... if (cc_vft != NULL && cc_vft->media_list_query != NULL) { (cc_vft->media_list_query)(psptr, video_offset, vq, audio_offset, aq); } else { if (video_offset > 0) { vq[0].enabled = 1; } if (audio_offset > 0) { aq[0].enabled = 1; } } for (ix = 0; ix < video_offset; ix++) { if (vq[ix].enabled != 0) { CPlayerMedia *mptr = new CPlayerMedia(psptr); err = mptr->create_streaming(vq[ix].fptr->media, errmsg, errlen, broadcast, config.get_config_value(CONFIG_USE_RTP_OVER_RTSP), media_count); if (err < 0) { return (-1); } if (err > 0) { delete mptr; } else media_count++; } } for (ix = 0; ix < audio_offset; ix++) { if (aq[ix].enabled != 0) { CPlayerMedia *mptr = new CPlayerMedia(psptr); err = mptr->create_streaming(aq[ix].fptr->media, errmsg, errlen, broadcast, config.get_config_value(CONFIG_USE_RTP_OVER_RTSP), media_count); if (err < 0) { return (-1); } if (err > 0) { delete mptr; } else media_count++; } } if (aq != NULL) free(aq); if (vq != NULL) free(vq); if (media_count == 0) { snprintf(errmsg, errlen, "No known codecs found in SDP"); return (-1); } psptr->streaming_media_set_up(); if (have_audio_but_no_driver > 0) { snprintf(errmsg, errlen, "Not playing audio codecs - no driver"); return (1); } if (invalid_count > 0) { snprintf(errmsg, errlen, "There were unknowns codecs during decode - playing valid ones"); return (1); } return (0); }
int CMp4File::create_audio(CPlayerSession *psptr, audio_query_t *aq, uint audio_offset, uint &start_desc) { uint ix; uint64_t IVLength; CPlayerMedia *mptr; codec_plugin_t *plugin; for (ix = 0; ix < audio_offset; ix++) { if (aq[ix].enabled != 0) { CMp4AudioByteStream *abyte; mptr = new CPlayerMedia(psptr, AUDIO_SYNC); if (mptr == NULL) { return (-1); } /* check if ismacryp */ uint32_t verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); if (MP4IsIsmaCrypMediaTrack(m_mp4file, aq[ix].track_id)) { MP4GetTrackIntegerProperty(m_mp4file, aq[ix].track_id, "mdia.minf.stbl.stsd.enca.sinf.schi.iSFM.IV-length", &IVLength); abyte = new CMp4EncAudioByteStream(this, aq[ix].track_id, IVLength); } else { abyte = new CMp4AudioByteStream(this, aq[ix].track_id); } MP4SetVerbosity(m_mp4file, verb); audio_info_t *ainfo; ainfo = (audio_info_t *)malloc(sizeof(audio_info_t)); memset(ainfo, 0, sizeof(*ainfo)); ainfo->freq = aq[ix].sampling_freq; if (aq[ix].chans != -1) { ainfo->chans = aq[ix].chans; } if ((aq[ix].type == MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE) || (aq[ix].type == MP4_PCM16_BIG_ENDIAN_AUDIO_TYPE)) { ainfo->bitspersample = 16; } int ret; plugin = check_for_audio_codec(STREAM_TYPE_MP4_FILE, aq[ix].compressor, // media_data field NULL, aq[ix].type, aq[ix].profile, aq[ix].config, aq[ix].config_len, &config); ret = mptr->create_audio_plugin(plugin, STREAM_TYPE_MP4_FILE, aq[ix].compressor, aq[ix].type, aq[ix].profile, NULL, // sdp info ainfo, // audio info aq[ix].config, aq[ix].config_len); if (ret < 0) { mp4f_message(LOG_ERR, "Couldn't create audio from plugin %s", plugin->c_name); psptr->set_message("Couldn't start audio plugin %s", plugin->c_name); delete mptr; delete abyte; return -1; } ret = mptr->create_media("audio", abyte); if (ret != 0) { return (-1); } MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); char *mp4info = MP4Info(m_mp4file, aq[ix].track_id); MP4SetVerbosity(m_mp4file, verb); char *temp = mp4info; while (*temp != '\0') { if (isspace(*temp)) *temp = ' '; if (!isprint(*temp)) *temp = '*'; temp++; } psptr->set_session_desc(start_desc, mp4info); free(mp4info); start_desc++; } else { if (aq[ix].config != NULL) free((void *)aq[ix].config); } } return 0; }
/* * 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); }
static int create_mpeg3_video (video_query_t *vq, mpeg2ps_t *vfile, CPlayerSession *psptr, int &sdesc) { CPlayerMedia *mptr; codec_plugin_t *plugin; int ret; plugin = check_for_video_codec(STREAM_TYPE_MPEG_FILE, "mp2v", NULL, vq->type, -1, NULL, 0, &config); if (plugin == NULL) { psptr->set_message("Can't find plugin for mpeg video"); return 0; } mptr = new CPlayerMedia(psptr, VIDEO_SYNC); if (mptr == NULL) { psptr->set_message("Could not create video media"); return -1; } video_info_t *vinfo; vinfo = MALLOC_STRUCTURE(video_info_t); vinfo->height = vq->h; vinfo->width = vq->w; char buffer[80]; int bitrate; char *name = mpeg2ps_get_video_stream_name(vfile, vq->track_id); ret = snprintf(buffer, 80, "%s Video, %d x %d", name, vinfo->width, vinfo->height); free(name); if (vq->frame_rate != 0.0) { ret += snprintf(buffer + ret, 80 - ret, ", %g", vq->frame_rate); } bitrate = (int)(mpeg2ps_get_video_stream_bitrate(vfile, vq->track_id) / 1000.0); if (bitrate > 0) { snprintf(buffer + ret, 80 - ret, ", %d kbps", bitrate); } psptr->set_session_desc(sdesc, buffer); sdesc++; mpeg3f_message(LOG_DEBUG, "video stream h %d w %d fr %g bitr %d", vinfo->height, vinfo->width, vq->frame_rate, bitrate); ret = mptr->create_video_plugin(plugin, STREAM_TYPE_MPEG_FILE, vq->compressor, vq->type, vq->profile, NULL, vinfo, NULL, 0); if (ret < 0) { mpeg3f_message(LOG_ERR, "Failed to create video plugin"); psptr->set_message("Failed to create video plugin"); free(vinfo); return -1; } CMpeg3VideoByteStream *vbyte; vbyte = new CMpeg3VideoByteStream(vfile, vq->track_id); if (vbyte == NULL) { psptr->set_message("Failed to create video bytestream"); return -1; } ret = mptr->create_media("video", vbyte); if (ret != 0) { psptr->set_message("Couldn't create video media"); return -1; } return 1; }
int CMp4File::create_video(CPlayerSession *psptr, video_query_t *vq, uint video_offset, uint &start_desc) { uint ix; CPlayerMedia *mptr; codec_plugin_t *plugin; const char *file_kms_uri; const char *inuse_kms_uri; for (ix = 0; ix < video_offset; ix++) { if (vq[ix].enabled != 0) { mptr = new CPlayerMedia(psptr, VIDEO_SYNC); if (mptr == NULL) { return (-1); } video_info_t *vinfo; vinfo = (video_info_t *)malloc(sizeof(video_info_t)); vinfo->height = vq[ix].h; vinfo->width = vq[ix].w; plugin = check_for_video_codec(vq[ix].stream_type, vq[ix].compressor, NULL, vq[ix].type, vq[ix].profile, vq[ix].config, vq[ix].config_len, &config); int ret = mptr->create_video_plugin(plugin, vq[ix].stream_type, vq[ix].compressor, vq[ix].type, vq[ix].profile, NULL, // sdp info vinfo, // video info vq[ix].config, vq[ix].config_len); if (ret < 0) { mp4f_message(LOG_ERR, "Failed to create plugin data"); psptr->set_message("Failed to start plugin"); delete mptr; return -1; } CMp4VideoByteStream *vbyte = NULL; uint64_t IVLength; /* check if clear-text or ismacryp. * in this context original format is encv * and compressor specifies which codec */ uint32_t verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); if (strcasecmp(vq[ix].original_fmt, "avc1") == 0) { vbyte = new CMp4H264VideoByteStream(this, vq[ix].track_id); } else if (strcasecmp(vq[ix].original_fmt, "encv") == 0) { MP4GetTrackIntegerProperty(m_mp4file, vq[ix].track_id, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.IV-length", &IVLength); if (strcasecmp(vq[ix].compressor, "mp4v") == 0) { vbyte = new CMp4EncVideoByteStream(this, vq[ix].track_id,IVLength); } else if (((strcasecmp(vq[ix].compressor, "avc1") == 0) || (strcasecmp(vq[ix].compressor, "264b")) == 0)) { vbyte = new CMp4EncH264VideoByteStream(this, vq[ix].track_id,IVLength); // check if file kms uri matches in-use kms uri // advisory only MP4GetTrackStringProperty(m_mp4file, vq[ix].track_id, "mdia.minf.stbl.stsd.encv.sinf.schi.iKMS.kms_URI", &file_kms_uri); inuse_kms_uri = ((CMp4EncH264VideoByteStream *)vbyte)->get_inuse_kms_uri(); if (file_kms_uri && inuse_kms_uri) { if (strcmp(file_kms_uri, inuse_kms_uri)) { mp4f_message(LOG_DEBUG, "KMS in file (%s) does not match KMS in use (%s)\n", file_kms_uri, inuse_kms_uri); } } } } else { vbyte = new CMp4VideoByteStream(this, vq[ix].track_id); } MP4SetVerbosity(m_mp4file, verb); if (vbyte == NULL) { delete mptr; return (-1); } ret = mptr->create_media("video", vbyte); if (ret != 0) { return (-1); } MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); char *mp4info = MP4Info(m_mp4file, vq[ix].track_id); MP4SetVerbosity(m_mp4file, verb); char *temp = mp4info; while (*temp != '\0') { if (isspace(*temp)) *temp = ' '; if (!isprint(*temp)) *temp = '*'; temp++; } psptr->set_session_desc(start_desc, mp4info); free(mp4info); start_desc++; } else { if (vq[ix].config != NULL) free((void *)vq[ix].config); } } 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(); } }
int CMp4File::create_video(CPlayerSession *psptr, video_query_t *vq, uint video_offset, uint &start_desc) { uint ix; CPlayerMedia *mptr; codec_plugin_t *plugin; for (ix = 0; ix < video_offset; ix++) { if (vq[ix].enabled != 0) { mptr = new CPlayerMedia(psptr, VIDEO_SYNC); if (mptr == NULL) { return (-1); } video_info_t *vinfo; vinfo = (video_info_t *)malloc(sizeof(video_info_t)); vinfo->height = vq[ix].h; vinfo->width = vq[ix].w; plugin = check_for_video_codec(vq[ix].stream_type, vq[ix].compressor, NULL, vq[ix].type, vq[ix].profile, vq[ix].config, vq[ix].config_len, &config); int ret = mptr->create_video_plugin(plugin, vq[ix].stream_type, vq[ix].compressor, vq[ix].type, vq[ix].profile, NULL, // sdp info vinfo, // video info vq[ix].config, vq[ix].config_len); if (ret < 0) { mp4f_message(LOG_ERR, "Failed to create plugin data"); psptr->set_message("Failed to start plugin"); delete mptr; return -1; } CMp4VideoByteStream *vbyte; uint64_t IVLength; /* check if ismacryp */ uint32_t verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); if (strcasecmp(vq[ix].compressor, "avc1") == 0) { vbyte = new CMp4H264VideoByteStream(this, vq[ix].track_id); } else if (strcasecmp(vq[ix].compressor, "encv") == 0) { MP4GetTrackIntegerProperty(m_mp4file, vq[ix].track_id, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.IV-length", &IVLength); vbyte = new CMp4EncVideoByteStream(this, vq[ix].track_id,IVLength); } else { vbyte = new CMp4VideoByteStream(this, vq[ix].track_id); } MP4SetVerbosity(m_mp4file, verb); if (vbyte == NULL) { delete mptr; return (-1); } ret = mptr->create_media("video", vbyte); if (ret != 0) { return (-1); } MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); char *mp4info = MP4Info(m_mp4file, vq[ix].track_id); MP4SetVerbosity(m_mp4file, verb); char *temp = mp4info; while (*temp != '\0') { if (isspace(*temp)) *temp = ' '; if (!isprint(*temp)) *temp = '*'; temp++; } psptr->set_session_desc(start_desc, mp4info); free(mp4info); start_desc++; } else { if (vq[ix].config != NULL) free((void *)vq[ix].config); } } return 0; }
//#define DROP_PAKS 1 static void c_recv_callback (struct rtp *session, rtp_event *e) { CPlayerMedia *m = (CPlayerMedia *)rtp_get_recv_userdata(session); m->recv_callback(session, e); }
int CMp4File::create_text(CPlayerSession *psptr, text_query_t *tq, uint text_offset, uint &start_desc) { uint ix; //uint64_t IVLength; CPlayerMedia *mptr; codec_plugin_t *plugin; uint32_t verb = MP4GetVerbosity(m_mp4file); for (ix = 0; ix < text_offset; ix++) { if (tq[ix].enabled != 0) { CMp4TextByteStream *tbyte; mptr = new CPlayerMedia(psptr, TIMED_TEXT_SYNC); if (mptr == NULL) { return (-1); } /* check if ismacryp */ #if 0 uint32_t verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); if (MP4IsIsmaCrypMediaTrack(m_mp4file, aq[ix].track_id)) { IVLength = MP4GetTrackIntegerProperty(m_mp4file, aq[ix].track_id, "mdia.minf.stbl.stsd.enca.sinf.schi.iSFM.IV-length"); abyte = new CMp4EncAudioByteStream(this, aq[ix].track_id, IVLength); } else { abyte = new CMp4AudioByteStream(this, aq[ix].track_id); } MP4SetVerbosity(m_mp4file, verb); #else tbyte = new CMp4TextByteStream(this, tq[ix].track_id); #endif int ret; plugin = check_for_text_codec(tq[ix].stream_type, tq[ix].compressor, NULL, NULL, 0, &config); ret = mptr->create_text_plugin(plugin, STREAM_TYPE_MP4_FILE, tq[ix].compressor, NULL, // sdp info NULL, 0); if (ret < 0) { mp4f_message(LOG_ERR, "Couldn't create text from plugin %s", plugin->c_name); psptr->set_message("Couldn't start text plugin %s", plugin->c_name); delete mptr; delete tbyte; return -1; } ret = mptr->create_media("text", tbyte); if (ret != 0) { return (-1); } MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); char *mp4info = MP4Info(m_mp4file, tq[ix].track_id); MP4SetVerbosity(m_mp4file, verb); char *temp = mp4info; while (*temp != '\0') { if (isspace(*temp)) *temp = ' '; if (!isprint(*temp)) *temp = '*'; temp++; } psptr->set_session_desc(start_desc, mp4info); free(mp4info); start_desc++; } else { CHECK_AND_FREE(tq[ix].config); } } return 0; }
int parse_name_for_session (CPlayerSession *psptr, const char *name, char *errmsg, uint32_t errlen, control_callback_vft_t *cc_vft) { int err; #ifdef HAVE_IGMP_V3 // gross, but here for multiple files const char *mcast_src = config.get_config_string(CONFIG_MULTICAST_SRC); if (mcast_src != NULL) { udp_set_multicast_src(mcast_src); } else { udp_set_multicast_src("0.0.0.0"); } #endif ADV_SPACE(name); if (strncmp(name, "rtsp://", strlen("rtsp://")) == 0) { err = create_media_for_streaming_ondemand(psptr, name, errmsg, errlen, cc_vft); return (err); } if (strncmp(name, "http://", strlen("http://")) == 0) { err = create_media_for_http(psptr, name, errmsg, errlen, cc_vft); return (err); } int have_audio_driver; have_audio_driver = do_we_have_audio(); #ifndef _WIN32 if (strncmp(name, "iptv://", strlen("iptv://")) == 0) { err = create_media_for_iptv(psptr, name, errmsg, errlen, have_audio_driver, cc_vft); return err; } #endif #ifndef _WIN32 if (strncmp(name, "mpeg2t://", strlen("mpeg2t://")) == 0) { err = create_mpeg2t_session(psptr, name, NULL, errmsg, errlen, have_audio_driver, cc_vft); return (err); } struct stat statbuf; if (stat(name, &statbuf) != 0) { snprintf(errmsg, errlen, "File \'%s\' not found", name); return (-1); } if (!S_ISREG(statbuf.st_mode)) { snprintf(errmsg, errlen, "File \'%s\' is not a file", name); return (-1); } #else OFSTRUCT ReOpenBuff; if (OpenFile(name, &ReOpenBuff,OF_READ) == HFILE_ERROR) { snprintf(errmsg, errlen, "File %s not found", name); return (-1); } #endif err = -1; const char *suffix = strrchr(name, '.'); if (suffix == NULL) { snprintf(errmsg, errlen, "No useable suffix on file %s", name); return err; } if (strcasecmp(suffix, ".sdp") == 0) { err = create_media_from_sdp_file(psptr, name, errmsg, errlen, have_audio_driver, cc_vft); } else if ((strcasecmp(suffix, ".mov") == 0) || (strcasecmp(suffix, ".mp4") == 0) || (strcasecmp(suffix, ".3gp") == 0) || (strcasecmp(suffix, ".m4a") == 0)) { if (config.get_config_value(CONFIG_USE_OLD_MP4_LIB) == 0) { err = create_media_for_mp4_file(psptr, name, errmsg, errlen, have_audio_driver, cc_vft); } else err = -1; if (err < 0) { err = create_media_for_qtime_file(psptr, name, errmsg, errlen, have_audio_driver); } } else if (strcasecmp(suffix, ".avi") == 0) { err = create_media_for_avi_file(psptr, name, errmsg, errlen, have_audio_driver, cc_vft); } else if (strcasecmp(suffix, ".mpeg") == 0 || strcasecmp(suffix, ".mpg") == 0 || strcasecmp(suffix, ".vob") == 0) { #ifdef _WIN32 err = -1; #else err = create_media_for_mpeg2t_file(psptr, name, errmsg, errlen, have_audio_driver, cc_vft); if (err < 0) { err = create_media_for_mpeg_file(psptr, name, errmsg, errlen, have_audio_driver, cc_vft); } #endif } else { // raw files codec_data_t *cdata = NULL; double maxtime; char *desc[4]; bool is_video = false; codec_plugin_t *codec; desc[0] = NULL; desc[1] = NULL; desc[2] = NULL; desc[3] = NULL; if (have_audio_driver) { cdata = audio_codec_check_for_raw_file(name, &codec, &maxtime, desc, &config); } if (cdata == NULL) { cdata = video_codec_check_for_raw_file(name, &codec, &maxtime, desc, &config); is_video = true; } if (cdata == NULL) { err = -1; } else { CPlayerMedia *mptr; /* * Create the player media, and the bytestream */ mptr = new CPlayerMedia(psptr); COurInByteStreamFile *fbyte; fbyte = new COurInByteStreamFile(codec, cdata, maxtime); mptr->create(fbyte, is_video); mptr->set_plugin_data(codec, cdata, is_video ? get_video_vft() : NULL, is_video ? NULL : get_audio_vft()); for (int ix = 0; ix < 4; ix++) if (desc[ix] != NULL) psptr->set_session_desc(ix, desc[ix]); if (maxtime != 0.0) { psptr->session_set_seekable(1); } err = 0; } } if (err >= 0) { const char *temp; temp = psptr->get_session_desc(0); if (temp == NULL) { psptr->set_session_desc(0, name); } } return (err); }