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