summaryrefslogtreecommitdiffstats
path: root/debian/transcode/transcode-1.1.7/testsuite/test-framecode.c
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2020-09-11 14:38:47 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2020-09-11 14:38:47 +0900
commit884c8093d63402a1ad0b502244b791e3c6782be3 (patch)
treea600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/transcode/transcode-1.1.7/testsuite/test-framecode.c
parent14e1aa2006796f147f3f4811fb908a6b01e79253 (diff)
downloadextra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.tar.gz
extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.zip
Added debian extra dependency packages.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'debian/transcode/transcode-1.1.7/testsuite/test-framecode.c')
-rw-r--r--debian/transcode/transcode-1.1.7/testsuite/test-framecode.c524
1 files changed, 524 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/testsuite/test-framecode.c b/debian/transcode/transcode-1.1.7/testsuite/test-framecode.c
new file mode 100644
index 00000000..557e43c6
--- /dev/null
+++ b/debian/transcode/transcode-1.1.7/testsuite/test-framecode.c
@@ -0,0 +1,524 @@
+/*
+ * test-framecode.c -- test tclib framecode handling
+ * Written by Andrew Church <achurch@achurch.org>
+ *
+ * This file is part of transcode, a video stream processing tool.
+ * transcode is free software, distributable under the terms of the GNU
+ * General Public License (version 2 or later). See the file COPYING
+ * for details.
+ */
+
+/* We define our own dummy free() for testing, so avoid string.h declaring
+ * it over us */
+#define free string_h_free
+#include <string.h>
+#undef free
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+
+#include "libtc/framecode.h"
+
+/* Global verbosity level (0: silent, 1: test list, 2: debug info) */
+static int verbose = 1;
+
+/*************************************************************************/
+
+/* Fake free() function, to enable testing of free_fc_time(). */
+
+#define FREED_POINTER ((struct fc_time *)1)
+
+void free(void *fct); /* prototype, to avoid warnings */
+void free(void *fct)
+{
+ ((struct fc_time *)fct)->next = FREED_POINTER;
+}
+
+/*************************************************************************/
+
+/* Helper routines for test_new_fc_time_from_string() to extract an integer
+ * or a framecode from a string and advance the string pointer. Both
+ * routines return nonzero on success, zero on failure. */
+
+static int get_uint(char **sptr, unsigned int *valptr)
+{
+ char *s = *sptr;
+ unsigned long lval;
+
+ if (*s < '0' || *s > '9')
+ return 0;
+ errno = 0;
+ lval = strtoul(s, sptr, 10);
+ if (errno == ERANGE
+#if ULONG_MAX > UINT_MAX
+ || lval > UINT_MAX
+#endif
+ ) {
+ return 0;
+ }
+ *valptr = (unsigned int)lval;
+ return 1;
+}
+
+static int get_fc(char **sptr, unsigned int *frameptr, double fps)
+{
+ char *s = *sptr;
+ unsigned int frame, temp;
+ int is_time = 0;
+
+ if (!get_uint(&s, &frame))
+ return 0;
+ if (*s == ':') {
+ is_time = 1;
+ s++;
+ if (!get_uint(&s, &temp))
+ return 0;
+ frame = frame*60 + temp;
+ if (*s == ':') {
+ s++;
+ if (!get_uint(&s, &temp))
+ return 0;
+ frame = frame*60 + temp;
+ }
+ }
+ if (*s == '.' || is_time) {
+ frame = (unsigned int)floor(frame * fps);
+ }
+ if (*s == '.') {
+ s++;
+ if (!get_uint(&s, &temp))
+ return 0;
+ frame += temp;
+ }
+ *sptr = s;
+ *frameptr = frame;
+ return 1;
+}
+
+/*************************************************************************/
+/*************************************************************************/
+
+/* Check that new_fc_time properly clears the fields of the allocated
+ * fc_time structure. */
+
+static int test_new_fc_time(void)
+{
+ struct fc_time *fct;
+
+ fct = new_fc_time();
+ return fct->next == NULL
+ && fct->fps == 0.0
+ && fct->stepf == 0
+ && fct->vob_offset == 0
+ && fct->sh == 0
+ && fct->sm == 0
+ && fct->ss == 0
+ && fct->sf == 0
+ && fct->stf == 0
+ && fct->eh == 0
+ && fct->em == 0
+ && fct->es == 0
+ && fct->ef == 0
+ && fct->etf == 0;
+}
+
+/*************************************************************************/
+
+/* Check that free_fc_time() properly frees all elements in a list. */
+
+static int test_free_fc_time(void)
+{
+ struct fc_time fct1, fct2, fct3;
+
+ fct1.next = &fct2;
+ fct2.next = &fct3;
+ fct3.next = NULL;
+ free_fc_time(&fct1);
+ return fct1.next == FREED_POINTER
+ && fct2.next == FREED_POINTER
+ && fct3.next == FREED_POINTER;
+}
+
+/*************************************************************************/
+
+/* Check that set_fc_time with the given parameters sets the fields of the
+ * fc_time structure properly. */
+
+static int test_set_fc_time(int start, int end, double fps)
+{
+ struct fc_time fct;
+
+ fct.next = NULL;
+ fct.fps = fps;
+ fct.stepf = 0;
+ fct.vob_offset = 0;
+ fct.sh = fct.sm = fct.ss = fct.sf = fct.stf = ~0;
+ fct.eh = fct.em = fct.es = fct.ef = fct.etf = ~0;
+ set_fc_time(&fct, start, end);
+ if (verbose >= 2) {
+ printf("[%d->%u:%u:%u.%u|%u - %d->%u:%u:%u.%u|%u @ %.1f] ",
+ start, fct.sh, fct.sm, fct.ss, fct.sf, fct.stf,
+ end, fct.eh, fct.em, fct.es, fct.ef, fct.etf,
+ fps);
+ }
+ return fct.sh == (int)floor(start/fps) / 3600
+ && fct.sm == (int)floor(start/fps) / 60 % 60
+ && fct.ss == (int)floor(start/fps) % 60
+ && fct.sf == floor(start - ((int)floor(start/fps))*fps)
+ && fct.stf == start
+ && fct.eh == (int)floor(end/fps) / 3600
+ && fct.em == (int)floor(end/fps) / 60 % 60
+ && fct.es == (int)floor(end/fps) % 60
+ && fct.ef == floor(end - ((int)floor(end/fps))*fps)
+ && fct.etf == end;
+}
+
+/*************************************************************************/
+
+/* Check that fc_time_contains properly determines whether a given frame
+ * number is contained in a list of up to three fc_time structures. When
+ * testing with less than three fc_time structures, use -1 for the start
+ * and end values as follows:
+ * Two structures -> test(frame, fps, start1, end1, start2, end2, -1, -1)
+ * One structure -> test(frame, fps, start1, end1, -1, -1, -1, -1)
+ * Assumes that set_fc_time() works correctly. */
+
+static int test_fc_time_contains(int frame, double fps,
+ int start1, int end1,
+ int start2, int end2,
+ int start3, int end3)
+{
+ struct fc_time fct1, fct2, fct3;
+ int expected; /* Do we expect it to be found or not? */
+ int result; /* What we actually got out of the function */
+
+ fct1.next = NULL;
+ fct1.fps = fps;
+ fct1.stepf = 0;
+ fct1.vob_offset = 0;
+ fct2.next = NULL;
+ fct2.fps = fps;
+ fct2.stepf = 0;
+ fct2.vob_offset = 0;
+ fct3.next = NULL;
+ fct3.fps = fps;
+ fct3.stepf = 0;
+ fct3.vob_offset = 0;
+
+ set_fc_time(&fct1, start1, end1);
+ expected = (frame >= start1 && frame < end1);
+ if (start2 >= 0 && end2 >= 0) {
+ fct1.next = &fct2;
+ set_fc_time(&fct2, start2, end2);
+ expected |= (frame >= start2 && frame < end2);
+ if (start3 >= 0 && end3 >= 0) {
+ fct2.next = &fct3;
+ set_fc_time(&fct3, start3, end3);
+ expected |= (frame >= start3 && frame < end3);
+ }
+ }
+
+ result = fc_time_contains(&fct1, frame);
+ return (expected && result) || (!expected && !result);
+}
+
+/*************************************************************************/
+
+/* Check that new_fc_time_from_string() properly parses the given string.
+ * Assumes that new_fc_time() and set_fc_time() work correctly. */
+
+static int test_new_fc_time_from_string(const char *string,
+ const char *separator,
+ double fps)
+{
+ struct fc_time *fctret, *fctexpect, *tail, *fct;
+ char strsave[1000], *s;
+
+ if (strlen(string) > sizeof(strsave)-1) {
+ fprintf(stderr, "*** test_new_fc_time_from_string(): string too long"
+ " (max %u chars)\n", (unsigned int)sizeof(strsave)-1);
+ return 0;
+ }
+
+ /* Call the function itself */
+ fctret = new_fc_time_from_string(string, separator, fps,
+ verbose>=2 ? 1 : -1);
+
+ /* Figure out what we're supposed to get; if we're supposed to get an
+ * error, return success or failure at that point */
+ fctexpect = tail = NULL;
+ snprintf(strsave, sizeof(strsave), "%s", string);
+ for (s = strtok(strsave,separator); s; s = strtok(NULL,separator)) {
+ unsigned int start = 0, end = 0, stepf = 1;
+ if (!get_fc(&s, &start, fps)
+ || *s++ != '-'
+ || !get_fc(&s, &end, fps)
+ ) {
+ return fctret == NULL;
+ }
+ if (*s == '/') {
+ s++;
+ if (!get_uint(&s, &stepf))
+ return fctret == NULL;
+ }
+ if (*s)
+ return fctret == NULL;
+ fct = new_fc_time();
+ if (!fct) {
+ fprintf(stderr, "*** Out of memory\n");
+ exit(-1);
+ }
+ fct->fps = fps;
+ fct->stepf = stepf;
+ set_fc_time(fct, start, end);
+ if (!fctexpect) {
+ fctexpect = fct;
+ } else {
+ tail->next = fct;
+ }
+ tail = fct;
+ }
+
+ /* Compare the returned list against the expected one */
+ for (fct = fctexpect; fct; fct = fct->next) {
+ if (verbose >= 2) {
+ printf("\n[[%u:%u:%u.%u|%u - %u:%u:%u.%u|%u / %u @ %.1f]]"
+ "\n<<%u:%u:%u.%u|%u - %u:%u:%u.%u|%u / %u @ (%d)>>\n",
+ fct->sh, fct->sm, fct->ss, fct->sf, fct->stf,
+ fct->eh, fct->em, fct->es, fct->ef, fct->etf,
+ fct->stepf, fct->fps,
+ fctret->sh, fctret->sm, fctret->ss, fctret->sf, fctret->stf,
+ fctret->eh, fctret->em, fctret->es, fctret->ef, fctret->etf,
+ fctret->stepf, (fctret->fps == fct->fps));
+ }
+ if (!fctret
+ || fctret->fps != fct->fps
+ || fctret->stepf != fct->stepf
+ || fctret->sh != fct->sh
+ || fctret->sm != fct->sm
+ || fctret->ss != fct->ss
+ || fctret->sf != fct->sf
+ || fctret->stf != fct->stf
+ || fctret->eh != fct->eh
+ || fctret->em != fct->em
+ || fctret->es != fct->es
+ || fctret->ef != fct->ef
+ || fctret->etf != fct->etf
+ ) {
+ return 0;
+ }
+ fctret = fctret->next;
+ }
+
+ /* Everything succeeded */
+ return 1;
+}
+
+/*************************************************************************/
+/*************************************************************************/
+
+/* Helper macro to print a test name and result status, and set the
+ * `failed' variable to nonzero if the test failed. Usage:
+ * DO_TEST("name", test_function(param1,param2));
+ * The test function is assumed to return a true value for success, a
+ * false value for failure (the return type does not matter).
+ */
+#define DO_TEST(name,test) do { \
+ if (verbose > 0) { \
+ printf("%s... ", (name)); \
+ fflush(stdout); \
+ } \
+ if (test) { \
+ if (verbose > 0) \
+ printf("ok\n"); \
+ } else { \
+ if (verbose > 0) \
+ printf("FAILED\n"); \
+ failed = 1; \
+ } \
+} while (0)
+
+/* Shorthand for test_new_fc_time_from_string() */
+#define DO_TEST_FC_STRING(str) \
+ DO_TEST("new_fc_time_from_string(" str ")", \
+ test_new_fc_time_from_string(str, ",", 10.0))
+
+/*************************************************************************/
+
+/* Main program. */
+
+int main(int argc, char *argv[])
+{
+ int failed = 0;
+ int opt;
+
+ /* Option processing */
+ while ((opt = getopt(argc, argv, "hqv")) != EOF) {
+ if (opt == 'q') {
+ verbose = 0;
+ } else if (opt == 'v') {
+ verbose = 2;
+ } else {
+ fprintf(stderr,
+ "Usage: %s [-q | -v]\n"
+ "-q: quiet (don't print list of tests)\n"
+ "-v: verbose (print debugging info)\n", argv[0]);
+ return 1;
+ }
+ }
+
+ /* Check that new_fc_time properly clears fields. */
+ DO_TEST("new_fc_time", test_new_fc_time());
+
+ /* Check that free_fc_time properly frees a multi-struct list. */
+ DO_TEST("free_fc_time", test_free_fc_time());
+
+ /* Check set_fc_time() using various frame ranges and fps.
+ * First check simple frame counts within the first second; then
+ * move on to values that require splitting between H/M/S/F; and
+ * finally check that rounding of fractional frames (downward) is
+ * performed correctly. */
+ DO_TEST("set_fc_time(0-1/10)", test_set_fc_time(0, 1, 10));
+ DO_TEST("set_fc_time(1-2/10)", test_set_fc_time(1, 2, 10));
+ DO_TEST("set_fc_time(0-10/10)", test_set_fc_time(0, 10, 10));
+ DO_TEST("set_fc_time(10-20/10)", test_set_fc_time(10, 20, 10));
+ DO_TEST("set_fc_time(0-600/10)", test_set_fc_time(0, 600, 10));
+ DO_TEST("set_fc_time(600-1200/10)", test_set_fc_time(600, 1200, 10));
+ DO_TEST("set_fc_time(0-36000/10)", test_set_fc_time(0, 36000, 10));
+ DO_TEST("set_fc_time(36000-72000/10)", test_set_fc_time(36000,72000,10));
+ DO_TEST("set_fc_time(0-37234/10)", test_set_fc_time(0, 37234, 10));
+ DO_TEST("set_fc_time(37234-74468/10)", test_set_fc_time(37234,74468,10));
+ DO_TEST("set_fc_time(0-10/8.8)", test_set_fc_time(0, 10, 8.8));
+ DO_TEST("set_fc_time(10-20/8.8)", test_set_fc_time(10, 20, 8.8));
+ DO_TEST("set_fc_time(0-10/8.2)", test_set_fc_time(0, 10, 8.2));
+ DO_TEST("set_fc_time(10-20/8.2)", test_set_fc_time(10, 20, 8.2));
+
+ /* Everything from here on down depends on set_fc_time() (and on
+ * new_fc_time() in the case of new_fc_time_from_string()), so abort
+ * now if we've failed somewhere. */
+ if (failed) {
+ fprintf(stderr, "*** Aborting due to test failures.\n");
+ return 1;
+ }
+
+ /* Test various cases with fc_time_contains():
+ * A: 1 less than the starting frame in a large range
+ * B: Equal to the starting frame in a large range
+ * C: Midway between the starting and ending frames in a large range
+ * D: 1 less than the ending frame in a large range
+ * E: Equal to the ending frame in a large range
+ * F: 1 less than the only frame in a 1-frame range
+ * G: Equal to the only frame in a 1-frame range
+ * H: 1 more than the only frame in a 1-frame range
+ * for various types of lists:
+ * 1: Only one fc_time in the list (first structure)
+ * 2: The second of a list of 2 fc_times (last structure)
+ * 3: The second of a list of 3 fc_times (middle structure)
+ */
+ DO_TEST("fc_time_contains(1A)",
+ test_fc_time_contains( 9, 10.0, 10, 20, -1, -1, -1, -1));
+ DO_TEST("fc_time_contains(1B)",
+ test_fc_time_contains(10, 10.0, 10, 20, -1, -1, -1, -1));
+ DO_TEST("fc_time_contains(1C)",
+ test_fc_time_contains(15, 10.0, 10, 20, -1, -1, -1, -1));
+ DO_TEST("fc_time_contains(1D)",
+ test_fc_time_contains(19, 10.0, 10, 20, -1, -1, -1, -1));
+ DO_TEST("fc_time_contains(1E)",
+ test_fc_time_contains(20, 10.0, 10, 20, -1, -1, -1, -1));
+ DO_TEST("fc_time_contains(1F)",
+ test_fc_time_contains( 9, 10.0, 10, 11, -1, -1, -1, -1));
+ DO_TEST("fc_time_contains(1G)",
+ test_fc_time_contains(10, 10.0, 10, 11, -1, -1, -1, -1));
+ DO_TEST("fc_time_contains(1H)",
+ test_fc_time_contains(11, 10.0, 10, 11, -1, -1, -1, -1));
+ DO_TEST("fc_time_contains(2A)",
+ test_fc_time_contains( 9, 10.0, 1, 2, 10, 20, -1, -1));
+ DO_TEST("fc_time_contains(2B)",
+ test_fc_time_contains(10, 10.0, 1, 2, 10, 20, -1, -1));
+ DO_TEST("fc_time_contains(2C)",
+ test_fc_time_contains(15, 10.0, 1, 2, 10, 20, -1, -1));
+ DO_TEST("fc_time_contains(2D)",
+ test_fc_time_contains(19, 10.0, 1, 2, 10, 20, -1, -1));
+ DO_TEST("fc_time_contains(2E)",
+ test_fc_time_contains(20, 10.0, 1, 2, 10, 20, -1, -1));
+ DO_TEST("fc_time_contains(2F)",
+ test_fc_time_contains( 9, 10.0, 1, 2, 10, 11, -1, -1));
+ DO_TEST("fc_time_contains(2G)",
+ test_fc_time_contains(10, 10.0, 1, 2, 10, 11, -1, -1));
+ DO_TEST("fc_time_contains(2H)",
+ test_fc_time_contains(11, 10.0, 1, 2, 10, 11, -1, -1));
+ DO_TEST("fc_time_contains(3A)",
+ test_fc_time_contains( 9, 10.0, 1, 2, 10, 20, 30, 40));
+ DO_TEST("fc_time_contains(3B)",
+ test_fc_time_contains(10, 10.0, 1, 2, 10, 20, 30, 40));
+ DO_TEST("fc_time_contains(3C)",
+ test_fc_time_contains(15, 10.0, 1, 2, 10, 20, 30, 40));
+ DO_TEST("fc_time_contains(3D)",
+ test_fc_time_contains(19, 10.0, 1, 2, 10, 20, 30, 40));
+ DO_TEST("fc_time_contains(3E)",
+ test_fc_time_contains(20, 10.0, 1, 2, 10, 20, 30, 40));
+ DO_TEST("fc_time_contains(3F)",
+ test_fc_time_contains( 9, 10.0, 1, 2, 10, 11, 30, 40));
+ DO_TEST("fc_time_contains(3G)",
+ test_fc_time_contains(10, 10.0, 1, 2, 10, 11, 30, 40));
+ DO_TEST("fc_time_contains(3H)",
+ test_fc_time_contains(11, 10.0, 1, 2, 10, 11, 30, 40));
+
+ /* See whether new_fc_time_from_string() works with a simple string */
+ DO_TEST_FC_STRING("10-20");
+ DO_TEST_FC_STRING("10-20/3");
+ /* Try some invalid variations */
+ DO_TEST_FC_STRING("10-");
+ DO_TEST_FC_STRING("-20");
+ DO_TEST_FC_STRING("10-20/");
+ DO_TEST_FC_STRING("a-20");
+ DO_TEST_FC_STRING("10-b");
+ DO_TEST_FC_STRING("10a-20");
+ DO_TEST_FC_STRING("10-20b");
+ DO_TEST_FC_STRING("10-20/c");
+ DO_TEST_FC_STRING("10-20/30c");
+ /* Try with multiple entries */
+ DO_TEST_FC_STRING("10-20,30-40");
+ DO_TEST_FC_STRING(",10-20,,30-40,"); // extra commas should be ignored
+ DO_TEST_FC_STRING("10-20,30-40/5,60-70");
+ DO_TEST_FC_STRING("10-20,30-40b,50-60");
+ /* Try timecodes instead of frames */
+ DO_TEST_FC_STRING("1.0-20");
+ DO_TEST_FC_STRING("10-2.0");
+ DO_TEST_FC_STRING("1:1-2000");
+ DO_TEST_FC_STRING("1-2:2");
+ DO_TEST_FC_STRING("1:08-2000"); // make sure it doesn't try to parse octal
+ DO_TEST_FC_STRING("10-2:08");
+ DO_TEST_FC_STRING("1:1:1-200000");
+ DO_TEST_FC_STRING("10-2:2:2");
+ DO_TEST_FC_STRING("1:1:1.1-200000");
+ DO_TEST_FC_STRING("10-2:2:2.2");
+ DO_TEST_FC_STRING("1:1:1.1-200000/3");
+ DO_TEST_FC_STRING("10-2:2:2.2/3");
+ /* Test invalid timecodes as well */
+ DO_TEST_FC_STRING("1:1:1:1-200000");
+ DO_TEST_FC_STRING("10-2:2:2:2");
+ DO_TEST_FC_STRING("1.1.1-200000");
+ DO_TEST_FC_STRING("10-2.2.2");
+ DO_TEST_FC_STRING("1:1:1.1.1-200000");
+ DO_TEST_FC_STRING("10-2:2:2.2.2");
+
+ /* All done, exit with appropriate status */
+ return failed ? 1 : 0;
+}
+
+/*************************************************************************/
+
+/*
+ * Local variables:
+ * c-file-style: "stroustrup"
+ * c-file-offsets: ((case-label . *) (statement-case-intro . *))
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+ */