[FFmpeg-cvslog] avcodec: move some AVCodecContext fields to an internal struct.
Justin Ruggles
git at videolan.org
Sun Nov 20 03:03:19 CET 2011
ffmpeg | branch: master | Justin Ruggles <justin.ruggles at gmail.com> | Tue Nov 15 15:34:50 2011 -0500| [f3a29b750a5979ae6847879fba758faf1fae88d0] | committer: Justin Ruggles
avcodec: move some AVCodecContext fields to an internal struct.
A new field, AVCodecContext.internal is used to hold a new struct
AVCodecInternal, which has private fields that are not codec-specific and are
used by general libavcodec functions.
Moved internal_buffer, internal_buffer_count, and is_copy.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f3a29b750a5979ae6847879fba758faf1fae88d0
---
doc/APIchanges | 8 ++++
libavcodec/avcodec.h | 24 +++++++++++--
libavcodec/h264.c | 3 +-
libavcodec/internal.h | 34 ++++++++++++++++++
libavcodec/mimic.c | 4 ++-
libavcodec/mpegvideo.c | 2 +-
libavcodec/options.c | 2 +-
libavcodec/pthread.c | 16 ++++++--
libavcodec/utils.c | 88 ++++++++++++++++++++++++------------------------
libavcodec/version.h | 5 ++-
libavcodec/vp3.c | 4 ++-
libavcodec/vp8.c | 3 +-
12 files changed, 135 insertions(+), 58 deletions(-)
diff --git a/doc/APIchanges b/doc/APIchanges
index f1913bd..026e5ad 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,14 @@ libavutil: 2011-04-18
API changes, most recent first:
+2011-xx-xx - xxxxxxx - lavc 53.21.0
+ Move some AVCodecContext fields to a new private struct, AVCodecInternal,
+ which is accessed from a new field, AVCodecContext.internal.
+ - fields moved:
+ AVCodecContext.internal_buffer --> AVCodecInternal.buffer
+ AVCodecContext.internal_buffer_count --> AVCodecInternal.buffer_count
+ AVCodecContext.is_copy --> AVCodecInternal.is_copy
+
2011-11-13 - lavf 53.15.0
New interrupt callback API, allowing per-AVFormatContext/AVIOContext
interrupt callbacks.
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 7d506a1..67bbdf8 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1156,6 +1156,8 @@ typedef struct AVFrame {
void *thread_opaque;
} AVFrame;
+struct AVCodecInternal;
+
/**
* main external API structure.
* New fields can be added to the end with minor version bumps.
@@ -1979,17 +1981,21 @@ typedef struct AVCodecContext {
*/
int color_table_id;
+#if FF_API_INTERNAL_CONTEXT
/**
* internal_buffer count
* Don't touch, used by libavcodec default_get_buffer().
+ * @deprecated this field was moved to an internal context
*/
- int internal_buffer_count;
+ attribute_deprecated int internal_buffer_count;
/**
* internal_buffers
* Don't touch, used by libavcodec default_get_buffer().
+ * @deprecated this field was moved to an internal context
*/
- void *internal_buffer;
+ attribute_deprecated void *internal_buffer;
+#endif
/**
* Global quality for codecs which cannot change it per frame.
@@ -2875,14 +2881,18 @@ typedef struct AVCodecContext {
*/
AVPacket *pkt;
+#if FF_API_INTERNAL_CONTEXT
/**
* Whether this is a copy of the context which had init() called on it.
* This is used by multithreading - shared tables and picture pointers
* should be freed from the original context only.
* - encoding: Set by libavcodec.
* - decoding: Set by libavcodec.
+ *
+ * @deprecated this field has been moved to an internal context
*/
- int is_copy;
+ attribute_deprecated int is_copy;
+#endif
/**
* Which multithreading methods to use.
@@ -2945,6 +2955,14 @@ typedef struct AVCodecContext {
#define AV_EF_BITSTREAM (1<<1)
#define AV_EF_BUFFER (1<<2)
#define AV_EF_EXPLODE (1<<3)
+
+ /**
+ * Private context used for internal data.
+ *
+ * Unlike priv_data, this is not codec-specific. It is used in general
+ * libavcodec functions.
+ */
+ struct AVCodecInternal *internal;
} AVCodecContext;
/**
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index d959d56..7930525 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -1173,7 +1173,8 @@ static void copy_parameter_set(void **to, void **from, int count, int size)
static int decode_init_thread_copy(AVCodecContext *avctx){
H264Context *h= avctx->priv_data;
- if (!avctx->is_copy) return 0;
+ if (!avctx->internal->is_copy)
+ return 0;
memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 54d57d2..18e851c 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -25,8 +25,42 @@
#define AVCODEC_INTERNAL_H
#include <stdint.h>
+
+#include "libavutil/pixfmt.h"
#include "avcodec.h"
+typedef struct InternalBuffer {
+ int last_pic_num;
+ uint8_t *base[4];
+ uint8_t *data[4];
+ int linesize[4];
+ int width;
+ int height;
+ enum PixelFormat pix_fmt;
+} InternalBuffer;
+
+typedef struct AVCodecInternal {
+ /**
+ * internal buffer count
+ * used by default get/release/reget_buffer().
+ */
+ int buffer_count;
+
+ /**
+ * internal buffers
+ * used by default get/release/reget_buffer().
+ */
+ InternalBuffer *buffer;
+
+ /**
+ * Whether the parent AVCodecContext is a copy of the context which had
+ * init() called on it.
+ * This is used by multithreading - shared tables and picture pointers
+ * should be freed from the original context only.
+ */
+ int is_copy;
+} AVCodecInternal;
+
struct AVCodecDefault {
const uint8_t *key;
const uint8_t *value;
diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index c0d8546..b93f51f 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -24,6 +24,7 @@
#include <stdint.h>
#include "avcodec.h"
+#include "internal.h"
#include "get_bits.h"
#include "bytestream.h"
#include "dsputil.h"
@@ -405,7 +406,8 @@ static av_cold int mimic_decode_end(AVCodecContext *avctx)
av_free(ctx->swap_buf);
- if(avctx->is_copy) return 0;
+ if (avctx->internal->is_copy)
+ return 0;
for(i = 0; i < 16; i++)
if(ctx->buf_ptrs[i].data[0])
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 4c149f2..dcef706 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -858,7 +858,7 @@ void MPV_common_end(MpegEncContext *s)
av_freep(&s->reordered_input_picture);
av_freep(&s->dct_offset);
- if(s->picture && !s->avctx->is_copy){
+ if(s->picture && !s->avctx->internal->is_copy){
for(i=0; i<s->picture_count; i++){
free_picture(s, &s->picture[i]);
}
diff --git a/libavcodec/options.c b/libavcodec/options.c
index 100d4e6..a3a102c 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -643,9 +643,9 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src)
dest->priv_data = NULL;
dest->codec = NULL;
dest->slice_offset = NULL;
- dest->internal_buffer = NULL;
dest->hwaccel = NULL;
dest->thread_opaque = NULL;
+ dest->internal = NULL;
/* reallocate values that should be allocated separately */
dest->rc_eq = NULL;
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index 7557e68..9fe9b8d 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -31,6 +31,7 @@
#include "config.h"
#include "avcodec.h"
+#include "internal.h"
#include "thread.h"
#if HAVE_PTHREADS
@@ -672,8 +673,10 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count)
pthread_cond_destroy(&p->output_cond);
av_freep(&p->avpkt.data);
- if (i)
+ if (i) {
av_freep(&p->avctx->priv_data);
+ av_freep(&p->avctx->internal);
+ }
av_freep(&p->avctx);
}
@@ -728,9 +731,15 @@ static int frame_thread_init(AVCodecContext *avctx)
update_context_from_thread(avctx, copy, 1);
} else {
- copy->is_copy = 1;
copy->priv_data = av_malloc(codec->priv_data_size);
memcpy(copy->priv_data, src->priv_data, codec->priv_data_size);
+ copy->internal = av_malloc(sizeof(AVCodecInternal));
+ if (!copy->internal) {
+ err = AVERROR(ENOMEM);
+ goto error;
+ }
+ *(copy->internal) = *(src->internal);
+ copy->internal->is_copy = 1;
if (codec->init_thread_copy)
err = codec->init_thread_copy(copy);
@@ -862,8 +871,7 @@ void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
}
if(avctx->debug & FF_DEBUG_BUFFERS)
- av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p, %d buffers used\n",
- f, f->owner->internal_buffer_count);
+ av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
fctx = p->parent;
pthread_mutex_lock(&fctx->buffer_mutex);
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index cd8dce9..3e182a1 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -125,15 +125,6 @@ void avcodec_set_dimensions(AVCodecContext *s, int width, int height){
s->height= -((-height)>>s->lowres);
}
-typedef struct InternalBuffer{
- int last_pic_num;
- uint8_t *base[4];
- uint8_t *data[4];
- int linesize[4];
- int width, height;
- enum PixelFormat pix_fmt;
-}InternalBuffer;
-
#define INTERNAL_BUFFER_SIZE (32+1)
void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[4]){
@@ -250,32 +241,27 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
int h= s->height;
InternalBuffer *buf;
int *picture_number;
+ AVCodecInternal *avci = s->internal;
if(pic->data[0]!=NULL) {
av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n");
return -1;
}
- if(s->internal_buffer_count >= INTERNAL_BUFFER_SIZE) {
- av_log(s, AV_LOG_ERROR, "internal_buffer_count overflow (missing release_buffer?)\n");
+ if(avci->buffer_count >= INTERNAL_BUFFER_SIZE) {
+ av_log(s, AV_LOG_ERROR, "buffer_count overflow (missing release_buffer?)\n");
return -1;
}
if(av_image_check_size(w, h, 0, s))
return -1;
- if(s->internal_buffer==NULL){
- s->internal_buffer= av_mallocz((INTERNAL_BUFFER_SIZE+1)*sizeof(InternalBuffer));
+ if (!avci->buffer) {
+ avci->buffer = av_mallocz((INTERNAL_BUFFER_SIZE+1) *
+ sizeof(InternalBuffer));
}
-#if 0
- s->internal_buffer= av_fast_realloc(
- s->internal_buffer,
- &s->internal_buffer_size,
- sizeof(InternalBuffer)*FFMAX(99, s->internal_buffer_count+1)/*FIXME*/
- );
-#endif
- buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];
- picture_number= &(((InternalBuffer*)s->internal_buffer)[INTERNAL_BUFFER_SIZE]).last_pic_num; //FIXME ugly hack
+ buf = &avci->buffer[avci->buffer_count];
+ picture_number = &(avci->buffer[INTERNAL_BUFFER_SIZE]).last_pic_num; //FIXME ugly hack
(*picture_number)++;
if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){
@@ -366,14 +352,15 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
pic->data[i]= buf->data[i];
pic->linesize[i]= buf->linesize[i];
}
- s->internal_buffer_count++;
+ avci->buffer_count++;
if(s->pkt) pic->pkt_pts= s->pkt->pts;
else pic->pkt_pts= AV_NOPTS_VALUE;
pic->reordered_opaque= s->reordered_opaque;
if(s->debug&FF_DEBUG_BUFFERS)
- av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d buffers used\n", pic, s->internal_buffer_count);
+ av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d "
+ "buffers used\n", pic, avci->buffer_count);
return 0;
}
@@ -381,22 +368,23 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){
int i;
InternalBuffer *buf, *last;
+ AVCodecInternal *avci = s->internal;
assert(pic->type==FF_BUFFER_TYPE_INTERNAL);
- assert(s->internal_buffer_count);
-
- if(s->internal_buffer){
- buf = NULL; /* avoids warning */
- for(i=0; i<s->internal_buffer_count; i++){ //just 3-5 checks so is not worth to optimize
- buf= &((InternalBuffer*)s->internal_buffer)[i];
- if(buf->data[0] == pic->data[0])
- break;
- }
- assert(i < s->internal_buffer_count);
- s->internal_buffer_count--;
- last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];
+ assert(avci->buffer_count);
+
+ if (avci->buffer) {
+ buf = NULL; /* avoids warning */
+ for (i = 0; i < avci->buffer_count; i++) { //just 3-5 checks so is not worth to optimize
+ buf = &avci->buffer[i];
+ if (buf->data[0] == pic->data[0])
+ break;
+ }
+ assert(i < avci->buffer_count);
+ avci->buffer_count--;
+ last = &avci->buffer[avci->buffer_count];
- FFSWAP(InternalBuffer, *buf, *last);
+ FFSWAP(InternalBuffer, *buf, *last);
}
for(i=0; i<4; i++){
@@ -406,7 +394,8 @@ void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){
//printf("R%X\n", pic->opaque);
if(s->debug&FF_DEBUG_BUFFERS)
- av_log(s, AV_LOG_DEBUG, "default_release_buffer called on pic %p, %d buffers used\n", pic, s->internal_buffer_count);
+ av_log(s, AV_LOG_DEBUG, "default_release_buffer called on pic %p, %d "
+ "buffers used\n", pic, avci->buffer_count);
}
int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){
@@ -521,6 +510,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD
goto end;
}
+ avctx->internal = av_mallocz(sizeof(AVCodecInternal));
+ if (!avctx->internal) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+
if (codec->priv_data_size > 0) {
if(!avctx->priv_data){
avctx->priv_data = av_mallocz(codec->priv_data_size);
@@ -670,6 +665,7 @@ end:
free_and_end:
av_dict_free(&tmp);
av_freep(&avctx->priv_data);
+ av_freep(&avctx->internal);
avctx->codec= NULL;
goto end;
}
@@ -844,6 +840,7 @@ av_cold int avcodec_close(AVCodecContext *avctx)
avctx->codec->close(avctx);
avcodec_default_free_buffers(avctx);
avctx->coded_frame = NULL;
+ av_freep(&avctx->internal);
if (avctx->codec && avctx->codec->priv_class)
av_opt_free(avctx->priv_data);
av_opt_free(avctx);
@@ -1109,22 +1106,25 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
}
void avcodec_default_free_buffers(AVCodecContext *s){
+ AVCodecInternal *avci = s->internal;
int i, j;
- if(s->internal_buffer==NULL) return;
+ if (!avci->buffer)
+ return;
- if (s->internal_buffer_count)
- av_log(s, AV_LOG_WARNING, "Found %i unreleased buffers!\n", s->internal_buffer_count);
+ if (avci->buffer_count)
+ av_log(s, AV_LOG_WARNING, "Found %i unreleased buffers!\n",
+ avci->buffer_count);
for(i=0; i<INTERNAL_BUFFER_SIZE; i++){
- InternalBuffer *buf= &((InternalBuffer*)s->internal_buffer)[i];
+ InternalBuffer *buf = &avci->buffer[i];
for(j=0; j<4; j++){
av_freep(&buf->base[j]);
buf->data[j]= NULL;
}
}
- av_freep(&s->internal_buffer);
+ av_freep(&avci->buffer);
- s->internal_buffer_count=0;
+ avci->buffer_count=0;
}
#if FF_API_OLD_FF_PICT_TYPES
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 356ecbb..35e8958 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -21,7 +21,7 @@
#define AVCODEC_VERSION_H
#define LIBAVCODEC_VERSION_MAJOR 53
-#define LIBAVCODEC_VERSION_MINOR 20
+#define LIBAVCODEC_VERSION_MINOR 21
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
@@ -104,5 +104,8 @@
#ifndef FF_API_PARSE_FRAME
#define FF_API_PARSE_FRAME (LIBAVCODEC_VERSION_MAJOR < 54)
#endif
+#ifndef FF_API_INTERNAL_CONTEXT
+#define FF_API_INTERNAL_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
#endif /* AVCODEC_VERSION_H */
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 991ddce..a31ad4e 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -35,6 +35,7 @@
#include "libavutil/imgutils.h"
#include "avcodec.h"
+#include "internal.h"
#include "dsputil.h"
#include "get_bits.h"
@@ -2008,7 +2009,8 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx)
av_free(s->motion_val[1]);
av_free(s->edge_emu_buffer);
- if (avctx->is_copy) return 0;
+ if (avctx->internal->is_copy)
+ return 0;
for (i = 0; i < 16; i++) {
free_vlc(&s->dc_vlc[i]);
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 836176d..d9be734 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -24,6 +24,7 @@
#include "libavutil/imgutils.h"
#include "avcodec.h"
+#include "internal.h"
#include "vp8.h"
#include "vp8data.h"
#include "rectangle.h"
@@ -88,7 +89,7 @@ static void vp8_decode_flush_impl(AVCodecContext *avctx,
VP8Context *s = avctx->priv_data;
int i;
- if (!avctx->is_copy) {
+ if (!avctx->internal->is_copy) {
for (i = 0; i < 5; i++)
if (s->frames[i].data[0])
vp8_release_frame(s, &s->frames[i], prefer_delayed_free, can_direct_free);
More information about the ffmpeg-cvslog
mailing list