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); }
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); }
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; } }