int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer, int rdt_rawdata) {

  int n=1;
  uint8_t header[8];
  rmff_pheader_t ph;
  int size;
  int flags1, flags2;
  int unknown1;
  uint32_t ts;
  static uint32_t prev_ts = -1;
  static int prev_stream_number = -1;

  n=rtsp_read_data(rtsp_session, header, 8);
  if (n<8) return 0;
  if (header[0] != 0x24)
  {
    mp_msg(MSGT_STREAM, MSGL_WARN, "realrtsp: rdt chunk not recognized: got 0x%02x\n",
      header[0]);
    return 0;
  }
  /* header[1] is channel, normally 0, ignored */
  size=(header[2]<<8)+header[3];
  flags1=header[4];
  if ((flags1 & 0xc0) != 0x40)
  {
#ifdef LOG
    printf("got flags1: 0x%02x\n",flags1);
#endif
    if(header[6] == 0x06) { // eof packet
      rtsp_read_data(rtsp_session, header, 7); // Skip the rest of the eof packet
      /* Some files have short auxiliary streams, we must ignore eof packets
       * for these streams to avoid premature eof.
       * Now the code declares eof only if the stream with id == 0 gets eof
       * (old code was: eof on the first eof packet received).
       */
      if(flags1 & 0x7c) // ignore eof for streams with id != 0
        return 0;
      mp_msg(MSGT_STREAM, MSGL_INFO, "realrtsp: Stream EOF detected\n");
      return -1;
    }
    header[0]=header[5];
    header[1]=header[6];
    header[2]=header[7];
    n=rtsp_read_data(rtsp_session, header+3, 5);
    if (n<5) return 0;
#ifdef LOG
    printf("ignoring bytes:\n");
    hexdump(header, 8);
#endif
    n=rtsp_read_data(rtsp_session, header+4, 4);
    if (n<4) return 0;
    flags1=header[4];
    size-=9;
  }
  flags2=header[7];
  // header[5..6] == frame number in stream
  unknown1=(header[5]<<16)+(header[6]<<8)+(header[7]);
  n=rtsp_read_data(rtsp_session, header, 6);
  if (n<6) return 0;
  ts=AV_RB32(header);

#ifdef LOG
  printf("ts: %u, size: %u, flags: 0x%02x, unknown values: 0x%06x 0x%02x 0x%02x\n",
          ts, size, flags1, unknown1, header[4], header[5]);
#endif
  size+=2;

  ph.object_version=0;
  ph.length=size;
  ph.stream_number=(flags1>>1)&0x1f;
  ph.timestamp=ts;
  ph.reserved=0;
  if ((flags2&1) == 0 && (prev_ts != ts || prev_stream_number != ph.stream_number))
  {
    prev_ts = ts;
    prev_stream_number = ph.stream_number;
    ph.flags=2;
  }
  else
    ph.flags=0;
  *buffer = xbuffer_ensure_size(*buffer, 12+size);
  if(rdt_rawdata) {
      if (size < 12)
          return 0;
    n=rtsp_read_data(rtsp_session, *buffer, size-12);
    return (n <= 0) ? 0 : n;
  }
  rmff_dump_pheader(&ph, *buffer);
  if (size < 12)
      return 0;
  size-=12;
  n=rtsp_read_data(rtsp_session, (*buffer)+12, size);

  return (n <= 0) ? 0 : n+12;
}
예제 #2
0
static int real_process_media_packet(struct stream_t *stream,uint8_t *header,
				     uint8_t *buffer,size_t max_size)
{
    int ret = 0;
    struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;
    struct rmff_pheader_t ph = {0};
    int size = 0;
    int seq = 0;
    int flags1 = 0,flags2 = 0;
    uint32_t ts = 0;

    if(header[0] != 0x24) {
	display(MSDL_ERR,"wrong rdt magic : [0x%02x]\n",header[0]);
	/* dump header*/
	dbgdump(header,8);
	display(MSDL_DBG,"\n");
	goto failed;
    }

    size = (header[1] << 16) + (header[2] << 8) + header[3];
    flags1 = header[4];
  
    if((flags1!=0x40) && (flags1!=0x42)) {
	display(MSDL_DBG,"wrong rdt flags1 : [0x%02x]\n",flags1);
	if(header[6] == 0x06) {
	    display(MSDL_DBG,"got end of stream packet\n");
	    stream_ctrl->status = STREAMING_FINISHED;
	    return 0;
	}
	header[0] = header[5];
	header[1] = header[6];
	header[2] = header[7];
	
	ret = read_data(stream,header + 3,5);
	if(ret < 5) goto failed;
    
	ret = read_data(stream,header + 4,4);
	if(ret < 4) goto failed;
    
	flags1 = header[4];
	size -= 9;
    
    }
    flags2 = header[7];
    seq = (header[5] << 8) + header[6];
    ret = read_data(stream,header,6);
    if(ret < 6) goto failed;
  
    ts = get32_be(header);
    stream_ctrl->packet_count++;
    display(MSDL_DBG,"ts:%u size:%u, flags1:0x%02x, seq:%d, flags2:%x\n",
	    ts,size,flags1,seq,flags2);
    
    size += 2;
  
    ph.object_version = 0;
    ph.length = size;
    ph.stream_number = (flags1>>1) & 1;
    ph.timestamp = ts;
    ph.reserved = 0;
  
    if((flags2 & 1) == 0 &&
       (stream_ctrl->rtsp_ctrl->prev_ts != ts ||
	stream_ctrl->rtsp_ctrl->prev_stream_number != ph.stream_number)) {
	stream_ctrl->rtsp_ctrl->prev_ts = ts;
	stream_ctrl->rtsp_ctrl->prev_stream_number = ph.stream_number;
	ph.flags = 2;
    }
    else {
	ph.flags = 0;
    }
  

    /*
     * Keep Alive SET_PARAMETER
     */
    /*if(!(stream_ctrl->packet_count % 200)) {
	struct rtsp_header_t *rtsp_hdr;
	rtsp_hdr = new_rtsp_header_with_standard_fields(stream_ctrl->rtsp_ctrl);
	if(stream->dlopts->bandwidth) {
	    char *buffer = xmalloc(BUFSIZE_1K);
	    snprintf(buffer,BUFSIZE_1K - 1,
		     "SetDeliveryBandwidth: Bandwidth=%d;BackOff=0",stream->dlopts->bandwidth);
	    rtsp_set_field(rtsp_hdr,buffer);
	    free(buffer);
	}
	rtsp_request_set_parameter(rtsp_hdr,stream_ctrl->rtsp_ctrl->mrl);
	rtsp_send_request_and_free(stream,rtsp_hdr);
	}*/

    
    /* if buffering, do special thing */
    if(stream_ctrl->status == STREAMING_RESUME_BUFFERING) {
	display(MSDL_DBG,
		"target ts: %d [0x%x], current packet ts: %d [0x%x]\n",
		stream_ctrl->rtsp_ctrl->resume_start_ts,
		stream_ctrl->rtsp_ctrl->resume_start_ts,
		ph.timestamp,ph.timestamp);

	if(ph.timestamp == stream_ctrl->rtsp_ctrl->resume_start_ts) {
	    stream_ctrl->status = STREAMING_DOWNLOADING; /* fallthrouh */
	}
	else {
	    int ret = 0;
	    ret = read_data(stream,stream_ctrl->write_buffer,size - 12); /* trash data */
	    if(ret <= 0) goto failed;
	    return 0;
	}
    }


    if(max_size > size) {
	/* all data can go to buffer --> just do it!! */
	rmff_dump_pheader(&ph,buffer);
	size -= 12;
	ret = read_data(stream,buffer + 12,size);
	if(ret <= 0) goto failed;
    
	return ret + 12;
    }
    else {
	/*
	  buffer is not enough.. copy max_size data to 
	  buffer and the rest goes to netsock->buffer.
	*/
	rmff_dump_pheader(&ph,stream_ctrl->write_buffer);
    
	ret = read_data(stream,stream_ctrl->write_buffer + 12,size - 12);
	if(ret <= 0) goto failed;
	
	/*
	  it is guranteed that netsock->buffer is
	  empty when it comes here!
	  --> reset stream_ctrl->write_pos and so on...
	*/
    	memcpy(buffer,stream_ctrl->write_buffer,max_size);
	stream_ctrl->write_data_len = size - max_size;
	stream_ctrl->write_pos = max_size;
    
	return max_size;
    }
    
  failed:
    return -1;
}