From: <mn...@ke...> - 2010-05-10 13:56:58
|
Module: gst-ffmpeg Branch: master Commit: 83820511a8be7af645df8d2ed0289df6d44e0bdd URL: http://cgit.freedesktop.org/gstreamer/gst-ffmpeg/commit/?id=83820511a8be7af645df8d2ed0289df6d44e0bdd Author: Olivier Crête <oli...@co...> Date: Fri Mar 6 13:47:05 2009 -0500 gstffmpegenc: Make getcaps proxy the downstream height/width/framerate requirements See #577784. --- ext/ffmpeg/gstffmpegenc.c | 72 +++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 69 insertions(+), 3 deletions(-) diff --git a/ext/ffmpeg/gstffmpegenc.c b/ext/ffmpeg/gstffmpegenc.c index 203a902..c48fd64 100644 --- a/ext/ffmpeg/gstffmpegenc.c +++ b/ext/ffmpeg/gstffmpegenc.c @@ -307,6 +307,67 @@ gst_ffmpegenc_finalize (GObject * object) } static GstCaps * +gst_ffmpegenc_get_possible_sizes (GstFFMpegEnc * ffmpegenc, GstPad * pad, + const GstCaps * caps) +{ + GstCaps *othercaps = NULL; + GstCaps *tmpcaps = NULL; + GstCaps *intersect = NULL; + guint i; + + othercaps = gst_pad_peer_get_caps (ffmpegenc->srcpad); + + if (!othercaps) + return gst_caps_copy (caps); + + intersect = gst_caps_intersect (othercaps, + gst_pad_get_pad_template_caps (ffmpegenc->srcpad)); + gst_caps_unref (othercaps); + + if (gst_caps_is_empty (intersect)) + return intersect; + + if (gst_caps_is_any (intersect)) + return gst_caps_copy (caps); + + tmpcaps = gst_caps_new_empty (); + + for (i = 0; i < gst_caps_get_size (intersect); i++) { + GstStructure *s = gst_caps_get_structure (intersect, i); + const GValue *height = NULL; + const GValue *width = NULL; + const GValue *framerate = NULL; + GstStructure *tmps; + + height = gst_structure_get_value (s, "height"); + width = gst_structure_get_value (s, "width"); + framerate = gst_structure_get_value (s, "framerate"); + + tmps = gst_structure_new ("video/x-raw-rgb", NULL); + if (width) + gst_structure_set_value (tmps, "width", width); + if (height) + gst_structure_set_value (tmps, "height", height); + if (framerate) + gst_structure_set_value (tmps, "framerate", framerate); + gst_caps_merge_structure (tmpcaps, gst_structure_copy (tmps)); + + gst_structure_set_name (tmps, "video/x-raw-yuv"); + gst_caps_merge_structure (tmpcaps, gst_structure_copy (tmps)); + + gst_structure_set_name (tmps, "video/x-raw-gray"); + gst_caps_merge_structure (tmpcaps, tmps); + } + gst_caps_unref (intersect); + + intersect = gst_caps_intersect (caps, tmpcaps); + gst_caps_unref (tmpcaps); + + return intersect; +} + + +static GstCaps * gst_ffmpegenc_getcaps (GstPad * pad) { GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) GST_PAD_PARENT (pad); @@ -315,6 +376,7 @@ gst_ffmpegenc_getcaps (GstPad * pad) AVCodecContext *ctx = NULL; enum PixelFormat pixfmt; GstCaps *caps = NULL; + GstCaps *finalcaps = NULL; gint i; GST_DEBUG_OBJECT (ffmpegenc, "getting caps"); @@ -331,7 +393,7 @@ gst_ffmpegenc_getcaps (GstPad * pad) /* cached */ if (oclass->sinkcaps) { - caps = gst_caps_copy (oclass->sinkcaps); + caps = gst_ffmpegenc_get_possible_sizes (ffmpegenc, pad, oclass->sinkcaps); GST_DEBUG_OBJECT (ffmpegenc, "return cached caps %" GST_PTR_FORMAT, caps); return caps; } @@ -430,7 +492,8 @@ gst_ffmpegenc_getcaps (GstPad * pad) /* make sure we have something */ if (!caps) { - caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); + caps = gst_ffmpegenc_get_possible_sizes (ffmpegenc, pad, + gst_pad_get_pad_template_caps (pad)); GST_DEBUG_OBJECT (ffmpegenc, "probing gave nothing, " "return template %" GST_PTR_FORMAT, caps); return caps; @@ -439,7 +502,10 @@ gst_ffmpegenc_getcaps (GstPad * pad) GST_DEBUG_OBJECT (ffmpegenc, "probed caps gave %" GST_PTR_FORMAT, caps); oclass->sinkcaps = gst_caps_copy (caps); - return caps; + finalcaps = gst_ffmpegenc_get_possible_sizes (ffmpegenc, pad, caps); + gst_caps_unref (caps); + + return finalcaps; } static gboolean |