* qatar/master: swscale: Fix stack alignment for SSE avcodec: move some AVCodecContext fields to an internal struct. avcodec: use av_opt_set() instead of deprecated av_set_string3() avcodec: fix some const warnings avcodec: remove pointless AVOption, internal_buffer_count imgutils: Fix illegal read. Conflicts: doc/APIchanges libavcodec/avcodec.h libavcodec/version.h Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n0.9
| @@ -19,6 +19,14 @@ API changes, most recent first: | |||
| 2011-10-20 - b35e9e1 - lavu 51.22.0 | |||
| Add av_strtok() to avstring.h. | |||
| 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. | |||
| @@ -1214,6 +1214,8 @@ typedef struct AVFrame { | |||
| } AVFrame; | |||
| struct AVCodecInternal; | |||
| /** | |||
| * main external API structure. | |||
| * New fields can be added to the end with minor version bumps. | |||
| @@ -2041,17 +2043,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. | |||
| @@ -2937,14 +2943,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. | |||
| @@ -3013,6 +3023,14 @@ typedef struct AVCodecContext { | |||
| #define AV_EF_COMPLIANT (1<<17) | |||
| #define AV_EF_AGGRESSIVE (1<<18) | |||
| /** | |||
| * Private context used for internal data. | |||
| * | |||
| * Unlike priv_data, this is not codec-specific. It is used in general | |||
| * libavcodec functions. | |||
| */ | |||
| struct AVCodecInternal *internal; | |||
| /** | |||
| * Current statistics for PTS correction. | |||
| * - decoding: maintained and used by libavcodec, not intended to be used by user apps | |||
| @@ -1205,7 +1205,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)); | |||
| @@ -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; | |||
| @@ -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]) | |||
| @@ -859,7 +859,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]); | |||
| } | |||
| @@ -330,7 +330,6 @@ static const AVOption options[]={ | |||
| {"ibias", "intra quant bias", OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.dbl = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E}, | |||
| {"pbias", "inter quant bias", OFFSET(inter_quant_bias), AV_OPT_TYPE_INT, {.dbl = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E}, | |||
| {"color_table_id", NULL, OFFSET(color_table_id), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX}, | |||
| {"internal_buffer_count", NULL, OFFSET(internal_buffer_count), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX}, | |||
| {"global_quality", NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, | |||
| {"coder", NULL, OFFSET(coder_type), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E, "coder"}, | |||
| {"vlc", "variable length coder / huffman coder", 0, AV_OPT_TYPE_CONST, {.dbl = FF_CODER_TYPE_VLC }, INT_MIN, INT_MAX, V|E, "coder"}, | |||
| @@ -590,15 +589,15 @@ int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){ | |||
| } | |||
| } | |||
| if(codec->priv_class){ | |||
| *(AVClass**)s->priv_data= codec->priv_class; | |||
| *(const AVClass**)s->priv_data = codec->priv_class; | |||
| av_opt_set_defaults(s->priv_data); | |||
| } | |||
| } | |||
| if (codec && codec->defaults) { | |||
| int ret; | |||
| AVCodecDefault *d = codec->defaults; | |||
| const AVCodecDefault *d = codec->defaults; | |||
| while (d->key) { | |||
| ret = av_set_string3(s, d->key, d->value, 0, NULL); | |||
| ret = av_opt_set(s, d->key, d->value, 0); | |||
| av_assert0(ret >= 0); | |||
| d++; | |||
| } | |||
| @@ -653,9 +652,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; | |||
| @@ -679,8 +679,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); | |||
| } | |||
| @@ -734,9 +736,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); | |||
| @@ -870,8 +878,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); | |||
| @@ -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]){ | |||
| @@ -267,32 +258,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)){ | |||
| @@ -383,7 +369,7 @@ 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; | |||
| @@ -399,7 +385,8 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ | |||
| pic->format = s->pix_fmt; | |||
| 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; | |||
| } | |||
| @@ -407,22 +394,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++){ | |||
| @@ -432,7 +420,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){ | |||
| @@ -556,6 +545,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); | |||
| @@ -721,6 +716,7 @@ end: | |||
| free_and_end: | |||
| av_dict_free(&tmp); | |||
| av_freep(&avctx->priv_data); | |||
| av_freep(&avctx->internal); | |||
| avctx->codec= NULL; | |||
| goto end; | |||
| } | |||
| @@ -945,6 +941,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); | |||
| @@ -1223,22 +1220,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 | |||
| @@ -21,8 +21,8 @@ | |||
| #define AVCODEC_VERSION_H | |||
| #define LIBAVCODEC_VERSION_MAJOR 53 | |||
| #define LIBAVCODEC_VERSION_MINOR 35 | |||
| #define LIBAVCODEC_VERSION_MICRO 1 | |||
| #define LIBAVCODEC_VERSION_MINOR 36 | |||
| #define LIBAVCODEC_VERSION_MICRO 0 | |||
| #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | |||
| LIBAVCODEC_VERSION_MINOR, \ | |||
| @@ -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 */ | |||
| @@ -35,6 +35,7 @@ | |||
| #include "libavutil/imgutils.h" | |||
| #include "avcodec.h" | |||
| #include "internal.h" | |||
| #include "dsputil.h" | |||
| #include "get_bits.h" | |||
| @@ -2011,7 +2012,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]); | |||
| @@ -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); | |||
| @@ -126,7 +126,7 @@ int av_image_fill_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, int heigh | |||
| has_plane[desc->comp[i].plane] = 1; | |||
| total_size = size[0]; | |||
| for (i = 1; has_plane[i] && i < 4; i++) { | |||
| for (i = 1; i < 4 && has_plane[i]; i++) { | |||
| int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; | |||
| data[i] = data[i-1] + size[i-1]; | |||
| h = (height + (1 << s) - 1) >> s; | |||
| @@ -790,7 +790,7 @@ static int check_image_pointers(const uint8_t * const data[4], enum PixelFormat | |||
| * swscale wrapper, so we don't need to export the SwsContext. | |||
| * Assumes planar YUV to be in YUV order instead of YVU. | |||
| */ | |||
| int sws_scale(struct SwsContext *c, const uint8_t* const srcSlice[], | |||
| int attribute_align_arg sws_scale(struct SwsContext *c, const uint8_t* const srcSlice[], | |||
| const int srcStride[], int srcSliceY, int srcSliceH, | |||
| uint8_t* const dst[], const int dstStride[]) | |||
| { | |||