gstreamer/tests/check/elements/adaptive_demux_engine.h
Jan Schmidt 309368bac3 adaptivedemux: Fix tests for delayed pad exposure.
Make the unit tests handle the fact that pads don't appear
immediately. Before, the test assumed pads are exposed before the
internal source element is created, which is no longer true.
2017-02-08 22:59:49 +11:00

202 lines
7.5 KiB
C

/* A generic test engine for elements based upon GstAdaptiveDemux
*
* Copyright (c) <2015> YouView TV Ltd
*
* 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_ADAPTIVE_DEMUX_TEST_ENGINE_H__
#define __GST_ADAPTIVE_DEMUX_TEST_ENGINE_H__
#include <gst/gst.h>
#include <gst/app/gstappsink.h>
#include "test_http_src.h"
G_BEGIN_DECLS
typedef struct _GstAdaptiveDemuxTestEngine GstAdaptiveDemuxTestEngine;
typedef struct _GstAdaptiveDemuxTestOutputStream {
gchar *name;
/* the GstAppSink element getting the data for this stream */
GstAppSink *appsink;
GstPad *pad;
/* the internal pad of adaptivedemux element used to send data to the GstAppSink element */
GstPad *internal_pad;
gulong internal_pad_probe;
/* current segment start offset */
guint64 segment_start;
/* the size received so far on this segment */
guint64 segment_received_size;
/* the total size received so far on this stream, excluding current segment */
guint64 total_received_size;
} GstAdaptiveDemuxTestOutputStream;
/* GstAdaptiveDemuxTestCallbacks: contains various callbacks that can
* be registered by a test. Not all callbacks needs to be configured
* by a test. A callback that is not required by a test must be set
* to NULL.
*/
typedef struct _GstAdaptiveDemuxTestCallbacks
{
/**
* pre_test: called before starting the pipeline
* @engine: #GstAdaptiveDemuxTestEngine
* @user_data: the user_data passed to gst_adaptive_demux_test_run()
*/
void (*pre_test) (GstAdaptiveDemuxTestEngine *engine, gpointer user_data);
/**
* post_test: called after stopping the pipeline.
* @engine: #GstAdaptiveDemuxTestEngine
* @user_data: the user_data passed to gst_adaptive_demux_test_run()
*/
void (*post_test) (GstAdaptiveDemuxTestEngine *engine, gpointer user_data);
/**
* appsink_received_data: called each time AppSink receives data
* @engine: #GstAdaptiveDemuxTestEngine
* @stream: #GstAdaptiveDemuxTestOutputStream
* @buffer: the #GstBuffer that was recevied by #GstAppSink
* @user_data: the user_data passed to gst_adaptive_demux_test_run()
* Returns: #TRUE to continue processing, #FALSE to cause EOS
*
* Can be used by a test to perform additional operations (eg validate
* output data)
*/
gboolean (*appsink_received_data) (GstAdaptiveDemuxTestEngine *engine,
GstAdaptiveDemuxTestOutputStream * stream,
GstBuffer * buffer, gpointer user_data);
/**
* appsink_eos: called each time AppSink receives eos
* @engine: #GstAdaptiveDemuxTestEngine
* @stream: #GstAdaptiveDemuxTestOutputStream
* @user_data: the user_data passed to gst_adaptive_demux_test_run()
*
* Can be used by a test to perform additional operations (eg validate
* output data)
*/
void (*appsink_eos) (GstAdaptiveDemuxTestEngine *engine,
GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data);
/**
* appsink_event: called when an event is received by appsink
* @engine: #GstAdaptiveDemuxTestEngine
* @stream: #GstAdaptiveDemuxTestOutputStream
* @event: the #GstEvent that was pushed in the demuxer pad
* @user_data: the user_data passed to gst_adaptive_demux_test_run()
*
* Can be used by a test to do some checks on the events
*/
void (*appsink_event) (GstAdaptiveDemuxTestEngine *engine,
GstAdaptiveDemuxTestOutputStream * stream,
GstEvent * event, gpointer user_data);
/**
* demux_pad_added: called each time the demux creates a new pad
* @engine: #GstAdaptiveDemuxTestEngine
* @stream: the #GstAdaptiveDemuxTestOutputStream that has been created
* @user_data: the user_data passed to gst_adaptive_demux_test_run()
*/
void (*demux_pad_added) (GstAdaptiveDemuxTestEngine * engine,
GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data);
/**
* demux_pad_removed: called each time the demux removes a pad
* @engine: #GstAdaptiveDemuxTestEngine
* @stream: the #GstAdaptiveDemuxTestOutputStream that will no longer
* be used
* @user_data: the user_data passed to gst_adaptive_demux_test_run()
*/
void (*demux_pad_removed) (GstAdaptiveDemuxTestEngine * engine,
GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data);
/**
* demux_sent_data: called each time the demux sends data to AppSink
* @engine: #GstAdaptiveDemuxTestEngine
* @stream: #GstAdaptiveDemuxTestOutputStream
* @buffer: the #GstBuffer that was sent by demux
* @user_data: the user_data passed to gst_adaptive_demux_test_run()
*/
gboolean (*demux_sent_data) (GstAdaptiveDemuxTestEngine *engine,
GstAdaptiveDemuxTestOutputStream * stream,
GstBuffer * buffer, gpointer user_data);
/**
* demux_sent_event: called each time the demux sends event to AppSink
* @engine: #GstAdaptiveDemuxTestEngine
* @stream: #GstAdaptiveDemuxTestOutputStream
* @event: the #GstEvent that was sent by demux
* @user_data: the user_data passed to gst_adaptive_demux_test_run()
*/
gboolean (*demux_sent_event) (GstAdaptiveDemuxTestEngine *engine,
GstAdaptiveDemuxTestOutputStream * stream,
GstEvent * event, gpointer user_data);
/**
* bus_error_message: called if an error is posted to the bus
* @engine: #GstAdaptiveDemuxTestEngine
* @msg: the #GstMessage that contains the error
* @user_data: the user_data passed to gst_adaptive_demux_test_run()
*
* The callback can decide if this error is expected, or to fail
* the test
*/
void (*bus_error_message)(GstAdaptiveDemuxTestEngine *engine,
GstMessage * msg, gpointer user_data);
} GstAdaptiveDemuxTestCallbacks;
/* structure containing all data used by a test
* Any callback defined by a test will receive this as first parameter
*/
struct _GstAdaptiveDemuxTestEngine
{
GstElement *pipeline;
GstClock *clock;
GstElement *demux;
GstElement *manifest_source;
GMainLoop *loop;
GPtrArray *output_streams; /* GPtrArray<GstAdaptiveDemuxTestOutputStream> */
/* mutex to lock accesses to this structure when data is shared
* between threads */
GMutex lock;
};
/**
* gst_adaptive_demux_test_run:
* @element_name: The name of the demux element (e.g. "dashdemux")
* @manifest_uri: The URI of the manifest to load
* @callbacks: The callbacks to use while the test is in operating
* @user_data: Opaque pointer that is passed to every callback
*
* Creates a pipeline with the specified demux element in it,
* connect a testhttpsrc element to this demux element and
* request manifest_uri. When the demux element adds a new
* pad, the engine will create an AppSink element and attach
* it to this pad.
*
* Information about these pads is collected in
* GstAdaptiveDemuxTestEngine::output_streams
*/
void gst_adaptive_demux_test_run (const gchar * element_name,
const gchar * manifest_uri,
const GstAdaptiveDemuxTestCallbacks * callbacks,
gpointer user_data);
G_END_DECLS
#endif /* __GST_ADAPTIVE_DEMUX_TEST_ENGINE_H__ */