Commit | Line | Data |
---|---|---|
2ba45a60 DM |
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 | /** | |
23 | * @file | |
24 | * Options definition for AVCodecContext. | |
25 | */ | |
26 | ||
27 | #include "avcodec.h" | |
28 | #include "internal.h" | |
29 | #include "libavutil/avassert.h" | |
f6fa7814 | 30 | #include "libavutil/internal.h" |
2ba45a60 DM |
31 | #include "libavutil/mem.h" |
32 | #include "libavutil/opt.h" | |
33 | #include <float.h> /* FLT_MIN, FLT_MAX */ | |
34 | #include <string.h> | |
35 | ||
36 | #include "options_table.h" | |
37 | ||
38 | static const char* context_to_name(void* ptr) { | |
39 | AVCodecContext *avc= ptr; | |
40 | ||
41 | if(avc && avc->codec && avc->codec->name) | |
42 | return avc->codec->name; | |
43 | else | |
44 | return "NULL"; | |
45 | } | |
46 | ||
47 | static void *codec_child_next(void *obj, void *prev) | |
48 | { | |
49 | AVCodecContext *s = obj; | |
50 | if (!prev && s->codec && s->codec->priv_class && s->priv_data) | |
51 | return s->priv_data; | |
52 | return NULL; | |
53 | } | |
54 | ||
55 | static const AVClass *codec_child_class_next(const AVClass *prev) | |
56 | { | |
57 | AVCodec *c = NULL; | |
58 | ||
59 | /* find the codec that corresponds to prev */ | |
60 | while (prev && (c = av_codec_next(c))) | |
61 | if (c->priv_class == prev) | |
62 | break; | |
63 | ||
64 | /* find next codec with priv options */ | |
65 | while (c = av_codec_next(c)) | |
66 | if (c->priv_class) | |
67 | return c->priv_class; | |
68 | return NULL; | |
69 | } | |
70 | ||
71 | static AVClassCategory get_category(void *ptr) | |
72 | { | |
73 | AVCodecContext* avctx = ptr; | |
74 | if(avctx->codec && avctx->codec->decode) return AV_CLASS_CATEGORY_DECODER; | |
75 | else return AV_CLASS_CATEGORY_ENCODER; | |
76 | } | |
77 | ||
78 | static const AVClass av_codec_context_class = { | |
79 | .class_name = "AVCodecContext", | |
80 | .item_name = context_to_name, | |
81 | .option = avcodec_options, | |
82 | .version = LIBAVUTIL_VERSION_INT, | |
83 | .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset), | |
84 | .child_next = codec_child_next, | |
85 | .child_class_next = codec_child_class_next, | |
86 | .category = AV_CLASS_CATEGORY_ENCODER, | |
87 | .get_category = get_category, | |
88 | }; | |
89 | ||
90 | int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) | |
91 | { | |
92 | int flags=0; | |
93 | memset(s, 0, sizeof(AVCodecContext)); | |
94 | ||
95 | s->av_class = &av_codec_context_class; | |
96 | ||
97 | s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN; | |
f6fa7814 DM |
98 | if (codec) { |
99 | s->codec = codec; | |
2ba45a60 | 100 | s->codec_id = codec->id; |
f6fa7814 | 101 | } |
2ba45a60 DM |
102 | |
103 | if(s->codec_type == AVMEDIA_TYPE_AUDIO) | |
104 | flags= AV_OPT_FLAG_AUDIO_PARAM; | |
105 | else if(s->codec_type == AVMEDIA_TYPE_VIDEO) | |
106 | flags= AV_OPT_FLAG_VIDEO_PARAM; | |
107 | else if(s->codec_type == AVMEDIA_TYPE_SUBTITLE) | |
108 | flags= AV_OPT_FLAG_SUBTITLE_PARAM; | |
109 | av_opt_set_defaults2(s, flags, flags); | |
110 | ||
111 | s->time_base = (AVRational){0,1}; | |
f6fa7814 DM |
112 | s->framerate = (AVRational){ 0, 1 }; |
113 | s->pkt_timebase = (AVRational){ 0, 1 }; | |
2ba45a60 DM |
114 | s->get_buffer2 = avcodec_default_get_buffer2; |
115 | s->get_format = avcodec_default_get_format; | |
116 | s->execute = avcodec_default_execute; | |
117 | s->execute2 = avcodec_default_execute2; | |
118 | s->sample_aspect_ratio = (AVRational){0,1}; | |
119 | s->pix_fmt = AV_PIX_FMT_NONE; | |
120 | s->sample_fmt = AV_SAMPLE_FMT_NONE; | |
2ba45a60 DM |
121 | |
122 | s->reordered_opaque = AV_NOPTS_VALUE; | |
123 | if(codec && codec->priv_data_size){ | |
124 | if(!s->priv_data){ | |
125 | s->priv_data= av_mallocz(codec->priv_data_size); | |
126 | if (!s->priv_data) { | |
127 | return AVERROR(ENOMEM); | |
128 | } | |
129 | } | |
130 | if(codec->priv_class){ | |
131 | *(const AVClass**)s->priv_data = codec->priv_class; | |
132 | av_opt_set_defaults(s->priv_data); | |
133 | } | |
134 | } | |
135 | if (codec && codec->defaults) { | |
136 | int ret; | |
137 | const AVCodecDefault *d = codec->defaults; | |
138 | while (d->key) { | |
139 | ret = av_opt_set(s, d->key, d->value, 0); | |
140 | av_assert0(ret >= 0); | |
141 | d++; | |
142 | } | |
143 | } | |
144 | return 0; | |
145 | } | |
146 | ||
147 | AVCodecContext *avcodec_alloc_context3(const AVCodec *codec) | |
148 | { | |
149 | AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); | |
150 | ||
151 | if (!avctx) | |
152 | return NULL; | |
153 | ||
154 | if(avcodec_get_context_defaults3(avctx, codec) < 0){ | |
155 | av_free(avctx); | |
156 | return NULL; | |
157 | } | |
158 | ||
159 | return avctx; | |
160 | } | |
161 | ||
162 | void avcodec_free_context(AVCodecContext **pavctx) | |
163 | { | |
164 | AVCodecContext *avctx = *pavctx; | |
165 | ||
166 | if (!avctx) | |
167 | return; | |
168 | ||
169 | avcodec_close(avctx); | |
170 | ||
171 | av_freep(&avctx->extradata); | |
172 | av_freep(&avctx->subtitle_header); | |
f6fa7814 DM |
173 | av_freep(&avctx->intra_matrix); |
174 | av_freep(&avctx->inter_matrix); | |
175 | av_freep(&avctx->rc_override); | |
2ba45a60 DM |
176 | |
177 | av_freep(pavctx); | |
178 | } | |
179 | ||
180 | int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) | |
181 | { | |
182 | const AVCodec *orig_codec = dest->codec; | |
183 | uint8_t *orig_priv_data = dest->priv_data; | |
184 | ||
185 | if (avcodec_is_open(dest)) { // check that the dest context is uninitialized | |
186 | av_log(dest, AV_LOG_ERROR, | |
187 | "Tried to copy AVCodecContext %p into already-initialized %p\n", | |
188 | src, dest); | |
189 | return AVERROR(EINVAL); | |
190 | } | |
191 | ||
192 | av_opt_free(dest); | |
193 | ||
194 | memcpy(dest, src, sizeof(*dest)); | |
f6fa7814 | 195 | av_opt_copy(dest, src); |
2ba45a60 DM |
196 | |
197 | dest->priv_data = orig_priv_data; | |
198 | ||
199 | if (orig_priv_data) | |
200 | av_opt_copy(orig_priv_data, src->priv_data); | |
201 | ||
202 | dest->codec = orig_codec; | |
203 | ||
204 | /* set values specific to opened codecs back to their default state */ | |
205 | dest->slice_offset = NULL; | |
206 | dest->hwaccel = NULL; | |
207 | dest->internal = NULL; | |
208 | ||
209 | /* reallocate values that should be allocated separately */ | |
2ba45a60 DM |
210 | dest->extradata = NULL; |
211 | dest->intra_matrix = NULL; | |
212 | dest->inter_matrix = NULL; | |
213 | dest->rc_override = NULL; | |
214 | dest->subtitle_header = NULL; | |
2ba45a60 DM |
215 | |
216 | #define alloc_and_copy_or_fail(obj, size, pad) \ | |
217 | if (src->obj && size > 0) { \ | |
218 | dest->obj = av_malloc(size + pad); \ | |
219 | if (!dest->obj) \ | |
220 | goto fail; \ | |
221 | memcpy(dest->obj, src->obj, size); \ | |
222 | if (pad) \ | |
223 | memset(((uint8_t *) dest->obj) + size, 0, pad); \ | |
224 | } | |
225 | alloc_and_copy_or_fail(extradata, src->extradata_size, | |
226 | FF_INPUT_BUFFER_PADDING_SIZE); | |
227 | alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0); | |
228 | alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0); | |
229 | alloc_and_copy_or_fail(rc_override, src->rc_override_count * sizeof(*src->rc_override), 0); | |
230 | alloc_and_copy_or_fail(subtitle_header, src->subtitle_header_size, 1); | |
231 | av_assert0(dest->subtitle_header_size == src->subtitle_header_size); | |
232 | #undef alloc_and_copy_or_fail | |
233 | ||
234 | return 0; | |
235 | ||
236 | fail: | |
237 | av_freep(&dest->rc_override); | |
238 | av_freep(&dest->intra_matrix); | |
239 | av_freep(&dest->inter_matrix); | |
240 | av_freep(&dest->extradata); | |
f6fa7814 DM |
241 | #if FF_API_MPV_OPT |
242 | FF_DISABLE_DEPRECATION_WARNINGS | |
2ba45a60 | 243 | av_freep(&dest->rc_eq); |
f6fa7814 DM |
244 | FF_ENABLE_DEPRECATION_WARNINGS |
245 | #endif | |
2ba45a60 DM |
246 | return AVERROR(ENOMEM); |
247 | } | |
248 | ||
249 | const AVClass *avcodec_get_class(void) | |
250 | { | |
251 | return &av_codec_context_class; | |
252 | } | |
253 | ||
254 | #define FOFFSET(x) offsetof(AVFrame,x) | |
255 | ||
256 | static const AVOption frame_options[]={ | |
257 | {"best_effort_timestamp", "", FOFFSET(best_effort_timestamp), AV_OPT_TYPE_INT64, {.i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, 0}, | |
258 | {"pkt_pos", "", FOFFSET(pkt_pos), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0}, | |
259 | {"pkt_size", "", FOFFSET(pkt_size), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0}, | |
260 | {"sample_aspect_ratio", "", FOFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0}, | |
261 | {"width", "", FOFFSET(width), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, | |
262 | {"height", "", FOFFSET(height), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, | |
263 | {"format", "", FOFFSET(format), AV_OPT_TYPE_INT, {.i64 = -1 }, 0, INT_MAX, 0}, | |
264 | {"channel_layout", "", FOFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, 0}, | |
265 | {"sample_rate", "", FOFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, | |
266 | {NULL}, | |
267 | }; | |
268 | ||
269 | static const AVClass av_frame_class = { | |
270 | .class_name = "AVFrame", | |
271 | .item_name = NULL, | |
272 | .option = frame_options, | |
273 | .version = LIBAVUTIL_VERSION_INT, | |
274 | }; | |
275 | ||
276 | const AVClass *avcodec_get_frame_class(void) | |
277 | { | |
278 | return &av_frame_class; | |
279 | } | |
280 | ||
281 | #define SROFFSET(x) offsetof(AVSubtitleRect,x) | |
282 | ||
283 | static const AVOption subtitle_rect_options[]={ | |
284 | {"x", "", SROFFSET(x), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, | |
285 | {"y", "", SROFFSET(y), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, | |
286 | {"w", "", SROFFSET(w), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, | |
287 | {"h", "", SROFFSET(h), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, | |
288 | {"type", "", SROFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, | |
289 | {"flags", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0, "flags"}, | |
290 | {"forced", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0}, | |
291 | {NULL}, | |
292 | }; | |
293 | ||
294 | static const AVClass av_subtitle_rect_class = { | |
295 | .class_name = "AVSubtitleRect", | |
296 | .item_name = NULL, | |
297 | .option = subtitle_rect_options, | |
298 | .version = LIBAVUTIL_VERSION_INT, | |
299 | }; | |
300 | ||
301 | const AVClass *avcodec_get_subtitle_rect_class(void) | |
302 | { | |
303 | return &av_subtitle_rect_class; | |
304 | } |