Pipe for scripts<->application communication, write UYVY files
Got pipe to work between movie subprocess and main code. We use it to display progress from the scripts. Write "gstreamer raw" files, that can be worked with easily from gstreamer.
This commit is contained in:
@@ -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_movie_finished(GSubprocess *proc, GAsyncResult *res, GdkTexture *thumb)
|
||||
{
|
||||
notify_movie_progress();
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
|
Reference in New Issue
Block a user