diff options
Diffstat (limited to 'code')
-rw-r--r-- | code/test/vid/Makefile | 15 | ||||
-rw-r--r-- | code/test/vid/cap.c | 36 | ||||
-rw-r--r-- | code/test/vid/client.c | 106 | ||||
-rw-r--r-- | code/test/vid/enc.c | 100 | ||||
-rw-r--r-- | code/test/vid/enc.h | 5 | ||||
-rw-r--r-- | code/test/vid/server.c | 63 | ||||
-rw-r--r-- | code/test/vid/server.h | 5 | ||||
-rw-r--r-- | code/test/vid/tools.c | 145 | ||||
-rw-r--r-- | code/test/vid/tools.h | 12 |
9 files changed, 355 insertions, 132 deletions
diff --git a/code/test/vid/Makefile b/code/test/vid/Makefile index 757429d..fbdbe15 100644 --- a/code/test/vid/Makefile +++ b/code/test/vid/Makefile @@ -1,17 +1,20 @@ LIBVPX_HOME=../libvpx -CFLAGS=-D_V4L2_KERNEL_ -I/usr/src/linux-headers-$(uname -r) -I$(LIBVPX_HOME) +CFLAGS=-D_V4L2_KERNEL_ -I/usr/src/linux-headers-$(uname -r) -I$(LIBVPX_HOME) -I../../core -I../../vconn -I../../util LDFLAGS=-L$(LIBVPX_HOME) -deps=$(LIBVPX_HOME)/ivfenc.c.o $(LIBVPX_HOME)/video_writer.c.o +dep=../../core/libecpcore.a ../../core/crypto/libecpcr.a ../../core/htable/libecpht.a ../../core/posix/libecptr.a ../../core/posix/libecptm.a ../../vconn/libecpvconn.a ../../util/libecputil.a ../init.o -all: cap +all: client cap %.o: %.c $(CC) $(CFLAGS) -c $< -cap: cap.o enc.o tools.o - $(CC) -o $@ $< enc.o tools.o $(deps) -lvpx -lm -pthread $(LDFLAGS) +cap: cap.o enc.o tools.o server.o + $(CC) -o $@ $< enc.o tools.o server.o -lvpx -lm -pthread $(dep) $(LDFLAGS) +client: client.o tools.o + $(CC) -o $@ $< tools.o -lvpx -lm -pthread $(dep) $(LDFLAGS) + clean: rm -f *.o - rm -f cap + rm -f cap client diff --git a/code/test/vid/cap.c b/code/test/vid/cap.c index c156fab..99fa500 100644 --- a/code/test/vid/cap.c +++ b/code/test/vid/cap.c @@ -398,7 +398,7 @@ int v4l2_set_mmap(int fd, int *buffers_count) return CAP_OK; } -int v4l2_retrieve_frame(int fd, int buffers_count, vpx_image_t *raw, vpx_codec_ctx_t *codec, int frame_count, int kframe_interval) +int v4l2_retrieve_frame(int fd, int buffers_count, vpx_image_t *raw, vpx_codec_ctx_t *codec, int frame_index, int kframe_interval) { int sz; fd_set fds; @@ -445,10 +445,11 @@ int v4l2_retrieve_frame(int fd, int buffers_count, vpx_image_t *raw, vpx_codec_c // printf("Length: %d \tBytesused: %d \tAddress: %p\n", buf.length, buf.bytesused, &buffers[buf.index]); sz = ALIGN_16B(width) * height * 3 / 2; - vpx_img_read(raw, buffers[buf.index].start, sz); - if (frame_count % kframe_interval == 0) - flags |= VPX_EFLAG_FORCE_KF; - vpx_encode_frame(codec, raw, frame_count, flags); + if (!vpx_img_read(raw, buffers[buf.index].start, sz)) { + die_codec(NULL, "Failed to read image."); + } + if (frame_index % kframe_interval == 0) flags |= VPX_EFLAG_FORCE_KF; + vpx_encode_frame(codec, raw, frame_index, flags); if (xioctl(fd, VIDIOC_QBUF, &buf) == -1) { CAP_ERROR_RET("failed to queue buffer."); @@ -475,7 +476,6 @@ int v4l2_close_camera(int fd, int buffers_count) int main(int argc, char *argv[]) { - int i, n; int fd; int target_bitrate = 200; double after; @@ -484,13 +484,12 @@ int main(int argc, char *argv[]) int buffers_count; int kframe_interval; vpx_codec_er_flags_t err_resilient; - int frame_count; - char *out_fname; + char *address; + char *key_file; if (argc != 13) { - CAP_ERROR_RET("./cap <width> <height> <buffers [4,8]> <video mode [0,1]> <exposure [-4,4]> <hflip [0,1]> <vflip [0,1]> <kframe interval> <bitrate> <err resilient> <num frames> <file name>") + CAP_ERROR_RET("./cap <width> <height> <buffers [4,8]> <video mode [0,1]> <exposure [-4,4]> <hflip [0,1]> <vflip [0,1]> <kframe interval> <bitrate> <err resilient> <address> <key file>") } - n = 0; width = (int) atoi(argv[1]); height = (int) atoi(argv[2]); n_buffers = (int) atoi(argv[3]); @@ -508,8 +507,8 @@ int main(int argc, char *argv[]) kframe_interval = (int) atoi(argv[8]); target_bitrate = (int) atoi(argv[9]); err_resilient = strtoul(argv[10], NULL, 0); - frame_count = (int) atoi(argv[11]); - out_fname = argv[12]; + address = argv[11]; + key_file = argv[12]; printf("---- cap parameters -----\nwidth: %d\nheight: %d\nv4l2 buffers: %d\nexposure: %d\nhflip: %d\nvflip: %d\nMode: %s\n", width, height, n_buffers, sensor_exposure, sensor_hflip, sensor_vflip, sensor_video_mode ? "V4L2_MODE_VIDEO" : "V4L2_MODE_IMAGE"); @@ -538,16 +537,21 @@ int main(int argc, char *argv[]) CAP_ERROR_RET("failed to mmap."); } + int n = 0; int _fps = 30; const char *codec_arg = "vp9"; vpx_codec_ctx_t codec; vpx_image_t raw; - vpx_init(codec_arg, out_fname, width, height, _fps); - vpx_open(&codec, get_vpx_encoder_by_name(codec_arg)->codec_interface(), width, height, _fps, target_bitrate, err_resilient, &raw); - for (i = 0; i < frame_count; i++) { + vpx_open(codec_arg, width, height, _fps, target_bitrate, err_resilient, &codec, &raw); + + while (1) { + if (!conn_is_open()) { + sleep(1); + continue; + } before = get_wall_time(); - if (v4l2_retrieve_frame(fd, buffers_count, &raw, &codec, i, kframe_interval)) { + if (v4l2_retrieve_frame(fd, buffers_count, &raw, &codec, n, kframe_interval)) { CAP_ERROR_RET("failed to retrieve frame."); } after = get_wall_time(); diff --git a/code/test/vid/client.c b/code/test/vid/client.c new file mode 100644 index 0000000..00b8c0a --- /dev/null +++ b/code/test/vid/client.c @@ -0,0 +1,106 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> + +#include "core.h" +#include "util.h" + +#include "vpx/vpx_decoder.h" +#include "vpx/vp8cx.h" +#include "tools.h" + +#define CTYPE_TEST 0 +#define MTYPE_MSG 8 + +#define FRAG_BUF_SIZE 8192 +#define RBUF_MSG_SIZE 128 + +ECPContext ctx_c; +ECPSocket sock_c; +ECPConnHandler handler_c; + +ECPNode node; +ECPConnection conn; + +FILE *outfile; +vpx_codec_ctx_t codec; + +ECPRBRecv rbuf_recv; +ECPRBMessage rbuf_r_msg[RBUF_MSG_SIZE]; +ECPFragIter frag_iter; +unsigned char frag_buffer[FRAG_BUF_SIZE]; + +ssize_t handle_msg(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *f, ssize_t sz) { + vpx_codec_iter_t iter = NULL; + vpx_image_t *img = NULL; + if (vpx_codec_decode(&codec, f, (unsigned int)sz, NULL, 0)) + die_codec(&codec, "Failed to decode frame."); + + while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) { + if (!vpx_img_write_f(img, outfile)) { + die_codec(NULL, "Failed to write image."); + } + } + + return sz; +} + +static void usage(char *arg) { + fprintf(stderr, "Usage: %s <node.pub>\n", arg); + exit(1); +} + +int main(int argc, char *argv[]) { + int rv; + + if (argc != 2) usage(argv[0]); + + rv = ecp_init(&ctx_c); + printf("ecp_init RV:%d\n", rv); + + if (!rv) rv = ecp_conn_handler_init(&handler_c); + if (!rv) { + handler_c.msg[MTYPE_MSG] = handle_msg; + ctx_c.handler[CTYPE_TEST] = &handler_c; + } + + if (!rv) rv = ecp_sock_create(&sock_c, &ctx_c, NULL); + printf("ecp_sock_create RV:%d\n", rv); + + if (!rv) rv = ecp_sock_open(&sock_c, NULL); + printf("ecp_sock_open RV:%d\n", rv); + + if (!rv) rv = ecp_start_receiver(&sock_c); + printf("ecp_start_receiver RV:%d\n", rv); + + if (!rv) rv = ecp_util_node_load(&ctx_c, &node, argv[1]); + printf("ecp_util_node_load RV:%d\n", rv); + + if (!rv) rv = ecp_conn_create(&conn, &sock_c, CTYPE_TEST); + printf("ecp_conn_create RV:%d\n", rv); + + if (!rv) rv = ecp_rbuf_create(&conn, NULL, NULL, 0, &rbuf_recv, rbuf_r_msg, RBUF_MSG_SIZE); + printf("ecp_rbuf_create RV:%d\n", rv); + + if (!rv) { + ecp_frag_iter_init(&frag_iter, frag_buffer, FRAG_BUF_SIZE); + rbuf_recv.frag_iter = &frag_iter; + } + + if (!rv) rv = ecp_conn_open(&conn, &node); + printf("ecp_conn_open RV:%d\n", rv); + + const char *codec_arg = "vp9"; + const VpxInterface *decoder = get_vpx_decoder_by_name(codec_arg); + if (!decoder) die_codec(NULL, "Unknown input codec."); + + printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface())); + + if (vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0)) + die_codec(&codec, "Failed to initialize decoder."); + + while (1) sleep(1); + + if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec"); +}
\ No newline at end of file diff --git a/code/test/vid/enc.c b/code/test/vid/enc.c index a1730b4..91fe5e8 100644 --- a/code/test/vid/enc.c +++ b/code/test/vid/enc.c @@ -100,68 +100,7 @@ #include <string.h> #include "enc.h" - -static const char *exec_name = "./enc"; - -void usage_exit(void) { - fprintf(stderr, - "Usage: %s <codec> <width> <height> <infile> <outfile> " - "<keyframe-interval> <error-resilient> <frames to encode>\n" - "See comments in simple_encoder.c for more information.\n", - exec_name); - exit(EXIT_FAILURE); -} - -static VpxVideoWriter *writer; - -static VpxVideoWriter *open_writer(const char *file_name, uint32_t fourcc, int width, int height, int fps) { - VpxVideoInfo info = { 0, 0, 0, { 0, 0 } }; - - info.codec_fourcc = fourcc; - info.frame_width = width; - info.frame_height = height; - info.time_base.numerator = 1; - info.time_base.denominator = fps; - - return vpx_video_writer_open(file_name, kContainerIVF, &info); -} - -// TODO(dkovalev): move this function to vpx_image.{c, h}, so it will be part -// of vpx_image_t support -int vpx_img_plane_width(const vpx_image_t *img, int plane) { - if (plane > 0 && img->x_chroma_shift > 0) - return (img->d_w + 1) >> img->x_chroma_shift; - else - return img->d_w; -} - -int vpx_img_plane_height(const vpx_image_t *img, int plane) { - if (plane > 0 && img->y_chroma_shift > 0) - return (img->d_h + 1) >> img->y_chroma_shift; - else - return img->d_h; -} - -int vpx_img_read(vpx_image_t *img, void *img_buf, int sz) { - int plane; - - for (plane = 0; plane < 3; ++plane) { - unsigned char *buf = img->planes[plane]; - const int stride = img->stride[plane]; - const int w = vpx_img_plane_width(img, plane) * - ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1); - const int h = vpx_img_plane_height(img, plane); - int y; - - for (y = 0; y < h; ++y) { - memcpy(buf, img_buf, w); - img_buf += w; - buf += stride; - } - } - - return 1; -} +#include "server.h" int vpx_encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img, int frame_index, int flags) { int got_pkts = 0; @@ -176,9 +115,7 @@ int vpx_encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img, int frame_index, if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; - if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf, - pkt->data.frame.sz, - pkt->data.frame.pts)) { + if (send_frame(pkt->data.frame.buf, pkt->data.frame.sz, pkt->data.frame.pts) < 0) { die_codec(codec, "Failed to write compressed frame"); } printf(keyframe ? "K" : "."); @@ -190,12 +127,20 @@ int vpx_encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img, int frame_index, } -void vpx_open(vpx_codec_ctx_t *codec, vpx_codec_iface_t *codec_interface, int width, int height, int fps, int bitrate, vpx_codec_er_flags_t err_resilient, vpx_image_t *raw) { +void vpx_open(const char *codec_arg, int width, int height, int fps, int bitrate, vpx_codec_er_flags_t err_resilient, vpx_codec_ctx_t *codec, vpx_image_t *raw) { vpx_codec_enc_cfg_t cfg; vpx_codec_err_t res; - res = vpx_codec_enc_config_default(codec_interface, &cfg, 0); - if (res) die("Failed to get default codec config."); + const VpxInterface *encoder = get_vpx_encoder_by_name(codec_arg); + if (!encoder) die_codec(NULL, "Unsupported codec."); + + printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); + + if (!vpx_img_alloc(raw, VPX_IMG_FMT_I420, width, height, 1)) + die_codec(NULL, "Failed to allocate image."); + + res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0); + if (res) die_codec(NULL, "Failed to get default codec config."); cfg.g_w = width; cfg.g_h = height; @@ -205,15 +150,11 @@ void vpx_open(vpx_codec_ctx_t *codec, vpx_codec_iface_t *codec_interface, int wi cfg.g_error_resilient = err_resilient; cfg.rc_end_usage = VPX_CBR; - if (vpx_codec_enc_init(codec, codec_interface, &cfg, 0)) + if (vpx_codec_enc_init(codec, encoder->codec_interface(), &cfg, 0)) die_codec(codec, "Failed to initialize encoder"); if (vpx_codec_control(codec, VP8E_SET_CPUUSED, 8)) die_codec(codec, "Failed to initialize cpuused"); - - if (!vpx_img_alloc(raw, VPX_IMG_FMT_I420, width, height, 1)) { - die("Failed to allocate image."); - } } void vpx_close(vpx_codec_ctx_t *codec, vpx_image_t *raw) { @@ -223,17 +164,4 @@ void vpx_close(vpx_codec_ctx_t *codec, vpx_image_t *raw) { vpx_img_free(raw); if (vpx_codec_destroy(codec)) die_codec(codec, "Failed to destroy codec."); - - vpx_video_writer_close(writer); } - -void vpx_init(const char *codec_arg, const char *outfile_arg, int width, int height, int fps) { - const VpxInterface *encoder = get_vpx_encoder_by_name(codec_arg); - if (!encoder) die("Unsupported codec."); - - writer = open_writer(outfile_arg, encoder->fourcc, width, height, fps); - if (!writer) die("Failed to open %s for writing.", outfile_arg); - - printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); -} - diff --git a/code/test/vid/enc.h b/code/test/vid/enc.h index d534971..5acd8ce 100644 --- a/code/test/vid/enc.h +++ b/code/test/vid/enc.h @@ -1,10 +1,7 @@ #include "vpx/vpx_encoder.h" #include "vpx/vp8cx.h" #include "tools.h" -#include "video_writer.h" -int vpx_img_read(vpx_image_t *img, void *img_buf, int sz); int vpx_encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img, int frame_index, int flags); -void vpx_open(vpx_codec_ctx_t *codec, vpx_codec_iface_t *codec_interface, int width, int height, int fps, int bitrate, vpx_codec_er_flags_t err_resilient, vpx_image_t *raw); +void vpx_open(const char *codec_arg, int width, int height, int fps, int bitrate, vpx_codec_er_flags_t err_resilient, vpx_codec_ctx_t *codec, vpx_image_t *raw); void vpx_close(vpx_codec_ctx_t *codec, vpx_image_t *raw); -void vpx_init(const char *codec_arg, const char *outfile_arg, int width, int height, int fps); diff --git a/code/test/vid/server.c b/code/test/vid/server.c new file mode 100644 index 0000000..08653f1 --- /dev/null +++ b/code/test/vid/server.c @@ -0,0 +1,63 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> + +#include "server.h" +#include "util.h" + +static ECPContext ctx_s; +static ECPSocket sock_s; +static ECPDHKey key_perma_s; +static ECPConnHandler handler_s; + +static ECPConnection *conn; +static int is_open = 0; + +#define CTYPE_TEST 0 +#define MTYPE_MSG 8 + +static ssize_t handle_open(ECPConnection *c, ecp_seq_t sq, unsigned char t, unsigned char *m, ssize_t sz) { + ssize_t rv = ecp_conn_handle_open(c, sq, t, m, sz); + if (rv < 0) return rv; + + conn = c; + is_open = 1; + + return rv; +} + +ssize_t send_frame(unsigned char *buffer, size_t size, ecp_pts_t pts) { + return ecp_send(conn, MTYPE_MSG, buffer, size); +} + +int conn_is_open(void) { + return is_open; +} + +int init_server(char *address, char *key) { + int rv; + + rv = ecp_init(&ctx_s); + printf("ecp_init RV:%d\n", rv); + + if (!rv) rv = ecp_conn_handler_init(&handler_s); + if (!rv) { + handler_s.msg[ECP_MTYPE_OPEN] = handle_open; + ctx_s.handler[CTYPE_TEST] = &handler_s; + } + + if (!rv) rv = ecp_util_key_load(&ctx_s, &key_perma_s, key); + printf("ecp_util_key_load RV:%d\n", rv); + + if (!rv) rv = ecp_sock_create(&sock_s, &ctx_s, &key_perma_s); + printf("ecp_sock_create RV:%d\n", rv); + + if (!rv) rv = ecp_sock_open(&sock_s, address); + printf("ecp_sock_open RV:%d\n", rv); + + if (!rv) rv = ecp_start_receiver(&sock_s); + printf("ecp_start_receiver RV:%d\n", rv); + + return rv; +} diff --git a/code/test/vid/server.h b/code/test/vid/server.h new file mode 100644 index 0000000..3f9c57e --- /dev/null +++ b/code/test/vid/server.h @@ -0,0 +1,5 @@ +#include "core.h" + +ssize_t send_frame(unsigned char *buffer, size_t size, ecp_pts_t pts); +int conn_is_open(void); +int init_server(char *address, char *key);
\ No newline at end of file diff --git a/code/test/vid/tools.c b/code/test/vid/tools.c index 6122209..3331670 100644 --- a/code/test/vid/tools.c +++ b/code/test/vid/tools.c @@ -27,28 +27,137 @@ const VpxInterface *get_vpx_encoder_by_name(const char *name) { return NULL; } -#define LOG_ERROR(label) \ - do { \ - const char *l = label; \ - va_list ap; \ - va_start(ap, fmt); \ - if (l) fprintf(stderr, "%s: ", l); \ - vfprintf(stderr, fmt, ap); \ - fprintf(stderr, "\n"); \ - va_end(ap); \ - } while (0) - -void die(const char *fmt, ...) { - LOG_ERROR(NULL); - usage_exit(); +static const VpxInterface vpx_decoders[] = { + { "vp8", VP8_FOURCC, &vpx_codec_vp8_dx }, + { "vp9", VP9_FOURCC, &vpx_codec_vp9_dx }, +}; + +int get_vpx_decoder_count(void) { + return sizeof(vpx_decoders) / sizeof(vpx_decoders[0]); +} + +const VpxInterface *get_vpx_decoder_by_index(int i) { return &vpx_decoders[i]; } + +const VpxInterface *get_vpx_decoder_by_name(const char *name) { + int i; + + for (i = 0; i < get_vpx_decoder_count(); ++i) { + const VpxInterface *const decoder = get_vpx_decoder_by_index(i); + if (strcmp(decoder->name, name) == 0) return decoder; + } + + return NULL; } void die_codec(vpx_codec_ctx_t *ctx, const char *s) { - const char *detail = vpx_codec_error_detail(ctx); + if (ctx) { + const char *detail = vpx_codec_error_detail(ctx); - printf("%s: %s\n", s, vpx_codec_error(ctx)); - if (detail) printf(" %s\n", detail); + fprintf(stderr, "%s: %s\n", s, vpx_codec_error(ctx)); + if (detail) fprintf(stderr, " %s\n", detail); + } else { + fprintf(stderr, "%s", s); + } exit(EXIT_FAILURE); } -
\ No newline at end of file +// TODO(dkovalev): move this function to vpx_image.{c, h}, so it will be part +// of vpx_image_t support +int vpx_img_plane_width(const vpx_image_t *img, int plane) { + if (plane > 0 && img->x_chroma_shift > 0) + return (img->d_w + 1) >> img->x_chroma_shift; + else + return img->d_w; +} + +int vpx_img_plane_height(const vpx_image_t *img, int plane) { + if (plane > 0 && img->y_chroma_shift > 0) + return (img->d_h + 1) >> img->y_chroma_shift; + else + return img->d_h; +} + +int vpx_img_read(vpx_image_t *img, void *img_buf, int sz) { + int plane; + int off = 0; + + for (plane = 0; plane < 3; ++plane) { + unsigned char *buf = img->planes[plane]; + const int stride = img->stride[plane]; + const int w = vpx_img_plane_width(img, plane) * + ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1); + const int h = vpx_img_plane_height(img, plane); + int y; + + for (y = 0; y < h; ++y) { + if (off + w > sz) return 0; + memcpy(buf, img_buf + off, w); + off += w; + buf += stride; + } + } + + return 1; +} + +int vpx_img_write(const vpx_image_t *img, void *img_buf, int sz) { + int plane; + int off = 0; + + for (plane = 0; plane < 3; ++plane) { + const unsigned char *buf = img->planes[plane]; + const int stride = img->stride[plane]; + const int w = vpx_img_plane_width(img, plane) * + ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1); + const int h = vpx_img_plane_height(img, plane); + int y; + + for (y = 0; y < h; ++y) { + if (off + w > sz) return 0; + memcpy(img_buf + off, buf, w); + off += w; + buf += stride; + } + } + + return 1; +} + +int vpx_img_read_f(vpx_image_t *img, FILE *file) { + int plane; + + for (plane = 0; plane < 3; ++plane) { + unsigned char *buf = img->planes[plane]; + const int stride = img->stride[plane]; + const int w = vpx_img_plane_width(img, plane) * + ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1); + const int h = vpx_img_plane_height(img, plane); + int y; + + for (y = 0; y < h; ++y) { + if (fread(buf, 1, w, file) != (size_t)w) return 0; + buf += stride; + } + } + + return 1; +} + +int vpx_img_write_f(const vpx_image_t *img, FILE *file) { + int plane; + + for (plane = 0; plane < 3; ++plane) { + const unsigned char *buf = img->planes[plane]; + const int stride = img->stride[plane]; + const int w = vpx_img_plane_width(img, plane) * + ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1); + const int h = vpx_img_plane_height(img, plane); + int y; + + for (y = 0; y < h; ++y) { + if (fwrite(buf, 1, w, file) != (size_t)w) return 0; + buf += stride; + } + } +} + diff --git a/code/test/vid/tools.h b/code/test/vid/tools.h index 0bbf512..645d5ba 100644 --- a/code/test/vid/tools.h +++ b/code/test/vid/tools.h @@ -4,6 +4,7 @@ #include "vpx/vpx_codec.h" #include "vpx/vpx_image.h" #include "vpx/vp8cx.h" +#include "vpx/vp8dx.h" #define VP8_FOURCC 0x30385056 #define VP9_FOURCC 0x30395056 @@ -19,11 +20,18 @@ typedef struct VpxInterface { vpx_codec_iface_t *(*const codec_interface)(); } VpxInterface; -void usage_exit(void); const VpxInterface *get_vpx_encoder_by_index(int i); const VpxInterface *get_vpx_encoder_by_name(const char *name); -void die(const char *fmt, ...); +const VpxInterface *get_vpx_decoder_by_index(int i); +const VpxInterface *get_vpx_decoder_by_name(const char *name); + void die_codec(vpx_codec_ctx_t *ctx, const char *s); +int vpx_img_read(vpx_image_t *img, void *img_buf, int sz); +int vpx_img_write(const vpx_image_t *img, void *img_buf, int sz); + +int vpx_img_read_f(vpx_image_t *img, FILE *file); +int vpx_img_write_f(const vpx_image_t *img, FILE *file); + #endif
\ No newline at end of file |