GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-float, "
- "rate = (int) [ 1, 200000 ], "
- "channels = (int) [ 1, 255 ], " "endianness = (int) BYTE_ORDER, "
- "width = (int) 32")
+ GST_STATIC_CAPS ("audio/x-raw, "
+ "format = (string) " GST_AUDIO_NE (F32) ", "
+ "rate = (int) [ 1, 200000 ], " "channels = (int) [ 1, 255 ]")
);
static GstStaticPadTemplate vorbis_enc_src_factory =
GstAudioInfo * info);
static GstFlowReturn gst_vorbis_enc_handle_frame (GstAudioEncoder * enc,
GstBuffer * in_buf);
-static GstCaps *gst_vorbis_enc_getcaps (GstAudioEncoder * enc);
+static GstCaps *gst_vorbis_enc_getcaps (GstAudioEncoder * enc,
+ GstCaps * filter);
static gboolean gst_vorbis_enc_sink_event (GstAudioEncoder * enc,
GstEvent * event);
static GstFlowReturn gst_vorbis_enc_pre_push (GstAudioEncoder * enc,
GValue * value, GParamSpec * pspec);
static void gst_vorbis_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
-static void gst_vorbis_enc_add_interfaces (GType vorbisenc_type);
-GST_BOILERPLATE_FULL (GstVorbisEnc, gst_vorbis_enc, GstAudioEncoder,
- GST_TYPE_AUDIO_ENCODER, gst_vorbis_enc_add_interfaces);
-
-static void
-gst_vorbis_enc_add_interfaces (GType vorbisenc_type)
-{
- static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
-
- g_type_add_interface_static (vorbisenc_type, GST_TYPE_TAG_SETTER,
- &tag_setter_info);
-}
-
-static void
-gst_vorbis_enc_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&vorbis_enc_src_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&vorbis_enc_sink_factory));
-
- gst_element_class_set_details_simple (element_class,
- "Vorbis audio encoder", "Codec/Encoder/Audio",
- "Encodes audio in Vorbis format",
- "Monty <monty@xiph.org>, " "Wim Taymans <wim@fluendo.com>");
-}
+#define gst_vorbis_enc_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstVorbisEnc, gst_vorbis_enc,
+ GST_TYPE_AUDIO_ENCODER, G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));
static void
gst_vorbis_enc_class_init (GstVorbisEncClass * klass)
{
GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
GstAudioEncoderClass *base_class;
gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
base_class = (GstAudioEncoderClass *) (klass);
gobject_class->set_property = gst_vorbis_enc_set_property;
gobject_class->get_property = gst_vorbis_enc_get_property;
gobject_class->dispose = gst_vorbis_enc_dispose;
- base_class->start = GST_DEBUG_FUNCPTR (gst_vorbis_enc_start);
- base_class->stop = GST_DEBUG_FUNCPTR (gst_vorbis_enc_stop);
- base_class->set_format = GST_DEBUG_FUNCPTR (gst_vorbis_enc_set_format);
- base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vorbis_enc_handle_frame);
- base_class->getcaps = GST_DEBUG_FUNCPTR (gst_vorbis_enc_getcaps);
- base_class->event = GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_event);
- base_class->pre_push = GST_DEBUG_FUNCPTR (gst_vorbis_enc_pre_push);
-
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
g_param_spec_int ("max-bitrate", "Maximum Bitrate",
"Specify a maximum bitrate (in bps). Useful for streaming "
g_param_spec_string ("last-message", "last-message",
"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 (&vorbis_enc_src_factory));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&vorbis_enc_sink_factory));
+
+ gst_element_class_set_details_simple (gstelement_class,
+ "Vorbis audio encoder", "Codec/Encoder/Audio",
+ "Encodes audio in Vorbis format",
+ "Monty <monty@xiph.org>, " "Wim Taymans <wim@fluendo.com>");
+
+ base_class->start = GST_DEBUG_FUNCPTR (gst_vorbis_enc_start);
+ base_class->stop = GST_DEBUG_FUNCPTR (gst_vorbis_enc_stop);
+ base_class->set_format = GST_DEBUG_FUNCPTR (gst_vorbis_enc_set_format);
+ base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vorbis_enc_handle_frame);
+ base_class->getcaps = GST_DEBUG_FUNCPTR (gst_vorbis_enc_getcaps);
+ base_class->event = GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_event);
+ base_class->pre_push = GST_DEBUG_FUNCPTR (gst_vorbis_enc_pre_push);
}
static void
-gst_vorbis_enc_init (GstVorbisEnc * vorbisenc, GstVorbisEncClass * klass)
+gst_vorbis_enc_init (GstVorbisEnc * vorbisenc)
{
GstAudioEncoder *enc = GST_AUDIO_ENCODER (vorbisenc);
GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
GST_DEBUG_OBJECT (enc, "start");
- vorbisenc->tags = gst_tag_list_new ();
+ vorbisenc->tags = gst_tag_list_new_empty ();
vorbisenc->header_sent = FALSE;
return TRUE;
GstCaps *caps = gst_caps_new_empty ();
int i, c;
- gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw-float",
+ gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
+ "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
"rate", GST_TYPE_INT_RANGE, 1, 200000,
- "channels", G_TYPE_INT, 1,
- "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32,
- NULL));
+ "channels", G_TYPE_INT, 1, NULL));
- gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw-float",
+ gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
+ "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
"rate", GST_TYPE_INT_RANGE, 1, 200000,
- "channels", G_TYPE_INT, 2,
- "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32,
- NULL));
+ "channels", G_TYPE_INT, 2, NULL));
for (i = 3; i <= 8; i++) {
GValue chanpos = { 0 };
}
g_value_unset (&pos);
- structure = gst_structure_new ("audio/x-raw-float",
- "rate", GST_TYPE_INT_RANGE, 1, 200000,
- "channels", G_TYPE_INT, i,
- "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
+ structure = gst_structure_new ("audio/x-raw",
+ "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
+ "rate", GST_TYPE_INT_RANGE, 1, 200000, "channels", G_TYPE_INT, i, NULL);
gst_structure_set_value (structure, "channel-positions", &chanpos);
g_value_unset (&chanpos);
gst_caps_append_structure (caps, structure);
}
- gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw-float",
+ gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
+ "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
"rate", GST_TYPE_INT_RANGE, 1, 200000,
- "channels", GST_TYPE_INT_RANGE, 9, 255,
- "endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32,
- NULL));
+ "channels", GST_TYPE_INT_RANGE, 9, 255, NULL));
return caps;
}
static GstCaps *
-gst_vorbis_enc_getcaps (GstAudioEncoder * enc)
+gst_vorbis_enc_getcaps (GstAudioEncoder * enc, GstCaps * filter)
{
GstVorbisEnc *vorbisenc = GST_VORBISENC (enc);
+ GstCaps *caps;
if (vorbisenc->sinkcaps == NULL)
vorbisenc->sinkcaps = gst_vorbis_enc_generate_sink_caps ();
- return gst_audio_encoder_proxy_getcaps (enc, vorbisenc->sinkcaps);
+ if (filter) {
+ GstCaps *int_caps = gst_caps_intersect_full (filter, vorbisenc->sinkcaps,
+ GST_CAPS_INTERSECT_FIRST);
+ caps = gst_audio_encoder_proxy_getcaps (enc, int_caps);
+ gst_caps_unref (int_caps);
+ } else {
+ caps = gst_audio_encoder_proxy_getcaps (enc, vorbisenc->sinkcaps);
+ }
+
+ return caps;
}
static gint64
GstBuffer *outbuf;
outbuf = gst_buffer_new_and_alloc (packet->bytes);
- memcpy (GST_BUFFER_DATA (outbuf), packet->packet, packet->bytes);
+ gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
GST_BUFFER_OFFSET (outbuf) = vorbisenc->bytes_out;
GST_BUFFER_OFFSET_END (outbuf) = 0;
GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
- GST_DEBUG ("created header packet buffer, %d bytes",
- GST_BUFFER_SIZE (outbuf));
+ GST_DEBUG ("created header packet buffer, %" G_GSIZE_FORMAT " bytes",
+ gst_buffer_get_size (outbuf));
return outbuf;
}
"Pushing buffer with GP %" G_GINT64_FORMAT ", ts %" GST_TIME_FORMAT,
GST_BUFFER_OFFSET_END (buffer),
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
- gst_buffer_set_caps (buffer,
- GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (vorbisenc)));
return gst_pad_push (GST_AUDIO_ENCODER_SRC_PAD (vorbisenc), buffer);
}
va_start (va, buf);
/* put buffers in a fixed list */
while (buf) {
- g_assert (gst_buffer_is_metadata_writable (buf));
+ g_assert (gst_buffer_is_writable (buf));
/* mark buffer */
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
{
GstVorbisEnc *vorbisenc;
GstFlowReturn ret = GST_FLOW_OK;
- gfloat *data;
+ gfloat *data, *ptr;
gulong size;
+ gsize bsize;
gulong i, j;
float **vorbis_buffer;
GstBuffer *buf1, *buf2, *buf3;
buf3 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_code);
/* mark and put on caps */
- caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-vorbis");
caps = _gst_caps_set_buffer_array (caps, "streamheader",
buf1, buf2, buf3, NULL);
/* negotiate with these caps */
GST_DEBUG_OBJECT (vorbisenc, "here are the caps: %" GST_PTR_FORMAT, caps);
-
- gst_buffer_set_caps (buf1, caps);
- gst_buffer_set_caps (buf2, caps);
- gst_buffer_set_caps (buf3, caps);
gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (vorbisenc), caps);
gst_caps_unref (caps);
if (!buffer)
return gst_vorbis_enc_clear (vorbisenc);
+ data = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_WRITE);
+
/* data to encode */
- data = (gfloat *) GST_BUFFER_DATA (buffer);
- size = GST_BUFFER_SIZE (buffer) / (vorbisenc->channels * sizeof (float));
+ size = bsize / (vorbisenc->channels * sizeof (float));
+
+ ptr = data;
/* expose the buffer to submit data */
vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
/* deinterleave samples, write the buffer data */
for (i = 0; i < size; i++) {
for (j = 0; j < vorbisenc->channels; j++) {
- vorbis_buffer[j][i] = *data++;
+ vorbis_buffer[j][i] = *ptr++;
}
}
/* tell the library how much we actually submitted */
vorbis_analysis_wrote (&vorbisenc->vd, size);
+ gst_buffer_unmap (buffer, data, bsize);
GST_LOG_OBJECT (vorbisenc, "wrote %lu samples to vorbis", size);
GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
buf = gst_buffer_new_and_alloc (op.bytes);
- memcpy (GST_BUFFER_DATA (buf), op.packet, op.bytes);
+ gst_buffer_fill (buf, 0, op.packet, op.bytes);
/* tracking granulepos should tell us samples accounted for */
ret =
gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER