Пример #1
0
static GstFlowReturn
gst_real_audio_demux_chain (GstPad * pad, GstBuffer * buf)
{
  GstRealAudioDemux *demux;

  demux = GST_REAL_AUDIO_DEMUX (GST_PAD_PARENT (pad));

  return gst_real_audio_demux_handle_buffer (demux, buf);
}
Пример #2
0
static GstFlowReturn
gst_real_audio_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstRealAudioDemux *demux;

  demux = GST_REAL_AUDIO_DEMUX (parent);

  return gst_real_audio_demux_handle_buffer (demux, buf);
}
Пример #3
0
static void
gst_real_audio_demux_loop (GstRealAudioDemux * demux)
{
  GstFlowReturn ret;
  GstBuffer *buf;
  guint bytes_needed;

  /* check how much data we need */
  switch (demux->state) {
    case REAL_AUDIO_DEMUX_STATE_MARKER:
      bytes_needed = 6 + 16;    /* 16 are beginning of header */
      break;
    case REAL_AUDIO_DEMUX_STATE_HEADER:
      if (!gst_real_audio_demux_get_data_offset_from_header (demux))
        goto parse_header_error;
      bytes_needed = demux->data_offset - (6 + 16);
      break;
    case REAL_AUDIO_DEMUX_STATE_DATA:
      if (demux->packet_size > 0) {
        /* TODO: should probably take into account width/height as well? */
        bytes_needed = demux->packet_size;
      } else {
        bytes_needed = 1024;
      }
      break;
    default:
      g_return_if_reached ();
  }

  /* now get the data */
  GST_LOG_OBJECT (demux, "getting data: %5u bytes @ %8" G_GINT64_MODIFIER "u",
      bytes_needed, demux->offset);

  if (demux->upstream_size > 0 && demux->offset >= demux->upstream_size)
    goto eos;

  ret = gst_pad_pull_range (demux->sinkpad, demux->offset, bytes_needed, &buf);

  if (ret != GST_FLOW_OK)
    goto pull_range_error;

  if (GST_BUFFER_SIZE (buf) != bytes_needed)
    goto pull_range_short_read;

  ret = gst_real_audio_demux_handle_buffer (demux, buf);
  if (ret != GST_FLOW_OK)
    goto handle_flow_error;

  /* TODO: increase this in chain function too (for timestamps)? */
  demux->offset += bytes_needed;

  /* check for the end of the segment */
  if (demux->segment.stop != -1 && demux->segment.last_stop != -1 &&
      demux->segment.last_stop > demux->segment.stop) {
    GST_DEBUG_OBJECT (demux, "reached end of segment");
    goto eos;
  }

  return;

/* ERRORS */
parse_header_error:
  {
    GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL), (NULL));
    goto pause_task;
  }
handle_flow_error:
  {
    GST_WARNING_OBJECT (demux, "handle_buf flow: %s", gst_flow_get_name (ret));
    goto pause_task;
  }
pull_range_error:
  {
    GST_WARNING_OBJECT (demux, "pull range flow: %s", gst_flow_get_name (ret));
    goto pause_task;
  }
pull_range_short_read:
  {
    GST_WARNING_OBJECT (demux, "pull range short read: wanted %u bytes, but "
        "got only %u bytes", bytes_needed, GST_BUFFER_SIZE (buf));
    gst_buffer_unref (buf);
    goto eos;
  }
eos:
  {
    if (demux->state != REAL_AUDIO_DEMUX_STATE_DATA) {
      GST_WARNING_OBJECT (demux, "reached EOS before finished parsing header");
      goto parse_header_error;
    }
    GST_INFO_OBJECT (demux, "EOS");
    if ((demux->segment.flags & GST_SEEK_FLAG_SEGMENT) != 0) {
      gint64 stop;

      /* for segment playback we need to post when (in stream time)
       * we stopped, this is either stop (when set) or the duration. */
      if ((stop = demux->segment.stop) == -1)
        stop = demux->segment.duration;

      GST_DEBUG_OBJECT (demux, "sending segment done, at end of segment");
      gst_element_post_message (GST_ELEMENT (demux),
          gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
              stop));
    } else {
      /* normal playback, send EOS event downstream */
      GST_DEBUG_OBJECT (demux, "sending EOS event, at end of stream");
      gst_pad_push_event (demux->srcpad, gst_event_new_eos ());
    }
    goto pause_task;
  }
pause_task:
  {
    demux->segment_running = FALSE;
    gst_pad_pause_task (demux->sinkpad);
    GST_DEBUG_OBJECT (demux, "pausing task");
    return;
  }
}