mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-03 15:06:34 +00:00
ext/vorbis/vorbisenc.*: Multi-channel caps negotiation, so we can do proper multichannel vorbis encoding, negotiated ...
Original commit message from CVS: * ext/vorbis/vorbisenc.c: (raw_caps_factory), (gst_vorbis_enc_class_init), (gst_vorbis_enc_dispose), (gst_vorbis_enc_generate_sink_caps), (gst_vorbis_enc_sink_getcaps), (gst_vorbis_enc_init), (gst_vorbis_enc_buffer_from_header_packet), (gst_vorbis_enc_chain), (gst_vorbis_enc_change_state): * ext/vorbis/vorbisenc.h: Multi-channel caps negotiation, so we can do proper multichannel vorbis encoding, negotiated through audioconvert.
This commit is contained in:
parent
36ff3da6e2
commit
d2ddf5eba5
3 changed files with 138 additions and 7 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2006-05-30 Michael Smith <msmith@fluendo.com>
|
||||
|
||||
* ext/vorbis/vorbisenc.c: (raw_caps_factory),
|
||||
(gst_vorbis_enc_class_init), (gst_vorbis_enc_dispose),
|
||||
(gst_vorbis_enc_generate_sink_caps), (gst_vorbis_enc_sink_getcaps),
|
||||
(gst_vorbis_enc_init), (gst_vorbis_enc_buffer_from_header_packet),
|
||||
(gst_vorbis_enc_chain), (gst_vorbis_enc_change_state):
|
||||
* ext/vorbis/vorbisenc.h:
|
||||
Multi-channel caps negotiation, so we can do proper multichannel
|
||||
vorbis encoding, negotiated through audioconvert.
|
||||
|
||||
2006-05-30 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* tests/check/elements/adder.c: (test_event_message_received),
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
|
||||
#include <gst/gsttagsetter.h>
|
||||
#include <gst/tag/tag.h>
|
||||
#include <gst/audio/multichannel.h>
|
||||
#include "vorbisenc.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (vorbisenc_debug);
|
||||
|
@ -120,6 +121,7 @@ static gboolean gst_vorbis_enc_sink_event (GstPad * pad, GstEvent * event);
|
|||
static GstFlowReturn gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static gboolean gst_vorbis_enc_setup (GstVorbisEnc * vorbisenc);
|
||||
|
||||
static void gst_vorbis_enc_dispose (GObject * object);
|
||||
static void gst_vorbis_enc_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static void gst_vorbis_enc_set_property (GObject * object, guint prop_id,
|
||||
|
@ -149,12 +151,12 @@ vorbis_caps_factory (void)
|
|||
static GstCaps *
|
||||
raw_caps_factory (void)
|
||||
{
|
||||
/* lowest sample rate is in vorbis/lib/modes/setup_8.h, 8000 Hz
|
||||
* highest sample rate is in vorbis/lib/modes/setup_44.h, 50000 Hz */
|
||||
/* lowest, highest sample rates come from vorbis/lib/modes/setup_X.h:
|
||||
* 1-200000 Hz */
|
||||
return
|
||||
gst_caps_new_simple ("audio/x-raw-float",
|
||||
"rate", GST_TYPE_INT_RANGE, 8000, 50000,
|
||||
"channels", GST_TYPE_INT_RANGE, 1, 2,
|
||||
"rate", GST_TYPE_INT_RANGE, 1, 200000,
|
||||
"channels", GST_TYPE_INT_RANGE, 1, 256,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32, NULL);
|
||||
}
|
||||
|
||||
|
@ -189,6 +191,7 @@ gst_vorbis_enc_class_init (GstVorbisEncClass * 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;
|
||||
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BITRATE,
|
||||
g_param_spec_int ("max-bitrate", "Maximum Bitrate",
|
||||
|
@ -221,6 +224,113 @@ gst_vorbis_enc_class_init (GstVorbisEncClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_vorbis_enc_change_state);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vorbis_enc_dispose (GObject * object)
|
||||
{
|
||||
GstVorbisEnc *vorbisenc = GST_VORBISENC (object);
|
||||
|
||||
if (vorbisenc->sinkcaps) {
|
||||
gst_caps_unref (vorbisenc->sinkcaps);
|
||||
vorbisenc->sinkcaps = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static GstAudioChannelPosition vorbischannelpositions[][6] = {
|
||||
{ /* Mono */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_MONO},
|
||||
{ /* Stereo */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
|
||||
{ /* Stereo + Centre */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
|
||||
{ /* Quadraphonic */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
|
||||
},
|
||||
{ /* Stereo + Centre + rear stereo */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
|
||||
},
|
||||
{ /* Full 5.1 Surround */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE,
|
||||
},
|
||||
};
|
||||
static GstCaps *
|
||||
gst_vorbis_enc_generate_sink_caps (void)
|
||||
{
|
||||
GstCaps *caps = gst_caps_new_empty ();
|
||||
int i, c;
|
||||
|
||||
gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw-float",
|
||||
"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));
|
||||
|
||||
gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw-float",
|
||||
"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));
|
||||
|
||||
for (i = 3; i <= 6; i++) {
|
||||
GValue chanpos = { 0 };
|
||||
GValue pos = { 0 };
|
||||
GstStructure *structure;
|
||||
|
||||
g_value_init (&chanpos, GST_TYPE_ARRAY);
|
||||
g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION);
|
||||
|
||||
for (c = 0; c < i; c++) {
|
||||
g_value_set_enum (&pos, vorbischannelpositions[i - 1][c]);
|
||||
gst_value_array_append_value (&chanpos, &pos);
|
||||
}
|
||||
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);
|
||||
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",
|
||||
"rate", GST_TYPE_INT_RANGE, 1, 200000,
|
||||
"channels", GST_TYPE_INT_RANGE, 7, 256,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER, "width", G_TYPE_INT, 32,
|
||||
NULL));
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_vorbis_enc_sink_getcaps (GstPad * pad)
|
||||
{
|
||||
GstVorbisEnc *vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
|
||||
|
||||
if (vorbisenc->sinkcaps == NULL)
|
||||
vorbisenc->sinkcaps = gst_vorbis_enc_generate_sink_caps ();
|
||||
|
||||
return gst_caps_ref (vorbisenc->sinkcaps);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vorbis_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
|
@ -488,6 +598,8 @@ gst_vorbis_enc_init (GstVorbisEnc * vorbisenc, GstVorbisEncClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_vorbis_enc_chain));
|
||||
gst_pad_set_setcaps_function (vorbisenc->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_setcaps));
|
||||
gst_pad_set_getcaps_function (vorbisenc->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_getcaps));
|
||||
gst_pad_set_query_function (vorbisenc->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_vorbis_enc_sink_query));
|
||||
gst_element_add_pad (GST_ELEMENT (vorbisenc), vorbisenc->sinkpad);
|
||||
|
@ -807,6 +919,8 @@ gst_vorbis_enc_buffer_from_header_packet (GstVorbisEnc * vorbisenc,
|
|||
GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
|
||||
|
||||
gst_buffer_set_caps (outbuf, vorbisenc->srccaps);
|
||||
|
||||
GST_DEBUG ("created header packet buffer, %d bytes",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
return outbuf;
|
||||
|
@ -958,7 +1072,8 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
|
|||
buf3 = gst_vorbis_enc_buffer_from_header_packet (vorbisenc, &header_code);
|
||||
|
||||
/* mark and put on caps */
|
||||
caps = gst_pad_get_caps (vorbisenc->srcpad);
|
||||
vorbisenc->srccaps = gst_caps_new_simple ("audio/x-vorbis", NULL);
|
||||
caps = vorbisenc->srccaps;
|
||||
caps = gst_vorbis_enc_set_header_on_caps (caps, buf1, buf2, buf3);
|
||||
|
||||
/* negotiate with these caps */
|
||||
|
@ -969,8 +1084,6 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
|
|||
gst_buffer_set_caps (buf2, caps);
|
||||
gst_buffer_set_caps (buf3, caps);
|
||||
|
||||
gst_caps_unref (caps);
|
||||
|
||||
/* push out buffers */
|
||||
if ((ret = gst_vorbis_enc_push_buffer (vorbisenc, buf1)) != GST_FLOW_OK)
|
||||
goto failed_header_push;
|
||||
|
@ -1210,6 +1323,10 @@ gst_vorbis_enc_change_state (GstElement * element, GstStateChange transition)
|
|||
vorbis_info_clear (&vorbisenc->vi);
|
||||
g_free (vorbisenc->last_message);
|
||||
vorbisenc->last_message = NULL;
|
||||
if (vorbisenc->srccaps) {
|
||||
gst_caps_unref (vorbisenc->srccaps);
|
||||
vorbisenc->srccaps = NULL;
|
||||
}
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
gst_tag_list_free (vorbisenc->tags);
|
||||
|
|
|
@ -53,6 +53,9 @@ struct _GstVorbisEnc {
|
|||
GstPad *sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
GstCaps *srccaps;
|
||||
GstCaps *sinkcaps;
|
||||
|
||||
vorbis_info vi; /* struct that stores all the static vorbis bitstream
|
||||
settings */
|
||||
vorbis_comment vc; /* struct that stores all the user comments */
|
||||
|
|
Loading…
Reference in a new issue