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

📄 mpeg2t_thread.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
 */static mpeg2t_client_t *mpeg2t_create_client (CPlayerSession *psptr,					      const char *address,					      in_port_t rx_port,					      in_port_t tx_port,					      int use_rtp,					      double rtcp_bw, 					      int ttl,					      rtsp_client_t *client = NULL,					      char *rtsp_url = NULL){  mpeg2t_client_t *info;  int ret;  mpeg2t_msg_type_t msg;  mpeg2t_msg_resp_t resp;  rtsp_command_t cmd;  rtsp_decode_t *decode;  int err;  info = MALLOC_STRUCTURE(mpeg2t_client_t);  if (info == NULL) return (NULL);  memset(info, 0, sizeof(mpeg2t_client_t));  info->m_rtsp_client = client;  if (client != NULL) {    info->m_have_rtsp = 1;  } else {    info->m_have_rtsp = 0;  }  info->m_rtsp_url = rtsp_url;  info->address = strdup(address);  info->rx_port = rx_port;  info->tx_port = tx_port;  info->useRTP = use_rtp;  info->rtcp_bw = rtcp_bw;  info->ttl = ttl;  info->recv_timeout = 100;  info->decoder = create_mpeg2_transport();  if (info->decoder == NULL) {    mpeg2t_delete_client(info);    return (NULL);  }  info->decoder->save_frames_at_start = 1;  info->pam_recvd_sem = SDL_CreateSemaphore(0);  info->msg_mutex = SDL_CreateMutex();  // start the thread, which starts the data being received, so we  // can look at the program maps  if (mpeg2t_create_thread(info) != 0) {    mpeg2t_delete_client(info);    return (NULL);  }  SDL_Delay(100);  msg = MPEG2T_MSG_START;  ret = mpeg2t_thread_ipc_send_wait(info,				  (unsigned char *)&msg,				  sizeof(msg),				  &resp);  if (ret < 0 || resp < 0) {    mpeg2t_delete_client(info);    psptr->set_message("Couldn't create client - error %d", resp);    return NULL;  }  if (info->m_rtsp_client) {    // issue play, so we've got the thread ready to receive data,     // and we can look for the program maps    memset(&cmd, 0, sizeof(rtsp_command_t));    decode = NULL;    cmd.scale=1.0;    cmd.range="0-";    err = rtsp_send_aggregate_play(info->m_rtsp_client, 				   info->m_rtsp_url, 				   &cmd, 				   &decode);    if (err != RTSP_RESPONSE_GOOD) {      psptr->set_message("RTSP play error %s %s", 	       decode->retcode, decode->retresp);      free_decode_response(decode);      memset(&cmd, 0, sizeof(rtsp_command_t));      decode = NULL;      rtsp_send_aggregate_teardown(info->m_rtsp_client, 				   info->m_rtsp_url, 				   &cmd, 				   &decode);      free_rtsp_client(info->m_rtsp_client);      mpeg2t_delete_client(info);      return NULL;    }    free_decode_response(decode);  }    // Wait until we get the program maps (should probably be PMAP_WAIT),   // so we can determine audio/video  int max = config.get_config_value(CONFIG_MPEG2T_PAM_WAIT_SECS);  do {    ret = SDL_SemWaitTimeout(info->pam_recvd_sem, 1000);    if (ret == SDL_MUTEX_TIMEDOUT) {      max--;      if (psptr->ShouldStopProcessing()) {	max = -1;      }      mpeg2t_message(LOG_DEBUG, "timeout - still left %d", max);    }  } while (ret == SDL_MUTEX_TIMEDOUT && max >= 0);  if (ret == SDL_MUTEX_TIMEDOUT) {    if (info->decoder->program_maps_recvd != 0) {      mpeg2t_message(LOG_INFO, "Program count received %d doesn't match program count %d", 		     info->decoder->program_maps_recvd, 		     info->decoder->program_count);    } else {      if (info->m_rtsp_client) {	memset(&cmd, 0, sizeof(rtsp_command_t));	decode = NULL;	rtsp_send_aggregate_teardown(info->m_rtsp_client, 				     info->m_rtsp_url, 				     &cmd, 				     &decode);      free_rtsp_client(info->m_rtsp_client);      }      psptr->set_message("Did not receive Transport Stream Program Map in %d seconds", config.get_config_value(CONFIG_MPEG2T_PAM_WAIT_SECS));      mpeg2t_delete_client(info);      return NULL;    }  }  return (info);}void mpeg2t_delete_client (mpeg2t_client_t *info){  mpeg2t_stream_t *p;  mpeg2t_thread_close(info);  CHECK_AND_FREE(info->address);  delete_mpeg2t_transport(info->decoder);  info->decoder = NULL;  SDL_DestroyMutex(info->msg_mutex);  SDL_DestroySemaphore(info->pam_recvd_sem);  p = info->stream;  while (p != NULL) {    info->stream = p->next_stream;    free(p);    p = info->stream;  }  free(info);}static void close_mpeg2t_client (void *data){  mpeg2t_delete_client((mpeg2t_client_t *)data);}static int mpeg2t_create_video(mpeg2t_client_t *info,			       CPlayerSession *psptr, 			       video_query_t *vq, 			       int video_offset,			       int &sdesc){  int ix;  CPlayerMedia *mptr;  codec_plugin_t *plugin;  int created = 0;  for (ix = 0; ix < video_offset; ix++) {    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 - 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) {	mpeg2t_message(LOG_ERR, "Failed to create plugin data");	psptr->set_message("Failed to start plugin");	delete mptr;	return -1;      }      mpeg2t_stream_t *stream;      stream = MALLOC_STRUCTURE(mpeg2t_stream_t);      stream->m_parent = info;      stream->m_mptr = mptr;      stream->m_is_video = 1;      stream->m_buffering = 1;      stream->m_have_info = 0;      stream->m_have_eof = 0;      stream->next_stream = info->stream;      info->stream = stream;      mpeg2t_set_userdata(&es_pid->pid, stream);      CMpeg2tVideoByteStream *vbyte;      vbyte = new CMpeg2tVideoByteStream(es_pid, info->m_have_rtsp);      if (vbyte == NULL) {	mpeg2t_message(LOG_CRIT, "failed to create byte stream");	delete mptr;	free(stream);	return (-1);      }      ret = mptr->create_media("video", vbyte, true);      if (ret != 0) {	mpeg2t_message(LOG_CRIT, "failed to create from file");	free(stream);	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 mpeg2t_create_audio (mpeg2t_client_t *info,				CPlayerSession *psptr, 				audio_query_t *aq, 				int audio_offset,				int &sdesc){  int 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(info->decoder,aq[ix].track_id);    if (pidptr->pak_type != MPEG2T_ES_PAK) {      mpeg2t_message(LOG_CRIT, "mpeg2t audio 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) {      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) {	mpeg2t_message(LOG_ERR, "Failed to create plugin data");	psptr->set_message("Failed to start plugin");	delete mptr;	return -1;      }      mpeg2t_stream_t *stream;      stream = MALLOC_STRUCTURE(mpeg2t_stream_t);      stream->m_parent = info;      stream->m_mptr = mptr;      stream->m_is_video = 0;      stream->m_buffering = 1;      stream->m_have_info = 0;      stream->next_stream = info->stream;      info->stream = stream;      mpeg2t_set_userdata(&es_pid->pid, stream);      created = 1;      CMpeg2tAudioByteStream *abyte;      abyte = new CMpeg2tAudioByteStream(es_pid, info->m_have_rtsp);      if (abyte == NULL) {	mpeg2t_message(LOG_CRIT, "failed to create byte stream");	delete mptr;	free(stream);	return (-1);      }      ret = mptr->create_media("audio", abyte, true);      if (ret != 0) {	mpeg2t_message(LOG_CRIT, "failed to create from file");	free(stream);	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;}mpeg2t_client_t *mpeg2t_start_rtsp (CPlayerSession *psptr, 				    const char *orig_name){  char *rtsp_url;  rtsp_client_t *rptr;  int err;  rtsp_command_t cmd;  rtsp_decode_t *decode;  int rtsp_resp;  int have_duration = 0;  uint64_t duration = 0;  mpeg2t_client_t *mp2t;  rtsp_url = strdup(orig_name + 2);  rtsp_url[0] = 'r';  rtsp_url[1] = 't';  rtsp_url[2] = 's';  rtsp_url[3] = 'p';  // That's to change mpeg2t:// to rtsp://  rptr = rtsp_create_client(rtsp_url, &err,			    config.GetStringValue(CONFIG_RTSP_PROXY_ADDR),			    config.GetIntegerValue(CONFIG_RTSP_PROXY_PORT));  if (rptr == NULL) {    psptr->set_message("Couldn't create rtsp client %d", err);    free(rtsp_url);    return NULL;  }  memset(&cmd, 0, sizeof(rtsp_command_t));  // don't set accept  rtsp_resp = rtsp_send_describe(rptr, &cmd, &decode);  if (rtsp_resp == RTSP_RESPONSE_GOOD) {    // good response - see what they returned.    if (decode->content_type != NULL) {      if (strncasecmp(decode->content_type, 		      "application/sdp", 		      strlen("application/sdp")) == 0) {	free_decode_response(decode);	free(rtsp_url);	psptr->set_message("Returned content type is SDP - please use rtsp://");	return NULL;      } else if (strncasecmp(decode->content_type, 			     "application/x-rtsp-mh",			     strlen("application/x-rtsp-mh")) == 0) {	// 	if (decode->body) {	  const char *dptr = strcasestr(decode->body, "Duration");	  if (dptr != NULL) {	    dptr += strlen("duration");	    ADV_SPACE(dptr);	    if (*dptr == '=') {	      dptr++;	      ADV_SPACE(dptr);	      char *endptr;	      duration = strtoull(dptr, &endptr, 10);	      duration = (duration + 999) / TO_U64(1000); // convert usec to msec

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -