📄 mpeg2t_thread.cpp
字号:
vq[ix].config, vq[ix].config_len); int ret = mptr->create_video_plugin(plugin, "MPEG2 TRANSPORT", vq[ix].type, vq[ix].profile, NULL, // sdp info vinfo, // video info vq[ix].config, vq[ix].config_len); if (ret < 0) { mpeg2t_message(LOG_ERR, "Failed to create plugin data"); snprintf(errmsg, errlen, "Failed to start plugin"); delete mptr; return -1; } CMpeg2tVideoByteStream *vbyte; mpeg2t_pid_t *pidptr; mpeg2t_es_t *es_pid; pidptr = mpeg2t_lookup_pid(info->decoder,vq[ix].track_id); if (pidptr->pak_type != MPEG2T_ES_PAK) { mpeg2t_message(LOG_CRIT, "mpeg2t video type is not es pak"); exit(1); } es_pid = (mpeg2t_es_t *)pidptr; vbyte = new CMpeg2tVideoByteStream(es_pid); if (vbyte == NULL) { mpeg2t_message(LOG_CRIT, "failed to create byte stream"); delete mptr; return (-1); } ret = mptr->create(vbyte, TRUE, errmsg, errlen, 1); if (ret != 0) { mpeg2t_message(LOG_CRIT, "failed to create from file"); return (-1); } mpeg2t_stream_t *stream; stream = MALLOC_STRUCTURE(mpeg2t_stream_t); stream->m_mptr = mptr; stream->m_is_video = 1; stream->m_buffering = 1; stream->m_frames_since_last_psts = 0; stream->m_last_psts = 0; stream->m_have_info = 0; stream->next_stream = info->stream; info->stream = stream; 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_es_set_userdata(es_pid, stream); mpeg2t_start_saving_frames(es_pid); } } return 0;}static int mpeg2t_create_audio (mpeg2t_client_t *info, CPlayerSession *psptr, audio_query_t *aq, int audio_offset, char *errmsg, uint32_t errlen, int &sdesc){ int ix; CPlayerMedia *mptr; codec_plugin_t *plugin; for (ix = 0; ix < audio_offset; ix++) { if (aq[ix].enabled != 0) { mptr = new CPlayerMedia(psptr); 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("MPEG2 TRANSPORT", NULL, aq[ix].type, aq[ix].profile, aq[ix].config, aq[ix].config_len); int ret = mptr->create_audio_plugin(plugin, "MPEG2 TRANSPORT", aq[ix].type, aq[ix].profile, NULL, // sdp info ainfo, // video info aq[ix].config, aq[ix].config_len); if (ret < 0) { mpeg2t_message(LOG_ERR, "Failed to create plugin data"); snprintf(errmsg, errlen, "Failed to start plugin"); delete mptr; return -1; } CMpeg2tAudioByteStream *abyte; mpeg2t_pid_t *pidptr; mpeg2t_es_t *es_pid; pidptr = mpeg2t_lookup_pid(info->decoder,aq[ix].track_id); if (pidptr->pak_type != MPEG2T_ES_PAK) { mpeg2t_message(LOG_CRIT, "mpeg2t video type is not es pak"); exit(1); } es_pid = (mpeg2t_es_t *)pidptr; abyte = new CMpeg2tAudioByteStream(es_pid); if (abyte == NULL) { mpeg2t_message(LOG_CRIT, "failed to create byte stream"); delete mptr; return (-1); } ret = mptr->create(abyte, FALSE, errmsg, errlen, 1); if (ret != 0) { mpeg2t_message(LOG_CRIT, "failed to create from file"); return (-1); } mpeg2t_stream_t *stream; stream = MALLOC_STRUCTURE(mpeg2t_stream_t); stream->m_mptr = mptr; stream->m_is_video = 0; stream->m_buffering = 1; stream->m_frames_since_last_psts = 0; stream->m_last_psts = 0; stream->m_have_info = 0; stream->next_stream = info->stream; info->stream = stream; 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_es_set_userdata(es_pid, stream); mpeg2t_start_saving_frames(es_pid); } } return 0;}int create_mpeg2t_session (CPlayerSession *psptr, const char *orig_name, session_desc_t *sdp, char *errmsg, uint32_t errlen, int have_audio_driver, control_callback_vft_t *cc_vft){ const char *colon, *slash, *name; char *addr, *port; uint32_t addrlen, portlen; mpeg2t_client_t *mp2t; in_port_t rxport; if (orig_name != NULL) { name = orig_name + strlen("mpeg2t://"); colon = strchr(name, ':'); slash = strchr(name, '/'); if (slash == NULL) slash = name + strlen(name); if (colon == NULL || slash == NULL || colon > slash) { snprintf(errmsg, errlen, "Misformed mpeg2 url %s", orig_name); return -1; } addrlen = colon - name; portlen = slash - colon - 1; addr = (char *)malloc(1 + addrlen); port = (char *)malloc(1 + portlen); memcpy(addr, name, addrlen); addr[addrlen] = '\0'; memcpy(port, colon + 1, portlen); port[portlen] = '\0'; char *eport; rxport = strtoul(port, &eport, 10); if (eport == NULL || *eport != '\0') { snprintf(errmsg, errlen, "Illegal port number in url %s", orig_name); free(addr); free(port); return -1; } free(port); mp2t = mpeg2t_create_client(addr, rxport, 0, 0, 0.0, 0, errmsg, errlen); free(addr); } else if (sdp != NULL) { // from SDP connect_desc_t *cptr; double bw; cptr = get_connect_desc_from_media(sdp->media); if (find_rtcp_bandwidth_from_media(sdp->media, &bw) < 0) { bw = 5000.0; } mp2t = mpeg2t_create_client(cptr->conn_addr, sdp->media->port, 0, 1, // use rtp bw, cptr->ttl, errmsg, errlen); } else { return -1; } if (mp2t == NULL) { return -1; } psptr->set_media_close_callback(close_mpeg2t_client, mp2t); // Okay - we need to gather together information about pids and // lists, then call the audio/video query vectors. int audio_count, video_count; int audio_info_count, video_info_count; int passes; mpeg2t_pid_t *pid_ptr; mpeg2t_es_t *es_pid; pid_ptr = &mp2t->decoder->pas.pid; audio_count = video_count = 0; audio_info_count = video_info_count = 0; passes = 0; do { SDL_LockMutex(mp2t->decoder->pid_mutex); while (pid_ptr != NULL) { switch (pid_ptr->pak_type) { case MPEG2T_PAS_PAK: case MPEG2T_PROG_MAP_PAK: break; case MPEG2T_ES_PAK: es_pid = (mpeg2t_es_t *)pid_ptr; switch (es_pid->stream_type) { case MPEG2T_ST_MPEG_VIDEO: case MPEG2T_ST_MPEG4_VIDEO: case MPEG2T_ST_11172_VIDEO: video_count++; if (es_pid->info_loaded) video_info_count++; break; case MPEG2T_ST_11172_AUDIO: case MPEG2T_ST_MPEG_AUDIO: audio_count++; if (es_pid->info_loaded) audio_info_count++; break; case MPEG2T_ST_MPEG_AUDIO_6_A: case MPEG2T_ST_MPEG_AUDIO_6_B: case MPEG2T_ST_MPEG_AUDIO_6_C: case MPEG2T_ST_MPEG_AUDIO_6_D: case MPEG2T_ST_MPEG2_AAC: default: mpeg2t_message(LOG_INFO, "PID %x - Unknown/unused stream type %d", pid_ptr->pid, es_pid->stream_type); break; } break; } pid_ptr = pid_ptr->next_pid; } SDL_UnlockMutex(mp2t->decoder->pid_mutex); passes++; if (audio_count != audio_info_count || video_info_count != video_count) { SDL_Delay(1 * 1000); } } while (audio_info_count != audio_count && video_info_count != video_info_count); video_query_t *vq; audio_query_t *aq; if (video_count > 0) { vq = (video_query_t *)malloc(sizeof(video_query_t) * video_count); memset(vq, 0, sizeof(video_query_t) * video_count); } else { vq = NULL; } if (audio_count > 0) { aq = (audio_query_t *)malloc(sizeof(audio_query_t) * audio_count); memset(aq, 0, sizeof(audio_query_t) * audio_count); } else { aq = NULL; } int vid_cnt = 0, aud_cnt = 0; codec_plugin_t *plugin; pid_ptr = &mp2t->decoder->pas.pid; SDL_LockMutex(mp2t->decoder->pid_mutex); while (pid_ptr != NULL) { switch (pid_ptr->pak_type) { case MPEG2T_PAS_PAK: case MPEG2T_PROG_MAP_PAK: break; case MPEG2T_ES_PAK: es_pid = (mpeg2t_es_t *)pid_ptr; switch (es_pid->stream_type) { case MPEG2T_ST_11172_VIDEO: case MPEG2T_ST_MPEG_VIDEO: case MPEG2T_ST_MPEG4_VIDEO: if (vid_cnt < video_count) { plugin = check_for_video_codec("MPEG2 TRANSPORT", NULL, es_pid->stream_type, -1, es_pid->es_data, es_pid->es_info_len); if (plugin == NULL) { snprintf(errmsg, errlen, "Can't find plugin for stream type %d", es_pid->stream_type); mpeg2t_message(LOG_ERR, errmsg); } else { vq[vid_cnt].track_id = pid_ptr->pid; vq[vid_cnt].compressor = "MPEG2 TRANSPORT"; vq[vid_cnt].type = es_pid->stream_type; vq[vid_cnt].profile = -1; vq[vid_cnt].fptr = NULL; if (es_pid->info_loaded != 0) { vq[vid_cnt].h = es_pid->h; vq[vid_cnt].w = es_pid->w; vq[vid_cnt].frame_rate = es_pid->frame_rate; mpeg2t_message(LOG_DEBUG, "video stream h %d w %d fr %g bitr %g", es_pid->h, es_pid->w, es_pid->frame_rate, es_pid->bitrate); } else { vq[vid_cnt].h = -1; vq[vid_cnt].w = -1; vq[vid_cnt].frame_rate = 0.0; } vq[vid_cnt].config = es_pid->es_data; vq[vid_cnt].config_len = es_pid->es_info_len; vq[vid_cnt].enabled = 0; vq[vid_cnt].reference = NULL; vid_cnt++; } } break; case MPEG2T_ST_MPEG_AUDIO: case MPEG2T_ST_11172_AUDIO: if (aud_cnt < audio_count) { plugin = check_for_audio_codec("MPEG2 TRANSPORT", NULL, es_pid->stream_type, -1, es_pid->es_data, es_pid->es_info_len); if (plugin == NULL) { snprintf(errmsg, errlen, "Can't find plugin for stream type %d", es_pid->stream_type); mpeg2t_message(LOG_ERR, errmsg); } else { aq[aud_cnt].track_id = pid_ptr->pid; aq[aud_cnt].compressor = "MPEG2 TRANSPORT"; aq[aud_cnt].type = es_pid->stream_type; aq[aud_cnt].profile = -1; aq[aud_cnt].fptr = NULL; aq[aud_cnt].config = es_pid->es_data; aq[aud_cnt].config_len = es_pid->es_info_len; if (es_pid->info_loaded != 0) { aq[aud_cnt].chans = es_pid->audio_chans; aq[aud_cnt].sampling_freq = es_pid->sample_freq; mpeg2t_message(LOG_DEBUG, "audio stream chans %d sf %d bitrate %g", es_pid->audio_chans, es_pid->sample_freq, es_pid->bitrate / 1000.0); } else { aq[aud_cnt].chans = -1; aq[aud_cnt].sampling_freq = -1; } aq[aud_cnt].enabled = 0; aq[aud_cnt].reference = NULL; aud_cnt++; } } break; case MPEG2T_ST_MPEG_AUDIO_6_A: case MPEG2T_ST_MPEG_AUDIO_6_B: case MPEG2T_ST_MPEG_AUDIO_6_C: case MPEG2T_ST_MPEG_AUDIO_6_D: case MPEG2T_ST_MPEG2_AAC: default: mpeg2t_message(LOG_INFO, "PID %x - Unknown/unused stream type %d", es_pid->stream_type, pid_ptr->pid); break; } break; } pid_ptr = pid_ptr->next_pid; } SDL_UnlockMutex(mp2t->decoder->pid_mutex); if (cc_vft && cc_vft->media_list_query != NULL) { (cc_vft->media_list_query)(psptr, video_count, vq, audio_count, aq); } else { if (video_count > 0) { vq[0].enabled = 1; } if (audio_count > 0) { aq[0].enabled = 1; } } int total_enabled = 0; psptr->set_session_desc(0, "MPEG2 Transport Stream"); int sdesc = 1; for (vid_cnt = 0; vid_cnt < video_count; vid_cnt++) { if (vq[vid_cnt].enabled == 1) { // create video media if (mpeg2t_create_video(mp2t, psptr, vq, video_count, errmsg, errlen, sdesc) < 0) { free(aq); free(vq); return -1; } total_enabled++; } } for (aud_cnt = 0; aud_cnt < audio_count; aud_cnt++) { if (aq[aud_cnt].enabled == 1) { // create audio media if (mpeg2t_create_audio(mp2t, psptr, aq, audio_count, errmsg, errlen, sdesc) < 0) { free(aq); free(vq); return -1; } total_enabled++; } } free(aq); free(vq); if (total_enabled != 0) { // This is to get the m_streaming bit set, so we can do the // elapsed time correctly psptr->create_streaming_broadcast(NULL, errmsg, errlen); return 0; } return -1;} // NOTE TO SELF - need to add a mechanism that indicates that // we're paused. We'll need to keep reading the RTP packets, but// will want to flush them.// Options are to add a do_pause to the bytestream.// or have a pause registration in either player media or playersession
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -