summaryrefslogtreecommitdiffstats
path: root/gst/avi/gstavidemux.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/avi/gstavidemux.c')
-rw-r--r--gst/avi/gstavidemux.c846
1 files changed, 478 insertions, 368 deletions
diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
index 77ff97f6..ad0b1ef3 100644
--- a/gst/avi/gstavidemux.c
+++ b/gst/avi/gstavidemux.c
@@ -68,138 +68,46 @@ GST_PAD_TEMPLATE_FACTORY (sink_templ,
GST_PAD_ALWAYS,
GST_CAPS_NEW (
"avidemux_sink",
- "video/avi",
- "format", GST_PROPS_STRING ("AVI")
- )
-)
-
-GST_PAD_TEMPLATE_FACTORY (src_video_templ,
- "video_%02d",
- GST_PAD_SRC,
- GST_PAD_SOMETIMES,
- GST_CAPS_NEW (
- "avidemux_src_video_avi",
- "video/avi",
- "format", GST_PROPS_LIST (
- GST_PROPS_STRING ("strf_vids"),
- GST_PROPS_STRING ("strf_iavs")
- ),
- "width", GST_PROPS_INT_RANGE (16, 4096),
- "height", GST_PROPS_INT_RANGE (16, 4096)
-
- ),
- GST_CAPS_NEW (
- "avidemux_src_video_raw",
- "video/raw",
- "format", GST_PROPS_LIST (
- GST_PROPS_FOURCC (GST_MAKE_FOURCC('Y','U','Y','2')),
- GST_PROPS_FOURCC (GST_MAKE_FOURCC('I','4','2','0'))
- ),
- "width", GST_PROPS_INT_RANGE (16, 4096),
- "height", GST_PROPS_INT_RANGE (16, 4096)
- ),
- GST_CAPS_NEW (
- "avidemux_src_video_jpeg",
- "video/jpeg",
- "width", GST_PROPS_INT_RANGE (16, 4096),
- "height", GST_PROPS_INT_RANGE (16, 4096)
- ),
- GST_CAPS_NEW (
- "avidemux_src_video_dv",
- "video/dv",
- "format", GST_PROPS_LIST (
- GST_PROPS_STRING ("NTSC"),
- GST_PROPS_STRING ("PAL")
- ),
- "width", GST_PROPS_INT_RANGE (16, 4096),
- "height", GST_PROPS_INT_RANGE (16, 4096)
- ),
- GST_CAPS_NEW (
- "avidemux_src_video_divx",
- "video/divx",
- "width", GST_PROPS_INT_RANGE (16, 4096),
- "height", GST_PROPS_INT_RANGE (16, 4096)
- ),
- GST_CAPS_NEW (
- "avidemux_src_video_xvid",
- "video/xvid",
- "width", GST_PROPS_INT_RANGE (16, 4096),
- "height", GST_PROPS_INT_RANGE (16, 4096)
- )
-)
-
-GST_PAD_TEMPLATE_FACTORY (src_audio_templ,
- "audio_%02d",
- GST_PAD_SRC,
- GST_PAD_SOMETIMES,
- GST_CAPS_NEW (
- "avidemux_src_audio_avi",
"video/avi",
- "format", GST_PROPS_STRING ("strf_auds")
- ),
- GST_CAPS_NEW (
- "avidemux_src_audio_raw",
- "audio/raw",
- "format", GST_PROPS_STRING ("int"),
- "law", GST_PROPS_INT (0),
- "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN),
- "signed", GST_PROPS_LIST (
- GST_PROPS_BOOLEAN (TRUE),
- GST_PROPS_BOOLEAN (FALSE)
- ),
- "width", GST_PROPS_LIST (
- GST_PROPS_INT (8),
- GST_PROPS_INT (16)
- ),
- "depth", GST_PROPS_LIST (
- GST_PROPS_INT (8),
- GST_PROPS_INT (16)
- ),
- "rate", GST_PROPS_INT_RANGE (11025, 44100),
- "channels", GST_PROPS_INT_RANGE (1, 2)
- ),
- GST_CAPS_NEW (
- "avidemux_src_audio_mp3",
- "audio/x-mp3",
- NULL
- ),
- GST_CAPS_NEW (
- "avidemux_src_audio_ac3",
- "audio/a52",
NULL
- ),
- GST_CAPS_NEW (
- "avidemux_src_audio_vorbis",
- "application/x-ogg",
- NULL
)
-)
-
-static void gst_avi_demux_class_init (GstAviDemuxClass *klass);
-static void gst_avi_demux_init (GstAviDemux *avi_demux);
-
-static void gst_avi_demux_loop (GstElement *element);
-
-static gboolean gst_avi_demux_send_event (GstElement *element, GstEvent *event);
-
-static const GstEventMask*
- gst_avi_demux_get_event_mask (GstPad *pad);
-static gboolean gst_avi_demux_handle_src_event (GstPad *pad, GstEvent *event);
-static const GstFormat* gst_avi_demux_get_src_formats (GstPad *pad);
-static const GstQueryType*
- gst_avi_demux_get_src_query_types (GstPad *pad);
-static gboolean gst_avi_demux_handle_src_query (GstPad *pad, GstQueryType type,
- GstFormat *format, gint64 *value);
-static gboolean gst_avi_demux_src_convert (GstPad *pad, GstFormat src_format, gint64 src_value,
- GstFormat *dest_format, gint64 *dest_value);
+);
+
+static void gst_avi_demux_class_init (GstAviDemuxClass *klass);
+static void gst_avi_demux_init (GstAviDemux *avi_demux);
+
+static void gst_avi_demux_loop (GstElement *element);
+
+static gboolean gst_avi_demux_send_event (GstElement *element,
+ GstEvent *event);
+
+static const GstEventMask *
+ gst_avi_demux_get_event_mask (GstPad *pad);
+static gboolean gst_avi_demux_handle_src_event (GstPad *pad,
+ GstEvent *event);
+static const GstFormat *
+ gst_avi_demux_get_src_formats (GstPad *pad);
+static const GstQueryType *
+ gst_avi_demux_get_src_query_types (GstPad *pad);
+static gboolean gst_avi_demux_handle_src_query (GstPad *pad,
+ GstQueryType type,
+ GstFormat *format,
+ gint64 *value);
+static gboolean gst_avi_demux_src_convert (GstPad *pad,
+ GstFormat src_format,
+ gint64 src_value,
+ GstFormat *dest_format,
+ gint64 *dest_value);
static GstElementStateReturn
- gst_avi_demux_change_state (GstElement *element);
-
-static void gst_avi_demux_get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec);
+ gst_avi_demux_change_state (GstElement *element);
+static void gst_avi_demux_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static GstPadTemplate *videosrctempl, *audiosrctempl;
static GstElementClass *parent_class = NULL;
/*static guint gst_avi_demux_signals[LAST_SIGNAL] = { 0 }; */
@@ -280,7 +188,7 @@ avi_type_find (GstBuffer *buf,
new = GST_CAPS_NEW ("avi_type_find",
"video/avi",
- "format", GST_PROPS_STRING ("AVI"));
+ NULL);
return new;
}
@@ -524,7 +432,7 @@ gst_avi_demux_metadata (GstAviDemux *avi_demux, gint len)
type = "Subject";
break;
case GST_RIFF_INFO_ISFT:
- type = "Encoder"; /* "Sotware" */
+ type = "Encoder"; /* "Software" */
break;
case GST_RIFF_INFO_ISHP:
type = "Sharpness";
@@ -577,102 +485,91 @@ gst_avi_demux_streaminfo (GstAviDemux *avi_demux)
/*g_object_notify(G_OBJECT(avi_demux), "streaminfo");*/
}
-static void
-gst_avi_demux_strf_vids (GstAviDemux *avi_demux)
+/* video/audio pad/caps stuff */
+
+#define GST_AVI_VID_CAPS_NEW(name, mimetype, props...) \
+ (strf != NULL) ? \
+ GST_CAPS_NEW (name, \
+ mimetype, \
+ "width", GST_PROPS_INT (width), \
+ "height", GST_PROPS_INT (height), \
+ "framerate", GST_PROPS_FLOAT (framerate), \
+ ##props) \
+ : \
+ GST_CAPS_NEW (name, \
+ mimetype, \
+ "width", GST_PROPS_INT_RANGE (16, 4096), \
+ "height", GST_PROPS_INT_RANGE (16, 4096), \
+ "framerate", GST_PROPS_FLOAT_RANGE (0., G_MAXFLOAT), \
+ ##props)
+
+static GstCaps *
+gst_avi_demux_video_caps (guint32 codec_fcc,
+ gst_riff_strh *strh,
+ gst_riff_strf_vids *strf,
+ GstAviDemux *avi_demux)
{
- gst_riff_strf_vids *strf;
- guint8 *strfdata;
- GstPad *srcpad;
- GstCaps *newcaps = NULL, *capslist = NULL;
- avi_stream_context *stream;
- GstByteStream *bs = avi_demux->bs;
- guint32 got_bytes;
- gchar *codecname;
- GstPropsEntry *entry;
-
- got_bytes = gst_bytestream_peek_bytes (bs, &strfdata, sizeof (gst_riff_strf_vids));
- strf = (gst_riff_strf_vids *) strfdata;
- if (got_bytes != sizeof (gst_riff_strf_vids))
- return;
-
- GST_INFO ( "gst_avi_demux: strf tag found in context vids");
- GST_INFO ( "gst_avi_demux: size %d", GUINT32_FROM_LE (strf->size));
- GST_INFO ( "gst_avi_demux: width %d", GUINT32_FROM_LE (strf->width));
- GST_INFO ( "gst_avi_demux: height %d", GUINT32_FROM_LE (strf->height));
- GST_INFO ( "gst_avi_demux: planes %d", GUINT16_FROM_LE (strf->planes));
- GST_INFO ( "gst_avi_demux: bit_cnt %d", GUINT16_FROM_LE (strf->bit_cnt));
- GST_INFO ( "gst_avi_demux: compression 0x%08x (%s)",
- GUINT32_FROM_LE (strf->compression), gst_riff_id_to_fourcc (strf->compression));
- GST_INFO ( "gst_avi_demux: image_size %d", GUINT32_FROM_LE (strf->image_size));
- GST_INFO ( "gst_avi_demux: xpels_meter %d", GUINT32_FROM_LE (strf->xpels_meter));
- GST_INFO ( "gst_avi_demux: ypels_meter %d", GUINT32_FROM_LE (strf->ypels_meter));
- GST_INFO ( "gst_avi_demux: num_colors %d", GUINT32_FROM_LE (strf->num_colors));
- GST_INFO ( "gst_avi_demux: imp_colors %d", GUINT32_FROM_LE (strf->imp_colors));
-
- srcpad = gst_pad_new_from_template (
- GST_PAD_TEMPLATE_GET (src_video_templ), g_strdup_printf ("video_%02d",
- avi_demux->num_v_streams));
-
- capslist = gst_caps_append(NULL, GST_CAPS_NEW (
- "avidemux_video_src",
- "video/avi",
- "format", GST_PROPS_STRING ("strf_vids"),
- "size", GST_PROPS_INT (GUINT32_FROM_LE (strf->size)),
- "width", GST_PROPS_INT (GUINT32_FROM_LE (strf->width)),
- "height", GST_PROPS_INT (GUINT32_FROM_LE (strf->height)),
- "planes", GST_PROPS_INT (GUINT16_FROM_LE (strf->planes)),
- "bit_cnt", GST_PROPS_INT (GUINT16_FROM_LE (strf->bit_cnt)),
- "compression", GST_PROPS_FOURCC (GUINT32_FROM_LE (strf->compression)),
- "image_size", GST_PROPS_INT (GUINT32_FROM_LE (strf->image_size)),
- "xpels_meter", GST_PROPS_INT (GUINT32_FROM_LE (strf->xpels_meter)),
- "ypels_meter", GST_PROPS_INT (GUINT32_FROM_LE (strf->ypels_meter)),
- "num_colors", GST_PROPS_INT (GUINT32_FROM_LE (strf->num_colors)),
- "imp_colors", GST_PROPS_INT (GUINT32_FROM_LE (strf->imp_colors))
- ));
+ GstCaps *caps = NULL;
+ gchar *codecname = NULL;
+ gint width = -1, height = -1;
+ gdouble framerate = 0.;
+
+ if (strf != NULL) {
+ width = GUINT32_FROM_LE (strf->width);
+ height = GUINT32_FROM_LE (strf->height);
+ }
+ if (strh != NULL) {
+ framerate = 1. * GUINT32_FROM_LE (strh->rate) /
+ GUINT32_FROM_LE (strh->scale); /* fps */
+ }
- /* let's try some gstreamer-like mime-type caps */
- switch (GUINT32_FROM_LE(strf->compression))
- {
+ switch (codec_fcc) {
case GST_MAKE_FOURCC('I','4','2','0'):
case GST_MAKE_FOURCC('Y','U','Y','2'):
- newcaps = GST_CAPS_NEW (
- "avidemux_video_src",
- "video/raw",
- "format", GST_PROPS_FOURCC(GUINT32_FROM_LE(strf->compression)),
- "width", GST_PROPS_INT(strf->width),
- "height", GST_PROPS_INT(strf->height)
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src_raw",
+ "video/x-raw-yuv",
+ "format", GST_PROPS_FOURCC (codec_fcc)
);
- codecname = g_strdup_printf("Raw Video (%4.4s)",
- (char *) &strf->compression);
+ codecname = g_strdup_printf("Raw Video (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
break;
+
case GST_MAKE_FOURCC('M','J','P','G'): /* YUY2 MJPEG */
case GST_MAKE_FOURCC('J','P','E','G'): /* generic (mostly RGB) MJPEG */
case GST_MAKE_FOURCC('P','I','X','L'): /* Miro/Pinnacle fourccs */
case GST_MAKE_FOURCC('V','I','X','L'): /* Miro/Pinnacle fourccs */
- newcaps = GST_CAPS_NEW (
- "avidemux_video_src",
- "video/jpeg",
- "width", GST_PROPS_INT(strf->width),
- "height", GST_PROPS_INT(strf->height)
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src_jpeg",
+ "video/x-jpeg",
+ NULL
);
- codecname = g_strdup_printf("Motion-JPEG (%4.4s)",
- (char *) &strf->compression);
+ codecname = g_strdup_printf("Motion-JPEG (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
break;
+
case GST_MAKE_FOURCC('H','F','Y','U'):
- codecname = g_strdup_printf("HuffYUV (%4.4s)",
- (char *) &strf->compression);
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src_hfyu",
+ "video/x-huffyuv",
+ NULL
+ );
+ codecname = g_strdup_printf("HuffYUV (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
break;
+
case GST_MAKE_FOURCC('M','P','E','G'):
case GST_MAKE_FOURCC('M','P','G','I'):
- newcaps = GST_CAPS_NEW (
- "avidemux_video_src",
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src_mpeg",
"video/mpeg",
- "width", GST_PROPS_INT(strf->width),
- "height", GST_PROPS_INT(strf->height)
+ "systemstream", GST_PROPS_BOOLEAN (FALSE),
+ "mpegversion", GST_PROPS_BOOLEAN (1)
);
- codecname = g_strdup_printf("MPEG-1 (%4.4s)",
- (char *) &strf->compression);
+ codecname = g_strdup_printf("MPEG-1 (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
break;
+
case GST_MAKE_FOURCC('H','2','6','3'):
case GST_MAKE_FOURCC('i','2','6','3'):
case GST_MAKE_FOURCC('L','2','6','3'):
@@ -680,67 +577,174 @@ gst_avi_demux_strf_vids (GstAviDemux *avi_demux)
case GST_MAKE_FOURCC('V','D','O','W'):
case GST_MAKE_FOURCC('V','I','V','O'):
case GST_MAKE_FOURCC('x','2','6','3'):
- codecname = g_strdup_printf("H263-compatible (%4.4s)",
- (char *) &strf->compression);
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src_263",
+ "video/x-h263",
+ NULL
+ );
+ codecname = g_strdup_printf("H263-compatible (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
break;
- case GST_MAKE_FOURCC('d','i','v','x'):
+
case GST_MAKE_FOURCC('D','I','V','3'):
case GST_MAKE_FOURCC('D','I','V','4'):
case GST_MAKE_FOURCC('D','I','V','5'):
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src_divx3",
+ "video/x-divx",
+ "divxversion", GST_PROPS_INT(3)
+ );
+ codecname = g_strdup_printf("DivX-3.x (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
+ break;
+
+ case GST_MAKE_FOURCC('d','i','v','x'):
case GST_MAKE_FOURCC('D','I','V','X'):
case GST_MAKE_FOURCC('D','X','5','0'):
- newcaps = GST_CAPS_NEW (
- "avidemux_video_src",
- "video/divx",
- "width", GST_PROPS_INT(strf->width),
- "height", GST_PROPS_INT(strf->height)
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src_divx5",
+ "video/x-divx",
+ "divxversion", GST_PROPS_INT(5)
);
- codecname = g_strdup_printf("DivX/MPEG-4 (%4.4s)",
- (char *) &strf->compression);
+ codecname = g_strdup_printf("DivX 4.x/5.x (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
break;
+
case GST_MAKE_FOURCC('X','V','I','D'):
case GST_MAKE_FOURCC('x','v','i','d'):
- newcaps = GST_CAPS_NEW (
+ caps = GST_AVI_VID_CAPS_NEW (
"avidemux_video_src",
- "video/xvid",
- "width", GST_PROPS_INT(strf->width),
- "height", GST_PROPS_INT(strf->height)
+ "video/x-xvid",
+ NULL
);
- codecname = g_strdup_printf("XviD/MPEG-4 (%4.4s)",
- (char *) &strf->compression);
+ codecname = g_strdup_printf("XviD (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
break;
+
case GST_MAKE_FOURCC('M','P','G','4'):
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src",
+ "video/x-msmpeg",
+ "msmpegversion", GST_PROPS_INT (41)
+ );
+ codecname = g_strdup_printf("MS MPEG-4.1 (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
+ break;
+
case GST_MAKE_FOURCC('M','P','4','2'):
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src",
+ "video/x-msmpeg",
+ "msmpegversion", GST_PROPS_INT (42)
+ );
+ codecname = g_strdup_printf("MS MPEG-4.2 (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
+ break;
+
case GST_MAKE_FOURCC('M','P','4','3'):
- codecname = g_strdup_printf("MS MPEG-4 (%4.4s)",
- (char *) &strf->compression);
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src",
+ "video/x-msmpeg",
+ "msmpegversion", GST_PROPS_INT (43)
+ );
+ codecname = g_strdup_printf("MS MPEG-4.3 (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
+ break;
+
+ case GST_MAKE_FOURCC('3','I','V','1'):
+ case GST_MAKE_FOURCC('3','I','V','2'):
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src_3ivx",
+ "video/x-3ivx",
+ NULL
+ );
+ codecname = g_strdup_printf("3ivX (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
break;
+
case GST_MAKE_FOURCC('D','V','S','D'):
case GST_MAKE_FOURCC('d','v','s','d'):
- newcaps = GST_CAPS_NEW (
+ caps = GST_AVI_VID_CAPS_NEW (
"avidemux_video_src",
- "video/dv",
- "format", GST_PROPS_STRING("NTSC"), /* FIXME??? */
- "width", GST_PROPS_INT(strf->width),
- "height", GST_PROPS_INT(strf->height)
+ "video/x-dv",
+ "systemstream", GST_PROPS_BOOLEAN (FALSE)
+ );
+ codecname = g_strdup_printf("Digital Video (" GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
+ break;
+
+ case GST_MAKE_FOURCC('W','M','V','1'):
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src_wmv1",
+ "video/x-wmv",
+ "wmvversion", GST_PROPS_INT (1)
+ );
+ codecname = g_strdup_printf("Windows Media Format 1 ("
+ GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
+ break;
+
+ case GST_MAKE_FOURCC('W','M','V','2'):
+ caps = GST_AVI_VID_CAPS_NEW (
+ "avidemux_video_src_wmv2",
+ "video/x-wmv",
+ "wmvversion", GST_PROPS_INT (2)
);
- codecname = g_strdup_printf("Digital Video (%4.4s)",
- (char *) &strf->compression);
+ codecname = g_strdup_printf("Windows Media Format 2 ("
+ GST_FOURCC_FORMAT ")",
+ GST_FOURCC_ARGS(codec_fcc));
break;
+
default:
- codecname = g_strdup_printf("Unknown (%4.4s)",
- (char *) &strf->compression);
+ g_warning ("avidemux: unkown video format " GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS(codec_fcc));
break;
}
- if (newcaps) capslist = gst_caps_append (capslist, newcaps);
-
/* set video codec info on streaminfo caps */
- entry = gst_props_entry_new("videocodec", GST_PROPS_STRING(codecname));
- gst_props_add_entry(avi_demux->streaminfo->properties, entry);
- g_free(codecname);
+ if (strf != NULL && codecname != NULL) {
+ GstPropsEntry *entry;
+ entry = gst_props_entry_new("videocodec",
+ GST_PROPS_STRING(codecname));
+ gst_props_add_entry(avi_demux->streaminfo->properties, entry);
+ }
+ if (codecname != NULL) {
+ g_free(codecname);
+ }
+
+ return caps;
+}
+
+static void
+gst_avi_demux_strf_vids (GstAviDemux *avi_demux)
+{
+ gst_riff_strf_vids *strf;
+ gst_riff_strh *strh;
+ guint8 *strfdata;
+ GstPad *srcpad;
+ GstCaps *caps = NULL;
+ avi_stream_context *stream;
+ GstByteStream *bs = avi_demux->bs;
+ guint32 got_bytes;
+ gchar *padname;
+
+ got_bytes = gst_bytestream_peek_bytes (bs, &strfdata, sizeof (gst_riff_strf_vids));
+ strf = (gst_riff_strf_vids *) strfdata;
+ if (got_bytes != sizeof (gst_riff_strf_vids))
+ return;
+
+ padname = g_strdup_printf ("video_%02d", avi_demux->num_v_streams);
+ srcpad = gst_pad_new_from_template (videosrctempl, padname);
+ g_free (padname);
- gst_pad_try_set_caps (srcpad, capslist);
+ /* let's try some gstreamer-like mime-type caps */
+ strh = &avi_demux->stream[avi_demux->num_streams].strh;
+ caps = gst_avi_demux_video_caps (GUINT32_FROM_LE(strf->compression),
+ strh, strf, avi_demux);
+
+ if (caps != NULL) {
+ gst_pad_try_set_caps (srcpad, caps);
+ }
gst_pad_set_formats_function (srcpad, gst_avi_demux_get_src_formats);
gst_pad_set_event_mask_function (srcpad, gst_avi_demux_get_event_mask);
gst_pad_set_event_function (srcpad, gst_avi_demux_handle_src_event);
@@ -757,130 +761,195 @@ gst_avi_demux_strf_vids (GstAviDemux *avi_demux)
gst_element_add_pad (GST_ELEMENT (avi_demux), srcpad);
}
-static void
-gst_avi_demux_strf_auds (GstAviDemux *avi_demux)
+#define GST_AVI_AUD_CAPS_NEW(name, mimetype, props...) \
+ (strf != NULL) ? \
+ GST_CAPS_NEW (name, \
+ mimetype, \
+ "rate", GST_PROPS_INT (rate), \
+ "channels", GST_PROPS_INT (channels), \
+ ##props) \
+ : \
+ GST_CAPS_NEW (name, \
+ mimetype, \
+ "rate", GST_PROPS_INT_RANGE (8000, 96000), \
+ "channels", GST_PROPS_INT_RANGE (1, 2), \
+ ##props)
+
+
+static GstCaps *
+gst_avi_demux_audio_caps (guint16 codec_id,
+ gst_riff_strf_auds *strf,
+ GstAviDemux *avi_demux)
{
- gst_riff_strf_auds *strf;
- guint8 *strfdata;
- GstPad *srcpad;
- GstCaps *newcaps = NULL, *capslist = NULL;
- avi_stream_context *stream;
- GstByteStream *bs = avi_demux->bs;
- guint32 got_bytes;
- gchar *codecname;
- GstPropsEntry *entry;
+ GstCaps *caps = NULL;
+ gchar *codecname = NULL;
+ gint rate = -1, channels = -1;
- got_bytes = gst_bytestream_peek_bytes (bs, &strfdata, sizeof (gst_riff_strf_auds));
- strf = (gst_riff_strf_auds *) strfdata;
- if (got_bytes != sizeof (gst_riff_strf_auds))
- return;
+ if (strf != NULL) {
+ rate = GUINT32_FROM_LE (strf->rate);
+ channels = GUINT16_FROM_LE (strf->channels);
+ }
- GST_INFO ( "gst_avi_demux: strf tag found in context auds");
- GST_INFO ( "gst_avi_demux: format %d", GUINT16_FROM_LE (strf->format));
- GST_INFO ( "gst_avi_demux: channels %d", GUINT16_FROM_LE (strf->channels));
- GST_INFO ( "gst_avi_demux: rate %d", GUINT32_FROM_LE (strf->rate));
- GST_INFO ( "gst_avi_demux: av_bps %d", GUINT32_FROM_LE (strf->av_bps));
- GST_INFO ( "gst_avi_demux: blockalign %d", GUINT16_FROM_LE (strf->blockalign));
- GST_INFO ( "gst_avi_demux: size %d", GUINT16_FROM_LE (strf->size));
+ switch (codec_id) {
+ case GST_RIFF_WAVE_FORMAT_MPEGL3: /* mp3 */
+ caps = GST_AVI_AUD_CAPS_NEW ("avi_demux_audio_src_mp3",
+ "audio/mpeg",
+ "layer", GST_PROPS_INT (3));
+ codecname = g_strdup_printf("MPEG-1 layer 3 audio (0x%04x)",
+ codec_id);
+ break;
- srcpad = gst_pad_new_from_template (
- GST_PAD_TEMPLATE_GET (src_audio_templ), g_strdup_printf ("audio_%02d",
- avi_demux->num_a_streams));
-
- capslist = gst_caps_append(NULL, GST_CAPS_NEW (
- "avidemux_audio_src",
- "video/avi",
- "format", GST_PROPS_STRING ("strf_auds"),
- "fmt", GST_PROPS_INT (GUINT16_FROM_LE (strf->format)),
- "channels", GST_PROPS_INT (GUINT16_FROM_LE (strf->channels)),
- "rate", GST_PROPS_INT (GUINT32_FROM_LE (strf->rate)),
- "av_bps", GST_PROPS_INT (GUINT32_FROM_LE (strf->av_bps)),
- "blockalign", GST_PROPS_INT (GUINT16_FROM_LE (strf->blockalign)),
- "size", GST_PROPS_INT (GUINT16_FROM_LE (strf->size))
- ));
-
- /* let's try some gstreamer-formatted mime types */
- switch (GUINT16_FROM_LE(strf->format))
- {
- case GST_RIFF_WAVE_FORMAT_MPEGL3:
- case GST_RIFF_WAVE_FORMAT_MPEGL12: /* mp3 */
- newcaps = gst_caps_new ("avidemux_audio_src",
- "audio/x-mp3",
- NULL);
- codecname = g_strdup_printf("MPEG/audio (0x%04x)",
- strf->format);
+ case GST_RIFF_WAVE_FORMAT_MPEGL12: /* mp1 or mp2 */
+ caps = GST_AVI_AUD_CAPS_NEW ("avi_demux_audio_src_mp12",
+ "audio/mpeg",
+ "layer", GST_PROPS_INT (2));
+ codecname = g_strdup_printf("MPEG-1 layer 1/2 audio (0x%04x)",
+ codec_id);
break;
- case GST_RIFF_WAVE_FORMAT_PCM: /* PCM/wav */
- newcaps = gst_caps_new ("avidemux_audio_src",
- "audio/raw",
- gst_props_new (
- "format", GST_PROPS_STRING ("int"),
- "law", GST_PROPS_INT (0),
- "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN),
- "signed", GST_PROPS_BOOLEAN ((GUINT16_FROM_LE (strf->size) != 8)),
- "width", GST_PROPS_INT ((GUINT16_FROM_LE (strf->blockalign)*8) /
- GUINT16_FROM_LE (strf->channels)),
- "depth", GST_PROPS_INT (GUINT16_FROM_LE (strf->size)),
- "rate", GST_PROPS_INT (GUINT32_FROM_LE (strf->rate)),
- "channels", GST_PROPS_INT (GUINT16_FROM_LE (strf->channels)),
- NULL
- ));
+
+ case GST_RIFF_WAVE_FORMAT_PCM: /* PCM/wav */ {
+ GstPropsEntry *width = NULL, *depth = NULL, *signedness = NULL;
+
+ if (strf != NULL) {
+ gint ba = GUINT16_FROM_LE (strf->blockalign);
+ gint ch = GUINT16_FROM_LE (strf->channels);
+ gint ws = GUINT16_FROM_LE (strf->size);
+
+ width = gst_props_entry_new ("width",
+ GST_PROPS_INT (ba * 8 / ch));
+ depth = gst_props_entry_new ("depth",
+ GST_PROPS_INT (ws));
+ signedness = gst_props_entry_new ("signed",
+ GST_PROPS_BOOLEAN (ws != 8));
+ } else {
+ signedness = gst_props_entry_new ("signed",
+ GST_PROPS_LIST (
+ GST_PROPS_BOOLEAN (TRUE),
+ GST_PROPS_BOOLEAN (FALSE)));
+ width = gst_props_entry_new ("width",
+ GST_PROPS_LIST (
+ GST_PROPS_INT (8),
+ GST_PROPS_INT (16)));
+ depth = gst_props_entry_new ("depth",
+ GST_PROPS_LIST (
+ GST_PROPS_INT (8),
+ GST_PROPS_INT (16)));
+ }
+
+ caps = GST_AVI_AUD_CAPS_NEW ("avi_demux_audio_src_pcm",
+ "audio/x-raw-int",
+ "endianness",
+ GST_PROPS_INT (G_LITTLE_ENDIAN));
+ gst_props_add_entry (caps->properties, width);
+ gst_props_add_entry (caps->properties, depth);
+ gst_props_add_entry (caps->properties, signedness);
+
codecname = g_strdup_printf("Raw PCM/WAV (0x%04x)",
- strf->format);
+ codec_id);
+ }
break;
+
case GST_RIFF_WAVE_FORMAT_MULAW:
+ if (strf != NULL && strf->size != 8) {
+ g_warning ("invalid depth (%d) of mulaw audio, overwriting.",
+ strf->size);
+ }
+ caps = GST_AVI_AUD_CAPS_NEW ("avidemux_audio_src",
+ "audio/x-mulaw",
+ NULL);
+ codecname = g_strdup_printf("A-law encoded (0x%04x)",
+ codec_id);
+ break;
+
case GST_RIFF_WAVE_FORMAT_ALAW:
- if (strf->size != 8)
- g_warning ("invalid depth (%d) of mulaw/alaw audio, overwriting.", strf->size);
- newcaps = gst_caps_new ("avidemux_audio_src",
- "audio/raw",
- gst_props_new (
- "format", GST_PROPS_STRING ("int"),
- "law", GST_PROPS_INT (GUINT16_FROM_LE(strf->format) == GST_RIFF_WAVE_FORMAT_ALAW ? 2 : 1),
- "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN),
- "width", GST_PROPS_INT (8),
- "depth", GST_PROPS_INT (8),
- "rate", GST_PROPS_INT (GUINT32_FROM_LE (strf->rate)),
- "channels", GST_PROPS_INT (GUINT16_FROM_LE (strf->channels)),
- NULL
- ));
- codecname = g_strdup_printf("%s-law encoded (0x%04x)",
- GUINT16_FROM_LE(strf->format) == GST_RIFF_WAVE_FORMAT_ALAW ? "A" : "Mu", strf->format);
+ if (strf != NULL && strf->size != 8) {
+ g_warning ("invalid depth (%d) of alaw audio, overwriting.",
+ strf->size);
+ }
+ caps = GST_AVI_AUD_CAPS_NEW ("avidemux_audio_src",
+ "audio/x-alaw",
+ NULL);
+ codecname = g_strdup_printf("A-law encoded (0x%04x)",
+ codec_id);
break;
+
case GST_RIFF_WAVE_FORMAT_VORBIS1: /* ogg/vorbis mode 1 */
case GST_RIFF_WAVE_FORMAT_VORBIS2: /* ogg/vorbis mode 2 */
case GST_RIFF_WAVE_FORMAT_VORBIS3: /* ogg/vorbis mode 3 */
case GST_RIFF_WAVE_FORMAT_VORBIS1PLUS: /* ogg/vorbis mode 1+ */
case GST_RIFF_WAVE_FORMAT_VORBIS2PLUS: /* ogg/vorbis mode 2+ */
case GST_RIFF_WAVE_FORMAT_VORBIS3PLUS: /* ogg/vorbis mode 3+ */
- newcaps = gst_caps_new ("avidemux_audio_src",
- "application/x-ogg",
- NULL);
- codecname = g_strdup_printf("Ogg/Vorbis (0x%04x)",
- strf->format);
+ caps = GST_AVI_AUD_CAPS_NEW ("asf_demux_audio_src_vorbis",
+ "audio/x-vorbis",
+ NULL);
+ codecname = g_strdup_printf("Vorbis (0x%04x)",
+ codec_id);
break;
+
case GST_RIFF_WAVE_FORMAT_A52:
- newcaps = gst_caps_new ("avidemux_audio_src",
- "audio/a52",
- NULL);
- codecname = g_strdup_printf("AC3/AC52 (0x%04x)",
- strf->format);
+ caps = GST_AVI_AUD_CAPS_NEW ("asf_demux_audio_src_ac3",
+ "audio/x-ac3",
+ NULL);
+ codecname = g_strdup_printf("AC-3 (0x%04x)",
+ codec_id);
break;
+
default:
- g_warning ("avidemux: unkown audio format %d", GUINT16_FROM_LE(strf->format));
- codecname = g_strdup_printf("Unknown (0x%04x)",
- strf->format);
+ g_warning ("avidemux: unkown audio format 0x%04x",
+ codec_id);
break;
}
- if (newcaps) capslist = gst_caps_append(capslist, newcaps);
+ if (strf != NULL && codecname != NULL) {
+ /* set audio codec in streaminfo */
+ GstPropsEntry *entry;
+ entry = gst_props_entry_new("audiocodec",
+ GST_PROPS_STRING(codecname));
+ gst_props_add_entry(avi_demux->streaminfo->properties, entry);
+ }
+ if (codecname != NULL) {
+ g_free (codecname);
+ }
+
+ return caps;
+}
- /* set audio codec in streaminfo */
- entry = gst_props_entry_new("audiocodec", GST_PROPS_STRING(codecname));
- gst_props_add_entry(avi_demux->streaminfo->properties, entry);
- g_free(codecname);
+static void
+gst_avi_demux_strf_auds (GstAviDemux *avi_demux)
+{
+ gst_riff_strf_auds *strf;
+ guint8 *strfdata;
+ GstPad *srcpad;
+ GstCaps *caps = NULL;
+ avi_stream_context *stream;
+ GstByteStream *bs = avi_demux->bs;
+ guint32 got_bytes;
+ gchar *padname;
+
+ got_bytes = gst_bytestream_peek_bytes (bs, &strfdata, sizeof (gst_riff_strf_auds));
+ strf = (gst_riff_strf_auds *) strfdata;
+ if (got_bytes != sizeof (gst_riff_strf_auds))
+ return;
- gst_pad_try_set_caps(srcpad, capslist);
+ GST_INFO ( "gst_avi_demux: strf tag found in context auds");
+ GST_INFO ( "gst_avi_demux: format %d", GUINT16_FROM_LE (strf->format));
+ GST_INFO ( "gst_avi_demux: channels %d", GUINT16_FROM_LE (strf->channels));
+ GST_INFO ( "gst_avi_demux: rate %d", GUINT32_FROM_LE (strf->rate));
+ GST_INFO ( "gst_avi_demux: av_bps %d", GUINT32_FROM_LE (strf->av_bps));
+ GST_INFO ( "gst_avi_demux: blockalign %d", GUINT16_FROM_LE (strf->blockalign));
+ GST_INFO ( "gst_avi_demux: size %d", GUINT16_FROM_LE (strf->size));
+
+ padname = g_strdup_printf ("audio_%02d",
+ avi_demux->num_a_streams);
+ srcpad = gst_pad_new_from_template (audiosrctempl, padname);
+ g_free (padname);
+
+ caps = gst_avi_demux_audio_caps (GUINT16_FROM_LE (strf->format),
+ strf, avi_demux);
+
+ if (caps != NULL) {
+ gst_pad_try_set_caps(srcpad, caps);
+ }
gst_pad_set_formats_function (srcpad, gst_avi_demux_get_src_formats);
gst_pad_set_event_mask_function (srcpad, gst_avi_demux_get_event_mask);
gst_pad_set_event_function (srcpad, gst_avi_demux_handle_src_event);
@@ -897,16 +966,25 @@ gst_avi_demux_strf_auds (GstAviDemux *avi_demux)
gst_element_add_pad (GST_ELEMENT (avi_demux), srcpad);
}
+static GstCaps *
+gst_avi_demux_iavs_caps (void)
+{
+ return GST_CAPS_NEW ("avi_type_dv",
+ "video/x-dv",
+ "systemstream", GST_PROPS_BOOLEAN (TRUE));
+}
+
static void
gst_avi_demux_strf_iavs (GstAviDemux *avi_demux)
{
gst_riff_strf_iavs *strf;
guint8 *strfdata;
GstPad *srcpad;
- GstCaps *newcaps = NULL, *capslist = NULL;
+ GstCaps *caps = NULL;
avi_stream_context *stream;
GstByteStream *bs = avi_demux->bs;
guint32 got_bytes;
+ gchar *padname;
got_bytes = gst_bytestream_peek_bytes (bs, &strfdata, sizeof (gst_riff_strf_iavs));
strf = (gst_riff_strf_iavs *) strfdata;
@@ -923,33 +1001,16 @@ gst_avi_demux_strf_iavs (GstAviDemux *avi_demux)
GST_INFO ( "gst_avi_demux: DVReserved1 %08x", GUINT32_FROM_LE (strf->DVReserved1));
GST_INFO ( "gst_avi_demux: DVReserved2 %08x", GUINT32_FROM_LE (strf->DVReserved2));
- srcpad = gst_pad_new_from_template (
- GST_PAD_TEMPLATE_GET (src_video_templ), g_strdup_printf ("video_%02d",
- avi_demux->num_v_streams));
-
- capslist = gst_caps_append(NULL, GST_CAPS_NEW (
- "avidemux_video_src",
- "video/avi",
- "format", GST_PROPS_STRING ("strf_iavs"),
- "DVAAuxSrc", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVAAuxSrc)),
- "DVAAuxCtl", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVAAuxCtl)),
- "DVAAuxSrc1", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVAAuxSrc1)),
- "DVAAuxCtl1", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVAAuxCtl1)),
- "DVVAuxSrc", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVVAuxSrc)),
- "DVVAuxCtl", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVVAuxCtl)),
- "DVReserved1", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVReserved1)),
- "DVReserved2", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVReserved2))
- ));
-
- newcaps = gst_caps_new ("avi_type_dv",
- "video/dv",
- gst_props_new (
- "format", GST_PROPS_STRING ("NTSC"), /* FIXME??? */
- NULL));
-
- if (newcaps) capslist = gst_caps_append(capslist, newcaps);
-
- gst_pad_try_set_caps(srcpad, capslist);
+ padname = g_strdup_printf ("video_%02d",
+ avi_demux->num_v_streams);
+ srcpad = gst_pad_new_from_template (videosrctempl, padname);
+ g_free (padname);
+
+ caps = gst_avi_demux_iavs_caps ();
+
+ if (caps != NULL) {
+ gst_pad_try_set_caps(srcpad, caps);
+ }
gst_pad_set_formats_function (srcpad, gst_avi_demux_get_src_formats);
gst_pad_set_event_mask_function (srcpad, gst_avi_demux_get_event_mask);
gst_pad_set_event_function (srcpad, gst_avi_demux_handle_src_event);
@@ -1821,6 +1882,37 @@ plugin_init (GModule *module, GstPlugin *plugin)
{
GstElementFactory *factory;
GstTypeFactory *type;
+ gint i = 0;
+ GstCaps *audcaps = NULL, *vidcaps = NULL, *temp;
+ guint32 vid_list[] = {
+ GST_MAKE_FOURCC('I','4','2','0'),
+ GST_MAKE_FOURCC('Y','U','Y','2'),
+ GST_MAKE_FOURCC('M','J','P','G'),
+ GST_MAKE_FOURCC('D','V','S','D'),
+ GST_MAKE_FOURCC('W','M','V','1'),
+ GST_MAKE_FOURCC('W','M','V','2'),
+ GST_MAKE_FOURCC('M','P','G','4'),
+ GST_MAKE_FOURCC('M','P','4','2'),
+ GST_MAKE_FOURCC('M','P','4','3'),
+ GST_MAKE_FOURCC('H','F','Y','U'),
+ GST_MAKE_FOURCC('D','I','V','3'),
+ GST_MAKE_FOURCC('M','P','E','G'),
+ GST_MAKE_FOURCC('H','2','6','3'),
+ GST_MAKE_FOURCC('D','I','V','X'),
+ GST_MAKE_FOURCC('X','V','I','D'),
+ GST_MAKE_FOURCC('3','I','V','1'),
+ 0 /* end */
+ };
+ gint aud_list[] = {
+ GST_RIFF_WAVE_FORMAT_MPEGL3,
+ GST_RIFF_WAVE_FORMAT_MPEGL12,
+ GST_RIFF_WAVE_FORMAT_PCM,
+ GST_RIFF_WAVE_FORMAT_VORBIS1,
+ GST_RIFF_WAVE_FORMAT_A52,
+ GST_RIFF_WAVE_FORMAT_ALAW,
+ GST_RIFF_WAVE_FORMAT_MULAW,
+ -1 /* end */
+ };
/* this filter needs the riff parser */
if (!gst_library_load ("gstbytestream"))
@@ -1835,9 +1927,28 @@ plugin_init (GModule *module, GstPlugin *plugin)
g_return_val_if_fail (factory != NULL, FALSE);
gst_element_factory_set_rank (factory, GST_ELEMENT_RANK_PRIMARY);
- gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (src_audio_templ));
- gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (src_video_templ));
- gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (sink_templ));
+ for (i = 0; aud_list[i] != -1; i++) {
+ temp = gst_avi_demux_audio_caps (aud_list[i], NULL, NULL);
+ audcaps = gst_caps_append (audcaps, temp);
+ }
+ audiosrctempl = gst_pad_template_new ("audio_%02d",
+ GST_PAD_SRC,
+ GST_PAD_SOMETIMES,
+ audcaps, NULL);
+ for (i = 0; vid_list[i] != 0; i++) {
+ temp = gst_avi_demux_video_caps (vid_list[i], NULL, NULL, NULL);
+ vidcaps = gst_caps_append (vidcaps, temp);
+ }
+ vidcaps = gst_caps_append (vidcaps,
+ gst_avi_demux_iavs_caps ());
+ videosrctempl = gst_pad_template_new ("video_%02d",
+ GST_PAD_SRC,
+ GST_PAD_SOMETIMES,
+ vidcaps, NULL);
+ gst_element_factory_add_pad_template (factory, audiosrctempl);
+ gst_element_factory_add_pad_template (factory, videosrctempl);
+ gst_element_factory_add_pad_template (factory,
+ GST_PAD_TEMPLATE_GET (sink_templ));
type = gst_type_factory_new (&avidefinition);
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
@@ -1853,4 +1964,3 @@ GstPluginDesc plugin_desc = {
"avidemux",
plugin_init
};
-