Пример #1
0
static event_t *
sendpkt(rtmp_t *r, media_queue_t *mq, media_codec_t *mc,
	int64_t dts, int64_t pts, const void *data, 
	size_t size, int skip, int dt, int duration, int drive_clock)
{
  event_t *e = NULL;
  media_buf_t *mb = media_buf_alloc_unlocked(r->mp, size);

  mb->mb_data_type = dt;
  mb->mb_duration = duration;
  mb->mb_cw = media_codec_ref(mc);
  mb->mb_drive_clock = drive_clock;
  mb->mb_dts = dts;
  mb->mb_pts = pts;
  mb->mb_skip = skip;
	
  memcpy(mb->mb_data, data, size);

  do {

    if(mb == NULL || (e = mb_enqueue_with_events(r->mp, mq, mb)) == NULL) {
      mb = NULL;
      break;
    }

    e = rtmp_process_event(r, e, &mb);

  } while(e == NULL);

  if(mb != NULL)
    media_buf_free_unlocked(r->mp, mb);

  return e;
}
Пример #2
0
static event_t *
sendpkt(rtmp_t *r, media_queue_t *mq, media_codec_t *mc,
	int64_t dts, int64_t pts, int64_t time, const void *data, 
	size_t size, int skip, int dt, int duration)
{
  event_t *e = NULL;
  media_buf_t *mb = media_buf_alloc_unlocked(r->mp, size);

  mb->mb_data_type = dt;
  mb->mb_duration = duration;
  mb->mb_cw = media_codec_ref(mc);
  mb->mb_time = time;
  mb->mb_dts = dts;
  mb->mb_pts = pts;
  mb->mb_skip = skip;
  mb->mb_send_pts = dt == MB_VIDEO;
	
  memcpy(mb->mb_data, data, size);
  mb->mb_epoch = r->epoch;

  do {

    if(mb == NULL || (e = mb_enqueue_with_events(r->mp, mq, mb)) == NULL)
      break;
    
    e = rtmp_process_event(r, e, &mb);

  } while(e == NULL);

  return e;
}
Пример #3
0
static event_t *
sendpkt(rtmp_t *r, media_queue_t *mq, media_codec_t *mc,
	int64_t dts, int64_t pts, int64_t time, const void *data, 
	size_t size, int skip, int dt, int duration)
{
  event_t *e = NULL;
  media_buf_t *mb = media_buf_alloc();

  mb->mb_data_type = dt;
  mb->mb_duration = duration;
  mb->mb_cw = media_codec_ref(mc);
  mb->mb_time = time;
  mb->mb_dts = dts;
  mb->mb_pts = pts;
  mb->mb_skip = skip;

  mb->mb_data = malloc(size +   FF_INPUT_BUFFER_PADDING_SIZE);
  memset(mb->mb_data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
  memcpy(mb->mb_data, data, size);
  mb->mb_size = size;
  mb->mb_epoch = r->epoch;

  do {

    if(mb == NULL || (e = mb_enqueue_with_events(r->mp, mq, mb)) == NULL)
      break;
    
    e = rtmp_process_event(r, e, &mb);

  } while(e == NULL);

  return e;
}
Пример #4
0
static event_t *
rtmp_loop(rtmp_t *r, media_pipe_t *mp, char *url, char *errbuf, size_t errlen)
{
  RTMPPacket p = {0};
  int pos = -1, ret;
  uint32_t dts;
  event_t *e = NULL;

  while(1) {


    if(pos == -1) {

      mp->mp_eof = 0;
      ret = RTMP_GetNextMediaPacket(r->r, &p);

      if(ret == 2) {
	/* Wait for queues to drain */
	mp->mp_eof = 1;
      again:
	e = mp_wait_for_empty_queues(mp);

	if(e != NULL) {
	  e = rtmp_process_event(r, e, NULL);
	  if(e == NULL)
	    goto again;
	}

	if(e == NULL)
	  e = event_create_type(EVENT_EOF);
	break;
      }

      if(ret == 0) {
	int64_t restartpos = r->seekpos_video;

        if(cancellable_is_cancelled(mp->mp_cancellable)) {
          snprintf(errbuf, errlen, "Cancelled");
          return NULL;
        }

	TRACE(TRACE_ERROR, "RTMP", "Disconnected");
	sleep(1);

	if(restartpos == AV_NOPTS_VALUE) {
	  snprintf(errbuf, errlen,
		   "Giving up restart since nothing was decoded");
	  return NULL;
	}


	RTMP_Close(r->r);

	RTMP_Init(r->r, mp->mp_cancellable);

	memset(&p, 0, sizeof(p));

	TRACE(TRACE_DEBUG, "RTMP", "Reconnecting stream at pos %ld", 
	      restartpos);

	if(!RTMP_SetupURL(r->r, url)) {
	  snprintf(errbuf, errlen, "Unable to setup RTMP session");
	  return NULL;
	}

	if(!RTMP_Connect(r->r, NULL, errbuf, errlen, 5000)) {
	  return NULL;
	}

	if(!RTMP_ConnectStream(r->r, 0)) {
	  snprintf(errbuf, errlen, "Unable to stream RTMP session");
	  return NULL;
	}

	if(mp->mp_flags & MP_CAN_SEEK)
	  RTMP_SendSeek(r->r, restartpos / 1000);
	continue;
      }

      dts = p.m_nTimeStamp;

      switch(p.m_packetType) {
      case RTMP_PACKET_TYPE_INFO:
	if(handle_metadata(r, p.m_body, p.m_nBodySize, mp, errbuf, errlen)) {
	  RTMPPacket_Free(&p);
	  return NULL;
	}
	break;

      case RTMP_PACKET_TYPE_VIDEO:
	e = get_packet_v(r, (void *)p.m_body, p.m_nBodySize, dts, mp);
	break;

      case RTMP_PACKET_TYPE_AUDIO:
	e = get_packet_a(r, (void *)p.m_body, p.m_nBodySize, dts, mp);
	break;
	
      case 0x16:
	pos = 0;
	break;
      default:
	TRACE(TRACE_DEBUG, "RTMP", 
	      "Got unknown packet type %d\n", p.m_packetType);
	break;
      }
      if(pos == -1)
	RTMPPacket_Free(&p);
    }

    if(pos != -1) {
      if(pos + 11 < p.m_nBodySize) {
	uint32_t ds = AMF_DecodeInt24(p.m_body + pos + 1);
	  
	if(pos + 11 + ds + 4 > p.m_nBodySize) {
	  snprintf(errbuf, errlen, "Corrupt stream");
	  RTMPPacket_Free(&p);
	  return NULL;
	}

	dts = AMF_DecodeInt24(p.m_body + pos + 4);
	dts |= (p.m_body[pos + 7] << 24);

	if(p.m_body[pos] == RTMP_PACKET_TYPE_INFO) {
	  if(handle_metadata(r, p.m_body, p.m_nBodySize, mp, errbuf, errlen)) {
	    RTMPPacket_Free(&p);
	    return NULL;
	  }
	} else if(p.m_body[pos] == RTMP_PACKET_TYPE_VIDEO) {
	  e = get_packet_v(r, (void *)p.m_body + pos + 11, ds, dts, mp);
	} else if(p.m_body[pos] == RTMP_PACKET_TYPE_AUDIO) {
	  e = get_packet_a(r, (void *)p.m_body + pos + 11, ds, dts, mp);
	} else {
	  TRACE(TRACE_DEBUG, "RTMP", 
		"Got unknown packet type %d\n", p.m_body[pos]);
	}
	pos += 11 + ds + 4;
      } else {
	pos = -1;
	RTMPPacket_Free(&p);
      }
    }
    if(e != NULL)
      break;
  }
  return e;
}
Пример #5
0
static event_t *
rtmp_loop(rtmp_t *r, media_pipe_t *mp, char *url, char *errbuf, size_t errlen)
{
  RTMPPacket p = {0};
  int pos = -1, ret;
  uint32_t dts;
  event_t *e = NULL;

  mp_set_playstatus_by_hold(mp, 0, NULL);

  while(1) {


    if(pos == -1) {

      mp->mp_eof = 0;
      ret = RTMP_GetNextMediaPacket(r->r, &p);

      if(ret == 2) {
	/* Wait for queues to drain */
	mp->mp_eof = 1;
      again:
	e = mp_wait_for_empty_queues(mp);

	if(e != NULL) {
	  e = rtmp_process_event(r, e, NULL);
	  if(e == NULL)
	    goto again;
	}
	mp_set_playstatus_stop(mp);

	if(e == NULL)
	  e = event_create_type(EVENT_EOF);
	break;
      }

      if(ret == 0) {
	RTMP_Close(r->r);
	  
	RTMP_Init(r->r);

	memset(&p, 0, sizeof(p));

	TRACE(TRACE_DEBUG, "RTMP", "Reconnecting stream at pos %d", 
	      r->seekbase);

	if(!RTMP_SetupURL(r->r, url)) {
	  snprintf(errbuf, errlen, "Unable to setup RTMP session");
	  e = NULL;
	  break;
	}

	if(!RTMP_Connect(r->r, NULL)) {
	  snprintf(errbuf, errlen, "Unable to connect RTMP session");
	  e = NULL;
	  break;
	}

	if(!RTMP_ConnectStream(r->r, r->can_seek ? r->seekbase / 1000 : 0)) {
	  snprintf(errbuf, errlen, "Unable to stream RTMP session");
	  return NULL;
	}
	r->epoch++;


	r->lastdts = 0;
	r->seekbase = AV_NOPTS_VALUE;
	mp_flush(mp, 0);
	continue;
      }

      dts = p.m_nTimeStamp;

      switch(p.m_packetType) {
      case RTMP_PACKET_TYPE_INFO:
	if(handle_metadata(r, p.m_body, p.m_nBodySize, mp, errbuf, errlen)) {
	  RTMPPacket_Free(&p);
	  return NULL;
	}
	break;

      case RTMP_PACKET_TYPE_VIDEO:
	e = get_packet_v(r, (void *)p.m_body, p.m_nBodySize, dts, mp);
	break;

      case RTMP_PACKET_TYPE_AUDIO:
	e = get_packet_a(r, (void *)p.m_body, p.m_nBodySize, dts, mp);
	break;
	
      case 0x16:
	pos = 0;
	break;
      default:
	TRACE(TRACE_DEBUG, "RTMP", 
	      "Got unknown packet type %d\n", p.m_packetType);
	break;
      }
      if(pos == -1)
	RTMPPacket_Free(&p);
    }

    if(pos != -1) {
      if(pos + 11 < p.m_nBodySize) {
	uint32_t ds = AMF_DecodeInt24(p.m_body + pos + 1);
	  
	if(pos + 11 + ds + 4 > p.m_nBodySize) {
	  snprintf(errbuf, errlen, "Corrupt stream");
	  RTMPPacket_Free(&p);
	  return NULL;
	}

	dts = AMF_DecodeInt24(p.m_body + pos + 4);
	dts |= (p.m_body[pos + 7] << 24);

	if(p.m_body[pos] == RTMP_PACKET_TYPE_INFO) {
	  if(handle_metadata(r, p.m_body, p.m_nBodySize, mp, errbuf, errlen)) {
	    RTMPPacket_Free(&p);
	    return NULL;
	  }
	} else if(p.m_body[pos] == RTMP_PACKET_TYPE_VIDEO) {
	  e = get_packet_v(r, (void *)p.m_body + pos + 11, ds, dts, mp);
	} else if(p.m_body[pos] == RTMP_PACKET_TYPE_AUDIO) {
	  e = get_packet_a(r, (void *)p.m_body + pos + 11, ds, dts, mp);
	} else {
	  TRACE(TRACE_DEBUG, "RTMP", 
		"Got unknown packet type %d\n", p.m_body[pos]);
	}
	pos += 11 + ds + 4;
      } else {
	pos = -1;
	RTMPPacket_Free(&p);
      }
    }
    if(e != NULL)
      break;
  }
  return e;
}