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

📄 mpeg2t_thread.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	      have_duration = endptr != dptr;	    }	  }	}      }    }   } else {    // not good, but try anyway for setup.  }  if (decode != NULL) free_decode_response(decode);  // we're done with describe - we might have something, we might not   // lets go with a SETUP.  memset(&cmd, 0, sizeof(rtsp_command_t));  decode = NULL;  char buffer[2048];  char *ouraddr = get_host_ip_address();  C2ConsecIpPort *port = new C2ConsecIpPort(psptr->get_unused_ip_port_ptr());  snprintf(buffer, sizeof(buffer), "RAW/RAW/UDP;unicast;destination=%s;client_port=%u",	   ouraddr, port->first_port());  cmd.transport = buffer;  rtsp_session_t *session;  err = rtsp_send_setup(rptr, rtsp_url, &cmd, &session, &decode, 1);  free(ouraddr);  if (err != RTSP_RESPONSE_GOOD) {    if (decode != NULL) {      psptr->set_message("RTSP error %s %s",	       decode->retcode, decode->retresp);    } else {      psptr->set_message("RTSP setup error %d", err);    }    free_rtsp_client(rptr);    free_decode_response(decode);    free(rtsp_url);    return NULL;  }  // we have a good setup - we'll need to parse the transport for the   // ports to set up, then create the client.  rtsp_transport_parse_t parse;  memset(&parse, 0, sizeof(parse));  parse.client_port = port->first_port();  delete port;  err = process_rtsp_transport(&parse, decode->transport, "RAW/RAW/UDP");  if (err < 0) {    psptr->set_message("error in rtsp transport \"%s\"", decode->transport);    free_rtsp_client(rptr);    free_decode_response(decode);    free(rtsp_url);    return NULL;  }  free_decode_response(decode);    mp2t = mpeg2t_create_client(psptr, 			      parse.source,			      parse.client_port,			      parse.server_port, 			      0, 			      0.0,			      0, 			      rptr,			      rtsp_url);  // now, we'll start playing, and capturingr until we get enough to set  // up the decoders - we'll save everything for a bit  if (mp2t != NULL) {    mp2t->m_have_end_time = have_duration;    mp2t->m_end_time = duration;  }  return mp2t;}void mpeg2t_check_streams (video_query_t **pvq, 			   audio_query_t **paq,			   mpeg2t_t *decoder,			   uint &audio_count,			   uint &video_count,			   CPlayerSession *psptr,			   control_callback_vft_t *cc_vft){  uint audio_info_count, video_info_count;  mpeg2t_pid_t *pid_ptr;  mpeg2t_es_t *es_pid;  int passes;  pid_ptr = &decoder->pas.pid;  audio_count = video_count = 0;  audio_info_count = video_info_count = 0;  passes = 0;  do {  SDL_LockMutex(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:      case MPEG2T_ST_H264_VIDEO:	video_count++;	if (es_pid->info_loaded) video_info_count++;	break;      case MPEG2T_ST_11172_AUDIO:      case MPEG2T_ST_MPEG_AUDIO:      case 129:	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(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;  }  *pvq = vq;  *paq = aq;  uint vid_cnt = 0, aud_cnt = 0;  codec_plugin_t *plugin;  pid_ptr = &decoder->pas.pid;  SDL_LockMutex(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;      if (es_pid->is_video > 0) {	if (vid_cnt < video_count) {	  plugin = check_for_video_codec(STREAM_TYPE_MPEG2_TRANSPORT_STREAM,					 NULL,					 NULL,					 es_pid->stream_type,					 -1,					 es_pid->es_data,					 es_pid->es_info_len,					 &config);	  if (plugin == NULL) {	    psptr->set_message(		     "Can't find video plugin for stream type %d",		     es_pid->stream_type);	    mpeg2t_message(LOG_ERR, "%s", psptr->get_message());	  } else {	    vq[vid_cnt].track_id = pid_ptr->pid;	    vq[vid_cnt].stream_type = STREAM_TYPE_MPEG2_TRANSPORT_STREAM;	    vq[vid_cnt].compressor = NULL;	    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;	    es_pid->es_data = NULL;	    es_pid->es_info_len = 0;	    vq[vid_cnt].enabled = 0;	    vq[vid_cnt].reference = NULL;	    vid_cnt++;	  }	}      } else {	if (aud_cnt < audio_count) {	  plugin = check_for_audio_codec(STREAM_TYPE_MPEG2_TRANSPORT_STREAM,					 NULL,					 NULL,					 es_pid->stream_type,					 -1,					 es_pid->es_data,					 es_pid->es_info_len,					 &config);	  if (plugin == NULL) {	    psptr->set_message(		     "Can't find audio plugin for stream type %d",		     es_pid->stream_type);	    mpeg2t_message(LOG_ERR, "%s", psptr->get_message());	  } else {	    aq[aud_cnt].track_id = pid_ptr->pid;	    aq[aud_cnt].stream_type = STREAM_TYPE_MPEG2_TRANSPORT_STREAM;	    aq[aud_cnt].compressor = NULL;	    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;	    es_pid->es_data = NULL;	    es_pid->es_info_len = 0;	    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++;	  }	}      }    }    pid_ptr = pid_ptr->next_pid;  }  SDL_UnlockMutex(decoder->pid_mutex);  if (cc_vft && cc_vft->media_list_query != NULL) {    (cc_vft->media_list_query)(psptr, vid_cnt, vq, aud_cnt, aq,			       0, NULL);  } else {    if (video_count > 0) {      vq[0].enabled = 1;    }    if (audio_count > 0) {      aq[0].enabled = 1;    }  }  video_count = vid_cnt;  audio_count = aud_cnt;}int create_mpeg2t_session (CPlayerSession *psptr,			   const char *orig_name, 			   session_desc_t *sdp,			   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) {	psptr->set_message("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') {	psptr->set_message("Illegal port number in url %s", orig_name);	free(addr);	free(port);	return -1;      }      free(port);        mp2t = mpeg2t_create_client(psptr, addr, rxport, 0, 0, 0.0, 0);      free(addr);    } else {       // we have a rtsp like url.      mp2t = mpeg2t_start_rtsp(psptr, orig_name);      if (mp2t == NULL)	return -1;    }   } 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(psptr,				cptr->conn_addr,				sdp->media->port,				0,				1, // use rtp				bw,				cptr->ttl);  } 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.  uint audio_count, video_count;  video_query_t *vq;  audio_query_t *aq;  mp2t->decoder->save_frames_at_start = 0;  mpeg2t_check_streams(&vq, &aq, mp2t->decoder, audio_count, video_count, 		       psptr, cc_vft);  int total_enabled = 0;  psptr->set_session_desc(0, "MPEG2 Transport Stream");  int sdesc = 1;  // create video media  int ret =  mpeg2t_create_video(mp2t, psptr, vq, video_count, 				 sdesc);  if (ret < 0) {    free(aq);    free(vq);    return -1;  }  total_enabled += ret;  // create audio media  ret = mpeg2t_create_audio(mp2t, psptr, aq, 			    audio_count, sdesc);  if (ret < 0) {    free(aq);    free(vq);    return -1;  }  total_enabled += ret;  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    if (mp2t->m_rtsp_client) {      psptr->create_streaming_ondemand_other(mp2t->m_rtsp_client,					     mp2t->m_rtsp_url,					     mp2t->m_have_end_time,					     mp2t->m_end_time,					     1,					     0);    } else {					           psptr->create_streaming_broadcast(NULL);    }    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 + -