*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
/**
* <refsect2>
* <title>Example pipelines</title>
* |[
- * gst-launch audiotestsrc num-buffers=100 ! speexenc ! oggmux ! filesink location=beep.ogg
+ * gst-launch-1.0 audiotestsrc num-buffers=100 ! speexenc ! oggmux ! filesink location=beep.ogg
* ]| Encode an Ogg/Speex file.
* </refsect2>
*/
"The last status message", NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- gst_element_class_add_pad_template (gstelement_class,
- gst_static_pad_template_get (&src_factory));
- gst_element_class_add_pad_template (gstelement_class,
- gst_static_pad_template_get (&sink_factory));
- gst_element_class_set_details_simple (gstelement_class, "Speex audio encoder",
- "Codec/Encoder/Audio",
+ gst_element_class_add_static_pad_template (gstelement_class, &src_factory);
+ gst_element_class_add_static_pad_template (gstelement_class, &sink_factory);
+ gst_element_class_set_static_metadata (gstelement_class,
+ "Speex audio encoder", "Codec/Encoder/Audio",
"Encodes audio in Speex format", "Wim Taymans <wim@fluendo.com>");
GST_DEBUG_CATEGORY_INIT (speexenc_debug, "speexenc", 0, "Speex encoder");
/* arrange granulepos marking (and required perfect ts) */
gst_audio_encoder_set_mark_granule (benc, TRUE);
gst_audio_encoder_set_perfect_timestamp (benc, TRUE);
+ GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (enc));
}
static gboolean
speex_bits_init (&enc->bits);
enc->tags = gst_tag_list_new_empty ();
enc->header_sent = FALSE;
+ enc->encoded_samples = 0;
return TRUE;
}
enc->state = NULL;
}
speex_bits_destroy (&enc->bits);
- gst_tag_list_free (enc->tags);
+ speex_bits_set_bit_buffer (&enc->bits, NULL, 0);
+ gst_tag_list_unref (enc->tags);
enc->tags = NULL;
gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
GST_DEBUG_OBJECT (enc, "merged tags = %" GST_PTR_FORMAT, merged_tags);
comments = gst_tag_list_to_vorbiscomment_buffer (merged_tags, NULL,
0, "Encoded with GStreamer Speexenc");
- gst_tag_list_free (merged_tags);
+ gst_tag_list_unref (merged_tags);
GST_BUFFER_OFFSET (comments) = 0;
GST_BUFFER_OFFSET_END (comments) = 0;
}
break;
}
+ case GST_EVENT_SEGMENT:
+ enc->encoded_samples = 0;
+ break;
default:
break;
}
gsize bsize, size;
GstBuffer *outbuf;
GstFlowReturn ret = GST_FLOW_OK;
+ GstSegment *segment;
+ GstClockTime duration;
if (G_LIKELY (buf)) {
gst_buffer_map (buf, &map, GST_MAP_READ);
if (G_UNLIKELY (bsize % bytes)) {
GST_DEBUG_OBJECT (enc, "draining; adding silence samples");
+ /* If encoding part of a frame, and we have no set stop time on
+ * the output segment, we update the segment stop time to reflect
+ * the last sample. This will let oggmux set the last page's
+ * granpos to tell a decoder the dummy samples should be clipped.
+ */
+ segment = &GST_AUDIO_ENCODER_OUTPUT_SEGMENT (enc);
+ GST_DEBUG_OBJECT (enc, "existing output segment %" GST_SEGMENT_FORMAT,
+ segment);
+ if (!GST_CLOCK_TIME_IS_VALID (segment->stop)) {
+ int input_samples = bsize / (enc->channels * 2);
+ GST_DEBUG_OBJECT (enc,
+ "No stop time and partial frame, updating segment");
+ duration =
+ gst_util_uint64_scale (enc->encoded_samples + input_samples,
+ GST_SECOND, enc->rate);
+ segment->stop = segment->start + duration;
+ GST_DEBUG_OBJECT (enc, "new output segment %" GST_SEGMENT_FORMAT,
+ segment);
+ gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (enc),
+ gst_event_new_segment (segment));
+ }
+
size = ((bsize / bytes) + 1) * bytes;
data0 = data = g_malloc0 (size);
memcpy (data, bdata, bsize);
ret = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc),
outbuf, samples);
+ enc->encoded_samples += frame_size;
done:
g_free (data0);
/*
* (really really) FIXME: move into core (dixit tpm)
*/
-/**
+/*
* _gst_caps_set_buffer_array:
- * @caps: a #GstCaps
+ * @caps: (transfer full): a #GstCaps
* @field: field in caps to set
* @buf: header buffers
*
* Adds given buffers to an array of buffers set as the given @field
* on the given @caps. List of buffer arguments must be NULL-terminated.
*
- * Returns: input caps with a streamheader field added, or NULL if some error
+ * Returns: (transfer full): input caps with a streamheader field added, or NULL
+ * if some error occurred
*/
static GstCaps *
_gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
buf = va_arg (va, GstBuffer *);
}
+ va_end (va);
gst_structure_set_value (structure, field, &array);
g_value_unset (&array);