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 37static 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 46static 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 54static 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 70static 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 77static 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 89int 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 143AVCodecContext *avcodec_alloc_context3(const AVCodec *codec) 144{ 145 AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); 146 147 if(avctx==NULL) return NULL; 148 149 if(avcodec_get_context_defaults3(avctx, codec) < 0){ 150 av_free(avctx); 151 return NULL; 152 } 153 154 return avctx; 155} 156 157void avcodec_free_context(AVCodecContext **pavctx) 158{ 159 AVCodecContext *avctx = *pavctx; 160 161 if (!avctx) 162 return; 163 164 avcodec_close(avctx); 165 166 av_freep(&avctx->extradata); 167 av_freep(&avctx->subtitle_header); 168 169 av_freep(pavctx); 170} 171 172int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) 173{ 174 const AVCodec *orig_codec = dest->codec; 175 uint8_t *orig_priv_data = dest->priv_data; 176 177 if (avcodec_is_open(dest)) { // check that the dest context is uninitialized 178 av_log(dest, AV_LOG_ERROR, 179 "Tried to copy AVCodecContext %p into already-initialized %p\n", 180 src, dest); 181 return AVERROR(EINVAL); 182 } 183 184 av_opt_free(dest); 185 186 memcpy(dest, src, sizeof(*dest)); 187 188 dest->priv_data = orig_priv_data; 189 190 if (orig_priv_data) 191 av_opt_copy(orig_priv_data, src->priv_data); 192 193 dest->codec = orig_codec; 194 195 /* set values specific to opened codecs back to their default state */ 196 dest->slice_offset = NULL; 197 dest->hwaccel = NULL; 198 dest->internal = NULL; 199 200 /* reallocate values that should be allocated separately */ 201 dest->rc_eq = NULL; 202 dest->extradata = NULL; 203 dest->intra_matrix = NULL; 204 dest->inter_matrix = NULL; 205 dest->rc_override = NULL; 206 dest->subtitle_header = NULL; 207 if (src->rc_eq) { 208 dest->rc_eq = av_strdup(src->rc_eq); 209 if (!dest->rc_eq) 210 return AVERROR(ENOMEM); 211 } 212 213#define alloc_and_copy_or_fail(obj, size, pad) \ 214 if (src->obj && size > 0) { \ 215 dest->obj = av_malloc(size + pad); \ 216 if (!dest->obj) \ 217 goto fail; \ 218 memcpy(dest->obj, src->obj, size); \ 219 if (pad) \ 220 memset(((uint8_t *) dest->obj) + size, 0, pad); \ 221 } 222 alloc_and_copy_or_fail(extradata, src->extradata_size, 223 FF_INPUT_BUFFER_PADDING_SIZE); 224 alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0); 225 alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0); 226 alloc_and_copy_or_fail(rc_override, src->rc_override_count * sizeof(*src->rc_override), 0); 227 alloc_and_copy_or_fail(subtitle_header, src->subtitle_header_size, 1); 228 av_assert0(dest->subtitle_header_size == src->subtitle_header_size); 229#undef alloc_and_copy_or_fail 230 231 return 0; 232 233fail: 234 av_freep(&dest->rc_override); 235 av_freep(&dest->intra_matrix); 236 av_freep(&dest->inter_matrix); 237 av_freep(&dest->extradata); 238 av_freep(&dest->rc_eq); 239 return AVERROR(ENOMEM); 240} 241 242const AVClass *avcodec_get_class(void) 243{ 244 return &av_codec_context_class; 245} 246 247#define FOFFSET(x) offsetof(AVFrame,x) 248 249static const AVOption frame_options[]={ 250{"best_effort_timestamp", "", FOFFSET(best_effort_timestamp), AV_OPT_TYPE_INT64, {.i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, 0}, 251{"pkt_pos", "", FOFFSET(pkt_pos), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0}, 252{"pkt_size", "", FOFFSET(pkt_size), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0}, 253{"sample_aspect_ratio", "", FOFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0}, 254{"width", "", FOFFSET(width), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, 255{"height", "", FOFFSET(height), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, 256{"format", "", FOFFSET(format), AV_OPT_TYPE_INT, {.i64 = -1 }, 0, INT_MAX, 0}, 257{"channel_layout", "", FOFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, 0}, 258{"sample_rate", "", FOFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, 259{NULL}, 260}; 261 262static const AVClass av_frame_class = { 263 .class_name = "AVFrame", 264 .item_name = NULL, 265 .option = frame_options, 266 .version = LIBAVUTIL_VERSION_INT, 267}; 268 269const AVClass *avcodec_get_frame_class(void) 270{ 271 return &av_frame_class; 272} 273 274#define SROFFSET(x) offsetof(AVSubtitleRect,x) 275 276static const AVOption subtitle_rect_options[]={ 277{"x", "", SROFFSET(x), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, 278{"y", "", SROFFSET(y), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, 279{"w", "", SROFFSET(w), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, 280{"h", "", SROFFSET(h), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, 281{"type", "", SROFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0}, 282{"flags", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0, "flags"}, 283{"forced", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0}, 284{NULL}, 285}; 286 287static const AVClass av_subtitle_rect_class = { 288 .class_name = "AVSubtitleRect", 289 .item_name = NULL, 290 .option = subtitle_rect_options, 291 .version = LIBAVUTIL_VERSION_INT, 292}; 293 294const AVClass *avcodec_get_subtitle_rect_class(void) 295{ 296 return &av_subtitle_rect_class; 297} 298