[FFmpeg-devel] MXF D10 regression tests

Reimar Döffinger Reimar.Doeffinger
Wed Mar 18 14:20:43 CET 2009


On Wed, Mar 18, 2009 at 01:44:03PM +0100, Michael Niedermayer wrote:
> It is not supposed to be a restriction for avcodec_encode_video() though
> maybe it is by a bug. (i did not test this)
> The restriction is just on the internal buffers, which for encoding are
> allocated by lavc.

Oh, ok. Then attached patch can fix this simpler and more thoroughly (it
seems to fix both intra and inter 4:2:2 encoding on PPC).
Note it may still contain some brainfarts, it still feels a bit
confusing and suboptimal to me currently.
-------------- next part --------------
Index: libavcodec/imgconvert.c
===================================================================
--- libavcodec/imgconvert.c	(revision 18029)
+++ libavcodec/imgconvert.c	(working copy)
@@ -533,14 +533,21 @@
     return 0;
 }
 
-int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width)
+#define ALIGN(x, a) (((x)+(a)-1)&~((a)-1))
+
+int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width, int align)
 {
-    int w2;
+    int w2, orig_w = width;
     const PixFmtInfo *pinfo;
 
     memset(picture->linesize, 0, sizeof(picture->linesize));
 
     pinfo = &pix_fmt_info[pix_fmt];
+    w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
+    if (align) {
+        width = ALIGN(w2 << pinfo->x_chroma_shift, align << pinfo->x_chroma_shift);
+        w2 = ALIGN(w2, align);
+    }
     switch(pix_fmt) {
     case PIX_FMT_YUV420P:
     case PIX_FMT_YUV422P:
@@ -552,13 +559,11 @@
     case PIX_FMT_YUVJ422P:
     case PIX_FMT_YUVJ444P:
     case PIX_FMT_YUVJ440P:
-        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
         picture->linesize[0] = width;
         picture->linesize[1] = w2;
         picture->linesize[2] = w2;
         break;
     case PIX_FMT_YUVA420P:
-        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
         picture->linesize[0] = width;
         picture->linesize[1] = w2;
         picture->linesize[2] = w2;
@@ -566,7 +571,6 @@
         break;
     case PIX_FMT_NV12:
     case PIX_FMT_NV21:
-        w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
         picture->linesize[0] = width;
         picture->linesize[1] = w2;
         break;
@@ -597,15 +601,18 @@
         picture->linesize[0] = width * 2;
         break;
     case PIX_FMT_UYYVYY411:
-        picture->linesize[0] = width + width/2;
+        picture->linesize[0] = orig_w + orig_w/2;
+        if (align) picture->linesize[0] = ALIGN(picture->linesize[0], align);
         break;
     case PIX_FMT_RGB4:
     case PIX_FMT_BGR4:
-        picture->linesize[0] = width / 2;
+        picture->linesize[0] = orig_w / 2;
+        if (align) picture->linesize[0] = ALIGN(picture->linesize[0], align);
         break;
     case PIX_FMT_MONOWHITE:
     case PIX_FMT_MONOBLACK:
-        picture->linesize[0] = (width + 7) >> 3;
+        picture->linesize[0] = (orig_w + 7) >> 3;
+        if (align) picture->linesize[0] = ALIGN(picture->linesize[0], align);
         break;
     case PIX_FMT_PAL8:
     case PIX_FMT_RGB8:
@@ -719,7 +726,7 @@
     if(avcodec_check_dimensions(NULL, width, height))
         return -1;
 
-    if (ff_fill_linesize(picture, pix_fmt, width))
+    if (ff_fill_linesize(picture, pix_fmt, width, 0))
         return -1;
 
     return ff_fill_pointer(picture, ptr, pix_fmt, height);
Index: libavcodec/imgconvert.h
===================================================================
--- libavcodec/imgconvert.h	(revision 18029)
+++ libavcodec/imgconvert.h	(working copy)
@@ -27,7 +27,7 @@
 #include <stdint.h>
 #include "avcodec.h"
 
-int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width);
+int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width, int align);
 
 int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt, int height);
 
Index: libavcodec/utils.c
===================================================================
--- libavcodec/utils.c	(revision 18029)
+++ libavcodec/utils.c	(working copy)
@@ -243,7 +243,7 @@
         int size[4] = {0};
         int tmpsize;
         AVPicture picture;
-        int stride_align[4];
+        int stride_align = STRIDE_ALIGN;
 
         avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
 
@@ -254,22 +254,17 @@
             h+= EDGE_WIDTH*2;
         }
 
-        ff_fill_linesize(&picture, s->pix_fmt, w);
-
-        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)
-                stride_align[i]= 16;
-            else
+                stride_align= 16;
 #endif
-            stride_align[i] = STRIDE_ALIGN;
-            picture.linesize[i] = ALIGN(picture.linesize[i], stride_align[i]);
-        }
 
+        ff_fill_linesize(&picture, s->pix_fmt, w, stride_align);
+
         tmpsize = ff_fill_pointer(&picture, NULL, s->pix_fmt, h);
         if (tmpsize < 0)
             return -1;
@@ -296,7 +291,7 @@
             if((s->flags&CODEC_FLAG_EMU_EDGE) || !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), stride_align[i]);
+                buf->data[i] = buf->base[i] + ALIGN((buf->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift), stride_align);
         }
         if(size[1] && !size[2])
             ff_set_systematic_pal((uint32_t*)buf->data[1], s->pix_fmt);



More information about the ffmpeg-devel mailing list