mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-30 19:18:31 +00:00
ffmux: avoid generating caps when registering
Don't generate caps when we register the class but delay that till when we actually create an instance of the class.
This commit is contained in:
parent
e8c689fe94
commit
bd1b315c43
1 changed files with 58 additions and 70 deletions
|
@ -65,12 +65,6 @@ struct _GstFFMpegMux
|
||||||
int max_delay;
|
int max_delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _GstFFMpegMuxClassParams
|
|
||||||
{
|
|
||||||
AVOutputFormat *in_plugin;
|
|
||||||
GstCaps *srccaps, *videosinkcaps, *audiosinkcaps;
|
|
||||||
} GstFFMpegMuxClassParams;
|
|
||||||
|
|
||||||
typedef struct _GstFFMpegMuxClass GstFFMpegMuxClass;
|
typedef struct _GstFFMpegMuxClass GstFFMpegMuxClass;
|
||||||
|
|
||||||
struct _GstFFMpegMuxClass
|
struct _GstFFMpegMuxClass
|
||||||
|
@ -133,6 +127,10 @@ static void gst_ffmpegmux_set_property (GObject * object, guint prop_id,
|
||||||
static void gst_ffmpegmux_get_property (GObject * object, guint prop_id,
|
static void gst_ffmpegmux_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
|
static GstCaps *gst_ffmpegmux_get_id_caps (enum CodecID *id_list);
|
||||||
|
static void gst_ffmpeg_mux_simple_caps_set_int_list (GstCaps * caps,
|
||||||
|
const gchar * field, guint num, const gint * values);
|
||||||
|
|
||||||
#define GST_FFMUX_PARAMS_QDATA g_quark_from_static_string("ffmux-params")
|
#define GST_FFMUX_PARAMS_QDATA g_quark_from_static_string("ffmux-params")
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
@ -145,20 +143,21 @@ gst_ffmpegmux_base_init (gpointer g_class)
|
||||||
GstFFMpegMuxClass *klass = (GstFFMpegMuxClass *) g_class;
|
GstFFMpegMuxClass *klass = (GstFFMpegMuxClass *) g_class;
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||||
GstElementDetails details;
|
GstElementDetails details;
|
||||||
GstFFMpegMuxClassParams *params;
|
|
||||||
GstPadTemplate *videosinktempl, *audiosinktempl, *srctempl;
|
GstPadTemplate *videosinktempl, *audiosinktempl, *srctempl;
|
||||||
|
AVOutputFormat *in_plugin;
|
||||||
|
GstCaps *srccaps, *audiosinkcaps, *videosinkcaps;
|
||||||
|
enum CodecID *video_ids = NULL, *audio_ids = NULL;
|
||||||
|
|
||||||
params =
|
in_plugin =
|
||||||
(GstFFMpegMuxClassParams *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
|
(AVOutputFormat *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
|
||||||
GST_FFMUX_PARAMS_QDATA);
|
GST_FFMUX_PARAMS_QDATA);
|
||||||
g_assert (params != NULL);
|
g_assert (in_plugin != NULL);
|
||||||
|
|
||||||
/* construct the element details struct */
|
/* construct the element details struct */
|
||||||
details.longname = g_strdup_printf ("FFmpeg %s muxer",
|
details.longname = g_strdup_printf ("FFmpeg %s muxer", in_plugin->long_name);
|
||||||
params->in_plugin->long_name);
|
|
||||||
details.klass = g_strdup ("Codec/Muxer");
|
details.klass = g_strdup ("Codec/Muxer");
|
||||||
details.description = g_strdup_printf ("FFmpeg %s muxer",
|
details.description = g_strdup_printf ("FFmpeg %s muxer",
|
||||||
params->in_plugin->long_name);
|
in_plugin->long_name);
|
||||||
details.author = "Wim Taymans <wim.taymans@chello.be>, "
|
details.author = "Wim Taymans <wim.taymans@chello.be>, "
|
||||||
"Ronald Bultje <rbultje@ronald.bitfreak.net>";
|
"Ronald Bultje <rbultje@ronald.bitfreak.net>";
|
||||||
gst_element_class_set_details (element_class, &details);
|
gst_element_class_set_details (element_class, &details);
|
||||||
|
@ -166,24 +165,58 @@ gst_ffmpegmux_base_init (gpointer g_class)
|
||||||
g_free (details.klass);
|
g_free (details.klass);
|
||||||
g_free (details.description);
|
g_free (details.description);
|
||||||
|
|
||||||
|
/* Try to find the caps that belongs here */
|
||||||
|
srccaps = gst_ffmpeg_formatid_to_caps (in_plugin->name);
|
||||||
|
if (!srccaps) {
|
||||||
|
GST_DEBUG ("Couldn't get source caps for muxer '%s', skipping format",
|
||||||
|
in_plugin->name);
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_ffmpeg_formatid_get_codecids (in_plugin->name,
|
||||||
|
&video_ids, &audio_ids, in_plugin)) {
|
||||||
|
gst_caps_unref (srccaps);
|
||||||
|
GST_DEBUG
|
||||||
|
("Couldn't get sink caps for muxer '%s'. Most likely because no input format mapping exists.",
|
||||||
|
in_plugin->name);
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
|
videosinkcaps = video_ids ? gst_ffmpegmux_get_id_caps (video_ids) : NULL;
|
||||||
|
audiosinkcaps = audio_ids ? gst_ffmpegmux_get_id_caps (audio_ids) : NULL;
|
||||||
|
|
||||||
|
/* fix up allowed caps for some muxers */
|
||||||
|
/* FIXME : This should be in gstffmpegcodecmap.c ! */
|
||||||
|
if (strcmp (in_plugin->name, "flv") == 0) {
|
||||||
|
const gint rates[] = { 44100, 22050, 11025 };
|
||||||
|
|
||||||
|
gst_ffmpeg_mux_simple_caps_set_int_list (audiosinkcaps, "rate", 3, rates);
|
||||||
|
} else if (strcmp (in_plugin->name, "gif") == 0) {
|
||||||
|
if (videosinkcaps)
|
||||||
|
gst_caps_unref (videosinkcaps);
|
||||||
|
|
||||||
|
videosinkcaps =
|
||||||
|
gst_caps_from_string ("video/x-raw-rgb, bpp=(int)24, depth=(int)24");
|
||||||
|
}
|
||||||
|
|
||||||
/* pad templates */
|
/* pad templates */
|
||||||
srctempl = gst_pad_template_new ("src", GST_PAD_SRC,
|
srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
|
||||||
GST_PAD_ALWAYS, params->srccaps);
|
|
||||||
gst_element_class_add_pad_template (element_class, srctempl);
|
gst_element_class_add_pad_template (element_class, srctempl);
|
||||||
|
|
||||||
if (params->audiosinkcaps) {
|
if (audiosinkcaps) {
|
||||||
audiosinktempl = gst_pad_template_new ("audio_%d",
|
audiosinktempl = gst_pad_template_new ("audio_%d",
|
||||||
GST_PAD_SINK, GST_PAD_REQUEST, params->audiosinkcaps);
|
GST_PAD_SINK, GST_PAD_REQUEST, audiosinkcaps);
|
||||||
gst_element_class_add_pad_template (element_class, audiosinktempl);
|
gst_element_class_add_pad_template (element_class, audiosinktempl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->videosinkcaps) {
|
if (videosinkcaps) {
|
||||||
videosinktempl = gst_pad_template_new ("video_%d",
|
videosinktempl = gst_pad_template_new ("video_%d",
|
||||||
GST_PAD_SINK, GST_PAD_REQUEST, params->videosinkcaps);
|
GST_PAD_SINK, GST_PAD_REQUEST, videosinkcaps);
|
||||||
gst_element_class_add_pad_template (element_class, videosinktempl);
|
gst_element_class_add_pad_template (element_class, videosinktempl);
|
||||||
}
|
}
|
||||||
|
|
||||||
klass->in_plugin = params->in_plugin;
|
beach:
|
||||||
|
klass->in_plugin = in_plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -707,8 +740,8 @@ gst_ffmpegmux_change_state (GstElement * element, GstStateChange transition)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstCaps *
|
static GstCaps *
|
||||||
gst_ffmpegmux_get_id_caps (enum CodecID * id_list)
|
gst_ffmpegmux_get_id_caps (enum CodecID *id_list)
|
||||||
{
|
{
|
||||||
GstCaps *caps, *t;
|
GstCaps *caps, *t;
|
||||||
gint i;
|
gint i;
|
||||||
|
@ -770,7 +803,6 @@ gst_ffmpegmux_register (GstPlugin * plugin)
|
||||||
};
|
};
|
||||||
GType type;
|
GType type;
|
||||||
AVOutputFormat *in_plugin;
|
AVOutputFormat *in_plugin;
|
||||||
GstFFMpegMuxClassParams *params;
|
|
||||||
|
|
||||||
in_plugin = av_oformat_next (NULL);
|
in_plugin = av_oformat_next (NULL);
|
||||||
|
|
||||||
|
@ -779,8 +811,6 @@ gst_ffmpegmux_register (GstPlugin * plugin)
|
||||||
while (in_plugin) {
|
while (in_plugin) {
|
||||||
gchar *type_name;
|
gchar *type_name;
|
||||||
gchar *p;
|
gchar *p;
|
||||||
GstCaps *srccaps, *audiosinkcaps, *videosinkcaps;
|
|
||||||
enum CodecID *video_ids = NULL, *audio_ids = NULL;
|
|
||||||
|
|
||||||
if ((!strncmp (in_plugin->name, "u16", 3)) ||
|
if ((!strncmp (in_plugin->name, "u16", 3)) ||
|
||||||
(!strncmp (in_plugin->name, "s16", 3)) ||
|
(!strncmp (in_plugin->name, "s16", 3)) ||
|
||||||
|
@ -806,23 +836,8 @@ gst_ffmpegmux_register (GstPlugin * plugin)
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to find the caps that belongs here */
|
/* FIXME : We need a fast way to know whether we have mappings for this
|
||||||
srccaps = gst_ffmpeg_formatid_to_caps (in_plugin->name);
|
* muxer type. */
|
||||||
if (!srccaps) {
|
|
||||||
GST_DEBUG ("Couldn't get source caps for muxer '%s', skipping format",
|
|
||||||
in_plugin->name);
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
if (!gst_ffmpeg_formatid_get_codecids (in_plugin->name,
|
|
||||||
&video_ids, &audio_ids, in_plugin)) {
|
|
||||||
gst_caps_unref (srccaps);
|
|
||||||
GST_DEBUG
|
|
||||||
("Couldn't get sink caps for muxer '%s'. Most likely because no input format mapping exists.",
|
|
||||||
in_plugin->name);
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
videosinkcaps = video_ids ? gst_ffmpegmux_get_id_caps (video_ids) : NULL;
|
|
||||||
audiosinkcaps = audio_ids ? gst_ffmpegmux_get_id_caps (audio_ids) : NULL;
|
|
||||||
|
|
||||||
/* construct the type */
|
/* construct the type */
|
||||||
type_name = g_strdup_printf ("ffmux_%s", in_plugin->name);
|
type_name = g_strdup_printf ("ffmux_%s", in_plugin->name);
|
||||||
|
@ -835,44 +850,17 @@ gst_ffmpegmux_register (GstPlugin * plugin)
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fix up allowed caps for some muxers */
|
|
||||||
if (strcmp (in_plugin->name, "flv") == 0) {
|
|
||||||
const gint rates[] = { 44100, 22050, 11025 };
|
|
||||||
|
|
||||||
gst_ffmpeg_mux_simple_caps_set_int_list (audiosinkcaps, "rate", 3, rates);
|
|
||||||
} else if (strcmp (in_plugin->name, "gif") == 0) {
|
|
||||||
if (videosinkcaps)
|
|
||||||
gst_caps_unref (videosinkcaps);
|
|
||||||
|
|
||||||
videosinkcaps =
|
|
||||||
gst_caps_from_string ("video/x-raw-rgb, bpp=(int)24, depth=(int)24");
|
|
||||||
}
|
|
||||||
|
|
||||||
type = g_type_from_name (type_name);
|
type = g_type_from_name (type_name);
|
||||||
|
|
||||||
if (!type) {
|
if (!type) {
|
||||||
/* create a cache for these properties */
|
|
||||||
params = g_new0 (GstFFMpegMuxClassParams, 1);
|
|
||||||
params->in_plugin = in_plugin;
|
|
||||||
params->srccaps = srccaps;
|
|
||||||
params->videosinkcaps = videosinkcaps;
|
|
||||||
params->audiosinkcaps = audiosinkcaps;
|
|
||||||
|
|
||||||
/* create the type now */
|
/* create the type now */
|
||||||
type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
|
type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
|
||||||
g_type_set_qdata (type, GST_FFMUX_PARAMS_QDATA, (gpointer) params);
|
g_type_set_qdata (type, GST_FFMUX_PARAMS_QDATA, (gpointer) in_plugin);
|
||||||
g_type_add_interface_static (type, GST_TYPE_TAG_SETTER, &tag_setter_info);
|
g_type_add_interface_static (type, GST_TYPE_TAG_SETTER, &tag_setter_info);
|
||||||
} else {
|
|
||||||
gst_caps_replace (&srccaps, NULL);
|
|
||||||
gst_caps_replace (&audiosinkcaps, NULL);
|
|
||||||
gst_caps_replace (&videosinkcaps, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_element_register (plugin, type_name, GST_RANK_NONE, type)) {
|
if (!gst_element_register (plugin, type_name, GST_RANK_NONE, type)) {
|
||||||
g_free (type_name);
|
g_free (type_name);
|
||||||
gst_caps_replace (&srccaps, NULL);
|
|
||||||
gst_caps_replace (&audiosinkcaps, NULL);
|
|
||||||
gst_caps_replace (&videosinkcaps, NULL);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue