media-info: replacing file-checker with a simpler media-info struct

This struct stores information about a media and tests run on it. It
also has a few helper functions that allows storing the results to a
file and loading it back.

Instead of having the file-checker object that would compare the
extracted values from the file to expected results set to its properties,
the media-info will store the values and it will be possible to compare
old media-info with new media-info from the same file. This allows
tracking improvements and regressions on different gstreamer versions.

Right now, the media-info is very tiny and doesn't store much info, only
the uri and the file size in bytes, but it will receive more additions in
the upcoming commits for storing duration, media topology, seekability and
playback information.
This commit is contained in:
Thiago Santos 2013-08-19 16:38:13 -03:00
parent 6a3070a1e4
commit 1c32bbbac3
7 changed files with 195 additions and 443 deletions

View file

@ -10,14 +10,13 @@ libgstvalidate_@GST_API_VERSION@_la_SOURCES = \
gst-validate-scenario.c \ gst-validate-scenario.c \
gst-validate-override.c \ gst-validate-override.c \
gst-validate-override-registry.c \ gst-validate-override-registry.c \
gst-validate-file-checker.c \ gst-validate-media-info.c \
validate.c validate.c
noinst_HEADERS = \ noinst_HEADERS = \
gettext.h \ gettext.h \
gst-validate-bin-monitor.h \ gst-validate-bin-monitor.h \
gst-validate-element-monitor.h \ gst-validate-element-monitor.h \
gst-validate-file-checker.h \
gst-validate-i18n-lib.h \ gst-validate-i18n-lib.h \
gst-validate-monitor-factory.h \ gst-validate-monitor-factory.h \
gst-validate-monitor.h \ gst-validate-monitor.h \
@ -27,7 +26,8 @@ noinst_HEADERS = \
gst-validate-reporter.h \ gst-validate-reporter.h \
gst-validate-report.h \ gst-validate-report.h \
gst-validate-runner.h \ gst-validate-runner.h \
gst-validate-scenario.h gst-validate-scenario.h \
gst-validate-media-info.h
lib_LTLIBRARIES = \ lib_LTLIBRARIES = \
libgstvalidate-@GST_API_VERSION@.la \ libgstvalidate-@GST_API_VERSION@.la \

View file

