summaryrefslogtreecommitdiffstats
path: root/gst/avi
diff options
context:
space:
mode:
Diffstat (limited to 'gst/avi')
-rw-r--r--gst/avi/gstavidemux.c846
-rw-r--r--gst/avi/gstavimux.c406
2 files changed, 695 insertions, 557 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
};
-
diff --git a/gst/avi/gstavimux.c b/gst/avi/gstavimux.c
index 8dfa50fa..6b3a442b 100644
--- a/gst/avi/gstavimux.c
+++ b/gst/avi/gstavimux.c
@@ -84,55 +84,74 @@ GST_PAD_TEMPLATE_FACTORY (video_sink_factory,
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_CAPS_NEW (
- "avimux_sink_video_avi",
- "video/avi",
- "format", GST_PROPS_STRING ("strf_vids")
- ),
- GST_CAPS_NEW (
"avimux_sink_video_yuv",
- "video/raw",
+ "video/x-raw-yuv",
"format", GST_PROPS_LIST (
GST_PROPS_FOURCC (GST_MAKE_FOURCC('Y','U','Y','2')),
- GST_PROPS_FOURCC (GST_MAKE_FOURCC('I','4','2','0')),
- GST_PROPS_FOURCC (GST_MAKE_FOURCC('Y','4','1','P'))
+ 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 (
- "avimux_sink_video_rgb",
- "video/raw",
- "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC('R','G','B',' ')),
+ "avimux_sink_video_jpeg",
+ "video/x-jpeg",
+ "width", GST_PROPS_INT_RANGE (16, 4096),
+ "height", GST_PROPS_INT_RANGE (16, 4096)
+ ),
+ GST_CAPS_NEW (
+ "avimux_sink_video_divx",
+ "video/x-divx",
"width", GST_PROPS_INT_RANGE (16, 4096),
"height", GST_PROPS_INT_RANGE (16, 4096),
- "depth", GST_PROPS_LIST(
- GST_PROPS_INT(16),
- GST_PROPS_INT(16),
- GST_PROPS_INT(24),
- GST_PROPS_INT(32)
- ),
- "bpp", GST_PROPS_LIST(
- GST_PROPS_INT(15),
- GST_PROPS_INT(16),
- GST_PROPS_INT(24),
- GST_PROPS_INT(32)
- )
+ "divxversion", GST_PROPS_INT_RANGE (3, 5)
),
GST_CAPS_NEW (
- "avimux_sink_video_jpeg",
- "video/jpeg",
+ "avimux_sink_video_xvid",
+ "video/x-xvid",
"width", GST_PROPS_INT_RANGE (16, 4096),
"height", GST_PROPS_INT_RANGE (16, 4096)
),
GST_CAPS_NEW (
- "avimux_sink_video_divx",
- "video/divx",
+ "avimux_sink_video_3ivx",
+ "video/x-3ivx",
"width", GST_PROPS_INT_RANGE (16, 4096),
"height", GST_PROPS_INT_RANGE (16, 4096)
),
GST_CAPS_NEW (
- "avimux_sink_video_xvid",
- "video/xvid",
+ "avimux_sink_video_msmpeg",
+ "video/x-msmpeg",
+ "width", GST_PROPS_INT_RANGE (16, 4096),
+ "height", GST_PROPS_INT_RANGE (16, 4096),
+ "msmpegversion", GST_PROPS_INT_RANGE (41, 43)
+ ),
+ GST_CAPS_NEW (
+ "avimux_sink_video_mpeg",
+ "video/mpeg",
+ "width", GST_PROPS_INT_RANGE (16, 4096),
+ "height", GST_PROPS_INT_RANGE (16, 4096),
+ "mpegversion", GST_PROPS_INT (1),
+ "systemstream", GST_PROPS_BOOLEAN (FALSE)
+ ),
+ GST_CAPS_NEW (
+ "avimux_sink_video_h263",
+ "video/x-h263",
+ "width", GST_PROPS_INT_RANGE (16, 4096),
+ "height", GST_PROPS_INT_RANGE (16, 4096)
+ ),
+ GST_CAPS_NEW (
+ "avimux_sink_video_dv",
+ "video/x-dv",
+ "width", GST_PROPS_INT (720),
+ "height", GST_PROPS_LIST (
+ GST_PROPS_INT (576),
+ GST_PROPS_INT (480)
+ ),
+ "systemstream", GST_PROPS_BOOLEAN (FALSE)
+ ),
+ GST_CAPS_NEW (
+ "avimux_sink_video_hfyu",
+ "video/x-huffyuv",
"width", GST_PROPS_INT_RANGE (16, 4096),
"height", GST_PROPS_INT_RANGE (16, 4096)
)
@@ -143,15 +162,8 @@ GST_PAD_TEMPLATE_FACTORY (audio_sink_factory,
GST_PAD_SINK,
GST_PAD_REQUEST,
GST_CAPS_NEW (
- "avimux_sink_audio",
- "video/avi",
- "format", GST_PROPS_STRING ("strf_auds")
- ),
- GST_CAPS_NEW (
- "avimux_sink_audio",
- "audio/raw",
- "format", GST_PROPS_STRING ("int"),
- "law", GST_PROPS_INT (0),
+ "avimux_sink_audio_raw",
+ "audio/x-raw-int",
"endianness", GST_PROPS_INT (G_LITTLE_ENDIAN),
"signed", GST_PROPS_LIST (
GST_PROPS_BOOLEAN (TRUE),
@@ -165,18 +177,27 @@ GST_PAD_TEMPLATE_FACTORY (audio_sink_factory,
GST_PROPS_INT (8),
GST_PROPS_INT (16)
),
- "rate", GST_PROPS_INT_RANGE (1000, 48000),
+ "rate", GST_PROPS_INT_RANGE (1000, 96000),
+ "channels", GST_PROPS_INT_RANGE (1, 2)
+ ),
+ GST_CAPS_NEW (
+ "avimux_sink_audio_mpeg",
+ "audio/mpeg",
+ "layer", GST_PROPS_INT_RANGE (1, 3),
+ "rate", GST_PROPS_INT_RANGE (1000, 96000),
"channels", GST_PROPS_INT_RANGE (1, 2)
),
GST_CAPS_NEW (
- "avimux_sink_audio",
- "audio/x-mp3",
- NULL
+ "avimux_sink_audio_vorbis",
+ "audio/x-vorbis",
+ "rate", GST_PROPS_INT_RANGE (1000, 96000),
+ "channels", GST_PROPS_INT_RANGE (1, 2)
),
GST_CAPS_NEW (
- "avimux_sink_audio",
- "application/x-ogg",
- NULL
+ "avimux_sink_audio_ac3",
+ "audio/x-ac3",
+ "rate", GST_PROPS_INT_RANGE (1000, 96000),
+ "channels", GST_PROPS_INT_RANGE (1, 6)
)
)
@@ -237,7 +258,8 @@ gst_avimux_class_init (GstAviMuxClass *klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BIGFILE,
- g_param_spec_boolean("bigfile","Bigfile Support","Whether to capture large or small AVI files",
+ g_param_spec_boolean("bigfile","Bigfile Support",
+ "Support for openDML-2.0 (big) AVI files",
0,G_PARAM_READWRITE));
gstelement_class->request_new_pad = gst_avimux_request_new_pad;
@@ -300,7 +322,7 @@ gst_avimux_init (GstAviMux *avimux)
}
static GstPadLinkReturn
-gst_avimux_sinkconnect (GstPad *pad, GstCaps *vscaps)
+gst_avimux_vidsinkconnect (GstPad *pad, GstCaps *vscaps)
{
GstAviMux *avimux;
GstCaps *caps;
@@ -311,170 +333,188 @@ gst_avimux_sinkconnect (GstPad *pad, GstCaps *vscaps)
if (!GST_CAPS_IS_FIXED (vscaps))
return GST_PAD_LINK_DELAYED;
- GST_DEBUG ("avimux: sinkconnect triggered on %s", gst_pad_get_name (pad));
+ GST_DEBUG ("avimux: video sinkconnect triggered on %s",
+ gst_pad_get_name (pad));
for (caps = vscaps; caps != NULL; caps = vscaps = vscaps->next)
{
const gchar* mimetype = gst_caps_get_mime(caps);
-
- if (!strcmp (mimetype, "video/avi"))
- {
- const gchar* format;
-
- gst_caps_get_string (caps, "format", &format);
-
- if (!strncmp (format, "strf_vids", 9)) {
- avimux->vids.size = sizeof(gst_riff_strf_vids);
- gst_caps_get (caps,
- "width", &avimux->vids.width,
- "height", &avimux->vids.height,
- "planes", &avimux->vids.planes,
- "bit_cnt", &avimux->vids.bit_cnt,
- "compression", &avimux->vids.compression,
- "image_size", &avimux->vids.image_size,
- "xpels_meter", &avimux->vids.xpels_meter,
- "ypels_meter", &avimux->vids.ypels_meter,
- "num_colors", &avimux->vids.num_colors,
- "imp_colors", &avimux->vids.imp_colors,
- NULL);
- avimux->vids_hdr.fcc_handler = avimux->vids.compression;
- avimux->avi_hdr.width = avimux->vids.width;
- avimux->avi_hdr.height = avimux->vids.height;
- goto done;
- }
- else if (!strncmp (format, "strf_auds", 9)) {
- gst_caps_get (caps,
- "format", &avimux->auds.format,
- "channels", &avimux->auds.channels,
- "rate", &avimux->auds.rate,
- "av_bps", &avimux->auds.av_bps,
- "blockalign", &avimux->auds.blockalign,
- "size", &avimux->auds.size,
- NULL);
- avimux->auds_hdr.samplesize = avimux->auds_hdr.scale = avimux->auds.blockalign;
- avimux->auds_hdr.rate = avimux->auds.av_bps;
- goto done;
- }
- }
- else if (!strcmp (mimetype, "video/raw"))
+ gfloat fps = 0.;
+
+ /* global */
+ avimux->vids.size = sizeof(gst_riff_strf_vids);
+ avimux->vids.planes = 1;
+ gst_caps_get (caps, "width", &avimux->vids.width,
+ "height", &avimux->vids.height,
+ "framerate", &fps,
+ NULL);
+ if (fps != 0.)
+ avimux->vids_hdr.scale = avimux->vids_hdr.rate / fps;
+
+ if (!strcmp (mimetype, "video/x-raw-yuv"))
{
guint32 format;
- gint temp;
gst_caps_get_fourcc_int (caps, "format", &format);
+ avimux->vids.compression = format;
switch (format)
{
case GST_MAKE_FOURCC('Y','U','Y','2'):
+ avimux->vids.bit_cnt = 16;
+ break;
case GST_MAKE_FOURCC('I','4','2','0'):
- case GST_MAKE_FOURCC('Y','4','1','P'):
- case GST_MAKE_FOURCC('R','G','B',' '):
- avimux->vids.size = sizeof(gst_riff_strf_vids);
- gst_caps_get (caps, "width", &avimux->vids.width,
- "height", &avimux->vids.height, NULL);
- avimux->vids.planes = 1;
- switch (format)
- {
- case GST_MAKE_FOURCC('Y','U','Y','2'):
- avimux->vids.bit_cnt = 16; /* YUY2 */
- break;
- case GST_MAKE_FOURCC('R','G','B',' '):
- gst_caps_get_int (caps, "bpp", &temp); /* RGB */
- avimux->vids.bit_cnt = temp;
- break;
- case GST_MAKE_FOURCC('Y','4','1','P'):
- case GST_MAKE_FOURCC('I','4','2','0'):
- avimux->vids.bit_cnt = 12; /* Y41P or I420 */
- break;
- }
- gst_caps_get_fourcc_int(caps, "format", &avimux->vids.compression);
- avimux->vids_hdr.fcc_handler = avimux->vids.compression;
- avimux->vids.image_size = avimux->vids.height * avimux->vids.width;
- avimux->avi_hdr.width = avimux->vids.width;
- avimux->avi_hdr.height = avimux->vids.height;
- goto done;
- default:
+ avimux->vids.bit_cnt = 12;
break;
}
+
+ goto done;
}
- else if (!strcmp (mimetype, "video/jpeg") ||
- !strcmp (mimetype, "video/xvid") ||
- !strcmp (mimetype, "video/divx"))
+ else
{
- avimux->vids.size = sizeof(gst_riff_strf_vids);
- gst_caps_get (caps, "width", &avimux->vids.width,
- "height", &avimux->vids.height, NULL);
- avimux->vids.planes = 1;
- avimux->vids.bit_cnt = 24;
+ avimux->vids.bit_cnt = 24;
+ avimux->vids.compression = 0;
- if (!strcmp (mimetype, "video/jpeg"))
+ /* find format */
+ if (!strcmp (mimetype, "video/x-huffyuv")) {
+ avimux->vids.compression = GST_MAKE_FOURCC('H','F','Y','U');
+ } else if (!strcmp (mimetype, "video/x-jpeg")) {
avimux->vids.compression = GST_MAKE_FOURCC('M','J','P','G');
- else if (!strcmp (mimetype, "video/divx"))
- avimux->vids.compression = GST_MAKE_FOURCC('D','I','V','X');
- else if (!strcmp (mimetype, "video/xvid"))
+ } else if (!strcmp (mimetype, "video/x-divx")) {
+ gint divxversion;
+ gst_caps_get_int (caps, "divxversion", &divxversion);
+ switch (divxversion) {
+ case 3:
+ avimux->vids.compression = GST_MAKE_FOURCC('D','I','V','3');
+ break;
+ case 4:
+ avimux->vids.compression = GST_MAKE_FOURCC('D','I','V','X');
+ break;
+ case 5:
+ avimux->vids.compression = GST_MAKE_FOURCC('D','X','5','0');
+ break;
+ }
+ } else if (!strcmp (mimetype, "video/x-xvid")) {
avimux->vids.compression = GST_MAKE_FOURCC('X','V','I','D');
+ } else if (!strcmp (mimetype, "video/x-3ivx")) {
+ avimux->vids.compression = GST_MAKE_FOURCC('3','I','V','2');
+ } else if (!strcmp (mimetype, "video/x-msmpeg")) {
+ gint msmpegversion;
+ gst_caps_get_int (caps, "msmpegversion", &msmpegversion);
+ switch (msmpegversion) {
+ case 41:
+ avimux->vids.compression = GST_MAKE_FOURCC('M','P','G','4');
+ break;
+ case 42:
+ avimux->vids.compression = GST_MAKE_FOURCC('M','P','4','2');
+ break;
+ case 43:
+ avimux->vids.compression = GST_MAKE_FOURCC('M','P','4','3');
+ break;
+ }
+ } else if (!strcmp (mimetype, "video/x-dv")) {
+ avimux->vids.compression = GST_MAKE_FOURCC('D','V','S','D');
+ } else if (!strcmp (mimetype, "video/x-h263")) {
+ avimux->vids.compression = GST_MAKE_FOURCC('H','2','6','3');
+ } else if (!strcmp (mimetype, "video/mpeg")) {
+ avimux->vids.compression = GST_MAKE_FOURCC('M','P','E','G');
+ }
+
+ if (!avimux->vids.compression) {
+ continue;
+ }
- avimux->vids_hdr.fcc_handler = avimux->vids.compression;
- avimux->avi_hdr.width = avimux->vids.width;
- avimux->avi_hdr.height = avimux->vids.height;
- avimux->vids.image_size = avimux->vids.height * avimux->vids.width;
goto done;
}
- else if (!strcmp (mimetype, "audio/raw"))
- {
- gint width;
+ }
+ return GST_PAD_LINK_REFUSED;
+
+done:
+ avimux->vids_hdr.fcc_handler = avimux->vids.compression;
+ avimux->vids.image_size = avimux->vids.height * avimux->vids.width;
+ avimux->avi_hdr.width = avimux->vids.width;
+ avimux->avi_hdr.height = avimux->vids.height;
+ avimux->avi_hdr.us_frame = avimux->vids_hdr.scale;
+ return GST_PAD_LINK_OK;
+}
+static GstPadLinkReturn
+gst_avimux_audsinkconnect (GstPad *pad, GstCaps *vscaps)
+{
+ GstAviMux *avimux;
+ GstCaps *caps;
+
+ avimux = GST_AVIMUX (gst_pad_get_parent (pad));
+
+ /* we are not going to act on variable caps */
+ if (!GST_CAPS_IS_FIXED (vscaps))
+ return GST_PAD_LINK_DELAYED;
+
+ GST_DEBUG ("avimux: audio sinkconnect triggered on %s",
+ gst_pad_get_name (pad));
+
+ for (caps = vscaps; caps != NULL; caps = vscaps = vscaps->next)
+ {
+ const gchar* mimetype = gst_caps_get_mime(caps);
+
+ /* we want these for all */
+ gst_caps_get (caps, "channels", &avimux->auds.channels,
+ "rate", &avimux->auds.rate,
+ NULL);
+
+ if (!strcmp (mimetype, "audio/x-raw-int"))
+ {
avimux->auds.format = GST_RIFF_WAVE_FORMAT_PCM;
- gst_caps_get (caps, "channels", &avimux->auds.channels,
- "rate", &avimux->auds.rate,
- "width", &width,
+
+ gst_caps_get (caps, "width", &avimux->auds.blockalign,
"depth", &avimux->auds.size,
NULL);
- avimux->auds_hdr.rate = avimux->auds.av_bps = width * avimux->auds.rate * avimux->auds.channels / 8;
- avimux->auds_hdr.samplesize = avimux->auds_hdr.scale = avimux->auds.blockalign = width * avimux->auds.channels/8;
+
+ /* set some more info straight */
+ avimux->auds.blockalign /= 8;
+ avimux->auds.blockalign *= avimux->auds.channels;
+ avimux->auds.av_bps = avimux->auds.blockalign * avimux->auds.rate;
goto done;
}
- else if (!strcmp (mimetype, "audio/x-mp3"))
+ else if (!strcmp (mimetype, "audio/mpeg") ||
+ !strcmp (mimetype, "audio/x-vorbis") ||
+ !strcmp (mimetype, "audio/x-ac3"))
{
- gint layer = 3;
+ avimux->auds.format = 0;
- if (GST_CAPS_PROPERTIES(caps) != NULL &&
- gst_caps_has_property(caps, "layer"))
+ if (!strcmp (mimetype, "audio/mpeg")) {
+ gint layer = 3;
gst_caps_get_int(caps, "layer", &layer);
- else
- GST_DEBUG (
- "No layer specified, assuming layer 3");
-
- /* we don't need to do anything here, compressed mp3 contains it all */
- avimux->auds.format = (layer == 3?
- GST_RIFF_WAVE_FORMAT_MPEGL3 :
- GST_RIFF_WAVE_FORMAT_MPEGL12);
- avimux->auds_hdr.scale = avimux->auds_hdr.samplesize =
- avimux->auds.blockalign = 1;
- avimux->auds_hdr.rate = avimux->auds.av_bps = 0;
- avimux->auds.size = 16;
- /* nobody cares about this valus, but is has to be set (regardless of
- * whether the value is correct) */
- avimux->auds.channels = 1;
- /* we'll request this later on from the earlier pads */
- avimux->auds.rate = 0;
- goto done;
- }
- else if (!strcmp (mimetype, "application/x-ogg"))
- {
- avimux->auds.format = GST_RIFF_WAVE_FORMAT_VORBIS1;
- avimux->auds_hdr.scale = avimux->auds_hdr.samplesize =
- avimux->auds.blockalign = 1;
- avimux->auds_hdr.rate = avimux->auds.av_bps = 0;
+ switch (layer) {
+ case 3:
+ avimux->auds.format = GST_RIFF_WAVE_FORMAT_MPEGL3;
+ break;
+ case 1: case 2:
+ avimux->auds.format = GST_RIFF_WAVE_FORMAT_MPEGL12;
+ break;
+ }
+ } else if (!strcmp (mimetype, "audio/x-vorbis")) {
+ avimux->auds.format = GST_RIFF_WAVE_FORMAT_VORBIS3;
+ } else if (!strcmp (mimetype, "audio/x-ac3")) {
+ avimux->auds.format = GST_RIFF_WAVE_FORMAT_A52;
+ }
+
+ avimux->auds.blockalign = 1;
+ avimux->auds.av_bps = 0;
avimux->auds.size = 16;
- /* see above */
- avimux->auds.channels = 1;
- avimux->auds.rate = 0;
+
+ if (!avimux->auds.format) {
+ continue;
+ }
+
goto done;
}
}
return GST_PAD_LINK_REFUSED;
done:
+ avimux->auds_hdr.rate = avimux->auds.blockalign * avimux->auds.rate;
+ avimux->auds_hdr.samplesize = avimux->auds.blockalign;
+ avimux->auds_hdr.scale = avimux->auds.blockalign;
return GST_PAD_LINK_OK;
}
@@ -552,11 +592,13 @@ gst_avimux_request_new_pad (GstElement *element,
if (templ == GST_PAD_TEMPLATE_GET (audio_sink_factory)) {
g_return_val_if_fail(avimux->audiosinkpad == NULL, NULL);
newpad = gst_pad_new_from_template (templ, "audio_00");
+ gst_pad_set_link_function (newpad, gst_avimux_audsinkconnect);
avimux->audiosinkpad = newpad;
}
else if (templ == GST_PAD_TEMPLATE_GET (video_sink_factory)) {
g_return_val_if_fail(avimux->videosinkpad == NULL, NULL);
newpad = gst_pad_new_from_template (templ, "video_00");
+ gst_pad_set_link_function (newpad, gst_avimux_vidsinkconnect);
avimux->videosinkpad = newpad;
}
else {
@@ -568,7 +610,6 @@ gst_avimux_request_new_pad (GstElement *element,
G_CALLBACK(gst_avimux_pad_link), (gpointer)avimux);
g_signal_connect(newpad, "unlinked",
G_CALLBACK(gst_avimux_pad_unlink), (gpointer)avimux);
- gst_pad_set_link_function (newpad, gst_avimux_sinkconnect);
gst_element_add_pad (element, newpad);
gst_pad_set_event_function(newpad, gst_avimux_handle_event);
gst_pad_set_event_mask_function(newpad, gst_avimux_get_event_masks);
@@ -997,25 +1038,12 @@ gst_avimux_stop_file (GstAviMux *avimux)
avimux->avi_hdr.tot_frames = avimux->num_frames;
if (avimux->video_pad_connected) {
avimux->vids_hdr.length = avimux->num_frames;
-
- /* get fps */
- framerate = gst_video_frame_rate(GST_PAD_PEER(avimux->videosinkpad));
- avimux->vids_hdr.scale = 1000000 / framerate;
}
- if (avimux->audio_pad_connected)
- {
- if (avimux->auds_hdr.scale)
- avimux->auds_hdr.length = avimux->audio_size/(avimux->auds.channels*avimux->auds.size/8);
- else
- avimux->auds_hdr.length = 0; /* urm...? FIXME! ;-) */
-
- /* sampling rate, if known - yes this is a hack */
- if (!avimux->auds.rate)
- avimux->auds.rate = gst_video_frame_rate(GST_PAD_PEER(avimux->audiosinkpad));
+ if (avimux->audio_pad_connected) {
+ avimux->auds_hdr.length = avimux->audio_size/avimux->auds.blockalign;
}
/* set rate and everything having to do with that */
- avimux->avi_hdr.us_frame = avimux->vids_hdr.scale;
avimux->avi_hdr.max_bps = 0;
if (avimux->audio_pad_connected) {
/* calculate bps if needed */