Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

add debug flag for saving significant frames from the video

  • Loading branch information...
commit cbbaeb3de8d555c2ae7e6c00d2a1bd2637ec759a 1 parent 1fe52a0
@davepacheco authored
Showing with 52 additions and 11 deletions.
  1. +0 −3  TODO
  2. +29 −4 src/kartvid.c
  3. +22 −3 src/kv.c
  4. +1 −1  src/kv.h
View
3  TODO
@@ -10,9 +10,6 @@ Current status:
Quality of life:
- Write a tool for diffing results between two runs on the same race.
- Add a button to the UI for rerunning kartvid?
-- Add support for writing out PNG images.
-- Add a debug flag that causes kartvid to save PNG image of each significant
- frame.
Known issues:
- 2012-06-19-00.mov:
View
33 src/kartvid.c
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
+#include <sys/stat.h>
#include <png.h>
@@ -51,7 +52,7 @@ static kv_cmd_t kv_commands[] = {
{ "frames", cmd_frames, "[-j] dir_of_image_files",
"emit race events for a sequence of video frames" },
{ "rgb2hsv", cmd_rgb2hsv, "r g b", "convert rgb value to hsv" },
- { "video", cmd_video, "[-j] video_file",
+ { "video", cmd_video, "[-j] [-d debugdir] video_file",
"emit race events for an entire video" }
};
@@ -333,7 +334,7 @@ cmd_frames(int argc, char *argv[])
return (EXIT_USAGE);
}
- if ((kvp = kv_vidctx_init(dirname((char *)kv_arg0), emit)) == NULL)
+ if ((kvp = kv_vidctx_init(dirname((char *)kv_arg0), emit, NULL)) == NULL)
return (EXIT_FAILURE);
if ((dirp = opendir(argv[0])) == NULL) {
@@ -440,16 +441,21 @@ cmd_video(int argc, char *argv[])
video_t *vp;
int rv;
char c;
+ const char *dbgdir = NULL;
kv_emit_f emit;
emit = kv_screen_print;
- while ((c = getopt(argc, argv, "j")) != -1) {
+ while ((c = getopt(argc, argv, "jd:")) != -1) {
switch (c) {
case 'j':
emit = kv_screen_json;
break;
+ case 'd':
+ dbgdir = optarg;
+ break;
+
case '?':
default:
return (EXIT_USAGE);
@@ -464,6 +470,24 @@ cmd_video(int argc, char *argv[])
return (EXIT_USAGE);
}
+ /*
+ * This isn't strictly necessary, but is a useful prereq so that we
+ * don't get partway through the conversion and fail because the user
+ * forgot to create the directory.
+ */
+ if (dbgdir != NULL) {
+ struct stat st;
+ if (stat(dbgdir, &st) != 0) {
+ warn("stat %s", dbgdir);
+ return (EXIT_USAGE);
+ }
+
+ if ((st.st_mode & S_IFDIR) == 0) {
+ warnx("not a directory: %s", dbgdir);
+ return (EXIT_USAGE);
+ }
+ }
+
if ((vp = video_open(argv[0])) == NULL)
return (EXIT_FAILURE);
@@ -471,7 +495,8 @@ cmd_video(int argc, char *argv[])
(void) fprintf(stderr, "framerate: %lf\n",
video_framerate(vp));
- if ((kvp = kv_vidctx_init(dirname((char *)kv_arg0), emit)) == NULL) {
+ if ((kvp = kv_vidctx_init(dirname((char *)kv_arg0), emit,
+ dbgdir)) == NULL) {
video_free(vp);
return (EXIT_FAILURE);
}
View
25 src/kv.c
@@ -37,6 +37,7 @@ struct kv_vidctx {
int kv_last_start;
kv_emit_f kv_emit;
double kv_framerate;
+ char kv_dbgdir[PATH_MAX];
};
int
@@ -494,7 +495,7 @@ kv_screen_json(const char *source, int frame, int msec, kv_screen_t *ksp,
}
kv_vidctx_t *
-kv_vidctx_init(const char *rootdir, kv_emit_f emit)
+kv_vidctx_init(const char *rootdir, kv_emit_f emit, const char *dbgdir)
{
kv_vidctx_t *kvp;
@@ -510,6 +511,8 @@ kv_vidctx_init(const char *rootdir, kv_emit_f emit)
kvp->kv_last_start = -1;
kvp->kv_emit = emit;
+ if (dbgdir != NULL)
+ (void) strlcpy(kvp->kv_dbgdir, dbgdir, sizeof (kvp->kv_dbgdir));
return (kvp);
}
@@ -548,6 +551,20 @@ kv_vidctx_chars(kv_vidctx_t *kvp, kv_screen_t *ksp, int i)
}
void
+kv_vidctx_frame_emit(kv_vidctx_t *kvp, const char *framename, int i, int timems,
+ img_t *img, kv_screen_t *ksp, kv_screen_t *raceksp, FILE *fp)
+{
+ if (kvp->kv_dbgdir[0] != '\0') {
+ char buf[PATH_MAX];
+ (void) snprintf(buf, sizeof (buf), "%s/%s", kvp->kv_dbgdir,
+ framename);
+ (void) img_write(img, buf);
+ }
+
+ kvp->kv_emit(framename, i, timems, ksp, raceksp, fp);
+}
+
+void
kv_vidctx_frame(const char *framename, int i, int timems,
img_t *image, kv_vidctx_t *kvp)
{
@@ -599,7 +616,8 @@ kv_vidctx_frame(const char *framename, int i, int timems,
kvp->kv_last_start = i;
*pksp = *ksp;
*raceksp = *ksp;
- kvp->kv_emit(framename, i, timems, ksp, NULL, stdout);
+ kv_vidctx_frame_emit(kvp, framename, i, timems, image,
+ ksp, NULL, stdout);
bzero(&kvp->kv_startbuffer[0], sizeof (kvp->kv_startbuffer));
return;
}
@@ -655,7 +673,8 @@ kv_vidctx_frame(const char *framename, int i, int timems,
}
}
- kvp->kv_emit(framename, i, timems, ksp, raceksp, stdout);
+ kv_vidctx_frame_emit(kvp, framename, i, timems, image, ksp,
+ raceksp, stdout);
*pksp = *ksp;
if (ksp->ks_events & KVE_RACE_DONE)
View
2  src/kv.h
@@ -56,7 +56,7 @@ void kv_screen_json(const char *, int, int, kv_screen_t *, kv_screen_t *,
struct kv_vidctx;
typedef struct kv_vidctx kv_vidctx_t;
-kv_vidctx_t *kv_vidctx_init(const char *, kv_emit_f);
+kv_vidctx_t *kv_vidctx_init(const char *, kv_emit_f, const char *);
void kv_vidctx_frame(const char *, int, int, img_t *, kv_vidctx_t *);
void kv_vidctx_free(kv_vidctx_t *);
Please sign in to comment.
Something went wrong with that request. Please try again.