From c693aa6f71b4f539cf9df67ba42f4b1932981687 Mon Sep 17 00:00:00 2001 From: Thierry Foucu Date: Fri, 18 Nov 2011 17:36:50 -0800 Subject: [PATCH 1/6] imgutils: Fix illegal read. Found with address sanitizer. Signed-off-by: Alex Converse --- libavutil/imgutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c index 5cd71e21ce..b734db7bb1 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -118,7 +118,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; From 86d3730360bf085f5ba35951350b3c8e8e804350 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 18 Nov 2011 19:49:24 -0500 Subject: [PATCH 2/6] avcodec: remove pointless AVOption, internal_buffer_count --- libavcodec/options.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/options.c b/libavcodec/options.c index e747408b19..d1cc183050 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -329,7 +329,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"}, From fa9aeb82e25fe7eaf38086798ca79825e423da4e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 19 Nov 2011 01:09:48 -0500 Subject: [PATCH 3/6] avcodec: fix some const warnings libavcodec/options.c:583: warning: assignment discards qualifiers from pointer target type libavcodec/options.c:589: warning: initialization discards qualifiers from pointer target type --- libavcodec/options.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/options.c b/libavcodec/options.c index d1cc183050..76ca66c902 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -580,13 +580,13 @@ 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); av_assert0(ret >= 0); From 513b6919555b9e2b0c1f86fd5f02caaa14bcbe69 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 19 Nov 2011 01:14:27 -0500 Subject: [PATCH 4/6] avcodec: use av_opt_set() instead of deprecated av_set_string3() --- libavcodec/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/options.c b/libavcodec/options.c index 76ca66c902..100d4e6a90 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -588,7 +588,7 @@ int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){ int ret; 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++; } From f3a29b750a5979ae6847879fba758faf1fae88d0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 15 Nov 2011 15:34:50 -0500 Subject: [PATCH 5/6] 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. --- 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 | 86 +++++++++++++++++++++--------------------- libavcodec/version.h | 5 ++- libavcodec/vp3.c | 4 +- libavcodec/vp8.c | 3 +- 12 files changed, 134 insertions(+), 57 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index f1913bd6de..026e5ad539 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 7d506a1f72..67bbdf89a2 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 d959d5652a..793052581d 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 54d57d2bec..18e851c48e 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -25,8 +25,42 @@ #define AVCODEC_INTERNAL_H #include + +#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 c0d8546eb8..b93f51fa3e 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -24,6 +24,7 @@ #include #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 4c149f232f..dcef706751 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; ipicture_count; i++){ free_picture(s, &s->picture[i]); } diff --git a/libavcodec/options.c b/libavcodec/options.c index 100d4e6a90..a3a102c0c8 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 7557e68c65..9fe9b8d784 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 cd8dce91fc..3e182a1613 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); + assert(avci->buffer_count); - if(s->internal_buffer){ - buf = NULL; /* avoids warning */ - for(i=0; iinternal_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]; + 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; iinternal_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 356ecbb15c..35e8958c69 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 991ddce892..a31ad4e99f 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 836176df2b..d9be734a9b 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); From 09d243ddd0d939e97f3fe0b7f27320763ee41493 Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Fri, 18 Nov 2011 15:06:17 -0800 Subject: [PATCH 6/6] swscale: Fix stack alignment for SSE Although gcc guarantees 16 byte stack alignment, threads under WinXP don't appear to be guaranteed to start stack aligned. So fix the alignment. Signed-off-by: Ronald S. Bultje --- libswscale/swscale_unscaled.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index c0161c24e9..c7e6a28ac5 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -806,7 +806,7 @@ static int check_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, * 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[]) {