# HG changeset patch # User rbultje # Date 1270068049 0 # Node ID 2baae9246958176f5c9479dbdd8500aa67618e4b # Parent a9780299ef4856c285746cdce64e31deb364b19c Add avcodec_copy_context(). diff -r a9780299ef48 -r 2baae9246958 avcodec.h --- a/avcodec.h Wed Mar 31 14:13:49 2010 +0000 +++ b/avcodec.h Wed Mar 31 20:40:49 2010 +0000 @@ -3259,6 +3259,19 @@ AVCodecContext *avcodec_alloc_context2(enum AVMediaType); /** + * Copy the settings of the source AVCodecContext into the destination + * AVCodecContext. The resulting destination codec context will be + * unopened, i.e. you are required to call avcodec_open() before you + * can use this AVCodecContext to decode/encode video/audio data. + * + * @param dest target codec context, should be initialized with + * avcodec_alloc_context(), but otherwise uninitialized + * @param src source codec context + * @return AVERROR() on error (e.g. memory allocation error), 0 on success + */ +int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); + +/** * Sets the fields of the given AVFrame to default values. * * @param pic The AVFrame of which the fields should be set to default values. diff -r a9780299ef48 -r 2baae9246958 options.c --- a/options.c Wed Mar 31 14:13:49 2010 +0000 +++ b/options.c Wed Mar 31 20:40:49 2010 +0000 @@ -471,3 +471,63 @@ return avcodec_alloc_context2(AVMEDIA_TYPE_UNKNOWN); } +int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) +{ + if (dest->codec) { // check that the dest context is uninitialized + av_log(dest, AV_LOG_ERROR, + "Tried to copy AVCodecContext %p into already-initialized %p\n", + src, dest); + return AVERROR(EINVAL); + } + memcpy(dest, src, sizeof(*dest)); + + /* set values specific to opened codecs back to their default state */ + dest->priv_data = NULL; + dest->codec = NULL; + dest->palctrl = NULL; + dest->slice_offset = NULL; + dest->internal_buffer = NULL; + dest->hwaccel = NULL; + dest->execute = NULL; + dest->execute2 = NULL; + dest->reget_buffer = NULL; + dest->thread_opaque = NULL; + + /* reallocate values that should be allocated separately */ + dest->rc_eq = NULL; + dest->extradata = NULL; + dest->intra_matrix = NULL; + dest->inter_matrix = NULL; + dest->rc_override = NULL; + if (src->rc_eq) { + dest->rc_eq = av_strdup(src->rc_eq); + if (!dest->rc_eq) + return AVERROR(ENOMEM); + } + +#define alloc_and_copy_or_fail(obj, size, pad) \ + if (src->obj && size > 0) { \ + dest->obj = av_malloc(size + pad); \ + if (!dest->obj) \ + goto fail; \ + memcpy(dest->obj, src->obj, size); \ + if (pad) \ + memset(((uint8_t *) dest->obj) + size, 0, pad); \ + } + alloc_and_copy_or_fail(extradata, src->extradata_size, + FF_INPUT_BUFFER_PADDING_SIZE); + alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0); + alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0); + alloc_and_copy_or_fail(rc_override, src->rc_override_count * sizeof(*src->rc_override), 0); +#undef alloc_and_copy_or_fail + + return 0; + +fail: + av_freep(&dest->rc_override); + av_freep(&dest->intra_matrix); + av_freep(&dest->inter_matrix); + av_freep(&dest->extradata); + av_freep(&dest->rc_eq); + return AVERROR(ENOMEM); +}