vsrc_mptestsrc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002 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 modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 /**
22  * @file
23  * MP test source, ported from MPlayer libmpcodecs/vf_test.c
24  */
25 
26 #include "libavutil/avstring.h"
27 #include "libavutil/opt.h"
28 #include "libavutil/parseutils.h"
29 #include "libavutil/pixdesc.h"
30 #include "avfilter.h"
31 #include "internal.h"
32 #include "formats.h"
33 #include "video.h"
34 
35 #define WIDTH 512
36 #define HEIGHT 512
37 
38 enum test_type {
51 };
52 
53 typedef struct MPTestContext {
54  const AVClass *class;
55  unsigned int frame_nb;
57  int64_t pts, max_pts, duration;
58  int hsub, vsub;
61 
62 #define OFFSET(x) offsetof(MPTestContext, x)
63 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
64 static const AVOption mptestsrc_options[]= {
65  { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
66  { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
67  { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },
68  { "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },
69 
70  { "test", "set test to perform", OFFSET(test), AV_OPT_TYPE_INT, {.i64=TEST_ALL}, 0, INT_MAX, FLAGS, "test" },
71  { "t", "set test to perform", OFFSET(test), AV_OPT_TYPE_INT, {.i64=TEST_ALL}, 0, INT_MAX, FLAGS, "test" },
72  { "dc_luma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_DC_LUMA}, INT_MIN, INT_MAX, FLAGS, "test" },
73  { "dc_chroma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_DC_CHROMA}, INT_MIN, INT_MAX, FLAGS, "test" },
74  { "freq_luma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_FREQ_LUMA}, INT_MIN, INT_MAX, FLAGS, "test" },
75  { "freq_chroma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_FREQ_CHROMA}, INT_MIN, INT_MAX, FLAGS, "test" },
76  { "amp_luma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_AMP_LUMA}, INT_MIN, INT_MAX, FLAGS, "test" },
77  { "amp_chroma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_AMP_CHROMA}, INT_MIN, INT_MAX, FLAGS, "test" },
78  { "cbp", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_CBP}, INT_MIN, INT_MAX, FLAGS, "test" },
79  { "mv", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_MV}, INT_MIN, INT_MAX, FLAGS, "test" },
80  { "ring1", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_RING1}, INT_MIN, INT_MAX, FLAGS, "test" },
81  { "ring2", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_RING2}, INT_MIN, INT_MAX, FLAGS, "test" },
82  { "all", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_ALL}, INT_MIN, INT_MAX, FLAGS, "test" },
83  { NULL },
84 };
85 
86 AVFILTER_DEFINE_CLASS(mptestsrc);
87 
88 static double c[64];
89 
90 static void init_idct(void)
91 {
92  int i, j;
93 
94  for (i = 0; i < 8; i++) {
95  double s = i == 0 ? sqrt(0.125) : 0.5;
96 
97  for (j = 0; j < 8; j++)
98  c[i*8+j] = s*cos((M_PI/8.0)*i*(j+0.5));
99  }
100 }
101 
102 static void idct(uint8_t *dst, int dst_linesize, int src[64])
103 {
104  int i, j, k;
105  double tmp[64];
106 
107  for (i = 0; i < 8; i++) {
108  for (j = 0; j < 8; j++) {
109  double sum = 0.0;
110 
111  for (k = 0; k < 8; k++)
112  sum += c[k*8+j] * src[8*i+k];
113 
114  tmp[8*i+j] = sum;
115  }
116  }
117 
118  for (j = 0; j < 8; j++) {
119  for (i = 0; i < 8; i++) {
120  double sum = 0.0;
121 
122  for (k = 0; k < 8; k++)
123  sum += c[k*8+i]*tmp[8*k+j];
124 
125  dst[dst_linesize*i + j] = av_clip((int)floor(sum+0.5), 0, 255);
126  }
127  }
128 }
129 
130 static void draw_dc(uint8_t *dst, int dst_linesize, int color, int w, int h)
131 {
132  int x, y;
133 
134  for (y = 0; y < h; y++)
135  for (x = 0; x < w; x++)
136  dst[x + y*dst_linesize] = color;
137 }
138 
139 static void draw_basis(uint8_t *dst, int dst_linesize, int amp, int freq, int dc)
140 {
141  int src[64];
142 
143  memset(src, 0, 64*sizeof(int));
144  src[0] = dc;
145  if (amp)
146  src[freq] = amp;
147  idct(dst, dst_linesize, src);
148 }
149 
150 static void draw_cbp(uint8_t *dst[3], int dst_linesize[3], int cbp, int amp, int dc)
151 {
152  if (cbp&1) draw_basis(dst[0] , dst_linesize[0], amp, 1, dc);
153  if (cbp&2) draw_basis(dst[0]+8 , dst_linesize[0], amp, 1, dc);
154  if (cbp&4) draw_basis(dst[0]+ 8*dst_linesize[0], dst_linesize[0], amp, 1, dc);
155  if (cbp&8) draw_basis(dst[0]+8+8*dst_linesize[0], dst_linesize[0], amp, 1, dc);
156  if (cbp&16) draw_basis(dst[1] , dst_linesize[1], amp, 1, dc);
157  if (cbp&32) draw_basis(dst[2] , dst_linesize[2], amp, 1, dc);
158 }
159 
160 static void dc_test(uint8_t *dst, int dst_linesize, int w, int h, int off)
161 {
162  const int step = FFMAX(256/(w*h/256), 1);
163  int x, y, color = off;
164 
165  for (y = 0; y < h; y += 16) {
166  for (x = 0; x < w; x += 16) {
167  draw_dc(dst + x + y*dst_linesize, dst_linesize, color, 8, 8);
168  color += step;
169  }
170  }
171 }
172 
173 static void freq_test(uint8_t *dst, int dst_linesize, int off)
174 {
175  int x, y, freq = 0;
176 
177  for (y = 0; y < 8*16; y += 16) {
178  for (x = 0; x < 8*16; x += 16) {
179  draw_basis(dst + x + y*dst_linesize, dst_linesize, 4*(96+off), freq, 128*8);
180  freq++;
181  }
182  }
183 }
184 
185 static void amp_test(uint8_t *dst, int dst_linesize, int off)
186 {
187  int x, y, amp = off;
188 
189  for (y = 0; y < 16*16; y += 16) {
190  for (x = 0; x < 16*16; x += 16) {
191  draw_basis(dst + x + y*dst_linesize, dst_linesize, 4*amp, 1, 128*8);
192  amp++;
193  }
194  }
195 }
196 
197 static void cbp_test(uint8_t *dst[3], int dst_linesize[3], int off)
198 {
199  int x, y, cbp = 0;
200 
201  for (y = 0; y < 16*8; y += 16) {
202  for (x = 0; x < 16*8; x += 16) {
203  uint8_t *dst1[3];
204  dst1[0] = dst[0] + x*2 + y*2*dst_linesize[0];
205  dst1[1] = dst[1] + x + y* dst_linesize[1];
206  dst1[2] = dst[2] + x + y* dst_linesize[2];
207 
208  draw_cbp(dst1, dst_linesize, cbp, (64+off)*4, 128*8);
209  cbp++;
210  }
211  }
212 }
213 
214 static void mv_test(uint8_t *dst, int dst_linesize, int off)
215 {
216  int x, y;
217 
218  for (y = 0; y < 16*16; y++) {
219  if (y&16)
220  continue;
221  for (x = 0; x < 16*16; x++)
222  dst[x + y*dst_linesize] = x + off*8/(y/32+1);
223  }
224 }
225 
226 static void ring1_test(uint8_t *dst, int dst_linesize, int off)
227 {
228  int x, y, color = 0;
229 
230  for (y = off; y < 16*16; y += 16) {
231  for (x = off; x < 16*16; x += 16) {
232  draw_dc(dst + x + y*dst_linesize, dst_linesize, ((x+y)&16) ? color : -color, 16, 16);
233  color++;
234  }
235  }
236 }
237 
238 static void ring2_test(uint8_t *dst, int dst_linesize, int off)
239 {
240  int x, y;
241 
242  for (y = 0; y < 16*16; y++) {
243  for (x = 0; x < 16*16; x++) {
244  double d = sqrt((x-8*16)*(x-8*16) + (y-8*16)*(y-8*16));
245  double r = d/20 - (int)(d/20);
246  if (r < off/30.0) {
247  dst[x + y*dst_linesize] = 255;
248  dst[x + y*dst_linesize+256] = 0;
249  } else {
250  dst[x + y*dst_linesize] = x;
251  dst[x + y*dst_linesize+256] = x;
252  }
253  }
254  }
255 }
256 
257 static av_cold int init(AVFilterContext *ctx)
258 {
259  MPTestContext *test = ctx->priv;
260 
261  test->max_pts = test->duration >= 0 ?
263  test->frame_nb = 0;
264  test->pts = 0;
265 
266  av_log(ctx, AV_LOG_VERBOSE, "rate:%d/%d duration:%f\n",
267  test->frame_rate.num, test->frame_rate.den,
268  test->duration < 0 ? -1 : test->max_pts * av_q2d(av_inv_q(test->frame_rate)));
269  init_idct();
270 
271  return 0;
272 }
273 
274 static int config_props(AVFilterLink *outlink)
275 {
276  AVFilterContext *ctx = outlink->src;
277  MPTestContext *test = ctx->priv;
278  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(outlink->format);
279 
280  test->hsub = pix_desc->log2_chroma_w;
281  test->vsub = pix_desc->log2_chroma_h;
282 
283  outlink->w = WIDTH;
284  outlink->h = HEIGHT;
285  outlink->time_base = av_inv_q(test->frame_rate);
286 
287  return 0;
288 }
289 
291 {
292  static const enum AVPixelFormat pix_fmts[] = {
294  };
295 
297  return 0;
298 }
299 
300 static int request_frame(AVFilterLink *outlink)
301 {
302  MPTestContext *test = outlink->src->priv;
303  AVFrame *picref;
304  int w = WIDTH, h = HEIGHT, cw = w>>test->hsub, ch = h>>test->vsub;
305  unsigned int frame = test->frame_nb;
306  enum test_type tt = test->test;
307  int i;
308 
309  if (test->max_pts >= 0 && test->pts > test->max_pts)
310  return AVERROR_EOF;
311  picref = ff_get_video_buffer(outlink, w, h);
312  if (!picref)
313  return AVERROR(ENOMEM);
314  picref->pts = test->pts++;
315 
316  // clean image
317  for (i = 0; i < h; i++)
318  memset(picref->data[0] + i*picref->linesize[0], 0, w);
319  for (i = 0; i < ch; i++) {
320  memset(picref->data[1] + i*picref->linesize[1], 128, cw);
321  memset(picref->data[2] + i*picref->linesize[2], 128, cw);
322  }
323 
324  if (tt == TEST_ALL && frame%30) /* draw a black frame at the beginning of each test */
325  tt = (frame/30)%(TEST_NB-1);
326 
327  switch (tt) {
328  case TEST_DC_LUMA: dc_test(picref->data[0], picref->linesize[0], 256, 256, frame%30); break;
329  case TEST_DC_CHROMA: dc_test(picref->data[1], picref->linesize[1], 256, 256, frame%30); break;
330  case TEST_FREQ_LUMA: freq_test(picref->data[0], picref->linesize[0], frame%30); break;
331  case TEST_FREQ_CHROMA: freq_test(picref->data[1], picref->linesize[1], frame%30); break;
332  case TEST_AMP_LUMA: amp_test(picref->data[0], picref->linesize[0], frame%30); break;
333  case TEST_AMP_CHROMA: amp_test(picref->data[1], picref->linesize[1], frame%30); break;
334  case TEST_CBP: cbp_test(picref->data , picref->linesize , frame%30); break;
335  case TEST_MV: mv_test(picref->data[0], picref->linesize[0], frame%30); break;
336  case TEST_RING1: ring1_test(picref->data[0], picref->linesize[0], frame%30); break;
337  case TEST_RING2: ring2_test(picref->data[0], picref->linesize[0], frame%30); break;
338  }
339 
340  test->frame_nb++;
341  return ff_filter_frame(outlink, picref);
342 }
343 
344 static const AVFilterPad mptestsrc_outputs[] = {
345  {
346  .name = "default",
347  .type = AVMEDIA_TYPE_VIDEO,
348  .request_frame = request_frame,
349  .config_props = config_props,
350  },
351  { NULL }
352 };
353 
355  .name = "mptestsrc",
356  .description = NULL_IF_CONFIG_SMALL("Generate various test pattern."),
357  .priv_size = sizeof(MPTestContext),
358  .init = init,
359 
361 
362  .inputs = NULL,
363  .outputs = mptestsrc_outputs,
364  .priv_class = &mptestsrc_class,
365 };
const char * s
Definition: avisynth_c.h:668
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1778
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
AVOption.
Definition: opt.h:251
#define HEIGHT
static int config_props(AVFilterLink *outlink)
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:117
external API header
static void init_idct(void)
int num
numerator
Definition: rational.h:44
static av_cold int init(AVFilterContext *ctx)
AVFilter avfilter_vsrc_mptestsrc
static int request_frame(AVFilterLink *outlink)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:143
static void dc_test(uint8_t *dst, int dst_linesize, int w, int h, int off)
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:66
output residual component w
Definition: test.py:1
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:308
set threshold d
struct MPTestContext MPTestContext
const char * name
Pad name.
static void cbp_test(uint8_t *dst[3], int dst_linesize[3], int off)
uint8_t
it can be given away to ff_start_frame *A reference passed to ff_filter_frame(or the deprecated ff_start_frame) is given away and must no longer be used.*A reference created with avfilter_ref_buffer belongs to the code that created it.*A reference obtained with ff_get_video_buffer or ff_get_audio_buffer belongs to the code that requested it.*A reference given as return value by the get_video_buffer or get_audio_buffer method is given away and must no longer be used.Link reference fields---------------------The AVFilterLink structure has a few AVFilterBufferRef fields.The cur_buf and out_buf were used with the deprecated start_frame/draw_slice/end_frame API and should no longer be used.src_buf
AVRational frame_rate
#define av_cold
Definition: attributes.h:78
AVOptions.
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:77
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:159
static double av_q2d(AVRational a)
Convert rational to double.
Definition: rational.h:69
#define AVERROR_EOF
End of file.
Definition: error.h:55
integer sqrt
Definition: avutil.txt:2
void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:545
frame
Definition: stft.m:14
A filter pad used for either input or output.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:130
Discrete Time axis x
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:75
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
const char * r
Definition: vf_curves.c:94
void * priv
private data for use by the filter
Definition: avfilter.h:545
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
AVFILTER_DEFINE_CLASS(mptestsrc)
#define FFMAX(a, b)
Definition: common.h:56
enum test_type test
#define AV_LOG_VERBOSE
Definition: log.h:157
static void ring2_test(uint8_t *dst, int dst_linesize, int off)
static const AVFilterPad mptestsrc_outputs[]
for k
NULL
Definition: eval.c:55
static void mv_test(uint8_t *dst, int dst_linesize, int off)
AVS_Value src
Definition: avisynth_c.h:523
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:202
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
static int query_formats(AVFilterContext *ctx)
#define OFFSET(x)
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:55
FIXME Range Coding of cr are mx and my are Motion Vector top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff)*mv_scale Intra DC Predicton block[y][x] dc[1]
Definition: snow.txt:392
test_type
Describe the class of an AVClass context structure.
Definition: log.h:50
Filter definition.
Definition: avfilter.h:436
int64_t duration
synthesis window for stochastic i
rational number numerator/denominator
Definition: rational.h:43
offset must point to AVRational
Definition: opt.h:233
const char * name
filter name
Definition: avfilter.h:437
static void amp_test(uint8_t *dst, int dst_linesize, int off)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
misc parsing utilities
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:122
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
static void draw_basis(uint8_t *dst, int dst_linesize, int amp, int freq, int dc)
unsigned int frame_nb
#define FLAGS
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:68
static double c[64]
int den
denominator
Definition: rational.h:45
function y
Definition: D.m:1
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
static void draw_dc(uint8_t *dst, int dst_linesize, int color, int w, int h)
#define WIDTH
An instance of a filter.
Definition: avfilter.h:524
static void ring1_test(uint8_t *dst, int dst_linesize, int off)
static const AVOption mptestsrc_options[]
static void idct(uint8_t *dst, int dst_linesize, int src[64])
#define M_PI
Definition: mathematics.h:46
static void draw_cbp(uint8_t *dst[3], int dst_linesize[3], int cbp, int amp, int dc)
internal API functions
static void freq_test(uint8_t *dst, int dst_linesize, int off)
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step