Mercurial > libavcodec.hg
changeset 11311:ee2e050815be libavcodec
Fix avcodec_align_dimensions to return values suitably aligned for FLV decoding
with SSE and add a avcodec_align_dimensions2 taht returns the stride alignment
requirements independently from doing the width/height padding.
author | reimar |
---|---|
date | Sat, 27 Feb 2010 21:13:22 +0000 |
parents | 1ff8ae765206 |
children | 20752e8b2657 |
files | avcodec.h utils.c |
diffstat | 2 files changed, 46 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/avcodec.h Sat Feb 27 14:08:06 2010 +0000 +++ b/avcodec.h Sat Feb 27 21:13:22 2010 +0000 @@ -1367,7 +1367,7 @@ /** * Called at the beginning of each frame to get a buffer for it. * If pic.reference is set then the frame will be read later by libavcodec. - * avcodec_align_dimensions() should be used to find the required width and + * avcodec_align_dimensions2() should be used to find the required width and * height, as they normally need to be rounded up to the next multiple of 16. * if CODEC_CAP_DR1 is not set then get_buffer() must call * avcodec_default_get_buffer() instead of providing buffers allocated by @@ -3226,7 +3226,19 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic); +/** + * Modifies width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you do not use any horizontal + * padding. + */ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); +/** + * Modifies width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you also ensure that all + * line sizes are a multiple of the respective linesize_align[i]. + */ +void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, + int linesize_align[4]); /** * Checks if the given dimension of a picture is valid, meaning that all
--- a/utils.c Sat Feb 27 14:08:06 2010 +0000 +++ b/utils.c Sat Feb 27 21:13:22 2010 +0000 @@ -31,6 +31,7 @@ #include "libavutil/avstring.h" #include "libavutil/integer.h" #include "libavutil/crc.h" +#include "libavutil/pixdesc.h" #include "avcodec.h" #include "dsputil.h" #include "opt.h" @@ -117,7 +118,7 @@ #define INTERNAL_BUFFER_SIZE 32 -void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ +void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[4]){ int w_align= 1; int h_align= 1; @@ -180,6 +181,36 @@ *height= FFALIGN(*height, h_align); if(s->codec_id == CODEC_ID_H264) *height+=2; // some of the optimized chroma MC reads one line too much + + linesize_align[0] = + linesize_align[1] = + linesize_align[2] = + linesize_align[3] = STRIDE_ALIGN; +//STRIDE_ALIGN is 8 for SSE* but this does not work for SVQ1 chroma planes +//we could change STRIDE_ALIGN to 16 for x86/sse but it would increase the +//picture size unneccessarily in some cases. The solution here is not +//pretty and better ideas are welcome! +#if HAVE_MMX + if(s->codec_id == CODEC_ID_SVQ1 || s->codec_id == CODEC_ID_VP5 || + s->codec_id == CODEC_ID_VP6 || s->codec_id == CODEC_ID_VP6F || + s->codec_id == CODEC_ID_VP6A) { + linesize_align[0] = + linesize_align[1] = + linesize_align[2] = 16; + } +#endif +} + +void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ + int chroma_shift = av_pix_fmt_descriptors[s->pix_fmt].log2_chroma_w; + int linesize_align[4]; + int align; + avcodec_align_dimensions2(s, width, height, linesize_align); + align = FFMAX(linesize_align[0], linesize_align[3]); + linesize_align[1] <<= chroma_shift; + linesize_align[2] <<= chroma_shift; + align = FFMAX3(align, linesize_align[1], linesize_align[2]); + *width=FFALIGN(*width, align); } int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h){ @@ -244,7 +275,7 @@ avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift); - avcodec_align_dimensions(s, &w, &h); + avcodec_align_dimensions2(s, &w, &h, stride_align); if(!(s->flags&CODEC_FLAG_EMU_EDGE)){ w+= EDGE_WIDTH*2; @@ -260,18 +291,6 @@ unaligned = 0; for (i=0; i<4; i++){ -//STRIDE_ALIGN is 8 for SSE* but this does not work for SVQ1 chroma planes -//we could change STRIDE_ALIGN to 16 for x86/sse but it would increase the -//picture size unneccessarily in some cases. The solution here is not -//pretty and better ideas are welcome! -#if HAVE_MMX - if(s->codec_id == CODEC_ID_SVQ1 || s->codec_id == CODEC_ID_VP5 || - s->codec_id == CODEC_ID_VP6 || s->codec_id == CODEC_ID_VP6F || - s->codec_id == CODEC_ID_VP6A) - stride_align[i]= 16; - else -#endif - stride_align[i] = STRIDE_ALIGN; unaligned |= picture.linesize[i] % stride_align[i]; } } while (unaligned);