avcodec/pnm: Avoid structure pointer dereferences in inner loop in pnm_get()
[ffmpeg.git] / libavcodec / tests / options.c
1 /*
2  * Copyright (c) 2001 Fabrice Bellard
3  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "libavcodec/options.c"
23
24 static int dummy_init(AVCodecContext *ctx)
25 {
26     //TODO: this code should set every possible pointer that could be set by codec and is not an option;
27     ctx->extradata_size = 8;
28     ctx->extradata = av_malloc(ctx->extradata_size);
29     return 0;
30 }
31
32 static int dummy_close(AVCodecContext *ctx)
33 {
34     av_freep(&ctx->extradata);
35     ctx->extradata_size = 0;
36     return 0;
37 }
38
39 static int dummy_encode(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
40 {
41     return AVERROR(ENOSYS);
42 }
43
44 typedef struct Dummy12Context {
45     AVClass  *av_class;
46     int      num;
47     char*    str;
48 } Dummy12Context;
49
50 typedef struct Dummy3Context {
51     void     *fake_av_class;
52     int      num;
53     char*    str;
54 } Dummy3Context;
55
56 #define OFFSET(x) offsetof(Dummy12Context, x)
57 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
58 static const AVOption dummy_options[] = {
59     { "str", "set str", OFFSET(str), AV_OPT_TYPE_STRING, { .str = "i'm src default value" }, 0, 0, VE},
60     { "num", "set num", OFFSET(num), AV_OPT_TYPE_INT,    { .i64 = 1500100900 },    0, INT_MAX, VE},
61     { NULL },
62 };
63
64 static const AVClass dummy_v1_class = {
65     .class_name = "dummy_v1_class",
66     .item_name  = av_default_item_name,
67     .option     = dummy_options,
68     .version    = LIBAVUTIL_VERSION_INT,
69 };
70
71 static const AVClass dummy_v2_class = {
72     .class_name = "dummy_v2_class",
73     .item_name  = av_default_item_name,
74     .option     = dummy_options,
75     .version    = LIBAVUTIL_VERSION_INT,
76 };
77
78 /* codec with options */
79 static AVCodec dummy_v1_encoder = {
80     .name             = "dummy_v1_codec",
81     .type             = AVMEDIA_TYPE_VIDEO,
82     .id               = AV_CODEC_ID_NONE - 1,
83     .encode2          = dummy_encode,
84     .init             = dummy_init,
85     .close            = dummy_close,
86     .priv_class       = &dummy_v1_class,
87     .priv_data_size   = sizeof(Dummy12Context),
88 };
89
90 /* codec with options, different class */
91 static AVCodec dummy_v2_encoder = {
92     .name             = "dummy_v2_codec",
93     .type             = AVMEDIA_TYPE_VIDEO,
94     .id               = AV_CODEC_ID_NONE - 2,
95     .encode2          = dummy_encode,
96     .init             = dummy_init,
97     .close            = dummy_close,
98     .priv_class       = &dummy_v2_class,
99     .priv_data_size   = sizeof(Dummy12Context),
100 };
101
102 /* codec with priv data, but no class */
103 static AVCodec dummy_v3_encoder = {
104     .name             = "dummy_v3_codec",
105     .type             = AVMEDIA_TYPE_VIDEO,
106     .id               = AV_CODEC_ID_NONE - 3,
107     .encode2          = dummy_encode,
108     .init             = dummy_init,
109     .close            = dummy_close,
110     .priv_data_size   = sizeof(Dummy3Context),
111 };
112
113 /* codec without priv data */
114 static AVCodec dummy_v4_encoder = {
115     .name             = "dummy_v4_codec",
116     .type             = AVMEDIA_TYPE_VIDEO,
117     .id               = AV_CODEC_ID_NONE - 4,
118     .encode2          = dummy_encode,
119     .init             = dummy_init,
120     .close            = dummy_close,
121 };
122
123 static void test_copy_print_codec(const AVCodecContext *ctx)
124 {
125     printf("%-14s: %dx%d prv: %s",
126            ctx->codec ? ctx->codec->name : "NULL",
127            ctx->width, ctx->height,
128            ctx->priv_data ? "set" : "null");
129     if (ctx->codec && ctx->codec->priv_class && ctx->codec->priv_data_size) {
130         int64_t i64;
131         char *str = NULL;
132         av_opt_get_int(ctx->priv_data, "num", 0, &i64);
133         av_opt_get(ctx->priv_data, "str", 0, (uint8_t**)&str);
134         printf(" opts: %"PRId64" %s", i64, str);
135         av_free(str);
136     }
137     printf("\n");
138 }
139
140 static void test_copy(const AVCodec *c1, const AVCodec *c2)
141 {
142     AVCodecContext *ctx1, *ctx2;
143     printf("%s -> %s\nclosed:\n", c1 ? c1->name : "NULL", c2 ? c2->name : "NULL");
144     ctx1 = avcodec_alloc_context3(c1);
145     ctx2 = avcodec_alloc_context3(c2);
146     ctx1->width = ctx1->height = 128;
147     ctx1->time_base = (AVRational){12,34};
148     if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
149         av_opt_set(ctx2->priv_data, "num", "667", 0);
150         av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
151     }
152     avcodec_copy_context(ctx2, ctx1);
153     test_copy_print_codec(ctx1);
154     test_copy_print_codec(ctx2);
155     if (ctx1->codec) {
156         int ret;
157         printf("opened:\n");
158         ret = avcodec_open2(ctx1, ctx1->codec, NULL);
159         if (ret < 0) {
160             fprintf(stderr, "avcodec_open2 failed\n");
161             exit(1);
162         }
163         if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
164             av_opt_set(ctx2->priv_data, "num", "667", 0);
165             av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
166         }
167         avcodec_copy_context(ctx2, ctx1);
168         test_copy_print_codec(ctx1);
169         test_copy_print_codec(ctx2);
170         avcodec_close(ctx1);
171     }
172     avcodec_free_context(&ctx1);
173     avcodec_free_context(&ctx2);
174 }
175
176 int main(void)
177 {
178     AVCodec *dummy_codec[] = {
179         &dummy_v1_encoder,
180         &dummy_v2_encoder,
181         &dummy_v3_encoder,
182         &dummy_v4_encoder,
183         NULL,
184     };
185     int i, j;
186
187     for (i = 0; dummy_codec[i]; i++)
188         avcodec_register(dummy_codec[i]);
189
190     printf("testing avcodec_copy_context()\n");
191     for (i = 0; i < FF_ARRAY_ELEMS(dummy_codec); i++)
192         for (j = 0; j < FF_ARRAY_ELEMS(dummy_codec); j++)
193             test_copy(dummy_codec[i], dummy_codec[j]);
194     return 0;
195 }