summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoi Cohen <roico@roico-desktop.(none)>2007-05-28 17:17:34 +0300
committerRoi Cohen <roico@roico-desktop.(none)>2007-05-28 17:17:34 +0300
commit2a76c70dbca679a0a1d2a82a31b7cf1af9e4eeeb (patch)
treecf327c8b9dc6804faae2b43ceebd1a98965d3a55
parent5f9bad4d6640cc58f99a0ece6e16cb68ecca5744 (diff)
downloadscreencasting-2a76c70dbca679a0a1d2a82a31b7cf1af9e4eeeb.tar.gz
screencasting-2a76c70dbca679a0a1d2a82a31b7cf1af9e4eeeb.tar.bz2
don't create all yuv data each frame - only update yuv data for damaged regions.
-rw-r--r--plugin/rsc2raw.c117
-rw-r--r--plugin/rsc2raw.h15
-rw-r--r--plugin/screencasting.c4
3 files changed, 117 insertions, 19 deletions
diff --git a/plugin/rsc2raw.c b/plugin/rsc2raw.c
index 0b022a5..b21d83a 100644
--- a/plugin/rsc2raw.c
+++ b/plugin/rsc2raw.c
@@ -5,28 +5,115 @@
#include "frame.h"
#include "rsc2raw.h"
-void applyInputFrame(u_int8_t *raw_frame, Frame *data, u_int32_t frame_width, u_int32_t frame_height)
+RawFrame* initRawFrame(u_int32_t width, u_int32_t height)
+{
+ RawFrame* frame = (RawFrame*) malloc(sizeof(RawFrame));
+
+ frame->y_raw = (u_int8_t*) malloc(sizeof(u_int8_t) * width * height);
+ frame->u_raw = (u_int8_t*) malloc(sizeof(u_int8_t) * width * height);
+ frame->v_raw = (u_int8_t*) malloc(sizeof(u_int8_t) * width * height);
+
+ frame->y_output = frame->y_raw; // Y output is per-pixel, just like the raw data.
+ frame->u_output = (u_int8_t*) malloc(sizeof(u_int8_t) * width * height / 4);
+ frame->v_output = (u_int8_t*) malloc(sizeof(u_int8_t) * width * height / 4);
+
+ return frame;
+}
+
+void applyInputFrame(RawFrame* raw_frame, Frame* frame, u_int32_t width, u_int32_t height)
{
// TODO: Error-checking
- unsigned long i, j;
- for (i = 0; i < data->numRects; i++)
+ unsigned long i, x, y;
+ for (i = 0; i < frame->numRects; i++)
{
- Rect *rect = &data->rects[i];
-
- for (j = 0; j < rect->height; j++)
+ Rect *rect = &frame->rects[i];
+
+ for (x = 0; x < rect->width; x++)
{
- int rect_line = rect->y + j;
- int frame_line = (frame_height - 1) - rect_line;
-
- u_int8_t *raw_frame_line = raw_frame + 3 * frame_width * frame_line; // go to the correct line of the frame.
- u_int8_t *rect_data_line = rect->buffer + 3 * rect->width * j; // go to the correct line of the rect data.
-
- memcpy(raw_frame_line + 3 * rect->x, rect_data_line, sizeof(u_int8_t) * rect->width * 3);
+ for (y = 0; y < rect->height; y++)
+ {
+ // In rect's data (y axis):
+ // 0 - most bottom pixel. (height - 1) - toppest pixel.
+ // rect->y - most bottom pixel in the rect.
+
+ // In raw-frame's data (y axis):
+ // 0 - toppest pixel. (height - 1) - most bottom pixel.
+
+ int frame_line = rect->y + y; // Goes from most-bottom pixel in the rect up.
+ frame_line = (height - 1) - frame_line; // Convert to raw-frame format.
+
+ int frame_row = rect->x + x;
+
+ u_int8_t* y_pixel = raw_frame->y_raw +
+ frame_line * width +
+ frame_row;
+ u_int8_t* u_pixel = raw_frame->u_raw +
+ frame_line * width +
+ frame_row;
+ u_int8_t* v_pixel = raw_frame->v_raw +
+ frame_line * width +
+ frame_row;
+
+ u_int8_t* rgb_pixel = rect->buffer +
+ 3 * y * rect->width +
+ 3 * x;
+
+ // Magic conversion factors - Wikipedia knows what they mean.
+
+ *y_pixel = ((66 * rgb_pixel[0] + // R
+ 129 * rgb_pixel[1] + // G
+ 25 * rgb_pixel[2] + 128) >> 8) + 16; // B
+
+ *u_pixel = ((-38 * rgb_pixel[0] + // R
+ -74 * rgb_pixel[1] + // G
+ 112 * rgb_pixel[2] + 128) >> 8) + 128; // B
+
+ *v_pixel = ((112 * rgb_pixel[0] + // R
+ -94 * rgb_pixel[1] + // G
+ -18 * rgb_pixel[2] + 128) >> 8) + 128; // B
+ }
+ }
+
+ // UV output arrays - avarages of 2x2 pixels.
+ int first_x = rect->x / 2;
+ int last_x = (rect->x + rect->width - 1) / 2;
+
+ int first_y = ((height - 1) - (rect->y + rect->height - 1)) / 2; // Read comment in first loop.
+ int last_y = ((height - 1) - rect->y) / 2; // Read comment in first loop.
+
+ for (x = first_x / 2; x <= last_x; x++)
+ {
+ for (y = first_y / 2; y <= last_y; y++)
+ {
+ int pixel1 = 2 * y * width + 2 * x;
+ int pixel2 = 2 * y * width + 2 * (x + 1);
+ int pixel3 = 2 * (y + 1) * width + 2 * x;
+ int pixel4 = 2 * (y + 1) * width + 2 * (x + 1);
+
+ raw_frame->u_output[y * width / 2 + x] = (raw_frame->u_raw[pixel1] +
+ raw_frame->u_raw[pixel2] +
+ raw_frame->u_raw[pixel3] +
+ raw_frame->u_raw[pixel4]) / 4;
+
+ raw_frame->v_output[y * width / 2 + x] = (raw_frame->v_raw[pixel1] +
+ raw_frame->v_raw[pixel2] +
+ raw_frame->v_raw[pixel3] +
+ raw_frame->v_raw[pixel4]) / 4;
+ }
}
}
}
+void writeOutputFrame(FILE *output, RawFrame* raw_frame, u_int32_t width, u_int32_t height)
+{
+ fwrite(raw_frame->y_output, sizeof(u_int8_t), height * width, output);
+
+ fwrite(raw_frame->u_output, sizeof(u_int8_t), height * width / 4, output);
+ fwrite(raw_frame->v_output, sizeof(u_int8_t), height * width / 4, output);
+}
+
+/*
void writeOutputFrame(FILE *output, u_int8_t *data, u_int32_t width, u_int32_t height)
{
// TODO: Error checking
@@ -73,7 +160,7 @@ void writeOutputFrame(FILE *output, u_int8_t *data, u_int32_t width, u_int32_t h
112 * data[pixel4 + 2] + 128) >> 8) / 4 + 128; // B
- Us[z] = ((112 * data[pixel1 + 0] + // R
+ Vs[z] = ((112 * data[pixel1 + 0] + // R
-94 * data[pixel1 + 1] + // G
-18 * data[pixel1 + 2] + 128 + // B
@@ -101,4 +188,4 @@ void writeOutputFrame(FILE *output, u_int8_t *data, u_int32_t width, u_int32_t h
free(Ys);
free(Us);
free(Vs);
-}
+}*/
diff --git a/plugin/rsc2raw.h b/plugin/rsc2raw.h
index 80e7577..40636f8 100644
--- a/plugin/rsc2raw.h
+++ b/plugin/rsc2raw.h
@@ -9,7 +9,18 @@
#define OUTPUT_FPS 25 // We output at 25fps, non-interlaced. TODO: make this CLI configurable (implies switch to getopts)
#define OUTPUT_MS_PER_FRAME 1000 / OUTPUT_FPS
-void applyInputFrame(u_int8_t *raw_frame, Frame *data, u_int32_t frame_width, u_int32_t frame_height);
-void writeOutputFrame(FILE *output, u_int8_t *data, u_int32_t width, u_int32_t height);
+typedef struct {
+ u_int8_t* y_raw;
+ u_int8_t* u_raw;
+ u_int8_t* v_raw;
+
+ u_int8_t* y_output;
+ u_int8_t* u_output;
+ u_int8_t* v_output;
+} RawFrame;
+
+RawFrame* initRawFrame(u_int32_t width, u_int32_t height);
+void applyInputFrame(RawFrame* raw_frame, Frame* frame, u_int32_t width, u_int32_t height);
+void writeOutputFrame(FILE *output, RawFrame* raw_frame, u_int32_t width, u_int32_t height);
#endif
diff --git a/plugin/screencasting.c b/plugin/screencasting.c
index e51cec4..111caf9 100644
--- a/plugin/screencasting.c
+++ b/plugin/screencasting.c
@@ -144,14 +144,14 @@ secondThread(void* screen)
unsigned int current_input_video_time = 0;
unsigned int outputted_frames = 0;
- u_int8_t *raw_frame;
+ RawFrame* raw_frame;
Frame* frame;
u_int32_t width = s->width;
u_int32_t height = s->height;
- raw_frame = malloc(sizeof(u_int8_t) * width * height * 3);
+ raw_frame = initRawFrame(width, height);
// Before screen casting, save resolution of screencast.
// fwrite(&width, sizeof(u_int32_t), 1, f);