Merge branch 'master' into 0.11

Conflicts:
	ext/vorbis/gstvorbisdec.c
	ext/vorbis/gstvorbisenc.c
	ext/vorbis/gstvorbisenc.h
	gst/audiotestsrc/gstaudiotestsrc.c
This commit is contained in:
Wim Taymans 2011-10-08 10:19:06 +02:00
commit 73b894107a
14 changed files with 405 additions and 1519 deletions

View file

@ -11,7 +11,8 @@ libgstvorbis_la_SOURCES = gstvorbis.c \
gstvorbistag.c \ gstvorbistag.c \
gstvorbiscommon.c gstvorbiscommon.c
libgstvorbis_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(VORBIS_CFLAGS) libgstvorbis_la_CFLAGS = -DGST_USE_UNSTABLE_API \
$(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(VORBIS_CFLAGS)
## AM_PATH_VORBIS also sets VORBISENC_LIBS ## AM_PATH_VORBIS also sets VORBISENC_LIBS
libgstvorbis_la_LIBADD = \ libgstvorbis_la_LIBADD = \
$(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_MAJORMINOR@.la \ $(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_MAJORMINOR@.la \
@ -27,7 +28,8 @@ plugin_LTLIBRARIES += libgstivorbisdec.la
libgstivorbisdec_la_SOURCES = gstivorbisdec.c \ libgstivorbisdec_la_SOURCES = gstivorbisdec.c \
gstvorbisdec.c gstvorbisdeclib.c gstvorbiscommon.c gstvorbisdec.c gstvorbisdeclib.c gstvorbiscommon.c
libgstivorbisdec_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \ libgstivorbisdec_la_CFLAGS = -DGST_USE_UNSTABLE_API \
$(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
-DTREMOR $(IVORBIS_CFLAGS) -DTREMOR $(IVORBIS_CFLAGS)
libgstivorbisdec_la_LIBADD = \ libgstivorbisdec_la_LIBADD = \
$(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_MAJORMINOR@.la \ $(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_MAJORMINOR@.la \

File diff suppressed because it is too large Load diff

View file

@ -27,6 +27,7 @@
#endif #endif
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/audio/gstaudiodecoder.h>
#include "gstvorbisdeclib.h" #include "gstvorbisdeclib.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -51,15 +52,11 @@ typedef struct _GstVorbisDecClass GstVorbisDecClass;
* Opaque data structure. * Opaque data structure.
*/ */
struct _GstVorbisDec { struct _GstVorbisDec {
GstElement element; GstAudioDecoder element;
GstPad *sinkpad;
GstPad *srcpad;
vorbis_dsp_state vd; vorbis_dsp_state vd;
vorbis_info vi; vorbis_info vi;
vorbis_comment vc; vorbis_comment vc;
#ifndef USE_TREMOLO #ifndef USE_TREMOLO
vorbis_block vb; vorbis_block vb;
#endif #endif
@ -67,26 +64,13 @@ struct _GstVorbisDec {
gboolean initialized; gboolean initialized;
GstAudioInfo info; GstAudioInfo info;
/* list of buffers that need timestamps */
GList *queued;
/* gather/decode queues for reverse playback */
GList *gather;
GList *decode;
GstSegment segment;
gboolean discont;
guint32 seqnum;
GstClockTime last_timestamp;
GList *pendingevents;
GstTagList *taglist; GstTagList *taglist;
CopySampleFunc copy_samples; CopySampleFunc copy_samples;
}; };
struct _GstVorbisDecClass { struct _GstVorbisDecClass {
GstElementClass parent_class; GstAudioDecoderClass parent_class;
}; };
GType gst_vorbis_dec_get_type(void); GType gst_vorbis_dec_get_type(void);

File diff suppressed because it is too large Load diff

View file

@ -23,6 +23,7 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/audio/gstaudioencoder.h>
#include <vorbis/codec.h> #include <vorbis/codec.h>
@ -48,14 +49,11 @@ typedef struct _GstVorbisEncClass GstVorbisEncClass;
* Opaque data structure. * Opaque data structure.
*/ */
struct _GstVorbisEnc { struct _GstVorbisEnc {
GstElement element; GstAudioEncoder element;
GstPad *sinkpad;
GstPad *srcpad;
GstCaps *srccaps;
GstCaps *sinkcaps; GstCaps *sinkcaps;
/* codec */
vorbis_info vi; /* struct that stores all the static vorbis bitstream vorbis_info vi; /* struct that stores all the static vorbis bitstream
settings */ settings */
vorbis_comment vc; /* struct that stores all the user comments */ vorbis_comment vc; /* struct that stores all the user comments */
@ -63,6 +61,7 @@ struct _GstVorbisEnc {
vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
vorbis_block vb; /* local working space for packet->PCM decode */ vorbis_block vb; /* local working space for packet->PCM decode */
/* properties */
gboolean managed; gboolean managed;
gint bitrate; gint bitrate;
gint min_bitrate; gint min_bitrate;
@ -74,13 +73,8 @@ struct _GstVorbisEnc {
gint frequency; gint frequency;
guint64 samples_in; guint64 samples_in;
guint64 samples_out;
guint64 bytes_out; guint64 bytes_out;
GstClockTime next_ts;
GstClockTime expected_ts;
gboolean next_discont;
guint64 granulepos_offset;
gint64 subgranule_offset;
GstSegment segment;
GstTagList * tags; GstTagList * tags;
@ -90,7 +84,7 @@ struct _GstVorbisEnc {
}; };
struct _GstVorbisEncClass { struct _GstVorbisEncClass {
GstElementClass parent_class; GstAudioEncoderClass parent_class;
}; };
GType gst_vorbis_enc_get_type(void); GType gst_vorbis_enc_get_type(void);

View file

@ -1579,6 +1579,10 @@ gst_audio_decoder_src_event (GstPad * pad, GstEvent * event)
gboolean res = FALSE; gboolean res = FALSE;
dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad)); dec = GST_AUDIO_DECODER (gst_pad_get_parent (pad));
if (G_UNLIKELY (dec == NULL)) {
gst_event_unref (event);
return FALSE;
}
GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event), GST_DEBUG_OBJECT (dec, "received event %d, %s", GST_EVENT_TYPE (event),
GST_EVENT_TYPE_NAME (event)); GST_EVENT_TYPE_NAME (event));
@ -1779,6 +1783,9 @@ gst_audio_decoder_src_query (GstPad * pad, GstQuery * query)
gboolean res = FALSE; gboolean res = FALSE;
dec = GST_AUDIO_DECODER (GST_PAD_PARENT (pad)); dec = GST_AUDIO_DECODER (GST_PAD_PARENT (pad));
if (G_UNLIKELY (dec == NULL))
return FALSE;
peerpad = gst_pad_get_peer (GST_PAD (dec->sinkpad)); peerpad = gst_pad_get_peer (GST_PAD (dec->sinkpad));
GST_LOG_OBJECT (dec, "handling query: %" GST_PTR_FORMAT, query); GST_LOG_OBJECT (dec, "handling query: %" GST_PTR_FORMAT, query);

View file

@ -1504,6 +1504,9 @@ gst_audio_encoder_src_query (GstPad * pad, GstQuery * query)
gboolean res = FALSE; gboolean res = FALSE;
enc = GST_AUDIO_ENCODER (GST_PAD_PARENT (pad)); enc = GST_AUDIO_ENCODER (GST_PAD_PARENT (pad));
if (G_UNLIKELY (enc == NULL))
return FALSE;
peerpad = gst_pad_get_peer (GST_PAD (enc->sinkpad)); peerpad = gst_pad_get_peer (GST_PAD (enc->sinkpad));
GST_LOG_OBJECT (enc, "handling query: %" GST_PTR_FORMAT, query); GST_LOG_OBJECT (enc, "handling query: %" GST_PTR_FORMAT, query);

View file

@ -789,7 +789,7 @@ gst_audio_test_src_create_red_noise_##type (GstAudioTestSrc * src, g##type * sam
while (TRUE) { \ while (TRUE) { \
gdouble r = g_rand_double_range (src->gen, -1.0, 1.0); \ gdouble r = g_rand_double_range (src->gen, -1.0, 1.0); \
state += r; \ state += r; \
if (state<-8.0f || state>8.0f) state -= r; \ if (state < -8.0f || state > 8.0f) state -= r; \
else break; \ else break; \
} \ } \
samples[i++] = (g##type) (amp * state * 0.0625f); /* /16.0 */ \ samples[i++] = (g##type) (amp * state * 0.0625f); /* /16.0 */ \
@ -958,6 +958,7 @@ gst_audio_test_src_change_wave (GstAudioTestSrc * src)
src->gen = g_rand_new (); src->gen = g_rand_new ();
src->red.state = 0.0; src->red.state = 0.0;
src->process = violet_noise_funcs[idx]; src->process = violet_noise_funcs[idx];
break;
default: default:
GST_ERROR ("invalid wave-form"); GST_ERROR ("invalid wave-form");
break; break;

View file

@ -1090,45 +1090,6 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
last = sgroup->outfilter; last = sgroup->outfilter;
/* FIXME :
*
* The usage of parsers in encoding/muxing scenarios is
* just too undefined to just use as-is.
*
* Take the use-case where you want to re-mux a stream of type
* "my/media". You create a StreamEncodingProfile with that type
* as the target (as-is). And you use decodebin2/uridecodebin
* upstream.
*
* * demuxer exposes "my/media"
* * a parser is available for "my/media" which has a source pad
* caps of "my/media,parsed=True"
* * decodebin2/uridecodebin exposes a new pad with the parsed caps
* * You request a new stream from encodebin, which will match the
* streamprofile and creates a group (i.e. going through this method)
* There is a matching parser (the same used in the decoder) whose
* source pad caps intersects with the stream profile caps, you
* therefore use it...
* * ... but that parser has a "my/media,parsed=False" sink pad caps
* * ... and you can't link your decodebin pad to encodebin.
*
* In the end, it comes down to parsers only taking into account the
* decoding use-cases.
*
* One way to solve that might be to :
* * Make parsers sink pad caps be "framed={False,True}" and the
* source pad caps be "framed=True"
* * Modify decodebin2 accordingly to avoid looping and chaining
* an infinite number of parsers
*
* Another way would be to have "well-known" caps properties to specify
* whether a stream has been parsed or not.
* * currently we fail. aacparse uses 'framed' and mp3parse uses 'parsed'
*/
/* FIXME : Re-enable once parser situation is un-$#*@(%$#ed */
#if 0
/* Parser.
* FIXME : identify smart parsers (used for re-encoding) */
sgroup->parser = _get_parser (ebin, sprof); sgroup->parser = _get_parser (ebin, sprof);
if (sgroup->parser != NULL) { if (sgroup->parser != NULL) {
@ -1139,7 +1100,6 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
goto parser_link_failure; goto parser_link_failure;
last = sgroup->parser; last = sgroup->parser;
} }
#endif
/* Stream combiner */ /* Stream combiner */
sgroup->combiner = g_object_new (GST_TYPE_STREAM_COMBINER, NULL); sgroup->combiner = g_object_new (GST_TYPE_STREAM_COMBINER, NULL);
@ -1467,11 +1427,9 @@ combiner_link_failure:
GST_ERROR_OBJECT (ebin, "Failure linking to the combiner"); GST_ERROR_OBJECT (ebin, "Failure linking to the combiner");
goto cleanup; goto cleanup;
#if 0
parser_link_failure: parser_link_failure:
GST_ERROR_OBJECT (ebin, "Failure linking the parser"); GST_ERROR_OBJECT (ebin, "Failure linking the parser");
goto cleanup; goto cleanup;
#endif
converter_link_failure: converter_link_failure:
GST_ERROR_OBJECT (ebin, "Failure linking the video converters"); GST_ERROR_OBJECT (ebin, "Failure linking the video converters");

View file

@ -2445,12 +2445,14 @@ stream_changed_data_probe (GstPad * pad, GstProbeType type,
/* helper function to lookup stuff in lists */ /* helper function to lookup stuff in lists */
static gboolean static gboolean
array_has_value (const gchar * values[], const gchar * value) array_has_value (const gchar * values[], const gchar * value, gboolean exact)
{ {
gint i; gint i;
for (i = 0; values[i]; i++) { for (i = 0; values[i]; i++) {
if (values[i] && g_str_has_prefix (value, values[i])) if (exact && !strcmp (value, values[i]))
return TRUE;
if (!exact && g_str_has_prefix (value, values[i]))
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
@ -2508,7 +2510,7 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
GstPad *sinkpad; GstPad *sinkpad;
GstPadLinkReturn res; GstPadLinkReturn res;
GstSourceSelect *select = NULL; GstSourceSelect *select = NULL;
gint i; gint i, pass;
gboolean changed = FALSE; gboolean changed = FALSE;
playbin = group->playbin; playbin = group->playbin;
@ -2521,9 +2523,12 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
"pad %s:%s with caps %" GST_PTR_FORMAT " added in group %p", "pad %s:%s with caps %" GST_PTR_FORMAT " added in group %p",
GST_DEBUG_PAD_NAME (pad), caps, group); GST_DEBUG_PAD_NAME (pad), caps, group);
/* major type of the pad, this determines the selector to use */ /* major type of the pad, this determines the selector to use,
try exact match first so we don't prematurely match video/
for video/x-dvd-subpicture */
for (pass = 0; !select && pass < 2; pass++) {
for (i = 0; i < PLAYBIN_STREAM_LAST; i++) { for (i = 0; i < PLAYBIN_STREAM_LAST; i++) {
if (array_has_value (group->selector[i].media_list, name)) { if (array_has_value (group->selector[i].media_list, name, pass == 0)) {
select = &group->selector[i]; select = &group->selector[i];
break; break;
} else if (group->selector[i].get_media_caps) { } else if (group->selector[i].get_media_caps) {
@ -2537,6 +2542,7 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
gst_caps_unref (media_caps); gst_caps_unref (media_caps);
} }
} }
}
/* no selector found for the media type, don't bother linking it to a /* no selector found for the media type, don't bother linking it to a
* selector. This will leave the pad unlinked and thus ignored. */ * selector. This will leave the pad unlinked and thus ignored. */
if (select == NULL) if (select == NULL)

View file

@ -255,6 +255,8 @@ enum
PROP_FRAME, PROP_FRAME,
PROP_AV_OFFSET, PROP_AV_OFFSET,
PROP_VIDEO_SINK, PROP_VIDEO_SINK,
PROP_AUDIO_SINK,
PROP_TEXT_SINK,
PROP_LAST PROP_LAST
}; };
@ -422,6 +424,31 @@ gst_play_sink_class_init (GstPlaySinkClass * klass)
g_param_spec_object ("video-sink", "Video Sink", g_param_spec_object ("video-sink", "Video Sink",
"the video output element to use (NULL = default sink)", "the video output element to use (NULL = default sink)",
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstPlaySink:audio-sink:
*
* Set the used audio sink element. NULL will use the default sink. playsink
* must be in %GST_STATE_NULL
*
* Since: 0.10.36
*/
g_object_class_install_property (gobject_klass, PROP_AUDIO_SINK,
g_param_spec_object ("audio-sink", "Audio Sink",
"the audio output element to use (NULL = default sink)",
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstPlaySink:text-sink:
*
* Set the used text sink element. NULL will use the default sink. playsink
* must be in %GST_STATE_NULL
*
* Since: 0.10.36
*/
g_object_class_install_property (gobject_klass, PROP_TEXT_SINK,
g_param_spec_object ("text-sink", "Text sink",
"the text output element to use (NULL = default textoverlay)",
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_signal_new ("reconfigure", G_TYPE_FROM_CLASS (klass), g_signal_new ("reconfigure", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstPlaySinkClass, G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstPlaySinkClass,
@ -3628,6 +3655,14 @@ gst_play_sink_set_property (GObject * object, guint prop_id,
gst_play_sink_set_sink (playsink, GST_PLAY_SINK_TYPE_VIDEO, gst_play_sink_set_sink (playsink, GST_PLAY_SINK_TYPE_VIDEO,
g_value_get_object (value)); g_value_get_object (value));
break; break;
case PROP_AUDIO_SINK:
gst_play_sink_set_sink (playsink, GST_PLAY_SINK_TYPE_AUDIO,
g_value_get_object (value));
break;
case PROP_TEXT_SINK:
gst_play_sink_set_sink (playsink, GST_PLAY_SINK_TYPE_TEXT,
g_value_get_object (value));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
break; break;
@ -3670,6 +3705,14 @@ gst_play_sink_get_property (GObject * object, guint prop_id,
g_value_take_object (value, gst_play_sink_get_sink (playsink, g_value_take_object (value, gst_play_sink_get_sink (playsink,
GST_PLAY_SINK_TYPE_VIDEO)); GST_PLAY_SINK_TYPE_VIDEO));
break; break;
case PROP_AUDIO_SINK:
g_value_take_object (value, gst_play_sink_get_sink (playsink,
GST_PLAY_SINK_TYPE_AUDIO));
break;
case PROP_TEXT_SINK:
g_value_take_object (value, gst_play_sink_get_sink (playsink,
GST_PLAY_SINK_TYPE_TEXT));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
break; break;

View file

@ -339,10 +339,7 @@ gst_play_sink_audio_convert_getcaps (GstPad * pad, GstCaps * filter)
GstPad *otherpad, *peer; GstPad *otherpad, *peer;
GST_PLAY_SINK_AUDIO_CONVERT_LOCK (self); GST_PLAY_SINK_AUDIO_CONVERT_LOCK (self);
if (pad == self->srcpad) otherpad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (pad));
otherpad = gst_object_ref (self->sinkpad);
else
otherpad = gst_object_ref (self->srcpad);
GST_PLAY_SINK_AUDIO_CONVERT_UNLOCK (self); GST_PLAY_SINK_AUDIO_CONVERT_UNLOCK (self);
peer = gst_pad_get_peer (otherpad); peer = gst_pad_get_peer (otherpad);

View file

@ -319,10 +319,7 @@ gst_play_sink_video_convert_getcaps (GstPad * pad, GstCaps * filter)
GstPad *otherpad, *peer; GstPad *otherpad, *peer;
GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self); GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self);
if (pad == self->srcpad) otherpad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (pad));
otherpad = gst_object_ref (self->sinkpad);
else
otherpad = gst_object_ref (self->srcpad);
GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self); GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self);
peer = gst_pad_get_peer (otherpad); peer = gst_pad_get_peer (otherpad);

View file

@ -87,6 +87,7 @@ GST_START_TEST (test_all_waves)
while (values[j].value_name) { while (values[j].value_name) {
GST_DEBUG_OBJECT (audiotestsrc, "testing wave %s", values[j].value_name); GST_DEBUG_OBJECT (audiotestsrc, "testing wave %s", values[j].value_name);
g_object_set (audiotestsrc, "wave", values[j].value, NULL);
fail_unless (gst_element_set_state (audiotestsrc, fail_unless (gst_element_set_state (audiotestsrc,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,