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:
Pavel Machek
2024-05-01 22:47:40 +02:00
parent df7e7e9eed
commit f0d8834b4a
4 changed files with 102 additions and 14 deletions

View File

@@ -22,8 +22,8 @@ jpegize() {
done
for DNG in *.dng; do
PERC=$[(100*$I)/$NUM]
echo $PERC
PERC=$[(50*$I)/$NUM]
echo Message: ${PERC}%
BASE=${DNG%%.dng}
# -w Use camera white balance
# +M use embedded color matrix
@@ -67,10 +67,13 @@ elif [ "-$1" == "-stop" ]; then
mkdir $GIGA_DIR/sm
kill `cat $2/audio.pid`
jpegize $2 # | zenity --progress "--text=Converting, phase 1, dng -> jpeg" --time-remaining
echo Message: Mp
cd $GIGA_DIR/sm
@LIBEXECDIR@/mpegize.py convertall $GIGA_DIR/ $FPS
echo Message: Cl
mv $GIGA_DIR/smo/*.mp4 $DEST_NAME
rm -r $GIGA_DIR
echo Message: Ok
else
echo "Unrecognized command"
fi

View File

@@ -914,6 +914,12 @@ notify_movie_progress(void)
gtk_button_set_label(GTK_BUTTON(movie), "Rec");
}
void
notify_movie_message(gchar *msg)
{
gtk_button_set_label(GTK_BUTTON(movie), msg);
}
void
on_movie_clicked(GtkWidget *widget, gpointer user_data)
{

View File

@@ -35,3 +35,5 @@ void mp_main_set_zbar_result(MPZBarScanResult *result);
int remap(int value, int input_min, int input_max, int output_min, int output_max);
bool check_window_active();
void notify_movie_message(gchar *msg);

View File

@@ -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,