mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-11 11:51:34 +00:00
1138 lines
38 KiB
C
1138 lines
38 KiB
C
/* GStreamer Editing Services
|
|
* Copyright (C) 2013 Mathieu Duponchelle <mduponchelle1@gmail.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.
|
|
*/
|
|
|
|
#include "test-utils.h"
|
|
#include <ges/ges.h>
|
|
#include <gst/check/gstcheck.h>
|
|
|
|
static GList *tests_names;
|
|
|
|
/* *INDENT-OFF* */
|
|
static const char * const profile_specs[][4] = {
|
|
{ "application/ogg", "audio/x-vorbis", "video/x-theora", "assets/vorbis_theora.rendered.ogv" },
|
|
{ "video/webm", "audio/x-vorbis", "video/x-vp8", "assets/vorbis_vp8.rendered.webm"},
|
|
{ "video/quicktime,variant=iso", "audio/mpeg,mpegversion=1,layer=3", "video/x-h264", "assets/aac_h264.rendered.mov"},
|
|
{ "video/x-matroska", "audio/x-vorbis", "video/x-h264", "assets/vorbis_h264.rendered.mkv"},
|
|
};
|
|
/* *INDENT-ON* */
|
|
|
|
typedef enum
|
|
{
|
|
PROFILE_NONE = -1,
|
|
PROFILE_VORBIS_THEORA_OGG,
|
|
PROFILE_VORBIS_VP8_WEBM,
|
|
PROFILE_AAC_H264_QUICKTIME,
|
|
PROFILE_VORBIS_H264_MATROSKA,
|
|
} EncodingProfileName;
|
|
|
|
typedef struct _PresetInfos
|
|
{
|
|
const gchar *muxer_preset_name;
|
|
const gchar *audio_preset_name;
|
|
const gchar *video_preset_name;
|
|
|
|
gsize expected_size;
|
|
|
|
} PresetInfos;
|
|
|
|
typedef struct SeekInfo
|
|
{
|
|
GstClockTime position; /* position to seek to */
|
|
GstClockTime seeking_position; /* position to do seek from */
|
|
} SeekInfo;
|
|
|
|
static GMainLoop *loop;
|
|
static GESPipeline *pipeline = NULL;
|
|
static gint64 seeked_position = GST_CLOCK_TIME_NONE; /* last seeked position */
|
|
static gint64 seek_tol = 0.05 * GST_SECOND; /* tolerance seek interval */
|
|
static GList *seeks; /* list of seeks */
|
|
static gboolean got_async_done = FALSE;
|
|
static gboolean seek_paused = FALSE, seek_paused_noplay = FALSE;
|
|
|
|
/* This allow us to run the tests multiple times with different input files */
|
|
static const gchar *testfilename1 = NULL;
|
|
static const gchar *testfilename2 = NULL;
|
|
static const gchar *test_image_filename = NULL;
|
|
static EncodingProfileName current_profile = PROFILE_NONE;
|
|
|
|
#define DURATION_TOLERANCE 0.1 * GST_SECOND
|
|
|
|
#define get_asset(filename, asset) \
|
|
{ \
|
|
GError *error = NULL; \
|
|
gchar *uri = ges_test_file_name (filename); \
|
|
asset = ges_uri_clip_asset_request_sync (uri, &error); \
|
|
fail_unless (GES_IS_ASSET (asset), "Testing file %s could not be used as an "\
|
|
"asset -- Reason: %s", uri, error ? error->message : "Uknown"); \
|
|
g_free (uri); \
|
|
}
|
|
|
|
static SeekInfo *
|
|
new_seek_info (GstClockTime seeking_position, GstClockTime position)
|
|
{
|
|
SeekInfo *info = g_slice_new0 (SeekInfo);
|
|
info->seeking_position = seeking_position;
|
|
info->position = position;
|
|
return info;
|
|
}
|
|
|
|
static GstEncodingProfile *
|
|
create_profile (const char *container, const char *container_preset,
|
|
const char *audio, const char *audio_preset, const char *video,
|
|
const char *video_preset)
|
|
{
|
|
GstEncodingContainerProfile *cprof = NULL;
|
|
GstEncodingProfile *prof = NULL;
|
|
GstCaps *caps;
|
|
|
|
/* If we have both audio and video, we must have container */
|
|
if (audio && video && !container)
|
|
return NULL;
|
|
|
|
if (container) {
|
|
caps = gst_caps_from_string (container);
|
|
cprof = gst_encoding_container_profile_new ("User profile", "User profile",
|
|
caps, NULL);
|
|
gst_caps_unref (caps);
|
|
if (!cprof)
|
|
return NULL;
|
|
if (container_preset)
|
|
gst_encoding_profile_set_preset ((GstEncodingProfile *) cprof,
|
|
container_preset);
|
|
}
|
|
|
|
if (audio) {
|
|
caps = gst_caps_from_string (audio);
|
|
prof = (GstEncodingProfile *) gst_encoding_audio_profile_new (caps, NULL,
|
|
NULL, 0);
|
|
if (!prof)
|
|
goto beach;
|
|
if (audio_preset)
|
|
gst_encoding_profile_set_preset (prof, audio_preset);
|
|
if (cprof)
|
|
gst_encoding_container_profile_add_profile (cprof, prof);
|
|
gst_caps_unref (caps);
|
|
}
|
|
if (video) {
|
|
caps = gst_caps_from_string (video);
|
|
prof = (GstEncodingProfile *) gst_encoding_video_profile_new (caps, NULL,
|
|
NULL, 0);
|
|
if (!prof)
|
|
goto beach;
|
|
if (video_preset)
|
|
gst_encoding_profile_set_preset (prof, video_preset);
|
|
if (cprof)
|
|
gst_encoding_container_profile_add_profile (cprof, prof);
|
|
gst_caps_unref (caps);
|
|
}
|
|
|
|
return cprof ? (GstEncodingProfile *) cprof : (GstEncodingProfile *) prof;
|
|
|
|
beach:
|
|
if (cprof)
|
|
gst_encoding_profile_unref (cprof);
|
|
else
|
|
gst_encoding_profile_unref (prof);
|
|
return NULL;
|
|
}
|
|
|
|
static GstEncodingProfile *
|
|
create_audio_video_profile (EncodingProfileName type)
|
|
{
|
|
return create_profile (profile_specs[type][0], NULL, profile_specs[type][1],
|
|
NULL, profile_specs[type][2], NULL);
|
|
}
|
|
|
|
/* This is used to specify a dot dumping after the target element started outputting buffers */
|
|
static const gchar *target_element = "smart-mixer-mixer";
|
|
|
|
static GstPadProbeReturn
|
|
dump_to_dot (GstPad * pad, GstPadProbeInfo * info)
|
|
{
|
|
GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
|
|
GST_DEBUG_GRAPH_SHOW_ALL, "ges-integration-smart-mixer-push-buffer");
|
|
return (GST_PAD_PROBE_REMOVE);
|
|
}
|
|
|
|
static gboolean
|
|
my_bus_callback (GstBus * bus, GstMessage * message, gpointer data)
|
|
{
|
|
gboolean *ret = (gboolean *) data;
|
|
|
|
switch (GST_MESSAGE_TYPE (message)) {
|
|
case GST_MESSAGE_STATE_CHANGED:{
|
|
GstState old_state, new_state;
|
|
|
|
gst_message_parse_state_changed (message, &old_state, &new_state, NULL);
|
|
/* HACK */
|
|
if (new_state == GST_STATE_PLAYING
|
|
&& !g_strcmp0 (GST_MESSAGE_SRC_NAME (message), target_element))
|
|
gst_pad_add_probe (gst_element_get_static_pad (GST_ELEMENT
|
|
(GST_MESSAGE_SRC (message)), "src"), GST_PAD_PROBE_TYPE_BUFFER,
|
|
(GstPadProbeCallback) dump_to_dot, NULL, NULL);
|
|
break;
|
|
}
|
|
case GST_MESSAGE_ERROR:{
|
|
GError *err;
|
|
gchar *debug;
|
|
|
|
gst_message_parse_error (message, &err, &debug);
|
|
GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
|
|
GST_DEBUG_GRAPH_SHOW_ALL, "ges-integration-error");
|
|
|
|
g_assert_no_error (err);
|
|
g_error_free (err);
|
|
g_free (debug);
|
|
g_main_loop_quit (loop);
|
|
break;
|
|
}
|
|
case GST_MESSAGE_EOS:
|
|
GST_INFO ("EOS\n");
|
|
*ret = TRUE;
|
|
g_main_loop_quit (loop);
|
|
break;
|
|
case GST_MESSAGE_ASYNC_DONE:
|
|
got_async_done = TRUE;
|
|
if (GST_CLOCK_TIME_IS_VALID (seeked_position))
|
|
seeked_position = GST_CLOCK_TIME_NONE;
|
|
|
|
if (seeks == NULL && seek_paused_noplay) {
|
|
/* We are now done with seeking, let it play until the end */
|
|
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
|
|
gst_element_get_state (GST_ELEMENT (pipeline), NULL, NULL, -1);
|
|
}
|
|
break;
|
|
default:
|
|
/* unhandled message */
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
get_position (void)
|
|
{
|
|
GList *tmp;
|
|
gint64 position;
|
|
gst_element_query_position (GST_ELEMENT (pipeline), GST_FORMAT_TIME,
|
|
&position);
|
|
tmp = seeks;
|
|
|
|
GST_LOG ("Current position: %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
|
|
while (tmp) {
|
|
SeekInfo *seek = tmp->data;
|
|
if ((position >= (seek->seeking_position - seek_tol))
|
|
&& (position <= (seek->seeking_position + seek_tol))) {
|
|
|
|
if (!got_async_done)
|
|
fail_if (GST_CLOCK_TIME_IS_VALID (seeked_position));
|
|
got_async_done = FALSE;
|
|
|
|
GST_INFO ("seeking to: %" GST_TIME_FORMAT,
|
|
GST_TIME_ARGS (seek->position));
|
|
|
|
seeked_position = seek->position;
|
|
if (seek_paused) {
|
|
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
|
|
GST_LOG ("Set state playing");
|
|
gst_element_get_state (GST_ELEMENT (pipeline), NULL, NULL, -1);
|
|
GST_LOG ("Done wainting");
|
|
}
|
|
|
|
if (seek_paused_noplay) {
|
|
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
|
|
gst_element_get_state (GST_ELEMENT (pipeline), NULL, NULL, -1);
|
|
}
|
|
fail_unless (gst_element_seek_simple (GST_ELEMENT (pipeline),
|
|
GST_FORMAT_TIME,
|
|
GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, seek->position));
|
|
|
|
if (seek_paused) {
|
|
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
|
|
gst_element_get_state (GST_ELEMENT (pipeline), NULL, NULL, -1);
|
|
}
|
|
seeks = g_list_remove_link (seeks, tmp);
|
|
g_slice_free (SeekInfo, seek);
|
|
g_list_free (tmp);
|
|
break;
|
|
}
|
|
tmp = tmp->next;
|
|
}
|
|
/* if seeking paused without playing and we reached the last seek, just play
|
|
* till the end */
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
check_rendered_file_properties (const gchar * render_file,
|
|
GstClockTime duration)
|
|
{
|
|
GESUriClipAsset *asset;
|
|
GstDiscovererInfo *info;
|
|
GstClockTime real_duration;
|
|
|
|
/* TODO: extend these tests */
|
|
|
|
get_asset (render_file, asset);
|
|
info = ges_uri_clip_asset_get_info (GES_URI_CLIP_ASSET (asset));
|
|
gst_object_unref (asset);
|
|
|
|
fail_unless (GST_IS_DISCOVERER_INFO (info), "Could not discover file %s",
|
|
render_file);
|
|
|
|
/* Let's not be too nazi */
|
|
|
|
real_duration = gst_discoverer_info_get_duration (info);
|
|
|
|
fail_if ((real_duration < duration - DURATION_TOLERANCE)
|
|
|| (real_duration > duration + DURATION_TOLERANCE), "Duration %"
|
|
GST_TIME_FORMAT " not in range [%" GST_TIME_FORMAT " -- %"
|
|
GST_TIME_FORMAT "]", GST_TIME_ARGS (real_duration),
|
|
GST_TIME_ARGS (duration - DURATION_TOLERANCE),
|
|
GST_TIME_ARGS (duration + DURATION_TOLERANCE));
|
|
|
|
|
|
gst_object_unref (info);
|
|
}
|
|
|
|
static gboolean
|
|
check_timeline (GESTimeline * timeline)
|
|
{
|
|
GstBus *bus;
|
|
static gboolean ret;
|
|
GstEncodingProfile *profile;
|
|
gchar *render_uri = NULL;
|
|
|
|
ret = FALSE;
|
|
|
|
ges_timeline_commit (timeline);
|
|
pipeline = ges_pipeline_new ();
|
|
if (current_profile != PROFILE_NONE) {
|
|
render_uri = ges_test_file_name (profile_specs[current_profile][3]);
|
|
|
|
profile = create_audio_video_profile (current_profile);
|
|
ges_pipeline_set_render_settings (pipeline, render_uri, profile);
|
|
ges_pipeline_set_mode (pipeline, TIMELINE_MODE_RENDER);
|
|
|
|
|
|
gst_object_unref (profile);
|
|
} else if (g_getenv ("GES_MUTE_TESTS")) {
|
|
GstElement *sink = gst_element_factory_make ("fakesink", NULL);
|
|
|
|
g_object_set (sink, "sync", TRUE, NULL);
|
|
ges_pipeline_preview_set_audio_sink (pipeline, sink);
|
|
|
|
sink = gst_element_factory_make ("fakesink", NULL);
|
|
g_object_set (sink, "sync", TRUE, NULL);
|
|
ges_pipeline_preview_set_video_sink (pipeline, sink);
|
|
}
|
|
|
|
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
|
|
gst_bus_add_watch (bus, my_bus_callback, &ret);
|
|
gst_object_unref (bus);
|
|
|
|
ges_pipeline_add_timeline (pipeline, timeline);
|
|
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
|
|
gst_element_get_state (GST_ELEMENT (pipeline), NULL, NULL, -1);
|
|
GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
|
|
GST_DEBUG_GRAPH_SHOW_ALL, "ges-integration-playing");
|
|
if (seeks != NULL)
|
|
g_timeout_add (50, (GSourceFunc) get_position, NULL);
|
|
|
|
g_main_loop_run (loop);
|
|
|
|
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
|
|
gst_element_get_state (GST_ELEMENT (pipeline), NULL, NULL, -1);
|
|
|
|
if (current_profile != PROFILE_NONE) {
|
|
check_rendered_file_properties (profile_specs[current_profile][3],
|
|
ges_timeline_get_duration (timeline));
|
|
g_free (render_uri);
|
|
}
|
|
|
|
gst_object_unref (pipeline);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* Test seeking in various situations */
|
|
static void
|
|
run_simple_seeks_test (GESTimeline * timeline)
|
|
{
|
|
GList *tmp;
|
|
GESLayer *layer;
|
|
GESUriClipAsset *asset1;
|
|
|
|
get_asset (testfilename1, asset1);
|
|
|
|
layer = ges_layer_new ();
|
|
fail_unless (ges_timeline_add_layer (timeline, layer));
|
|
ges_layer_add_asset (layer, GES_ASSET (asset1), 0 * GST_SECOND,
|
|
0 * GST_SECOND, 1 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN);
|
|
|
|
gst_object_unref (asset1);
|
|
|
|
ges_layer_add_asset (layer, GES_ASSET (asset1), 1 * GST_SECOND,
|
|
0 * GST_SECOND, 1 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN);
|
|
|
|
/**
|
|
* Our timeline
|
|
* [ E ]
|
|
* inpoints 0--------01--------2
|
|
* | clip | clip |
|
|
* time 0--------10--------1
|
|
*/
|
|
if (!seek_paused_noplay) {
|
|
seeks =
|
|
g_list_append (seeks, new_seek_info (0.2 * GST_SECOND,
|
|
0.6 * GST_SECOND));
|
|
seeks =
|
|
g_list_append (seeks, new_seek_info (1.0 * GST_SECOND,
|
|
1.2 * GST_SECOND));
|
|
seeks =
|
|
g_list_append (seeks, new_seek_info (1.5 * GST_SECOND,
|
|
1.8 * GST_SECOND));
|
|
} else {
|
|
/* if pipeline is not playing, let's make point-to-point seeks */
|
|
seeks =
|
|
g_list_append (seeks, new_seek_info (0.2 * GST_SECOND,
|
|
0.6 * GST_SECOND));
|
|
seeks =
|
|
g_list_append (seeks, new_seek_info (0.6 * GST_SECOND,
|
|
1.2 * GST_SECOND));
|
|
seeks =
|
|
g_list_append (seeks, new_seek_info (1.2 * GST_SECOND,
|
|
1.8 * GST_SECOND));
|
|
}
|
|
fail_unless (check_timeline (timeline));
|
|
if (seeks != NULL) {
|
|
/* free failed seeks */
|
|
while (seeks) {
|
|
SeekInfo *info = seeks->data;
|
|
|
|
tmp = seeks;
|
|
GST_ERROR ("Seeking at %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT
|
|
" did not happen", GST_TIME_ARGS (info->seeking_position),
|
|
GST_TIME_ARGS (info->position));
|
|
seeks = g_list_remove_link (seeks, tmp);
|
|
g_slice_free (SeekInfo, info);
|
|
g_list_free (tmp);
|
|
}
|
|
fail_if (TRUE, "Got EOS before being able to execute all seeks");
|
|
}
|
|
}
|
|
|
|
static void
|
|
test_seeking_audio (void)
|
|
{
|
|
GESTimeline *timeline = ges_timeline_new ();
|
|
|
|
fail_unless (ges_timeline_add_track (timeline,
|
|
GES_TRACK (ges_audio_track_new ())));
|
|
|
|
seek_paused = FALSE;
|
|
seek_paused_noplay = FALSE;
|
|
run_simple_seeks_test (timeline);
|
|
}
|
|
|
|
static void
|
|
test_seeking_video (void)
|
|
{
|
|
GESTimeline *timeline = ges_timeline_new ();
|
|
|
|
fail_unless (ges_timeline_add_track (timeline,
|
|
GES_TRACK (ges_video_track_new ())));
|
|
|
|
seek_paused = FALSE;
|
|
seek_paused_noplay = FALSE;
|
|
run_simple_seeks_test (timeline);
|
|
}
|
|
|
|
static void
|
|
test_seeking (void)
|
|
{
|
|
GESTimeline *timeline = ges_timeline_new_audio_video ();
|
|
|
|
seek_paused = FALSE;
|
|
seek_paused_noplay = FALSE;
|
|
run_simple_seeks_test (timeline);
|
|
}
|
|
|
|
static void
|
|
test_seeking_paused_audio (void)
|
|
{
|
|
GESTimeline *timeline = ges_timeline_new ();
|
|
|
|
fail_unless (ges_timeline_add_track (timeline,
|
|
GES_TRACK (ges_audio_track_new ())));
|
|
|
|
seek_paused = TRUE;
|
|
seek_paused_noplay = FALSE;
|
|
run_simple_seeks_test (timeline);
|
|
}
|
|
|
|
static void
|
|
test_seeking_paused_video (void)
|
|
{
|
|
GESTimeline *timeline = ges_timeline_new ();
|
|
|
|
fail_unless (ges_timeline_add_track (timeline,
|
|
GES_TRACK (ges_video_track_new ())));
|
|
|
|
seek_paused = TRUE;
|
|
seek_paused_noplay = FALSE;
|
|
run_simple_seeks_test (timeline);
|
|
}
|
|
|
|
static void
|
|
test_seeking_paused (void)
|
|
{
|
|
GESTimeline *timeline = ges_timeline_new_audio_video ();
|
|
|
|
seek_paused = TRUE;
|
|
seek_paused_noplay = FALSE;
|
|
run_simple_seeks_test (timeline);
|
|
}
|
|
|
|
static void
|
|
test_seeking_paused_audio_noplay (void)
|
|
{
|
|
GESTimeline *timeline = ges_timeline_new ();
|
|
|
|
fail_unless (ges_timeline_add_track (timeline,
|
|
GES_TRACK (ges_audio_track_new ())));
|
|
|
|
seek_paused = FALSE;
|
|
seek_paused_noplay = TRUE;
|
|
run_simple_seeks_test (timeline);
|
|
}
|
|
|
|
static void
|
|
test_seeking_paused_video_noplay (void)
|
|
{
|
|
GESTimeline *timeline = ges_timeline_new ();
|
|
|
|
fail_unless (ges_timeline_add_track (timeline,
|
|
GES_TRACK (ges_video_track_new ())));
|
|
|
|
seek_paused = FALSE;
|
|
seek_paused_noplay = TRUE;
|
|
run_simple_seeks_test (timeline);
|
|
}
|
|
|
|
static void
|
|
test_seeking_paused_noplay (void)
|
|
{
|
|
GESTimeline *timeline = ges_timeline_new_audio_video ();
|
|
|
|
seek_paused = FALSE;
|
|
seek_paused_noplay = TRUE;
|
|
run_simple_seeks_test (timeline);
|
|
}
|
|
|
|
/* Test adding an effect [E] marks the effect */
|
|
static void
|
|
test_effect (void)
|
|
{
|
|
GESTimeline *timeline;
|
|
GESLayer *layer;
|
|
GError *error = NULL;
|
|
GESUriClipAsset *asset1;
|
|
GESEffect *effect;
|
|
GESClip *clip;
|
|
gchar *uri = ges_test_file_name (testfilename1);
|
|
|
|
asset1 = ges_uri_clip_asset_request_sync (uri, &error);
|
|
g_free (uri);
|
|
fail_unless (GES_IS_ASSET (asset1), "Testing file %s could not be used as an "
|
|
"asset -- Reason: %s", uri, error ? error->message : "Uknown");
|
|
|
|
fail_unless (asset1 != NULL);
|
|
|
|
layer = ges_layer_new ();
|
|
timeline = ges_timeline_new_audio_video ();
|
|
fail_unless (ges_timeline_add_layer (timeline, layer));
|
|
|
|
clip =
|
|
ges_layer_add_asset (layer, GES_ASSET (asset1), 0 * GST_SECOND,
|
|
0 * GST_SECOND, 1 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN);
|
|
gst_object_unref (asset1);
|
|
|
|
effect = ges_effect_new ("agingtv");
|
|
ges_container_add (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (effect));
|
|
|
|
/**
|
|
* Our timeline
|
|
* [ E ]
|
|
* inpoints 0--------0
|
|
* | clip |
|
|
* time 0--------1
|
|
*/
|
|
|
|
fail_unless (check_timeline (timeline));
|
|
}
|
|
|
|
static void
|
|
test_transition (void)
|
|
{
|
|
GESTimeline *timeline;
|
|
GESLayer *layer;
|
|
GESUriClipAsset *asset1, *asset2;
|
|
GESClip *clip;
|
|
|
|
timeline = ges_timeline_new_audio_video ();
|
|
layer = ges_layer_new ();
|
|
fail_unless (ges_timeline_add_layer (timeline, layer));
|
|
|
|
g_object_set (layer, "auto-transition", TRUE, NULL);
|
|
|
|
get_asset (testfilename1, asset1);
|
|
get_asset (testfilename2, asset2);
|
|
|
|
fail_unless (asset1 != NULL && asset2 != NULL);
|
|
|
|
clip =
|
|
ges_layer_add_asset (layer, GES_ASSET (asset1), 0 * GST_SECOND,
|
|
0 * GST_SECOND, 2 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN);
|
|
gst_object_unref (asset1);
|
|
|
|
clip =
|
|
ges_layer_add_asset (layer, GES_ASSET (asset2), 1 * GST_SECOND,
|
|
0 * GST_SECOND, 2 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN);
|
|
gst_object_unref (asset2);
|
|
|
|
ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (clip), 1 * GST_SECOND);
|
|
|
|
/**
|
|
* Our timeline
|
|
* [T]
|
|
* inpoints 0--------0 0--------0
|
|
* | clip | | clip2 |
|
|
* time 0------- 2 1--------3
|
|
*/
|
|
|
|
fail_unless (check_timeline (timeline));
|
|
}
|
|
|
|
static void
|
|
run_basic (GESTimeline * timeline)
|
|
{
|
|
GESLayer *layer;
|
|
GESUriClipAsset *asset1;
|
|
GESUriClipAsset *asset2;
|
|
|
|
get_asset (testfilename1, asset1);
|
|
get_asset (testfilename2, asset2);
|
|
layer = ges_layer_new ();
|
|
fail_unless (ges_timeline_add_layer (timeline, layer));
|
|
|
|
ges_layer_add_asset (layer, GES_ASSET (asset1), 0 * GST_SECOND,
|
|
0 * GST_SECOND, 1 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN);
|
|
gst_object_unref (asset1);
|
|
/* Test most simple case */
|
|
|
|
ges_layer_add_asset (layer, GES_ASSET (asset2), 1 * GST_SECOND,
|
|
0 * GST_SECOND, 1 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN);
|
|
gst_object_unref (asset2);
|
|
|
|
/**
|
|
* Our timeline
|
|
*
|
|
* inpoints 0--------0 0--------0
|
|
* | clip | | clip2 |
|
|
* time 0------- 1 1--------2
|
|
*/
|
|
|
|
fail_unless (check_timeline (timeline));
|
|
}
|
|
|
|
static void
|
|
test_basic (void)
|
|
{
|
|
run_basic (ges_timeline_new_audio_video ());
|
|
}
|
|
|
|
static void
|
|
test_basic_audio (void)
|
|
{
|
|
GESTimeline *timeline = ges_timeline_new ();
|
|
|
|
fail_unless (ges_timeline_add_track (timeline,
|
|
GES_TRACK (ges_audio_track_new ())));
|
|
|
|
run_basic (timeline);
|
|
}
|
|
|
|
static void
|
|
test_basic_video (void)
|
|
{
|
|
GESTimeline *timeline = ges_timeline_new ();
|
|
|
|
fail_unless (ges_timeline_add_track (timeline,
|
|
GES_TRACK (ges_video_track_new ())));
|
|
|
|
run_basic (timeline);
|
|
}
|
|
|
|
static void
|
|
test_image (void)
|
|
{
|
|
GESTimeline *timeline;
|
|
GESLayer *layer;
|
|
GESUriClipAsset *asset1, *asset2;
|
|
|
|
get_asset (test_image_filename, asset1);
|
|
get_asset (testfilename1, asset2);
|
|
|
|
layer = ges_layer_new ();
|
|
timeline = ges_timeline_new_audio_video ();
|
|
fail_unless (ges_timeline_add_layer (timeline, layer));
|
|
|
|
ges_layer_add_asset (layer, GES_ASSET (asset1), 0 * GST_SECOND,
|
|
0 * GST_SECOND, 1 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN);
|
|
gst_object_unref (asset1);
|
|
/* Test most simple case */
|
|
|
|
layer = ges_layer_new ();
|
|
fail_unless (ges_timeline_add_layer (timeline, layer));
|
|
|
|
ges_layer_add_asset (layer, GES_ASSET (asset2), 0 * GST_SECOND,
|
|
0 * GST_SECOND, 1 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN);
|
|
gst_object_unref (asset2);
|
|
|
|
|
|
/**
|
|
* Our timeline
|
|
*
|
|
* inpoints 0--------0
|
|
* | clip |
|
|
* time 0--------1
|
|
*/
|
|
|
|
fail_unless (check_timeline (timeline));
|
|
}
|
|
|
|
static gboolean
|
|
test_mix_layers (GESTimeline * timeline, GESUriClipAsset ** assets,
|
|
guint32 num_assets, guint32 num_layers)
|
|
{
|
|
GESLayer *layer;
|
|
GESClip *clip;
|
|
GList *tmp;
|
|
GESTrackElement *track_element;
|
|
GESTrackType track_type;
|
|
GESUriClipAsset *asset;
|
|
guint32 i, j;
|
|
gfloat step = 1.0 / num_layers;
|
|
|
|
for (i = 0; i < num_layers; i++) {
|
|
layer = ges_timeline_append_layer (timeline);
|
|
fail_unless (layer != NULL);
|
|
|
|
for (j = 0; j < num_assets; j++) {
|
|
asset = assets[j];
|
|
|
|
clip =
|
|
ges_layer_add_asset (layer, GES_ASSET (asset),
|
|
(i * step + j) * GST_SECOND, 0 * GST_SECOND, 1 * GST_SECOND,
|
|
GES_TRACK_TYPE_UNKNOWN);
|
|
fail_unless (clip != NULL);
|
|
|
|
for (tmp = GES_CONTAINER_CHILDREN (clip); tmp; tmp = tmp->next) {
|
|
track_element = GES_TRACK_ELEMENT (tmp->data);
|
|
track_type = ges_track_element_get_track_type (track_element);
|
|
|
|
switch (track_type) {
|
|
case GES_TRACK_TYPE_VIDEO:
|
|
ges_track_element_set_child_properties (track_element, "alpha",
|
|
(gdouble) (num_layers - 1 - i) * step, NULL);
|
|
break;
|
|
case GES_TRACK_TYPE_AUDIO:
|
|
ges_track_element_set_child_properties (track_element, "volume",
|
|
(gdouble) (num_layers - 1 - i) * step, NULL);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static void
|
|
test_mixing (void)
|
|
{
|
|
GESTimeline *timeline;
|
|
GESUriClipAsset *asset[2];
|
|
GError *error = NULL;
|
|
|
|
gchar *uri1 = ges_test_file_name (testfilename1);
|
|
gchar *uri2 = ges_test_file_name (testfilename1);
|
|
|
|
timeline = ges_timeline_new_audio_video ();
|
|
|
|
asset[0] = ges_uri_clip_asset_request_sync (uri1, &error);
|
|
asset[1] = ges_uri_clip_asset_request_sync (uri2, &error);
|
|
|
|
g_free (uri1);
|
|
g_free (uri2);
|
|
|
|
/* we are only using the first asset / clip for now */
|
|
fail_unless (test_mix_layers (timeline, asset, 1, 2));
|
|
|
|
/**
|
|
* Our timeline has 4 layers
|
|
*
|
|
* inpoints 0--------0
|
|
* | clip |
|
|
* time 0--------1
|
|
* inpoints 0--------0
|
|
* | clip |
|
|
* time 0.25--1.25
|
|
* inpoints 0--------0
|
|
* | clip |
|
|
* time 0.5----1.5
|
|
* inpoints 0--------0
|
|
* | clip |
|
|
* time 0.75--1.75
|
|
*/
|
|
|
|
fail_unless (check_timeline (timeline));
|
|
|
|
}
|
|
|
|
static void
|
|
test_title (void)
|
|
{
|
|
GESTitleClip *title;
|
|
GESAsset *asset[2];
|
|
GESTimeline *timeline;
|
|
GESLayer *layer, *layer1;
|
|
|
|
GError *error = NULL;
|
|
gchar *uri1 = ges_test_file_name (testfilename1);
|
|
|
|
timeline = ges_timeline_new_audio_video ();
|
|
layer = ges_timeline_append_layer (timeline);
|
|
layer1 = ges_timeline_append_layer (timeline);
|
|
asset[0] = ges_asset_request (GES_TYPE_TITLE_CLIP, NULL, &error);
|
|
asset[1] = GES_ASSET (ges_uri_clip_asset_request_sync (uri1, &error));
|
|
g_free (uri1);
|
|
|
|
/**
|
|
* Our timeline
|
|
*
|
|
* inpoints 0--------0
|
|
* | Title |
|
|
* time 0------- 1
|
|
* inpoints 0--------0
|
|
* | clip |
|
|
* time 0------- 1
|
|
*/
|
|
title =
|
|
GES_TITLE_CLIP (ges_layer_add_asset (layer, asset[0], 0, 0,
|
|
1 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN));
|
|
ges_title_clip_set_text (title, "This is a title test");
|
|
ges_layer_add_asset (layer1, asset[1], 1 * GST_SECOND, 0, 1 * GST_SECOND,
|
|
GES_TRACK_TYPE_UNKNOWN);
|
|
|
|
fail_unless (check_timeline (timeline));
|
|
}
|
|
|
|
|
|
#define CREATE_TEST(name, func, profile) \
|
|
GST_START_TEST (test_##name##_raw_h264_mov) \
|
|
{ \
|
|
g_print("running test_%s_%s\n", #name, "raw_h264_mov"); \
|
|
testfilename1 = "assets/raw_h264.0.mov"; \
|
|
testfilename2 = "assets/raw_h264.1.mov"; \
|
|
test_image_filename = "assets/png.png"; \
|
|
current_profile = profile; \
|
|
func (); \
|
|
} \
|
|
GST_END_TEST; \
|
|
GST_START_TEST (test_##name##_vorbis_theora_ogv) \
|
|
{ \
|
|
g_print("running test_%s_%s\n", #name, "vorbis_theora_ogv"); \
|
|
testfilename1 = "assets/vorbis_theora.0.ogg"; \
|
|
testfilename2 = "assets/vorbis_theora.1.ogg"; \
|
|
test_image_filename = "assets/png.png"; \
|
|
current_profile = profile; \
|
|
func (); \
|
|
} \
|
|
GST_END_TEST; \
|
|
GST_START_TEST (test_##name##_vorbis_vp8_webm) \
|
|
{ \
|
|
g_print("running test_%s_%s\n", #name, "vorbis_vp8_webm"); \
|
|
testfilename1 = "assets/vorbis_vp8.0.webm"; \
|
|
testfilename2 = "assets/vorbis_vp8.1.webm"; \
|
|
test_image_filename = "assets/png.png"; \
|
|
current_profile = profile; \
|
|
func (); \
|
|
} \
|
|
GST_END_TEST; \
|
|
GST_START_TEST (test_##name##_mp3_h264_mov) \
|
|
{ \
|
|
g_print("running test_%s_%s\n", #name, "mp3_h264_mov"); \
|
|
testfilename1 = "assets/mp3_h264.0.mov"; \
|
|
testfilename2 = "assets/mp3_h264.1.mov"; \
|
|
test_image_filename = "assets/png.png"; \
|
|
current_profile = profile; \
|
|
func (); \
|
|
} \
|
|
GST_END_TEST;
|
|
|
|
#define CREATE_TEST_FROM_NAMES(name, to, profile) \
|
|
CREATE_TEST( name##to, test_##name, profile)
|
|
|
|
#define CREATE_RENDERING_TEST(name, func) \
|
|
CREATE_TEST_FROM_NAMES(name, _render_to_vorbis_theora_ogg, PROFILE_VORBIS_THEORA_OGG) \
|
|
CREATE_TEST_FROM_NAMES(name, _render_to_vorbis_vp8_webm, PROFILE_VORBIS_VP8_WEBM) \
|
|
CREATE_TEST_FROM_NAMES(name, _render_to_aac_h264_quicktime, PROFILE_AAC_H264_QUICKTIME) \
|
|
CREATE_TEST_FROM_NAMES(name, _render_to_vorbis_h264_matroska, PROFILE_VORBIS_H264_MATROSKA)
|
|
|
|
#define CREATE_PLAYBACK_TEST(name) \
|
|
CREATE_TEST_FROM_NAMES(name, _playback, PROFILE_NONE)
|
|
|
|
#define CREATE_TEST_FULL(name) \
|
|
CREATE_PLAYBACK_TEST(name) \
|
|
CREATE_RENDERING_TEST(name, func)
|
|
|
|
#define ADD_PLAYBACK_TESTS(name) \
|
|
tcase_add_test (tc_chain, test_##name##_playback_vorbis_vp8_webm); \
|
|
tcase_add_test (tc_chain, test_##name##_playback_vorbis_theora_ogv); \
|
|
tcase_add_test (tc_chain, test_##name##_playback_raw_h264_mov); \
|
|
tcase_add_test (tc_chain, test_##name##_playback_mp3_h264_mov); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_playback_mp3_h264_mov")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_playback_raw_h264_mov")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_playback_vorbis_theora_ogv")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_playback_vorbis_vp8_webm"));
|
|
|
|
#define ADD_RENDERING_TESTS(name) \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_theora_ogg_raw_h264_mov); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_theora_ogg_mp3_h264_mov); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_theora_ogg_vorbis_vp8_webm); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_theora_ogg_vorbis_theora_ogv); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_vp8_webm_vorbis_vp8_webm); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_vp8_webm_raw_h264_mov); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_vp8_webm_mp3_h264_mov); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_vp8_webm_vorbis_theora_ogv); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_aac_h264_quicktime_raw_h264_mov); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_aac_h264_quicktime_vorbis_theora_ogv); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_aac_h264_quicktime_vorbis_vp8_webm); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_aac_h264_quicktime_mp3_h264_mov); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_h264_matroska_raw_h264_mov); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_h264_matroska_vorbis_theora_ogv); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_h264_matroska_vorbis_vp8_webm); \
|
|
tcase_add_test (tc_chain, test_##name##_render_to_vorbis_h264_matroska_mp3_h264_mov); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", \
|
|
#name, "_render_to_vorbis_theora_ogg_raw_h264_mov")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_vorbis_theora_ogg_mp3_h264_mov")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_vorbis_theora_ogg_vorbis_vp8_webm")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_vorbis_theora_ogg_vorbis_theora_ogv")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_vorbis_vp8_webm_vorbis_vp8_webm")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_vorbis_vp8_webm_raw_h264_mov")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_vorbis_vp8_webm_mp3_h264_mov")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_vorbis_vp8_webm_vorbis_theora_ogv")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_aac_h264_quicktime_raw_h264_mov")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_aac_h264_quicktime_vorbis_theora_ogv")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_aac_h264_quicktime_vorbis_vp8_webm")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_aac_h264_quicktime_mp3_h264_mov")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_vorbis_h264_matroska_raw_h264_mov")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_vorbis_h264_matroska_vorbis_theora_ogv")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_vorbis_h264_matroska_vorbis_vp8_webm")); \
|
|
tests_names = g_list_prepend (tests_names, g_strdup_printf ("%s%s%s", "test_", #name, \
|
|
"_render_to_vorbis_h264_matroska_mp3_h264_mov"));
|
|
|
|
#define ADD_TESTS(name) \
|
|
ADD_PLAYBACK_TESTS(name) \
|
|
ADD_RENDERING_TESTS(name)
|
|
|
|
|
|
/* *INDENT-OFF* */
|
|
CREATE_TEST_FULL(basic)
|
|
CREATE_TEST_FULL(basic_audio)
|
|
CREATE_TEST_FULL(basic_video)
|
|
CREATE_TEST_FULL(transition)
|
|
CREATE_TEST_FULL(effect)
|
|
CREATE_TEST_FULL(mixing)
|
|
CREATE_TEST_FULL(title)
|
|
|
|
CREATE_PLAYBACK_TEST(seeking)
|
|
CREATE_PLAYBACK_TEST(seeking_audio)
|
|
CREATE_PLAYBACK_TEST(seeking_video)
|
|
CREATE_PLAYBACK_TEST(seeking_paused)
|
|
CREATE_PLAYBACK_TEST(seeking_paused_audio)
|
|
CREATE_PLAYBACK_TEST(seeking_paused_video)
|
|
CREATE_PLAYBACK_TEST(seeking_paused_noplay)
|
|
CREATE_PLAYBACK_TEST(seeking_paused_audio_noplay)
|
|
CREATE_PLAYBACK_TEST(seeking_paused_video_noplay)
|
|
CREATE_PLAYBACK_TEST(image)
|
|
/* *INDENT-ON* */
|
|
|
|
static Suite *
|
|
ges_suite (void)
|
|
{
|
|
Suite *s = suite_create ("ges-integration");
|
|
TCase *tc_chain = tcase_create ("integration");
|
|
|
|
suite_add_tcase (s, tc_chain);
|
|
|
|
ADD_TESTS (basic);
|
|
ADD_TESTS (basic_audio);
|
|
ADD_TESTS (basic_video);
|
|
|
|
ADD_TESTS (effect);
|
|
ADD_TESTS (transition);
|
|
|
|
ADD_TESTS (mixing);
|
|
|
|
ADD_TESTS (title);
|
|
|
|
ADD_PLAYBACK_TESTS (image);
|
|
|
|
ADD_PLAYBACK_TESTS (seeking);
|
|
ADD_PLAYBACK_TESTS (seeking_audio);
|
|
ADD_PLAYBACK_TESTS (seeking_video);
|
|
|
|
ADD_PLAYBACK_TESTS (seeking_paused);
|
|
ADD_PLAYBACK_TESTS (seeking_paused_audio);
|
|
ADD_PLAYBACK_TESTS (seeking_paused_video);
|
|
|
|
ADD_PLAYBACK_TESTS (seeking_paused_noplay);
|
|
ADD_PLAYBACK_TESTS (seeking_paused_audio_noplay);
|
|
ADD_PLAYBACK_TESTS (seeking_paused_video_noplay);
|
|
|
|
/* TODO : next test case : complex timeline created from project. */
|
|
/* TODO : deep checking of rendered clips */
|
|
/* TODO : might be interesting to try all profiles, and maintain a list of currently working profiles ? */
|
|
|
|
return s;
|
|
}
|
|
|
|
static gboolean
|
|
generate_all_files (void)
|
|
{
|
|
if (!ges_generate_test_file_audio_video ("assets/vorbis_vp8.0.webm",
|
|
"vorbisenc", "vp8enc", "webmmux", "18", "11"))
|
|
return FALSE;
|
|
if (!ges_generate_test_file_audio_video ("assets/vorbis_vp8.1.webm",
|
|
"vorbisenc", "vp8enc", "webmmux", "0", "0"))
|
|
return FALSE;
|
|
if (!ges_generate_test_file_audio_video ("assets/vorbis_theora.0.ogg",
|
|
"vorbisenc", "theoraenc", "oggmux", "18", "11"))
|
|
return FALSE;
|
|
if (!ges_generate_test_file_audio_video ("assets/vorbis_theora.1.ogg",
|
|
"vorbisenc", "theoraenc", "oggmux", "0", "0"))
|
|
return FALSE;
|
|
if (!ges_generate_test_file_audio_video ("assets/raw_h264.0.mov", NULL,
|
|
"x264enc", "qtmux", "18", "11"))
|
|
return FALSE;
|
|
if (!ges_generate_test_file_audio_video ("assets/raw_h264.1.mov", NULL,
|
|
"x264enc", "qtmux", "0", "0"))
|
|
return FALSE;
|
|
if (!ges_generate_test_file_audio_video ("assets/mp3_h264.0.mov",
|
|
"lamemp3enc", "x264enc", "qtmux", "18", "11"))
|
|
return FALSE;
|
|
if (!ges_generate_test_file_audio_video ("assets/mp3_h264.1.mov",
|
|
"lamemp3enc", "x264enc", "qtmux", "0", "0"))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
int nf;
|
|
GOptionContext *ctx;
|
|
|
|
GError *err = NULL;
|
|
gboolean list_tests = FALSE, list_tests_only = FALSE;
|
|
Suite *s = ges_suite ();
|
|
|
|
GOptionEntry options[] = {
|
|
{"list-tests", 'l', 0.0, G_OPTION_ARG_NONE, &list_tests,
|
|
"List all avalaible tests", "N"},
|
|
{"list-tests-only", 'o', 0.0, G_OPTION_ARG_NONE, &list_tests_only,
|
|
"List all avalaible tests", "N"},
|
|
{NULL}
|
|
};
|
|
|
|
ctx = g_option_context_new ("Run integration tests");
|
|
g_option_context_add_main_entries (ctx, options, NULL);
|
|
g_option_context_add_group (ctx, gst_init_get_option_group ());
|
|
|
|
if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
|
|
g_printerr ("Error initializing: %s\n", err->message);
|
|
g_option_context_free (ctx);
|
|
exit (1);
|
|
}
|
|
|
|
if (list_tests || list_tests_only) {
|
|
GList *tmp;
|
|
|
|
g_print ("=== Listing tests %s === \n", list_tests_only ? "only" : "");
|
|
for (tmp = tests_names; tmp; tmp = tmp->next)
|
|
g_print ("%s\n", (gchar *) tmp->data);
|
|
g_print ("=== Listed tests ===\n");
|
|
|
|
if (list_tests_only == TRUE) {
|
|
g_list_free_full (tests_names, g_free);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
gst_check_init (&argc, &argv);
|
|
ges_init ();
|
|
|
|
if (!generate_all_files ()) {
|
|
GST_ERROR ("error generating necessary test files in rendering test\n");
|
|
return 1;
|
|
}
|
|
|
|
|
|
loop = g_main_loop_new (NULL, FALSE);
|
|
nf = gst_check_run_suite (s, "ges", __FILE__);
|
|
|
|
g_list_free_full (tests_names, g_free);
|
|
|
|
return nf;
|
|
}
|