aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2010-03-31 20:40:49 +0000
committerRonald S. Bultje <rsbultje@gmail.com>2010-03-31 20:40:49 +0000
commitd103218046883cb9e7f6e83af53b0982fee370ba (patch)
tree3cef854c1f1a61160c817b945fc02d678d63a662
parente33f1fa0a91868d58670a6f0b71f80b6b8a4e7d5 (diff)
downloadffmpeg-d103218046883cb9e7f6e83af53b0982fee370ba.tar.gz
Add avcodec_copy_context().
Originally committed as revision 22750 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/avcodec.h13
-rw-r--r--libavcodec/options.c60
2 files changed, 73 insertions, 0 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 12d9b3d47c..251e47dbc6 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3259,6 +3259,19 @@ AVCodecContext *avcodec_alloc_context(void);
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 --git a/libavcodec/options.c b/libavcodec/options.c
index 89b25483c2..04fd3ba496 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -471,3 +471,63 @@ AVCodecContext *avcodec_alloc_context(void){
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);
+}