Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
  3.  * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22. /**
  23.  * @file
  24.  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder
  25.  * @author Stefan Gehrer <stefan.gehrer@gmx.de>
  26.  */
  27.  
  28. #include "avcodec.h"
  29. #include "get_bits.h"
  30. #include "golomb.h"
  31. #include "h264chroma.h"
  32. #include "idctdsp.h"
  33. #include "internal.h"
  34. #include "mathops.h"
  35. #include "qpeldsp.h"
  36. #include "cavs.h"
  37.  
  38. static const uint8_t alpha_tab[64] = {
  39.      0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  3,  3,
  40.      4,  4,  5,  5,  6,  7,  8,  9, 10, 11, 12, 13, 15, 16, 18, 20,
  41.     22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
  42.     46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
  43. };
  44.  
  45. static const uint8_t beta_tab[64] = {
  46.      0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,
  47.      2,  2,  3,  3,  3,  3,  4,  4,  4,  4,  5,  5,  5,  5,  6,  6,
  48.      6,  7,  7,  7,  8,  8,  8,  9,  9, 10, 10, 11, 11, 12, 13, 14,
  49.     15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
  50. };
  51.  
  52. static const uint8_t tc_tab[64] = {
  53.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  54.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
  55.     2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
  56.     5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
  57. };
  58.  
  59. /** mark block as unavailable, i.e. out of picture
  60.  *  or not yet decoded */
  61. static const cavs_vector un_mv = { 0, 0, 1, NOT_AVAIL };
  62.  
  63. static const int8_t left_modifier_l[8] = {  0, -1,  6, -1, -1, 7, 6, 7 };
  64. static const int8_t top_modifier_l[8]  = { -1,  1,  5, -1, -1, 5, 7, 7 };
  65. static const int8_t left_modifier_c[7] = {  5, -1,  2, -1,  6, 5, 6 };
  66. static const int8_t top_modifier_c[7]  = {  4,  1, -1, -1,  4, 6, 6 };
  67.  
  68. /*****************************************************************************
  69.  *
  70.  * in-loop deblocking filter
  71.  *
  72.  ****************************************************************************/
  73.  
  74. static inline int get_bs(cavs_vector *mvP, cavs_vector *mvQ, int b)
  75. {
  76.     if ((mvP->ref == REF_INTRA) || (mvQ->ref == REF_INTRA))
  77.         return 2;
  78.     if((abs(mvP->x - mvQ->x) >= 4) ||
  79.        (abs(mvP->y - mvQ->y) >= 4) ||
  80.        (mvP->ref != mvQ->ref))
  81.         return 1;
  82.     if (b) {
  83.         mvP += MV_BWD_OFFS;
  84.         mvQ += MV_BWD_OFFS;
  85.         if((abs(mvP->x - mvQ->x) >= 4) ||
  86.            (abs(mvP->y - mvQ->y) >= 4) ||
  87.            (mvP->ref != mvQ->ref))
  88.             return 1;
  89.     }
  90.     return 0;
  91. }
  92.  
  93. #define SET_PARAMS                                                \
  94.     alpha = alpha_tab[av_clip_uintp2(qp_avg + h->alpha_offset, 6)];  \
  95.     beta  =  beta_tab[av_clip_uintp2(qp_avg + h->beta_offset,  6)];  \
  96.     tc    =    tc_tab[av_clip_uintp2(qp_avg + h->alpha_offset, 6)];
  97.  
  98. /**
  99.  * in-loop deblocking filter for a single macroblock
  100.  *
  101.  * boundary strength (bs) mapping:
  102.  *
  103.  * --4---5--
  104.  * 0   2   |
  105.  * | 6 | 7 |
  106.  * 1   3   |
  107.  * ---------
  108.  *
  109.  */
  110. void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type)
  111. {
  112.     uint8_t bs[8];
  113.     int qp_avg, alpha, beta, tc;
  114.     int i;
  115.  
  116.     /* save un-deblocked lines */
  117.     h->topleft_border_y = h->top_border_y[h->mbx * 16 + 15];
  118.     h->topleft_border_u = h->top_border_u[h->mbx * 10 + 8];
  119.     h->topleft_border_v = h->top_border_v[h->mbx * 10 + 8];
  120.     memcpy(&h->top_border_y[h->mbx * 16],     h->cy + 15 * h->l_stride, 16);
  121.     memcpy(&h->top_border_u[h->mbx * 10 + 1], h->cu +  7 * h->c_stride, 8);
  122.     memcpy(&h->top_border_v[h->mbx * 10 + 1], h->cv +  7 * h->c_stride, 8);
  123.     for (i = 0; i < 8; i++) {
  124.         h->left_border_y[i * 2 + 1] = *(h->cy + 15 + (i * 2 + 0) * h->l_stride);
  125.         h->left_border_y[i * 2 + 2] = *(h->cy + 15 + (i * 2 + 1) * h->l_stride);
  126.         h->left_border_u[i + 1]     = *(h->cu + 7  +  i          * h->c_stride);
  127.         h->left_border_v[i + 1]     = *(h->cv + 7  +  i          * h->c_stride);
  128.     }
  129.     if (!h->loop_filter_disable) {
  130.         /* determine bs */
  131.         if (mb_type == I_8X8)
  132.             memset(bs, 2, 8);
  133.         else {
  134.             memset(bs, 0, 8);
  135.             if (ff_cavs_partition_flags[mb_type] & SPLITV) {
  136.                 bs[2] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X1], mb_type > P_8X8);
  137.                 bs[3] = get_bs(&h->mv[MV_FWD_X2], &h->mv[MV_FWD_X3], mb_type > P_8X8);
  138.             }
  139.             if (ff_cavs_partition_flags[mb_type] & SPLITH) {
  140.                 bs[6] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X2], mb_type > P_8X8);
  141.                 bs[7] = get_bs(&h->mv[MV_FWD_X1], &h->mv[MV_FWD_X3], mb_type > P_8X8);
  142.             }
  143.             bs[0] = get_bs(&h->mv[MV_FWD_A1], &h->mv[MV_FWD_X0], mb_type > P_8X8);
  144.             bs[1] = get_bs(&h->mv[MV_FWD_A3], &h->mv[MV_FWD_X2], mb_type > P_8X8);
  145.             bs[4] = get_bs(&h->mv[MV_FWD_B2], &h->mv[MV_FWD_X0], mb_type > P_8X8);
  146.             bs[5] = get_bs(&h->mv[MV_FWD_B3], &h->mv[MV_FWD_X1], mb_type > P_8X8);
  147.         }
  148.         if (AV_RN64(bs)) {
  149.             if (h->flags & A_AVAIL) {
  150.                 qp_avg = (h->qp + h->left_qp + 1) >> 1;
  151.                 SET_PARAMS;
  152.                 h->cdsp.cavs_filter_lv(h->cy, h->l_stride, alpha, beta, tc, bs[0], bs[1]);
  153.                 qp_avg = (ff_cavs_chroma_qp[h->qp] + ff_cavs_chroma_qp[h->left_qp] + 1) >> 1;
  154.                 SET_PARAMS;
  155.                 h->cdsp.cavs_filter_cv(h->cu, h->c_stride, alpha, beta, tc, bs[0], bs[1]);
  156.                 h->cdsp.cavs_filter_cv(h->cv, h->c_stride, alpha, beta, tc, bs[0], bs[1]);
  157.             }
  158.             qp_avg = h->qp;
  159.             SET_PARAMS;
  160.             h->cdsp.cavs_filter_lv(h->cy + 8,               h->l_stride, alpha, beta, tc, bs[2], bs[3]);
  161.             h->cdsp.cavs_filter_lh(h->cy + 8 * h->l_stride, h->l_stride, alpha, beta, tc, bs[6], bs[7]);
  162.  
  163.             if (h->flags & B_AVAIL) {
  164.                 qp_avg = (h->qp + h->top_qp[h->mbx] + 1) >> 1;
  165.                 SET_PARAMS;
  166.                 h->cdsp.cavs_filter_lh(h->cy, h->l_stride, alpha, beta, tc, bs[4], bs[5]);
  167.                 qp_avg = (ff_cavs_chroma_qp[h->qp] + ff_cavs_chroma_qp[h->top_qp[h->mbx]] + 1) >> 1;
  168.                 SET_PARAMS;
  169.                 h->cdsp.cavs_filter_ch(h->cu, h->c_stride, alpha, beta, tc, bs[4], bs[5]);
  170.                 h->cdsp.cavs_filter_ch(h->cv, h->c_stride, alpha, beta, tc, bs[4], bs[5]);
  171.             }
  172.         }
  173.     }
  174.     h->left_qp        = h->qp;
  175.     h->top_qp[h->mbx] = h->qp;
  176. }
  177.  
  178. #undef SET_PARAMS
  179.  
  180. /*****************************************************************************
  181.  *
  182.  * spatial intra prediction
  183.  *
  184.  ****************************************************************************/
  185.  
  186. void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top,
  187.                                   uint8_t **left, int block)
  188. {
  189.     int i;
  190.  
  191.     switch (block) {
  192.     case 0:
  193.         *left               = h->left_border_y;
  194.         h->left_border_y[0] = h->left_border_y[1];
  195.         memset(&h->left_border_y[17], h->left_border_y[16], 9);
  196.         memcpy(&top[1], &h->top_border_y[h->mbx * 16], 16);
  197.         top[17] = top[16];
  198.         top[0]  = top[1];
  199.         if ((h->flags & A_AVAIL) && (h->flags & B_AVAIL))
  200.             h->left_border_y[0] = top[0] = h->topleft_border_y;
  201.         break;
  202.     case 1:
  203.         *left = h->intern_border_y;
  204.         for (i = 0; i < 8; i++)
  205.             h->intern_border_y[i + 1] = *(h->cy + 7 + i * h->l_stride);
  206.         memset(&h->intern_border_y[9], h->intern_border_y[8], 9);
  207.         h->intern_border_y[0] = h->intern_border_y[1];
  208.         memcpy(&top[1], &h->top_border_y[h->mbx * 16 + 8], 8);
  209.         if (h->flags & C_AVAIL)
  210.             memcpy(&top[9], &h->top_border_y[(h->mbx + 1) * 16], 8);
  211.         else
  212.             memset(&top[9], top[8], 9);
  213.         top[17] = top[16];
  214.         top[0]  = top[1];
  215.         if (h->flags & B_AVAIL)
  216.             h->intern_border_y[0] = top[0] = h->top_border_y[h->mbx * 16 + 7];
  217.         break;
  218.     case 2:
  219.         *left = &h->left_border_y[8];
  220.         memcpy(&top[1], h->cy + 7 * h->l_stride, 16);
  221.         top[17] = top[16];
  222.         top[0]  = top[1];
  223.         if (h->flags & A_AVAIL)
  224.             top[0] = h->left_border_y[8];
  225.         break;
  226.     case 3:
  227.         *left = &h->intern_border_y[8];
  228.         for (i = 0; i < 8; i++)
  229.             h->intern_border_y[i + 9] = *(h->cy + 7 + (i + 8) * h->l_stride);
  230.         memset(&h->intern_border_y[17], h->intern_border_y[16], 9);
  231.         memcpy(&top[0], h->cy + 7 + 7 * h->l_stride, 9);
  232.         memset(&top[9], top[8], 9);
  233.         break;
  234.     }
  235. }
  236.  
  237. void ff_cavs_load_intra_pred_chroma(AVSContext *h)
  238. {
  239.     /* extend borders by one pixel */
  240.     h->left_border_u[9]              = h->left_border_u[8];
  241.     h->left_border_v[9]              = h->left_border_v[8];
  242.     if(h->flags & C_AVAIL) {
  243.         h->top_border_u[h->mbx*10 + 9] = h->top_border_u[h->mbx*10 + 11];
  244.         h->top_border_v[h->mbx*10 + 9] = h->top_border_v[h->mbx*10 + 11];
  245.     } else {
  246.         h->top_border_u[h->mbx * 10 + 9] = h->top_border_u[h->mbx * 10 + 8];
  247.         h->top_border_v[h->mbx * 10 + 9] = h->top_border_v[h->mbx * 10 + 8];
  248.     }
  249.     if((h->flags & A_AVAIL) && (h->flags & B_AVAIL)) {
  250.         h->top_border_u[h->mbx * 10] = h->left_border_u[0] = h->topleft_border_u;
  251.         h->top_border_v[h->mbx * 10] = h->left_border_v[0] = h->topleft_border_v;
  252.     } else {
  253.         h->left_border_u[0]          = h->left_border_u[1];
  254.         h->left_border_v[0]          = h->left_border_v[1];
  255.         h->top_border_u[h->mbx * 10] = h->top_border_u[h->mbx * 10 + 1];
  256.         h->top_border_v[h->mbx * 10] = h->top_border_v[h->mbx * 10 + 1];
  257.     }
  258. }
  259.  
  260. static void intra_pred_vert(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
  261. {
  262.     int y;
  263.     uint64_t a = AV_RN64(&top[1]);
  264.     for (y = 0; y < 8; y++)
  265.         *((uint64_t *)(d + y * stride)) = a;
  266. }
  267.  
  268. static void intra_pred_horiz(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
  269. {
  270.     int y;
  271.     uint64_t a;
  272.     for (y = 0; y < 8; y++) {
  273.         a = left[y + 1] * 0x0101010101010101ULL;
  274.         *((uint64_t *)(d + y * stride)) = a;
  275.     }
  276. }
  277.  
  278. static void intra_pred_dc_128(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
  279. {
  280.     int y;
  281.     uint64_t a = 0x8080808080808080ULL;
  282.     for (y = 0; y < 8; y++)
  283.         *((uint64_t *)(d + y * stride)) = a;
  284. }
  285.  
  286. static void intra_pred_plane(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
  287. {
  288.     int x, y, ia;
  289.     int ih = 0;
  290.     int iv = 0;
  291.     const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
  292.  
  293.     for (x = 0; x < 4; x++) {
  294.         ih += (x + 1) *  (top[5 + x] -  top[3 - x]);
  295.         iv += (x + 1) * (left[5 + x] - left[3 - x]);
  296.     }
  297.     ia = (top[8] + left[8]) << 4;
  298.     ih = (17 * ih + 16) >> 5;
  299.     iv = (17 * iv + 16) >> 5;
  300.     for (y = 0; y < 8; y++)
  301.         for (x = 0; x < 8; x++)
  302.             d[y * stride + x] = cm[(ia + (x - 3) * ih + (y - 3) * iv + 16) >> 5];
  303. }
  304.  
  305. #define LOWPASS(ARRAY, INDEX)                                           \
  306.     ((ARRAY[(INDEX) - 1] + 2 * ARRAY[(INDEX)] + ARRAY[(INDEX) + 1] + 2) >> 2)
  307.  
  308. static void intra_pred_lp(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
  309. {
  310.     int x, y;
  311.     for (y = 0; y < 8; y++)
  312.         for (x = 0; x < 8; x++)
  313.             d[y * stride + x] = (LOWPASS(top, x + 1) + LOWPASS(left, y + 1)) >> 1;
  314. }
  315.  
  316. static void intra_pred_down_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
  317. {
  318.     int x, y;
  319.     for (y = 0; y < 8; y++)
  320.         for (x = 0; x < 8; x++)
  321.             d[y * stride + x] = (LOWPASS(top, x + y + 2) + LOWPASS(left, x + y + 2)) >> 1;
  322. }
  323.  
  324. static void intra_pred_down_right(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
  325. {
  326.     int x, y;
  327.     for (y = 0; y < 8; y++)
  328.         for (x = 0; x < 8; x++)
  329.             if (x == y)
  330.                 d[y * stride + x] = (left[1] + 2 * top[0] + top[1] + 2) >> 2;
  331.             else if (x > y)
  332.                 d[y * stride + x] = LOWPASS(top, x - y);
  333.             else
  334.                 d[y * stride + x] = LOWPASS(left, y - x);
  335. }
  336.  
  337. static void intra_pred_lp_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
  338. {
  339.     int x, y;
  340.     for (y = 0; y < 8; y++)
  341.         for (x = 0; x < 8; x++)
  342.             d[y * stride + x] = LOWPASS(left, y + 1);
  343. }
  344.  
  345. static void intra_pred_lp_top(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
  346. {
  347.     int x, y;
  348.     for (y = 0; y < 8; y++)
  349.         for (x = 0; x < 8; x++)
  350.             d[y * stride + x] = LOWPASS(top, x + 1);
  351. }
  352.  
  353. #undef LOWPASS
  354.  
  355. static inline void modify_pred(const int8_t *mod_table, int *mode)
  356. {
  357.     *mode = mod_table[*mode];
  358.     if (*mode < 0) {
  359.         av_log(NULL, AV_LOG_ERROR, "Illegal intra prediction mode\n");
  360.         *mode = 0;
  361.     }
  362. }
  363.  
  364. void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv)
  365. {
  366.     /* save pred modes before they get modified */
  367.     h->pred_mode_Y[3]             = h->pred_mode_Y[5];
  368.     h->pred_mode_Y[6]             = h->pred_mode_Y[8];
  369.     h->top_pred_Y[h->mbx * 2 + 0] = h->pred_mode_Y[7];
  370.     h->top_pred_Y[h->mbx * 2 + 1] = h->pred_mode_Y[8];
  371.  
  372.     /* modify pred modes according to availability of neighbour samples */
  373.     if (!(h->flags & A_AVAIL)) {
  374.         modify_pred(left_modifier_l, &h->pred_mode_Y[4]);
  375.         modify_pred(left_modifier_l, &h->pred_mode_Y[7]);
  376.         modify_pred(left_modifier_c, pred_mode_uv);
  377.     }
  378.     if (!(h->flags & B_AVAIL)) {
  379.         modify_pred(top_modifier_l, &h->pred_mode_Y[4]);
  380.         modify_pred(top_modifier_l, &h->pred_mode_Y[5]);
  381.         modify_pred(top_modifier_c, pred_mode_uv);
  382.     }
  383. }
  384.  
  385. /*****************************************************************************
  386.  *
  387.  * motion compensation
  388.  *
  389.  ****************************************************************************/
  390.  
  391. static inline void mc_dir_part(AVSContext *h, AVFrame *pic, int chroma_height,
  392.                                int delta, int list, uint8_t *dest_y,
  393.                                uint8_t *dest_cb, uint8_t *dest_cr,
  394.                                int src_x_offset, int src_y_offset,
  395.                                qpel_mc_func *qpix_op,
  396.                                h264_chroma_mc_func chroma_op, cavs_vector *mv)
  397. {
  398.     const int mx         = mv->x + src_x_offset * 8;
  399.     const int my         = mv->y + src_y_offset * 8;
  400.     const int luma_xy    = (mx & 3) + ((my & 3) << 2);
  401.     uint8_t *src_y       = pic->data[0] + (mx >> 2) + (my >> 2) * h->l_stride;
  402.     uint8_t *src_cb      = pic->data[1] + (mx >> 3) + (my >> 3) * h->c_stride;
  403.     uint8_t *src_cr      = pic->data[2] + (mx >> 3) + (my >> 3) * h->c_stride;
  404.     int extra_width      = 0;
  405.     int extra_height     = extra_width;
  406.     const int full_mx    = mx >> 2;
  407.     const int full_my    = my >> 2;
  408.     const int pic_width  = 16 * h->mb_width;
  409.     const int pic_height = 16 * h->mb_height;
  410.     int emu = 0;
  411.  
  412.     if (!pic->data[0])
  413.         return;
  414.     if (mx & 7)
  415.         extra_width  -= 3;
  416.     if (my & 7)
  417.         extra_height -= 3;
  418.  
  419.     if (full_mx < 0 - extra_width ||
  420.         full_my < 0 - extra_height ||
  421.         full_mx + 16 /* FIXME */ > pic_width + extra_width ||
  422.         full_my + 16 /* FIXME */ > pic_height + extra_height) {
  423.         h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
  424.                                  src_y - 2 - 2 * h->l_stride,
  425.                                  h->l_stride, h->l_stride,
  426.                                  16 + 5, 16 + 5 /* FIXME */,
  427.                                  full_mx - 2, full_my - 2,
  428.                                  pic_width, pic_height);
  429.         src_y = h->edge_emu_buffer + 2 + 2 * h->l_stride;
  430.         emu   = 1;
  431.     }
  432.  
  433.     // FIXME try variable height perhaps?
  434.     qpix_op[luma_xy](dest_y, src_y, h->l_stride);
  435.  
  436.     if (emu) {
  437.         h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb,
  438.                                  h->c_stride, h->c_stride,
  439.                                  9, 9 /* FIXME */,
  440.                                  mx >> 3, my >> 3,
  441.                                  pic_width >> 1, pic_height >> 1);
  442.         src_cb = h->edge_emu_buffer;
  443.     }
  444.     chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx & 7, my & 7);
  445.  
  446.     if (emu) {
  447.         h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr,
  448.                                  h->c_stride, h->c_stride,
  449.                                  9, 9 /* FIXME */,
  450.                                  mx >> 3, my >> 3,
  451.                                  pic_width >> 1, pic_height >> 1);
  452.         src_cr = h->edge_emu_buffer;
  453.     }
  454.     chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx & 7, my & 7);
  455. }
  456.  
  457. static inline void mc_part_std(AVSContext *h, int chroma_height, int delta,
  458.                                uint8_t *dest_y,
  459.                                uint8_t *dest_cb,
  460.                                uint8_t *dest_cr,
  461.                                int x_offset, int y_offset,
  462.                                qpel_mc_func *qpix_put,
  463.                                h264_chroma_mc_func chroma_put,
  464.                                qpel_mc_func *qpix_avg,
  465.                                h264_chroma_mc_func chroma_avg,
  466.                                cavs_vector *mv)
  467. {
  468.     qpel_mc_func *qpix_op =  qpix_put;
  469.     h264_chroma_mc_func chroma_op = chroma_put;
  470.  
  471.     dest_y   += x_offset * 2 + y_offset * h->l_stride * 2;
  472.     dest_cb  += x_offset     + y_offset * h->c_stride;
  473.     dest_cr  += x_offset     + y_offset * h->c_stride;
  474.     x_offset += 8 * h->mbx;
  475.     y_offset += 8 * h->mby;
  476.  
  477.     if (mv->ref >= 0) {
  478.         AVFrame *ref = h->DPB[mv->ref].f;
  479.         mc_dir_part(h, ref, chroma_height, delta, 0,
  480.                     dest_y, dest_cb, dest_cr, x_offset, y_offset,
  481.                     qpix_op, chroma_op, mv);
  482.  
  483.         qpix_op   = qpix_avg;
  484.         chroma_op = chroma_avg;
  485.     }
  486.  
  487.     if ((mv + MV_BWD_OFFS)->ref >= 0) {
  488.         AVFrame *ref = h->DPB[0].f;
  489.         mc_dir_part(h, ref, chroma_height, delta, 1,
  490.                     dest_y, dest_cb, dest_cr, x_offset, y_offset,
  491.                     qpix_op, chroma_op, mv + MV_BWD_OFFS);
  492.     }
  493. }
  494.  
  495. void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type)
  496. {
  497.     if (ff_cavs_partition_flags[mb_type] == 0) { // 16x16
  498.         mc_part_std(h, 8, 0, h->cy, h->cu, h->cv, 0, 0,
  499.                     h->cdsp.put_cavs_qpel_pixels_tab[0],
  500.                     h->h264chroma.put_h264_chroma_pixels_tab[0],
  501.                     h->cdsp.avg_cavs_qpel_pixels_tab[0],
  502.                     h->h264chroma.avg_h264_chroma_pixels_tab[0],
  503.                     &h->mv[MV_FWD_X0]);
  504.     } else {
  505.         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 0,
  506.                     h->cdsp.put_cavs_qpel_pixels_tab[1],
  507.                     h->h264chroma.put_h264_chroma_pixels_tab[1],
  508.                     h->cdsp.avg_cavs_qpel_pixels_tab[1],
  509.                     h->h264chroma.avg_h264_chroma_pixels_tab[1],
  510.                     &h->mv[MV_FWD_X0]);
  511.         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 0,
  512.                     h->cdsp.put_cavs_qpel_pixels_tab[1],
  513.                     h->h264chroma.put_h264_chroma_pixels_tab[1],
  514.                     h->cdsp.avg_cavs_qpel_pixels_tab[1],
  515.                     h->h264chroma.avg_h264_chroma_pixels_tab[1],
  516.                     &h->mv[MV_FWD_X1]);
  517.         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 4,
  518.                     h->cdsp.put_cavs_qpel_pixels_tab[1],
  519.                     h->h264chroma.put_h264_chroma_pixels_tab[1],
  520.                     h->cdsp.avg_cavs_qpel_pixels_tab[1],
  521.                     h->h264chroma.avg_h264_chroma_pixels_tab[1],
  522.                     &h->mv[MV_FWD_X2]);
  523.         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 4,
  524.                     h->cdsp.put_cavs_qpel_pixels_tab[1],
  525.                     h->h264chroma.put_h264_chroma_pixels_tab[1],
  526.                     h->cdsp.avg_cavs_qpel_pixels_tab[1],
  527.                     h->h264chroma.avg_h264_chroma_pixels_tab[1],
  528.                     &h->mv[MV_FWD_X3]);
  529.     }
  530. }
  531.  
  532. /*****************************************************************************
  533.  *
  534.  * motion vector prediction
  535.  *
  536.  ****************************************************************************/
  537.  
  538. static inline void scale_mv(AVSContext *h, int *d_x, int *d_y,
  539.                             cavs_vector *src, int distp)
  540. {
  541.     int den = h->scale_den[FFMAX(src->ref, 0)];
  542.  
  543.     *d_x = (src->x * distp * den + 256 + FF_SIGNBIT(src->x)) >> 9;
  544.     *d_y = (src->y * distp * den + 256 + FF_SIGNBIT(src->y)) >> 9;
  545. }
  546.  
  547. static inline void mv_pred_median(AVSContext *h,
  548.                                   cavs_vector *mvP,
  549.                                   cavs_vector *mvA,
  550.                                   cavs_vector *mvB,
  551.                                   cavs_vector *mvC)
  552. {
  553.     int ax, ay, bx, by, cx, cy;
  554.     int len_ab, len_bc, len_ca, len_mid;
  555.  
  556.     /* scale candidates according to their temporal span */
  557.     scale_mv(h, &ax, &ay, mvA, mvP->dist);
  558.     scale_mv(h, &bx, &by, mvB, mvP->dist);
  559.     scale_mv(h, &cx, &cy, mvC, mvP->dist);
  560.     /* find the geometrical median of the three candidates */
  561.     len_ab  = abs(ax - bx) + abs(ay - by);
  562.     len_bc  = abs(bx - cx) + abs(by - cy);
  563.     len_ca  = abs(cx - ax) + abs(cy - ay);
  564.     len_mid = mid_pred(len_ab, len_bc, len_ca);
  565.     if (len_mid == len_ab) {
  566.         mvP->x = cx;
  567.         mvP->y = cy;
  568.     } else if (len_mid == len_bc) {
  569.         mvP->x = ax;
  570.         mvP->y = ay;
  571.     } else {
  572.         mvP->x = bx;
  573.         mvP->y = by;
  574.     }
  575. }
  576.  
  577. void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC,
  578.                 enum cavs_mv_pred mode, enum cavs_block size, int ref)
  579. {
  580.     cavs_vector *mvP = &h->mv[nP];
  581.     cavs_vector *mvA = &h->mv[nP-1];
  582.     cavs_vector *mvB = &h->mv[nP-4];
  583.     cavs_vector *mvC = &h->mv[nC];
  584.     const cavs_vector *mvP2 = NULL;
  585.  
  586.     mvP->ref  = ref;
  587.     mvP->dist = h->dist[mvP->ref];
  588.     if (mvC->ref == NOT_AVAIL || (nP == MV_FWD_X3) || (nP == MV_BWD_X3 ))
  589.         mvC = &h->mv[nP - 5];  // set to top-left (mvD)
  590.     if (mode == MV_PRED_PSKIP &&
  591.         (mvA->ref == NOT_AVAIL ||
  592.          mvB->ref == NOT_AVAIL ||
  593.          (mvA->x | mvA->y | mvA->ref) == 0 ||
  594.          (mvB->x | mvB->y | mvB->ref) == 0)) {
  595.         mvP2 = &un_mv;
  596.     /* if there is only one suitable candidate, take it */
  597.     } else if (mvA->ref >= 0 && mvB->ref < 0  && mvC->ref < 0) {
  598.         mvP2 = mvA;
  599.     } else if (mvA->ref < 0  && mvB->ref >= 0 && mvC->ref < 0) {
  600.         mvP2 = mvB;
  601.     } else if (mvA->ref < 0  && mvB->ref < 0  && mvC->ref >= 0) {
  602.         mvP2 = mvC;
  603.     } else if (mode == MV_PRED_LEFT     && mvA->ref == ref) {
  604.         mvP2 = mvA;
  605.     } else if (mode == MV_PRED_TOP      && mvB->ref == ref) {
  606.         mvP2 = mvB;
  607.     } else if (mode == MV_PRED_TOPRIGHT && mvC->ref == ref) {
  608.         mvP2 = mvC;
  609.     }
  610.     if (mvP2) {
  611.         mvP->x = mvP2->x;
  612.         mvP->y = mvP2->y;
  613.     } else
  614.         mv_pred_median(h, mvP, mvA, mvB, mvC);
  615.  
  616.     if (mode < MV_PRED_PSKIP) {
  617.         mvP->x += get_se_golomb(&h->gb);
  618.         mvP->y += get_se_golomb(&h->gb);
  619.     }
  620.     set_mvs(mvP, size);
  621. }
  622.  
  623. /*****************************************************************************
  624.  *
  625.  * macroblock level
  626.  *
  627.  ****************************************************************************/
  628.  
  629. /**
  630.  * initialise predictors for motion vectors and intra prediction
  631.  */
  632. void ff_cavs_init_mb(AVSContext *h)
  633. {
  634.     int i;
  635.  
  636.     /* copy predictors from top line (MB B and C) into cache */
  637.     for (i = 0; i < 3; i++) {
  638.         h->mv[MV_FWD_B2 + i] = h->top_mv[0][h->mbx * 2 + i];
  639.         h->mv[MV_BWD_B2 + i] = h->top_mv[1][h->mbx * 2 + i];
  640.     }
  641.     h->pred_mode_Y[1] = h->top_pred_Y[h->mbx * 2 + 0];
  642.     h->pred_mode_Y[2] = h->top_pred_Y[h->mbx * 2 + 1];
  643.     /* clear top predictors if MB B is not available */
  644.     if (!(h->flags & B_AVAIL)) {
  645.         h->mv[MV_FWD_B2]  = un_mv;
  646.         h->mv[MV_FWD_B3]  = un_mv;
  647.         h->mv[MV_BWD_B2]  = un_mv;
  648.         h->mv[MV_BWD_B3]  = un_mv;
  649.         h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL;
  650.         h->flags         &= ~(C_AVAIL | D_AVAIL);
  651.     } else if (h->mbx) {
  652.         h->flags |= D_AVAIL;
  653.     }
  654.     if (h->mbx == h->mb_width - 1) // MB C not available
  655.         h->flags &= ~C_AVAIL;
  656.     /* clear top-right predictors if MB C is not available */
  657.     if (!(h->flags & C_AVAIL)) {
  658.         h->mv[MV_FWD_C2] = un_mv;
  659.         h->mv[MV_BWD_C2] = un_mv;
  660.     }
  661.     /* clear top-left predictors if MB D is not available */
  662.     if (!(h->flags & D_AVAIL)) {
  663.         h->mv[MV_FWD_D3] = un_mv;
  664.         h->mv[MV_BWD_D3] = un_mv;
  665.     }
  666. }
  667.  
  668. /**
  669.  * save predictors for later macroblocks and increase
  670.  * macroblock address
  671.  * @return 0 if end of frame is reached, 1 otherwise
  672.  */
  673. int ff_cavs_next_mb(AVSContext *h)
  674. {
  675.     int i;
  676.  
  677.     h->flags |= A_AVAIL;
  678.     h->cy    += 16;
  679.     h->cu    += 8;
  680.     h->cv    += 8;
  681.     /* copy mvs as predictors to the left */
  682.     for (i = 0; i <= 20; i += 4)
  683.         h->mv[i] = h->mv[i + 2];
  684.     /* copy bottom mvs from cache to top line */
  685.     h->top_mv[0][h->mbx * 2 + 0] = h->mv[MV_FWD_X2];
  686.     h->top_mv[0][h->mbx * 2 + 1] = h->mv[MV_FWD_X3];
  687.     h->top_mv[1][h->mbx * 2 + 0] = h->mv[MV_BWD_X2];
  688.     h->top_mv[1][h->mbx * 2 + 1] = h->mv[MV_BWD_X3];
  689.     /* next MB address */
  690.     h->mbidx++;
  691.     h->mbx++;
  692.     if (h->mbx == h->mb_width) { // New mb line
  693.         h->flags = B_AVAIL | C_AVAIL;
  694.         /* clear left pred_modes */
  695.         h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
  696.         /* clear left mv predictors */
  697.         for (i = 0; i <= 20; i += 4)
  698.             h->mv[i] = un_mv;
  699.         h->mbx = 0;
  700.         h->mby++;
  701.         /* re-calculate sample pointers */
  702.         h->cy = h->cur.f->data[0] + h->mby * 16 * h->l_stride;
  703.         h->cu = h->cur.f->data[1] + h->mby * 8 * h->c_stride;
  704.         h->cv = h->cur.f->data[2] + h->mby * 8 * h->c_stride;
  705.         if (h->mby == h->mb_height) { // Frame end
  706.             return 0;
  707.         }
  708.     }
  709.     return 1;
  710. }
  711.  
  712. /*****************************************************************************
  713.  *
  714.  * frame level
  715.  *
  716.  ****************************************************************************/
  717.  
  718. int ff_cavs_init_pic(AVSContext *h)
  719. {
  720.     int i;
  721.  
  722.     /* clear some predictors */
  723.     for (i = 0; i <= 20; i += 4)
  724.         h->mv[i] = un_mv;
  725.     h->mv[MV_BWD_X0] = ff_cavs_dir_mv;
  726.     set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
  727.     h->mv[MV_FWD_X0] = ff_cavs_dir_mv;
  728.     set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
  729.     h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
  730.     h->cy             = h->cur.f->data[0];
  731.     h->cu             = h->cur.f->data[1];
  732.     h->cv             = h->cur.f->data[2];
  733.     h->l_stride       = h->cur.f->linesize[0];
  734.     h->c_stride       = h->cur.f->linesize[1];
  735.     h->luma_scan[2]   = 8 * h->l_stride;
  736.     h->luma_scan[3]   = 8 * h->l_stride + 8;
  737.     h->mbx            = h->mby = h->mbidx = 0;
  738.     h->flags          = 0;
  739.  
  740.     return 0;
  741. }
  742.  
  743. /*****************************************************************************
  744.  *
  745.  * headers and interface
  746.  *
  747.  ****************************************************************************/
  748.  
  749. /**
  750.  * some predictions require data from the top-neighbouring macroblock.
  751.  * this data has to be stored for one complete row of macroblocks
  752.  * and this storage space is allocated here
  753.  */
  754. int ff_cavs_init_top_lines(AVSContext *h)
  755. {
  756.     /* alloc top line of predictors */
  757.     h->top_qp       = av_mallocz(h->mb_width);
  758.     h->top_mv[0]    = av_mallocz_array(h->mb_width * 2 + 1,  sizeof(cavs_vector));
  759.     h->top_mv[1]    = av_mallocz_array(h->mb_width * 2 + 1,  sizeof(cavs_vector));
  760.     h->top_pred_Y   = av_mallocz_array(h->mb_width * 2,  sizeof(*h->top_pred_Y));
  761.     h->top_border_y = av_mallocz_array(h->mb_width + 1,  16);
  762.     h->top_border_u = av_mallocz_array(h->mb_width,  10);
  763.     h->top_border_v = av_mallocz_array(h->mb_width,  10);
  764.  
  765.     /* alloc space for co-located MVs and types */
  766.     h->col_mv        = av_mallocz_array(h->mb_width * h->mb_height,
  767.                                         4 * sizeof(cavs_vector));
  768.     h->col_type_base = av_mallocz(h->mb_width * h->mb_height);
  769.     h->block         = av_mallocz(64 * sizeof(int16_t));
  770.  
  771.     if (!h->top_qp || !h->top_mv[0] || !h->top_mv[1] || !h->top_pred_Y ||
  772.         !h->top_border_y || !h->top_border_u || !h->top_border_v ||
  773.         !h->col_mv || !h->col_type_base || !h->block) {
  774.         av_freep(&h->top_qp);
  775.         av_freep(&h->top_mv[0]);
  776.         av_freep(&h->top_mv[1]);
  777.         av_freep(&h->top_pred_Y);
  778.         av_freep(&h->top_border_y);
  779.         av_freep(&h->top_border_u);
  780.         av_freep(&h->top_border_v);
  781.         av_freep(&h->col_mv);
  782.         av_freep(&h->col_type_base);
  783.         av_freep(&h->block);
  784.         return AVERROR(ENOMEM);
  785.     }
  786.     return 0;
  787. }
  788.  
  789. av_cold int ff_cavs_init(AVCodecContext *avctx)
  790. {
  791.     AVSContext *h = avctx->priv_data;
  792.  
  793.     ff_blockdsp_init(&h->bdsp, avctx);
  794.     ff_h264chroma_init(&h->h264chroma, 8);
  795.     ff_idctdsp_init(&h->idsp, avctx);
  796.     ff_videodsp_init(&h->vdsp, 8);
  797.     ff_cavsdsp_init(&h->cdsp, avctx);
  798.     ff_init_scantable_permutation(h->idsp.idct_permutation,
  799.                                   h->cdsp.idct_perm);
  800.     ff_init_scantable(h->idsp.idct_permutation, &h->scantable, ff_zigzag_direct);
  801.  
  802.     h->avctx       = avctx;
  803.     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
  804.  
  805.     h->cur.f    = av_frame_alloc();
  806.     h->DPB[0].f = av_frame_alloc();
  807.     h->DPB[1].f = av_frame_alloc();
  808.     if (!h->cur.f || !h->DPB[0].f || !h->DPB[1].f) {
  809.         ff_cavs_end(avctx);
  810.         return AVERROR(ENOMEM);
  811.     }
  812.  
  813.     h->luma_scan[0]                     = 0;
  814.     h->luma_scan[1]                     = 8;
  815.     h->intra_pred_l[INTRA_L_VERT]       = intra_pred_vert;
  816.     h->intra_pred_l[INTRA_L_HORIZ]      = intra_pred_horiz;
  817.     h->intra_pred_l[INTRA_L_LP]         = intra_pred_lp;
  818.     h->intra_pred_l[INTRA_L_DOWN_LEFT]  = intra_pred_down_left;
  819.     h->intra_pred_l[INTRA_L_DOWN_RIGHT] = intra_pred_down_right;
  820.     h->intra_pred_l[INTRA_L_LP_LEFT]    = intra_pred_lp_left;
  821.     h->intra_pred_l[INTRA_L_LP_TOP]     = intra_pred_lp_top;
  822.     h->intra_pred_l[INTRA_L_DC_128]     = intra_pred_dc_128;
  823.     h->intra_pred_c[INTRA_C_LP]         = intra_pred_lp;
  824.     h->intra_pred_c[INTRA_C_HORIZ]      = intra_pred_horiz;
  825.     h->intra_pred_c[INTRA_C_VERT]       = intra_pred_vert;
  826.     h->intra_pred_c[INTRA_C_PLANE]      = intra_pred_plane;
  827.     h->intra_pred_c[INTRA_C_LP_LEFT]    = intra_pred_lp_left;
  828.     h->intra_pred_c[INTRA_C_LP_TOP]     = intra_pred_lp_top;
  829.     h->intra_pred_c[INTRA_C_DC_128]     = intra_pred_dc_128;
  830.     h->mv[7]                            = un_mv;
  831.     h->mv[19]                           = un_mv;
  832.     return 0;
  833. }
  834.  
  835. av_cold int ff_cavs_end(AVCodecContext *avctx)
  836. {
  837.     AVSContext *h = avctx->priv_data;
  838.  
  839.     av_frame_free(&h->cur.f);
  840.     av_frame_free(&h->DPB[0].f);
  841.     av_frame_free(&h->DPB[1].f);
  842.  
  843.     av_freep(&h->top_qp);
  844.     av_freep(&h->top_mv[0]);
  845.     av_freep(&h->top_mv[1]);
  846.     av_freep(&h->top_pred_Y);
  847.     av_freep(&h->top_border_y);
  848.     av_freep(&h->top_border_u);
  849.     av_freep(&h->top_border_v);
  850.     av_freep(&h->col_mv);
  851.     av_freep(&h->col_type_base);
  852.     av_freep(&h->block);
  853.     av_freep(&h->edge_emu_buffer);
  854.     return 0;
  855. }
  856.