Mercurial > libavcodec.hg
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); |