FFmpeg
stripetest.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2025 Michael Niedermayer
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 "libavutil/frame.h"
22 #include "libavutil/adler32.h"
24 
25 typedef const uint8_t *cuint8;
26 
27 static void strips(AVFrame *frame, int mul)
28 {
29  for(int y=0; y<frame->height; y++) {
30  for(int x=0; x<frame->width; x++) {
31  if (y&1) {
32  frame->data[0][x + y*frame->linesize[0]] = x*x + y*mul;
33  } else {
34  frame->data[0][x + y*frame->linesize[0]] = (y-x)*(y-x);
35  }
36  }
37  }
38  for(int y=0; y<(frame->height+1)/2; y++) {
39  for(int x=0; x<(frame->width+1)/2; x++) {
40  if (y&1) {
41  frame->data[1][x + y*frame->linesize[1]] = x + y + mul;
42  frame->data[2][x + y*frame->linesize[2]] = mul*x - y*x;
43  } else {
44  frame->data[1][x + y*frame->linesize[1]] = (x - y)/(mul+1);
45  frame->data[2][x + y*frame->linesize[2]] = (y + x)/(mul+1);
46  }
47  }
48  }
49 }
50 
52 {
53  AVAdler a = 123;
54 
55  for(int y=0; y<f->height; y++) {
56  a = av_adler32_update(a, &f->data[0][y*f->linesize[0]], f->width);
57  }
58  for(int y=0; y<(f->height+1)/2; y++) {
59  a = av_adler32_update(a, &f->data[1][y*f->linesize[1]], (f->width+1)/2);
60  a = av_adler32_update(a, &f->data[2][y*f->linesize[2]], (f->width+1)/2);
61  }
62 
63  return a;
64 }
65 
66 static int64_t test(int width, int height, const char *testname, int mul, int flags, int pict_type, int quality) {
67  AVFrame *in = av_frame_alloc();
71  int64_t ret;
72 
73  if (!in || !out || !context || !mode) {
74  ret = AVERROR(ENOMEM);
75  goto end;
76  }
77 
78  in-> width = out->width = width;
79  in->height = out->height = height;
80  in->format = out->format = AV_PIX_FMT_YUV420P;
81 
82  ret = av_frame_get_buffer(in, 0);
83  if (ret < 0)
84  goto end;
85 
87  if (ret < 0)
88  goto end;
89 
90  strips(in, mul);
91 
92  pp_postprocess( (cuint8[]){in->data[0], in->data[1], in->data[2]}, in->linesize,
93  out->data, out->linesize,
94  width, height, NULL, 0,
95  mode, context, pict_type);
96 
97  ret = chksum(out);
98 end:
99  av_frame_free(&in);
100  av_frame_free(&out);
103 
104  return ret;
105 }
106 
107 int main(int argc, char **argv) {
108  const char *teststrings[] = {
109  "be,lb",
110  "be,li",
111  "be,ci",
112  "be,md",
113  "be,fd",
114  "be,l5",
115  };
116 
117  for (int w=8; w< 352; w=w*3-1) {
118  for (int h=8; h< 352; h=h*5-7) {
119  for (int b=0; b<6; b++) {
120  for (int m=0; m<17; m = 2*m+1) {
121  int64_t ret = test(352, 288, teststrings[b], m, PP_FORMAT_420, 0, 11);
122  printf("striptest %dx%d T:%s m:%d result %"PRIX64"\n", w, h, teststrings[b], m, ret);
123  }
124  }
125  }
126  }
127 
128  return 0;
129 }
flags
const SwsFlags flags[]
Definition: swscale.c:61
pp_get_mode_by_name_and_quality
pp_mode * pp_get_mode_by_name_and_quality(const char *name, int quality)
Return a pp_mode or NULL if an error occurred.
Definition: postprocess.c:595
PP_FORMAT_420
#define PP_FORMAT_420
Definition: postprocess.h:97
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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. Frame references ownership and permissions
out
FILE * out
Definition: movenc.c:55
av_frame_get_buffer
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:205
int64_t
long long int64_t
Definition: coverity.c:34
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:63
mode
Definition: swscale.c:56
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:410
w
uint8_t w
Definition: llviddspenc.c:38
b
#define b
Definition: input.c:42
quality
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about quality
Definition: rate_distortion.txt:12
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:431
strips
static void strips(AVFrame *frame, int mul)
Definition: stripetest.c:27
chksum
static int64_t chksum(AVFrame *f)
Definition: stripetest.c:51
pp_free_context
av_cold void pp_free_context(void *vc)
Definition: postprocess.c:863
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:51
pp_free_mode
void pp_free_mode(pp_mode *mode)
Definition: postprocess.c:791
postprocess.h
pp_postprocess
void pp_postprocess(const uint8_t *src[3], const int srcStride[3], uint8_t *dst[3], const int dstStride[3], int width, int height, const int8_t *QP_store, int QPStride, pp_mode *vm, void *vc, int pict_type)
Definition: postprocess.c:886
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
pp_get_context
av_cold pp_context * pp_get_context(int width, int height, int cpuCaps)
Definition: postprocess.c:833
context
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 default minimum maximum flags name is the option keep it simple and lowercase description are in without and describe what they for example set the foo of the bar offset is the offset of the field in your context
Definition: writing_filters.txt:91
NULL
#define NULL
Definition: coverity.c:32
adler32.h
av_adler32_update
AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf, size_t len)
Calculate the Adler32 checksum of a buffer.
Definition: adler32.c:44
f
f
Definition: af_crystalizer.c:122
height
#define height
Definition: dsp.h:85
test
static int64_t test(int width, int height, const char *testname, int mul, int flags, int pict_type, int quality)
Definition: stripetest.c:66
pp_mode
void pp_mode
Definition: postprocess.h:65
printf
printf("static const uint8_t my_array[100] = {\n")
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:497
frame.h
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
main
int main(int argc, char **argv)
Definition: stripetest.c:107
ret
ret
Definition: filter_design.txt:187
frame
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 the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
AVAdler
uint32_t AVAdler
Definition: adler32.h:42
AVFrame::height
int height
Definition: frame.h:482
mode
mode
Definition: ebur128.h:83
cuint8
const typedef uint8_t * cuint8
Definition: stripetest.c:25
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:455
h
h
Definition: vp9dsp_template.c:2070
width
#define width
Definition: dsp.h:85
pp_context
void pp_context
Definition: postprocess.h:64