FFmpeg
probetest.c
Go to the documentation of this file.
1 /*
2  * copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <stdlib.h>
22 
23 #include "libavformat/avformat.h"
24 #include "libavformat/demux.h"
25 #include "libavcodec/put_bits.h"
26 #include "libavutil/lfg.h"
27 #include "libavutil/mem.h"
28 #include "libavutil/timer.h"
29 
30 #define MAX_FORMATS 1000 //this must be larger than the number of formats
32 static int64_t time_array[MAX_FORMATS];
33 static int failures = 0;
34 static const char *single_format;
35 
36 #ifndef AV_READ_TIME
37 #define AV_READ_TIME(x) 0
38 #endif
39 
40 static void probe(AVProbeData *pd, int type, int p, int size)
41 {
42  int i = 0;
43  const AVInputFormat *fmt = NULL;
44  void *fmt_opaque = NULL;
45 
46  while ((fmt = av_demuxer_iterate(&fmt_opaque))) {
47  if (fmt->flags & AVFMT_NOFILE)
48  continue;
49  if (ffifmt(fmt)->read_probe &&
50  (!single_format || !strcmp(single_format, fmt->name))
51  ) {
52  int score;
53  int64_t start = AV_READ_TIME();
54  score = ffifmt(fmt)->read_probe(pd);
55  time_array[i] += AV_READ_TIME() - start;
56  if (score > score_array[i] && score > AVPROBE_SCORE_MAX / 4) {
57  score_array[i] = score;
58  fprintf(stderr,
59  "Failure of %s probing code with score=%d type=%d p=%X size=%d\n",
60  fmt->name, score, type, p, size);
61  failures++;
62  }
63  }
64  i++;
65  }
66 }
67 
68 static void print_times(void)
69 {
70  int i = 0;
71  const AVInputFormat *fmt = NULL;
72  void *fmt_opaque = NULL;
73 
74  while ((fmt = av_demuxer_iterate(&fmt_opaque))) {
75  if (fmt->flags & AVFMT_NOFILE)
76  continue;
77  if (time_array[i] > 1000000) {
78  fprintf(stderr, "%12"PRIu64" cycles, %12s\n",
79  time_array[i], fmt->name);
80  }
81  i++;
82  }
83 }
84 
85 static int read_int(char *arg) {
86  int ret;
87 
88  if (!arg || !*arg)
89  return -1;
90  ret = strtol(arg, &arg, 0);
91  if (*arg)
92  return -1;
93  return ret;
94 }
95 
96 int main(int argc, char **argv)
97 {
98  unsigned int p, i, type, size, retry;
99  AVProbeData pd = { 0 };
100  AVLFG state;
101  PutBitContext pb;
102  int retry_count= 4097;
103  int max_size = 65537;
104  int j;
105 
106  for (j = i = 1; i<argc; i++) {
107  if (!strcmp(argv[i], "-f") && i+1<argc && !single_format) {
108  single_format = argv[++i];
109  } else if (read_int(argv[i])>0 && j == 1) {
110  retry_count = read_int(argv[i]);
111  j++;
112  } else if (read_int(argv[i])>0 && j == 2) {
113  max_size = read_int(argv[i]);
114  j++;
115  } else {
116  fprintf(stderr, "probetest [-f <input format>] [<retry_count> [<max_size>]]\n");
117  return 1;
118  }
119  }
120 
121  if (max_size > 1000000000U/8) {
122  fprintf(stderr, "max_size out of bounds\n");
123  return 1;
124  }
125 
126  if (retry_count > 1000000000U) {
127  fprintf(stderr, "retry_count out of bounds\n");
128  return 1;
129  }
130 
131  av_lfg_init(&state, 0xdeadbeef);
132 
133  pd.buf = NULL;
134  for (size = 1; size < max_size; size *= 2) {
135  pd.buf_size = size;
137  pd.filename = "";
138 
139  if (!pd.buf) {
140  fprintf(stderr, "out of memory\n");
141  return 1;
142  }
143 
144  memset(pd.buf, 0, size + AVPROBE_PADDING_SIZE);
145 
146  fprintf(stderr, "testing size=%d\n", size);
147 
148  for (retry = 0; retry < retry_count; retry += FFMAX(size, 32)) {
149  for (type = 0; type < 4; type++) {
150  for (p = 0; p < 4096; p++) {
151  unsigned hist = 0;
152  init_put_bits(&pb, pd.buf, size);
153  switch (type) {
154  case 0:
155  for (i = 0; i < size * 8; i++)
156  put_bits(&pb, 1, (av_lfg_get(&state) & 0xFFFFFFFF) > p << 20);
157  break;
158  case 1:
159  for (i = 0; i < size * 8; i++) {
160  unsigned int p2 = hist ? p & 0x3F : (p >> 6);
161  unsigned int v = (av_lfg_get(&state) & 0xFFFFFFFF) > p2 << 26;
162  put_bits(&pb, 1, v);
163  hist = v;
164  }
165  break;
166  case 2:
167  for (i = 0; i < size * 8; i++) {
168  unsigned int p2 = (p >> (hist * 3)) & 7;
169  unsigned int v = (av_lfg_get(&state) & 0xFFFFFFFF) > p2 << 29;
170  put_bits(&pb, 1, v);
171  hist = (2 * hist + v) & 3;
172  }
173  break;
174  case 3:
175  for (i = 0; i < size; i++) {
176  int c = 0;
177  while (p & 63) {
178  c = (av_lfg_get(&state) & 0xFFFFFFFF) >> 24;
179  if (c >= 'a' && c <= 'z' && (p & 1))
180  break;
181  else if (c >= 'A' && c <= 'Z' && (p & 2))
182  break;
183  else if (c >= '0' && c <= '9' && (p & 4))
184  break;
185  else if (c == ' ' && (p & 8))
186  break;
187  else if (c == 0 && (p & 16))
188  break;
189  else if (c == 1 && (p & 32))
190  break;
191  }
192  pd.buf[i] = c;
193  }
194  }
195  flush_put_bits(&pb);
196  probe(&pd, type, p, size);
197  }
198  }
199  }
200  }
201  if(AV_READ_TIME())
202  print_times();
203  return failures;
204 }
MAX_FORMATS
#define MAX_FORMATS
Definition: probetest.c:30
FFInputFormat::read_probe
int(* read_probe)(const AVProbeData *)
Tell if a given file has a chance of being parsed as this format.
Definition: demux.h:63
av_lfg_init
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:32
init_put_bits
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:62
main
int main(int argc, char **argv)
Definition: probetest.c:96
put_bits
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:223
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:454
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
score_array
static int score_array[MAX_FORMATS]
Definition: probetest.c:31
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
AVPROBE_PADDING_SIZE
#define AVPROBE_PADDING_SIZE
extra allocated bytes at the end of the probe buffer
Definition: avformat.h:465
AVInputFormat
Definition: avformat.h:548
av_lfg_get
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition: lfg.h:53
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:553
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
AVProbeData::filename
const char * filename
Definition: avformat.h:452
lfg.h
read_int
static int read_int(char *arg)
Definition: probetest.c:85
time_array
static int64_t time_array[MAX_FORMATS]
Definition: probetest.c:32
PutBitContext
Definition: put_bits.h:50
arg
const char * arg
Definition: jacosubdec.c:67
NULL
#define NULL
Definition: coverity.c:32
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
timer.h
state
static struct @435 state
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVLFG
Context structure for the Lagged Fibonacci PRNG.
Definition: lfg.h:33
size
int size
Definition: twinvq_data.h:10344
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:468
av_demuxer_iterate
const AVInputFormat * av_demuxer_iterate(void **opaque)
Iterate over all registered demuxers.
Definition: allformats.c:606
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
single_format
static const char * single_format
Definition: probetest.c:34
demux.h
ret
ret
Definition: filter_design.txt:187
avformat.h
U
#define U(x)
Definition: vpx_arith.h:37
AVInputFormat::flags
int flags
Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS, AVFMT_NOTIMESTAMPS,...
Definition: avformat.h:567
ffifmt
static const FFInputFormat * ffifmt(const AVInputFormat *fmt)
Definition: demux.h:133
AV_READ_TIME
#define AV_READ_TIME(x)
Definition: probetest.c:37
failures
static int failures
Definition: probetest.c:33
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
mem.h
flush_put_bits
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:143
print_times
static void print_times(void)
Definition: probetest.c:68
put_bits.h
probe
static void probe(AVProbeData *pd, int type, int p, int size)
Definition: probetest.c:40
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155