summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-05-25 17:58:12 -0400
committerKristian Høgsberg <krh@bitplanet.net>2012-05-25 17:58:12 -0400
commit93b11c8e124848905bdc44f697e27c1d9e0a8ff1 (patch)
tree977a618f20e3cbc9a7dc8e865190cfa35c4abce7
parent894e0b544c2b7e8a02bde79a28087ef89204195a (diff)
wcap: Add wcap support to webm encoder
-rw-r--r--wcap-decode/vpxenc.c94
1 files changed, 93 insertions, 1 deletions
diff --git a/wcap-decode/vpxenc.c b/wcap-decode/vpxenc.c
index 866515f..3559a32 100644
--- a/wcap-decode/vpxenc.c
+++ b/wcap-decode/vpxenc.c
@@ -40,6 +40,8 @@
#include "EbmlWriter.h"
#include "EbmlIDs.h"
+#include "wcap-decode.h"
+
/* Need special handling of these functions on Windows */
#if defined(_MSC_VER)
/* MSVS doesn't define off_t, and uses _f{seek,tell}i64 */
@@ -289,7 +291,8 @@ enum video_file_type
{
FILE_TYPE_RAW,
FILE_TYPE_IVF,
- FILE_TYPE_Y4M
+ FILE_TYPE_Y4M,
+ FILE_TYPE_WCAP
};
struct detect_buffer {
@@ -310,8 +313,70 @@ struct input_state
unsigned int h;
struct vpx_rational framerate;
int use_i420;
+ struct wcap_decoder *wcap;
};
+static inline int rgb_to_yuv(uint32_t p, int *u, int *v)
+{
+ int r = (p >> 16) & 0xff;
+ int g = (p >> 8) & 0xff;
+ int b = (p >> 0) & 0xff;
+ int y;
+
+ y = 0.299 * r + 0.587 * g + 0.114 * b;
+ if (y > 255)
+ y = 255;
+
+ *u += 0.713 * (r - y);
+ *v += 0.564 * (b - y);
+
+ return y;
+}
+
+static inline int clamp_uv(int u)
+{
+ if (u < -512)
+ return 0;
+ else if (u > 511)
+ return 255;
+ else
+ return u / 4 + 128;
+}
+
+static void convert_to_yv12(struct wcap_decoder *wcap, vpx_image_t *img)
+{
+ unsigned char *y1, *y2, *u, *v;
+ uint32_t *p1, *p2, *end;
+ int i, u_accum, v_accum;
+
+ for (i = 0; i < wcap->height; i += 2) {
+ y1 = img->planes[0] + img->stride[0] * i;
+ y2 = img->planes[0] + img->stride[0] * i + img->stride[0];
+ u = img->planes[2] + img->stride[2] * i / 2;
+ v = img->planes[1] + img->stride[1] * i / 2;
+ p1 = wcap->frame + wcap->width * i;
+ p2 = wcap->frame + wcap->width * i + wcap->width;
+ end = p1 + wcap->width;
+
+ while (p1 < end) {
+ u_accum = 0;
+ v_accum = 0;
+ y1[0] = rgb_to_yuv(p1[0], &u_accum, &v_accum);
+ y1[1] = rgb_to_yuv(p1[1], &u_accum, &v_accum);
+ y2[0] = rgb_to_yuv(p2[0], &u_accum, &v_accum);
+ y2[1] = rgb_to_yuv(p2[1], &u_accum, &v_accum);
+ u[0] = clamp_uv(u_accum);
+ v[0] = clamp_uv(v_accum);
+
+ y1 += 2;
+ p1 += 2;
+ y2 += 2;
+ p2 += 2;
+ u++;
+ v++;
+ }
+ }
+}
#define IVF_FRAME_HDR_SZ (4+8) /* 4 byte size + 8 byte timestamp */
static int read_frame(struct input_state *input, vpx_image_t *img)
@@ -328,6 +393,13 @@ static int read_frame(struct input_state *input, vpx_image_t *img)
if (y4m_input_fetch_frame(y4m, f, img) < 1)
return 0;
}
+ else if (file_type == FILE_TYPE_WCAP)
+ {
+ if (!wcap_decoder_get_frame(input->wcap))
+ return 0;
+
+ convert_to_yv12(input->wcap, img);
+ }
else
{
if (file_type == FILE_TYPE_IVF)
@@ -443,6 +515,13 @@ unsigned int file_is_ivf(struct input_state *input,
return is_ivf;
}
+unsigned int file_is_wcap(struct input_state *input)
+{
+ if(mem_get_le32(input->detect.buf) == WCAP_HEADER_MAGIC)
+ return 1;
+
+ return 0;
+}
static void write_ivf_file_header(FILE *outfile,
const vpx_codec_enc_cfg_t *cfg,
@@ -1705,6 +1784,17 @@ void open_input_file(struct input_state *input)
fatal("Unsupported fourcc (%08x) in IVF", fourcc);
}
}
+ else if (input->detect.buf_read == 4 && file_is_wcap(input))
+ {
+ input->wcap = wcap_decoder_create(input->fn);
+
+ input->file_type = FILE_TYPE_WCAP;
+ input->w = input->wcap->width;
+ input->h = input->wcap->height;
+ input->framerate.num = 30;
+ input->framerate.den = 1;
+ input->use_i420 = 0;
+ }
else
{
input->file_type = FILE_TYPE_RAW;
@@ -1717,6 +1807,8 @@ static void close_input_file(struct input_state *input)
fclose(input->file);
if (input->file_type == FILE_TYPE_Y4M)
y4m_input_close(&input->y4m);
+ else if (input->file_type == FILE_TYPE_WCAP)
+ wcap_decoder_destroy(input->wcap);
}
static struct stream_state *new_stream(struct global_config *global,