2015-10-09 13:10:52 +00:00
/* GStreamer unit test for MPEG-DASH
*
* 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 .
*/
# include <gst/check/gstcheck.h>
2015-11-10 13:13:35 +00:00
# include "adaptive_demux_common.h"
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
# define DEMUX_ELEMENT_NAME "dashdemux"
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
# define COPY_OUTPUT_TEST_DATA(outputTestData,testData) do { \
guint otdPos , otdLen = sizeof ( ( outputTestData ) ) / sizeof ( ( outputTestData ) [ 0 ] ) ; \
for ( otdPos = 0 ; otdPos < otdLen ; + + otdPos ) { \
( testData ) - > output_streams = g_list_append ( ( testData ) - > output_streams , & ( outputTestData ) [ otdPos ] ) ; \
} \
} while ( 0 )
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
typedef struct _GstDashDemuxTestInputData
2015-10-09 13:10:52 +00:00
{
2015-11-10 13:13:35 +00:00
const gchar * uri ;
const guint8 * payload ;
guint64 size ;
} GstDashDemuxTestInputData ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
static gboolean
gst_dashdemux_http_src_start ( GstTestHTTPSrc * src ,
const gchar * uri , GstTestHTTPSrcInput * input_data , gpointer user_data )
{
const GstDashDemuxTestInputData * input =
( const GstDashDemuxTestInputData * ) user_data ;
for ( guint i = 0 ; input [ i ] . uri ; + + i ) {
if ( strcmp ( input [ i ] . uri , uri ) = = 0 ) {
input_data - > context = ( gpointer ) & input [ i ] ;
input_data - > size = input [ i ] . size ;
if ( input [ i ] . size = = 0 )
input_data - > size = strlen ( ( gchar * ) input [ i ] . payload ) ;
return TRUE ;
2015-10-09 13:10:52 +00:00
}
}
2015-11-10 13:13:35 +00:00
return FALSE ;
2015-10-09 13:10:52 +00:00
}
static GstFlowReturn
2015-11-10 13:13:35 +00:00
gst_dashdemux_http_src_create ( GstTestHTTPSrc * src ,
guint64 offset ,
guint length , GstBuffer * * retbuf , gpointer context , gpointer user_data )
2015-10-09 13:10:52 +00:00
{
2015-11-10 13:13:35 +00:00
/* const GstDashDemuxTestInputData *input =
( const GstDashDemuxTestInputData * ) user_data ; */
const GstDashDemuxTestInputData * input =
( const GstDashDemuxTestInputData * ) context ;
GstBuffer * buf ;
2015-10-20 14:46:36 +00:00
2015-11-10 13:13:35 +00:00
buf = gst_buffer_new_allocate ( NULL , length , NULL ) ;
fail_if ( buf = = NULL , " Not enough memory to allocate buffer " ) ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
if ( input - > payload ) {
gst_buffer_fill ( buf , 0 , input - > payload + offset , length ) ;
2015-10-09 13:10:52 +00:00
} else {
2015-11-10 13:13:35 +00:00
GstMapInfo info ;
guint pattern ;
2015-10-20 14:46:36 +00:00
2015-11-10 13:13:35 +00:00
pattern = offset - offset % sizeof ( pattern ) ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
gst_buffer_map ( buf , & info , GST_MAP_WRITE ) ;
for ( guint64 i = 0 ; i < length ; + + i ) {
gchar pattern_byte_to_write = ( offset + i ) % sizeof ( pattern ) ;
if ( pattern_byte_to_write = = 0 ) {
pattern = offset + i ;
}
info . data [ i ] = ( pattern > > ( pattern_byte_to_write * 8 ) ) & 0xFF ;
2015-10-09 13:10:52 +00:00
}
2015-11-10 13:13:35 +00:00
gst_buffer_unmap ( buf , & info ) ;
2015-10-09 13:10:52 +00:00
}
2015-11-10 13:13:35 +00:00
* retbuf = buf ;
return GST_FLOW_OK ;
2015-10-09 13:10:52 +00:00
}
2015-11-10 13:13:35 +00:00
/******************** Test specific code starts here **************************/
2015-10-09 13:10:52 +00:00
/*
* Test an mpd with an audio and a video stream
*
*/
GST_START_TEST ( simpleTest )
{
const gchar * mpd =
" <?xml version= \" 1.0 \" encoding= \" utf-8 \" ?> "
" <MPD xmlns:xsi= \" http://www.w3.org/2001/XMLSchema-instance \" "
" xmlns= \" urn:mpeg:DASH:schema:MPD:2011 \" "
" xsi:schemaLocation= \" urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd \" "
" xmlns:yt= \" http://youtube.com/yt/2012/10/10 \" "
" profiles= \" urn:mpeg:dash:profile:isoff-on-demand:2011 \" "
" type= \" static \" "
" minBufferTime= \" PT1.500S \" "
" mediaPresentationDuration= \" PT135.743S \" > "
" <Period> "
" <AdaptationSet mimeType= \" audio/webm \" "
" subsegmentAlignment= \" true \" > "
" <Representation id= \" 171 \" "
" codecs= \" vorbis \" "
" audioSamplingRate= \" 44100 \" "
" startWithSAP= \" 1 \" "
" bandwidth= \" 129553 \" > "
" <AudioChannelConfiguration "
" schemeIdUri= \" urn:mpeg:dash:23003:3:audio_channel_configuration:2011 \" "
" value= \" 2 \" /> "
" <BaseURL>audio.webm</BaseURL> "
" <SegmentBase indexRange= \" 4452-4686 \" "
" indexRangeExact= \" true \" > "
" <Initialization range= \" 0-4451 \" /> "
" </SegmentBase> "
" </Representation> "
" </AdaptationSet> "
" <AdaptationSet mimeType= \" video/webm \" "
" subsegmentAlignment= \" true \" > "
" <Representation id= \" 242 \" "
" codecs= \" vp9 \" "
" width= \" 426 \" "
" height= \" 240 \" "
" startWithSAP= \" 1 \" "
" bandwidth= \" 490208 \" > "
" <BaseURL>video.webm</BaseURL> "
" <SegmentBase indexRange= \" 234-682 \" "
" indexRangeExact= \" true \" > "
" <Initialization range= \" 0-233 \" /> "
" </SegmentBase> "
" </Representation></AdaptationSet></Period></MPD> " ;
2015-11-10 13:13:35 +00:00
GstDashDemuxTestInputData inputTestData [ ] = {
{ " http://unit.test/test.mpd " , ( guint8 * ) mpd , 0 } ,
2015-10-09 13:10:52 +00:00
{ " http://unit.test/audio.webm " , NULL , 5000 } ,
{ " http://unit.test/video.webm " , NULL , 9000 } ,
{ NULL , NULL , 0 } ,
} ;
2015-11-10 13:13:35 +00:00
GstTestHTTPSrcCallbacks http_src_callbacks = { 0 } ;
GstAdaptiveDemuxTestExpectedOutput outputTestData [ ] = {
2015-10-09 13:10:52 +00:00
{ " audio_00 " , 5000 , NULL } ,
2015-11-10 13:13:35 +00:00
{ " video_00 " , 9000 , NULL }
2015-10-09 13:10:52 +00:00
} ;
2015-11-10 13:13:35 +00:00
GstAdaptiveDemuxTestCallbacks test_callbacks = { 0 } ;
GstAdaptiveDemuxTestCase * testData ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
testData = gst_adaptive_demux_test_case_new ( ) ;
http_src_callbacks . src_start = gst_dashdemux_http_src_start ;
http_src_callbacks . src_create = gst_dashdemux_http_src_create ;
gst_test_http_src_install_callbacks ( & http_src_callbacks , inputTestData ) ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
COPY_OUTPUT_TEST_DATA ( outputTestData , testData ) ;
test_callbacks . appsink_received_data =
gst_adaptive_demux_test_check_received_data ;
test_callbacks . appsink_eos =
gst_adaptive_demux_test_check_size_of_received_data ;
gst_adaptive_demux_test_run ( DEMUX_ELEMENT_NAME , " http://unit.test/test.mpd " ,
& test_callbacks , testData ) ;
g_object_unref ( testData ) ;
2015-10-09 13:10:52 +00:00
}
GST_END_TEST ;
/*
* Test an mpd with 2 periods
*
*/
GST_START_TEST ( testTwoPeriods )
{
const gchar * mpd =
" <?xml version= \" 1.0 \" encoding= \" utf-8 \" ?> "
" <MPD xmlns:xsi= \" http://www.w3.org/2001/XMLSchema-instance \" "
" xmlns= \" urn:mpeg:DASH:schema:MPD:2011 \" "
" xsi:schemaLocation= \" urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd \" "
" xmlns:yt= \" http://youtube.com/yt/2012/10/10 \" "
" profiles= \" urn:mpeg:dash:profile:isoff-on-demand:2011 \" "
" type= \" static \" "
" minBufferTime= \" PT1.500S \" "
" mediaPresentationDuration= \" PT300S \" > "
" <Period id= \" Period0 \" duration= \" PT0.1S \" > "
" <AdaptationSet mimeType= \" audio/webm \" "
" subsegmentAlignment= \" true \" > "
" <Representation id= \" 171 \" "
" codecs= \" vorbis \" "
" audioSamplingRate= \" 44100 \" "
" startWithSAP= \" 1 \" "
" bandwidth= \" 129553 \" > "
" <AudioChannelConfiguration "
" schemeIdUri= \" urn:mpeg:dash:23003:3:audio_channel_configuration:2011 \" "
" value= \" 2 \" /> "
" <BaseURL>audio1.webm</BaseURL> "
" <SegmentBase indexRange= \" 4452-4686 \" "
" indexRangeExact= \" true \" > "
" <Initialization range= \" 0-4451 \" /> "
" </SegmentBase> "
" </Representation> "
" </AdaptationSet> "
" <AdaptationSet mimeType= \" video/webm \" "
" subsegmentAlignment= \" true \" > "
" <Representation id= \" 242 \" "
" codecs= \" vp9 \" "
" width= \" 426 \" "
" height= \" 240 \" "
" startWithSAP= \" 1 \" "
" bandwidth= \" 490208 \" > "
" <BaseURL>video1.webm</BaseURL> "
" <SegmentBase indexRange= \" 234-682 \" "
" indexRangeExact= \" true \" > "
" <Initialization range= \" 0-233 \" /> "
" </SegmentBase> "
" </Representation> "
" </AdaptationSet> "
" </Period> "
" <Period> "
" <AdaptationSet mimeType= \" audio/webm \" "
" subsegmentAlignment= \" true \" > "
" <Representation id= \" 171 \" "
" codecs= \" vorbis \" "
" audioSamplingRate= \" 44100 \" "
" startWithSAP= \" 1 \" "
" bandwidth= \" 129553 \" > "
" <AudioChannelConfiguration "
" schemeIdUri= \" urn:mpeg:dash:23003:3:audio_channel_configuration:2011 \" "
" value= \" 2 \" /> "
" <BaseURL>audio2.webm</BaseURL> "
" <SegmentBase indexRange= \" 4452-4686 \" "
" indexRangeExact= \" true \" > "
" <Initialization range= \" 0-4451 \" /> "
" </SegmentBase> "
" </Representation> "
" </AdaptationSet> "
" <AdaptationSet mimeType= \" video/webm \" "
" subsegmentAlignment= \" true \" > "
" <Representation id= \" 242 \" "
" codecs= \" vp9 \" "
" width= \" 426 \" "
" height= \" 240 \" "
" startWithSAP= \" 1 \" "
" bandwidth= \" 490208 \" > "
" <BaseURL>video2.webm</BaseURL> "
" <SegmentBase indexRange= \" 234-682 \" "
" indexRangeExact= \" true \" > "
" <Initialization range= \" 0-233 \" /> "
" </SegmentBase> "
" </Representation></AdaptationSet></Period></MPD> " ;
2015-11-10 13:13:35 +00:00
GstDashDemuxTestInputData inputTestData [ ] = {
{ " http://unit.test/test.mpd " , ( guint8 * ) mpd , 0 } ,
2015-10-09 13:10:52 +00:00
{ " http://unit.test/audio1.webm " , NULL , 5001 } ,
{ " http://unit.test/video1.webm " , NULL , 9001 } ,
{ " http://unit.test/audio2.webm " , NULL , 5002 } ,
{ " http://unit.test/video2.webm " , NULL , 9002 } ,
{ NULL , NULL , 0 } ,
} ;
2015-11-10 13:13:35 +00:00
GstTestHTTPSrcCallbacks http_src_callbacks = { 0 } ;
GstAdaptiveDemuxTestExpectedOutput outputTestData [ ] = {
2015-10-09 13:10:52 +00:00
{ " audio_00 " , 5001 , NULL } ,
{ " video_00 " , 9001 , NULL } ,
{ " audio_01 " , 5002 , NULL } ,
{ " video_01 " , 9002 , NULL } ,
} ;
2015-11-10 13:13:35 +00:00
GstAdaptiveDemuxTestCallbacks test_callbacks = { 0 } ;
GstAdaptiveDemuxTestCase * testData ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
testData = gst_adaptive_demux_test_case_new ( ) ;
http_src_callbacks . src_start = gst_dashdemux_http_src_start ;
http_src_callbacks . src_create = gst_dashdemux_http_src_create ;
COPY_OUTPUT_TEST_DATA ( outputTestData , testData ) ;
test_callbacks . appsink_received_data =
gst_adaptive_demux_test_check_received_data ;
test_callbacks . appsink_eos =
gst_adaptive_demux_test_check_size_of_received_data ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
gst_test_http_src_install_callbacks ( & http_src_callbacks , inputTestData ) ;
gst_adaptive_demux_test_run ( DEMUX_ELEMENT_NAME ,
" http://unit.test/test.mpd " , & test_callbacks , testData ) ;
gst_object_unref ( testData ) ;
2015-10-09 13:10:52 +00:00
}
GST_END_TEST ;
/* test setting a property on an object */
# define test_int_prop(object, name, value) \
do \
{ \
int val = value ; \
int val_after ; \
g_object_set ( object , name , val , NULL ) ; \
g_object_get ( object , name , & val_after , NULL ) ; \
fail_unless ( val_after = = val , " property check failed for %s: set to %d, but got %d " , \
name , val , val_after ) ; \
} while ( 0 )
# define test_float_prop(object, name, value) \
do \
{ \
float val = value ; \
float val_after ; \
g_object_set ( object , name , val , NULL ) ; \
g_object_get ( object , name , & val_after , NULL ) ; \
fail_unless ( val_after = = val , " property check failed for %s: set to %f, but got %f " , \
name , val , val_after ) ; \
} while ( 0 )
/* test setting an invalid value for a property on an object.
* Expect an assert and the property to remain unchanged
*/
# define test_invalid_int_prop(object, name, value) \
do \
{ \
int val_before ; \
int val_after ; \
int val = value ; \
g_object_get ( object , name , & val_before , NULL ) ; \
ASSERT_WARNING ( g_object_set ( object , name , val , NULL ) ) ; \
g_object_get ( object , name , & val_after , NULL ) ; \
fail_unless ( val_after = = val_before , " property check failed for %s: before %d, after %d " , \
name , val_before , val_after ) ; \
} while ( 0 )
# define test_invalid_float_prop(object, name, value) \
do \
{ \
float val_before ; \
float val_after ; \
float val = value ; \
g_object_get ( object , name , & val_before , NULL ) ; \
ASSERT_WARNING ( g_object_set ( object , name , val , NULL ) ) ; \
g_object_get ( object , name , & val_after , NULL ) ; \
fail_unless ( val_after = = val_before , " property check failed for %s: before %f, after %f " , \
name , val_before , val_after ) ; \
} while ( 0 )
static void
2015-11-10 13:13:35 +00:00
setAndTestDashParams ( GstAdaptiveDemuxTestEngine * engine , gpointer user_data )
2015-10-09 13:10:52 +00:00
{
2015-11-10 13:13:35 +00:00
/* GstAdaptiveDemuxTestCase * testData = (GstAdaptiveDemuxTestCase*)user_data; */
GObject * dashdemux = G_OBJECT ( engine - > demux ) ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
test_int_prop ( dashdemux , " connection-speed " , 1000 ) ;
test_invalid_int_prop ( dashdemux , " connection-speed " , 4294967 + 1 ) ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
test_float_prop ( dashdemux , " bitrate-limit " , 1 ) ;
test_invalid_float_prop ( dashdemux , " bitrate-limit " , 2.1 ) ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
test_int_prop ( dashdemux , " max-buffering-time " , 15 ) ;
test_invalid_int_prop ( dashdemux , " max-buffering-time " , 1 ) ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
test_float_prop ( dashdemux , " bandwidth-usage " , 0.5 ) ;
test_invalid_float_prop ( dashdemux , " bandwidth-usage " , 2 ) ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
test_int_prop ( dashdemux , " max-bitrate " , 1000 ) ;
test_invalid_int_prop ( dashdemux , " max-bitrate " , 10 ) ;
2015-10-09 13:10:52 +00:00
}
/*
* Test setting parameters
*
*/
GST_START_TEST ( testParameters )
{
const gchar * mpd =
" <?xml version= \" 1.0 \" encoding= \" utf-8 \" ?> "
" <MPD xmlns:xsi= \" http://www.w3.org/2001/XMLSchema-instance \" "
" xmlns= \" urn:mpeg:DASH:schema:MPD:2011 \" "
" xsi:schemaLocation= \" urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd \" "
" xmlns:yt= \" http://youtube.com/yt/2012/10/10 \" "
" profiles= \" urn:mpeg:dash:profile:isoff-on-demand:2011 \" "
" type= \" static \" "
" minBufferTime= \" PT1.500S \" "
" mediaPresentationDuration= \" PT135.743S \" > "
" <Period> "
" <AdaptationSet mimeType= \" audio/webm \" "
" subsegmentAlignment= \" true \" > "
" <Representation id= \" 171 \" "
" codecs= \" vorbis \" "
" audioSamplingRate= \" 44100 \" "
" startWithSAP= \" 1 \" "
" bandwidth= \" 129553 \" > "
" <AudioChannelConfiguration "
" schemeIdUri= \" urn:mpeg:dash:23003:3:audio_channel_configuration:2011 \" "
" value= \" 2 \" /> "
" <BaseURL>audio.webm</BaseURL> "
" <SegmentBase indexRange= \" 4452-4686 \" "
" indexRangeExact= \" true \" > "
" <Initialization range= \" 0-4451 \" /> "
" </SegmentBase> "
" </Representation></AdaptationSet></Period></MPD> " ;
2015-11-10 13:13:35 +00:00
GstDashDemuxTestInputData inputTestData [ ] = {
{ " http://unit.test/test.mpd " , ( guint8 * ) mpd , 0 } ,
2015-10-09 13:10:52 +00:00
{ " http://unit.test/audio.webm " , NULL , 5000 } ,
{ NULL , NULL , 0 } ,
} ;
2015-11-10 13:13:35 +00:00
GstTestHTTPSrcCallbacks http_src_callbacks = { 0 } ;
GstAdaptiveDemuxTestExpectedOutput outputTestData [ ] = {
2015-10-09 13:10:52 +00:00
{ " audio_00 " , 5000 , NULL } ,
} ;
2015-11-10 13:13:35 +00:00
GstAdaptiveDemuxTestCallbacks test_callbacks = { 0 } ;
GstAdaptiveDemuxTestCase * testData ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
testData = gst_adaptive_demux_test_case_new ( ) ;
http_src_callbacks . src_start = gst_dashdemux_http_src_start ;
http_src_callbacks . src_create = gst_dashdemux_http_src_create ;
COPY_OUTPUT_TEST_DATA ( outputTestData , testData ) ;
test_callbacks . pre_test = setAndTestDashParams ;
test_callbacks . appsink_received_data =
gst_adaptive_demux_test_check_received_data ;
test_callbacks . appsink_eos =
gst_adaptive_demux_test_check_size_of_received_data ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
gst_test_http_src_install_callbacks ( & http_src_callbacks , inputTestData ) ;
gst_adaptive_demux_test_run ( DEMUX_ELEMENT_NAME , " http://unit.test/test.mpd " ,
& test_callbacks , testData ) ;
gst_object_unref ( testData ) ;
2015-10-09 13:10:52 +00:00
}
GST_END_TEST ;
/*
* Test seeking
*
*/
GST_START_TEST ( testSeek )
{
const gchar * mpd =
" <?xml version= \" 1.0 \" encoding= \" utf-8 \" ?> "
" <MPD xmlns:xsi= \" http://www.w3.org/2001/XMLSchema-instance \" "
" xmlns= \" urn:mpeg:DASH:schema:MPD:2011 \" "
" xsi:schemaLocation= \" urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd \" "
" xmlns:yt= \" http://youtube.com/yt/2012/10/10 \" "
" profiles= \" urn:mpeg:dash:profile:isoff-on-demand:2011 \" "
" type= \" static \" "
" minBufferTime= \" PT1.500S \" "
" mediaPresentationDuration= \" PT135.743S \" > "
" <Period> "
" <AdaptationSet mimeType= \" audio/webm \" "
" subsegmentAlignment= \" true \" > "
" <Representation id= \" 171 \" "
" codecs= \" vorbis \" "
" audioSamplingRate= \" 44100 \" "
" startWithSAP= \" 1 \" "
" bandwidth= \" 129553 \" > "
" <AudioChannelConfiguration "
" schemeIdUri= \" urn:mpeg:dash:23003:3:audio_channel_configuration:2011 \" "
" value= \" 2 \" /> "
" <BaseURL>audio.webm</BaseURL> "
" <SegmentBase indexRange= \" 4452-4686 \" "
" indexRangeExact= \" true \" > "
" <Initialization range= \" 0-4451 \" /> "
" </SegmentBase> "
" </Representation></AdaptationSet></Period></MPD> " ;
2015-11-10 13:13:35 +00:00
GstDashDemuxTestInputData inputTestData [ ] = {
{ " http://unit.test/test.mpd " , ( guint8 * ) mpd , 0 } ,
2015-10-09 13:10:52 +00:00
{ " http://unit.test/audio.webm " , NULL , 10000 } ,
{ NULL , NULL , 0 } ,
} ;
2015-11-10 13:13:35 +00:00
GstTestHTTPSrcCallbacks http_src_callbacks = { 0 } ;
GstAdaptiveDemuxTestExpectedOutput outputTestData [ ] = {
2015-10-09 13:10:52 +00:00
{ " audio_00 " , 10000 , NULL } ,
} ;
2015-11-10 13:13:35 +00:00
GstAdaptiveDemuxTestCase * testData ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
testData = gst_adaptive_demux_test_case_new ( ) ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
http_src_callbacks . src_start = gst_dashdemux_http_src_start ;
http_src_callbacks . src_create = gst_dashdemux_http_src_create ;
COPY_OUTPUT_TEST_DATA ( outputTestData , testData ) ;
2015-10-16 16:10:11 +00:00
2015-11-10 13:13:35 +00:00
/* media segment starts at 4687
* Issue a seek request after media segment has started to be downloaded
* on the first pad listed in GstAdaptiveDemuxTestOutputStreamData and the
* first chunk of at least one byte has already arrived in AppSink
*/
testData - > threshold_for_seek = 4687 + 1 ;
2015-10-16 16:10:11 +00:00
2015-12-23 18:25:29 +00:00
/* seek to 5ms.
* Because there is only one fragment , we expect the whole file to be
* downloaded again
*/
testData - > seek_event =
gst_event_new_seek ( 1.0 , GST_FORMAT_TIME ,
GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT , GST_SEEK_TYPE_SET ,
5 * GST_MSECOND , GST_SEEK_TYPE_NONE , 0 ) ;
2015-11-10 13:13:35 +00:00
gst_test_http_src_install_callbacks ( & http_src_callbacks , inputTestData ) ;
gst_adaptive_demux_test_seek ( DEMUX_ELEMENT_NAME ,
" http://unit.test/test.mpd " , testData ) ;
gst_object_unref ( testData ) ;
2015-10-16 16:10:11 +00:00
}
GST_END_TEST ;
2016-01-05 20:41:23 +00:00
static void
run_seek_position_test ( gdouble rate , guint64 seek_start , GstSeekType stop_type ,
guint64 seek_stop , GstSeekFlags flags , guint64 segment_start ,
guint64 segment_stop , gint segments )
{
const gchar * mpd =
" <?xml version= \" 1.0 \" encoding= \" utf-8 \" ?> "
" <MPD xmlns:xsi= \" http://www.w3.org/2001/XMLSchema-instance \" "
" xmlns= \" urn:mpeg:DASH:schema:MPD:2011 \" "
" xsi:schemaLocation= \" urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd \" "
" xmlns:yt= \" http://youtube.com/yt/2012/10/10 \" "
" profiles= \" urn:mpeg:dash:profile:isoff-on-demand:2011 \" "
" type= \" static \" "
" minBufferTime= \" PT1.500S \" "
" mediaPresentationDuration= \" PT135.743S \" > "
" <Period> "
" <AdaptationSet "
" mimeType= \" audio/mp4 \" minBandwidth= \" 128000 \" "
" maxBandwidth= \" 128000 \" segmentAlignment= \" true \" > "
" <SegmentTemplate timescale= \" 48000 \" "
" initialization= \" init-$RepresentationID$.mp4 \" "
" media= \" $RepresentationID$-$Number$.mp4 \" "
" startNumber= \" 1 \" > "
" <SegmentTimeline> "
" <S t= \" 0 \" d= \" 48000 \" /> "
" <S d= \" 48000 \" /> "
" <S d= \" 48000 \" /> "
" <S d= \" 48000 \" /> "
" </SegmentTimeline> "
" </SegmentTemplate> "
" <Representation id= \" audio \" bandwidth= \" 128000 \" "
" codecs= \" mp4a.40.2 \" audioSamplingRate= \" 48000 \" > "
" <AudioChannelConfiguration "
" schemeIdUri= \" urn:mpeg:dash:23003:3:audio_channel_configuration:2011 \" "
" value= \" 2 \" > "
" </AudioChannelConfiguration> "
" </Representation></AdaptationSet></Period></MPD> " ;
GstDashDemuxTestInputData inputTestData [ ] = {
{ " http://unit.test/test.mpd " , ( guint8 * ) mpd , 0 } ,
{ " http://unit.test/init-audio.mp4 " , NULL , 10000 } ,
{ " http://unit.test/audio-1.mp4 " , NULL , 10000 } ,
{ " http://unit.test/audio-2.mp4 " , NULL , 10000 } ,
{ " http://unit.test/audio-3.mp4 " , NULL , 10000 } ,
{ " http://unit.test/audio-4.mp4 " , NULL , 10000 } ,
{ NULL , NULL , 0 } ,
} ;
GstTestHTTPSrcCallbacks http_src_callbacks = { 0 } ;
GstAdaptiveDemuxTestExpectedOutput outputTestData [ ] = {
/* 1 from the init segment */
{ " audio_00 " , ( 1 + segments ) * 10000 , NULL } ,
} ;
GstAdaptiveDemuxTestCase * testData ;
testData = gst_adaptive_demux_test_case_new ( ) ;
http_src_callbacks . src_start = gst_dashdemux_http_src_start ;
http_src_callbacks . src_create = gst_dashdemux_http_src_create ;
COPY_OUTPUT_TEST_DATA ( outputTestData , testData ) ;
/* media segment starts at 4687
* Issue a seek request after media segment has started to be downloaded
* on the first pad listed in GstAdaptiveDemuxTestOutputStreamData and the
* first chunk of at least one byte has already arrived in AppSink
*/
testData - > threshold_for_seek = 4687 + 1 ;
/* FIXME hack to avoid having a 0 seqnum */
gst_util_seqnum_next ( ) ;
/* seek to 5ms.
* Because there is only one fragment , we expect the whole file to be
* downloaded again
*/
testData - > seek_event =
gst_event_new_seek ( rate , GST_FORMAT_TIME , flags , GST_SEEK_TYPE_SET ,
seek_start , stop_type , seek_stop ) ;
gst_test_http_src_install_callbacks ( & http_src_callbacks , inputTestData ) ;
gst_adaptive_demux_test_seek ( DEMUX_ELEMENT_NAME ,
" http://unit.test/test.mpd " , testData ) ;
gst_object_unref ( testData ) ;
}
GST_START_TEST ( testSeekKeyUnitPosition )
{
/* Seek to 1.5s with key unit, it should go back to 1.0s. 3 segments will be
* pushed */
run_seek_position_test ( 1.0 , 1500 * GST_MSECOND , GST_SEEK_TYPE_NONE , 0 ,
GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT , 1000 * GST_MSECOND , - 1 , 3 ) ;
}
GST_END_TEST ;
GST_START_TEST ( testSeekPosition )
{
/* Seek to 1.5s without key unit, it should keep the 1.5s, but still push
* from the 1 st segment , so 3 segments will be
* pushed */
run_seek_position_test ( 1.0 , 1500 * GST_MSECOND , GST_SEEK_TYPE_NONE , 0 ,
GST_SEEK_FLAG_FLUSH , 1500 * GST_MSECOND , - 1 , 3 ) ;
}
GST_END_TEST ;
2015-11-10 13:13:35 +00:00
static void
testDownloadErrorMessageCallback ( GstAdaptiveDemuxTestEngine * engine ,
GstMessage * msg , gpointer user_data )
2015-10-20 16:21:00 +00:00
{
2015-11-10 13:13:35 +00:00
GError * err = NULL ;
gchar * dbg_info = NULL ;
2015-10-20 16:21:00 +00:00
2015-11-10 13:13:35 +00:00
fail_unless ( GST_MESSAGE_TYPE ( msg ) = = GST_MESSAGE_ERROR ) ;
gst_message_parse_error ( msg , & err , & dbg_info ) ;
GST_DEBUG ( " Error from element %s : %s \n " ,
GST_OBJECT_NAME ( msg - > src ) , err - > message ) ;
fail_unless_equals_string ( GST_OBJECT_NAME ( msg - > src ) , DEMUX_ELEMENT_NAME ) ;
/*GST_DEBUG ("dbg_info=%s\n", dbg_info); */
g_error_free ( err ) ;
g_free ( dbg_info ) ;
g_main_loop_quit ( engine - > loop ) ;
2015-10-20 16:21:00 +00:00
}
/*
2015-11-10 13:13:35 +00:00
* Test error case of failing to download a segment
2015-10-20 16:21:00 +00:00
*/
2015-11-10 13:13:35 +00:00
GST_START_TEST ( testDownloadError )
2015-10-20 16:21:00 +00:00
{
const gchar * mpd =
" <?xml version= \" 1.0 \" encoding= \" utf-8 \" ?> "
" <MPD xmlns:xsi= \" http://www.w3.org/2001/XMLSchema-instance \" "
" xmlns= \" urn:mpeg:DASH:schema:MPD:2011 \" "
" xsi:schemaLocation= \" urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd \" "
" xmlns:yt= \" http://youtube.com/yt/2012/10/10 \" "
" profiles= \" urn:mpeg:dash:profile:isoff-on-demand:2011 \" "
" type= \" static \" "
" minBufferTime= \" PT1.500S \" "
" mediaPresentationDuration= \" PT0.5S \" > "
" <Period> "
" <AdaptationSet mimeType= \" audio/webm \" "
" subsegmentAlignment= \" true \" > "
" <Representation id= \" 171 \" "
" codecs= \" vorbis \" "
" audioSamplingRate= \" 44100 \" "
" startWithSAP= \" 1 \" "
" bandwidth= \" 129553 \" > "
" <AudioChannelConfiguration "
" schemeIdUri= \" urn:mpeg:dash:23003:3:audio_channel_configuration:2011 \" "
" value= \" 2 \" /> "
2015-11-10 13:13:35 +00:00
" <BaseURL>audio_file_not_available.webm</BaseURL> "
2015-10-20 16:21:00 +00:00
" <SegmentBase indexRange= \" 4452-4686 \" "
" indexRangeExact= \" true \" > "
" <Initialization range= \" 0-4451 \" /> "
" </SegmentBase> "
" </Representation></AdaptationSet></Period></MPD> " ;
2015-11-10 13:13:35 +00:00
GstDashDemuxTestInputData inputTestData [ ] = {
{ " http://unit.test/test.mpd " , ( guint8 * ) mpd , 0 } ,
2015-10-20 16:21:00 +00:00
{ NULL , NULL , 0 } ,
} ;
2015-11-10 13:13:35 +00:00
GstTestHTTPSrcCallbacks http_src_callbacks = { 0 } ;
GstAdaptiveDemuxTestExpectedOutput outputTestData [ ] = {
{ " audio_00 " , 0 , NULL } ,
2015-10-20 16:21:00 +00:00
} ;
2015-11-10 13:13:35 +00:00
GstAdaptiveDemuxTestCallbacks test_callbacks = { 0 } ;
GstAdaptiveDemuxTestCase * testData ;
2015-10-20 16:21:00 +00:00
2015-11-10 13:13:35 +00:00
testData = gst_adaptive_demux_test_case_new ( ) ;
http_src_callbacks . src_start = gst_dashdemux_http_src_start ;
http_src_callbacks . src_create = gst_dashdemux_http_src_create ;
COPY_OUTPUT_TEST_DATA ( outputTestData , testData ) ;
test_callbacks . appsink_received_data =
gst_adaptive_demux_test_check_received_data ;
test_callbacks . bus_error_message = testDownloadErrorMessageCallback ;
test_callbacks . appsink_eos =
gst_adaptive_demux_test_check_size_of_received_data ;
2015-10-20 16:21:00 +00:00
2015-11-10 13:13:35 +00:00
gst_test_http_src_install_callbacks ( & http_src_callbacks , inputTestData ) ;
gst_adaptive_demux_test_run ( DEMUX_ELEMENT_NAME , " http://unit.test/test.mpd " ,
& test_callbacks , testData ) ;
gst_object_unref ( testData ) ;
2015-10-20 16:21:00 +00:00
}
GST_END_TEST ;
2015-10-16 15:20:34 +00:00
/* generate queries to adaptive demux */
static gboolean
2015-11-10 13:13:35 +00:00
testQueryCheckDataReceived ( GstAdaptiveDemuxTestEngine * engine ,
GstAdaptiveDemuxTestOutputStream * stream ,
GstBuffer * buffer , gpointer user_data )
2015-10-16 15:20:34 +00:00
{
GList * pads ;
GstPad * pad ;
GstQuery * query ;
gboolean ret ;
gint64 duration ;
gboolean seekable ;
gint64 segment_start ;
gint64 segment_end ;
gchar * uri ;
gchar * redirect_uri ;
gboolean redirect_permanent ;
2015-11-10 13:13:35 +00:00
pads = GST_ELEMENT_PADS ( stream - > appsink ) ;
2015-10-16 15:20:34 +00:00
/* AppSink should have only 1 pad */
fail_unless ( pads ! = NULL ) ;
fail_unless ( g_list_length ( pads ) = = 1 ) ;
pad = GST_PAD ( pads - > data ) ;
query = gst_query_new_duration ( GST_FORMAT_TIME ) ;
ret = gst_pad_peer_query ( pad , query ) ;
fail_unless ( ret = = TRUE ) ;
gst_query_parse_duration ( query , NULL , & duration ) ;
fail_unless ( duration = = 135743 * GST_MSECOND ) ;
gst_query_unref ( query ) ;
query = gst_query_new_seeking ( GST_FORMAT_TIME ) ;
ret = gst_pad_peer_query ( pad , query ) ;
fail_unless ( ret = = TRUE ) ;
gst_query_parse_seeking ( query , NULL , & seekable , & segment_start ,
& segment_end ) ;
fail_unless ( seekable = = TRUE ) ;
fail_unless ( segment_start = = 0 ) ;
fail_unless ( segment_end = = duration ) ;
gst_query_unref ( query ) ;
query = gst_query_new_uri ( ) ;
ret = gst_pad_peer_query ( pad , query ) ;
fail_unless ( ret = = TRUE ) ;
gst_query_parse_uri ( query , & uri ) ;
gst_query_parse_uri_redirection ( query , & redirect_uri ) ;
gst_query_parse_uri_redirection_permanent ( query , & redirect_permanent ) ;
fail_unless ( strcmp ( uri , " http://unit.test/test.mpd " ) = = 0 ) ;
/* adaptive demux does not reply with redirect information */
fail_unless ( redirect_uri = = NULL ) ;
fail_unless ( redirect_permanent = = FALSE ) ;
g_free ( uri ) ;
g_free ( redirect_uri ) ;
gst_query_unref ( query ) ;
2015-11-10 13:13:35 +00:00
return gst_adaptive_demux_test_check_received_data ( engine ,
stream , buffer , user_data ) ;
2015-10-16 15:20:34 +00:00
}
/*
* Test queries
*
*/
GST_START_TEST ( testQuery )
{
const gchar * mpd =
" <?xml version= \" 1.0 \" encoding= \" utf-8 \" ?> "
" <MPD xmlns:xsi= \" http://www.w3.org/2001/XMLSchema-instance \" "
" xmlns= \" urn:mpeg:DASH:schema:MPD:2011 \" "
" xsi:schemaLocation= \" urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd \" "
" xmlns:yt= \" http://youtube.com/yt/2012/10/10 \" "
" profiles= \" urn:mpeg:dash:profile:isoff-on-demand:2011 \" "
" type= \" static \" "
" minBufferTime= \" PT1.500S \" "
" mediaPresentationDuration= \" PT135.743S \" > "
" <Period> "
" <AdaptationSet mimeType= \" audio/webm \" "
" subsegmentAlignment= \" true \" > "
" <Representation id= \" 171 \" "
" codecs= \" vorbis \" "
" audioSamplingRate= \" 44100 \" "
" startWithSAP= \" 1 \" "
" bandwidth= \" 129553 \" > "
" <AudioChannelConfiguration "
" schemeIdUri= \" urn:mpeg:dash:23003:3:audio_channel_configuration:2011 \" "
" value= \" 2 \" /> "
" <BaseURL>audio.webm</BaseURL> "
" <SegmentBase indexRange= \" 4452-4686 \" "
" indexRangeExact= \" true \" > "
" <Initialization range= \" 0-4451 \" /> "
" </SegmentBase> "
" </Representation></AdaptationSet></Period></MPD> " ;
2015-11-10 13:13:35 +00:00
GstDashDemuxTestInputData inputTestData [ ] = {
{ " http://unit.test/test.mpd " , ( guint8 * ) mpd , 0 } ,
2015-10-16 15:20:34 +00:00
{ " http://unit.test/audio.webm " , NULL , 5000 } ,
{ NULL , NULL , 0 } ,
} ;
2015-11-10 13:13:35 +00:00
GstTestHTTPSrcCallbacks http_src_callbacks = { 0 } ;
GstAdaptiveDemuxTestExpectedOutput outputTestData [ ] = {
{ " audio_00 " , 5000 , NULL } ,
} ;
GstAdaptiveDemuxTestCallbacks test_callbacks = { 0 } ;
GstAdaptiveDemuxTestCase * testData ;
2015-10-16 15:20:34 +00:00
2015-11-10 13:13:35 +00:00
testData = gst_adaptive_demux_test_case_new ( ) ;
http_src_callbacks . src_start = gst_dashdemux_http_src_start ;
http_src_callbacks . src_create = gst_dashdemux_http_src_create ;
COPY_OUTPUT_TEST_DATA ( outputTestData , testData ) ;
test_callbacks . appsink_received_data = testQueryCheckDataReceived ;
test_callbacks . appsink_eos =
gst_adaptive_demux_test_check_size_of_received_data ;
gst_test_http_src_install_callbacks ( & http_src_callbacks , inputTestData ) ;
gst_adaptive_demux_test_run ( DEMUX_ELEMENT_NAME ,
" http://unit.test/test.mpd " , & test_callbacks , testData ) ;
gst_object_unref ( testData ) ;
}
GST_END_TEST ;
static GstFlowReturn
test_fragment_download_error_src_create ( GstTestHTTPSrc * src ,
guint64 offset ,
guint length , GstBuffer * * retbuf , gpointer context , gpointer user_data )
{
const GstDashDemuxTestInputData * input =
( const GstDashDemuxTestInputData * ) context ;
fail_unless ( input ! = NULL ) ;
if ( ! g_str_has_suffix ( input - > uri , " .mpd " ) & & offset > 2000 ) {
GST_DEBUG ( " network_error %s % " G_GUINT64_FORMAT " @ %d " ,
input - > uri , offset , 2000 ) ;
GST_ELEMENT_ERROR ( src , RESOURCE , READ ,
( ( " A network error occurred, or the server closed the connection unexpectedly. " ) ) , ( " A network error occurred, or the server closed the connection unexpectedly. " ) ) ;
return GST_FLOW_ERROR ;
}
return gst_dashdemux_http_src_create ( src , offset , length , retbuf , context ,
user_data ) ;
}
/* function to check total size of data received by AppSink
* will be called when AppSink receives eos .
*/
static void
testFragmentDownloadErrorCheckSizeOfDataReceived ( GstAdaptiveDemuxTestEngine *
engine , GstAdaptiveDemuxTestOutputStream * stream , gpointer user_data )
{
GstAdaptiveDemuxTestCase * testData = GST_ADAPTIVE_DEMUX_TEST_CASE ( user_data ) ;
GstAdaptiveDemuxTestExpectedOutput * testOutputStreamData ;
testOutputStreamData =
gst_adaptive_demux_test_find_test_data_by_stream ( testData , stream , NULL ) ;
fail_unless ( testOutputStreamData ! = NULL ) ;
/* expect to receive more than 0 */
fail_unless ( stream - > total_received_size > 0 ,
" size validation failed for %s, expected > 0, received %d " ,
testOutputStreamData - > name , stream - > total_received_size ) ;
/* expect to receive less than file size */
fail_unless ( stream - > total_received_size <
testOutputStreamData - > expected_size ,
" size validation failed for %s, expected < %d received %d " ,
testOutputStreamData - > name , testOutputStreamData - > expected_size ,
stream - > total_received_size ) ;
}
/*
* Test fragment download error
* Let the adaptive demux download a few bytes , then instruct the
* GstTestHTTPSrc element to generate an error .
*/
GST_START_TEST ( testFragmentDownloadError )
{
const gchar * mpd =
" <?xml version= \" 1.0 \" encoding= \" utf-8 \" ?> "
" <MPD xmlns:xsi= \" http://www.w3.org/2001/XMLSchema-instance \" "
" xmlns= \" urn:mpeg:DASH:schema:MPD:2011 \" "
" xsi:schemaLocation= \" urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd \" "
" xmlns:yt= \" http://youtube.com/yt/2012/10/10 \" "
" profiles= \" urn:mpeg:dash:profile:isoff-on-demand:2011 \" "
" type= \" static \" "
" minBufferTime= \" PT1.500S \" "
" mediaPresentationDuration= \" PT0.5S \" > "
" <Period> "
" <AdaptationSet mimeType= \" audio/webm \" "
" subsegmentAlignment= \" true \" > "
" <Representation id= \" 171 \" "
" codecs= \" vorbis \" "
" audioSamplingRate= \" 44100 \" "
" startWithSAP= \" 1 \" "
" bandwidth= \" 129553 \" > "
" <AudioChannelConfiguration "
" schemeIdUri= \" urn:mpeg:dash:23003:3:audio_channel_configuration:2011 \" "
" value= \" 2 \" /> "
" <BaseURL>audio.webm</BaseURL> "
" <SegmentBase indexRange= \" 4452-4686 \" "
" indexRangeExact= \" true \" > "
" <Initialization range= \" 0-4451 \" /> "
" </SegmentBase> "
" </Representation></AdaptationSet></Period></MPD> " ;
GstDashDemuxTestInputData inputTestData [ ] = {
{ " http://unit.test/test.mpd " , ( guint8 * ) mpd , 0 } ,
{ " http://unit.test/audio.webm " , NULL , 5000 } ,
{ NULL , NULL , 0 } ,
} ;
GstTestHTTPSrcCallbacks http_src_callbacks = { 0 } ;
GstAdaptiveDemuxTestExpectedOutput outputTestData [ ] = {
2015-10-16 15:20:34 +00:00
{ " audio_00 " , 5000 , NULL } ,
} ;
2015-11-10 13:13:35 +00:00
GstAdaptiveDemuxTestCallbacks test_callbacks = { 0 } ;
GstAdaptiveDemuxTestCase * testData ;
testData = gst_adaptive_demux_test_case_new ( ) ;
http_src_callbacks . src_start = gst_dashdemux_http_src_start ;
http_src_callbacks . src_create = test_fragment_download_error_src_create ;
COPY_OUTPUT_TEST_DATA ( outputTestData , testData ) ;
test_callbacks . appsink_received_data =
gst_adaptive_demux_test_check_received_data ;
test_callbacks . appsink_eos = testFragmentDownloadErrorCheckSizeOfDataReceived ;
/* test_callbacks.demux_sent_eos = gst_adaptive_demux_test_check_size_of_received_data; */
2015-10-16 15:20:34 +00:00
2015-11-10 13:13:35 +00:00
test_callbacks . bus_error_message = testDownloadErrorMessageCallback ;
2015-10-16 15:20:34 +00:00
2015-11-10 13:13:35 +00:00
gst_test_http_src_install_callbacks ( & http_src_callbacks , inputTestData ) ;
gst_adaptive_demux_test_run ( DEMUX_ELEMENT_NAME ,
" http://unit.test/test.mpd " , & test_callbacks , testData ) ;
gst_object_unref ( testData ) ;
2015-10-16 15:20:34 +00:00
}
GST_END_TEST ;
2015-10-09 13:10:52 +00:00
static Suite *
dash_demux_suite ( void )
{
Suite * s = suite_create ( " dash_demux " ) ;
TCase * tc_basicTest = tcase_create ( " basicTest " ) ;
tcase_add_test ( tc_basicTest , simpleTest ) ;
tcase_add_test ( tc_basicTest , testTwoPeriods ) ;
tcase_add_test ( tc_basicTest , testParameters ) ;
tcase_add_test ( tc_basicTest , testSeek ) ;
2016-01-05 20:41:23 +00:00
tcase_add_test ( tc_basicTest , testSeekKeyUnitPosition ) ;
tcase_add_test ( tc_basicTest , testSeekPosition ) ;
2015-10-16 16:10:11 +00:00
tcase_add_test ( tc_basicTest , testDownloadError ) ;
2015-11-10 13:13:35 +00:00
tcase_add_test ( tc_basicTest , testFragmentDownloadError ) ;
2015-10-16 15:20:34 +00:00
tcase_add_test ( tc_basicTest , testQuery ) ;
2015-10-09 13:10:52 +00:00
2015-11-10 13:13:35 +00:00
tcase_add_unchecked_fixture ( tc_basicTest , gst_adaptive_demux_test_setup ,
gst_adaptive_demux_test_teardown ) ;
2015-10-09 13:10:52 +00:00
suite_add_tcase ( s , tc_basicTest ) ;
return s ;
}
GST_CHECK_MAIN ( dash_demux ) ;