diff options
author | Dave Robillard <dave@drobilla.net> | 2009-06-03 16:37:53 -0400 |
---|---|---|
committer | Dave Robillard <dave@drobilla.net> | 2009-06-03 16:37:53 -0400 |
commit | 7f3bcd484b465d8216ac419754450adf07e9b0d2 (patch) | |
tree | 5320e188d7719d8fba29beaf7da8f6f73e51e4e8 /gst | |
parent | b19dd5920605c0036dacf19591a6feca7a736a50 (diff) | |
parent | e14bfea0c44aafba65239cbff9c6a4a93e0ae41a (diff) | |
download | gst-plugins-bad-7f3bcd484b465d8216ac419754450adf07e9b0d2.tar.gz gst-plugins-bad-7f3bcd484b465d8216ac419754450adf07e9b0d2.tar.bz2 gst-plugins-bad-7f3bcd484b465d8216ac419754450adf07e9b0d2.zip |
Merge branch 'master' of git://anongit.freedesktop.org/gstreamer/gst-plugins-bad into fdo
Diffstat (limited to 'gst')
-rw-r--r-- | gst/aacparse/gstaacparse.c | 67 | ||||
-rw-r--r-- | gst/aacparse/gstbaseparse.c | 10 | ||||
-rw-r--r-- | gst/amrparse/gstamrparse.c | 1 | ||||
-rw-r--r-- | gst/amrparse/gstbaseparse.c | 10 | ||||
-rw-r--r-- | gst/dvdspu/Makefile.am | 2 | ||||
-rw-r--r-- | gst/flacparse/gstbaseparse.c | 10 | ||||
-rw-r--r-- | gst/qtmux/atoms.c | 6 | ||||
-rw-r--r-- | gst/qtmux/atoms.h | 4 | ||||
-rw-r--r-- | gst/qtmux/ftypcc.h | 3 | ||||
-rw-r--r-- | gst/qtmux/gstqtmuxmap.c | 48 | ||||
-rw-r--r-- | gst/shapewipe/gstshapewipe.c | 43 |
11 files changed, 137 insertions, 67 deletions
diff --git a/gst/aacparse/gstaacparse.c b/gst/aacparse/gstaacparse.c index c9ad0b5f..07906347 100644 --- a/gst/aacparse/gstaacparse.c +++ b/gst/aacparse/gstaacparse.c @@ -70,22 +70,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_aacparse_debug); #define GST_CAT_DEFAULT gst_aacparse_debug -static const guint aac_sample_rates[] = { - 96000, - 88200, - 64000, - 48000, - 44100, - 32000, - 24000, - 22050, - 16000, - 12000, - 11025, - 8000 -}; - - #define ADIF_MAX_SIZE 40 /* Should be enough */ #define ADTS_MAX_SIZE 10 /* Should be enough */ @@ -121,6 +105,18 @@ gboolean gst_aacparse_event (GstBaseParse * parse, GstEvent * event); GST_BOILERPLATE_FULL (GstAacParse, gst_aacparse, GstBaseParse, GST_TYPE_BASE_PARSE, _do_init); +static inline gint +gst_aacparse_get_sample_rate_from_index (guint sr_idx) +{ + static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100, + 32000, 24000, 22050, 16000, 12000, 11025, 8000 + }; + + if (sr_idx < G_N_ELEMENTS (aac_sample_rates)) + return aac_sample_rates[sr_idx]; + GST_WARNING ("Invalid sample rate index %u", sr_idx); + return 0; +} /** * gst_aacparse_base_init: @@ -213,21 +209,30 @@ gst_aacparse_finalize (GObject * object) static gboolean gst_aacparse_set_src_caps (GstAacParse * aacparse) { - GstCaps *src_caps = NULL; - gchar *caps_str = NULL; + GstStructure *s; + GstCaps *sink_caps, *src_caps = NULL; gboolean res = FALSE; - src_caps = gst_caps_new_simple ("audio/mpeg", - "framed", G_TYPE_BOOLEAN, TRUE, + sink_caps = GST_PAD_CAPS (GST_BASE_PARSE (aacparse)->sinkpad); + GST_DEBUG_OBJECT (aacparse, "sink caps: %" GST_PTR_FORMAT, sink_caps); + if (sink_caps) + src_caps = gst_caps_copy (sink_caps); + else + src_caps = gst_caps_new_simple ("audio/mpeg", NULL); + + gst_caps_set_simple (src_caps, "framed", G_TYPE_BOOLEAN, TRUE, "mpegversion", G_TYPE_INT, aacparse->mpegversion, NULL); - caps_str = gst_caps_to_string (src_caps); - GST_DEBUG_OBJECT (aacparse, "setting srcpad caps: %s", caps_str); - g_free (caps_str); + s = gst_caps_get_structure (src_caps, 0); + if (!gst_structure_has_field (s, "rate") && aacparse->sample_rate > 0) + gst_structure_set (s, "rate", G_TYPE_INT, aacparse->sample_rate, NULL); + if (!gst_structure_has_field (s, "channels") && aacparse->channels > 0) + gst_structure_set (s, "channels", G_TYPE_INT, aacparse->channels, NULL); + + GST_DEBUG_OBJECT (aacparse, "setting src caps: %" GST_PTR_FORMAT, src_caps); gst_pad_use_fixed_caps (GST_BASE_PARSE (aacparse)->srcpad); res = gst_pad_set_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps); - gst_pad_fixate_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps); gst_caps_unref (src_caps); return res; } @@ -266,9 +271,11 @@ gst_aacparse_sink_setcaps (GstBaseParse * parse, GstCaps * caps) if (value) { GstBuffer *buf = gst_value_get_buffer (value); const guint8 *buffer = GST_BUFFER_DATA (buf); + guint sr_idx; + + sr_idx = ((buffer[0] & 0x07) << 1) | ((buffer[1] & 0x80) >> 7); aacparse->object_type = (buffer[0] & 0xf8) >> 3; - aacparse->sample_rate = ((buffer[0] & 0x07) << 1) | - ((buffer[1] & 0x80) >> 7); + aacparse->sample_rate = gst_aacparse_get_sample_rate_from_index (sr_idx); aacparse->channels = (buffer[1] & 0x78) >> 3; aacparse->header_type = DSPAAC_HEADER_NONE; aacparse->mpegversion = 4; @@ -468,13 +475,13 @@ gst_aacparse_detect_stream (GstAacParse * aacparse, aacparse->header_type = DSPAAC_HEADER_ADTS; sr_idx = (data[2] & 0x3c) >> 2; - aacparse->sample_rate = aac_sample_rates[sr_idx]; + aacparse->sample_rate = gst_aacparse_get_sample_rate_from_index (sr_idx); aacparse->mpegversion = (data[1] & 0x08) ? 2 : 4; aacparse->object_type = (data[2] & 0xc0) >> 6; aacparse->channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6); aacparse->bitrate = ((data[5] & 0x1f) << 6) | ((data[6] & 0xfc) >> 2); - aacparse->frames_per_sec = aac_sample_rates[sr_idx] / 1024.f; + aacparse->frames_per_sec = aacparse->sample_rate / 1024.f; GST_DEBUG ("ADTS: samplerate %d, channels %d, bitrate %d, objtype %d, " "fps %f", aacparse->sample_rate, aacparse->channels, @@ -544,9 +551,9 @@ gst_aacparse_detect_stream (GstAacParse * aacparse, /* FIXME: This gives totally wrong results. Duration calculation cannot be based on this */ - aacparse->sample_rate = aac_sample_rates[sr_idx]; + aacparse->sample_rate = gst_aacparse_get_sample_rate_from_index (sr_idx); - aacparse->frames_per_sec = aac_sample_rates[sr_idx] / 1024.f; + aacparse->frames_per_sec = aacparse->sample_rate / 1024.f; GST_INFO ("ADIF fps: %f", aacparse->frames_per_sec); // FIXME: Can we assume this? diff --git a/gst/aacparse/gstbaseparse.c b/gst/aacparse/gstbaseparse.c index 34d28ec2..026b1341 100644 --- a/gst/aacparse/gstbaseparse.c +++ b/gst/aacparse/gstbaseparse.c @@ -1730,18 +1730,14 @@ gst_base_parse_sink_setcaps (GstPad * pad, GstCaps * caps) GstBaseParseClass *klass; gboolean res = TRUE; - gchar *caps_str = gst_caps_to_string (caps); - g_free (caps_str); - - parse = GST_BASE_PARSE (gst_pad_get_parent (pad)); + parse = GST_BASE_PARSE (GST_PAD_PARENT (pad)); klass = GST_BASE_PARSE_GET_CLASS (parse); - GST_DEBUG_OBJECT (parse, "setcaps: %s", caps_str); + GST_DEBUG_OBJECT (parse, "caps: %" GST_PTR_FORMAT, caps); if (klass->set_sink_caps) res = klass->set_sink_caps (parse, caps); parse->negotiated = res; - gst_object_unref (parse); - return gst_pad_set_caps (pad, caps); + return res && gst_pad_set_caps (pad, caps); } diff --git a/gst/amrparse/gstamrparse.c b/gst/amrparse/gstamrparse.c index 5ec0c6c2..64cf9547 100644 --- a/gst/amrparse/gstamrparse.c +++ b/gst/amrparse/gstamrparse.c @@ -210,7 +210,6 @@ gst_amrparse_set_src_caps (GstAmrParse * amrparse) } gst_pad_use_fixed_caps (GST_BASE_PARSE (amrparse)->srcpad); res = gst_pad_set_caps (GST_BASE_PARSE (amrparse)->srcpad, src_caps); - gst_pad_fixate_caps (GST_BASE_PARSE (amrparse)->srcpad, src_caps); gst_caps_unref (src_caps); return res; } diff --git a/gst/amrparse/gstbaseparse.c b/gst/amrparse/gstbaseparse.c index e0f1f4d7..ad963785 100644 --- a/gst/amrparse/gstbaseparse.c +++ b/gst/amrparse/gstbaseparse.c @@ -1730,18 +1730,14 @@ gst_base_parse_sink_setcaps (GstPad * pad, GstCaps * caps) GstBaseParseClass *klass; gboolean res = TRUE; - gchar *caps_str = gst_caps_to_string (caps); - g_free (caps_str); - - parse = GST_BASE_PARSE (gst_pad_get_parent (pad)); + parse = GST_BASE_PARSE (GST_PAD_PARENT (pad)); klass = GST_BASE_PARSE_GET_CLASS (parse); - GST_DEBUG_OBJECT (parse, "setcaps: %s", caps_str); + GST_DEBUG_OBJECT (parse, "caps: %" GST_PTR_FORMAT, caps); if (klass->set_sink_caps) res = klass->set_sink_caps (parse, caps); parse->negotiated = res; - gst_object_unref (parse); - return gst_pad_set_caps (pad, caps); + return res && gst_pad_set_caps (pad, caps); } diff --git a/gst/dvdspu/Makefile.am b/gst/dvdspu/Makefile.am index 07a66357..950ed82c 100644 --- a/gst/dvdspu/Makefile.am +++ b/gst/dvdspu/Makefile.am @@ -8,6 +8,6 @@ libgstdvdspu_la_LIBADD = $(GST_LIBS) libgstdvdspu_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstdvdspu_la_LIBTOOLFLAGS = --tag=disable-static -noinst_HEADERS = gstdvdspu.h gstspu-pgs.h gstspu-vobsub.h +noinst_HEADERS = gstdvdspu.h gstspu-pgs.h gstspu-vobsub.h gstspu-common.h EXTRA_DIST = Notes.txt diff --git a/gst/flacparse/gstbaseparse.c b/gst/flacparse/gstbaseparse.c index 066fe517..85fb8d71 100644 --- a/gst/flacparse/gstbaseparse.c +++ b/gst/flacparse/gstbaseparse.c @@ -1960,18 +1960,14 @@ gst_base_parse_sink_setcaps (GstPad * pad, GstCaps * caps) GstBaseParseClass *klass; gboolean res = TRUE; - gchar *caps_str = gst_caps_to_string (caps); - g_free (caps_str); - - parse = GST_BASE_PARSE (gst_pad_get_parent (pad)); + parse = GST_BASE_PARSE (GST_PAD_PARENT (pad)); klass = GST_BASE_PARSE_GET_CLASS (parse); - GST_DEBUG_OBJECT (parse, "setcaps: %s", caps_str); + GST_DEBUG_OBJECT (parse, "caps: %" GST_PTR_FORMAT, caps); if (klass->set_sink_caps) res = klass->set_sink_caps (parse, caps); parse->negotiated = res; - gst_object_unref (parse); - return gst_pad_set_caps (pad, caps); + return res && gst_pad_set_caps (pad, caps); } diff --git a/gst/qtmux/atoms.c b/gst/qtmux/atoms.c index a5d8fe38..47db40ce 100644 --- a/gst/qtmux/atoms.c +++ b/gst/qtmux/atoms.c @@ -2783,6 +2783,9 @@ atom_trak_set_audio_type (AtomTRAK * trak, AtomsContext * context, atom_trak_set_audio_commons (trak, context, scale); ste = atom_trak_add_audio_entry (trak, context, entry->fourcc); + trak->is_video = FALSE; + trak->is_h264 = FALSE; + ste->version = entry->version; ste->compression_id = entry->compression_id; ste->sample_size = entry->sample_size; @@ -2811,6 +2814,9 @@ atom_trak_set_video_type (AtomTRAK * trak, AtomsContext * context, entry->height); ste = atom_trak_add_video_entry (trak, context, entry->fourcc); + trak->is_video = TRUE; + trak->is_h264 = (entry->fourcc == FOURCC_avc1); + ste->width = entry->width; ste->height = entry->height; ste->depth = entry->depth; diff --git a/gst/qtmux/atoms.h b/gst/qtmux/atoms.h index 4d8dce19..23bc19bb 100644 --- a/gst/qtmux/atoms.h +++ b/gst/qtmux/atoms.h @@ -518,6 +518,10 @@ typedef struct _AtomTRAK AtomTKHD tkhd; AtomMDIA mdia; + + /* some helper info for structural conformity checks */ + gboolean is_video; + gboolean is_h264; } AtomTRAK; typedef struct _AtomMOOV diff --git a/gst/qtmux/ftypcc.h b/gst/qtmux/ftypcc.h index d8320c79..4855adf7 100644 --- a/gst/qtmux/ftypcc.h +++ b/gst/qtmux/ftypcc.h @@ -53,6 +53,9 @@ G_BEGIN_DECLS #define FOURCC_mp41 GST_MAKE_FOURCC('m','p','4','1') #define FOURCC_mp42 GST_MAKE_FOURCC('m','p','4','2') #define FOURCC_mjp2 GST_MAKE_FOURCC('m','j','p','2') +#define FOURCC_3gp4 GST_MAKE_FOURCC('3','g','p','4') +#define FOURCC_3gp6 GST_MAKE_FOURCC('3','g','p','6') +#define FOURCC_3gg6 GST_MAKE_FOURCC('3','g','g','6') #define FOURCC_3gg7 GST_MAKE_FOURCC('3','g','g','7') #define FOURCC_avc1 GST_MAKE_FOURCC('a','v','c','1') #define FOURCC_qt__ GST_MAKE_FOURCC('q','t',' ',' ') diff --git a/gst/qtmux/gstqtmuxmap.c b/gst/qtmux/gstqtmuxmap.c index 11913670..e0e4faed 100644 --- a/gst/qtmux/gstqtmuxmap.c +++ b/gst/qtmux/gstqtmuxmap.c @@ -205,14 +205,40 @@ gst_qt_mux_map_format_to_flavor (GstQTMuxFormat format) return ATOMS_TREE_FLAVOR_ISOM; } +static void +gst_qt_mux_map_check_tracks (AtomMOOV * moov, gint * _video, gint * _audio, + gboolean * _has_h264) +{ + GList *it; + gint video = 0, audio = 0; + gboolean has_h264 = FALSE; + + for (it = moov->traks; it != NULL; it = g_list_next (it)) { + AtomTRAK *track = it->data; + + if (track->is_video) { + video++; + if (track->is_h264) + has_h264 = TRUE; + } else + audio++; + } + + if (_video) + *_video = video; + if (_audio) + *_audio = audio; + if (_has_h264) + *_has_h264 = has_h264; +} + /* pretty static, but possibly dynamic format info */ /* notes: * - avc1 brand is not used, since the specific extensions indicated by it * are not used (e.g. sample groupings, etc) - * - 3GPP2 specific formats not (yet) used, only 3GPP, so no need yet either - * for 3g2a (but later on, moov might be used to conditionally switch to - * 3g2a if needed) */ + * - TODO: maybe even more 3GPP brand fine-tuning ?? + * (but that might need ftyp rewriting at the end) */ void gst_qt_mux_map_format_to_header (GstQTMuxFormat format, GstBuffer ** _prefix, guint32 * _major, guint32 * _version, GList ** _compatible, AtomMOOV * moov) @@ -244,9 +270,23 @@ gst_qt_mux_map_format_to_header (GstQTMuxFormat format, GstBuffer ** _prefix, comp = mp4_brands; break; case GST_QT_MUX_FORMAT_3GP: - major = FOURCC_3gg7; + { + gint video, audio; + gboolean has_h264; + + gst_qt_mux_map_check_tracks (moov, &video, &audio, &has_h264); + /* only track restriction really matters for Basic Profile */ + if (video <= 1 && audio <= 1) { + /* it seems only newer spec knows about H264 */ + major = has_h264 ? FOURCC_3gp6 : FOURCC_3gp4; + version = has_h264 ? 0x100 : 0x200; + } else { + major = FOURCC_3gg6; + version = 0x100; + } comp = gpp_brands; break; + } case GST_QT_MUX_FORMAT_MJ2: major = FOURCC_mjp2; comp = mjp2_brands; diff --git a/gst/shapewipe/gstshapewipe.c b/gst/shapewipe/gstshapewipe.c index ec33f0a7..c2c4ce2b 100644 --- a/gst/shapewipe/gstshapewipe.c +++ b/gst/shapewipe/gstshapewipe.c @@ -17,6 +17,27 @@ * Boston, MA 02111-1307, USA. */ +/** + * SECTION:element-shapewipe + * + * The shapewipe element provides custom transitions on video streams + * based on a grayscale bitmap. The state of the transition can be + * controlled by the position property and an optional blended border + * can be added by the border property. + * + * Transition bitmaps can be downloaded from the + * <ulink url="http://cinelerra.org/transitions.php">Cinelerra transition</ulink> + * page. + * + * <refsect2> + * <title>Example launch line</title> + * |[ + * gst-launch -v videotestsrc ! video/x-raw-yuv,width=640,height=480 ! shapewipe position=0.5 name=shape ! videomixer name=mixer ! ffmpegcolorspace ! autovideosink filesrc location=mask.png ! typefind ! decodebin2 ! ffmpegcolorspace ! videoscale ! queue ! shape.mask_sink videotestsrc pattern=snow ! video/x-raw-yuv,width=640,height=480 ! queue ! mixer. + * ]| This pipeline adds the transition from mask.png with position 0.5 to an SMPTE test screen and snow. + * </refsect2> + */ + + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -571,7 +592,7 @@ gst_shape_wipe_blend_16 (GstShapeWipe * self, GstBuffer * inbuf, for (i = 0; i < self->height; i++) { for (j = 0; j < self->width; j++) { - gfloat in = *mask / 65535.0f; + gfloat in = *mask / 65536.0f; if (in < low) { output[0] = 0x00; /* A */ @@ -627,7 +648,7 @@ gst_shape_wipe_blend_8 (GstShapeWipe * self, GstBuffer * inbuf, for (i = 0; i < self->height; i++) { for (j = 0; j < self->width; j++) { - gfloat in = *mask / 255.0f; + gfloat in = *mask / 256.0f; if (in < low) { output[0] = 0x00; /* A */ @@ -678,26 +699,26 @@ gst_shape_wipe_video_sink_chain (GstPad * pad, GstBuffer * buffer) GST_TIME_ARGS (timestamp), self->mask_position); g_mutex_lock (self->mask_mutex); - mask = self->mask; - if (self->mask) - gst_buffer_ref (self->mask); - else + if (!self->mask) g_cond_wait (self->mask_cond, self->mask_mutex); if (self->mask == NULL) { g_mutex_unlock (self->mask_mutex); + gst_buffer_unref (buffer); return GST_FLOW_UNEXPECTED; + } else { + mask = gst_buffer_ref (self->mask); } - - mask = gst_buffer_ref (self->mask); - g_mutex_unlock (self->mask_mutex); ret = gst_pad_alloc_buffer_and_set_caps (self->srcpad, GST_BUFFER_OFFSET_NONE, GST_BUFFER_SIZE (buffer), GST_PAD_CAPS (self->srcpad), &outbuf); - if (G_UNLIKELY (ret != GST_FLOW_OK)) + if (G_UNLIKELY (ret != GST_FLOW_OK)) { + gst_buffer_unref (buffer); + gst_buffer_unref (mask); return ret; + } if (self->mask_bpp == 16) ret = gst_shape_wipe_blend_16 (self, buffer, mask, outbuf); @@ -728,6 +749,8 @@ gst_shape_wipe_mask_sink_chain (GstPad * pad, GstBuffer * buffer) g_cond_signal (self->mask_cond); g_mutex_unlock (self->mask_mutex); + gst_buffer_unref (buffer); + return ret; } |