|
@@ -638,18 +638,56 @@ format_movie_name(char *capture_fname)
|
|
|
|
|
|
int movie_recording;
|
|
|
static char movie_fname[255];
|
|
|
+static char stdout_buf[1024];
|
|
|
+
|
|
|
+static void on_read_complete(GObject *source_object, GAsyncResult *res, gpointer user_data) {
|
|
|
+ GInputStream *stream = G_INPUT_STREAM(source_object);
|
|
|
+ GError *error = NULL;
|
|
|
+ gssize bytes_read;
|
|
|
+
|
|
|
+ // Read the output from the stream
|
|
|
+ bytes_read = g_input_stream_read_finish(stream, res, &error);
|
|
|
+
|
|
|
+ if (bytes_read == 0) {
|
|
|
+ // End of file reached, close the stream
|
|
|
+ g_input_stream_close(stream, NULL, NULL);
|
|
|
+ g_object_unref(stream);
|
|
|
+ notify_movie_progress();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (bytes_read < 0) {
|
|
|
+ // Error occurred
|
|
|
+ g_print("Error reading subprocess output: %s\n", error->message);
|
|
|
+ g_error_free(error);
|
|
|
+ g_object_unref(stream);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ //g_print("Got buffer: %.*s", (int)bytes_read, stdout_buf);
|
|
|
+ stdout_buf[bytes_read] = 0;
|
|
|
+
|
|
|
+ {
|
|
|
+ char msg[] = "Message: ";
|
|
|
+ int l = sizeof(msg);
|
|
|
+ if (!strncmp(stdout_buf, msg, l-1)) {
|
|
|
+ char *c = strchr(stdout_buf, '\n');
|
|
|
+ if (!c)
|
|
|
+ return;
|
|
|
+ *c = 0;
|
|
|
+ notify_movie_message(strdup(stdout_buf + l - 1));
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-static void
|
|
|
-on_movie_finished(GSubprocess *proc, GAsyncResult *res, GdkTexture *thumb)
|
|
|
-{
|
|
|
- notify_movie_progress();
|
|
|
+ // Continue reading asynchronously
|
|
|
+ g_input_stream_read_async(stream, stdout_buf, sizeof(stdout_buf), G_PRIORITY_DEFAULT, NULL,
|
|
|
+ on_read_complete, NULL);
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
spawn_movie(char *cmd)
|
|
|
{
|
|
|
g_autoptr(GError) error = NULL;
|
|
|
- GSubprocess *proc = g_subprocess_new(0,
|
|
|
+ GSubprocess *proc = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE,
|
|
|
&error,
|
|
|
movie_script,
|
|
|
cmd,
|
|
@@ -664,8 +702,14 @@ spawn_movie(char *cmd)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- g_subprocess_communicate_utf8_async(
|
|
|
- proc, NULL, NULL, (GAsyncReadyCallback)on_movie_finished, NULL);
|
|
|
+
|
|
|
+ GInputStream *stdout_stream;
|
|
|
+ // Get the stdout stream of the subprocess
|
|
|
+ stdout_stream = g_subprocess_get_stdout_pipe(proc);
|
|
|
+
|
|
|
+ // Read the output of the subprocess asynchronously
|
|
|
+ g_input_stream_read_async(stdout_stream, stdout_buf, sizeof(stdout_buf), G_PRIORITY_DEFAULT, NULL,
|
|
|
+ on_read_complete, NULL);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -687,6 +731,28 @@ on_movie_stop(void)
|
|
|
spawn_movie("stop");
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+save_grw(const uint8_t *image, char *fname)
|
|
|
+{
|
|
|
+ FILE *outfile;
|
|
|
+ if ((outfile = fopen(fname, "wb")) == NULL) {
|
|
|
+ g_printerr("grw open %s: error %d, %s\n",
|
|
|
+ fname,
|
|
|
+ errno,
|
|
|
+ strerror(errno));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ int width = state_proc.mode->width;
|
|
|
+ int height = state_proc.mode->height;
|
|
|
+ int size = width*height*2;
|
|
|
+ fwrite(image, size, 1, outfile);
|
|
|
+ char buf[1024];
|
|
|
+ buf[0] = 0;
|
|
|
+ int header = sprintf(buf+1, "Caps: video/x-raw,format=YUY2,width=%d,height=%d\nSize: %d\nGRW", width, height, size);
|
|
|
+ fwrite(buf, header+1, 1, outfile);
|
|
|
+ fclose(outfile);
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
save_jpeg(const uint8_t *image, char *fname)
|
|
|
{
|
|
@@ -707,9 +773,8 @@ save_jpeg(const uint8_t *image, char *fname)
|
|
|
jpeg_create_compress(&cinfo);
|
|
|
jpeg_stdio_dest(&cinfo, outfile);
|
|
|
|
|
|
- //printf("Saving jpeg, %d x %d\n", cinfo.image_width, cinfo.image_height);
|
|
|
cinfo.image_width = state_proc.mode->width & -1;
|
|
|
- cinfo.image_height = state_proc.mode->height & -1; // FIXME?
|
|
|
+ cinfo.image_height = state_proc.mode->height & -1;
|
|
|
cinfo.input_components = 3;
|
|
|
cinfo.in_color_space = JCS_YCbCr;
|
|
|
jpeg_set_defaults(&cinfo);
|
|
@@ -1005,8 +1070,20 @@ process_image(MPPipeline *pipeline, const MPBuffer *buffer)
|
|
|
|
|
|
if (movie_recording) {
|
|
|
char name[1024];
|
|
|
- get_name(name, burst_dir, "dng");
|
|
|
- save_dng(image, name, 1);
|
|
|
+
|
|
|
+ switch (state_proc.mode->v4l_pixfmt) {
|
|
|
+ case V4L2_PIX_FMT_UYVY:
|
|
|
+ case V4L2_PIX_FMT_YUYV:
|
|
|
+ case V4L2_PIX_FMT_YVYU:
|
|
|
+ case V4L2_PIX_FMT_VYUY:
|
|
|
+ get_name(name, burst_dir, "grw");
|
|
|
+ save_grw(image, name);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ get_name(name, burst_dir, "dng");
|
|
|
+ save_dng(image, name, 1);
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
MPZBarImage *zbar_image = mp_zbar_image_new(image,
|