#include <unistd.h>
#include <getopt.h>
#include <math.h>
+#include <errno.h>
#include "../src/img.h"
#include <opencv2/core/core_c.h>
#include <opencv2/imgproc/imgproc_c.h>
/* test input image */
//#define TEST_INPUT
+struct scenes {
+ struct scenes *next;
+ int frame;
+} *scenes_start = NULL;
+
int flow_window = 30, border = 0;
double limit_frames = 0;
int interlace = 0, swap = 0;
+char scenes_file[256] = "";
+
+static int load_scenes(const char *filename)
+{
+ FILE *fp;
+ struct scenes *scenes, **scenesp = &scenes_start;
+ char buffer[256];
+ int frame = 0;
+ int line = 0;
+
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Failed to open scenes file '%s'\n", filename);
+ return -EIO;
+ }
+
+ while ((fgets(buffer, sizeof(buffer), fp))) {
+ line++;
+ buffer[sizeof(buffer)-1] = '\0';
+ if (buffer[0]) buffer[strlen(buffer)-1] = '\0';
+ if (buffer[0] == '\0')
+ continue;
+ if (buffer[0] < '0' || buffer[0] > '9') {
+ fprintf(stderr, "Error in scenes file. Expecting frame number in line %d.\n", line);
+ return -EINVAL;
+ }
+ if (atoi(buffer) == 0 && frame == 0)
+ continue;
+ if (atoi(buffer) <= frame) {
+ fprintf(stderr, "Error in scenes file. Expecting ascending frame number in line %d.\n", line);
+ return -EINVAL;
+ }
+ scenes = calloc(sizeof(*scenes), 1);
+ if (!scenes)
+ return -ENOMEM;
+ scenes->frame = atoi(buffer);
+ frame = scenes->frame;
+ *scenesp = scenes;
+ scenesp = &scenes->next;
+ }
+
+ if (!scenes_start) {
+ fprintf(stderr, "Error in scenes file. No frame numbers found.\n");
+ return -EINVAL;
+ }
+
+ scenes = scenes_start;
+ frame = 0;
+ while(scenes) {
+ printf("Scene: %d - %d\n", frame, scenes->frame);
+ frame = scenes->frame;
+ scenes = scenes->next;
+ }
+ printf("Scene: %d - end\n", frame);
+
+ fclose(fp);
+ return 0;
+}
static void field_img(int width, int height, unsigned short *img, int odd)
{
printf(" -b --border <pixles> Remove border pixles, if darker than image (try 1)\n");
printf(" -w --window <size> Change optical flow window size (default %d)\n", flow_window);
printf(" -f --frames <number> Limit number of input frames (default infinite)\n");
+ printf(" -S --scenes <file> Use given file to seperate scene changes, to avoid interpolation.\n");
+ printf(" Note: Output images that would be between two scenes get dropped.\n");
+ printf(" Frames between scene changes are dropped.\n");
+ printf(" The list must contain one frame number per line in ascending order.\n");
printf(" -i --interlace Handle input image as interlaced image\n");
printf(" Note: oldfps refers to frames, not the individual fields\n");
printf(" -e --even Use even lines for first field, instead of odd lines\n");
{"border", 1, 0, 'b'},
{"window", 1, 0, 'w'},
{"frames", 1, 0, 'f'},
+ {"scenes", 1, 0, 'S'},
{"interlace", 0, 0, 'i'},
{"even", 0, 0, 'e'},
{0, 0, 0, 0},
};
- c = getopt_long(argc, argv, "hd:b:w:f:ie", long_options, &option_index);
+ c = getopt_long(argc, argv, "hd:b:w:f:S:ie", long_options, &option_index);
if (c == -1)
break;
limit_frames = atoi(optarg);
skip_args += 2;
break;
+ case 'S':
+ strcpy(scenes_file, optarg);
+ skip_args += 2;
+ break;
case 'i':
interlace = 1;
skip_args++;
skip_args++;
break;
default:
+ fprintf(stderr, "internal parse error\n");
break;
}
}
argv += skip_args + 1;
if (argc != 6) {
+ if (argc > 1)
+ fprintf(stderr, "Please give correct number of arguments!\n\n");
print_help(app_name);
return 0;
}
printf("Optical Flow window: %d\n", flow_window);
if (limit_frames)
printf("Limit number of input frames: %.0f\n", limit_frames);
+ if (scenes_file[0]) {
+ rc = load_scenes(scenes_file);
+ if (rc)
+ goto out;
+ }
next_frame:
+ /* calc and round baseframe and offet */
baseframe = floor(inputframe);
offset = inputframe - baseframe;
if (offset < 0.001)
offset = 0.0;
baseframe++;
}
+ /* detect scene change */
+ if (scenes_start) {
+ /* check if we passed a scene change */
+ while (scenes_start && scenes_start->frame <= baseframe) {
+ printf("Enter new scene at frame %d\n", scenes_start->frame);
+ scenes_start = scenes_start->next;
+ }
+ }
+ if (scenes_start) {
+ /* check if we would interpolate between scenes, so we skip that */
+ if (scenes_start->frame == baseframe+1 /* next frame has a new scene */
+ && offset >= 0.0 /* not just copy base frame */
+ && !(interlace && offset <= 0.5)) { /* not interpolate interlaced fields */
+ printf("Skipping frame %.4f due to scene change at frame %d\n", inputframe, scenes_start->frame);
+ inputframe = baseframe+1;
+ scenes_start = scenes_start->next;
+ goto next_frame;
+ }
+ }
+ /* copy frames that match exactly */
if (offset == 0.0 || (interlace && offset == 0.5)) {
if (interlace) {
if (offset < 0.5)
if (rc < 0)
goto out;
} else {
+ /* interpolate frames that are in between */
printf("Processing input frame %.4f, output frame %d\n", inputframe, outputframe);
img1 = load_img(&width, &height, inputname, baseframe);
if (!img1)