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

📄 mpeg2t_thread.cpp

📁 网络MPEG4IP流媒体开发源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				     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 + -