LCOV - code coverage report
Current view: top level - libavcodec - vc1_loopfilter.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 207 207 100.0 %
Date: 2017-12-12 11:08:38 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * VC-1 and WMV3 decoder
       3             :  * Copyright (c) 2011 Mashiat Sarker Shakkhar
       4             :  * Copyright (c) 2006-2007 Konstantin Shishkov
       5             :  * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
       6             :  *
       7             :  * This file is part of FFmpeg.
       8             :  *
       9             :  * FFmpeg is free software; you can redistribute it and/or
      10             :  * modify it under the terms of the GNU Lesser General Public
      11             :  * License as published by the Free Software Foundation; either
      12             :  * version 2.1 of the License, or (at your option) any later version.
      13             :  *
      14             :  * FFmpeg is distributed in the hope that it will be useful,
      15             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :  * Lesser General Public License for more details.
      18             :  *
      19             :  * You should have received a copy of the GNU Lesser General Public
      20             :  * License along with FFmpeg; if not, write to the Free Software
      21             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      22             :  */
      23             : 
      24             : /**
      25             :  * @file
      26             :  * VC-1 and WMV3 loopfilter
      27             :  */
      28             : 
      29             : #include "avcodec.h"
      30             : #include "mpegvideo.h"
      31             : #include "vc1.h"
      32             : #include "vc1dsp.h"
      33             : 
      34      102750 : void ff_vc1_loop_filter_iblk(VC1Context *v, int pq)
      35             : {
      36      102750 :     MpegEncContext *s = &v->s;
      37             :     int j;
      38      102750 :     if (!s->first_slice_line) {
      39       98090 :         v->vc1dsp.vc1_v_loop_filter16(s->dest[0], s->linesize, pq);
      40       98090 :         if (s->mb_x)
      41       96063 :             v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
      42       98090 :         v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq);
      43             :         if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
      44      294270 :         for (j = 0; j < 2; j++) {
      45      196180 :             v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1], s->uvlinesize, pq);
      46      196180 :             if (s->mb_x)
      47      192126 :                 v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
      48             :         }
      49             :     }
      50      102750 :     v->vc1dsp.vc1_v_loop_filter16(s->dest[0] + 8 * s->linesize, s->linesize, pq);
      51             : 
      52      102750 :     if (s->mb_y == s->end_mb_y - 1) {
      53        4660 :         if (s->mb_x) {
      54        4481 :             v->vc1dsp.vc1_h_loop_filter16(s->dest[0], s->linesize, pq);
      55             :             if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
      56        4481 :             v->vc1dsp.vc1_h_loop_filter8(s->dest[1], s->uvlinesize, pq);
      57        4481 :             v->vc1dsp.vc1_h_loop_filter8(s->dest[2], s->uvlinesize, pq);
      58             :             }
      59             :         }
      60        4660 :         v->vc1dsp.vc1_h_loop_filter16(s->dest[0] + 8, s->linesize, pq);
      61             :     }
      62      102750 : }
      63             : 
      64       12376 : void ff_vc1_loop_filter_iblk_delayed(VC1Context *v, int pq)
      65             : {
      66       12376 :     MpegEncContext *s = &v->s;
      67             :     int j;
      68             : 
      69             :     /* The loopfilter runs 1 row and 1 column behind the overlap filter, which
      70             :      * means it runs two rows/cols behind the decoding loop. */
      71       12376 :     if (!s->first_slice_line) {
      72       11814 :         if (s->mb_x) {
      73       11648 :             if (s->mb_y >= s->start_mb_y + 2) {
      74       11099 :                 v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq);
      75             : 
      76       11099 :                 if (s->mb_x >= 2)
      77       10946 :                     v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 16, s->linesize, pq);
      78       11099 :                 v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize - 8, s->linesize, pq);
      79             :                 if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
      80       33297 :                 for (j = 0; j < 2; j++) {
      81       22198 :                     v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
      82       22198 :                     if (s->mb_x >= 2) {
      83       21892 :                         v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize - 8, s->uvlinesize, pq);
      84             :                     }
      85             :                 }
      86             :             }
      87       11648 :             v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize - 16, s->linesize, pq);
      88             :         }
      89             : 
      90       11814 :         if (s->mb_x == s->mb_width - 1) {
      91         166 :             if (s->mb_y >= s->start_mb_y + 2) {
      92         153 :                 v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
      93             : 
      94         153 :                 if (s->mb_x)
      95         153 :                     v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize, s->linesize, pq);
      96         153 :                 v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize + 8, s->linesize, pq);
      97             :                 if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
      98         459 :                 for (j = 0; j < 2; j++) {
      99         306 :                     v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
     100         306 :                     if (s->mb_x >= 2) {
     101         306 :                         v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 * s->uvlinesize, s->uvlinesize, pq);
     102             :                     }
     103             :                 }
     104             :             }
     105         166 :             v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize, s->linesize, pq);
     106             :         }
     107             : 
     108       11814 :         if (s->mb_y == s->end_mb_y) {
     109         562 :             if (s->mb_x) {
     110         549 :                 if (s->mb_x >= 2)
     111         536 :                     v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 16, s->linesize, pq);
     112         549 :                 v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize - 8, s->linesize, pq);
     113         549 :                 if (s->mb_x >= 2 && (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))) {
     114        1608 :                     for (j = 0; j < 2; j++) {
     115        1072 :                         v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize - 8, s->uvlinesize, pq);
     116             :                     }
     117             :                 }
     118             :             }
     119             : 
     120         562 :             if (s->mb_x == s->mb_width - 1) {
     121          13 :                 if (s->mb_x)
     122          13 :                     v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize, s->linesize, pq);
     123          13 :                 v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8, s->linesize, pq);
     124          13 :                 if (s->mb_x && (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))) {
     125          39 :                     for (j = 0; j < 2; j++) {
     126          26 :                         v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 * s->uvlinesize, s->uvlinesize, pq);
     127             :                     }
     128             :                 }
     129             :             }
     130             :         }
     131             :     }
     132       12376 : }
     133             : 
     134       12114 : void ff_vc1_smooth_overlap_filter_iblk(VC1Context *v)
     135             : {
     136       12114 :     MpegEncContext *s = &v->s;
     137             :     int mb_pos;
     138             : 
     139       12114 :     if (v->condover == CONDOVER_NONE)
     140       11715 :         return;
     141             : 
     142         399 :     mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     143             : 
     144             :     /* Within a MB, the horizontal overlap always runs before the vertical.
     145             :      * To accomplish that, we run the H on left and internal borders of the
     146             :      * currently decoded MB. Then, we wait for the next overlap iteration
     147             :      * to do H overlap on the right edge of this MB, before moving over and
     148             :      * running the V overlap. Therefore, the V overlap makes us trail by one
     149             :      * MB col and the H overlap filter makes us trail by one MB row. This
     150             :      * is reflected in the time at which we run the put_pixels loop. */
     151         399 :     if (v->condover == CONDOVER_ALL || v->pq >= 9 || v->over_flags_plane[mb_pos]) {
     152         488 :         if (s->mb_x && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
     153         236 :                         v->over_flags_plane[mb_pos - 1])) {
     154         420 :             v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][1],
     155         210 :                                       v->block[v->cur_blk_idx][0]);
     156         420 :             v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][3],
     157         210 :                                       v->block[v->cur_blk_idx][2]);
     158             :             if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
     159         420 :                 v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][4],
     160         210 :                                           v->block[v->cur_blk_idx][4]);
     161         420 :                 v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][5],
     162         210 :                                           v->block[v->cur_blk_idx][5]);
     163             :             }
     164             :         }
     165         504 :         v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][0],
     166         252 :                                   v->block[v->cur_blk_idx][1]);
     167         504 :         v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][2],
     168         252 :                                   v->block[v->cur_blk_idx][3]);
     169             : 
     170         252 :         if (s->mb_x == s->mb_width - 1) {
     171          32 :             if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
     172          15 :                                          v->over_flags_plane[mb_pos - s->mb_stride])) {
     173          26 :                 v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][2],
     174          13 :                                           v->block[v->cur_blk_idx][0]);
     175          26 :                 v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][3],
     176          13 :                                           v->block[v->cur_blk_idx][1]);
     177             :                 if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
     178          26 :                     v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][4],
     179          13 :                                               v->block[v->cur_blk_idx][4]);
     180          26 :                     v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][5],
     181          13 :                                               v->block[v->cur_blk_idx][5]);
     182             :                 }
     183             :             }
     184          34 :             v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][0],
     185          17 :                                       v->block[v->cur_blk_idx][2]);
     186          34 :             v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][1],
     187          17 :                                       v->block[v->cur_blk_idx][3]);
     188             :         }
     189             :     }
     190         399 :     if (s->mb_x && (v->condover == CONDOVER_ALL || v->over_flags_plane[mb_pos - 1])) {
     191         442 :         if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
     192         207 :                                      v->over_flags_plane[mb_pos - s->mb_stride - 1])) {
     193         336 :             v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][2],
     194         168 :                                       v->block[v->left_blk_idx][0]);
     195         336 :             v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][3],
     196         168 :                                       v->block[v->left_blk_idx][1]);
     197             :             if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
     198         336 :                 v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][4],
     199         168 :                                           v->block[v->left_blk_idx][4]);
     200         336 :                 v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][5],
     201         168 :                                           v->block[v->left_blk_idx][5]);
     202             :             }
     203             :         }
     204         470 :         v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][0],
     205         235 :                                   v->block[v->left_blk_idx][2]);
     206         470 :         v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][1],
     207         235 :                                   v->block[v->left_blk_idx][3]);
     208             :     }
     209             : }
     210             : 
     211      559824 : static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_num)
     212             : {
     213      559824 :     MpegEncContext *s  = &v->s;
     214      559824 :     int mb_cbp         = v->cbp[s->mb_x - s->mb_stride],
     215      559824 :         block_cbp      = mb_cbp      >> (block_num * 4), bottom_cbp,
     216      559824 :         mb_is_intra    = v->is_intra[s->mb_x - s->mb_stride],
     217      559824 :         block_is_intra = mb_is_intra >> block_num, bottom_is_intra;
     218      559824 :     int idx, linesize  = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
     219             :     uint8_t *dst;
     220             : 
     221      559824 :     if (block_num > 3) {
     222      186608 :         dst      = s->dest[block_num - 3];
     223             :     } else {
     224      373216 :         dst      = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 8) * linesize;
     225             :     }
     226      559824 :     if (s->mb_y != s->end_mb_y || block_num < 2) {
     227             :         int16_t (*mv)[2];
     228             :         int mv_stride;
     229             : 
     230      433360 :         if (block_num > 3) {
     231      123376 :             bottom_cbp      = v->cbp[s->mb_x]      >> (block_num * 4);
     232      123376 :             bottom_is_intra = v->is_intra[s->mb_x] >> block_num;
     233      123376 :             mv              = &v->luma_mv[s->mb_x - s->mb_stride];
     234      123376 :             mv_stride       = s->mb_stride;
     235             :         } else {
     236      496592 :             bottom_cbp      = (block_num < 2) ? (mb_cbp               >> ((block_num + 2) * 4))
     237      496592 :                                               : (v->cbp[s->mb_x]      >> ((block_num - 2) * 4));
     238      496592 :             bottom_is_intra = (block_num < 2) ? (mb_is_intra          >> (block_num + 2))
     239      496592 :                                               : (v->is_intra[s->mb_x] >> (block_num - 2));
     240      309984 :             mv_stride       = s->b8_stride;
     241      309984 :             mv              = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
     242             :         }
     243             : 
     244      736532 :         if (bottom_is_intra & 1 || block_is_intra & 1 ||
     245      501516 :             mv[0][0] != mv[mv_stride][0] || mv[0][1] != mv[mv_stride][1]) {
     246      263100 :             v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
     247             :         } else {
     248      170260 :             idx = ((bottom_cbp >> 2) | block_cbp) & 3;
     249      170260 :             if (idx == 3) {
     250       58508 :                 v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
     251      111752 :             } else if (idx) {
     252        9042 :                 if (idx == 1)
     253        4520 :                     v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
     254             :                 else
     255        4522 :                     v->vc1dsp.vc1_v_loop_filter4(dst,     linesize, v->pq);
     256             :             }
     257             :         }
     258             :     }
     259             : 
     260      559824 :     dst -= 4 * linesize;
     261      559824 :     ttblk = (v->ttblk[s->mb_x - s->mb_stride] >> (block_num * 4)) & 0xF;
     262      559824 :     if (ttblk == TT_4X4 || ttblk == TT_8X4) {
     263       52536 :         idx = (block_cbp | (block_cbp >> 2)) & 3;
     264       52536 :         if (idx == 3) {
     265       43391 :             v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
     266        9145 :         } else if (idx) {
     267        9145 :             if (idx == 1)
     268        4622 :                 v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
     269             :             else
     270        4523 :                 v->vc1dsp.vc1_v_loop_filter4(dst,     linesize, v->pq);
     271             :         }
     272             :     }
     273      559824 : }
     274             : 
     275      559824 : static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_num)
     276             : {
     277      559824 :     MpegEncContext *s  = &v->s;
     278      559824 :     int mb_cbp         = v->cbp[s->mb_x - 1 - s->mb_stride],
     279      559824 :         block_cbp      = mb_cbp      >> (block_num * 4), right_cbp,
     280      559824 :         mb_is_intra    = v->is_intra[s->mb_x - 1 - s->mb_stride],
     281      559824 :         block_is_intra = mb_is_intra >> block_num, right_is_intra;
     282      559824 :     int idx, linesize  = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
     283             :     uint8_t *dst;
     284             : 
     285      559824 :     if (block_num > 3) {
     286      186608 :         dst = s->dest[block_num - 3] - 8 * linesize;
     287             :     } else {
     288      373216 :         dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 16) * linesize - 8;
     289             :     }
     290             : 
     291      559824 :     if (s->mb_x != s->mb_width || !(block_num & 5)) {
     292             :         int16_t (*mv)[2];
     293             : 
     294      547060 :         if (block_num > 3) {
     295      180226 :             right_cbp      = v->cbp[s->mb_x - s->mb_stride] >> (block_num * 4);
     296      180226 :             right_is_intra = v->is_intra[s->mb_x - s->mb_stride] >> block_num;
     297      180226 :             mv             = &v->luma_mv[s->mb_x - s->mb_stride - 1];
     298             :         } else {
     299      913894 :             right_cbp      = (block_num & 1) ? (v->cbp[s->mb_x - s->mb_stride]      >> ((block_num - 1) * 4))
     300      547060 :                                              : (mb_cbp                              >> ((block_num + 1) * 4));
     301      913894 :             right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> (block_num - 1))
     302      547060 :                                              : (mb_is_intra                         >> (block_num + 1));
     303      366834 :             mv             = &s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
     304             :         }
     305      547060 :         if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1]) {
     306      356279 :             v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
     307             :         } else {
     308      190781 :             idx = ((right_cbp >> 1) | block_cbp) & 5; // FIXME check
     309      190781 :             if (idx == 5) {
     310       60704 :                 v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
     311      130077 :             } else if (idx) {
     312        9708 :                 if (idx == 1)
     313        5011 :                     v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize, linesize, v->pq);
     314             :                 else
     315        4697 :                     v->vc1dsp.vc1_h_loop_filter4(dst,                linesize, v->pq);
     316             :             }
     317             :         }
     318             :     }
     319             : 
     320      559824 :     dst -= 4;
     321      559824 :     ttblk = (v->ttblk[s->mb_x - s->mb_stride - 1] >> (block_num * 4)) & 0xf;
     322      559824 :     if (ttblk == TT_4X4 || ttblk == TT_4X8) {
     323       53954 :         idx = (block_cbp | (block_cbp >> 1)) & 5;
     324       53954 :         if (idx == 5) {
     325       44398 :             v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
     326        9556 :         } else if (idx) {
     327        9556 :             if (idx == 1)
     328        4960 :                 v->vc1dsp.vc1_h_loop_filter4(dst + linesize * 4, linesize, v->pq);
     329             :             else
     330        4596 :                 v->vc1dsp.vc1_h_loop_filter4(dst,                linesize, v->pq);
     331             :         }
     332             :     }
     333      559824 : }
     334             : 
     335       93304 : void ff_vc1_apply_p_loop_filter(VC1Context *v)
     336             : {
     337       93304 :     MpegEncContext *s = &v->s;
     338             :     int i;
     339       93304 :     int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
     340             : 
     341      653128 :     for (i = 0; i < block_count; i++) {
     342      559824 :         vc1_apply_p_v_loop_filter(v, i);
     343             :     }
     344             : 
     345             :     /* V always precedes H, therefore we run H one MB before V;
     346             :      * at the end of a row, we catch up to complete the row */
     347       93304 :     if (s->mb_x) {
     348      630791 :         for (i = 0; i < block_count; i++) {
     349      540678 :             vc1_apply_p_h_loop_filter(v, i);
     350             :         }
     351       90113 :         if (s->mb_x == s->mb_width - 1) {
     352        3191 :             s->mb_x++;
     353        3191 :             ff_update_block_index(s);
     354       22337 :             for (i = 0; i < block_count; i++) {
     355       19146 :                 vc1_apply_p_h_loop_filter(v, i);
     356             :             }
     357             :         }
     358             :     }
     359       93304 : }

Generated by: LCOV version 1.13