mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
videodecoder: implement caps query
Refactor the encoder's caps query proxying function to a common place and use it in the videodecoder to proxy downstream restrictions. The new function is private to the gstvideo lib. https://bugzilla.gnome.org/show_bug.cgi?id=741263
This commit is contained in:
parent
f78a3d9ef2
commit
f24075887f
6 changed files with 365 additions and 83 deletions
|
@ -42,6 +42,7 @@ libgstvideo_@GST_API_VERSION@_la_SOURCES = \
|
||||||
gstvideodecoder.c \
|
gstvideodecoder.c \
|
||||||
gstvideoencoder.c \
|
gstvideoencoder.c \
|
||||||
gstvideoutils.c \
|
gstvideoutils.c \
|
||||||
|
gstvideoutilsprivate.c \
|
||||||
video-resampler.c \
|
video-resampler.c \
|
||||||
video-blend.c \
|
video-blend.c \
|
||||||
video-overlay-composition.c
|
video-overlay-composition.c
|
||||||
|
@ -78,6 +79,7 @@ libgstvideo_@GST_API_VERSION@include_HEADERS = \
|
||||||
video-overlay-composition.h
|
video-overlay-composition.h
|
||||||
|
|
||||||
nodist_libgstvideo_@GST_API_VERSION@include_HEADERS = $(built_headers)
|
nodist_libgstvideo_@GST_API_VERSION@include_HEADERS = $(built_headers)
|
||||||
|
noinst_HEADERS = gstvideoutilsprivate.h
|
||||||
|
|
||||||
libgstvideo_@GST_API_VERSION@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) \
|
libgstvideo_@GST_API_VERSION@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) \
|
||||||
$(ORC_CFLAGS)
|
$(ORC_CFLAGS)
|
||||||
|
|
|
@ -295,6 +295,7 @@
|
||||||
|
|
||||||
#include "gstvideodecoder.h"
|
#include "gstvideodecoder.h"
|
||||||
#include "gstvideoutils.h"
|
#include "gstvideoutils.h"
|
||||||
|
#include "gstvideoutilsprivate.h"
|
||||||
|
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include <gst/video/video-event.h>
|
#include <gst/video/video-event.h>
|
||||||
|
@ -1613,6 +1614,19 @@ gst_video_decoder_sink_query_default (GstVideoDecoder * decoder,
|
||||||
res = klass->propose_allocation (decoder, query);
|
res = klass->propose_allocation (decoder, query);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GST_QUERY_CAPS:{
|
||||||
|
GstCaps *filter;
|
||||||
|
GstCaps *result;
|
||||||
|
|
||||||
|
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);
|
||||||
|
res = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
res = gst_pad_query_default (pad, GST_OBJECT (decoder), query);
|
res = gst_pad_query_default (pad, GST_OBJECT (decoder), query);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -117,6 +117,7 @@
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include "gstvideoencoder.h"
|
#include "gstvideoencoder.h"
|
||||||
#include "gstvideoutils.h"
|
#include "gstvideoutils.h"
|
||||||
|
#include "gstvideoutilsprivate.h"
|
||||||
|
|
||||||
#include <gst/video/gstvideometa.h>
|
#include <gst/video/gstvideometa.h>
|
||||||
#include <gst/video/gstvideopool.h>
|
#include <gst/video/gstvideopool.h>
|
||||||
|
@ -679,69 +680,9 @@ GstCaps *
|
||||||
gst_video_encoder_proxy_getcaps (GstVideoEncoder * encoder, GstCaps * caps,
|
gst_video_encoder_proxy_getcaps (GstVideoEncoder * encoder, GstCaps * caps,
|
||||||
GstCaps * filter)
|
GstCaps * filter)
|
||||||
{
|
{
|
||||||
GstCaps *templ_caps;
|
return __gst_video_element_proxy_getcaps (GST_ELEMENT_CAST (encoder),
|
||||||
GstCaps *allowed;
|
GST_VIDEO_ENCODER_SINK_PAD (encoder),
|
||||||
GstCaps *fcaps, *filter_caps;
|
GST_VIDEO_ENCODER_SRC_PAD (encoder), caps, filter);
|
||||||
gint i, j;
|
|
||||||
|
|
||||||
/* Allow downstream to specify width/height/framerate/PAR constraints
|
|
||||||
* and forward them upstream for video converters to handle
|
|
||||||
*/
|
|
||||||
templ_caps =
|
|
||||||
caps ? gst_caps_ref (caps) :
|
|
||||||
gst_pad_get_pad_template_caps (encoder->sinkpad);
|
|
||||||
allowed = gst_pad_get_allowed_caps (encoder->srcpad);
|
|
||||||
|
|
||||||
if (!allowed || gst_caps_is_empty (allowed) || gst_caps_is_any (allowed)) {
|
|
||||||
fcaps = templ_caps;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (encoder, "template caps %" GST_PTR_FORMAT, templ_caps);
|
|
||||||
GST_LOG_OBJECT (encoder, "allowed caps %" GST_PTR_FORMAT, allowed);
|
|
||||||
|
|
||||||
filter_caps = gst_caps_new_empty ();
|
|
||||||
|
|
||||||
for (i = 0; i < gst_caps_get_size (templ_caps); i++) {
|
|
||||||
GQuark q_name =
|
|
||||||
gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i));
|
|
||||||
|
|
||||||
for (j = 0; j < gst_caps_get_size (allowed); j++) {
|
|
||||||
const GstStructure *allowed_s = gst_caps_get_structure (allowed, j);
|
|
||||||
const GValue *val;
|
|
||||||
GstStructure *s;
|
|
||||||
|
|
||||||
s = gst_structure_new_id_empty (q_name);
|
|
||||||
if ((val = gst_structure_get_value (allowed_s, "width")))
|
|
||||||
gst_structure_set_value (s, "width", val);
|
|
||||||
if ((val = gst_structure_get_value (allowed_s, "height")))
|
|
||||||
gst_structure_set_value (s, "height", val);
|
|
||||||
if ((val = gst_structure_get_value (allowed_s, "framerate")))
|
|
||||||
gst_structure_set_value (s, "framerate", val);
|
|
||||||
if ((val = gst_structure_get_value (allowed_s, "pixel-aspect-ratio")))
|
|
||||||
gst_structure_set_value (s, "pixel-aspect-ratio", val);
|
|
||||||
|
|
||||||
filter_caps = gst_caps_merge_structure (filter_caps, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fcaps = gst_caps_intersect (filter_caps, templ_caps);
|
|
||||||
gst_caps_unref (filter_caps);
|
|
||||||
gst_caps_unref (templ_caps);
|
|
||||||
|
|
||||||
if (filter) {
|
|
||||||
GST_LOG_OBJECT (encoder, "intersecting with %" GST_PTR_FORMAT, filter);
|
|
||||||
filter_caps = gst_caps_intersect (fcaps, filter);
|
|
||||||
gst_caps_unref (fcaps);
|
|
||||||
fcaps = filter_caps;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
gst_caps_replace (&allowed, NULL);
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (encoder, "proxy caps %" GST_PTR_FORMAT, fcaps);
|
|
||||||
|
|
||||||
return fcaps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
|
|
109
gst-libs/gst/video/gstvideoutilsprivate.c
Normal file
109
gst-libs/gst/video/gstvideoutilsprivate.c
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2008 David Schleef <ds@schleef.org>
|
||||||
|
* Copyright (C) 2012 Collabora Ltd.
|
||||||
|
* Author : Edward Hervey <edward@collabora.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gst/video/video.h>
|
||||||
|
#include "gstvideoutilsprivate.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __gst_video_element_proxy_getcaps:
|
||||||
|
* @element: a #GstElement
|
||||||
|
* @sinkpad: the element's sink #GstPad
|
||||||
|
* @srcpad: the element's source #GstPad
|
||||||
|
* @initial_caps: initial caps
|
||||||
|
* @filter: filter caps
|
||||||
|
*
|
||||||
|
* Returns caps that express @initial_caps (or sink template caps if
|
||||||
|
* @initial_caps == NULL) restricted to resolution/format/...
|
||||||
|
* combinations supported by downstream elements (e.g. muxers).
|
||||||
|
*
|
||||||
|
* Returns: a #GstCaps owned by caller
|
||||||
|
*/
|
||||||
|
GstCaps *
|
||||||
|
__gst_video_element_proxy_getcaps (GstElement * element, GstPad * sinkpad,
|
||||||
|
GstPad * srcpad, GstCaps * initial_caps, GstCaps * filter)
|
||||||
|
{
|
||||||
|
GstCaps *templ_caps;
|
||||||
|
GstCaps *allowed;
|
||||||
|
GstCaps *fcaps, *filter_caps;
|
||||||
|
gint i, j;
|
||||||
|
|
||||||
|
/* Allow downstream to specify width/height/framerate/PAR constraints
|
||||||
|
* and forward them upstream for video converters to handle
|
||||||
|
*/
|
||||||
|
templ_caps = initial_caps ? gst_caps_ref (initial_caps) :
|
||||||
|
gst_pad_get_pad_template_caps (sinkpad);
|
||||||
|
allowed = gst_pad_get_allowed_caps (srcpad);
|
||||||
|
|
||||||
|
if (!allowed || gst_caps_is_empty (allowed) || gst_caps_is_any (allowed)) {
|
||||||
|
fcaps = templ_caps;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (element, "template caps %" GST_PTR_FORMAT, templ_caps);
|
||||||
|
GST_LOG_OBJECT (element, "allowed caps %" GST_PTR_FORMAT, allowed);
|
||||||
|
|
||||||
|
filter_caps = gst_caps_new_empty ();
|
||||||
|
|
||||||
|
for (i = 0; i < gst_caps_get_size (templ_caps); i++) {
|
||||||
|
GQuark q_name =
|
||||||
|
gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i));
|
||||||
|
|
||||||
|
for (j = 0; j < gst_caps_get_size (allowed); j++) {
|
||||||
|
const GstStructure *allowed_s = gst_caps_get_structure (allowed, j);
|
||||||
|
const GValue *val;
|
||||||
|
GstStructure *s;
|
||||||
|
|
||||||
|
s = gst_structure_new_id_empty (q_name);
|
||||||
|
if ((val = gst_structure_get_value (allowed_s, "width")))
|
||||||
|
gst_structure_set_value (s, "width", val);
|
||||||
|
if ((val = gst_structure_get_value (allowed_s, "height")))
|
||||||
|
gst_structure_set_value (s, "height", val);
|
||||||
|
if ((val = gst_structure_get_value (allowed_s, "framerate")))
|
||||||
|
gst_structure_set_value (s, "framerate", val);
|
||||||
|
if ((val = gst_structure_get_value (allowed_s, "pixel-aspect-ratio")))
|
||||||
|
gst_structure_set_value (s, "pixel-aspect-ratio", val);
|
||||||
|
|
||||||
|
filter_caps = gst_caps_merge_structure (filter_caps, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fcaps = gst_caps_intersect (filter_caps, templ_caps);
|
||||||
|
gst_caps_unref (filter_caps);
|
||||||
|
gst_caps_unref (templ_caps);
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
GST_LOG_OBJECT (element, "intersecting with %" GST_PTR_FORMAT, filter);
|
||||||
|
filter_caps = gst_caps_intersect (fcaps, filter);
|
||||||
|
gst_caps_unref (fcaps);
|
||||||
|
fcaps = filter_caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
gst_caps_replace (&allowed, NULL);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (element, "proxy caps %" GST_PTR_FORMAT, fcaps);
|
||||||
|
|
||||||
|
return fcaps;
|
||||||
|
}
|
40
gst-libs/gst/video/gstvideoutilsprivate.h
Normal file
40
gst-libs/gst/video/gstvideoutilsprivate.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2008 David Schleef <ds@schleef.org>
|
||||||
|
* Copyright (C) 2012 Collabora Ltd.
|
||||||
|
* Author : Edward Hervey <edward@collabora.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GST_VIDEO_H__
|
||||||
|
#include <gst/video/video.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _GST_VIDEO_UTILS_PRIVATE_H_
|
||||||
|
#define _GST_VIDEO_UTILS_PRIVATE_H_
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/* Element utility functions */
|
||||||
|
GstCaps *__gst_video_element_proxy_getcaps (GstElement * element, GstPad * sinkpad,
|
||||||
|
GstPad * srcpad, GstCaps * initial_caps,
|
||||||
|
GstCaps * filter);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
|
@ -27,6 +27,38 @@
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include <gst/app/app.h>
|
#include <gst/app/app.h>
|
||||||
|
|
||||||
|
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
GST_PAD_SINK,
|
||||||
|
GST_PAD_ALWAYS,
|
||||||
|
GST_STATIC_CAPS ("video/x-raw")
|
||||||
|
);
|
||||||
|
|
||||||
|
#define RESTRICTED_CAPS_WIDTH 800
|
||||||
|
#define RESTRICTED_CAPS_HEIGHT 600
|
||||||
|
#define RESTRICTED_CAPS_FPS_N 30
|
||||||
|
#define RESTRICTED_CAPS_FPS_D 1
|
||||||
|
static GstStaticPadTemplate sinktemplate_restricted =
|
||||||
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
GST_PAD_SINK,
|
||||||
|
GST_PAD_ALWAYS,
|
||||||
|
GST_STATIC_CAPS ("video/x-raw, width=(int)800, height=(int)600,"
|
||||||
|
" framerate=(fraction)30/1")
|
||||||
|
);
|
||||||
|
|
||||||
|
static GstStaticPadTemplate sinktemplate_with_range =
|
||||||
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
GST_PAD_SINK,
|
||||||
|
GST_PAD_ALWAYS,
|
||||||
|
GST_STATIC_CAPS ("video/x-raw, width=(int)[1,800], height=(int)[1,600],"
|
||||||
|
" framerate=(fraction)[1/1, 30/1]")
|
||||||
|
);
|
||||||
|
|
||||||
|
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
|
GST_PAD_SRC,
|
||||||
|
GST_PAD_ALWAYS,
|
||||||
|
GST_STATIC_CAPS ("video/x-test-custom")
|
||||||
|
);
|
||||||
|
|
||||||
static GstPad *mysrcpad, *mysinkpad;
|
static GstPad *mysrcpad, *mysinkpad;
|
||||||
static GstElement *dec;
|
static GstElement *dec;
|
||||||
static GList *events = NULL;
|
static GList *events = NULL;
|
||||||
|
@ -181,22 +213,17 @@ _mysinkpad_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_videodecodertester (void)
|
setup_videodecodertester (GstStaticPadTemplate * sinktmpl,
|
||||||
|
GstStaticPadTemplate * srctmpl)
|
||||||
{
|
{
|
||||||
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
if (sinktmpl == NULL)
|
||||||
GST_PAD_SINK,
|
sinktmpl = &sinktemplate;
|
||||||
GST_PAD_ALWAYS,
|
if (srctmpl == NULL)
|
||||||
GST_STATIC_CAPS ("video/x-raw")
|
srctmpl = &srctemplate;
|
||||||
);
|
|
||||||
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
|
|
||||||
GST_PAD_SRC,
|
|
||||||
GST_PAD_ALWAYS,
|
|
||||||
GST_STATIC_CAPS ("video/x-test-custom")
|
|
||||||
);
|
|
||||||
|
|
||||||
dec = g_object_new (GST_VIDEO_DECODER_TESTER_TYPE, NULL);
|
dec = g_object_new (GST_VIDEO_DECODER_TESTER_TYPE, NULL);
|
||||||
mysrcpad = gst_check_setup_src_pad (dec, &srctemplate);
|
mysrcpad = gst_check_setup_src_pad (dec, srctmpl);
|
||||||
mysinkpad = gst_check_setup_sink_pad (dec, &sinktemplate);
|
mysinkpad = gst_check_setup_sink_pad (dec, sinktmpl);
|
||||||
|
|
||||||
gst_pad_set_event_function (mysinkpad, _mysinkpad_event);
|
gst_pad_set_event_function (mysinkpad, _mysinkpad_event);
|
||||||
}
|
}
|
||||||
|
@ -259,7 +286,7 @@ GST_START_TEST (videodecoder_playback)
|
||||||
guint64 i;
|
guint64 i;
|
||||||
GList *iter;
|
GList *iter;
|
||||||
|
|
||||||
setup_videodecodertester ();
|
setup_videodecodertester (NULL, NULL);
|
||||||
|
|
||||||
gst_pad_set_active (mysrcpad, TRUE);
|
gst_pad_set_active (mysrcpad, TRUE);
|
||||||
gst_element_set_state (dec, GST_STATE_PLAYING);
|
gst_element_set_state (dec, GST_STATE_PLAYING);
|
||||||
|
@ -321,7 +348,7 @@ GST_START_TEST (videodecoder_playback_with_events)
|
||||||
GList *iter;
|
GList *iter;
|
||||||
GList *events_iter;
|
GList *events_iter;
|
||||||
|
|
||||||
setup_videodecodertester ();
|
setup_videodecodertester (NULL, NULL);
|
||||||
|
|
||||||
gst_pad_set_active (mysrcpad, TRUE);
|
gst_pad_set_active (mysrcpad, TRUE);
|
||||||
gst_element_set_state (dec, GST_STATE_PLAYING);
|
gst_element_set_state (dec, GST_STATE_PLAYING);
|
||||||
|
@ -429,7 +456,7 @@ GST_START_TEST (videodecoder_flush_events)
|
||||||
guint64 i;
|
guint64 i;
|
||||||
GList *events_iter;
|
GList *events_iter;
|
||||||
|
|
||||||
setup_videodecodertester ();
|
setup_videodecodertester (NULL, NULL);
|
||||||
|
|
||||||
gst_pad_set_active (mysrcpad, TRUE);
|
gst_pad_set_active (mysrcpad, TRUE);
|
||||||
gst_element_set_state (dec, GST_STATE_PLAYING);
|
gst_element_set_state (dec, GST_STATE_PLAYING);
|
||||||
|
@ -533,7 +560,7 @@ GST_START_TEST (videodecoder_playback_first_frames_not_decoded)
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
guint64 i = 0;
|
guint64 i = 0;
|
||||||
|
|
||||||
setup_videodecodertester ();
|
setup_videodecodertester (NULL, NULL);
|
||||||
|
|
||||||
gst_pad_set_active (mysrcpad, TRUE);
|
gst_pad_set_active (mysrcpad, TRUE);
|
||||||
gst_element_set_state (dec, GST_STATE_PLAYING);
|
gst_element_set_state (dec, GST_STATE_PLAYING);
|
||||||
|
@ -592,7 +619,7 @@ GST_START_TEST (videodecoder_buffer_after_segment)
|
||||||
GstClockTime pos;
|
GstClockTime pos;
|
||||||
GList *iter;
|
GList *iter;
|
||||||
|
|
||||||
setup_videodecodertester ();
|
setup_videodecodertester (NULL, NULL);
|
||||||
|
|
||||||
gst_pad_set_active (mysrcpad, TRUE);
|
gst_pad_set_active (mysrcpad, TRUE);
|
||||||
gst_element_set_state (dec, GST_STATE_PLAYING);
|
gst_element_set_state (dec, GST_STATE_PLAYING);
|
||||||
|
@ -661,7 +688,7 @@ GST_START_TEST (videodecoder_backwards_playback)
|
||||||
guint64 i;
|
guint64 i;
|
||||||
GList *iter;
|
GList *iter;
|
||||||
|
|
||||||
setup_videodecodertester ();
|
setup_videodecodertester (NULL, NULL);
|
||||||
|
|
||||||
gst_pad_set_active (mysrcpad, TRUE);
|
gst_pad_set_active (mysrcpad, TRUE);
|
||||||
gst_element_set_state (dec, GST_STATE_PLAYING);
|
gst_element_set_state (dec, GST_STATE_PLAYING);
|
||||||
|
@ -744,7 +771,7 @@ GST_START_TEST (videodecoder_backwards_buffer_after_segment)
|
||||||
guint64 i;
|
guint64 i;
|
||||||
GstClockTime pos;
|
GstClockTime pos;
|
||||||
|
|
||||||
setup_videodecodertester ();
|
setup_videodecodertester (NULL, NULL);
|
||||||
|
|
||||||
gst_pad_set_active (mysrcpad, TRUE);
|
gst_pad_set_active (mysrcpad, TRUE);
|
||||||
gst_element_set_state (dec, GST_STATE_PLAYING);
|
gst_element_set_state (dec, GST_STATE_PLAYING);
|
||||||
|
@ -817,6 +844,151 @@ GST_START_TEST (videodecoder_backwards_buffer_after_segment)
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
|
||||||
|
GST_START_TEST (videodecoder_query_caps_with_fixed_caps_peer)
|
||||||
|
{
|
||||||
|
GstCaps *caps;
|
||||||
|
GstCaps *filter;
|
||||||
|
GstStructure *structure;
|
||||||
|
gint width, height, fps_n, fps_d;
|
||||||
|
|
||||||
|
setup_videodecodertester (&sinktemplate_restricted, NULL);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
|
fail_unless (gst_structure_get_int (structure, "width", &width));
|
||||||
|
fail_unless (gst_structure_get_int (structure, "height", &height));
|
||||||
|
fail_unless (gst_structure_get_fraction (structure, "framerate", &fps_n,
|
||||||
|
&fps_d));
|
||||||
|
/* match our restricted caps values */
|
||||||
|
fail_unless (width == RESTRICTED_CAPS_WIDTH);
|
||||||
|
fail_unless (height == RESTRICTED_CAPS_HEIGHT);
|
||||||
|
fail_unless (fps_n == RESTRICTED_CAPS_FPS_N);
|
||||||
|
fail_unless (fps_d == RESTRICTED_CAPS_FPS_D);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
filter = gst_caps_new_simple ("video/x-custom-test", "width", G_TYPE_INT,
|
||||||
|
1000, "height", G_TYPE_INT, 1000, "framerate", GST_TYPE_FRACTION,
|
||||||
|
1000, 1, NULL);
|
||||||
|
caps = gst_pad_peer_query_caps (mysrcpad, filter);
|
||||||
|
fail_unless (caps != NULL);
|
||||||
|
fail_unless (gst_caps_is_empty (caps));
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
gst_caps_unref (filter);
|
||||||
|
|
||||||
|
cleanup_videodecodertest ();
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_get_int_range (GstStructure * s, const gchar * field, gint * min_v,
|
||||||
|
gint * max_v)
|
||||||
|
{
|
||||||
|
const GValue *value;
|
||||||
|
|
||||||
|
value = gst_structure_get_value (s, field);
|
||||||
|
fail_unless (value != NULL);
|
||||||
|
fail_unless (GST_VALUE_HOLDS_INT_RANGE (value));
|
||||||
|
|
||||||
|
*min_v = gst_value_get_int_range_min (value);
|
||||||
|
*max_v = gst_value_get_int_range_max (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_get_fraction_range (GstStructure * s, const gchar * field, gint * fps_n_min,
|
||||||
|
gint * fps_d_min, gint * fps_n_max, gint * fps_d_max)
|
||||||
|
{
|
||||||
|
const GValue *value;
|
||||||
|
const GValue *min_v, *max_v;
|
||||||
|
|
||||||
|
value = gst_structure_get_value (s, field);
|
||||||
|
fail_unless (value != NULL);
|
||||||
|
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (value));
|
||||||
|
|
||||||
|
min_v = gst_value_get_fraction_range_min (value);
|
||||||
|
fail_unless (GST_VALUE_HOLDS_FRACTION (min_v));
|
||||||
|
*fps_n_min = gst_value_get_fraction_numerator (min_v);
|
||||||
|
*fps_d_min = gst_value_get_fraction_denominator (min_v);
|
||||||
|
|
||||||
|
max_v = gst_value_get_fraction_range_max (value);
|
||||||
|
fail_unless (GST_VALUE_HOLDS_FRACTION (max_v));
|
||||||
|
*fps_n_max = gst_value_get_fraction_numerator (max_v);
|
||||||
|
*fps_d_max = gst_value_get_fraction_denominator (max_v);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_START_TEST (videodecoder_query_caps_with_range_caps_peer)
|
||||||
|
{
|
||||||
|
GstCaps *caps;
|
||||||
|
GstCaps *filter;
|
||||||
|
GstStructure *structure;
|
||||||
|
gint width, height, fps_n, fps_d;
|
||||||
|
gint width_min, height_min, fps_n_min, fps_d_min;
|
||||||
|
gint width_max, height_max, fps_n_max, fps_d_max;
|
||||||
|
|
||||||
|
setup_videodecodertester (&sinktemplate_with_range, NULL);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
|
_get_int_range (structure, "width", &width_min, &width_max);
|
||||||
|
_get_int_range (structure, "height", &height_min, &height_max);
|
||||||
|
_get_fraction_range (structure, "framerate", &fps_n_min, &fps_d_min,
|
||||||
|
&fps_n_max, &fps_d_max);
|
||||||
|
fail_unless (width_min == 1);
|
||||||
|
fail_unless (width_max == RESTRICTED_CAPS_WIDTH);
|
||||||
|
fail_unless (height_min == 1);
|
||||||
|
fail_unless (height_max == RESTRICTED_CAPS_HEIGHT);
|
||||||
|
fail_unless (fps_n_min == 1);
|
||||||
|
fail_unless (fps_d_min == 1);
|
||||||
|
fail_unless (fps_n_max == RESTRICTED_CAPS_FPS_N);
|
||||||
|
fail_unless (fps_d_max == RESTRICTED_CAPS_FPS_D);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
/* query with a fixed filter */
|
||||||
|
filter = gst_caps_new_simple ("video/x-test-custom", "width", G_TYPE_INT,
|
||||||
|
RESTRICTED_CAPS_WIDTH, "height", G_TYPE_INT, RESTRICTED_CAPS_HEIGHT,
|
||||||
|
"framerate", GST_TYPE_FRACTION, RESTRICTED_CAPS_FPS_N,
|
||||||
|
RESTRICTED_CAPS_FPS_D, NULL);
|
||||||
|
caps = gst_pad_peer_query_caps (mysrcpad, filter);
|
||||||
|
fail_unless (caps != NULL);
|
||||||
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
|
fail_unless (gst_structure_get_int (structure, "width", &width));
|
||||||
|
fail_unless (gst_structure_get_int (structure, "height", &height));
|
||||||
|
fail_unless (gst_structure_get_fraction (structure, "framerate", &fps_n,
|
||||||
|
&fps_d));
|
||||||
|
fail_unless (width == RESTRICTED_CAPS_WIDTH);
|
||||||
|
fail_unless (height == RESTRICTED_CAPS_HEIGHT);
|
||||||
|
fail_unless (fps_n == RESTRICTED_CAPS_FPS_N);
|
||||||
|
fail_unless (fps_d == RESTRICTED_CAPS_FPS_D);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
gst_caps_unref (filter);
|
||||||
|
|
||||||
|
/* query with a fixed filter that will lead to empty result */
|
||||||
|
filter = gst_caps_new_simple ("video/x-test-custom", "width", G_TYPE_INT,
|
||||||
|
1000, "height", G_TYPE_INT, 1000, "framerate", GST_TYPE_FRACTION,
|
||||||
|
1000, 1, NULL);
|
||||||
|
caps = gst_pad_peer_query_caps (mysrcpad, filter);
|
||||||
|
fail_unless (caps != NULL);
|
||||||
|
fail_unless (gst_caps_is_empty (caps));
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
gst_caps_unref (filter);
|
||||||
|
|
||||||
|
cleanup_videodecodertest ();
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
gst_videodecoder_suite (void)
|
gst_videodecoder_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -824,6 +996,10 @@ gst_videodecoder_suite (void)
|
||||||
TCase *tc = tcase_create ("general");
|
TCase *tc = tcase_create ("general");
|
||||||
|
|
||||||
suite_add_tcase (s, tc);
|
suite_add_tcase (s, tc);
|
||||||
|
|
||||||
|
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_playback);
|
tcase_add_test (tc, videodecoder_playback);
|
||||||
tcase_add_test (tc, videodecoder_playback_with_events);
|
tcase_add_test (tc, videodecoder_playback_with_events);
|
||||||
tcase_add_test (tc, videodecoder_playback_first_frames_not_decoded);
|
tcase_add_test (tc, videodecoder_playback_first_frames_not_decoded);
|
||||||
|
|
Loading…
Reference in a new issue