summaryrefslogtreecommitdiff
path: root/tests/check/elements/adaptive_demux_common.h
blob: f830387cd40354c8253900d2e0f2974ccc35d173 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/* A set of utility functions that are common between 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_COMMON_TEST_H__
#define __GST_ADAPTIVE_DEMUX_COMMON_TEST_H__

#include <gst/gst.h>
#include "adaptive_demux_engine.h"

G_BEGIN_DECLS

#define GST_TYPE_ADAPTIVE_DEMUX_TEST_CASE \
  (gst_adaptive_demux_test_case_get_type())
#define GST_ADAPTIVE_DEMUX_TEST_CASE(obj) \
  (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_ADAPTIVE_DEMUX_TEST_CASE, GstAdaptiveDemuxTestCase))
#define GST_ADAPTIVE_DEMUX_TEST_CASE_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_ADAPTIVE_DEMUX_TEST_CASE, GstAdaptiveDemuxTestCaseClass))
#define GST_ADAPTIVE_DEMUX_TEST_CASE_GET_CLASS(obj) \
  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ADAPTIVE_DEMUX_TEST_CASE, GstAdaptiveDemuxTestCaseClass))
#define GST_IS_ADAPTIVE_DEMUX_TEST_CASE(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_ADAPTIVE_DEMUX_TEST_CASE))
#define GST_IS_ADAPTIVE_DEMUX_TEST_CASE_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_ADAPTIVE_DEMUX_TEST_CASE))

/**
 * TestTaskState:
 * The seek test uses a separate task to perform the seek operation.
 * After starting the task, the caller blocks until the seek task
 * flushes the AppSink and changes the GstFakeSoupHTTPSrc element state from
 * PLAYING to PAUSED.
 * When that event is detected, the caller is allowed to resume.
 * Any data that will be sent to AppSink after resume will be rejected because
 * AppSink is in flushing mode.
 */
typedef enum
{
  TEST_TASK_STATE_NOT_STARTED,
  TEST_TASK_STATE_WAITING_FOR_TESTSRC_STATE_CHANGE,
  TEST_TASK_STATE_EXITING,
} TestTaskState;

/**
 * GstAdaptiveDemuxTestExpectedOutput:
 * Structure used to store output stream related data.
 * It is used by the test during output validation.
 * The fields are set by the testcase function prior
 * to starting the test.
 */
typedef struct _GstAdaptiveDemuxTestExpectedOutput
{
  /* the name of the demux src pad generating this stream */
  const char *name;
  /* the expected size on this stream */
  guint64 expected_size;
  /* the expected data on this stream (optional) */
  const guint8* expected_data;

  GstSegment post_seek_segment;
  gboolean segment_verification_needed;
} GstAdaptiveDemuxTestExpectedOutput;

typedef struct _GstAdaptiveDemuxTestCaseClass GstAdaptiveDemuxTestCaseClass;
typedef struct _GstAdaptiveDemuxTestCase
{
  GObject parent;

  /* output data used to validate the test
   * list of GstAdaptiveDemuxTestExpectedOutput, one entry per stream
   */
  GList *output_streams; /*GList<GstAdaptiveDemuxTestExpectedOutput>*/

  /* the number of streams that finished.
   * Main thread will stop the pipeline when all streams are finished
   * (i.e. count_of_finished_streams == g_list_length(output_streams) )
   */
  guint count_of_finished_streams;

  /* taskTesk... is a set of variables that can be used by a test
   * that needs to perform operations from another thread
   * For example, it is used by the seek test to perform the seek
   * operation
   */
  GstTask *test_task;
  GRecMutex test_task_lock;
  TestTaskState test_task_state;
  GMutex test_task_state_lock;
  GCond test_task_state_cond;

  /* seek test will wait for this amount of bytes to be sent by 
   * demux to AppSink before triggering a seek request
   */
  guint64 threshold_for_seek;
  GstEvent *seek_event;
  gboolean seeked;

  gpointer signal_context;
} GstAdaptiveDemuxTestCase;

/* high-level unit test functions */

