videodecoder: expose getcaps virtual function

Allows subclasses to do custom caps query replies.

Also exposes the standard caps query handler so subclasses can just
extend on top of it instead of reimplementing the caps query proxying.

https://bugzilla.gnome.org/show_bug.cgi?id=741263
This commit is contained in:
Thiago Santos 2014-12-17 14:18:03 -03:00
parent 4956800549
commit 8085352fb3
4 changed files with 97 additions and 8 deletions

View file

@ -1578,6 +1578,47 @@ gst_video_decoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
return ret;
}
/**
* gst_video_decoder_proxy_getcaps:
* @decoder: a #GstVideoDecoder
* @caps: (allow-none): initial caps
* @filter: (allow-none): filter caps
*
* Returns caps that express @caps (or sink template caps if @caps == NULL)
* restricted to resolution/format/... combinations supported by downstream
* elements.
*
* Returns: (transfer-full): a #GstCaps owned by caller
*
* @Since: 1.6
*/
GstCaps *
gst_video_decoder_proxy_getcaps (GstVideoDecoder * decoder, GstCaps * caps,
GstCaps * filter)
{
return __gst_video_element_proxy_getcaps (GST_ELEMENT_CAST (decoder),
GST_VIDEO_DECODER_SINK_PAD (decoder),
GST_VIDEO_DECODER_SRC_PAD (decoder), caps, filter);
}
static GstCaps *
gst_video_decoder_sink_getcaps (GstVideoDecoder * decoder, GstCaps * filter)
{
GstVideoDecoderClass *klass;
GstCaps *caps;
klass = GST_VIDEO_DECODER_GET_CLASS (decoder);
if (klass->getcaps)
caps = klass->getcaps (decoder, filter);
else
caps = gst_video_decoder_proxy_getcaps (decoder, NULL, filter);
GST_LOG_OBJECT (decoder, "Returning caps %" GST_PTR_FORMAT, caps);
return caps;
}
static gboolean
gst_video_decoder_sink_query_default (GstVideoDecoder * decoder,
GstQuery * query)
@ -1615,15 +1656,12 @@ gst_video_decoder_sink_query_default (GstVideoDecoder * decoder,
break;
}
case GST_QUERY_CAPS:{
GstCaps *filter;
GstCaps *result;
GstCaps *filter, *caps;
gst_query_parse_caps (query, &filter);
result = __gst_video_element_proxy_getcaps (GST_ELEMENT_CAST (decoder),
GST_VIDEO_DECODER_SINK_PAD (decoder),
GST_VIDEO_DECODER_SRC_PAD (decoder), NULL, filter);
gst_query_set_caps_result (query, result);
gst_caps_unref (result);
caps = gst_video_decoder_sink_getcaps (decoder, filter);
gst_query_set_caps_result (query, caps);
gst_caps_unref (caps);
res = TRUE;
break;
}

View file

@ -256,6 +256,11 @@ struct _GstVideoDecoder
* return TRUE if the query could be performed. Subclasses
* should chain up to the parent implementation to invoke the
* default handler. Since 1.4
* @getcaps: Optional.
* Allows for a custom sink getcaps implementation.
* If not implemented, default returns
* gst_video_decoder_proxy_getcaps
* applied to sink template caps.
*
* Subclasses can override any of the available virtual methods or not, as
* needed. At minimum @handle_frame needs to be overridden, and @set_format
@ -312,9 +317,12 @@ struct _GstVideoDecoderClass
gboolean (*src_query) (GstVideoDecoder *decoder,
GstQuery *query);
GstCaps* (*getcaps) (GstVideoDecoder *decoder,
GstCaps *filter);
/*< private >*/
void *padding[GST_PADDING_LARGE-3];
void *padding[GST_PADDING_LARGE-4];
};
GType gst_video_decoder_get_type (void);
@ -398,6 +406,11 @@ void gst_video_decoder_merge_tags (GstVideoDecoder *decoder,
const GstTagList *tags,
GstTagMergeMode mode);
GstCaps * gst_video_decoder_proxy_getcaps (GstVideoDecoder * decoder,
GstCaps * caps,
GstCaps * filter);
G_END_DECLS
#endif

View file

@ -989,6 +989,42 @@ GST_START_TEST (videodecoder_query_caps_with_range_caps_peer)
GST_END_TEST;
#define GETCAPS_CAPS_STR "video/x-test-custom, somefield=(string)getcaps"
static GstCaps *
_custom_video_decoder_getcaps (GstVideoDecoder * dec, GstCaps * filter)
{
return gst_caps_from_string (GETCAPS_CAPS_STR);
}
GST_START_TEST (videodecoder_query_caps_with_custom_getcaps)
{
GstCaps *caps;
GstVideoDecoderClass *klass;
GstCaps *expected_caps;
setup_videodecodertester (&sinktemplate_restricted, NULL);
klass = GST_VIDEO_DECODER_CLASS (GST_VIDEO_DECODER_GET_CLASS (dec));
klass->getcaps = _custom_video_decoder_getcaps;
gst_pad_set_active (mysrcpad, TRUE);
gst_element_set_state (dec, GST_STATE_PLAYING);
gst_pad_set_active (mysinkpad, TRUE);
caps = gst_pad_peer_query_caps (mysrcpad, NULL);
fail_unless (caps != NULL);
expected_caps = gst_caps_from_string (GETCAPS_CAPS_STR);
fail_unless (gst_caps_is_equal (expected_caps, caps));
gst_caps_unref (expected_caps);
gst_caps_unref (caps);
cleanup_videodecodertest ();
}
GST_END_TEST;
static Suite *
gst_videodecoder_suite (void)
{
@ -999,6 +1035,7 @@ gst_videodecoder_suite (void)
tcase_add_test (tc, videodecoder_query_caps_with_fixed_caps_peer);
tcase_add_test (tc, videodecoder_query_caps_with_range_caps_peer);
tcase_add_test (tc, videodecoder_query_caps_with_custom_getcaps);
tcase_add_test (tc, videodecoder_playback);
tcase_add_test (tc, videodecoder_playback_with_events);

View file

@ -114,6 +114,7 @@ EXPORTS
gst_video_decoder_have_frame
gst_video_decoder_merge_tags
gst_video_decoder_negotiate
gst_video_decoder_proxy_getcaps
gst_video_decoder_release_frame
gst_video_decoder_set_estimate_rate
gst_video_decoder_set_latency