comparison utils.c @ 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 a090d10c314f
children c4e86bcb2fee
comparison
equal deleted inserted replaced
11310:1ff8ae765206 11311:ee2e050815be
29 #define _XOPEN_SOURCE 600 29 #define _XOPEN_SOURCE 600
30 30
31 #include "libavutil/avstring.h" 31 #include "libavutil/avstring.h"
32 #include "libavutil/integer.h" 32 #include "libavutil/integer.h"
33 #include "libavutil/crc.h" 33 #include "libavutil/crc.h"
34 #include "libavutil/pixdesc.h"
34 #include "avcodec.h" 35 #include "avcodec.h"
35 #include "dsputil.h" 36 #include "dsputil.h"
36 #include "opt.h" 37 #include "opt.h"
37 #include "imgconvert.h" 38 #include "imgconvert.h"
38 #include "audioconvert.h" 39 #include "audioconvert.h"
115 enum PixelFormat pix_fmt; 116 enum PixelFormat pix_fmt;
116 }InternalBuffer; 117 }InternalBuffer;
117 118
118 #define INTERNAL_BUFFER_SIZE 32 119 #define INTERNAL_BUFFER_SIZE 32
119 120
120 void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ 121 void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[4]){
121 int w_align= 1; 122 int w_align= 1;
122 int h_align= 1; 123 int h_align= 1;
123 124
124 switch(s->pix_fmt){ 125 switch(s->pix_fmt){
125 case PIX_FMT_YUV420P: 126 case PIX_FMT_YUV420P:
178 179
179 *width = FFALIGN(*width , w_align); 180 *width = FFALIGN(*width , w_align);
180 *height= FFALIGN(*height, h_align); 181 *height= FFALIGN(*height, h_align);
181 if(s->codec_id == CODEC_ID_H264) 182 if(s->codec_id == CODEC_ID_H264)
182 *height+=2; // some of the optimized chroma MC reads one line too much 183 *height+=2; // some of the optimized chroma MC reads one line too much
184
185 linesize_align[0] =
186 linesize_align[1] =
187 linesize_align[2] =
188 linesize_align[3] = STRIDE_ALIGN;
189 //STRIDE_ALIGN is 8 for SSE* but this does not work for SVQ1 chroma planes
190 //we could change STRIDE_ALIGN to 16 for x86/sse but it would increase the
191 //picture size unneccessarily in some cases. The solution here is not
192 //pretty and better ideas are welcome!
193 #if HAVE_MMX
194 if(s->codec_id == CODEC_ID_SVQ1 || s->codec_id == CODEC_ID_VP5 ||
195 s->codec_id == CODEC_ID_VP6 || s->codec_id == CODEC_ID_VP6F ||
196 s->codec_id == CODEC_ID_VP6A) {
197 linesize_align[0] =
198 linesize_align[1] =
199 linesize_align[2] = 16;
200 }
201 #endif
202 }
203
204 void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){
205 int chroma_shift = av_pix_fmt_descriptors[s->pix_fmt].log2_chroma_w;
206 int linesize_align[4];
207 int align;
208 avcodec_align_dimensions2(s, width, height, linesize_align);
209 align = FFMAX(linesize_align[0], linesize_align[3]);
210 linesize_align[1] <<= chroma_shift;
211 linesize_align[2] <<= chroma_shift;
212 align = FFMAX3(align, linesize_align[1], linesize_align[2]);
213 *width=FFALIGN(*width, align);
183 } 214 }
184 215
185 int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h){ 216 int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h){
186 if((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/8) 217 if((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/8)
187 return 0; 218 return 0;
242 AVPicture picture; 273 AVPicture picture;
243 int stride_align[4]; 274 int stride_align[4];
244 275
245 avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift); 276 avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
246 277
247 avcodec_align_dimensions(s, &w, &h); 278 avcodec_align_dimensions2(s, &w, &h, stride_align);
248 279
249 if(!(s->flags&CODEC_FLAG_EMU_EDGE)){ 280 if(!(s->flags&CODEC_FLAG_EMU_EDGE)){
250 w+= EDGE_WIDTH*2; 281 w+= EDGE_WIDTH*2;
251 h+= EDGE_WIDTH*2; 282 h+= EDGE_WIDTH*2;
252 } 283 }
258 // increase alignment of w for next try (rhs gives the lowest bit set in w) 289 // increase alignment of w for next try (rhs gives the lowest bit set in w)
259 w += w & ~(w-1); 290 w += w & ~(w-1);
260 291
261 unaligned = 0; 292 unaligned = 0;
262 for (i=0; i<4; i++){ 293 for (i=0; i<4; i++){
263 //STRIDE_ALIGN is 8 for SSE* but this does not work for SVQ1 chroma planes
264 //we could change STRIDE_ALIGN to 16 for x86/sse but it would increase the
265 //picture size unneccessarily in some cases. The solution here is not
266 //pretty and better ideas are welcome!
267 #if HAVE_MMX
268 if(s->codec_id == CODEC_ID_SVQ1 || s->codec_id == CODEC_ID_VP5 ||
269 s->codec_id == CODEC_ID_VP6 || s->codec_id == CODEC_ID_VP6F ||
270 s->codec_id == CODEC_ID_VP6A)
271 stride_align[i]= 16;
272 else
273 #endif
274 stride_align[i] = STRIDE_ALIGN;
275 unaligned |= picture.linesize[i] % stride_align[i]; 294 unaligned |= picture.linesize[i] % stride_align[i];
276 } 295 }
277 } while (unaligned); 296 } while (unaligned);
278 297
279 tmpsize = ff_fill_pointer(&picture, NULL, s->pix_fmt, h); 298 tmpsize = ff_fill_pointer(&picture, NULL, s->pix_fmt, h);