[FFmpeg-devel] [PATCH] avcodec/imgconvert: Support non-planar colorspaces while padding

Przemysław Sobala przemyslaw.sobala at grupawp.pl
Fri Sep 18 16:31:16 CEST 2015


---
 libavcodec/imgconvert.c | 99 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 65 insertions(+), 34 deletions(-)

diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
index dc67560..a523bd5 100644
--- a/libavcodec/imgconvert.c
+++ b/libavcodec/imgconvert.c
@@ -236,54 +236,85 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
     int x_shift;
     int yheight;
     int i, y;
+    int max_step[4];
 
-    if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB ||
-        !is_yuv_planar(desc)) return -1;
+    if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB)
+        return -1;
 
-    for (i = 0; i < 3; i++) {
-        x_shift = i ? desc->log2_chroma_w : 0;
-        y_shift = i ? desc->log2_chroma_h : 0;
+    if (is_yuv_planar(desc)) {
+        for (i = 0; i < 3; i++) {
+            x_shift = i ? desc->log2_chroma_w : 0;
+            y_shift = i ? desc->log2_chroma_h : 0;
 
-        if (padtop || padleft) {
-            memset(dst->data[i], color[i],
-                dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
-        }
+            if (padtop || padleft) {
+                memset(dst->data[i], color[i],
+                    dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
+            }
 
-        if (padleft || padright) {
-            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
-                (dst->linesize[i] - (padright >> x_shift));
-            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
-            for (y = 0; y < yheight; y++) {
-                memset(optr, color[i], (padleft + padright) >> x_shift);
-                optr += dst->linesize[i];
+            if (padleft || padright) {
+                optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
+                    (dst->linesize[i] - (padright >> x_shift));
+                yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
+                for (y = 0; y < yheight; y++) {
+                    memset(optr, color[i], (padleft + padright) >> x_shift);
+                    optr += dst->linesize[i];
+                }
             }
+
+            if (src) { /* first line */
+                uint8_t *iptr = src->data[i];
+                optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
+                        (padleft >> x_shift);
+                memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
+                iptr += src->linesize[i];
+                optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
+                    (dst->linesize[i] - (padright >> x_shift));
+                yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
+                for (y = 0; y < yheight; y++) {
+                    memset(optr, color[i], (padleft + padright) >> x_shift);
+                    memcpy(optr + ((padleft + padright) >> x_shift), iptr,
+                           (width - padleft - padright) >> x_shift);
+                    iptr += src->linesize[i];
+                    optr += dst->linesize[i];
+                }
+            }
+
+            if (padbottom || padright) {
+                optr = dst->data[i] + dst->linesize[i] *
+                    ((height - padbottom) >> y_shift) - (padright >> x_shift);
+                memset(optr, color[i],dst->linesize[i] *
+                    (padbottom >> y_shift) + (padright >> x_shift));
+            }
+        }
+    } else {
+        if (src) 
+            return -1;
+        
+        av_image_fill_max_pixsteps(max_step, NULL, desc);
+
+        if (padtop || padleft) {
+            memset(dst->data[0], color[0],
+                    dst->linesize[0] * padtop + (padleft * max_step[0]));
         }
 
-        if (src) { /* first line */
-            uint8_t *iptr = src->data[i];
-            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
-                    (padleft >> x_shift);
-            memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
-            iptr += src->linesize[i];
-            optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
-                (dst->linesize[i] - (padright >> x_shift));
-            yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
+        if (padleft || padright) {
+            optr = dst->data[0] + dst->linesize[0] * padtop +
+                    (dst->linesize[0] - (padright * max_step[0]));
+            yheight = height - 1 - (padtop + padbottom);
             for (y = 0; y < yheight; y++) {
-                memset(optr, color[i], (padleft + padright) >> x_shift);
-                memcpy(optr + ((padleft + padright) >> x_shift), iptr,
-                       (width - padleft - padright) >> x_shift);
-                iptr += src->linesize[i];
-                optr += dst->linesize[i];
+                memset(optr, color[0], (padleft + padright) * max_step[0]);
+                optr += dst->linesize[0];
             }
         }
 
         if (padbottom || padright) {
-            optr = dst->data[i] + dst->linesize[i] *
-                ((height - padbottom) >> y_shift) - (padright >> x_shift);
-            memset(optr, color[i],dst->linesize[i] *
-                (padbottom >> y_shift) + (padright >> x_shift));
+            optr = dst->data[0] + dst->linesize[0] * (height - padbottom) -
+                    (padright * max_step[0]);
+            memset(optr, color[0], dst->linesize[0] * padbottom +
+                    (padright * max_step[0]));
         }
     }
+
     return 0;
 }
 
-- 
1.8.3.1



More information about the ffmpeg-devel mailing list