1 /* A generic test engine for elements based upon GstAdaptiveDemux 2 * 3 * Copyright (c) <2015> YouView TV Ltd 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public 16 * License along with this library; if not, write to the 17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21 #ifndef __GST_ADAPTIVE_DEMUX_TEST_ENGINE_H__ 22 #define __GST_ADAPTIVE_DEMUX_TEST_ENGINE_H__ 23 24 #include <gst/gst.h> 25 #include <gst/app/gstappsink.h> 26 #include "test_http_src.h" 27 28 G_BEGIN_DECLS 29 30 typedef struct _GstAdaptiveDemuxTestEngine GstAdaptiveDemuxTestEngine; 31 32 typedef struct _GstAdaptiveDemuxTestOutputStream { 33 gchar *name; 34 35 /* the GstAppSink element getting the data for this stream */ 36 GstAppSink *appsink; 37 GstPad *pad; 38 /* the internal pad of adaptivedemux element used to send data to the GstAppSink element */ 39 GstPad *internal_pad; 40 gulong internal_pad_probe; 41 /* current segment start offset */ 42 guint64 segment_start; 43 /* the size received so far on this segment */ 44 guint64 segment_received_size; 45 /* the total size received so far on this stream, excluding current segment */ 46 guint64 total_received_size; 47 } GstAdaptiveDemuxTestOutputStream; 48 49 /* GstAdaptiveDemuxTestCallbacks: contains various callbacks that can 50 * be registered by a test. Not all callbacks needs to be configured 51 * by a test. A callback that is not required by a test must be set 52 * to NULL. 53 */ 54 typedef struct _GstAdaptiveDemuxTestCallbacks 55 { 56 /** 57 * pre_test: called before starting the pipeline 58 * @engine: #GstAdaptiveDemuxTestEngine 59 * @user_data: the user_data passed to gst_adaptive_demux_test_run() 60 */ 61 void (*pre_test) (GstAdaptiveDemuxTestEngine *engine, gpointer user_data); 62 63 /** 64 * post_test: called after stopping the pipeline. 65 * @engine: #GstAdaptiveDemuxTestEngine 66 * @user_data: the user_data passed to gst_adaptive_demux_test_run() 67 */ 68 void (*post_test) (GstAdaptiveDemuxTestEngine *engine, gpointer user_data); 69 70 /** 71 * appsink_received_data: called each time AppSink receives data 72 * @engine: #GstAdaptiveDemuxTestEngine 73 * @stream: #GstAdaptiveDemuxTestOutputStream 74 * @buffer: the #GstBuffer that was recevied by #GstAppSink 75 * @user_data: the user_data passed to gst_adaptive_demux_test_run() 76 * Returns: %TRUE to continue processing, %FALSE to cause EOS 77 * 78 * Can be used by a test to perform additional operations (eg validate 79 * output data) 80 */ 81 gboolean (*appsink_received_data) (GstAdaptiveDemuxTestEngine *engine, 82 GstAdaptiveDemuxTestOutputStream * stream, 83 GstBuffer * buffer, gpointer user_data); 84 85 /** 86 * appsink_eos: called each time AppSink receives eos 87 * @engine: #GstAdaptiveDemuxTestEngine 88 * @stream: #GstAdaptiveDemuxTestOutputStream 89 * @user_data: the user_data passed to gst_adaptive_demux_test_run() 90 * 91 * Can be used by a test to perform additional operations (eg validate 92 * output data) 93 */ 94 void (*appsink_eos) (GstAdaptiveDemuxTestEngine *engine, 95 GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data); 96 97 /** 98 * appsink_event: called when an event is received by appsink 99 * @engine: #GstAdaptiveDemuxTestEngine 100 * @stream: #GstAdaptiveDemuxTestOutputStream 101 * @event: the #GstEvent that was pushed in the demuxer pad 102 * @user_data: the user_data passed to gst_adaptive_demux_test_run() 103 * 104 * Can be used by a test to do some checks on the events 105 */ 106 void (*appsink_event) (GstAdaptiveDemuxTestEngine *engine, 107 GstAdaptiveDemuxTestOutputStream * stream, 108 GstEvent * event, gpointer user_data); 109 110 /** 111 * demux_pad_added: called each time the demux creates a new pad 112 * @engine: #GstAdaptiveDemuxTestEngine 113 * @stream: the #GstAdaptiveDemuxTestOutputStream that has been created 114 * @user_data: the user_data passed to gst_adaptive_demux_test_run() 115 */ 116 void (*demux_pad_added) (GstAdaptiveDemuxTestEngine * engine, 117 GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data); 118 119 /** 120 * demux_pad_removed: called each time the demux removes a pad 121 * @engine: #GstAdaptiveDemuxTestEngine 122 * @stream: the #GstAdaptiveDemuxTestOutputStream that will no longer 123 * be used 124 * @user_data: the user_data passed to gst_adaptive_demux_test_run() 125 */ 126 void (*demux_pad_removed) (GstAdaptiveDemuxTestEngine * engine, 127 GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data); 128 129 /** 130 * demux_sent_data: called each time the demux sends data to AppSink 131 * @engine: #GstAdaptiveDemuxTestEngine 132 * @stream: #GstAdaptiveDemuxTestOutputStream 133 * @buffer: the #GstBuffer that was sent by demux 134 * @user_data: the user_data passed to gst_adaptive_demux_test_run() 135 */ 136 gboolean (*demux_sent_data) (GstAdaptiveDemuxTestEngine *engine, 137 GstAdaptiveDemuxTestOutputStream * stream, 138 GstBuffer * buffer, gpointer user_data); 139 140 /** 141 * demux_sent_event: called each time the demux sends event to AppSink 142 * @engine: #GstAdaptiveDemuxTestEngine 143 * @stream: #GstAdaptiveDemuxTestOutputStream 144 * @event: the #GstEvent that was sent by demux 145 * @user_data: the user_data passed to gst_adaptive_demux_test_run() 146 */ 147 gboolean (*demux_sent_event) (GstAdaptiveDemuxTestEngine *engine, 148 GstAdaptiveDemuxTestOutputStream * stream, 149 GstEvent * event, gpointer user_data); 150 151 /** 152 * bus_error_message: called if an error is posted to the bus 153 * @engine: #GstAdaptiveDemuxTestEngine 154 * @msg: the #GstMessage that contains the error 155 * @user_data: the user_data passed to gst_adaptive_demux_test_run() 156 * 157 * The callback can decide if this error is expected, or to fail 158 * the test 159 */ 160 void (*bus_error_message)(GstAdaptiveDemuxTestEngine *engine, 161 GstMessage * msg, gpointer user_data); 162 } GstAdaptiveDemuxTestCallbacks; 163 164 /* structure containing all data used by a test 165 * Any callback defined by a test will receive this as first parameter 166 */ 167 struct _GstAdaptiveDemuxTestEngine 168 { 169 GstElement *pipeline; 170 GstClock *clock; 171 GstElement *demux; 172 GstElement *manifest_source; 173 GMainLoop *loop; 174 GPtrArray *output_streams; /* GPtrArray<GstAdaptiveDemuxTestOutputStream> */ 175 /* mutex to lock accesses to this structure when data is shared 176 * between threads */ 177 GMutex lock; 178 }; 179 180 /** 181 * gst_adaptive_demux_test_run: 182 * @element_name: The name of the demux element (e.g. "dashdemux") 183 * @manifest_uri: The URI of the manifest to load 184 * @callbacks: The callbacks to use while the test is in operating 185 * @user_data: Opaque pointer that is passed to every callback 186 * 187 * Creates a pipeline with the specified demux element in it, 188 * connect a testhttpsrc element to this demux element and 189 * request manifest_uri. When the demux element adds a new 190 * pad, the engine will create an AppSink element and attach 191 * it to this pad. 192 * 193 * Information about these pads is collected in 194 * GstAdaptiveDemuxTestEngine::output_streams 195 */ 196 void gst_adaptive_demux_test_run (const gchar * element_name, 197 const gchar * manifest_uri, 198 const GstAdaptiveDemuxTestCallbacks * callbacks, 199 gpointer user_data); 200 201 G_END_DECLS 202 #endif /* __GST_ADAPTIVE_DEMUX_TEST_ENGINE_H__ */ 203