diff --git a/ChangeLog b/ChangeLog index 37ee93d4fb..a9fddf22b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2004-10-25 Ronald S. Bultje + + * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps), + (gst_ffmpeg_codectype_to_caps), (gst_ffmpeg_caps_with_codecid): + * ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_base_init), + (gst_ffmpegenc_connect), (gst_ffmpegenc_register): + Fix encoders. Fix if encoder supports >1 caps. + 2004-10-25 Ronald S. Bultje * ext/ffmpeg/gstffmpegcodecmap.c: diff --git a/ext/ffmpeg/gstffmpegcodecmap.c b/ext/ffmpeg/gstffmpegcodecmap.c index 1b184279d4..8abf02760f 100644 --- a/ext/ffmpeg/gstffmpegcodecmap.c +++ b/ext/ffmpeg/gstffmpegcodecmap.c @@ -241,15 +241,10 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id, break; case CODEC_ID_MPEG4: - if (encode) { + if (encode && context != NULL) { /* I'm not exactly sure what ffmpeg outputs... ffmpeg itself uses * the AVI fourcc 'DIVX', but 'mp4v' for Quicktime... */ - guint32 fourcc = 0; - - if (context) - fourcc = context->codec_tag; - - switch (fourcc) { + switch (context->codec_tag) { case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'): caps = GST_FF_VID_CAPS_NEW ("video/x-divx", "divxversion", G_TYPE_INT, 5, NULL); @@ -267,10 +262,15 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id, caps = GST_FF_VID_CAPS_NEW ("video/mpeg", "mpegversion", G_TYPE_INT, 4, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL); - gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-divx", - "divxversion", GST_TYPE_INT_RANGE, 4, 5, NULL)); - gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-xvid", NULL)); - gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-3ivx", NULL)); + if (encode) { + gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-divx", + "divxversion", G_TYPE_INT, 5, NULL)); + } else { + gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-divx", + "divxversion", GST_TYPE_INT_RANGE, 4, 5, NULL)); + gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-xvid", NULL)); + gst_caps_append (caps, GST_FF_VID_CAPS_NEW ("video/x-3ivx", NULL)); + } } break; @@ -901,7 +901,8 @@ gst_ffmpeg_codectype_to_caps (enum CodecType codec_type, switch (codec_type) { case CODEC_TYPE_VIDEO: if (context) { - caps = gst_ffmpeg_pixfmt_to_caps (context->pix_fmt, context); + caps = gst_ffmpeg_pixfmt_to_caps (context->pix_fmt, + context->width == -1 ? NULL : context); } else { GstCaps *temp; enum PixelFormat i; @@ -1201,6 +1202,9 @@ gst_ffmpeg_caps_with_codecid (enum CodecID codec_id, break; } + if (!gst_caps_is_fixed (caps)) + return; + /* common properties (width, height, fps) */ switch (codec_type) { case CODEC_TYPE_VIDEO: diff --git a/ext/ffmpeg/gstffmpegenc.c b/ext/ffmpeg/gstffmpegenc.c index 08018c3635..e8f06b8710 100644 --- a/ext/ffmpeg/gstffmpegenc.c +++ b/ext/ffmpeg/gstffmpegenc.c @@ -154,6 +154,7 @@ gst_ffmpegenc_base_init (GstFFMpegEncClass * klass) GstFFMpegEncClassParams *params; GstElementDetails details; GstPadTemplate *srctempl, *sinktempl; + AVCodecContext *ctx; params = g_hash_table_lookup (enc_global_plugins, GINT_TO_POINTER (G_OBJECT_CLASS_TYPE (gobject_class))); @@ -177,6 +178,28 @@ gst_ffmpegenc_base_init (GstFFMpegEncClass * klass) g_free (details.klass); g_free (details.description); + /* get pix_fmt for this encoder */ + if (params->in_plugin->type == CODEC_TYPE_VIDEO && + (ctx = avcodec_alloc_context ()) != NULL) { + ctx->width = 384; + ctx->height = 288; + ctx->frame_rate_base = DEFAULT_FRAME_RATE_BASE; + ctx->frame_rate = 25 * DEFAULT_FRAME_RATE_BASE; + ctx->bit_rate = 350 * 1000; + /* makes it silent */ + ctx->strict_std_compliance = -1; + + if (avcodec_open (ctx, params->in_plugin) >= 0) { + gst_caps_free (params->sinkcaps); + ctx->width = -1; + params->sinkcaps = + gst_ffmpeg_codectype_to_caps (params->in_plugin->type, ctx); + } + /* FIXME: ffmpeg likes to crash on this */ + //avcodec_close (ctx); + av_free (ctx); + } + /* pad templates */ sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, params->sinkcaps); @@ -337,20 +360,24 @@ gst_ffmpegenc_connect (GstPad * pad, const GstCaps * caps) return GST_PAD_LINK_REFUSED; } + /* some codecs support more than one format, first auto-choose one */ + allowed_caps = gst_pad_get_allowed_caps (ffmpegenc->srcpad); + gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id, + oclass->in_plugin->type, allowed_caps, ffmpegenc->context); + /* try to set this caps on the other side */ other_caps = gst_ffmpeg_codecid_to_caps (oclass->in_plugin->id, ffmpegenc->context, TRUE); + if (!other_caps) { avcodec_close (ffmpegenc->context); GST_DEBUG ("Unsupported codec - no caps found"); return GST_PAD_LINK_REFUSED; } - allowed_caps = gst_pad_get_allowed_caps (ffmpegenc->srcpad); icaps = gst_caps_intersect (allowed_caps, other_caps); gst_caps_free (allowed_caps); gst_caps_free (other_caps); - if (gst_caps_is_empty (icaps)) { gst_caps_free (icaps); return GST_PAD_LINK_REFUSED; @@ -361,7 +388,7 @@ gst_ffmpegenc_connect (GstPad * pad, const GstCaps * caps) newcaps = gst_caps_new_full (gst_structure_copy (gst_caps_get_structure (icaps, - 0)), NULL); + 0)), NULL); gst_caps_free (icaps); icaps = newcaps; } @@ -619,6 +646,7 @@ gst_ffmpegenc_register (GstPlugin * plugin) /* no quasi codecs, please */ if (in_plugin->id == CODEC_ID_RAWVIDEO || + in_plugin->id == CODEC_ID_ZLIB || (in_plugin->id >= CODEC_ID_PCM_S16LE && in_plugin->id <= CODEC_ID_PCM_ALAW)) { goto next;