[FFmpeg-cvslog] utvideo: account for coupled lines in YUV420 format

Kostya Shishkov git at videolan.org
Sun Oct 30 02:04:12 CEST 2011


ffmpeg | branch: master | Kostya Shishkov <kostya.shishkov at gmail.com> | Fri Oct 28 20:40:23 2011 +0200| [9a173575fd3bd9a4391f760484e918824204e618] | committer: Ronald S. Bultje

utvideo: account for coupled lines in YUV420 format

Luma slices in YUV420 colourspace should have height in multiple of two since
they have the same line of chrominance data corresponding to pair of them.

Signed-off-by: Ronald S. Bultje <rsbultje at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9a173575fd3bd9a4391f760484e918824204e618
---

 libavcodec/utvideo.c |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/libavcodec/utvideo.c b/libavcodec/utvideo.c
index aac3969..5faaa15 100644
--- a/libavcodec/utvideo.c
+++ b/libavcodec/utvideo.c
@@ -113,6 +113,7 @@ static int decode_plane(UtvideoContext *c, int plane_no,
     VLC vlc;
     GetBitContext gb;
     int prev;
+    const int cmask = ~(!plane_no && c->avctx->pix_fmt == PIX_FMT_YUV420P);
 
     if (build_huff(src, &vlc)) {
         av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
@@ -128,7 +129,7 @@ static int decode_plane(UtvideoContext *c, int plane_no,
         int slice_data_start, slice_data_end, slice_size;
 
         sstart = send;
-        send   = height * (slice + 1) / c->slices;
+        send   = (height * (slice + 1) / c->slices) & cmask;
         dest   = dst + sstart * stride;
 
         // slice offset and size validation was done earlier
@@ -204,16 +205,17 @@ static void restore_rgb_planes(uint8_t *src, int step, int stride, int width, in
 }
 
 static void restore_median(uint8_t *src, int step, int stride,
-                           int width, int height, int slices)
+                           int width, int height, int slices, int rmode)
 {
     int i, j, slice;
     int A, B, C;
     uint8_t *bsrc;
     int slice_start, slice_height;
+    const int cmask = ~rmode;
 
     for (slice = 0; slice < slices; slice++) {
-        slice_start = (slice * height) / slices;
-        slice_height = ((slice + 1) * height) / slices - slice_start;
+        slice_start = ((slice * height) / slices) & cmask;
+        slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start;
 
         bsrc = src + slice_start * stride;
 
@@ -337,7 +339,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
             if (c->frame_pred == PRED_MEDIAN)
                 restore_median(c->pic.data[0] + rgb_order[i], c->planes,
                                c->pic.linesize[0], avctx->width, avctx->height,
-                               c->slices);
+                               c->slices, 0);
         }
         restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0],
                            avctx->width, avctx->height);
@@ -353,7 +355,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
             if (c->frame_pred == PRED_MEDIAN)
                 restore_median(c->pic.data[i], 1, c->pic.linesize[i],
                                avctx->width >> !!i, avctx->height >> !!i,
-                               c->slices);
+                               c->slices, !i);
         }
         break;
     case PIX_FMT_YUV422P:
@@ -366,7 +368,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
                 return ret;
             if (c->frame_pred == PRED_MEDIAN)
                 restore_median(c->pic.data[i], 1, c->pic.linesize[i],
-                               avctx->width >> !!i, avctx->height, c->slices);
+                               avctx->width >> !!i, avctx->height, c->slices, 0);
         }
         break;
     }



More information about the ffmpeg-cvslog mailing list