Example #1
0
int main()
{
	tlog_init(TLOG_MODE_STDERR, TLOG_INFO, NULL);

	rcp_connect("10.25.25.220");

	start_message_manager();

	client_register(RCP_USER_LEVEL_LIVE, "", RCP_REGISTRATION_TYPE_NORMAL, RCP_ENCRYPTION_MODE_MD5);

	rcp_coder_list encoders, decoders;
	get_coder_list(RCP_CODER_ENCODER, RCP_MEDIA_TYPE_VIDEO, &encoders, 1);
	TL_DEBUG("***");
	for (int i=0; i<encoders.count; i++)
		TL_DEBUG("%x %x %x %x %x", encoders.coder[i].number, encoders.coder[i].caps, encoders.coder[i].current_cap, encoders.coder[i].param_caps, encoders.coder[i].current_param);
	TL_DEBUG("***");
	get_coder_list(RCP_CODER_DECODER, RCP_MEDIA_TYPE_VIDEO, &decoders, 1);
	TL_DEBUG("***");
	for (int i=0; i<decoders.count; i++)
		TL_DEBUG("%x %x %x %x %x", decoders.coder[i].number, decoders.coder[i].caps, decoders.coder[i].current_cap, decoders.coder[i].param_caps, decoders.coder[i].current_param);
	TL_DEBUG("***");

	rcp_session session;
	memset(&session, 0, sizeof(rcp_session));
	unsigned short udp_port = stream_connect_udp(&session);

	TL_DEBUG("udp port = %d", udp_port);

	rcp_media_descriptor desc = {
			RCP_MEP_UDP, 1, 1, 0, udp_port, 0, 1, RCP_VIDEO_CODING_MPEG4, RCP_VIDEO_RESOLUTION_4CIF
	};

	client_connect(&session, RCP_CONNECTION_METHOD_GET, RCP_MEDIA_TYPE_VIDEO, 0, &desc);

	pthread_create(&thread, NULL, keep_alive_thread, &session);

	rtp_merge_desc mdesc;
	rtp_init(RTP_PAYLOAD_TYPE_H263, 1, &mdesc);

	time_t end_time = time(NULL) + 10;
	while (time(NULL) < end_time)
	{
/*
		int num = recvfrom(con.stream_socket, buffer, 1500, 0, (struct sockaddr*)&si_remote, &slen);

		rtp_push_frame(buffer, num, &mdesc);
*/
		rtp_recv(session.stream_socket, &mdesc);

		if (rtp_pop_frame(&mdesc) == 0)
			fwrite(mdesc.data, mdesc.frame_lenght, 1, stdout);
	}

	pthread_cancel(thread);

	stop_message_manager();

	return 0;
}
Example #2
0
INT16 rtp_version_recv(RTP *rtp)
{
    UINT16 type;
    INT32  zero = 0;

    if (!rtp_recv(rtp, (UINT8 *) NULL, &type, &zero)) return (INT16) -1;
    return (INT16) type;
}
Example #3
0
void *rtp_thread (void *data)
{
    demux_t *demux = data;
    demux_sys_t *p_sys = demux->p_sys;
    bool autodetect = true;

    if (vlc_timer_create (&p_sys->timer, rtp_process, data))
        return NULL;
    vlc_cleanup_push (timer_cleanup, (void *)p_sys->timer);

    for (;;)
    {
        block_t *block = rtp_recv (demux);
        if (block == NULL)
            break;

        if (autodetect)
        {   /* Autodetect payload type, _before_ rtp_queue() */
            /* No need for lock - the queue is empty. */
            if (rtp_autodetect (demux, p_sys->session, block))
            {
                block_Release (block);
                continue;
            }
            autodetect = false;
        }

        int canc = vlc_savecancel ();
        vlc_mutex_lock (&p_sys->lock);
        rtp_queue (demux, p_sys->session, block);
        vlc_mutex_unlock (&p_sys->lock);
        vlc_restorecancel (canc);

        rtp_process (demux);
    }
    vlc_cleanup_run ();
    return NULL;
}
Example #4
0
int main(int argc, char* argv[])
{
	tlog_init(TLOG_MODE_STDERR, TLOG_INFO, NULL);

    if (argc < 3)
    {
        TL_INFO("%s <ip> <output>", argv[0]);
        return 0;
    }

	rcp_connect(argv[1]);

	start_message_manager();

	client_register(RCP_USER_LEVEL_LIVE, "", RCP_REGISTRATION_TYPE_NORMAL, RCP_ENCRYPTION_MODE_MD5);

	rcp_coder_list encoders, decoders;
	get_coder_list(RCP_CODER_ENCODER, RCP_MEDIA_TYPE_VIDEO, &encoders, 1);
	TL_DEBUG("***");
	for (int i=0; i<encoders.count; i++)
		TL_DEBUG("%x %x %x %x %x", encoders.coder[i].number, encoders.coder[i].caps, encoders.coder[i].current_cap, encoders.coder[i].param_caps, encoders.coder[i].current_param);
	TL_DEBUG("***");
	get_coder_list(RCP_CODER_DECODER, RCP_MEDIA_TYPE_VIDEO, &decoders, 1);
	TL_DEBUG("***");
	for (int i=0; i<decoders.count; i++)
		TL_DEBUG("%x %x %x %x %x", decoders.coder[i].number, decoders.coder[i].caps, decoders.coder[i].current_cap, decoders.coder[i].param_caps, decoders.coder[i].current_param);
	TL_DEBUG("***");

	rcp_session session;
	memset(&session, 0, sizeof(rcp_session));
	unsigned short udp_port = stream_connect_udp(&session);

	TL_DEBUG("udp port = %d", udp_port);

	rcp_media_descriptor desc = {
			RCP_MEP_UDP, 1, 1, 0, udp_port, 1, 1, RCP_VIDEO_CODING_H264, RCP_VIDEO_RESOLUTION_4CIF
	};

	client_connect(&session, RCP_CONNECTION_METHOD_GET, RCP_MEDIA_TYPE_VIDEO, 0, &desc);

	pthread_create(&thread, NULL, keep_alive_thread, &session);

	rtp_merge_desc mdesc;
	rtp_init(RTP_PAYLOAD_TYPE_H264, 1, &mdesc);

	signal(SIGTERM, term_handler);

	FILE * out = fopen(argv[2], "wb");

	while (!end)
	{
/*
		int num = recvfrom(con.stream_socket, buffer, 1500, 0, (struct sockaddr*)&si_remote, &slen);

		rtp_push_frame(buffer, num, &mdesc);
*/
		if (rtp_recv(session.stream_socket, &mdesc) == 0)
        {
			if (rtp_pop_frame(&mdesc) == 0)
			{
				fwrite(mdesc.data, mdesc.frame_lenght, 1, out);
			}
        }
		//char cmd[100];
		//sprintf(cmd, "kill %d", res);
		//system(cmd);
		//return 0;
	}

	fclose(out);

	pthread_cancel(thread);

	client_disconnect(&session);

	client_unregister();

	stop_message_manager();

	return 0;
}
Example #5
0
static void
rxmit_packets(struct cfg *cf, struct rtpp_session *sp, int ridx,
  double dtime)
{
    int ndrain, i, port;
    struct rtp_packet *packet = NULL;

    /* Repeat since we may have several packets queued on the same socket */
    for (ndrain = 0; ndrain < 5; ndrain++) {
	if (packet != NULL)
	    rtp_packet_free(packet);

	packet = rtp_recv(sp->fds[ridx]);
	if (packet == NULL)
	    break;
	packet->laddr = sp->laddr[ridx];
	packet->rport = sp->ports[ridx];
	packet->rtime = dtime;

	i = 0;
	if (sp->addr[ridx] != NULL) {
	    /* Check that the packet is authentic, drop if it isn't */
	    if (sp->asymmetric[ridx] == 0) {
		if (memcmp(sp->addr[ridx], &packet->raddr, packet->rlen) != 0) {
		    if (sp->canupdate[ridx] == 0) {
			/*
			 * Continue, since there could be good packets in
			 * queue.
			 */
			continue;
		    }
		    /* Signal that an address has to be updated */
		    i = 1;
		} else if (sp->canupdate[ridx] != 0 &&
		  sp->last_update[ridx] != 0 &&
		  dtime - sp->last_update[ridx] > UPDATE_WINDOW) {
		    sp->canupdate[ridx] = 0;
		}
	    } else {
		/*
		 * For asymmetric clients don't check
		 * source port since it may be different.
		 */
		if (!ishostseq(sp->addr[ridx], sstosa(&packet->raddr)))
		    /*
		     * Continue, since there could be good packets in
		     * queue.
		     */
		    continue;
	    }
	    sp->pcount[ridx]++;
	} else {
	    sp->pcount[ridx]++;
	    sp->addr[ridx] = malloc(packet->rlen);
	    if (sp->addr[ridx] == NULL) {
		sp->pcount[3]++;
		rtpp_log_write(RTPP_LOG_ERR, sp->log,
		  "can't allocate memory for remote address - "
		  "removing session");
		remove_session(cf, GET_RTP(sp));
		/* Break, sp is invalid now */
		break;
	    }
	    /* Signal that an address have to be updated. */
	    i = 1;
	}

	/*
	 * Update recorded address if it's necessary. Set "untrusted address"
	 * flag in the session state, so that possible future address updates
	 * from that client won't get address changed immediately to some
	 * bogus one.
	 */
	if (i != 0) {
	    sp->untrusted_addr[ridx] = 1;
	    memcpy(sp->addr[ridx], &packet->raddr, packet->rlen);
	    if (sp->prev_addr[ridx] == NULL || memcmp(sp->prev_addr[ridx],
	      &packet->raddr, packet->rlen) != 0) {
	        sp->canupdate[ridx] = 0;
	    }

	    port = ntohs(satosin(&packet->raddr)->sin_port);

	    rtpp_log_write(RTPP_LOG_INFO, sp->log,
	      "%s's address filled in: %s:%d (%s)",
	      (ridx == 0) ? "callee" : "caller",
	      addr2char(sstosa(&packet->raddr)), port,
	      (sp->rtp == NULL) ? "RTP" : "RTCP");

	    /*
	     * Check if we have updated RTP while RTCP is still
	     * empty or contains address that differs from one we
	     * used when updating RTP. Try to guess RTCP if so,
	     * should be handy for non-NAT'ed clients, and some
	     * NATed as well.
	     */
	    if (sp->rtcp != NULL && (sp->rtcp->addr[ridx] == NULL ||
	      !ishostseq(sp->rtcp->addr[ridx], sstosa(&packet->raddr)))) {
		if (sp->rtcp->addr[ridx] == NULL) {
		    sp->rtcp->addr[ridx] = malloc(packet->rlen);
		    if (sp->rtcp->addr[ridx] == NULL) {
			sp->pcount[3]++;
			rtpp_log_write(RTPP_LOG_ERR, sp->log,
			  "can't allocate memory for remote address - "
			  "removing session");
			remove_session(cf, sp);
			/* Break, sp is invalid now */
			break;
		    }
		}
		memcpy(sp->rtcp->addr[ridx], &packet->raddr, packet->rlen);
		satosin(sp->rtcp->addr[ridx])->sin_port = htons(port + 1);
		/* Use guessed value as the only true one for asymmetric clients */
		sp->rtcp->canupdate[ridx] = NOT(sp->rtcp->asymmetric[ridx]);
		rtpp_log_write(RTPP_LOG_INFO, sp->log, "guessing RTCP port "
		  "for %s to be %d",
		  (ridx == 0) ? "callee" : "caller", port + 1);
	    }
	}

	if (sp->resizers[ridx].output_nsamples > 0)
	    rtp_resizer_enqueue(&sp->resizers[ridx], &packet);
	if (packet != NULL)
	    send_packet(cf, sp, ridx, packet);
    }

    if (packet != NULL)
	rtp_packet_free(packet);
}
Example #6
0
void *mod_cin (void *ptr)
{
  int rtpfd;                    /* RTP socket file descriptor */
  int rtcpfd;                   /* RTCP socket file descriptor */
  socklen_t addr_len;                 /* Data size, Bytes received */
  struct sockaddr_in rtps;      /* RTP socket */
  struct sockaddr_in rtcps;     /* RTCP socket */
  struct sockaddr_in remote;    /* Remote address information */
  vstr_t recv_data;             /* Received data */
  rtp_packet_t *packet;         /* Parsed RTP packet */

  fd_set readset;
  int fdmax;

  fprintf(stderr, "+ Communication input module loaded.\n");

  vstr_init (&recv_data, RTP_MTU_SIZE);

  if ((rtpfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("Error opening socket");
    exit(1);
  }

  if ((rtcpfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("Error opening socket");
    exit(1);
  }

  rtps.sin_family = AF_INET;			/* Internet protocol */
  rtps.sin_port = htons(RTP_PORT);		/* Port */
  rtps.sin_addr.s_addr = htonl(INADDR_ANY);	/* rtps address */
  memset(&(rtps.sin_zero), '\0', 8);		/* Zero the rest */

  if (bind(rtpfd, (struct sockaddr *) &rtps, sizeof(struct sockaddr)) < 0) {
    perror("Error binding socket");
    exit(1);
  }

  rtcps.sin_family = AF_INET;			/* Internet protocol */
  rtcps.sin_port = htons(RTCP_PORT);		/* Port */
  rtcps.sin_addr.s_addr = htonl(INADDR_ANY);	/* rtcps address */
  memset(&(rtcps.sin_zero), '\0', 8);		/* Zero the rest */

  if (bind(rtcpfd, (struct sockaddr *) &rtcps, sizeof(struct sockaddr)) < 0) {
    perror("Error binding socket");
    exit(1);
  }

  fprintf(stderr, "+ RTP Listening at %s:%d...\n",
        inet_ntoa(rtps.sin_addr), ntohs(rtps.sin_port));

  fprintf(stderr, "+ RTCP Listening at %s:%d...\n",
        inet_ntoa(rtcps.sin_addr), ntohs(rtcps.sin_port));

  addr_len = sizeof(struct sockaddr);

  while(1)
  {
    FD_ZERO (&readset);
    FD_SET (rtpfd, &readset);
    FD_SET (rtcpfd, &readset);
    fdmax = (rtpfd < rtcpfd) ? rtcpfd : rtpfd;

    select (fdmax + 1, &readset, NULL, NULL, NULL);

    if (FD_ISSET(rtpfd, &readset)) {

      
      /* Receive data from network */
      recv_data.size = recvfrom (rtpfd, recv_data.data, RTP_MTU_SIZE, 0, (struct sockaddr *)&remote, &addr_len);
      printf("receive data, size = %d!!!!!!!!!!!!!!!!!\n", recv_data.size);
      vstr_adv_tail (&recv_data, recv_data.size);
      if (recv_data.size < 0) {
        perror("Error receiving data from socket");
        exit(1);
      }

      /* Write to buffer */
      packet = rtp_recv (&rtp, &recv_data);
      if (packet != NULL && rtp_enqueue (&rtp, packet) == -1)
        rtp_packet_free (packet);

      vstr_flush (&recv_data);
    }

    if (FD_ISSET(rtcpfd, &readset)) {

      /* Receive data from network */
      recv_data.size = recvfrom (rtcpfd, recv_data.data, RTP_MTU_SIZE, 0, (struct sockaddr *)&remote, &addr_len);
      vstr_adv_tail (&recv_data, recv_data.size);
      if (recv_data.size < 0) {
        perror("Error receiving data from socket");
        exit(1);
      }

      rtcp_recv (&rtp, &recv_data);

      vstr_flush (&recv_data);
    }

  }
}
Example #7
0
void *
os_sound_start_thread (void *_ca)
{
  int i;
  call_t *ca = (call_t *) _ca;
  struct timeval timeout;
  uint32_t rtp_ts, round;
  uint8_t mulaw_buffer[MULAW_BYTES * 16];
  int mulaw_buffer_pos;

#ifdef USE_PCM
  char data_out[MULAW_BYTES * 2 * 16];
#endif

  fprintf (stderr, "Sending and listening to ");
  fprintf (stderr, "%s port %d (local SSRC = 0x%08x)\n",
           rtp_get_addr (ca->rtp_session),
           rtp_get_rx_port (ca->rtp_session), rtp_my_ssrc (ca->rtp_session));

  round = 0;
  mulaw_buffer_pos = 0;

  while (ca->enable_audio != -1)
    {
      struct timeval t_beg;
      struct timeval t_end;
      struct timeval interval;

      gettimeofday (&t_beg, NULL);

      round++;
      /* original line rtp_ts = round * MULAW_MS; */
      rtp_ts = round * MULAW_BYTES;

      if (ca->local_sendrecv != _RECVONLY)
        {
          if (mulaw_buffer_pos < MULAW_BYTES * 4)
            {
              /* Send control packets */
              rtp_send_ctrl (ca->rtp_session, rtp_ts, NULL);

              /* Send data packets */
#ifdef USE_PCM
              i = read (ca->fd, data_out, MULAW_BYTES * 4);
              if (ca->local_sendrecv == _SENDRECV
                  || ca->local_sendrecv == _RECVONLY)
                {
              } else
                {
                  if (i < MULAW_BYTES * 4)
                    {
                      memset (data_out, 0, MULAW_BYTES * 4);
                      OSIP_TRACE (osip_trace
                                  (__FILE__, __LINE__, OSIP_INFO2, NULL,
                                   "restarting: %i\n", i));
                      close (ca->fd);
                      /* send a wav file! */
                      ca->fd = open (ca->wav_file, O_RDONLY);
                      if (ca->fd < 0)
                        {
                          OSIP_TRACE (osip_trace
                                      (__FILE__, __LINE__, OSIP_INFO2, NULL,
                                       "Could not open wav file: %s\n",
                                       ca->wav_file));
                          ca->fd = -1;
                          break;
                        }
                      i = read (ca->fd, data_out, MULAW_BYTES * 4);
                    }
                }
              if (ca->payload == 8)     /* A-Law */
                alaw_enc (data_out, mulaw_buffer + mulaw_buffer_pos, i);
              if (ca->payload == 0)     /* Mu-Law */
                mulaw_enc (data_out, mulaw_buffer + mulaw_buffer_pos, i);
              i = i / 2;
              mulaw_buffer_pos = mulaw_buffer_pos + i;
#else
              memset (mulaw_buffer + mulaw_buffer_pos, 0, MULAW_BYTES * 2);
              i = read (ca->fd, mulaw_buffer + mulaw_buffer_pos, MULAW_BYTES * 2);      /* ?? */
              mulaw_buffer_pos = mulaw_buffer_pos + i;
#endif
            }

          i = 0;
          if (mulaw_buffer_pos >= MULAW_BYTES)
            {
              i = rtp_send_data (ca->rtp_session, rtp_ts, ca->payload,
                                 0, 0, 0, (char *) mulaw_buffer, MULAW_BYTES,
                                 0, 0, 0);
              memmove (mulaw_buffer, mulaw_buffer + MULAW_BYTES, MULAW_BYTES * 15);
              mulaw_buffer_pos = mulaw_buffer_pos - MULAW_BYTES;
            }
      } else
        {
          /* Send control packets */
          rtp_send_ctrl (ca->rtp_session, rtp_ts, NULL);
        }

      /* Receive control and data packets */
      timeout.tv_sec = 0;
      timeout.tv_usec = 0;
      i = rtp_recv (ca->rtp_session, &timeout, rtp_ts);
      /* State maintenance */
      rtp_update (ca->rtp_session);

      gettimeofday (&t_end, NULL);

      /* make a diff between t_beg and t_end */
      interval.tv_sec = t_end.tv_sec - t_beg.tv_sec;
      interval.tv_usec = t_end.tv_usec - t_beg.tv_usec;

      if (interval.tv_usec < 0)
        {
          interval.tv_usec += 1000000L;
          --interval.tv_sec;
        }
      interval.tv_usec = (MULAW_MS * 1000 - interval.tv_usec);
      if (interval.tv_usec < 0)
        {
          interval.tv_usec += 1000000L;
          --interval.tv_sec;
        }
      if (interval.tv_sec < 0)
        {
          interval.tv_sec = 0;
          interval.tv_usec = 0;
        }
      select (0, NULL, NULL, NULL, &interval);
    }
  return NULL;
}
Example #8
0
static BOOL handshake(RTP *rtp)
{
UINT16 type;
INT16 client_version;
INT32 unused;
struct rtp_attr attr;
UINT8 msgbuf[RTP_MAXMSGLEN];
static CHAR *fid = "handshake";

/* Get the client protocol version number */
 
    rtp_log(RTP_DEBUG, "%s: read client protocol version", fid);
    if ((client_version = rtp_version_recv(rtp)) < 0) {
        rtp_log(RTP_ERR, "%s: rtp_version_recv: error %d",
            fid, client_version
        );
        return FALSE;
    }
    rtp_log(RTP_DEBUG, "%s: client version is %d", fid, client_version);

/* Send back our version number */
 
    rtp_log(RTP_DEBUG, "%s: send server protcol version %d",
        fid, RTP_VERSION
    );
    if (!rtp_version_send(rtp)) {
        rtp_log(RTP_ERR, "%s: rtp_version_send failed", fid);
        return FALSE;
    }

/* If the client is a higher version, protocol says quit now */
 
    if (client_version > RTP_VERSION) {
        rtp_log(RTP_ERR, "%s: unsupported protocol version (%d)",
            fid, client_version
        );
        return FALSE;
    }
 
/* Following is specific to protocol version */
 
    if (client_version == 1) {

    /* client should begin with its process id */

        if (!rtp_recv(rtp, msgbuf, &type, &unused)) {
            rtp_log(RTP_ERR, "%s: rtp_recv failed", fid);
            return FALSE;
        }

        if (type != RTP_MSG_PID) {
            rtp_log(RTP_ERR, "%s: unexpected message type %d != %d",
                fid, type, RTP_MSG_ATTR
            );
            errno = EPROTO;
            return FALSE;
        }

        rtp_pid_decode(msgbuf, &rtp->pid);
        rtp_log(RTP_DEBUG, "%s: client process id is %d", fid, rtp->pid);

    /* which we acknowledge with our process id */

        rtp_log(RTP_DEBUG, "%s: send pid ack", fid);
        if (!rtp_pid_send(rtp)) {
            rtp_log(RTP_ERR, "%s: rtp_pid_send failed", fid);
            return FALSE;
        }

    /* client should then send its attribute request */

        if (!rtp_recv(rtp, msgbuf, &type, &unused)) {
            rtp_log(RTP_ERR, "%s: rtp_recv failed", fid);
            return FALSE;
        }

        if (type != RTP_MSG_ATTR) {
            rtp_log(RTP_ERR, "%s: unexpected message type %d != %d",
                fid, type, RTP_MSG_ATTR
            );
            errno = EPROTO;
            return FALSE;
        }

        rtp_attr_decode(msgbuf, &attr);
        rtp_log(RTP_DEBUG, "%s: client attribute request received", fid);

    /* which will load in and echo back (maybe change it, too) */

        if (!set_attr(rtp, &attr)) {
            rtp_log(RTP_ERR, "%s: set_attr failed", fid);
            rtp_break(rtp);
            return FALSE;
        }

        rtp_log(RTP_DEBUG, "%s: send attribute ack", fid);
        if (!rtp_attr_send(rtp, &attr)) {
            return FALSE;
        }

    } else {
        rtp_log(RTP_ERR, "%s: unsupported protocol version (%d)",
            fid, client_version
        );
        errno = EPROTO;
        rtp_break(rtp);
        return FALSE;
    }

    rtp_log(RTP_DEBUG, "%s: handshake complete", fid);
    return TRUE;
}
Example #9
0
/****************************************************************************
 * RTP receive routines
 ****************************************************************************/
int CPlayerMedia::recv_thread (void)
{
  struct timeval timeout;
  int retcode;
  CMsg *newmsg;
  int recv_thread_stop = 0;

  m_rtp_buffering = 0;
  if (m_ports != NULL) {
    /*
     * We need to free up the ports that we got before RTP tries to set 
     * them up, so we don't have any re-use conflicts.  There is a small
     * window here that they might get used...
     */
    delete m_ports; // free up the port numbers
    m_ports = NULL;
  }

#ifdef _WIN32
  WORD wVersionRequested;
  WSADATA wsaData;
  int ret;
 
  wVersionRequested = MAKEWORD( 2, 0 );
  
  ret = WSAStartup( wVersionRequested, &wsaData );
  if ( ret != 0 ) {
    abort();
  }
#endif
  rtp_init(false);
  if (m_rtp_session != NULL) {
    rtp_start();
  }

  
  while (recv_thread_stop == 0) {
    if ((newmsg = m_rtp_msg_queue.get_message()) != NULL) {
      //player_debug_message("recv thread message %d", newmsg->get_value());
      switch (newmsg->get_value()) {
      case MSG_STOP_THREAD:
	recv_thread_stop = 1;
	break;
      case MSG_PAUSE_SESSION:
	// Indicate that we need to restart the session.
	// But keep going...
	rtp_start();
	break;
      }
      delete newmsg;
      newmsg = NULL;
    }
    if (recv_thread_stop == 1) {
      continue;
    }
    if (m_rtp_session == NULL) {
      SDL_Delay(50); 
    } else {
      if (m_rtp_session_from_outside) {
	SDL_Delay(500);
      } else {
	timeout.tv_sec = 0;
	timeout.tv_usec = 500000;
	retcode = rtp_recv(m_rtp_session, &timeout, 0);
      }
      //      player_debug_message("rtp_recv return %d", retcode);
      // Run rtp periodic after each packet received or idle time.
      if (m_paused == false || m_stream_ondemand != 0)
	rtp_periodic();
    }
    
  }
  /*
   * When we're done, send a bye, close up rtp, and go home
   */
  rtp_end();
  return (0);
}