1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/*
2233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
3233d2500723e5594f3e7c70896ffeeef32b9c950ywan *
4233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Use of this source code is governed by a BSD-style license
5233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  that can be found in the LICENSE file in the root of the source
6233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  tree. An additional intellectual property rights grant can be found
7233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  in the file PATENTS.  All contributing project authors may
8233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  be found in the AUTHORS file in the root of the source tree.
9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */
10233d2500723e5594f3e7c70896ffeeef32b9c950ywan
11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./vpxstats.h"
12233d2500723e5594f3e7c70896ffeeef32b9c950ywan
13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <math.h>
14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdlib.h>
15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <string.h>
16233d2500723e5594f3e7c70896ffeeef32b9c950ywan
17233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./tools_common.h"
18233d2500723e5594f3e7c70896ffeeef32b9c950ywan
19233d2500723e5594f3e7c70896ffeeef32b9c950ywanint stats_open_file(stats_io_t *stats, const char *fpf, int pass) {
20233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int res;
21233d2500723e5594f3e7c70896ffeeef32b9c950ywan  stats->pass = pass;
22233d2500723e5594f3e7c70896ffeeef32b9c950ywan
23233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (pass == 0) {
24233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->file = fopen(fpf, "wb");
25233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->buf.sz = 0;
26233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->buf.buf = NULL;
27233d2500723e5594f3e7c70896ffeeef32b9c950ywan    res = (stats->file != NULL);
28233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
29233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if USE_POSIX_MMAP
30233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct stat stat_buf;
31233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int fd;
32233d2500723e5594f3e7c70896ffeeef32b9c950ywan
33233d2500723e5594f3e7c70896ffeeef32b9c950ywan    fd = open(fpf, O_RDONLY);
34233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->file = fdopen(fd, "rb");
35233d2500723e5594f3e7c70896ffeeef32b9c950ywan    fstat(fd, &stat_buf);
36233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->buf.sz = stat_buf.st_size;
37233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->buf.buf = mmap(NULL, stats->buf.sz, PROT_READ, MAP_PRIVATE, fd, 0);
38233d2500723e5594f3e7c70896ffeeef32b9c950ywan    res = (stats->buf.buf != NULL);
39233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else
40233d2500723e5594f3e7c70896ffeeef32b9c950ywan    size_t nbytes;
41233d2500723e5594f3e7c70896ffeeef32b9c950ywan
42233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->file = fopen(fpf, "rb");
43233d2500723e5594f3e7c70896ffeeef32b9c950ywan
44233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (fseek(stats->file, 0, SEEK_END))
45233d2500723e5594f3e7c70896ffeeef32b9c950ywan      fatal("First-pass stats file must be seekable!");
46233d2500723e5594f3e7c70896ffeeef32b9c950ywan
47233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->buf.sz = stats->buf_alloc_sz = ftell(stats->file);
48233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rewind(stats->file);
49233d2500723e5594f3e7c70896ffeeef32b9c950ywan
50233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->buf.buf = malloc(stats->buf_alloc_sz);
51233d2500723e5594f3e7c70896ffeeef32b9c950ywan
52233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!stats->buf.buf)
53233d2500723e5594f3e7c70896ffeeef32b9c950ywan      fatal("Failed to allocate first-pass stats buffer (%lu bytes)",
54233d2500723e5594f3e7c70896ffeeef32b9c950ywan            (unsigned int)stats->buf_alloc_sz);
55233d2500723e5594f3e7c70896ffeeef32b9c950ywan
56233d2500723e5594f3e7c70896ffeeef32b9c950ywan    nbytes = fread(stats->buf.buf, 1, stats->buf.sz, stats->file);
57233d2500723e5594f3e7c70896ffeeef32b9c950ywan    res = (nbytes == stats->buf.sz);
58233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif  /* USE_POSIX_MMAP */
59233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
60233d2500723e5594f3e7c70896ffeeef32b9c950ywan
61233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return res;
62233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
63233d2500723e5594f3e7c70896ffeeef32b9c950ywan
64233d2500723e5594f3e7c70896ffeeef32b9c950ywanint stats_open_mem(stats_io_t *stats, int pass) {
65233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int res;
66233d2500723e5594f3e7c70896ffeeef32b9c950ywan  stats->pass = pass;
67233d2500723e5594f3e7c70896ffeeef32b9c950ywan
68233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!pass) {
69233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->buf.sz = 0;
70233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->buf_alloc_sz = 64 * 1024;
71233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->buf.buf = malloc(stats->buf_alloc_sz);
72233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
73233d2500723e5594f3e7c70896ffeeef32b9c950ywan
74233d2500723e5594f3e7c70896ffeeef32b9c950ywan  stats->buf_ptr = stats->buf.buf;
75233d2500723e5594f3e7c70896ffeeef32b9c950ywan  res = (stats->buf.buf != NULL);
76233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return res;
77233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
78233d2500723e5594f3e7c70896ffeeef32b9c950ywan
79233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid stats_close(stats_io_t *stats, int last_pass) {
80233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (stats->file) {
81233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (stats->pass == last_pass) {
82233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if USE_POSIX_MMAP
83233d2500723e5594f3e7c70896ffeeef32b9c950ywan      munmap(stats->buf.buf, stats->buf.sz);
84233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else
85233d2500723e5594f3e7c70896ffeeef32b9c950ywan      free(stats->buf.buf);
86233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif  /* USE_POSIX_MMAP */
87233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
88233d2500723e5594f3e7c70896ffeeef32b9c950ywan
89233d2500723e5594f3e7c70896ffeeef32b9c950ywan    fclose(stats->file);
90233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->file = NULL;
91233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
92233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (stats->pass == last_pass)
93233d2500723e5594f3e7c70896ffeeef32b9c950ywan      free(stats->buf.buf);
94233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
95233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
96233d2500723e5594f3e7c70896ffeeef32b9c950ywan
97233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid stats_write(stats_io_t *stats, const void *pkt, size_t len) {
98233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (stats->file) {
99233d2500723e5594f3e7c70896ffeeef32b9c950ywan    (void) fwrite(pkt, 1, len, stats->file);
100233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
101233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (stats->buf.sz + len > stats->buf_alloc_sz) {
102233d2500723e5594f3e7c70896ffeeef32b9c950ywan      size_t  new_sz = stats->buf_alloc_sz + 64 * 1024;
103233d2500723e5594f3e7c70896ffeeef32b9c950ywan      char   *new_ptr = realloc(stats->buf.buf, new_sz);
104233d2500723e5594f3e7c70896ffeeef32b9c950ywan
105233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (new_ptr) {
106233d2500723e5594f3e7c70896ffeeef32b9c950ywan        stats->buf_ptr = new_ptr + (stats->buf_ptr - (char *)stats->buf.buf);
107233d2500723e5594f3e7c70896ffeeef32b9c950ywan        stats->buf.buf = new_ptr;
108233d2500723e5594f3e7c70896ffeeef32b9c950ywan        stats->buf_alloc_sz = new_sz;
109233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else {
110233d2500723e5594f3e7c70896ffeeef32b9c950ywan        fatal("Failed to realloc firstpass stats buffer.");
111233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
112233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
113233d2500723e5594f3e7c70896ffeeef32b9c950ywan
114233d2500723e5594f3e7c70896ffeeef32b9c950ywan    memcpy(stats->buf_ptr, pkt, len);
115233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->buf.sz += len;
116233d2500723e5594f3e7c70896ffeeef32b9c950ywan    stats->buf_ptr += len;
117233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
118233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
119233d2500723e5594f3e7c70896ffeeef32b9c950ywan
120233d2500723e5594f3e7c70896ffeeef32b9c950ywanvpx_fixed_buf_t stats_get(stats_io_t *stats) {
121233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return stats->buf;
122233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
123