@ -13,9 +13,8 @@
#include <gst/validate/validate.h> #include <gst/validate/validate.h>
#include <gst/pbutils/encoding-profile.h> #include <gst/pbutils/encoding-profile.h>
static GstEncodingProfile *encoding_profile = NULL;
/* move this into some utils file */ /* move this into some utils file */
#if 0
static gboolean static gboolean
_parse_encoding_profile (const gchar * option_name, const gchar * value, _parse_encoding_profile (const gchar * option_name, const gchar * value,
gpointer udata, GError ** error) gpointer udata, GError ** error)
@ -140,59 +139,34 @@ _parse_encoding_profile (const gchar * option_name, const gchar * value,
return TRUE; return TRUE;
} }
#endif
int int
main (int argc, gchar ** argv) main (int argc, gchar ** argv)
{ {
GstValidateRunner *runner;
GOptionContext *ctx; GOptionContext *ctx;
GstValidateFileChecker *fc; GstValidateMediaInfo mi;
GError *err = NULL; GError *err = NULL;
guint count = -1; gchar *output_file = NULL;
gchar *output = NULL;
gboolean playback = FALSE, seekable = FALSE, reverse_playback = FALSE; gsize outputlength;
gint64 filesize = 0, filesize_tolerance = 0, duration_arg =
0, duration_tolerance = 0;
GstClockTime duration = GST_CLOCK_TIME_NONE;
GOptionEntry options[] = { GOptionEntry options[] = {
{"expected-profile", 'o', 0, G_OPTION_ARG_CALLBACK, {"output-file", 'o', 0, G_OPTION_ARG_FILENAME,
&_parse_encoding_profile, &output_file, "The output file to store the results",
"Set the properties to use for the encoding profile "
"to be used as expected for the file. For example:\n"
"video/mpegts:video/x-raw-yuv,width=1920,height=1080->video/x-h264:audio/x-ac3\n"
"A preset name can be used by adding +presetname, eg:\n"
"video/webm:video/x-vp8+mypreset:audio/x-vorbis\n"
"The presence property of the profile can be specified with |<presence>, eg:\n"
"video/webm:video/x-vp8|<presence>:audio/x-vorbis\n",
"properties-values"},
{"seekable", 's', 0, G_OPTION_ARG_NONE,
&seekable, "If the file should be seekable",
NULL}, NULL},
{"playback", 'p', 0, G_OPTION_ARG_NONE,
&playback, "If the file should be tested for playback",
NULL},
{"reverse-playback", '\0', 0, G_OPTION_ARG_NONE,
&reverse_playback,
"If the file should be tested for reverse playback",
NULL},
{"file-size", '\0', 0, G_OPTION_ARG_INT64, &filesize,
"The expected file size in bytes", NULL},
{"file-size-tolerance", '\0', 0, G_OPTION_ARG_INT64, &filesize_tolerance,
"The file size margin tolerance, in bytes", NULL},
{"duration", 'd', 0, G_OPTION_ARG_INT64, &duration_arg,
"The expected file duration in nanoseconds", NULL},
{"duration-tolerance", '\0', 0, G_OPTION_ARG_INT64, &duration_tolerance,
"The file duration tolerance margin, in nanoseconds", NULL},
{NULL} {NULL}
}; };
g_set_prgname ("gst-validate-file-check-" GST_API_VERSION); g_set_prgname ("gst-validate-file-check-" GST_API_VERSION);
ctx = g_option_context_new ("[URI]"); ctx = g_option_context_new ("[URI]");
g_option_context_set_summary (ctx, "Does conformance checks on files. " g_option_context_set_summary (ctx, "Analizes a media file and writes "
"Use the options to enable the tests to be made and pass the expected" "the results to stdout or a file. Can also compare the results found "
" results"); "with another results file for identifying regressions. The monitoring"
" lib from gst-validate will be enabled during the tests to identify "
"issues with the gstreamer elements involved with the media file's "
"container and codec types");
g_option_context_add_main_entries (ctx, options, NULL); g_option_context_add_main_entries (ctx, options, NULL);
if (!g_option_context_parse (ctx, &argc, &argv, &err)) { if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
@ -201,42 +175,28 @@ main (int argc, gchar ** argv)
exit (1); exit (1);
} }
g_option_context_free (ctx);
gst_init (&argc, &argv); gst_init (&argc, &argv);
gst_validate_init (); gst_validate_init ();
if (argc != 2) { if (argc != 2) {
g_printerr ("%i arguments recived, 1 expected.\n" gchar *msg = g_option_context_get_help (ctx, TRUE, NULL);
"You should run the test using:\n" g_printerr ("%s\n", msg);
" ./gst-validate-file-check-0.10 <uri> [options]\n", argc - 1); g_free (msg);
g_option_context_free (ctx);
return 1; return 1;
} }
g_option_context_free (ctx);
if (duration_arg > 0) gst_validate_media_info_init (&mi);
duration = (GstClockTime) duration_arg; gst_validate_media_info_inspect_uri (&mi, argv[1], NULL);
output = gst_validate_media_info_to_string (&mi, &outputlength);
/* Create the pipeline */ if (output_file)
runner = gst_validate_runner_new (); gst_validate_media_info_save (&mi, output_file, NULL);
fc = g_object_new (GST_TYPE_VALIDATE_FILE_CHECKER, "uri",
argv[1], "profile", encoding_profile, "qa-runner", runner,
"is-seekable", seekable, "test-playback", playback,
"test-reverse-playback", reverse_playback,
"file-size", (guint64) filesize, "file-size-tolerance", (guint64)
filesize_tolerance, "duration", (guint64) duration,
"duration-tolerance", (guint64) duration_tolerance, NULL);
g_print ("Starting tests\n"); gst_validate_media_info_clear (&mi);
if (!gst_validate_file_checker_run (fc)) {
g_print ("Failed file checking\n");
}
count = gst_validate_runner_get_reports_count (runner);
g_print ("Tests finished, total issues found: %u\n", count);
g_object_unref (fc);
g_object_unref (runner); g_print ("Media info:\n%s\n", output);
g_free (output);
if (count)
return -1;
return 0; return 0;
} }

View file

