Exemplo n.º 1
0
static GstFlowReturn
gst_rtp_mpv_pay_flush (GstRTPMPVPay * rtpmpvpay, GstClockTime timestamp,
    GstClockTime duration)
{
  GstBuffer *outbuf;
  GstFlowReturn ret;
  guint avail;
  guint8 *payload;
  gint packet_size;
  gint payload_size;

  avail = gst_adapter_available (rtpmpvpay->adapter);
  packet_size = gst_rtp_buffer_calc_packet_len (4 + avail, 0, 0);

  /* check for the maximum size of the rtp buffer */
  if (packet_size > GST_BASE_RTP_PAYLOAD_MTU (rtpmpvpay)) {
    payload_size =
        GST_BASE_RTP_PAYLOAD_MTU (rtpmpvpay) -
        gst_rtp_buffer_calc_packet_len (4, 0, 0);
  } else {
    payload_size = avail;
  }
  outbuf = gst_rtp_buffer_new_allocate (4 + payload_size, 0, 0);
  /* enable MPEG Video-specific header
   *
   *  0                   1                   2                   3
   *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |    MBZ  |T|         TR        | |N|S|B|E|  P  | | BFC | | FFC |
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   *                                  AN              FBV     FFV
   */
  payload = gst_rtp_buffer_get_payload (outbuf);
  /* fill in the MPEG Video-specific header */
  memset (payload, 0x0, 4);
  /* copy stuff from adapter to payload */
  gst_adapter_copy (rtpmpvpay->adapter, payload + 4, 0, payload_size);
  GST_BUFFER_TIMESTAMP (outbuf) = rtpmpvpay->first_ts;
  GST_BUFFER_DURATION (outbuf) = rtpmpvpay->duration;

  GST_DEBUG_OBJECT (rtpmpvpay, "pushing buffer of size %d",
      GST_BUFFER_SIZE (outbuf));
  ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmpvpay), outbuf);
  gst_adapter_flush (rtpmpvpay->adapter, payload_size);

  /* update the timestamp and duration */
  rtpmpvpay->first_ts = timestamp;
  rtpmpvpay->duration = duration;

  /* check if there is enough data for another rtp buffer */
  avail = gst_adapter_available (rtpmpvpay->adapter);
  packet_size = gst_rtp_buffer_calc_packet_len (4 + avail, 0, 0);

  if (packet_size >= GST_BASE_RTP_PAYLOAD_MTU (rtpmpvpay) && ret == GST_FLOW_OK) {
    GST_DEBUG_OBJECT (rtpmpvpay, "Have enough data for another rtp packet");
    ret = gst_rtp_mpv_pay_flush (rtpmpvpay, timestamp, duration);
  }
  return ret;
}
Exemplo n.º 2
0
static GstFlowReturn
gst_rtp_mpv_pay_handle_buffer (GstRTPBasePayload * basepayload,
    GstBuffer * buffer)
{
  GstRTPMPVPay *rtpmpvpay;
  guint avail, packet_len;
  GstClockTime timestamp, duration;
  GstFlowReturn ret = GST_FLOW_OK;

  rtpmpvpay = GST_RTP_MPV_PAY (basepayload);

  timestamp = GST_BUFFER_TIMESTAMP (buffer);
  duration = GST_BUFFER_DURATION (buffer);

  if (GST_BUFFER_IS_DISCONT (buffer)) {
    GST_DEBUG_OBJECT (rtpmpvpay, "DISCONT");
    gst_rtp_mpv_pay_reset (rtpmpvpay);
  }

  avail = gst_adapter_available (rtpmpvpay->adapter);

  if (duration == -1)
    duration = 0;

  if (rtpmpvpay->first_ts == GST_CLOCK_TIME_NONE || avail == 0)
    rtpmpvpay->first_ts = timestamp;

  if (avail == 0) {
    rtpmpvpay->duration = duration;
  } else {
    rtpmpvpay->duration += duration;
  }

  gst_adapter_push (rtpmpvpay->adapter, buffer);
  avail = gst_adapter_available (rtpmpvpay->adapter);

  /* get packet length of previous data and this new data,
   * payload length includes a 4 byte MPEG video-specific header */
  packet_len = gst_rtp_buffer_calc_packet_len (avail, 4, 0);
  GST_LOG_OBJECT (rtpmpvpay, "available %d, rtp packet length %d", avail,
      packet_len);

  if (gst_rtp_base_payload_is_filled (basepayload,
          packet_len, rtpmpvpay->duration)) {
    ret = gst_rtp_mpv_pay_flush (rtpmpvpay);
  } else {
    rtpmpvpay->first_ts = timestamp;
  }

  return ret;
}
Exemplo n.º 3
0
static GstFlowReturn
gst_rtp_mpv_pay_handle_buffer (GstBaseRTPPayload * basepayload,
    GstBuffer * buffer)
{
  GstRTPMPVPay *rtpmpvpay;
  guint size, avail, packet_len;
  guint8 *data;
  GstClockTime timestamp, duration;
  GstFlowReturn ret;

  rtpmpvpay = GST_RTP_MPV_PAY (basepayload);

  size = GST_BUFFER_SIZE (buffer);
  data = GST_BUFFER_DATA (buffer);
  timestamp = GST_BUFFER_TIMESTAMP (buffer);
  duration = GST_BUFFER_DURATION (buffer);

  gst_adapter_push (rtpmpvpay->adapter, buffer);
  avail = gst_adapter_available (rtpmpvpay->adapter);

  /* Initialize new RTP payload */
  if (avail == 0) {
    rtpmpvpay->first_ts = timestamp;
    rtpmpvpay->duration = duration;
  }

  /* get packet length of previous data and this new data,
   * payload length includes a 4 byte MPEG video-specific header */
  packet_len = gst_rtp_buffer_calc_packet_len (4 + avail, 0, 0);

  if (gst_basertppayload_is_filled (basepayload,
          packet_len, rtpmpvpay->duration + duration)) {
    ret = gst_rtp_mpv_pay_flush (rtpmpvpay, timestamp, duration);
  } else {
    if (GST_CLOCK_TIME_IS_VALID (duration))
      rtpmpvpay->duration += duration;
    ret = GST_FLOW_OK;
  }
  return ret;
}
Exemplo n.º 4
0
static gboolean
gst_rtp_mpv_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event)
{
  gboolean ret;
  GstRTPMPVPay *rtpmpvpay;

  rtpmpvpay = GST_RTP_MPV_PAY (payload);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
      /* make sure we push the last packets in the adapter on EOS */
      gst_rtp_mpv_pay_flush (rtpmpvpay);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_rtp_mpv_pay_reset (rtpmpvpay);
      break;
    default:
      break;
  }

  ret = GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->sink_event (payload, event);

  return ret;
}