]> git.sesse.net Git - ffmpeg/blobdiff - libswscale/swscale.c
Merge commit '7d7355aa92bb36ca0765c49a569a999bcb96f332'
[ffmpeg] / libswscale / swscale.c
index 3e4d177eaeccb656f1c1233ecf22edf31df30d81..ba66314c7d46a4ec4406dac686ff6c9cc558fc92 100644 (file)
@@ -254,7 +254,7 @@ static int swscale(SwsContext *c, const uint8_t *src[],
     yuv2anyX_fn yuv2anyX             = c->yuv2anyX;
     const int chrSrcSliceY           =                srcSliceY >> c->chrSrcVSubSample;
     const int chrSrcSliceH           = AV_CEIL_RSHIFT(srcSliceH,   c->chrSrcVSubSample);
-    int should_dither                = is9_OR_10BPS(c->srcFormat) ||
+    int should_dither                = isNBPS(c->srcFormat) ||
                                        is16BPS(c->srcFormat);
     int lastDstY;
 
@@ -440,7 +440,7 @@ static int swscale(SwsContext *c, const uint8_t *src[],
             firstPosY = FFMAX(firstLumSrcY, posY);
             lastPosY = FFMIN(firstLumSrcY + hout_slice->plane[0].available_lines - 1, srcSliceY + srcSliceH - 1);
         } else {
-            firstPosY = lastInLumBuf + 1;
+            firstPosY = posY;
             lastPosY = lastLumSrcY;
         }
 
@@ -449,7 +449,7 @@ static int swscale(SwsContext *c, const uint8_t *src[],
             firstCPosY = FFMAX(firstChrSrcY, cPosY);
             lastCPosY = FFMIN(firstChrSrcY + hout_slice->plane[1].available_lines - 1, AV_CEIL_RSHIFT(srcSliceY + srcSliceH, c->chrSrcVSubSample) - 1);
         } else {
-            firstCPosY = lastInChrBuf + 1;
+            firstCPosY = cPosY;
             lastCPosY = lastChrSrcY;
         }
 
@@ -566,9 +566,6 @@ static av_cold void sws_init_swscale(SwsContext *c)
 
     ff_sws_init_input_funcs(c);
 
-    if (HAVE_VSX && (!HAVE_BIGENDIAN)) {
-        ff_sws_init_input_funcs_vsx(c);
-    }
 
     if (c->srcBpc == 8) {
         if (c->dstBpc <= 14) {
@@ -764,12 +761,21 @@ int attribute_align_arg sws_scale(struct SwsContext *c,
     uint8_t *dst2[4];
     uint8_t *rgb0_tmp = NULL;
     int macro_height = isBayer(c->srcFormat) ? 2 : (1 << c->chrSrcVSubSample);
+    // copy strides, so they can safely be modified
+    int srcStride2[4];
+    int dstStride2[4];
+    int srcSliceY_internal = srcSliceY;
 
     if (!srcStride || !dstStride || !dst || !srcSlice) {
         av_log(c, AV_LOG_ERROR, "One of the input parameters to sws_scale() is NULL, please check the calling code\n");
         return 0;
     }
 
+    for (i=0; i<4; i++) {
+        srcStride2[i] = srcStride[i];
+        dstStride2[i] = dstStride[i];
+    }
+
     if ((srcSliceY & (macro_height-1)) ||
         ((srcSliceH& (macro_height-1)) && srcSliceY + srcSliceH != c->srcH) ||
         srcSliceY + srcSliceH > c->srcH) {
@@ -946,30 +952,12 @@ int attribute_align_arg sws_scale(struct SwsContext *c,
         for (i = 0; i < 4; i++)
             memset(c->dither_error[i], 0, sizeof(c->dither_error[0][0]) * (c->dstW+2));
 
-
-    // copy strides, so they can safely be modified
-    if (c->sliceDir == 1) {
-        // slices go from top to bottom
-        int srcStride2[4] = { srcStride[0], srcStride[1], srcStride[2],
-                              srcStride[3] };
-        int dstStride2[4] = { dstStride[0], dstStride[1], dstStride[2],
-                              dstStride[3] };
-
-        reset_ptr(src2, c->srcFormat);
-        reset_ptr((void*)dst2, c->dstFormat);
-
-        /* reset slice direction at end of frame */
-        if (srcSliceY + srcSliceH == c->srcH)
-            c->sliceDir = 0;
-
-        ret = c->swscale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2,
-                          dstStride2);
-    } else {
+    if (c->sliceDir != 1) {
         // slices go from bottom to top => we flip the image internally
-        int srcStride2[4] = { -srcStride[0], -srcStride[1], -srcStride[2],
-                              -srcStride[3] };
-        int dstStride2[4] = { -dstStride[0], -dstStride[1], -dstStride[2],
-                              -dstStride[3] };
+        for (i=0; i<4; i++) {
+            srcStride2[i] *= -1;
+            dstStride2[i] *= -1;
+        }
 
         src2[0] += (srcSliceH - 1) * srcStride[0];
         if (!usePal(c->srcFormat))
@@ -981,21 +969,26 @@ int attribute_align_arg sws_scale(struct SwsContext *c,
         dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
         dst2[3] += ( c->dstH                         - 1) * dstStride[3];
 
-        reset_ptr(src2, c->srcFormat);
-        reset_ptr((void*)dst2, c->dstFormat);
-
-        /* reset slice direction at end of frame */
-        if (!srcSliceY)
-            c->sliceDir = 0;
-
-        ret = c->swscale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH,
-                          srcSliceH, dst2, dstStride2);
+        srcSliceY_internal = c->srcH-srcSliceY-srcSliceH;
     }
+    reset_ptr(src2, c->srcFormat);
+    reset_ptr((void*)dst2, c->dstFormat);
+
+    /* reset slice direction at end of frame */
+    if (srcSliceY_internal + srcSliceH == c->srcH)
+        c->sliceDir = 0;
+    ret = c->swscale(c, src2, srcStride2, srcSliceY_internal, srcSliceH, dst2, dstStride2);
 
 
     if (c->dstXYZ && !(c->srcXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
+        int dstY = c->dstY ? c->dstY : srcSliceY + srcSliceH;
+        uint16_t *dst16 = (uint16_t*)(dst2[0] + (dstY - ret) * dstStride2[0]);
+        av_assert0(dstY >= ret);
+        av_assert0(ret >= 0);
+        av_assert0(c->dstH >= dstY);
+
         /* replace on the same data */
-        rgb48Toxyz12(c, (uint16_t*)dst2[0], (const uint16_t*)dst2[0], dstStride[0]/2, ret);
+        rgb48Toxyz12(c, dst16, dst16, dstStride2[0]/2, ret);
     }
 
     av_free(rgb0_tmp);