@ -1,93 +0,0 @@
/* GStreamer
* Copyright (C) 2013 Thiago Santos <thiago.sousa.santos@collabora.com>
*
* gst-validate-file-checker.h - Validate File conformance check utility functions / structs
*
* 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.1 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_VALIDATE_FILE_CHECK_H__
#define __GST_VALIDATE_FILE_CHECK_H__
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>
G_BEGIN_DECLS
#define GST_TYPE_VALIDATE_FILE_CHECKER (gst_validate_file_checker_get_type ())
#define GST_IS_VALIDATE_FILE_CHECKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VALIDATE_FILE_CHECKER))
#define GST_IS_VALIDATE_FILE_CHECKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VALIDATE_FILE_CHECKER))
#define GST_VALIDATE_FILE_CHECKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VALIDATE_FILE_CHECKER, GstValidateFileCheckerClass))
#define GST_VALIDATE_FILE_CHECKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VALIDATE_FILE_CHECKER, GstValidateFileChecker))
#define GST_VALIDATE_FILE_CHECKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VALIDATE_FILE_CHECKER, GstValidateFileCheckerClass))
#define GST_VALIDATE_FILE_CHECKER_CAST(obj) ((GstValidateFileChecker*)(obj))
#define GST_VALIDATE_FILE_CHECKER_CLASS_CAST(klass) ((GstValidateFileCheckerClass*)(klass))
typedef struct _GstValidateFileChecker GstValidateFileChecker;
typedef struct _GstValidateFileCheckerClass GstValidateFileCheckerClass;
/**
* GstValidateFileChecker:
*
* GStreamer Validate FileChecker class.
*
* Class that wraps a #GObject for Validate checks
*/
struct _GstValidateFileChecker {
GObject object;
/* <File checking data> */
/* Value for the expected total duration of the file in nanosecs
* Set to GST_CLOCK_TIME_NONE if it shouldn't be tested */
GstClockTime duration;
/* Acceptable tolerance for duration */
GstClockTime duration_tolerance;
/* Expected file_size, set to 0 to skip test */
guint64 file_size;
/* Acceptable tolerance for file_size check */
guint64 file_size_tolerance;
gboolean seekable; /* TODO should we care about disabling this check? */
gboolean test_playback;
gboolean test_reverse_playback;
gchar *uri;
/* Set to NULL to skip check */
GstEncodingProfile *profile;
};
/**
* GstValidateFileCheckerClass:
* @parent_class: parent
*
* GStreamer Validate FileChecker object class.
*/
struct _GstValidateFileCheckerClass {
GObjectClass parent_class;
};
/* normal GObject stuff */
GType gst_validate_file_checker_get_type (void);
gboolean gst_validate_file_checker_run (GstValidateFileChecker * fc);
G_END_DECLS
#endif /* __GST_VALIDATE_FILE_CHECK_H__ */

View file

