Merge branch '0.11' of ssh://git.freedesktop.org/git/gstreamer/gst-plugins-base into 0.11

This commit is contained in:
Sebastian Dröge 2012-03-02 10:13:52 +01:00
commit 84a02f9f13
4 changed files with 122 additions and 59 deletions

View File

@ -50,7 +50,6 @@
#define GST_CAT_DEFAULT theoradec_debug #define GST_CAT_DEFAULT theoradec_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define THEORA_DEF_CROP TRUE
#define THEORA_DEF_TELEMETRY_MV 0 #define THEORA_DEF_TELEMETRY_MV 0
#define THEORA_DEF_TELEMETRY_MBMODE 0 #define THEORA_DEF_TELEMETRY_MBMODE 0
#define THEORA_DEF_TELEMETRY_QI 0 #define THEORA_DEF_TELEMETRY_QI 0
@ -59,7 +58,6 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
enum enum
{ {
PROP_0, PROP_0,
PROP_CROP,
PROP_TELEMETRY_MV, PROP_TELEMETRY_MV,
PROP_TELEMETRY_MBMODE, PROP_TELEMETRY_MBMODE,
PROP_TELEMETRY_QI, PROP_TELEMETRY_QI,
@ -128,11 +126,6 @@ gst_theora_dec_class_init (GstTheoraDecClass * klass)
gobject_class->set_property = theora_dec_set_property; gobject_class->set_property = theora_dec_set_property;
gobject_class->get_property = theora_dec_get_property; gobject_class->get_property = theora_dec_get_property;
g_object_class_install_property (gobject_class, PROP_CROP,
g_param_spec_boolean ("crop", "Crop",
"Crop the image to the visible region", THEORA_DEF_CROP,
(GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
if (gst_theora_dec_ctl_is_supported (TH_DECCTL_SET_TELEMETRY_MV)) { if (gst_theora_dec_ctl_is_supported (TH_DECCTL_SET_TELEMETRY_MV)) {
g_object_class_install_property (gobject_class, PROP_TELEMETRY_MV, g_object_class_install_property (gobject_class, PROP_TELEMETRY_MV,
g_param_spec_int ("visualize-motion-vectors", g_param_spec_int ("visualize-motion-vectors",
@ -208,7 +201,6 @@ gst_theora_dec_init (GstTheoraDec * dec)
gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad); gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
dec->crop = THEORA_DEF_CROP;
dec->telemetry_mv = THEORA_DEF_TELEMETRY_MV; dec->telemetry_mv = THEORA_DEF_TELEMETRY_MV;
dec->telemetry_mbmode = THEORA_DEF_TELEMETRY_MBMODE; dec->telemetry_mbmode = THEORA_DEF_TELEMETRY_MBMODE;
dec->telemetry_qi = THEORA_DEF_TELEMETRY_QI; dec->telemetry_qi = THEORA_DEF_TELEMETRY_QI;
@ -776,12 +768,16 @@ theora_handle_comment_packet (GstTheoraDec * dec, ogg_packet * packet)
} }
static GstFlowReturn static GstFlowReturn
theora_negotiate_pool (GstTheoraDec * dec, GstCaps * caps, GstVideoInfo * info) theora_negotiate_pool (GstTheoraDec * dec)
{ {
GstQuery *query; GstQuery *query;
GstBufferPool *pool = NULL; GstBufferPool *pool;
guint size, min, max, prefix, alignment; guint size, min, max, prefix, alignment;
GstStructure *config; GstStructure *config;
GstCaps *caps;
/* find the caps of the output buffer */
caps = gst_pad_get_current_caps (dec->srcpad);
/* find a pool for the negotiated caps now */ /* find a pool for the negotiated caps now */
query = gst_query_new_allocation (caps, TRUE); query = gst_query_new_allocation (caps, TRUE);
@ -791,35 +787,45 @@ theora_negotiate_pool (GstTheoraDec * dec, GstCaps * caps, GstVideoInfo * info)
/* we got configuration from our peer, parse them */ /* we got configuration from our peer, parse them */
gst_query_parse_allocation_params (query, &size, &min, &max, &prefix, gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
&alignment, &pool); &alignment, &pool);
size = MAX (size, info->size);
} else { } else {
GST_DEBUG_OBJECT (dec, "didn't get downstream ALLOCATION hints"); GST_DEBUG_OBJECT (dec, "didn't get downstream ALLOCATION hints");
size = info->size; size = 0;
min = max = 0; min = max = 0;
prefix = 0; prefix = 0;
alignment = 0; alignment = 0;
pool = NULL;
} }
if (pool == NULL) { if (pool == NULL) {
/* we did not get a pool, make one ourselves then */ /* we did not get a pool, make one ourselves then */
pool = gst_buffer_pool_new (); pool = gst_video_buffer_pool_new ();
} }
if (dec->pool) if (dec->pool)
gst_object_unref (dec->pool); gst_object_unref (dec->pool);
dec->pool = pool; dec->pool = pool;
/* check if downstream supports cropping */
dec->has_cropping =
gst_query_has_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE);
if (dec->has_cropping) {
/* we can crop, configure the pool with buffers of caps and size of the
* decoded picture size and then crop them with metadata */
size = MAX (size, GST_VIDEO_INFO_SIZE (&dec->vinfo));
gst_caps_unref (caps);
caps = gst_video_info_to_caps (&dec->vinfo);
}
config = gst_buffer_pool_get_config (pool); config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_set (config, caps, size, min, max, prefix, alignment); gst_buffer_pool_config_set (config, caps, size, min, max, prefix, alignment);
gst_caps_unref (caps);
/* just set the option, if the pool can support it we will transparently use /* just set the option, if the pool can support it we will transparently use
* it through the video info API. We could also see if the pool support this * it through the video info API. We could also see if the pool support this
* option and only activate it then. */ * option and only activate it then. */
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
/* check if downstream supports cropping */
dec->has_cropping =
gst_query_has_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE);
GST_DEBUG_OBJECT (dec, "downstream cropping %d", dec->has_cropping); GST_DEBUG_OBJECT (dec, "downstream cropping %d", dec->has_cropping);
gst_buffer_pool_set_config (pool, config); gst_buffer_pool_set_config (pool, config);
@ -836,10 +842,10 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
{ {
GstCaps *caps; GstCaps *caps;
GstVideoFormat format; GstVideoFormat format;
gint width, height;
gint par_num, par_den; gint par_num, par_den;
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
GList *walk; GList *walk;
GstVideoInfo info;
GST_DEBUG_OBJECT (dec, "fps %d/%d, PAR %d/%d", GST_DEBUG_OBJECT (dec, "fps %d/%d, PAR %d/%d",
dec->info.fps_numerator, dec->info.fps_denominator, dec->info.fps_numerator, dec->info.fps_denominator,
@ -891,14 +897,6 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
goto invalid_format; goto invalid_format;
} }
if (dec->crop) {
width = dec->info.pic_width;
height = dec->info.pic_height;
} else {
/* no cropping, use the encoded dimensions */
width = dec->info.frame_width;
height = dec->info.frame_height;
}
if (dec->info.pic_width != dec->info.frame_width || if (dec->info.pic_width != dec->info.frame_width ||
dec->info.pic_height != dec->info.frame_height || dec->info.pic_height != dec->info.frame_height ||
dec->info.pic_x != 0 || dec->info.pic_y != 0) { dec->info.pic_x != 0 || dec->info.pic_y != 0) {
@ -929,7 +927,9 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
GST_WARNING_OBJECT (dec, "Could not enable BITS mode visualisation"); GST_WARNING_OBJECT (dec, "Could not enable BITS mode visualisation");
} }
gst_video_info_set_format (&dec->vinfo, format, width, height); /* our info contains the dimensions for the coded picture before cropping */
gst_video_info_set_format (&dec->vinfo, format, dec->info.frame_width,
dec->info.frame_height);
dec->vinfo.fps_n = dec->info.fps_numerator; dec->vinfo.fps_n = dec->info.fps_numerator;
dec->vinfo.fps_d = dec->info.fps_denominator; dec->vinfo.fps_d = dec->info.fps_denominator;
dec->vinfo.par_n = par_num; dec->vinfo.par_n = par_num;
@ -953,13 +953,16 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
break; break;
} }
caps = gst_video_info_to_caps (&dec->vinfo); /* for the output caps we always take the cropped dimensions */
info = dec->vinfo;
gst_video_info_set_format (&info, format, dec->info.pic_width,
dec->info.pic_height);
caps = gst_video_info_to_caps (&info);
gst_pad_set_caps (dec->srcpad, caps); gst_pad_set_caps (dec->srcpad, caps);
gst_caps_unref (caps); gst_caps_unref (caps);
/* negotiate a bufferpool */ /* make sure we negotiate a bufferpool */
if ((ret = theora_negotiate_pool (dec, caps, &dec->vinfo)) != GST_FLOW_OK) gst_pad_mark_reconfigure (dec->srcpad);
goto no_bufferpool;
dec->have_header = TRUE; dec->have_header = TRUE;
@ -983,10 +986,6 @@ invalid_format:
GST_ERROR_OBJECT (dec, "Invalid pixel format %d", dec->info.pixel_fmt); GST_ERROR_OBJECT (dec, "Invalid pixel format %d", dec->info.pixel_fmt);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
no_bufferpool:
{
return ret;
}
} }
static GstFlowReturn static GstFlowReturn
@ -1113,13 +1112,8 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf, GstBuffer ** out)
GstVideoCropMeta *crop; GstVideoCropMeta *crop;
gint offset_x, offset_y; gint offset_x, offset_y;
if (gst_pad_check_reconfigure (dec->srcpad)) { if (gst_pad_check_reconfigure (dec->srcpad))
GstCaps *caps; theora_negotiate_pool (dec);
caps = gst_pad_get_current_caps (dec->srcpad);
theora_negotiate_pool (dec, caps, &dec->vinfo);
gst_caps_unref (caps);
}
result = gst_buffer_pool_acquire_buffer (dec->pool, out, NULL); result = gst_buffer_pool_acquire_buffer (dec->pool, out, NULL);
if (G_UNLIKELY (result != GST_FLOW_OK)) if (G_UNLIKELY (result != GST_FLOW_OK))
@ -1128,7 +1122,7 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf, GstBuffer ** out)
if (!gst_video_frame_map (&frame, &dec->vinfo, *out, GST_MAP_WRITE)) if (!gst_video_frame_map (&frame, &dec->vinfo, *out, GST_MAP_WRITE))
goto invalid_frame; goto invalid_frame;
if (dec->crop && !dec->has_cropping) { if (!dec->has_cropping) {
/* we need to crop the hard way */ /* we need to crop the hard way */
offset_x = dec->info.pic_x; offset_x = dec->info.pic_x;
offset_y = dec->info.pic_y; offset_y = dec->info.pic_y;
@ -1650,9 +1644,6 @@ theora_dec_set_property (GObject * object, guint prop_id,
GstTheoraDec *dec = GST_THEORA_DEC (object); GstTheoraDec *dec = GST_THEORA_DEC (object);
switch (prop_id) { switch (prop_id) {
case PROP_CROP:
dec->crop = g_value_get_boolean (value);
break;
case PROP_TELEMETRY_MV: case PROP_TELEMETRY_MV:
dec->telemetry_mv = g_value_get_int (value); dec->telemetry_mv = g_value_get_int (value);
break; break;
@ -1678,9 +1669,6 @@ theora_dec_get_property (GObject * object, guint prop_id,
GstTheoraDec *dec = GST_THEORA_DEC (object); GstTheoraDec *dec = GST_THEORA_DEC (object);
switch (prop_id) { switch (prop_id) {
case PROP_CROP:
g_value_set_boolean (value, dec->crop);
break;
case PROP_TELEMETRY_MV: case PROP_TELEMETRY_MV:
g_value_set_int (value, dec->telemetry_mv); g_value_set_int (value, dec->telemetry_mv);
break; break;

View File

@ -82,8 +82,6 @@ struct _GstTheoraDec
gint telemetry_qi; gint telemetry_qi;
gint telemetry_bits; gint telemetry_bits;
gboolean crop;
/* list of buffers that need timestamps */ /* list of buffers that need timestamps */
GList *queued; GList *queued;
/* list of raw output buffers */ /* list of raw output buffers */

View File

@ -53,7 +53,7 @@ G_DEFINE_ABSTRACT_TYPE (GstVideoFilter, gst_video_filter,
/* Answer the allocation query downstream. */ /* Answer the allocation query downstream. */
static gboolean static gboolean
gst_video_filter_propose_allocation (GstBaseTransform * trans, gst_video_filter_propose_allocation (GstBaseTransform * trans,
gboolean passthrough, GstQuery * query) GstQuery * decide_query, GstQuery * query)
{ {
GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans); GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans);
GstVideoInfo info; GstVideoInfo info;
@ -63,9 +63,9 @@ gst_video_filter_propose_allocation (GstBaseTransform * trans,
guint size; guint size;
/* we're passthrough, let the parent implementation hande things */ /* we're passthrough, let the parent implementation hande things */
if (passthrough) if (decide_query == NULL)
return GST_BASE_TRANSFORM_CLASS (parent_class)->propose_allocation (trans, return GST_BASE_TRANSFORM_CLASS (parent_class)->propose_allocation (trans,
passthrough, query); decide_query, query);
gst_query_parse_allocation (query, &caps, &need_pool); gst_query_parse_allocation (query, &caps, &need_pool);
@ -124,7 +124,8 @@ gst_video_filter_decide_allocation (GstBaseTransform * trans, GstQuery * query)
GST_BUFFER_POOL_OPTION_VIDEO_META); GST_BUFFER_POOL_OPTION_VIDEO_META);
gst_buffer_pool_set_config (pool, config); gst_buffer_pool_set_config (pool, config);
} }
return TRUE; return GST_BASE_TRANSFORM_CLASS (parent_class)->decide_allocation (trans,
query);
} }

View File

@ -49,6 +49,12 @@ GST_DEBUG_CATEGORY (videoconvert_debug);
#define GST_CAT_DEFAULT videoconvert_debug #define GST_CAT_DEFAULT videoconvert_debug
GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE); GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
GType gst_video_convert_get_type (void);
static GQuark _colorspace_quark;
#define gst_video_convert_parent_class parent_class
G_DEFINE_TYPE (GstVideoConvert, gst_video_convert, GST_TYPE_VIDEO_FILTER);
enum enum
{ {
@ -72,8 +78,6 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_STATIC_CAPS (CSP_VIDEO_CAPS) GST_STATIC_CAPS (CSP_VIDEO_CAPS)
); );
GType gst_video_convert_get_type (void);
static void gst_video_convert_set_property (GObject * object, static void gst_video_convert_set_property (GObject * object,
guint property_id, const GValue * value, GParamSpec * pspec); guint property_id, const GValue * value, GParamSpec * pspec);
static void gst_video_convert_get_property (GObject * object, static void gst_video_convert_get_property (GObject * object,
@ -305,8 +309,74 @@ invalid_palette:
} }
} }
#define gst_video_convert_parent_class parent_class static gboolean
G_DEFINE_TYPE (GstVideoConvert, gst_video_convert, GST_TYPE_VIDEO_FILTER); gst_video_convert_propose_allocation (GstBaseTransform * trans,
GstQuery * decide_query, GstQuery * query)
{
gboolean ret;
guint i, n_metas;
/* let parent handle */
ret = GST_BASE_TRANSFORM_CLASS (parent_class)->propose_allocation (trans,
decide_query, query);
/* error or passthrough, we're done */
if (!ret || decide_query == NULL)
return ret;
/* non-passthrough, copy all metadata, decide_query does not contain the
* metadata anymore that depends on the buffer memory */
n_metas = gst_query_get_n_allocation_metas (decide_query);
for (i = 0; i < n_metas; i++) {
GType api;
api = gst_query_parse_nth_allocation_meta (decide_query, i);
gst_query_add_allocation_meta (query, api);
}
return ret;
}
typedef struct
{
GstBaseTransform *trans;
GstBuffer *outbuf;
GQuark tag;
} CopyMetaData;
static gboolean
foreach_metadata (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
{
CopyMetaData *data = user_data;
const GstMetaInfo *info = (*meta)->info;
if (info->transform_func) {
if (gst_meta_api_type_has_tag (info->api, data->tag)) {
/* metadata depends on colorspace. FIXME discard for now until we
* have some transform data for it. */
} else {
GstMetaTransformCopy copy_data = { 0, -1 };
/* simply copy then */
info->transform_func (data->outbuf, *meta, inbuf,
_gst_meta_transform_copy, &copy_data);
}
}
return TRUE;
}
static gboolean
gst_video_convert_copy_metadata (GstBaseTransform * trans,
GstBuffer * inbuf, GstBuffer * outbuf)
{
CopyMetaData data;
data.trans = trans;
data.outbuf = outbuf;
data.tag = _colorspace_quark;
gst_buffer_foreach_meta (inbuf, foreach_metadata, &data);
return GST_BASE_TRANSFORM_CLASS (parent_class)->copy_metadata (trans, inbuf,
outbuf);
}
static void static void
gst_video_convert_finalize (GObject * obj) gst_video_convert_finalize (GObject * obj)
@ -347,6 +417,10 @@ gst_video_convert_class_init (GstVideoConvertClass * klass)
GST_DEBUG_FUNCPTR (gst_video_convert_transform_caps); GST_DEBUG_FUNCPTR (gst_video_convert_transform_caps);
gstbasetransform_class->fixate_caps = gstbasetransform_class->fixate_caps =
GST_DEBUG_FUNCPTR (gst_video_convert_fixate_caps); GST_DEBUG_FUNCPTR (gst_video_convert_fixate_caps);
gstbasetransform_class->propose_allocation =
GST_DEBUG_FUNCPTR (gst_video_convert_propose_allocation);
gstbasetransform_class->copy_metadata =
GST_DEBUG_FUNCPTR (gst_video_convert_copy_metadata);
gstbasetransform_class->passthrough_on_same_caps = TRUE; gstbasetransform_class->passthrough_on_same_caps = TRUE;
@ -428,6 +502,8 @@ plugin_init (GstPlugin * plugin)
GST_DEBUG_CATEGORY_INIT (videoconvert_debug, "videoconvert", 0, GST_DEBUG_CATEGORY_INIT (videoconvert_debug, "videoconvert", 0,
"Colorspace Converter"); "Colorspace Converter");
_colorspace_quark = g_quark_from_static_string ("colorspace");
return gst_element_register (plugin, "videoconvert", return gst_element_register (plugin, "videoconvert",
GST_RANK_NONE, GST_TYPE_VIDEO_CONVERT); GST_RANK_NONE, GST_TYPE_VIDEO_CONVERT);
} }