[FFmpeg-cvslog] h264: move [uv]linesize to the per-slice context

Anton Khirnov git at videolan.org
Sun Mar 22 00:00:25 CET 2015


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Thu Jan 29 13:06:25 2015 +0100| [c28ed1d743443e783537d279ae721be3bbdf7646] | committer: Anton Khirnov

h264: move [uv]linesize to the per-slice context

While it is a per-frame variable, it is only really used in the
low-level decoding code, so it is more efficient to store it in the
slice context.

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

 libavcodec/h264.h             |    2 +-
 libavcodec/h264_mb.c          |    8 ++++----
 libavcodec/h264_mb_template.c |   36 +++++++++++++++++-----------------
 libavcodec/h264_slice.c       |   43 +++++++++++++++++------------------------
 libavcodec/svq3.c             |   32 +++++++++++++++---------------
 5 files changed, 57 insertions(+), 64 deletions(-)

diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 9fc5c12..6f46af4 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -366,6 +366,7 @@ typedef struct H264SliceContext {
     unsigned int topright_samples_available;
     unsigned int left_samples_available;
 
+    ptrdiff_t linesize, uvlinesize;
     ptrdiff_t mb_linesize;  ///< may be equal to s->linesize or s->linesize * 2, for mbaff
     ptrdiff_t mb_uvlinesize;
 
@@ -478,7 +479,6 @@ typedef struct H264Context {
 
     /* coded dimensions -- 16 * mb w/h */
     int width, height;
-    ptrdiff_t linesize, uvlinesize;
     int chroma_x_shift, chroma_y_shift;
 
     int droppable;
diff --git a/libavcodec/h264_mb.c b/libavcodec/h264_mb.c
index 57d429a..fea733a 100644
--- a/libavcodec/h264_mb.c
+++ b/libavcodec/h264_mb.c
@@ -487,13 +487,13 @@ static av_always_inline void prefetch_motion(const H264Context *h, H264SliceCont
         int off       = (mx << pixel_shift) +
                         (my + (sl->mb_x & 3) * 4) * sl->mb_linesize +
                         (64 << pixel_shift);
-        h->vdsp.prefetch(src[0] + off, h->linesize, 4);
+        h->vdsp.prefetch(src[0] + off, sl->linesize, 4);
         if (chroma_idc == 3 /* yuv444 */) {
-            h->vdsp.prefetch(src[1] + off, h->linesize, 4);
-            h->vdsp.prefetch(src[2] + off, h->linesize, 4);
+            h->vdsp.prefetch(src[1] + off, sl->linesize, 4);
+            h->vdsp.prefetch(src[2] + off, sl->linesize, 4);
         } else {
             off = ((mx >> 1) << pixel_shift) +
-                  ((my >> 1) + (sl->mb_x & 7)) * h->uvlinesize +
+                  ((my >> 1) + (sl->mb_x & 7)) * sl->uvlinesize +
                   (64 << pixel_shift);
             h->vdsp.prefetch(src[1] + off, src[2] - src[1], 2);
         }
diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c
index 94de316..75757a6 100644
--- a/libavcodec/h264_mb_template.c
+++ b/libavcodec/h264_mb_template.c
@@ -57,23 +57,23 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
     const int block_h   = 16 >> h->chroma_y_shift;
     const int chroma422 = CHROMA422(h);
 
-    dest_y  = h->cur_pic.f.data[0] + ((mb_x << PIXEL_SHIFT)     + mb_y * h->linesize)  * 16;
-    dest_cb = h->cur_pic.f.data[1] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h;
-    dest_cr = h->cur_pic.f.data[2] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h;
+    dest_y  = h->cur_pic.f.data[0] + ((mb_x << PIXEL_SHIFT)     + mb_y * sl->linesize)  * 16;
+    dest_cb = h->cur_pic.f.data[1] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * sl->uvlinesize * block_h;
+    dest_cr = h->cur_pic.f.data[2] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * sl->uvlinesize * block_h;
 
-    h->vdsp.prefetch(dest_y  + (sl->mb_x & 3) * 4 * h->linesize   + (64 << PIXEL_SHIFT), h->linesize,       4);
-    h->vdsp.prefetch(dest_cb + (sl->mb_x & 7)     * h->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2);
+    h->vdsp.prefetch(dest_y  + (sl->mb_x & 3) * 4 * sl->linesize   + (64 << PIXEL_SHIFT), sl->linesize,       4);
+    h->vdsp.prefetch(dest_cb + (sl->mb_x & 7)     * sl->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2);
 
     h->list_counts[mb_xy] = sl->list_count;
 
     if (!SIMPLE && MB_FIELD(sl)) {
-        linesize     = sl->mb_linesize = h->linesize * 2;
-        uvlinesize   = sl->mb_uvlinesize = h->uvlinesize * 2;
+        linesize     = sl->mb_linesize = sl->linesize * 2;
+        uvlinesize   = sl->mb_uvlinesize = sl->uvlinesize * 2;
         block_offset = &h->block_offset[48];
         if (mb_y & 1) { // FIXME move out of this function?
-            dest_y  -= h->linesize * 15;
-            dest_cb -= h->uvlinesize * (block_h - 1);
-            dest_cr -= h->uvlinesize * (block_h - 1);
+            dest_y  -= sl->linesize * 15;
+            dest_cb -= sl->uvlinesize * (block_h - 1);
+            dest_cr -= sl->uvlinesize * (block_h - 1);
         }
         if (FRAME_MBAFF(h)) {
             int list;
@@ -94,8 +94,8 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
             }
         }
     } else {
-        linesize   = sl->mb_linesize   = h->linesize;
-        uvlinesize = sl->mb_uvlinesize = h->uvlinesize;
+        linesize   = sl->mb_linesize   = sl->linesize;
+        uvlinesize = sl->mb_uvlinesize = sl->uvlinesize;
         // dct_offset = s->linesize * 16;
     }
 
@@ -287,19 +287,19 @@ static av_noinline void FUNC(hl_decode_mb_444)(const H264Context *h, H264SliceCo
 
     for (p = 0; p < plane_count; p++) {
         dest[p] = h->cur_pic.f.data[p] +
-                  ((mb_x << PIXEL_SHIFT) + mb_y * h->linesize) * 16;
-        h->vdsp.prefetch(dest[p] + (sl->mb_x & 3) * 4 * h->linesize + (64 << PIXEL_SHIFT),
-                         h->linesize, 4);
+                  ((mb_x << PIXEL_SHIFT) + mb_y * sl->linesize) * 16;
+        h->vdsp.prefetch(dest[p] + (sl->mb_x & 3) * 4 * sl->linesize + (64 << PIXEL_SHIFT),
+                         sl->linesize, 4);
     }
 
     h->list_counts[mb_xy] = sl->list_count;
 
     if (!SIMPLE && MB_FIELD(sl)) {
-        linesize     = sl->mb_linesize = sl->mb_uvlinesize = h->linesize * 2;
+        linesize     = sl->mb_linesize = sl->mb_uvlinesize = sl->linesize * 2;
         block_offset = &h->block_offset[48];
         if (mb_y & 1) // FIXME move out of this function?
             for (p = 0; p < 3; p++)
-                dest[p] -= h->linesize * 15;
+                dest[p] -= sl->linesize * 15;
         if (FRAME_MBAFF(h)) {
             int list;
             for (list = 0; list < sl->list_count; list++) {
@@ -319,7 +319,7 @@ static av_noinline void FUNC(hl_decode_mb_444)(const H264Context *h, H264SliceCo
             }
         }
     } else {
-        linesize = sl->mb_linesize = sl->mb_uvlinesize = h->linesize;
+        linesize = sl->mb_linesize = sl->mb_uvlinesize = sl->linesize;
     }
 
     if (!SIMPLE && IS_INTRA_PCM(mb_type)) {
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index d0438fd..047dbae 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -228,9 +228,6 @@ static int alloc_picture(H264Context *h, H264Picture *pic)
     if (ret < 0)
         goto fail;
 
-    h->linesize   = pic->f.linesize[0];
-    h->uvlinesize = pic->f.linesize[1];
-
     if (h->avctx->hwaccel) {
         const AVHWAccel *hwaccel = h->avctx->hwaccel;
         av_assert0(!pic->hwaccel_picture_private);
@@ -458,11 +455,6 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
         }
         context_reinitialized = 1;
 
-        /* update linesize on resize. The decoder doesn't
-         * necessarily call h264_frame_start in the new thread */
-        h->linesize   = h1->linesize;
-        h->uvlinesize = h1->uvlinesize;
-
         /* copy block_offset since frame_start may not be called */
         memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset));
     }
@@ -644,17 +636,15 @@ static int h264_frame_start(H264Context *h)
     if (CONFIG_ERROR_RESILIENCE)
         ff_er_frame_start(&h->slice_ctx[0].er);
 
-    assert(h->linesize && h->uvlinesize);
-
     for (i = 0; i < 16; i++) {
-        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
-        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * pic->f.linesize[0] * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * pic->f.linesize[0] * ((scan8[i] - scan8[0]) >> 3);
     }
     for (i = 0; i < 16; i++) {
         h->block_offset[16 + i]      =
-        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * pic->f.linesize[1] * ((scan8[i] - scan8[0]) >> 3);
         h->block_offset[48 + 16 + i] =
-        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * pic->f.linesize[1] * ((scan8[i] - scan8[0]) >> 3);
     }
 
     /* Some macroblocks can be accessed before they're available in case
@@ -1976,26 +1966,26 @@ static void loop_filter(const H264Context *h, H264SliceContext *sl, int start_x,
                 sl->mb_x = mb_x;
                 sl->mb_y = mb_y;
                 dest_y  = h->cur_pic.f.data[0] +
-                          ((mb_x << pixel_shift) + mb_y * h->linesize) * 16;
+                          ((mb_x << pixel_shift) + mb_y * sl->linesize) * 16;
                 dest_cb = h->cur_pic.f.data[1] +
                           (mb_x << pixel_shift) * (8 << CHROMA444(h)) +
-                          mb_y * h->uvlinesize * block_h;
+                          mb_y * sl->uvlinesize * block_h;
                 dest_cr = h->cur_pic.f.data[2] +
                           (mb_x << pixel_shift) * (8 << CHROMA444(h)) +
-                          mb_y * h->uvlinesize * block_h;
+                          mb_y * sl->uvlinesize * block_h;
                 // FIXME simplify above
 
                 if (MB_FIELD(sl)) {
-                    linesize   = sl->mb_linesize   = h->linesize   * 2;
-                    uvlinesize = sl->mb_uvlinesize = h->uvlinesize * 2;
+                    linesize   = sl->mb_linesize   = sl->linesize   * 2;
+                    uvlinesize = sl->mb_uvlinesize = sl->uvlinesize * 2;
                     if (mb_y & 1) { // FIXME move out of this function?
-                        dest_y  -= h->linesize   * 15;
-                        dest_cb -= h->uvlinesize * (block_h - 1);
-                        dest_cr -= h->uvlinesize * (block_h - 1);
+                        dest_y  -= sl->linesize   * 15;
+                        dest_cb -= sl->uvlinesize * (block_h - 1);
+                        dest_cr -= sl->uvlinesize * (block_h - 1);
                     }
                 } else {
-                    linesize   = sl->mb_linesize   = h->linesize;
-                    uvlinesize = sl->mb_uvlinesize = h->uvlinesize;
+                    linesize   = sl->mb_linesize   = sl->linesize;
+                    uvlinesize = sl->mb_uvlinesize = sl->uvlinesize;
                 }
                 backup_mb_border(h, sl, dest_y, dest_cb, dest_cr, linesize,
                                  uvlinesize, 0);
@@ -2083,7 +2073,10 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
     int lf_x_start = sl->mb_x;
     int ret;
 
-    ret = alloc_scratch_buffers(sl, h->linesize);
+    sl->linesize   = h->cur_pic_ptr->f.linesize[0];
+    sl->uvlinesize = h->cur_pic_ptr->f.linesize[1];
+
+    ret = alloc_scratch_buffers(sl, sl->linesize);
     if (ret < 0)
         return ret;
 
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c
index d28b2d2..00e7c89 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -313,23 +313,23 @@ static inline void svq3_mc_dir_part(SVQ3Context *s,
     }
 
     /* form component predictions */
-    dest = h->cur_pic.f.data[0] + x + y * h->linesize;
-    src  = pic->f.data[0] + mx + my * h->linesize;
+    dest = h->cur_pic.f.data[0] + x + y * sl->linesize;
+    src  = pic->f.data[0] + mx + my * sl->linesize;
 
     if (emu) {
         h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src,
-                                 h->linesize, h->linesize,
+                                 sl->linesize, sl->linesize,
                                  width + 1, height + 1,
                                  mx, my, s->h_edge_pos, s->v_edge_pos);
         src = sl->edge_emu_buffer;
     }
     if (thirdpel)
         (avg ? s->tdsp.avg_tpel_pixels_tab
-             : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, h->linesize,
+             : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, sl->linesize,
                                                  width, height);
     else
         (avg ? s->hdsp.avg_pixels_tab
-             : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, h->linesize,
+             : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, sl->linesize,
                                                        height);
 
     if (!(h->flags & CODEC_FLAG_GRAY)) {
@@ -340,12 +340,12 @@ static inline void svq3_mc_dir_part(SVQ3Context *s,
         blocksize++;
 
         for (i = 1; i < 3; i++) {
-            dest = h->cur_pic.f.data[i] + (x >> 1) + (y >> 1) * h->uvlinesize;
-            src  = pic->f.data[i] + mx + my * h->uvlinesize;
+            dest = h->cur_pic.f.data[i] + (x >> 1) + (y >> 1) * sl->uvlinesize;
+            src  = pic->f.data[i] + mx + my * sl->uvlinesize;
 
             if (emu) {
                 h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src,
-                                         h->uvlinesize, h->uvlinesize,
+                                         sl->uvlinesize, sl->uvlinesize,
                                          width + 1, height + 1,
                                          mx, my, (s->h_edge_pos >> 1),
                                          s->v_edge_pos >> 1);
@@ -354,12 +354,12 @@ static inline void svq3_mc_dir_part(SVQ3Context *s,
             if (thirdpel)
                 (avg ? s->tdsp.avg_tpel_pixels_tab
                      : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src,
-                                                         h->uvlinesize,
+                                                         sl->uvlinesize,
                                                          width, height);
             else
                 (avg ? s->hdsp.avg_pixels_tab
                      : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src,
-                                                               h->uvlinesize,
+                                                               sl->uvlinesize,
                                                                height);
         }
     }
@@ -1101,8 +1101,8 @@ static int get_buffer(AVCodecContext *avctx, H264Picture *pic)
             return AVERROR(ENOMEM);
     }
 
-    h->linesize   = pic->f.linesize[0];
-    h->uvlinesize = pic->f.linesize[1];
+    sl->linesize   = pic->f.linesize[0];
+    sl->uvlinesize = pic->f.linesize[1];
 
     return 0;
 fail:
@@ -1162,14 +1162,14 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
         return ret;
 
     for (i = 0; i < 16; i++) {
-        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
-        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * sl->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * sl->linesize * ((scan8[i] - scan8[0]) >> 3);
     }
     for (i = 0; i < 16; i++) {
         h->block_offset[16 + i]      =
-        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * sl->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
         h->block_offset[48 + 16 + i] =
-        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * sl->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
     }
 
     if (h->pict_type != AV_PICTURE_TYPE_I) {



More information about the ffmpeg-cvslog mailing list