...
 
Commits (4)
common @ cd5507ae
Subproject commit 2c2bce01ed5ed1d1684bd76a334477398009ef4a Subproject commit cd5507ae3df8dc48c07df9e37878846b6b79faa1
...@@ -69,7 +69,6 @@ GST_PLUGIN_DEFINE ( ...@@ -69,7 +69,6 @@ GST_PLUGIN_DEFINE (
plugin_init, plugin_init,
FFMPEG_VERSION, FFMPEG_VERSION,
"LGPL", "LGPL",
"(c) 2003 The FFMPEG team",
"FFMpeg", "FFMpeg",
"http://ffmpeg.sourceforge.net/" "http://ffmpeg.sourceforge.net/"
) )
This diff is collapsed.
...@@ -49,7 +49,7 @@ gst_ffmpeg_codectype_to_caps (enum CodecType codec_type, ...@@ -49,7 +49,7 @@ gst_ffmpeg_codectype_to_caps (enum CodecType codec_type,
*/ */
enum CodecID enum CodecID
gst_ffmpeg_caps_to_codecid (GstCaps *caps, gst_ffmpeg_caps_to_codecid (const GstCaps *caps,
AVCodecContext *context); AVCodecContext *context);
/* caps_to_codectype () transforms a GstCaps that belongs to /* caps_to_codectype () transforms a GstCaps that belongs to
...@@ -58,7 +58,7 @@ gst_ffmpeg_caps_to_codecid (GstCaps *caps, ...@@ -58,7 +58,7 @@ gst_ffmpeg_caps_to_codecid (GstCaps *caps,
void void
gst_ffmpeg_caps_to_codectype (enum CodecType type, gst_ffmpeg_caps_to_codectype (enum CodecType type,
GstCaps *caps, const GstCaps *caps,
AVCodecContext *context); AVCodecContext *context);
/* _formatid_to_caps () is meant for muxers/demuxers, it /* _formatid_to_caps () is meant for muxers/demuxers, it
......
This diff is collapsed.
...@@ -92,7 +92,7 @@ static void gst_ffmpegdec_init (GstFFMpegDec *ffmpegdec); ...@@ -92,7 +92,7 @@ static void gst_ffmpegdec_init (GstFFMpegDec *ffmpegdec);
static void gst_ffmpegdec_dispose (GObject *object); static void gst_ffmpegdec_dispose (GObject *object);
static GstPadLinkReturn gst_ffmpegdec_connect (GstPad *pad, static GstPadLinkReturn gst_ffmpegdec_connect (GstPad *pad,
GstCaps *caps); const GstCaps *caps);
static void gst_ffmpegdec_chain (GstPad *pad, static void gst_ffmpegdec_chain (GstPad *pad,
GstData *data); GstData *data);
...@@ -141,9 +141,9 @@ gst_ffmpegdec_base_init (GstFFMpegDecClass *klass) ...@@ -141,9 +141,9 @@ gst_ffmpegdec_base_init (GstFFMpegDecClass *klass)
/* pad templates */ /* pad templates */
sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK, sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
GST_PAD_ALWAYS, params->sinkcaps, NULL); GST_PAD_ALWAYS, params->sinkcaps);
srctempl = gst_pad_template_new ("src", GST_PAD_SRC, srctempl = gst_pad_template_new ("src", GST_PAD_SRC,
GST_PAD_ALWAYS, params->srccaps, NULL); GST_PAD_ALWAYS, params->srccaps);
gst_element_class_add_pad_template (element_class, srctempl); gst_element_class_add_pad_template (element_class, srctempl);
gst_element_class_add_pad_template (element_class, sinktempl); gst_element_class_add_pad_template (element_class, sinktempl);
...@@ -206,15 +206,11 @@ gst_ffmpegdec_dispose (GObject *object) ...@@ -206,15 +206,11 @@ gst_ffmpegdec_dispose (GObject *object)
static GstPadLinkReturn static GstPadLinkReturn
gst_ffmpegdec_connect (GstPad *pad, gst_ffmpegdec_connect (GstPad *pad,
GstCaps *caps) const GstCaps *caps)
{ {
GstFFMpegDec *ffmpegdec = (GstFFMpegDec *)(gst_pad_get_parent (pad)); GstFFMpegDec *ffmpegdec = (GstFFMpegDec *)(gst_pad_get_parent (pad));
GstFFMpegDecClass *oclass = (GstFFMpegDecClass*)(G_OBJECT_GET_CLASS (ffmpegdec)); GstFFMpegDecClass *oclass = (GstFFMpegDecClass*)(G_OBJECT_GET_CLASS (ffmpegdec));
/* we want fixed caps */
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_LINK_DELAYED;
/* close old session */ /* close old session */
if (ffmpegdec->opened) { if (ffmpegdec->opened) {
avcodec_close (ffmpegdec->context); avcodec_close (ffmpegdec->context);
...@@ -344,9 +340,11 @@ gst_ffmpegdec_chain (GstPad *pad, ...@@ -344,9 +340,11 @@ gst_ffmpegdec_chain (GstPad *pad,
switch (oclass->in_plugin->type) { switch (oclass->in_plugin->type) {
case CODEC_TYPE_VIDEO: case CODEC_TYPE_VIDEO:
/* workaround: /* workarounds, functions write to buffers:
libavcodec/svq1.c:svq1_decode_frame writes to the given buffer */ libavcodec/svq1.c:svq1_decode_frame writes to the given buffer.
if (oclass->in_plugin->id == CODEC_ID_SVQ1) { libavcodec/svq3.c:svq3_decode_slice_header too */
if (oclass->in_plugin->id == CODEC_ID_SVQ1 ||
oclass->in_plugin->id == CODEC_ID_SVQ3) {
inbuf = gst_buffer_copy_on_write(inbuf); inbuf = gst_buffer_copy_on_write(inbuf);
data = GST_BUFFER_DATA (inbuf); data = GST_BUFFER_DATA (inbuf);
size = GST_BUFFER_SIZE (inbuf); size = GST_BUFFER_SIZE (inbuf);
...@@ -480,7 +478,6 @@ gst_ffmpegdec_register (GstPlugin *plugin) ...@@ -480,7 +478,6 @@ gst_ffmpegdec_register (GstPlugin *plugin)
/* no quasi-codecs, please */ /* no quasi-codecs, please */
if (in_plugin->id == CODEC_ID_RAWVIDEO || if (in_plugin->id == CODEC_ID_RAWVIDEO ||
in_plugin->id == CODEC_ID_SVQ3 || /* segfaults */
(in_plugin->id >= CODEC_ID_PCM_S16LE && (in_plugin->id >= CODEC_ID_PCM_S16LE &&
in_plugin->id <= CODEC_ID_PCM_ALAW)) { in_plugin->id <= CODEC_ID_PCM_ALAW)) {
goto next; goto next;
......
...@@ -133,15 +133,15 @@ gst_ffmpegdemux_base_init (GstFFMpegDemuxClass *klass) ...@@ -133,15 +133,15 @@ gst_ffmpegdemux_base_init (GstFFMpegDemuxClass *klass)
sinktempl = gst_pad_template_new ("sink", sinktempl = gst_pad_template_new ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
params->sinkcaps, NULL); params->sinkcaps);
videosrctempl = gst_pad_template_new ("video_%02d", videosrctempl = gst_pad_template_new ("video_%02d",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_SOMETIMES, GST_PAD_SOMETIMES,
params->videosrccaps, NULL); params->videosrccaps);
audiosrctempl = gst_pad_template_new ("audio_%02d", audiosrctempl = gst_pad_template_new ("audio_%02d",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_SOMETIMES, GST_PAD_SOMETIMES,
params->audiosrccaps, NULL); params->audiosrccaps);
gst_element_class_add_pad_template (element_class, videosrctempl); gst_element_class_add_pad_template (element_class, videosrctempl);
gst_element_class_add_pad_template (element_class, audiosrctempl); gst_element_class_add_pad_template (element_class, audiosrctempl);
...@@ -217,12 +217,8 @@ gst_ffmpegdemux_type_find (GstTypeFind *tf, gpointer priv) ...@@ -217,12 +217,8 @@ gst_ffmpegdemux_type_find (GstTypeFind *tf, gpointer priv)
res = in_plugin->read_probe (&probe_data); res = in_plugin->read_probe (&probe_data);
res = res * GST_TYPE_FIND_MAXIMUM / AVPROBE_SCORE_MAX; res = res * GST_TYPE_FIND_MAXIMUM / AVPROBE_SCORE_MAX;
if (res > 0) { if (res > 0)
GstCaps *caps = params->sinkcaps; gst_type_find_suggest (tf, res, params->sinkcaps);
/* make sure we still hold a refcount to this caps */
gst_caps_ref (caps);
gst_type_find_suggest (tf, res, caps);
}
} }
} }
...@@ -386,6 +382,11 @@ gst_ffmpegdemux_change_state (GstElement *element) ...@@ -386,6 +382,11 @@ gst_ffmpegdemux_change_state (GstElement *element)
gboolean gboolean
gst_ffmpegdemux_register (GstPlugin *plugin) gst_ffmpegdemux_register (GstPlugin *plugin)
{ {
GType type;
AVInputFormat *in_plugin;
GstFFMpegDemuxClassParams *params;
AVCodec *in_codec;
gchar **extensions;
GTypeInfo typeinfo = { GTypeInfo typeinfo = {
sizeof(GstFFMpegDemuxClass), sizeof(GstFFMpegDemuxClass),
(GBaseInitFunc)gst_ffmpegdemux_base_init, (GBaseInitFunc)gst_ffmpegdemux_base_init,
...@@ -397,11 +398,7 @@ gst_ffmpegdemux_register (GstPlugin *plugin) ...@@ -397,11 +398,7 @@ gst_ffmpegdemux_register (GstPlugin *plugin)
0, 0,
(GInstanceInitFunc)gst_ffmpegdemux_init, (GInstanceInitFunc)gst_ffmpegdemux_init,
}; };
GType type; GstCaps *any_caps = gst_caps_new_any ();
AVInputFormat *in_plugin;
GstFFMpegDemuxClassParams *params;
AVCodec *in_codec;
gchar **extensions;
in_plugin = first_iformat; in_plugin = first_iformat;
...@@ -430,13 +427,13 @@ gst_ffmpegdemux_register (GstPlugin *plugin) ...@@ -430,13 +427,13 @@ gst_ffmpegdemux_register (GstPlugin *plugin)
} }
switch (in_codec->type) { switch (in_codec->type) {
case CODEC_TYPE_VIDEO: case CODEC_TYPE_VIDEO:
videosrccaps = gst_caps_append (videosrccaps, temp); gst_caps_append (videosrccaps, temp);
break; break;
case CODEC_TYPE_AUDIO: case CODEC_TYPE_AUDIO:
audiosrccaps = gst_caps_append (audiosrccaps, temp); gst_caps_append (audiosrccaps, temp);
break; break;
default: default:
gst_caps_unref (temp); gst_caps_free (temp);
break; break;
} }
} }
...@@ -480,13 +477,14 @@ gst_ffmpegdemux_register (GstPlugin *plugin) ...@@ -480,13 +477,14 @@ gst_ffmpegdemux_register (GstPlugin *plugin)
if (!gst_element_register (plugin, type_name, GST_RANK_MARGINAL, type) || if (!gst_element_register (plugin, type_name, GST_RANK_MARGINAL, type) ||
!gst_type_find_register (plugin, typefind_name, GST_RANK_MARGINAL, !gst_type_find_register (plugin, typefind_name, GST_RANK_MARGINAL,
gst_ffmpegdemux_type_find, gst_ffmpegdemux_type_find,
extensions, GST_CAPS_ANY, params)) extensions, any_caps, params))
return FALSE; return FALSE;
g_strfreev (extensions); g_strfreev (extensions);
next: next:
in_plugin = in_plugin->next; in_plugin = in_plugin->next;
} }
gst_caps_free (any_caps);
g_hash_table_remove (global_plugins, GINT_TO_POINTER (0)); g_hash_table_remove (global_plugins, GINT_TO_POINTER (0));
return TRUE; return TRUE;
......
...@@ -123,7 +123,7 @@ static void gst_ffmpegenc_init (GstFFMpegEnc *ffmpegenc); ...@@ -123,7 +123,7 @@ static void gst_ffmpegenc_init (GstFFMpegEnc *ffmpegenc);
static void gst_ffmpegenc_dispose (GObject *object); static void gst_ffmpegenc_dispose (GObject *object);
static GstPadLinkReturn static GstPadLinkReturn
gst_ffmpegenc_connect (GstPad *pad, GstCaps *caps); gst_ffmpegenc_connect (GstPad *pad, const GstCaps *caps);
static void gst_ffmpegenc_chain_video (GstPad *pad, GstData *_data); static void gst_ffmpegenc_chain_video (GstPad *pad, GstData *_data);
static void gst_ffmpegenc_chain_audio (GstPad *pad, GstData *_data); static void gst_ffmpegenc_chain_audio (GstPad *pad, GstData *_data);
...@@ -175,9 +175,9 @@ gst_ffmpegenc_base_init (GstFFMpegEncClass *klass) ...@@ -175,9 +175,9 @@ gst_ffmpegenc_base_init (GstFFMpegEncClass *klass)
/* pad templates */ /* pad templates */
sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK, sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
GST_PAD_ALWAYS, params->sinkcaps, NULL); GST_PAD_ALWAYS, params->sinkcaps);
srctempl = gst_pad_template_new ("src", GST_PAD_SRC, srctempl = gst_pad_template_new ("src", GST_PAD_SRC,
GST_PAD_ALWAYS, params->srccaps, NULL); GST_PAD_ALWAYS, params->srccaps);
gst_element_class_add_pad_template (element_class, srctempl); gst_element_class_add_pad_template (element_class, srctempl);
gst_element_class_add_pad_template (element_class, sinktempl); gst_element_class_add_pad_template (element_class, sinktempl);
...@@ -282,15 +282,13 @@ gst_ffmpegenc_dispose (GObject *object) ...@@ -282,15 +282,13 @@ gst_ffmpegenc_dispose (GObject *object)
static GstPadLinkReturn static GstPadLinkReturn
gst_ffmpegenc_connect (GstPad *pad, gst_ffmpegenc_connect (GstPad *pad,
GstCaps *caps) const GstCaps *caps)
{ {
GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) gst_pad_get_parent (pad); GstCaps *other_caps;
GstFFMpegEncClass *oclass = (GstFFMpegEncClass*)(G_OBJECT_GET_CLASS(ffmpegenc));
GstCaps *ret_caps;
GstPadLinkReturn ret; GstPadLinkReturn ret;
enum PixelFormat pix_fmt;
if (!GST_CAPS_IS_FIXED (caps)) GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) gst_pad_get_parent (pad);
return GST_PAD_LINK_DELAYED; GstFFMpegEncClass *oclass = (GstFFMpegEncClass *) G_OBJECT_GET_CLASS(ffmpegenc);
/* close old session */ /* close old session */
if (ffmpegenc->opened) { if (ffmpegenc->opened) {
...@@ -315,47 +313,37 @@ gst_ffmpegenc_connect (GstPad *pad, ...@@ -315,47 +313,37 @@ gst_ffmpegenc_connect (GstPad *pad,
/* no edges */ /* no edges */
ffmpegenc->context->flags |= CODEC_FLAG_EMU_EDGE; ffmpegenc->context->flags |= CODEC_FLAG_EMU_EDGE;
for (ret_caps = caps; ret_caps != NULL; ret_caps = ret_caps->next) { /* fetch pix_fmt and so on */
enum PixelFormat pix_fmt; gst_ffmpeg_caps_to_codectype (oclass->in_plugin->type,
caps, ffmpegenc->context);
/* fetch pix_fmt and so on */
gst_ffmpeg_caps_to_codectype (oclass->in_plugin->type,
caps, ffmpegenc->context);
pix_fmt = ffmpegenc->context->pix_fmt; pix_fmt = ffmpegenc->context->pix_fmt;
/* open codec */ /* open codec */
if (avcodec_open (ffmpegenc->context, oclass->in_plugin) < 0) { if (avcodec_open (ffmpegenc->context, oclass->in_plugin) < 0) {
GST_DEBUG ("ffenc_%s: Failed to open FFMPEG codec", GST_DEBUG ("ffenc_%s: Failed to open FFMPEG codec",
oclass->in_plugin->name); oclass->in_plugin->name);
continue; return GST_PAD_LINK_REFUSED;
}
/* is the colourspace correct? */
if (pix_fmt != ffmpegenc->context->pix_fmt) {
avcodec_close (ffmpegenc->context);
GST_DEBUG ("ffenc_%s: AV wants different colourspace (%d given, %d wanted)",
oclass->in_plugin->name, pix_fmt, ffmpegenc->context->pix_fmt);
continue;
}
break;
} }
if (ret_caps == NULL) { /* is the colourspace correct? */
if (pix_fmt != ffmpegenc->context->pix_fmt) {
avcodec_close (ffmpegenc->context);
GST_DEBUG ("ffenc_%s: AV wants different colourspace (%d given, %d wanted)",
oclass->in_plugin->name, pix_fmt, ffmpegenc->context->pix_fmt);
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
} }
/* try to set this caps on the other side */ /* try to set this caps on the other side */
ret_caps = gst_ffmpeg_codecid_to_caps (oclass->in_plugin->id, other_caps = gst_ffmpeg_codecid_to_caps (oclass->in_plugin->id,
ffmpegenc->context); ffmpegenc->context);
if (!ret_caps) { if (!other_caps) {
avcodec_close (ffmpegenc->context); avcodec_close (ffmpegenc->context);
GST_DEBUG ("Unsupported codec - no caps found"); GST_DEBUG ("Unsupported codec - no caps found");
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
} }
if ((ret = gst_pad_try_set_caps (ffmpegenc->srcpad, ret_caps)) <= 0) { if ((ret = gst_pad_try_set_caps (ffmpegenc->srcpad, other_caps)) <= 0) {
avcodec_close (ffmpegenc->context); avcodec_close (ffmpegenc->context);
GST_DEBUG ("Failed to set caps on next element for ffmpeg encoder (%s)", GST_DEBUG ("Failed to set caps on next element for ffmpeg encoder (%s)",
oclass->in_plugin->name); oclass->in_plugin->name);
......
...@@ -96,7 +96,7 @@ static void gst_ffmpegmux_dispose (GObject *object); ...@@ -96,7 +96,7 @@ static void gst_ffmpegmux_dispose (GObject *object);
static GstPadLinkReturn static GstPadLinkReturn
gst_ffmpegmux_connect (GstPad *pad, gst_ffmpegmux_connect (GstPad *pad,
GstCaps *caps); const GstCaps *caps);
static GstPad * gst_ffmpegmux_request_new_pad (GstElement *element, static GstPad * gst_ffmpegmux_request_new_pad (GstElement *element,
GstPadTemplate *templ, GstPadTemplate *templ,
const gchar *name); const gchar *name);
...@@ -138,15 +138,15 @@ gst_ffmpegmux_base_init (GstFFMpegMuxClass *klass) ...@@ -138,15 +138,15 @@ gst_ffmpegmux_base_init (GstFFMpegMuxClass *klass)
/* pad templates */ /* pad templates */
srctempl = gst_pad_template_new ("sink", GST_PAD_SRC, srctempl = gst_pad_template_new ("sink", GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
params->srccaps, NULL); params->srccaps);
audiosinktempl = gst_pad_template_new ("audio_%d", audiosinktempl = gst_pad_template_new ("audio_%d",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_REQUEST, GST_PAD_REQUEST,
params->audiosinkcaps, NULL); params->audiosinkcaps);
videosinktempl = gst_pad_template_new ("video_%d", videosinktempl = gst_pad_template_new ("video_%d",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_REQUEST, GST_PAD_REQUEST,
params->videosinkcaps, NULL); params->videosinkcaps);
gst_element_class_add_pad_template (element_class, srctempl); gst_element_class_add_pad_template (element_class, srctempl);
gst_element_class_add_pad_template (element_class, videosinktempl); gst_element_class_add_pad_template (element_class, videosinktempl);
...@@ -272,7 +272,7 @@ gst_ffmpegmux_request_new_pad (GstElement *element, ...@@ -272,7 +272,7 @@ gst_ffmpegmux_request_new_pad (GstElement *element,
static GstPadLinkReturn static GstPadLinkReturn
gst_ffmpegmux_connect (GstPad *pad, gst_ffmpegmux_connect (GstPad *pad,
GstCaps *caps) const GstCaps *caps)
{ {
GstFFMpegMux *ffmpegmux = (GstFFMpegMux *)(gst_pad_get_parent (pad)); GstFFMpegMux *ffmpegmux = (GstFFMpegMux *)(gst_pad_get_parent (pad));
gint i; gint i;
...@@ -281,9 +281,6 @@ gst_ffmpegmux_connect (GstPad *pad, ...@@ -281,9 +281,6 @@ gst_ffmpegmux_connect (GstPad *pad,
g_return_val_if_fail (ffmpegmux->opened == FALSE, g_return_val_if_fail (ffmpegmux->opened == FALSE,
GST_PAD_LINK_REFUSED); GST_PAD_LINK_REFUSED);
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_LINK_DELAYED;
for (i = 0; i < ffmpegmux->context->nb_streams; i++) { for (i = 0; i < ffmpegmux->context->nb_streams; i++) {
if (pad == ffmpegmux->sinkpads[i]) { if (pad == ffmpegmux->sinkpads[i]) {
break; break;
...@@ -297,12 +294,10 @@ gst_ffmpegmux_connect (GstPad *pad, ...@@ -297,12 +294,10 @@ gst_ffmpegmux_connect (GstPad *pad,
/* for the format-specific guesses, we'll go to /* for the format-specific guesses, we'll go to
* our famous codec mapper */ * our famous codec mapper */
for ( ; caps != NULL; caps = caps->next) { if (gst_ffmpeg_caps_to_codecid (caps,
if (gst_ffmpeg_caps_to_codecid (caps, &st->codec) != CODEC_ID_NONE) {
&st->codec) != CODEC_ID_NONE) { ffmpegmux->eos[i] = FALSE;
ffmpegmux->eos[i] = FALSE; return GST_PAD_LINK_OK;
return GST_PAD_LINK_OK;
}
} }
return GST_PAD_LINK_REFUSED; return GST_PAD_LINK_REFUSED;
...@@ -483,13 +478,13 @@ gst_ffmpegmux_register (GstPlugin *plugin) ...@@ -483,13 +478,13 @@ gst_ffmpegmux_register (GstPlugin *plugin)
} }
switch (in_codec->type) { switch (in_codec->type) {
case CODEC_TYPE_VIDEO: case CODEC_TYPE_VIDEO:
videosinkcaps = gst_caps_append (videosinkcaps, temp); gst_caps_append (videosinkcaps, temp);
break; break;
case CODEC_TYPE_AUDIO: case CODEC_TYPE_AUDIO:
audiosinkcaps = gst_caps_append (audiosinkcaps, temp); gst_caps_append (audiosinkcaps, temp);
break; break;
default: default:
gst_caps_unref (temp); gst_caps_free (temp);
break; break;
} }
} }
......