/**
 * gst_adaptive_demux_test_setup:
 * Causes the test HTTP src element to be registered
 */
void gst_adaptive_demux_test_setup (void);

void gst_adaptive_demux_test_teardown (void);

GType gst_adaptive_demux_test_case_get_type (void);

/**
 * gst_adaptive_demux_test_case_new: creates new #GstAdaptiveDemuxTestCase
 * object. Use #g_object_unref to free.
 */
GstAdaptiveDemuxTestCase * gst_adaptive_demux_test_case_new (void) G_GNUC_MALLOC;

/**
 * gst_adaptive_demux_test_seek: test that element supports seeking
 * @element_name: The name of the demux element (e.g. "dashdemux")
 * @manifest_uri: The URI of the manifest to load
 * @testData: The #GstAdaptiveDemuxTestCase that the test expects the
 * demux element to produce.
 * 
 * Creates a pipeline and starts it. Once data is flowing, request a
 * seek to almost the start of the stream.
 */
void gst_adaptive_demux_test_seek (const gchar * element_name,
    const gchar * manifest_uri,
    GstAdaptiveDemuxTestCase *testData);

/* Utility functions for use within a unit test */

/**
 * gst_adaptive_demux_test_check_size_of_received_data:
 * @engine: The #GstAdaptiveDemuxTestEngine that caused this callback
 * @stream: The #GstAdaptiveDemuxTestOutputStream that caused this callback
 * @user_data: A pointer to a #GstAdaptiveDemuxTestCase object
 *
 * This function can be used as an EOS callback to check that the
 * size of received data equals expected_size. It should be used with
 * a test that expects the entire file to be downloaded.
 */
void gst_adaptive_demux_test_check_size_of_received_data(
    GstAdaptiveDemuxTestEngine *engine,
    GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data);

/**
 * gst_adaptive_demux_test_download_error_size_of_received_data:
 * @engine: The #GstAdaptiveDemuxTestEngine that caused this callback
 * @stream: The #GstAdaptiveDemuxTestOutputStream that caused this callback
 * @user_data: A pointer to a #GstAdaptiveDemuxTestCase object
 *
 * This function can be used as an EOS callback to check that the
 * size of received data is >0 && <expected_size. It should be used with
 * a test that does not expect the entire file to be downloaded.
 */
void gst_adaptive_demux_test_download_error_size_of_received_data (
    GstAdaptiveDemuxTestEngine *engine,
    GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data);

/**
 * gst_adaptive_demux_test_check_received_data:
 * @engine: The #GstAdaptiveDemuxTestEngine that caused this callback
 * @stream: The #GstAdaptiveDemuxTestOutputStream that caused this callback
 * @buffer: The #GstBuffer containing the data to check
 * @user_data: A pointer to a #GstAdaptiveDemuxTestCase object
 * Returns: TRUE if buffer contains the expected data.
 *
 * This function can be used as an appSinkGotData callback, to check
 * that the contents of the received data matches the expected data
 */
gboolean gst_adaptive_demux_test_check_received_data (
    GstAdaptiveDemuxTestEngine *engine,
    GstAdaptiveDemuxTestOutputStream * stream,
    GstBuffer * buffer,
    gpointer user_data);

/**
 * gst_adaptive_demux_test_find_test_data_by_stream:
 * @testData: The #GstAdaptiveDemuxTestCase object that contains the
 * output_streams list to search
 * @stream: the #GstAdaptiveDemuxTestOutputStream to search for
 * @index: (out) (allow none) the index of the entry in output_streams
 * Returns: The #GstAdaptiveDemuxTestExpectedOutput that matches @stream, or
 * %NULL if not found
 *
 * Search the list of output test data for the entry that matches stream.
 */
GstAdaptiveDemuxTestExpectedOutput * gst_adaptive_demux_test_find_test_data_by_stream (
    GstAdaptiveDemuxTestCase * testData,
    GstAdaptiveDemuxTestOutputStream * stream,
    guint * index);

G_END_DECLS
#endif /* __GST_ADAPTIVE_DEMUX_COMMON_TEST_H__ */