@ -1,7 +1,7 @@
/* GStreamer /* GStreamer
* Copyright (C) 2013 Thiago Santos <thiago.sousa.santos@collabora.com> * Copyright (C) 2013 Thiago Santos <thiago.sousa.santos@collabora.com>
* *
* gst-validate-file-checker.c - Validate File conformance check utility functions / structs * gst-validate-media-info.c
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
@ -24,256 +24,87 @@
# include "config.h" # include "config.h"
#endif #endif
#include "gst-validate-file-checker.h" #include "gst-validate-media-info.h"
#include "gst-validate-reporter.h"
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <gst/pbutils/pbutils.h>
enum void
{ gst_validate_media_info_init (GstValidateMediaInfo * mi)
PROP_0,
PROP_RUNNER,
PROP_URI,
PROP_PROFILE,
PROP_DURATION,
PROP_DURATION_TOLERANCE,
PROP_FILE_SIZE,
PROP_FILE_SIZE_TOLERANCE,
PROP_SEEKABLE,
PROP_TEST_PLAYBACK,
PROP_TEST_REVERSE_PLAYBACK,
PROP_LAST
};
#define DEFAULT_DURATION GST_CLOCK_TIME_NONE
#define DEFAULT_DURATION_TOLERANCE 0
#define DEFAULT_FILE_SIZE 0
#define DEFAULT_FILE_SIZE_TOLERANCE 0
#define DEFAULT_SEEKABLE FALSE
#define DEFAULT_PLAYBACK FALSE
#define DEFAULT_REVERSE_PLAYBACK FALSE
GST_DEBUG_CATEGORY_STATIC (gst_validate_file_checker_debug);
#define GST_CAT_DEFAULT gst_validate_file_checker_debug
static void
gst_validate_file_checker_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void
gst_validate_file_checker_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
#define _do_init \
GST_DEBUG_CATEGORY_INIT (gst_validate_file_checker_debug, "qa_file_checker", 0, "VALIDATE FileChecker");\
G_IMPLEMENT_INTERFACE (GST_TYPE_VALIDATE_REPORTER, _reporter_iface_init)
static void
_reporter_iface_init (GstValidateReporterInterface * iface)
{ {
mi->uri = NULL;
mi->file_size = 0;
mi->duration = GST_CLOCK_TIME_NONE;
mi->seekable = FALSE;
mi->stream_info = NULL;
} }
#define gst_validate_file_checker_parent_class parent_class void
G_DEFINE_TYPE_WITH_CODE (GstValidateFileChecker, gst_validate_file_checker, gst_validate_media_info_clear (GstValidateMediaInfo * mi)
G_TYPE_OBJECT, _do_init);
static void
gst_validate_file_checker_dispose (GObject * object)
{ {
G_OBJECT_CLASS (parent_class)->dispose (object); g_free (mi->uri);
if (mi->stream_info)
gst_object_unref (mi->stream_info);
} }
static void gchar *
gst_validate_file_checker_finalize (GObject * object) gst_validate_media_info_to_string (GstValidateMediaInfo * mi, gsize * length)
{ {
GstValidateFileChecker *fc = GST_VALIDATE_FILE_CHECKER_CAST (object); GKeyFile *kf = g_key_file_new ();
gchar *data = NULL;
gst_validate_reporter_set_name (GST_VALIDATE_REPORTER (object), NULL); /* file info */
g_key_file_set_string (kf, "file-info", "uri", mi->uri);
g_key_file_set_uint64 (kf, "file-info", "file-size", mi->file_size);
g_free (fc->uri); data = g_key_file_to_data (kf, length, NULL);
if (fc->profile) g_key_file_free (kf);
gst_encoding_profile_unref (fc->profile);
G_OBJECT_CLASS (parent_class)->finalize (object); return data;
} }
static void gboolean
gst_validate_file_checker_class_init (GstValidateFileCheckerClass * klass) gst_validate_media_info_save (GstValidateMediaInfo * mi, const gchar * path,
GError ** err)
{ {
GObjectClass *gobject_class; gchar *data = NULL;
gsize datalength = 0;
gobject_class = G_OBJECT_CLASS (klass); data = gst_validate_media_info_to_string (mi, &datalength);
gobject_class->get_property = gst_validate_file_checker_get_property; g_file_set_contents (path, data, datalength, err);
gobject_class->set_property = gst_validate_file_checker_set_property; if (err)
gobject_class->dispose = gst_validate_file_checker_dispose; return FALSE;
gobject_class->finalize = gst_validate_file_checker_finalize; return TRUE;
g_object_class_install_property (gobject_class, PROP_RUNNER,
g_param_spec_object ("qa-runner", "VALIDATE Runner",
"The Validate runner to " "report errors to",
GST_TYPE_VALIDATE_RUNNER,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_URI,
g_param_spec_string ("uri", "URI", "The URI of the file to be checked",
NULL, G_PARAM_READWRITE | G_PARAM_STATIC_NAME));
g_object_class_install_property (gobject_class, PROP_PROFILE,
g_param_spec_object ("profile", "Profile",
"The GstEncodingProfile " "that should match what the file contains",
GST_TYPE_ENCODING_PROFILE, G_PARAM_READWRITE | G_PARAM_STATIC_NAME));
g_object_class_install_property (gobject_class, PROP_DURATION,
g_param_spec_uint64 ("duration", "duration", "Stream duration "
"in nanosecs, use GST_CLOCK_TIME_NONE to disable this check",
0, G_MAXUINT64, DEFAULT_DURATION,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME));
g_object_class_install_property (gobject_class, PROP_DURATION_TOLERANCE,
g_param_spec_uint64 ("duration-tolerance", "duration tolerance",
"Acceptable margin of error of the duration check (in nanoseconds)",
0, G_MAXUINT64, DEFAULT_DURATION_TOLERANCE,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME));
g_object_class_install_property (gobject_class, PROP_FILE_SIZE,
g_param_spec_uint64 ("file-size", "file size", "File size in bytes",
0, G_MAXUINT64, DEFAULT_FILE_SIZE,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME));
g_object_class_install_property (gobject_class, PROP_FILE_SIZE_TOLERANCE,
g_param_spec_uint64 ("file-size-tolerance", "file size tolerance",
"Acceptable margin of error of the file size check (in bytes)",
0, G_MAXUINT64, DEFAULT_FILE_SIZE_TOLERANCE,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME));
g_object_class_install_property (gobject_class, PROP_SEEKABLE,
g_param_spec_boolean ("is-seekable", "is seekable",
"If the resulting file should be seekable", DEFAULT_SEEKABLE,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME));
g_object_class_install_property (gobject_class, PROP_TEST_PLAYBACK,
g_param_spec_boolean ("test-playback", "test playback",
"If the file should be tested for playback", DEFAULT_PLAYBACK,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME));
g_object_class_install_property (gobject_class, PROP_TEST_REVERSE_PLAYBACK,
g_param_spec_boolean ("test-reverse-playback", "test reverse playback",
"If the file should be tested for reverse playback",
DEFAULT_REVERSE_PLAYBACK, G_PARAM_READWRITE | G_PARAM_STATIC_NAME));
} }
static void GstValidateMediaInfo *
gst_validate_file_checker_init (GstValidateFileChecker * fc) gst_validate_media_info_load (const gchar * path, GError ** err)
{ {
fc->uri = NULL; GKeyFile *kf = g_key_file_new ();
fc->profile = NULL; GstValidateMediaInfo *mi;
fc->duration = DEFAULT_DURATION;
fc->duration_tolerance = DEFAULT_DURATION_TOLERANCE; if (!g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, err)) {
fc->file_size = DEFAULT_FILE_SIZE; g_key_file_free (kf);
fc->file_size_tolerance = DEFAULT_FILE_SIZE_TOLERANCE; return NULL;
fc->seekable = DEFAULT_SEEKABLE;
fc->test_playback = DEFAULT_PLAYBACK;
fc->test_reverse_playback = DEFAULT_REVERSE_PLAYBACK;
} }
static void mi = g_new (GstValidateMediaInfo, 1);
gst_validate_file_checker_set_property (GObject * object, guint prop_id, gst_validate_media_info_init (mi);
const GValue * value, GParamSpec * pspec)
{
GstValidateFileChecker *fc;
fc = GST_VALIDATE_FILE_CHECKER_CAST (object); mi->uri = g_key_file_get_string (kf, "file-info", "uri", err);
if (err)
goto end;
mi->file_size = g_key_file_get_uint64 (kf, "file-info", "file-size", err);
if (err)
goto end;
switch (prop_id) { end:
case PROP_RUNNER: g_key_file_free (kf);
gst_validate_reporter_set_runner (GST_VALIDATE_REPORTER (fc), return mi;
g_value_get_object (value));
break;
case PROP_URI:
g_free (fc->uri);
fc->uri = g_value_dup_string (value);
break;
case PROP_PROFILE:
if (fc->profile)
gst_encoding_profile_unref (fc->profile);
fc->profile = (GstEncodingProfile *) g_value_get_object (value);
break;
case PROP_DURATION:
fc->duration = g_value_get_uint64 (value);
break;
case PROP_DURATION_TOLERANCE:
fc->duration_tolerance = g_value_get_uint64 (value);
break;
case PROP_FILE_SIZE:
fc->file_size = g_value_get_uint64 (value);
break;
case PROP_FILE_SIZE_TOLERANCE:
fc->file_size_tolerance = g_value_get_uint64 (value);
break;
case PROP_SEEKABLE:
fc->seekable = g_value_get_boolean (value);
break;
case PROP_TEST_PLAYBACK:
fc->test_playback = g_value_get_boolean (value);
break;
case PROP_TEST_REVERSE_PLAYBACK:
fc->test_reverse_playback = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_validate_file_checker_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstValidateFileChecker *fc;
fc = GST_VALIDATE_FILE_CHECKER_CAST (object);
switch (prop_id) {
case PROP_RUNNER:
g_value_set_object (value,
gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (fc)));
break;
case PROP_URI:
g_value_set_string (value, fc->uri);
break;
case PROP_PROFILE:
g_value_set_object (value, fc->profile);
break;
case PROP_DURATION:
g_value_set_uint64 (value, fc->duration);
break;
case PROP_DURATION_TOLERANCE:
g_value_set_uint64 (value, fc->duration_tolerance);
break;
case PROP_FILE_SIZE:
g_value_set_uint64 (value, fc->file_size);
break;
case PROP_FILE_SIZE_TOLERANCE:
g_value_set_uint64 (value, fc->file_size_tolerance);
break;
case PROP_SEEKABLE:
g_value_set_boolean (value, fc->seekable);
break;
case PROP_TEST_PLAYBACK:
g_value_set_boolean (value, fc->test_playback);
break;
case PROP_TEST_REVERSE_PLAYBACK:
g_value_set_boolean (value, fc->test_reverse_playback);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
} }
static gboolean static gboolean
check_file_size (GstValidateFileChecker * fc) check_file_size (GstValidateMediaInfo * mi)
{ {
GStatBuf statbuf; GStatBuf statbuf;
gchar *filepath; gchar *filepath;
@ -281,10 +112,12 @@ check_file_size (GstValidateFileChecker * fc)
gboolean ret = TRUE; gboolean ret = TRUE;
GError *err; GError *err;
filepath = g_filename_from_uri (fc->uri, NULL, &err); filepath = g_filename_from_uri (mi->uri, NULL, &err);
if (!filepath) { if (!filepath) {
#if 0
GST_VALIDATE_REPORT (fc, GST_VALIDATE_ISSUE_ID_FILE_NOT_FOUND, GST_VALIDATE_REPORT (fc, GST_VALIDATE_ISSUE_ID_FILE_NOT_FOUND,
"Failed to get filepath from uri %s. %s", fc->uri, err->message); "Failed to get filepath from uri %s. %s", fc->uri, err->message);
#endif
g_error_free (err); g_error_free (err);
return FALSE; return FALSE;
} }
@ -292,37 +125,28 @@ check_file_size (GstValidateFileChecker * fc)
if (g_stat (filepath, &statbuf) == 0) { if (g_stat (filepath, &statbuf) == 0) {
size = statbuf.st_size; size = statbuf.st_size;
} else { } else {
#if 0
GST_VALIDATE_REPORT (fc, GST_VALIDATE_ISSUE_ID_FILE_NOT_FOUND, GST_VALIDATE_REPORT (fc, GST_VALIDATE_ISSUE_ID_FILE_NOT_FOUND,
"Failed to get file stats from uri %s", fc->uri); "Failed to get file stats from uri %s", fc->uri);
#endif
ret = FALSE; ret = FALSE;
goto end; goto end;
} }
if (size == 0) { mi->file_size = size;
GST_VALIDATE_REPORT (fc, GST_VALIDATE_ISSUE_ID_FILE_SIZE_IS_ZERO,
"File %s has size 0", fc->uri);
ret = FALSE;
} else if (fc->file_size != 0
&& (size < fc->file_size - fc->file_size_tolerance
|| size > fc->file_size + fc->file_size_tolerance)) {
GST_VALIDATE_REPORT (fc, GST_VALIDATE_ISSUE_ID_FILE_SIZE_INCORRECT,
"File %s has size %" G_GUINT64_FORMAT ", it was expected to have %"
G_GUINT64_FORMAT " (+-%" G_GUINT64_FORMAT ")", fc->uri, size,
fc->file_size, fc->file_size_tolerance);
ret = FALSE;
goto end;
}
end: end:
g_free (filepath); g_free (filepath);
return ret; return ret;
} }
#if 0
static gboolean static gboolean
check_file_duration (GstValidateFileChecker * fc, GstDiscovererInfo * info) check_file_duration (GstValidateFileChecker * fc, GstDiscovererInfo * info)
{ {
GstClockTime real_duration; fc->results.duration = gst_discoverer_info_get_duration (info);
#if 0
if (!GST_CLOCK_TIME_IS_VALID (fc->duration)) if (!GST_CLOCK_TIME_IS_VALID (fc->duration))
return TRUE; return TRUE;
@ -336,14 +160,17 @@ check_file_duration (GstValidateFileChecker * fc, GstDiscovererInfo * info)
GST_TIME_ARGS (fc->duration_tolerance)); GST_TIME_ARGS (fc->duration_tolerance));
return FALSE; return FALSE;
} }
#endif
return TRUE; return TRUE;
} }
static gboolean static gboolean
check_seekable (GstValidateFileChecker * fc, GstDiscovererInfo * info) check_seekable (GstValidateFileChecker * fc, GstDiscovererInfo * info)
{ {
gboolean real_seekable; fc->results.seekable = gst_discoverer_info_get_seekable (info);
#if 0
real_seekable = gst_discoverer_info_get_seekable (info); real_seekable = gst_discoverer_info_get_seekable (info);
if (real_seekable != fc->seekable) { if (real_seekable != fc->seekable) {
GST_VALIDATE_REPORT (fc, GST_VALIDATE_ISSUE_ID_FILE_SEEKABLE_INCORRECT, GST_VALIDATE_REPORT (fc, GST_VALIDATE_ISSUE_ID_FILE_SEEKABLE_INCORRECT,
@ -351,6 +178,7 @@ check_seekable (GstValidateFileChecker * fc, GstDiscovererInfo * info)
fc->seekable ? "" : "not", real_seekable ? "is" : "isn't"); fc->seekable ? "" : "not", real_seekable ? "is" : "isn't");
return FALSE; return FALSE;
} }
#endif
return TRUE; return TRUE;
} }
@ -364,6 +192,7 @@ _gst_caps_can_intersect_safe (const GstCaps * a, const GstCaps * b)
return gst_caps_can_intersect (a, b); return gst_caps_can_intersect (a, b);
} }
#if 0
typedef struct typedef struct
{ {
GstEncodingProfile *profile; GstEncodingProfile *profile;
@ -574,18 +403,16 @@ end:
return ret; return ret;
} }
#endif
static gboolean static gboolean
check_encoding_profile (GstValidateFileChecker * fc, GstDiscovererInfo * info) check_encoding_profile (GstValidateFileChecker * fc, GstDiscovererInfo * info)
{ {
GstEncodingProfile *profile = fc->profile;
GstDiscovererStreamInfo *stream;
gboolean ret = TRUE; gboolean ret = TRUE;
gchar *msg = NULL;
if (profile == NULL) fc->results.stream_info = gst_discoverer_info_get_stream_info (info);
return TRUE;
#if 0
stream = gst_discoverer_info_get_stream_info (info); stream = gst_discoverer_info_get_stream_info (info);
if (!compare_encoding_profile_with_discoverer_stream (fc, fc->profile, stream, if (!compare_encoding_profile_with_discoverer_stream (fc, fc->profile, stream,
@ -595,6 +422,7 @@ check_encoding_profile (GstValidateFileChecker * fc, GstDiscovererInfo * info)
} }
gst_discoverer_stream_info_unref (stream); gst_discoverer_stream_info_unref (stream);
#endif
return ret; return ret;
} }
@ -674,8 +502,10 @@ end:
static gboolean static gboolean
check_playback (GstValidateFileChecker * fc) check_playback (GstValidateFileChecker * fc)
{ {
#if 0
if (!fc->test_playback) if (!fc->test_playback)
return TRUE; return TRUE;
#endif
return check_playback_scenario (fc, NULL, "Playback"); return check_playback_scenario (fc, NULL, "Playback");
} }
@ -697,42 +527,48 @@ send_reverse_seek (GstValidateFileChecker * fc, GstElement * pipeline)
static gboolean static gboolean
check_reverse_playback (GstValidateFileChecker * fc) check_reverse_playback (GstValidateFileChecker * fc)
{ {
#if 0
if (!fc->test_reverse_playback) if (!fc->test_reverse_playback)
return TRUE; return TRUE;
#endif
return check_playback_scenario (fc, send_reverse_seek, "Reverse playback"); return check_playback_scenario (fc, send_reverse_seek, "Reverse playback");
} }
#endif
gboolean gboolean
gst_validate_file_checker_run (GstValidateFileChecker * fc) gst_validate_media_info_inspect_uri (GstValidateMediaInfo * mi,
const gchar * uri, GError ** err)
{ {
GError *err = NULL;
GstDiscovererInfo *info; GstDiscovererInfo *info;
GstDiscoverer *discoverer = gst_discoverer_new (GST_SECOND * 60, &err); GstDiscoverer *discoverer = gst_discoverer_new (GST_SECOND * 60, err);
gboolean ret = TRUE; gboolean ret = TRUE;
g_return_val_if_fail (fc->uri != NULL, FALSE); g_return_val_if_fail (uri != NULL, FALSE);
g_free (mi->uri);
mi->uri = g_strdup (uri);
if (!discoverer) { if (!discoverer) {
GST_VALIDATE_REPORT (fc, GST_VALIDATE_ISSUE_ID_ALLOCATION_FAILURE,
"Failed to create GstDiscoverer");
return FALSE; return FALSE;
} }
info = gst_discoverer_discover_uri (discoverer, fc->uri, &err); info = gst_discoverer_discover_uri (discoverer, uri, err);
if (gst_discoverer_info_get_result (info) != GST_DISCOVERER_OK) { if (gst_discoverer_info_get_result (info) != GST_DISCOVERER_OK) {
GST_VALIDATE_REPORT (fc, GST_VALIDATE_ISSUE_ID_FILE_CHECK_FAILURE, gst_object_unref (discoverer);
"Discoverer failed to discover the file, result: %d",
gst_discoverer_info_get_result (info));
return FALSE; return FALSE;
} }
ret = check_file_size (fc) & ret; ret = check_file_size (mi) & ret;
ret = check_file_duration (fc, info) & ret; #if 0
ret = check_seekable (fc, info) & ret; ret = check_file_duration (mi, info) & ret;
ret = check_encoding_profile (fc, info) & ret; ret = check_seekable (mi, info) & ret;
ret = check_playback (fc) & ret; ret = check_encoding_profile (mi, info) & ret;
ret = check_reverse_playback (fc) & ret; ret = check_playback (mi) & ret;
ret = check_reverse_playback (mi) & ret;
#endif
gst_object_unref (discoverer);
return ret; return ret;
} }

View file

@ -0,0 +1,68 @@
/* GStreamer
* Copyright (C) 2013 Thiago Santos <thiago.sousa.santos@collabora.com>
*
* gst-validate-media-info.h - Media information structure
*
* 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.1 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_VALIDATE_MEDIA_INFO_H__
#define __GST_VALIDATE_MEDIA_INFO_H__
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>
G_BEGIN_DECLS
typedef struct _GstValidateMediaInfo GstValidateMediaInfo;
/**
* GstValidateMediaInfo:
*
* GStreamer Validate MediaInfo struct.
*
* Stores extracted information about a media
*/
struct _GstValidateMediaInfo {
/* <File checking data> */
/* Value for the expected total duration of the file in nanosecs
* Set to GST_CLOCK_TIME_NONE if it shouldn't be tested */
GstClockTime duration;
/* Expected file_size, set to 0 to skip test */
guint64 file_size;
gboolean seekable;
gchar *uri;
GstDiscovererStreamInfo *stream_info;
};
void gst_validate_media_info_init (GstValidateMediaInfo * mi);
void gst_validate_media_info_clear (GstValidateMediaInfo * mi);
gchar * gst_validate_media_info_to_string (GstValidateMediaInfo * mi, gsize * length);
gboolean gst_validate_media_info_save (GstValidateMediaInfo * mi, const gchar * path, GError ** err);
GstValidateMediaInfo * gst_validate_media_info_load (const gchar * path, GError ** err);
gboolean gst_validate_media_info_inspect_uri (GstValidateMediaInfo * mi, const gchar * uri, GError ** err);
G_END_DECLS
#endif /* __GST_VALIDATE_MEDIA_INFO_H__ */

View file

@ -13,9 +13,6 @@
#include <gst/validate/validate.h> #include <gst/validate/validate.h>
#include <gst/pbutils/encoding-profile.h> #include <gst/pbutils/encoding-profile.h>
#include "gst-validate-file-checker.h"
static GMainLoop *mainloop; static GMainLoop *mainloop;
static GstElement *pipeline; static GstElement *pipeline;
static GstEncodingProfile *encoding_profile = NULL; static GstEncodingProfile *encoding_profile = NULL;
@ -255,7 +252,6 @@ main (int argc, gchar ** argv)
GError *err = NULL; GError *err = NULL;
const gchar *scenario = NULL; const gchar *scenario = NULL;
guint count = -1; guint count = -1;
gboolean run_file_checks = FALSE;
GOptionEntry options[] = { GOptionEntry options[] = {
{"output-format", 'o', 0, G_OPTION_ARG_CALLBACK, &_parse_encoding_profile, {"output-format", 'o', 0, G_OPTION_ARG_CALLBACK, &_parse_encoding_profile,
@ -270,9 +266,6 @@ main (int argc, gchar ** argv)
{"set-scenario", '\0', 0, G_OPTION_ARG_STRING, &scenario, {"set-scenario", '\0', 0, G_OPTION_ARG_STRING, &scenario,
"Let you set a scenario, it will override the GST_VALIDATE_SCENARIO " "Let you set a scenario, it will override the GST_VALIDATE_SCENARIO "
"environment variable", NULL}, "environment variable", NULL},
{"run-file-checks", 'c', 0, G_OPTION_ARG_NONE,
&run_file_checks, "If post file transcoding checks should be run",
NULL},
{NULL} {NULL}
}; };
@ -348,18 +341,6 @@ exit:
g_object_unref (runner); g_object_unref (runner);
g_object_unref (pipeline); g_object_unref (pipeline);
if (run_file_checks) {
GstValidateFileChecker *fc =
g_object_new (GST_TYPE_VALIDATE_FILE_CHECKER, "uri",
argv[2], "profile", encoding_profile, "test-playback", TRUE, NULL);
if (!gst_validate_file_checker_run (fc)) {
g_print ("Failed file checking\n");
}
g_object_unref (fc);
}
if (count) if (count)
return -1; return -1;
return 0; return 0;

View file

@ -3,10 +3,10 @@
*/ */
#include <gst/validate/gst-validate-runner.h> #include <gst/validate/gst-validate-runner.h>
#include <gst/validate/gst-validate-file-checker.h>
#include <gst/validate/gst-validate-monitor-factory.h> #include <gst/validate/gst-validate-monitor-factory.h>
#include <gst/validate/gst-validate-override-registry.h> #include <gst/validate/gst-validate-override-registry.h>
#include <gst/validate/gst-validate-report.h> #include <gst/validate/gst-validate-report.h>
#include <gst/validate/gst-validate-reporter.h> #include <gst/validate/gst-validate-reporter.h>
#include <gst/validate/gst-validate-media-info.h>
void gst_validate_init (void); void gst_validate_init (void);