static GstFlowReturn gst_wavenc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) { GstWavEnc *wavenc = GST_WAVENC (parent); GstFlowReturn flow = GST_FLOW_OK; if (wavenc->channels <= 0) { GST_ERROR_OBJECT (wavenc, "Got data without caps"); return GST_FLOW_NOT_NEGOTIATED; } if (G_UNLIKELY (!wavenc->sent_header)) { gst_pad_set_caps (wavenc->srcpad, gst_static_pad_template_get_caps (&src_factory)); /* starting a file, means we have to finish it properly */ wavenc->finished_properly = FALSE; /* push initial bogus header, it will be updated on EOS */ flow = gst_wavenc_push_header (wavenc); if (flow != GST_FLOW_OK) { GST_WARNING_OBJECT (wavenc, "error pushing header: %s", gst_flow_get_name (flow)); return flow; } GST_DEBUG_OBJECT (wavenc, "wrote dummy header"); wavenc->audio_length = 0; wavenc->sent_header = TRUE; } GST_LOG_OBJECT (wavenc, "pushing %" G_GSIZE_FORMAT " bytes raw audio, ts=%" GST_TIME_FORMAT, gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); buf = gst_buffer_make_writable (buf); GST_BUFFER_OFFSET (buf) = WAV_HEADER_LEN + wavenc->audio_length; GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE; wavenc->audio_length += gst_buffer_get_size (buf); flow = gst_pad_push (wavenc->srcpad, buf); return flow; }
static gboolean gst_wavenc_event (GstPad * pad, GstEvent * event) { gboolean res = TRUE; GstWavEnc *wavenc; wavenc = GST_WAVENC (gst_pad_get_parent (pad)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS:{ GST_DEBUG_OBJECT (wavenc, "got EOS"); #if 0 /* Write our metadata if we have any */ if (wavenc->metadata) { write_metadata (wavenc); write_cues (wavenc); write_labels (wavenc); } #endif /* write header with correct length values */ gst_wavenc_push_header (wavenc, wavenc->length); /* we're done with this file */ wavenc->finished_properly = TRUE; /* and forward the EOS event */ res = gst_pad_event_default (pad, event); break; } case GST_EVENT_NEWSEGMENT: /* Just drop it, it's probably in TIME format * anyway. We'll send our own newsegment event */ gst_event_unref (event); break; default: res = gst_pad_event_default (pad, event); break; } gst_object_unref (wavenc); return res; }
static GstFlowReturn gst_wavenc_chain (GstPad * pad, GstBuffer * buf) { GstWavEnc *wavenc = GST_WAVENC (GST_PAD_PARENT (pad)); GstFlowReturn flow = GST_FLOW_OK; g_return_val_if_fail (wavenc->channels > 0, GST_FLOW_WRONG_STATE); if (!wavenc->sent_header) { /* use bogus size initially, we'll write the real * header when we get EOS and know the exact length */ flow = gst_wavenc_push_header (wavenc, 0x7FFF0000); if (flow != GST_FLOW_OK) return flow; GST_DEBUG_OBJECT (wavenc, "wrote dummy header"); wavenc->sent_header = TRUE; } wavenc->length += GST_BUFFER_SIZE (buf); GST_LOG_OBJECT (wavenc, "pushing %u bytes raw audio, ts=%" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); if (wavenc->width != wavenc->depth) { buf = gst_buffer_make_writable (buf); gst_wavenc_format_samples (buf, wavenc->width, wavenc->depth); } else { buf = gst_buffer_make_metadata_writable (buf); } gst_buffer_set_caps (buf, GST_PAD_CAPS (wavenc->srcpad)); GST_BUFFER_OFFSET (buf) = WAV_HEADER_LEN + wavenc->length; GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE; flow = gst_pad_push (wavenc->srcpad, buf); return flow; }
static GstFlowReturn gst_wavenc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) { GstWavEnc *wavenc = GST_WAVENC (parent); GstFlowReturn flow = GST_FLOW_OK; g_return_val_if_fail (wavenc->channels > 0, GST_FLOW_FLUSHING); if (G_UNLIKELY (!wavenc->sent_header)) { /* starting a file, means we have to finish it properly */ wavenc->finished_properly = FALSE; /* use bogus size initially, we'll write the real * header when we get EOS and know the exact length */ flow = gst_wavenc_push_header (wavenc); if (flow != GST_FLOW_OK) { GST_WARNING_OBJECT (wavenc, "error pushing header: %s", gst_flow_get_name (flow)); return flow; } GST_DEBUG_OBJECT (wavenc, "wrote dummy header"); wavenc->sent_header = TRUE; } GST_LOG_OBJECT (wavenc, "pushing %" G_GSIZE_FORMAT " bytes raw audio, ts=%" GST_TIME_FORMAT, gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); buf = gst_buffer_make_writable (buf); GST_BUFFER_OFFSET (buf) = WAV_HEADER_LEN + wavenc->audio_length; GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE; wavenc->audio_length += gst_buffer_get_size (buf); flow = gst_pad_push (wavenc->srcpad, buf); return flow; }
static gboolean gst_wavenc_event (GstPad * pad, GstObject * parent, GstEvent * event) { gboolean res = TRUE; GstWavEnc *wavenc; GstTagList *tags; GstToc *toc; wavenc = GST_WAVENC (parent); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CAPS: { GstCaps *caps; gst_event_parse_caps (event, &caps); gst_wavenc_sink_setcaps (pad, caps); /* have our own src caps */ gst_event_unref (event); break; } case GST_EVENT_EOS: { GstFlowReturn flow; GST_DEBUG_OBJECT (wavenc, "got EOS"); flow = gst_wavenc_write_toc (wavenc); if (flow != GST_FLOW_OK) { GST_WARNING_OBJECT (wavenc, "error pushing toc: %s", gst_flow_get_name (flow)); } flow = gst_wavenc_write_tags (wavenc); if (flow != GST_FLOW_OK) { GST_WARNING_OBJECT (wavenc, "error pushing tags: %s", gst_flow_get_name (flow)); } /* write header with correct length values */ gst_wavenc_push_header (wavenc); /* we're done with this file */ wavenc->finished_properly = TRUE; /* and forward the EOS event */ res = gst_pad_event_default (pad, parent, event); break; } case GST_EVENT_SEGMENT: /* Just drop it, it's probably in TIME format * anyway. We'll send our own newsegment event */ gst_event_unref (event); break; case GST_EVENT_TOC: gst_event_parse_toc (event, &toc, NULL); if (toc) { if (wavenc->toc != toc) { if (wavenc->toc) gst_toc_unref (wavenc->toc); wavenc->toc = toc; } else { gst_toc_unref (toc); } } res = gst_pad_event_default (pad, parent, event); break; case GST_EVENT_TAG: gst_event_parse_tag (event, &tags); if (tags) { if (wavenc->tags != tags) { if (wavenc->tags) gst_tag_list_unref (wavenc->tags); wavenc->tags = gst_tag_list_ref (tags); } } res = gst_pad_event_default (pad, parent, event); break; default: res = gst_pad_event_default (pad, parent, event); break; } return res; }
static gboolean gst_wavenc_event (GstPad * pad, GstObject * parent, GstEvent * event) { gboolean res = TRUE; GstWavEnc *wavenc; GstToc *toc; wavenc = GST_WAVENC (parent); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CAPS: { GstCaps *caps; gst_event_parse_caps (event, &caps); gst_wavenc_sink_setcaps (pad, caps); /* have our own src caps */ gst_event_unref (event); break; } case GST_EVENT_EOS:{ GST_DEBUG_OBJECT (wavenc, "got EOS"); if (!wavenc->toc) { GST_DEBUG_OBJECT (wavenc, "have no toc, checking toc_setter"); wavenc->toc = gst_toc_setter_get_toc (GST_TOC_SETTER (wavenc)); } if (wavenc->toc) { GST_DEBUG_OBJECT (wavenc, "have toc"); gst_wavenc_write_toc (wavenc); } #if 0 /* Write our metadata if we have any */ if (wavenc->metadata) { write_metadata (wavenc); write_cues (wavenc); write_labels (wavenc); } #endif /* write header with correct length values */ gst_wavenc_push_header (wavenc, wavenc->length); /* we're done with this file */ wavenc->finished_properly = TRUE; /* and forward the EOS event */ res = gst_pad_event_default (pad, parent, event); break; } case GST_EVENT_SEGMENT: /* Just drop it, it's probably in TIME format * anyway. We'll send our own newsegment event */ gst_event_unref (event); break; case GST_EVENT_TOC: gst_event_parse_toc (event, &toc, NULL); if (toc) { if (wavenc->toc != toc) { if (wavenc->toc) gst_toc_unref (wavenc->toc); wavenc->toc = toc; } else { gst_toc_unref (toc); } } res = gst_pad_event_default (pad, parent, event); break; default: res = gst_pad_event_default (pad, parent, event); break; } return res; }