wcap: Add wcap support to webm encoder

dev
Kristian Høgsberg 13 years ago
parent 894e0b544c
commit 93b11c8e12
  1. 94
      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,

Loading…
Cancel
Save