wcap: Add wcap support to webm encoder
This commit is contained in:
+93
-1
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user