From 78cb2e6553cdf63886a1ab17578aca462e9dc50d Mon Sep 17 00:00:00 2001 From: Tom Finegan Date: Thu, 7 Nov 2013 21:28:45 -0800 Subject: [PATCH] vpxenc: clean up; move stats code out of vpxenc.c Change-Id: I6b245ef5017c49373ba33e30f8fbf3d1b97409b5 --- examples.mk | 1 + vpxenc.c | 147 +++------------------------------------------------- vpxstats.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++ vpxstats.h | 37 +++++++++++++ 4 files changed, 179 insertions(+), 141 deletions(-) create mode 100644 vpxstats.c create mode 100644 vpxstats.h diff --git a/examples.mk b/examples.mk index 2cee298c2..16f3c8fa2 100644 --- a/examples.mk +++ b/examples.mk @@ -41,6 +41,7 @@ vpxenc.SRCS += webmenc.c webmenc.h vpxenc.SRCS += vpx_ports/mem_ops.h vpxenc.SRCS += vpx_ports/mem_ops_aligned.h vpxenc.SRCS += vpx_ports/vpx_timer.h +vpxenc.SRCS += vpxstats.c vpxstats.h vpxenc.SRCS += third_party/libmkv/EbmlIDs.h vpxenc.SRCS += third_party/libmkv/EbmlWriter.c vpxenc.SRCS += third_party/libmkv/EbmlWriter.h diff --git a/vpxenc.c b/vpxenc.c index f0f0df35e..b7897dbf3 100644 --- a/vpxenc.c +++ b/vpxenc.c @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "vpx_config.h" +#include "./vpx_config.h" #if defined(_WIN32) || defined(__OS2__) || !CONFIG_OS_SUPPORT #define USE_POSIX_MMAP 0 @@ -16,6 +16,7 @@ #define USE_POSIX_MMAP 1 #endif +#include #include #include #include @@ -43,11 +44,12 @@ #include "vpx/vp8dx.h" #endif +#include "./tools_common.h" #include "vpx_ports/mem_ops.h" #include "vpx_ports/vpx_timer.h" -#include "tools_common.h" -#include "webmenc.h" -#include "y4minput.h" +#include "./vpxstats.h" +#include "./webmenc.h" +#include "./y4minput.h" /* Swallow warnings about unused results of fread/fwrite */ static size_t wrap_fread(void *ptr, size_t size, size_t nmemb, @@ -116,126 +118,6 @@ static void warn_or_exit_on_error(vpx_codec_ctx_t *ctx, int fatal, va_end(ap); } -/* This structure is used to abstract the different ways of handling - * first pass statistics. - */ -typedef struct { - vpx_fixed_buf_t buf; - int pass; - FILE *file; - char *buf_ptr; - size_t buf_alloc_sz; -} stats_io_t; - -int stats_open_file(stats_io_t *stats, const char *fpf, int pass) { - int res; - - stats->pass = pass; - - if (pass == 0) { - stats->file = fopen(fpf, "wb"); - stats->buf.sz = 0; - stats->buf.buf = NULL, - res = (stats->file != NULL); - } else { -#if 0 -#elif USE_POSIX_MMAP - struct stat stat_buf; - int fd; - - fd = open(fpf, O_RDONLY); - stats->file = fdopen(fd, "rb"); - fstat(fd, &stat_buf); - stats->buf.sz = stat_buf.st_size; - stats->buf.buf = mmap(NULL, stats->buf.sz, PROT_READ, MAP_PRIVATE, - fd, 0); - res = (stats->buf.buf != NULL); -#else - size_t nbytes; - - stats->file = fopen(fpf, "rb"); - - if (fseek(stats->file, 0, SEEK_END)) - fatal("First-pass stats file must be seekable!"); - - stats->buf.sz = stats->buf_alloc_sz = ftell(stats->file); - rewind(stats->file); - - stats->buf.buf = malloc(stats->buf_alloc_sz); - - if (!stats->buf.buf) - fatal("Failed to allocate first-pass stats buffer (%lu bytes)", - (unsigned long)stats->buf_alloc_sz); - - nbytes = fread(stats->buf.buf, 1, stats->buf.sz, stats->file); - res = (nbytes == stats->buf.sz); -#endif - } - - return res; -} - -int stats_open_mem(stats_io_t *stats, int pass) { - int res; - stats->pass = pass; - - if (!pass) { - stats->buf.sz = 0; - stats->buf_alloc_sz = 64 * 1024; - stats->buf.buf = malloc(stats->buf_alloc_sz); - } - - stats->buf_ptr = stats->buf.buf; - res = (stats->buf.buf != NULL); - return res; -} - - -void stats_close(stats_io_t *stats, int last_pass) { - if (stats->file) { - if (stats->pass == last_pass) { -#if 0 -#elif USE_POSIX_MMAP - munmap(stats->buf.buf, stats->buf.sz); -#else - free(stats->buf.buf); -#endif - } - - fclose(stats->file); - stats->file = NULL; - } else { - if (stats->pass == last_pass) - free(stats->buf.buf); - } -} - -void stats_write(stats_io_t *stats, const void *pkt, size_t len) { - if (stats->file) { - (void) fwrite(pkt, 1, len, stats->file); - } else { - if (stats->buf.sz + len > stats->buf_alloc_sz) { - size_t new_sz = stats->buf_alloc_sz + 64 * 1024; - char *new_ptr = realloc(stats->buf.buf, new_sz); - - if (new_ptr) { - stats->buf_ptr = new_ptr + (stats->buf_ptr - (char *)stats->buf.buf); - stats->buf.buf = new_ptr; - stats->buf_alloc_sz = new_sz; - } else - fatal("Failed to realloc firstpass stats buffer."); - } - - memcpy(stats->buf_ptr, pkt, len); - stats->buf.sz += len; - stats->buf_ptr += len; - } -} - -vpx_fixed_buf_t stats_get(stats_io_t *stats) { - return stats->buf; -} - enum video_file_type { FILE_TYPE_RAW, FILE_TYPE_IVF, @@ -263,7 +145,6 @@ struct input_state { int only_i420; }; - #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) { FILE *f = input->file; @@ -478,22 +359,6 @@ static unsigned int murmur(const void *key, int len, unsigned int seed) { return h; } -#include "math.h" -#define MAX_PSNR 100 -static double vp8_mse2psnr(double Samples, double Peak, double Mse) { - double psnr; - - if ((double)Mse > 0.0) - psnr = 10.0 * log10(Peak * Peak * Samples / Mse); - else - psnr = MAX_PSNR; /* Limit to prevent / 0 */ - - if (psnr > MAX_PSNR) - psnr = MAX_PSNR; - - return psnr; -} - #include "args.h" static const arg_def_t debugmode = ARG_DEF("D", "debug", 0, diff --git a/vpxstats.c b/vpxstats.c new file mode 100644 index 000000000..70cea3ee7 --- /dev/null +++ b/vpxstats.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "./vpxstats.h" + +#include +#include +#include + +#include "./tools_common.h" + +int stats_open_file(stats_io_t *stats, const char *fpf, int pass) { + int res; + stats->pass = pass; + + if (pass == 0) { + stats->file = fopen(fpf, "wb"); + stats->buf.sz = 0; + stats->buf.buf = NULL; + res = (stats->file != NULL); + } else { +#if USE_POSIX_MMAP + struct stat stat_buf; + int fd; + + fd = open(fpf, O_RDONLY); + stats->file = fdopen(fd, "rb"); + fstat(fd, &stat_buf); + stats->buf.sz = stat_buf.st_size; + stats->buf.buf = mmap(NULL, stats->buf.sz, PROT_READ, MAP_PRIVATE, fd, 0); + res = (stats->buf.buf != NULL); +#else + size_t nbytes; + + stats->file = fopen(fpf, "rb"); + + if (fseek(stats->file, 0, SEEK_END)) + fatal("First-pass stats file must be seekable!"); + + stats->buf.sz = stats->buf_alloc_sz = ftell(stats->file); + rewind(stats->file); + + stats->buf.buf = malloc(stats->buf_alloc_sz); + + if (!stats->buf.buf) + fatal("Failed to allocate first-pass stats buffer (%lu bytes)", + (unsigned int)stats->buf_alloc_sz); + + nbytes = fread(stats->buf.buf, 1, stats->buf.sz, stats->file); + res = (nbytes == stats->buf.sz); +#endif /* USE_POSIX_MMAP */ + } + + return res; +} + +int stats_open_mem(stats_io_t *stats, int pass) { + int res; + stats->pass = pass; + + if (!pass) { + stats->buf.sz = 0; + stats->buf_alloc_sz = 64 * 1024; + stats->buf.buf = malloc(stats->buf_alloc_sz); + } + + stats->buf_ptr = stats->buf.buf; + res = (stats->buf.buf != NULL); + return res; +} + +void stats_close(stats_io_t *stats, int last_pass) { + if (stats->file) { + if (stats->pass == last_pass) { +#if USE_POSIX_MMAP + munmap(stats->buf.buf, stats->buf.sz); +#else + free(stats->buf.buf); +#endif /* USE_POSIX_MMAP */ + } + + fclose(stats->file); + stats->file = NULL; + } else { + if (stats->pass == last_pass) + free(stats->buf.buf); + } +} + +void stats_write(stats_io_t *stats, const void *pkt, size_t len) { + if (stats->file) { + (void) fwrite(pkt, 1, len, stats->file); + } else { + if (stats->buf.sz + len > stats->buf_alloc_sz) { + size_t new_sz = stats->buf_alloc_sz + 64 * 1024; + char *new_ptr = realloc(stats->buf.buf, new_sz); + + if (new_ptr) { + stats->buf_ptr = new_ptr + (stats->buf_ptr - (char *)stats->buf.buf); + stats->buf.buf = new_ptr; + stats->buf_alloc_sz = new_sz; + } else { + fatal("Failed to realloc firstpass stats buffer."); + } + } + + memcpy(stats->buf_ptr, pkt, len); + stats->buf.sz += len; + stats->buf_ptr += len; + } +} + +vpx_fixed_buf_t stats_get(stats_io_t *stats) { + return stats->buf; +} + +double vp8_mse2psnr(double samples, double peak, double mse) { + const int kMaxPSNR = 100; + double psnr = kMaxPSNR; + + if (mse > 0.0) + psnr = 10.0 * log10(peak * peak * samples / mse); + + if (psnr > kMaxPSNR) + psnr = kMaxPSNR; + + return psnr; +} diff --git a/vpxstats.h b/vpxstats.h new file mode 100644 index 000000000..18b3acdc0 --- /dev/null +++ b/vpxstats.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef VPXSTATS_H_ +#define VPXSTATS_H_ + +#include + +#include "vpx/vpx_encoder.h" + +/* This structure is used to abstract the different ways of handling + * first pass statistics + */ +typedef struct { + vpx_fixed_buf_t buf; + int pass; + FILE *file; + char *buf_ptr; + size_t buf_alloc_sz; +} stats_io_t; + +int stats_open_file(stats_io_t *stats, const char *fpf, int pass); +int stats_open_mem(stats_io_t *stats, int pass); +void stats_close(stats_io_t *stats, int last_pass); +void stats_write(stats_io_t *stats, const void *pkt, size_t len); +vpx_fixed_buf_t stats_get(stats_io_t *stats); + +double vp8_mse2psnr(double samples, double peak, double mse); + +#endif // VPXSTATS_H_ -- 2.40.0