$NetBSD: patch-aq,v 1.6 2006/01/25 20:06:33 tron Exp $ --- src/libffmpeg/libavcodec/utils.c.orig 2004-05-30 20:24:23.000000000 +0100 +++ src/libffmpeg/libavcodec/utils.c 2006-01-25 19:55:16.000000000 +0000 @@ -200,27 +200,11 @@ buf->last_pic_num= *picture_number; }else{ int h_chroma_shift, v_chroma_shift; - int s_align, pixel_size; - + int s_align, pixel_size, size[3]; + AVPicture picture; + avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift); - switch(s->pix_fmt){ - case PIX_FMT_RGB555: - case PIX_FMT_RGB565: - case PIX_FMT_YUV422: - pixel_size=2; - break; - case PIX_FMT_RGB24: - case PIX_FMT_BGR24: - pixel_size=3; - break; - case PIX_FMT_RGBA32: - pixel_size=4; - break; - default: - pixel_size=1; - } - avcodec_align_dimensions(s, &w, &h); #if defined(ARCH_POWERPC) || defined(HAVE_MMI) //FIXME some cleaner check s_align= 16; @@ -232,21 +216,39 @@ w+= EDGE_WIDTH*2; h+= EDGE_WIDTH*2; } - + avpicture_fill(&picture, NULL, s->pix_fmt, w, h); + pixel_size= picture.linesize[0]*8 / w; +//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d\n", (int)picture.data[1], w, h, s->pix_fmt); + assert(pixel_size>=1); + //FIXME next ensures that linesize= 2^x uvlinesize, thats needed because some MC code assumes it + if(pixel_size == 3*8) + w= ALIGN(w, s_align<pix_fmt, w, h); + size[0] = picture.linesize[0] * h; + size[1] -= size[0]; + if(picture.data[2]) + size[1]= size[2]= size[1]/2; + else + size[2]= 0; + buf->last_pic_num= -256*256*256*64; + memset(buf->base, 0, sizeof(buf->base)); + memset(buf->data, 0, sizeof(buf->data)); - for(i=0; i<3; i++){ + for(i=0; i<3 && size[i]; i++){ const int h_shift= i==0 ? 0 : h_chroma_shift; const int v_shift= i==0 ? 0 : v_chroma_shift; - //FIXME next ensures that linesize= 2^x uvlinesize, thats needed because some MC code assumes it - buf->linesize[i]= ALIGN(pixel_size*w>>h_shift, s_align<<(h_chroma_shift-h_shift)); + buf->linesize[i]= picture.linesize[i]; - buf->base[i]= av_mallocz((buf->linesize[i]*h>>v_shift)+16); //FIXME 16 + buf->base[i]= av_malloc(size[i]+16); //FIXME 16 if(buf->base[i]==NULL) return -1; - memset(buf->base[i], 128, buf->linesize[i]*h>>v_shift); - - if(s->flags&CODEC_FLAG_EMU_EDGE) + memset(buf->base[i], 128, size[i]); + + // no edge if EDEG EMU or not planar YUV, we check for PAL8 redundantly to protect against a exploitable bug regression ... + if((s->flags&CODEC_FLAG_EMU_EDGE) || (s->pix_fmt == PIX_FMT_PAL8) || !size[2]) buf->data[i] = buf->base[i]; else buf->data[i] = buf->base[i] + ALIGN((buf->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift), s_align);