static GstFlowReturn gst_wavpack_parse_chain (GstPad * pad, GstBuffer * buf) { GstWavpackParse *wvparse = GST_WAVPACK_PARSE (GST_PAD_PARENT (pad)); GstFlowReturn ret = GST_FLOW_OK; WavpackHeader wph; const guint8 *tmp_buf; if (!wvparse->adapter) { wvparse->adapter = gst_adapter_new (); } if (GST_BUFFER_IS_DISCONT (buf)) { gst_adapter_clear (wvparse->adapter); wvparse->discont = TRUE; } gst_adapter_push (wvparse->adapter, buf); if (gst_adapter_available (wvparse->adapter) < sizeof (WavpackHeader)) return ret; if (!gst_wavpack_parse_resync_adapter (wvparse->adapter)) return ret; tmp_buf = gst_adapter_peek (wvparse->adapter, sizeof (WavpackHeader)); gst_wavpack_read_header (&wph, (guint8 *) tmp_buf); while (gst_adapter_available (wvparse->adapter) >= wph.ckSize + 4 * 1 + 4) { GstBuffer *outbuf = gst_adapter_take_buffer (wvparse->adapter, wph.ckSize + 4 * 1 + 4); if (!outbuf) return GST_FLOW_ERROR; if (wvparse->srcpad == NULL) { if (!gst_wavpack_parse_create_src_pad (wvparse, outbuf, &wph)) { GST_ERROR_OBJECT (wvparse, "Failed to create src pad"); ret = GST_FLOW_ERROR; break; } } ret = gst_wavpack_parse_push_buffer (wvparse, outbuf, &wph); if (ret != GST_FLOW_OK) break; if (gst_adapter_available (wvparse->adapter) >= sizeof (WavpackHeader)) { tmp_buf = gst_adapter_peek (wvparse->adapter, sizeof (WavpackHeader)); if (!gst_wavpack_parse_resync_adapter (wvparse->adapter)) break; gst_wavpack_read_header (&wph, (guint8 *) tmp_buf); } } return ret; }
static void gst_wavpack_parse_loop (GstElement * element) { GstWavpackParse *parse = GST_WAVPACK_PARSE (element); GstFlowReturn flow_ret; WavpackHeader header = { {0,}, 0, }; GstBuffer *buf = NULL; flow_ret = gst_wavpack_parse_resync_loop (parse, &header); if (flow_ret != GST_FLOW_OK) goto pause; GST_LOG_OBJECT (parse, "Read header at offset %" G_GINT64_FORMAT ": chunk size = %u+8", parse->current_offset, header.ckSize); buf = gst_wavpack_parse_pull_buffer (parse, parse->current_offset, header.ckSize + 8, &flow_ret); if (flow_ret != GST_FLOW_OK) goto pause; if (parse->srcpad == NULL) { if (!gst_wavpack_parse_create_src_pad (parse, buf, &header)) { GST_ERROR_OBJECT (parse, "Failed to create src pad"); flow_ret = GST_FLOW_ERROR; goto pause; } } if (header.flags & INITIAL_BLOCK) gst_wavpack_parse_index_append_entry (parse, parse->current_offset, header.block_index, header.block_samples); flow_ret = gst_wavpack_parse_push_buffer (parse, buf, &header); if (flow_ret != GST_FLOW_OK) goto pause; return; pause: { const gchar *reason = gst_flow_get_name (flow_ret); GST_LOG_OBJECT (parse, "pausing task, reason %s", reason); gst_pad_pause_task (parse->sinkpad); if (GST_FLOW_IS_FATAL (flow_ret) || flow_ret == GST_FLOW_NOT_LINKED) { if (flow_ret == GST_FLOW_UNEXPECTED && parse->srcpad) { if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) { GstClockTime stop; GST_LOG_OBJECT (parse, "Sending segment done"); if ((stop = parse->segment.stop) == -1) stop = parse->segment.duration; gst_element_post_message (GST_ELEMENT_CAST (parse), gst_message_new_segment_done (GST_OBJECT_CAST (parse), parse->segment.format, stop)); } else { GST_LOG_OBJECT (parse, "Sending EOS, at end of stream"); gst_pad_push_event (parse->srcpad, gst_event_new_eos ()); } } else { GST_ELEMENT_ERROR (parse, STREAM, FAILED, (_("Internal data stream error.")), ("stream stopped, reason %s", reason)); if (parse->srcpad) gst_pad_push_event (parse->srcpad, gst_event_new_eos ()); } } return; } }