Ticket #1851: swscale.c

File swscale.c, 3.1 KB (added by gjdfgh, 4 years ago)

Test program

Line 
1// gcc swscale.c -W -Wall -std=c99 -lavutil -lswscale
2
3#include <inttypes.h>
4#include <stdbool.h>
5#include <stdio.h>
6#include <string.h>
7#include <assert.h>
8#include <libswscale/swscale.h>
9#include <libavutil/opt.h>
10#include <libavutil/pixfmt.h>
11
12#define W 128
13#define H 128
14#define STRIDE_YUV W
15#define STRIDE_RGBA (W * 4)
16
17void scale(uint8_t *dst[3], uint8_t *src[3], int s_yuv, int s_range,
18           int d_yuv, int d_range, int scale)
19{
20    struct SwsContext *sws = sws_alloc_context();
21
22    int exact = SWS_FULL_CHR_H_INT | SWS_FULL_CHR_H_INP |
23                SWS_ACCURATE_RND | SWS_BITEXACT;
24    av_opt_set_int(sws, "sws_flags", exact | SWS_POINT /* | SWS_PRINT_INFO*/, 0);
25
26    av_opt_set_int(sws, "srcw", W, 0);
27    av_opt_set_int(sws, "srch", H, 0);
28    av_opt_set_int(sws, "src_format", s_yuv ? PIX_FMT_YUV444P : PIX_FMT_RGBA, 0);
29
30    av_opt_set_int(sws, "dstw", scale ? W/2 : W, 0);
31    av_opt_set_int(sws, "dsth", scale ? H/2 : H, 0);
32    av_opt_set_int(sws, "dst_format", d_yuv ? PIX_FMT_YUV444P : PIX_FMT_RGBA, 0);
33
34    // needed? maybe not
35    //av_opt_set_int(sws, "src_range", !!s_range, 0);
36    //av_opt_set_int(sws, "dst_range", !!d_range, 0);
37
38    sws_setColorspaceDetails(sws, sws_getCoefficients(SWS_CS_ITU709), !!s_range,
39                             sws_getCoefficients(SWS_CS_ITU709), !!d_range,
40                             0, 1 << 16, 1 << 16);
41
42    int res = sws_init_context(sws, NULL, NULL);
43    assert(res >= 0);
44
45    int s_stride = s_yuv ? STRIDE_YUV : STRIDE_RGBA;
46    int d_stride = d_yuv ? STRIDE_YUV : STRIDE_RGBA;
47    int s_stride_a[3] = {s_stride, s_stride, s_stride};
48    int d_stride_a[3] = {d_stride, d_stride, d_stride};
49    sws_scale(sws, (const unsigned char *const *)src, s_stride_a, 0, H, dst, d_stride_a);
50    sws_freeContext(sws);
51}
52
53void set_white(uint8_t *c[3], bool yuv, int val)
54{
55    if (yuv) {
56        memset(c[0], val, STRIDE_YUV * H);
57        memset(c[1], 128, STRIDE_YUV * H);
58        memset(c[2], 128, STRIDE_YUV * H);
59    } else {
60        memset(c[0], val, STRIDE_RGBA * H);
61    }
62}
63
64int get_white(uint8_t *c[3], bool yuv)
65{
66    if (yuv) {
67        return c[0][W/4 + STRIDE_YUV * (H/4)];
68    } else {
69        return c[0][W/4 * 4 + STRIDE_RGBA * (H/4) + 1];
70    }
71}
72
73uint8_t *a[3], *b[3];
74
75void test(unsigned int mode)
76{
77    bool d_range = mode & 1;
78    bool d_yuv = mode & 2;
79    bool s_range = mode & 4;
80    bool s_yuv = mode & 8;
81    bool doscale = mode & 16;
82    bool lower = mode & 32;
83    int ival = lower ? 255 : 200;
84    set_white(a, s_yuv, ival);
85    scale(b, a, s_yuv, s_range, d_yuv, d_range, doscale);
86    int oval = get_white(b, d_yuv);
87    printf("%-9s", doscale ? "scale" : "no-scale");
88    printf("%s", s_yuv ? "yuv" : "rgb");
89    printf("-%s ", s_range ? "ful" : "lim");
90    printf("%s", d_yuv ? "yuv" : "rgb");
91    printf("-%s ", d_range ? "ful" : "lim");
92    printf(" %d -> %d\n", ival, oval);
93}
94
95int main(int argc, char **argv)
96{
97    for (int i = 0; i < 3; i++) {
98        a[i] = av_malloc(STRIDE_RGBA * H);
99        b[i] = av_malloc(STRIDE_RGBA * H);
100    }
101    for (int i = 0; i < 64; i++) {
102        test(i);
103        if (i % 16 == 15)
104            printf("\n");
105    }
106}