libavcodec/cavsdec.c
844d9012
 /*
  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
  * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
  *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
ba87f080
  * @file
844d9012
  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder
  * @author Stefan Gehrer <stefan.gehrer@gmx.de>
  */
 
5a9fa845
 #include "libavutil/avassert.h"
844d9012
 #include "avcodec.h"
9106a698
 #include "get_bits.h"
844d9012
 #include "golomb.h"
 #include "cavs.h"
594d4d5d
 #include "internal.h"
7d848264
 #include "mpeg12data.h"
 #include "mpegvideo.h"
844d9012
 
 static const uint8_t mv_scan[4] = {
185c2ef8
     MV_FWD_X0, MV_FWD_X1,
     MV_FWD_X2, MV_FWD_X3
844d9012
 };
 
 static const uint8_t cbp_tab[64][2] = {
185c2ef8
   { 63,  0 }, { 15, 15 }, { 31, 63 }, { 47, 31 }, {  0, 16 }, { 14, 32 }, { 13, 47 }, { 11, 13 },
   {  7, 14 }, {  5, 11 }, { 10, 12 }, {  8,  5 }, { 12, 10 }, { 61,  7 }, {  4, 48 }, { 55,  3 },
   {  1,  2 }, {  2,  8 }, { 59,  4 }, {  3,  1 }, { 62, 61 }, {  9, 55 }, {  6, 59 }, { 29, 62 },
   { 45, 29 }, { 51, 27 }, { 23, 23 }, { 39, 19 }, { 27, 30 }, { 46, 28 }, { 53,  9 }, { 30,  6 },
   { 43, 60 }, { 37, 21 }, { 60, 44 }, { 16, 26 }, { 21, 51 }, { 28, 35 }, { 19, 18 }, { 35, 20 },
   { 42, 24 }, { 26, 53 }, { 44, 17 }, { 32, 37 }, { 58, 39 }, { 24, 45 }, { 20, 58 }, { 17, 43 },
   { 18, 42 }, { 48, 46 }, { 22, 36 }, { 33, 33 }, { 25, 34 }, { 49, 40 }, { 40, 52 }, { 36, 49 },
   { 34, 50 }, { 50, 56 }, { 52, 25 }, { 54, 22 }, { 41, 54 }, { 56, 57 }, { 38, 41 }, { 57, 38 }
844d9012
 };
 
ef07ac1e
 static const uint8_t scan3x3[4] = { 4, 5, 7, 8 };
 
 static const uint8_t cavs_chroma_qp[64] = {
185c2ef8
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 42, 43, 43, 44, 44,
   45, 45, 46, 46, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51
ef07ac1e
 };
 
 static const uint8_t dequant_shift[64] = {
185c2ef8
   14, 14, 14, 14, 14, 14, 14, 14,
   13, 13, 13, 13, 13, 13, 13, 13,
   13, 12, 12, 12, 12, 12, 12, 12,
   11, 11, 11, 11, 11, 11, 11, 11,
   11, 10, 10, 10, 10, 10, 10, 10,
   10,  9,  9,  9,  9,  9,  9,  9,
   9,   8,  8,  8,  8,  8,  8,  8,
   7,   7,  7,  7,  7,  7,  7,  7
ef07ac1e
 };
 
 static const uint16_t dequant_mul[64] = {
185c2ef8
   32768, 36061, 38968, 42495, 46341, 50535, 55437, 60424,
   32932, 35734, 38968, 42495, 46177, 50535, 55109, 59933,
   65535, 35734, 38968, 42577, 46341, 50617, 55027, 60097,
   32809, 35734, 38968, 42454, 46382, 50576, 55109, 60056,
   65535, 35734, 38968, 42495, 46320, 50515, 55109, 60076,
   65535, 35744, 38968, 42495, 46341, 50535, 55099, 60087,
   65535, 35734, 38973, 42500, 46341, 50535, 55109, 60097,
   32771, 35734, 38965, 42497, 46341, 50535, 55109, 60099
ef07ac1e
 };
 
185c2ef8
 #define EOB 0, 0, 0
ef07ac1e
 
 static const struct dec_2dvlc intra_dec[7] = {
185c2ef8
     {
         { //level / run / table_inc
             {  1,  1,  1 }, { -1,  1,  1 }, {  1,  2,  1 }, { -1,  2,  1 }, {  1,  3,  1 }, { -1,  3, 1 },
             {  1,  4,  1 }, { -1,  4,  1 }, {  1,  5,  1 }, { -1,  5,  1 }, {  1,  6,  1 }, { -1,  6, 1 },
             {  1,  7,  1 }, { -1,  7,  1 }, {  1,  8,  1 }, { -1,  8,  1 }, {  1,  9,  1 }, { -1,  9, 1 },
             {  1, 10,  1 }, { -1, 10,  1 }, {  1, 11,  1 }, { -1, 11,  1 }, {  2,  1,  2 }, { -2,  1, 2 },
             {  1, 12,  1 }, { -1, 12,  1 }, {  1, 13,  1 }, { -1, 13,  1 }, {  1, 14,  1 }, { -1, 14, 1 },
             {  1, 15,  1 }, { -1, 15,  1 }, {  2,  2,  2 }, { -2,  2,  2 }, {  1, 16,  1 }, { -1, 16, 1 },
             {  1, 17,  1 }, { -1, 17,  1 }, {  3,  1,  3 }, { -3,  1,  3 }, {  1, 18,  1 }, { -1, 18, 1 },
             {  1, 19,  1 }, { -1, 19,  1 }, {  2,  3,  2 }, { -2,  3,  2 }, {  1, 20,  1 }, { -1, 20, 1 },
             {  1, 21,  1 }, { -1, 21,  1 }, {  2,  4,  2 }, { -2,  4,  2 }, {  1, 22,  1 }, { -1, 22, 1 },
             {  2,  5,  2 }, { -2,  5,  2 }, {  1, 23,  1 }, { -1, 23,  1 }, {   EOB    }
         },
         //level_add
         { 0, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1 },
         2, //golomb_order
         0, //inc_limit
         23, //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {  1,  1,  0 }, { -1,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, {  2,  1,  1 }, { -2,  1,  1 },
             {  1,  3,  0 }, { -1,  3,  0 }, {     EOB    }, {  1,  4,  0 }, { -1,  4,  0 }, {  1,  5,  0 },
             { -1,  5,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, {  3,  1,  2 }, { -3,  1,  2 }, {  2,  2,  1 },
             { -2,  2,  1 }, {  1,  7,  0 }, { -1,  7,  0 }, {  1,  8,  0 }, { -1,  8,  0 }, {  1,  9,  0 },
             { -1,  9,  0 }, {  2,  3,  1 }, { -2,  3,  1 }, {  4,  1,  2 }, { -4,  1,  2 }, {  1, 10,  0 },
             { -1, 10,  0 }, {  1, 11,  0 }, { -1, 11,  0 }, {  2,  4,  1 }, { -2,  4,  1 }, {  3,  2,  2 },
             { -3,  2,  2 }, {  1, 12,  0 }, { -1, 12,  0 }, {  2,  5,  1 }, { -2,  5,  1 }, {  5,  1,  3 },
             { -5,  1,  3 }, {  1, 13,  0 }, { -1, 13,  0 }, {  2,  6,  1 }, { -2,  6,  1 }, {  1, 14,  0 },
             { -1, 14,  0 }, {  2,  7,  1 }, { -2,  7,  1 }, {  2,  8,  1 }, { -2,  8,  1 }, {  3,  3,  2 },
             { -3,  3,  2 }, {  6,  1,  3 }, { -6,  1,  3 }, {  1, 15,  0 }, { -1, 15,  0 }
         },
         //level_add
         { 0, 7, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         1, //inc_limit
         15, //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 },
             {  3,  1,  1 }, { -3,  1,  1 }, {     EOB    }, {  1,  3,  0 }, { -1,  3,  0 }, {  2,  2,  0 },
             { -2,  2,  0 }, {  4,  1,  1 }, { -4,  1,  1 }, {  1,  4,  0 }, { -1,  4,  0 }, {  5,  1,  2 },
             { -5,  1,  2 }, {  1,  5,  0 }, { -1,  5,  0 }, {  3,  2,  1 }, { -3,  2,  1 }, {  2,  3,  0 },
             { -2,  3,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, {  6,  1,  2 }, { -6,  1,  2 }, {  2,  4,  0 },
             { -2,  4,  0 }, {  1,  7,  0 }, { -1,  7,  0 }, {  4,  2,  1 }, { -4,  2,  1 }, {  7,  1,  2 },
             { -7,  1,  2 }, {  3,  3,  1 }, { -3,  3,  1 }, {  2,  5,  0 }, { -2,  5,  0 }, {  1,  8,  0 },
             { -1,  8,  0 }, {  2,  6,  0 }, { -2,  6,  0 }, {  8,  1,  3 }, { -8,  1,  3 }, {  1,  9,  0 },
             { -1,  9,  0 }, {  5,  2,  2 }, { -5,  2,  2 }, {  3,  4,  1 }, { -3,  4,  1 }, {  2,  7,  0 },
             { -2,  7,  0 }, {  9,  1,  3 }, { -9,  1,  3 }, {  1, 10,  0 }, { -1, 10,  0 }
         },
         //level_add
         { 0, 10, 6, 4, 4, 3, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         2, //inc_limit
         10, //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 }, { -3,  1,  0 },
             {  1,  2,  0 }, { -1,  2,  0 }, {     EOB    }, {  4,  1,  0 }, { -4,  1,  0 }, {  5,  1,  1 },
             { -5,  1,  1 }, {  2,  2,  0 }, { -2,  2,  0 }, {  1,  3,  0 }, { -1,  3,  0 }, {  6,  1,  1 },
             { -6,  1,  1 }, {  3,  2,  0 }, { -3,  2,  0 }, {  7,  1,  1 }, { -7,  1,  1 }, {  1,  4,  0 },
             { -1,  4,  0 }, {  8,  1,  2 }, { -8,  1,  2 }, {  2,  3,  0 }, { -2,  3,  0 }, {  4,  2,  0 },
             { -4,  2,  0 }, {  1,  5,  0 }, { -1,  5,  0 }, {  9,  1,  2 }, { -9,  1,  2 }, {  5,  2,  1 },
             { -5,  2,  1 }, {  2,  4,  0 }, { -2,  4,  0 }, { 10,  1,  2 }, {-10,  1,  2 }, {  3,  3,  0 },
             { -3,  3,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, { 11,  1,  3 }, {-11,  1,  3 }, {  6,  2,  1 },
             { -6,  2,  1 }, {  1,  7,  0 }, { -1,  7,  0 }, {  2,  5,  0 }, { -2,  5,  0 }, {  3,  4,  0 },
             { -3,  4,  0 }, { 12,  1,  3 }, {-12,  1,  3 }, {  4,  3,  0 }, { -4,  3,  0 }
          },
         //level_add
         { 0, 13, 7, 5, 4, 3, 2, 2, -1, -1, -1 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         4, //inc_limit
         7, //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 }, { -3,  1,  0 },
             {     EOB    }, {  4,  1,  0 }, { -4,  1,  0 }, {  5,  1,  0 }, { -5,  1,  0 }, {  6,  1,  0 },
             { -6,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, {  7,  1,  0 }, { -7,  1,  0 }, {  8,  1,  1 },
             { -8,  1,  1 }, {  2,  2,  0 }, { -2,  2,  0 }, {  9,  1,  1 }, { -9,  1,  1 }, { 10,  1,  1 },
             {-10,  1,  1 }, {  1,  3,  0 }, { -1,  3,  0 }, {  3,  2,  0 }, { -3,  2,  0 }, { 11,  1,  2 },
             {-11,  1,  2 }, {  4,  2,  0 }, { -4,  2,  0 }, { 12,  1,  2 }, {-12,  1,  2 }, { 13,  1,  2 },
             {-13,  1,  2 }, {  5,  2,  0 }, { -5,  2,  0 }, {  1,  4,  0 }, { -1,  4,  0 }, {  2,  3,  0 },
             { -2,  3,  0 }, { 14,  1,  2 }, {-14,  1,  2 }, {  6,  2,  0 }, { -6,  2,  0 }, { 15,  1,  2 },
             {-15,  1,  2 }, { 16,  1,  2 }, {-16,  1,  2 }, {  3,  3,  0 }, { -3,  3,  0 }, {  1,  5,  0 },
             { -1,  5,  0 }, {  7,  2,  0 }, { -7,  2,  0 }, { 17,  1,  2 }, {-17,  1,  2 }
         },
         //level_add
         { 0,18, 8, 4, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         7, //inc_limit
         5, //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {     EOB    }, {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 },
             { -3,  1,  0 }, {  4,  1,  0 }, { -4,  1,  0 }, {  5,  1,  0 }, { -5,  1,  0 }, {  6,  1,  0 },
             { -6,  1,  0 }, {  7,  1,  0 }, { -7,  1,  0 }, {  8,  1,  0 }, { -8,  1,  0 }, {  9,  1,  0 },
             { -9,  1,  0 }, { 10,  1,  0 }, {-10,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, { 11,  1,  1 },
             {-11,  1,  1 }, { 12,  1,  1 }, {-12,  1,  1 }, { 13,  1,  1 }, {-13,  1,  1 }, {  2,  2,  0 },
             { -2,  2,  0 }, { 14,  1,  1 }, {-14,  1,  1 }, { 15,  1,  1 }, {-15,  1,  1 }, {  3,  2,  0 },
             { -3,  2,  0 }, { 16,  1,  1 }, {-16,  1,  1 }, {  1,  3,  0 }, { -1,  3,  0 }, { 17,  1,  1 },
             {-17,  1,  1 }, {  4,  2,  0 }, { -4,  2,  0 }, { 18,  1,  1 }, {-18,  1,  1 }, {  5,  2,  0 },
             { -5,  2,  0 }, { 19,  1,  1 }, {-19,  1,  1 }, { 20,  1,  1 }, {-20,  1,  1 }, {  6,  2,  0 },
             { -6,  2,  0 }, { 21,  1,  1 }, {-21,  1,  1 }, {  2,  3,  0 }, { -2,  3,  0 }
         },
         //level_add
         { 0, 22, 7, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         10, //inc_limit
         3, //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {     EOB    }, {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 },
             { -3,  1,  0 }, {  4,  1,  0 }, { -4,  1,  0 }, {  5,  1,  0 }, { -5,  1,  0 }, {  6,  1,  0 },
             { -6,  1,  0 }, {  7,  1,  0 }, { -7,  1,  0 }, {  8,  1,  0 }, { -8,  1,  0 }, {  9,  1,  0 },
             { -9,  1,  0 }, { 10,  1,  0 }, {-10,  1,  0 }, { 11,  1,  0 }, {-11,  1,  0 }, { 12,  1,  0 },
             {-12,  1,  0 }, { 13,  1,  0 }, {-13,  1,  0 }, { 14,  1,  0 }, {-14,  1,  0 }, { 15,  1,  0 },
             {-15,  1,  0 }, { 16,  1,  0 }, {-16,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, { 17,  1,  0 },
             {-17,  1,  0 }, { 18,  1,  0 }, {-18,  1,  0 }, { 19,  1,  0 }, {-19,  1,  0 }, { 20,  1,  0 },
             {-20,  1,  0 }, { 21,  1,  0 }, {-21,  1,  0 }, {  2,  2,  0 }, { -2,  2,  0 }, { 22,  1,  0 },
             {-22,  1,  0 }, { 23,  1,  0 }, {-23,  1,  0 }, { 24,  1,  0 }, {-24,  1,  0 }, { 25,  1,  0 },
             {-25,  1,  0 }, {  3,  2,  0 }, { -3,  2,  0 }, { 26,  1,  0 }, {-26,  1,  0 }
         },
         //level_add
         { 0, 27, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         INT_MAX, //inc_limit
         2, //max_run
     }
ef07ac1e
 };
 
 static const struct dec_2dvlc inter_dec[7] = {
185c2ef8
     {
         { //level / run
             {  1,  1,  1 }, { -1,  1,  1 }, {  1,  2,  1 }, { -1,  2,  1 }, {  1,  3,  1 }, { -1,  3,  1 },
             {  1,  4,  1 }, { -1,  4,  1 }, {  1,  5,  1 }, { -1,  5,  1 }, {  1,  6,  1 }, { -1,  6,  1 },
             {  1,  7,  1 }, { -1,  7,  1 }, {  1,  8,  1 }, { -1,  8,  1 }, {  1,  9,  1 }, { -1,  9,  1 },
             {  1, 10,  1 }, { -1, 10,  1 }, {  1, 11,  1 }, { -1, 11,  1 }, {  1, 12,  1 }, { -1, 12,  1 },
             {  1, 13,  1 }, { -1, 13,  1 }, {  2,  1,  2 }, { -2,  1,  2 }, {  1, 14,  1 }, { -1, 14,  1 },
             {  1, 15,  1 }, { -1, 15,  1 }, {  1, 16,  1 }, { -1, 16,  1 }, {  1, 17,  1 }, { -1, 17,  1 },
             {  1, 18,  1 }, { -1, 18,  1 }, {  1, 19,  1 }, { -1, 19,  1 }, {  3,  1,  3 }, { -3,  1,  3 },
             {  1, 20,  1 }, { -1, 20,  1 }, {  1, 21,  1 }, { -1, 21,  1 }, {  2,  2,  2 }, { -2,  2,  2 },
             {  1, 22,  1 }, { -1, 22,  1 }, {  1, 23,  1 }, { -1, 23,  1 }, {  1, 24,  1 }, { -1, 24,  1 },
             {  1, 25,  1 }, { -1, 25,  1 }, {  1, 26,  1 }, { -1, 26,  1 }, {   EOB    }
         },
         //level_add
         { 0, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
         3, //golomb_order
         0, //inc_limit
         26 //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {  1,  1,  0 }, { -1,  1,  0 }, {     EOB    }, {  1,  2,  0 }, { -1,  2,  0 }, {  1,  3,  0 },
             { -1,  3,  0 }, {  1,  4,  0 }, { -1,  4,  0 }, {  1,  5,  0 }, { -1,  5,  0 }, {  1,  6,  0 },
             { -1,  6,  0 }, {  2,  1,  1 }, { -2,  1,  1 }, {  1,  7,  0 }, { -1,  7,  0 }, {  1,  8,  0 },
             { -1,  8,  0 }, {  1,  9,  0 }, { -1,  9,  0 }, {  1, 10,  0 }, { -1, 10,  0 }, {  2,  2,  1 },
             { -2,  2,  1 }, {  1, 11,  0 }, { -1, 11,  0 }, {  1, 12,  0 }, { -1, 12,  0 }, {  3,  1,  2 },
             { -3,  1,  2 }, {  1, 13,  0 }, { -1, 13,  0 }, {  1, 14,  0 }, { -1, 14,  0 }, {  2,  3,  1 },
             { -2,  3,  1 }, {  1, 15,  0 }, { -1, 15,  0 }, {  2,  4,  1 }, { -2,  4,  1 }, {  1, 16,  0 },
             { -1, 16,  0 }, {  2,  5,  1 }, { -2,  5,  1 }, {  1, 17,  0 }, { -1, 17,  0 }, {  4,  1,  3 },
             { -4,  1,  3 }, {  2,  6,  1 }, { -2,  6,  1 }, {  1, 18,  0 }, { -1, 18,  0 }, {  1, 19,  0 },
             { -1, 19,  0 }, {  2,  7,  1 }, { -2,  7,  1 }, {  3,  2,  2 }, { -3,  2,  2 }
         },
         //level_add
         { 0, 5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         1, //inc_limit
         19 //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {  1,  1,  0 }, { -1,  1,  0 }, {     EOB    }, {  1,  2,  0 }, { -1,  2,  0 }, {  2,  1,  0 },
             { -2,  1,  0 }, {  1,  3,  0 }, { -1,  3,  0 }, {  1,  4,  0 }, { -1,  4,  0 }, {  3,  1,  1 },
             { -3,  1,  1 }, {  2,  2,  0 }, { -2,  2,  0 }, {  1,  5,  0 }, { -1,  5,  0 }, {  1,  6,  0 },
             { -1,  6,  0 }, {  1,  7,  0 }, { -1,  7,  0 }, {  2,  3,  0 }, { -2,  3,  0 }, {  4,  1,  2 },
             { -4,  1,  2 }, {  1,  8,  0 }, { -1,  8,  0 }, {  3,  2,  1 }, { -3,  2,  1 }, {  2,  4,  0 },
             { -2,  4,  0 }, {  1,  9,  0 }, { -1,  9,  0 }, {  1, 10,  0 }, { -1, 10,  0 }, {  5,  1,  2 },
             { -5,  1,  2 }, {  2,  5,  0 }, { -2,  5,  0 }, {  1, 11,  0 }, { -1, 11,  0 }, {  2,  6,  0 },
             { -2,  6,  0 }, {  1, 12,  0 }, { -1, 12,  0 }, {  3,  3,  1 }, { -3,  3,  1 }, {  6,  1,  2 },
             { -6,  1,  2 }, {  4,  2,  2 }, { -4,  2,  2 }, {  1, 13,  0 }, { -1, 13,  0 }, {  2,  7,  0 },
             { -2,  7,  0 }, {  3,  4,  1 }, { -3,  4,  1 }, {  1, 14,  0 }, { -1, 14,  0 }
         },
         //level_add
         { 0, 7, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         2, //inc_limit
         14 //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {  1,  1,  0 }, { -1,  1,  0 }, {     EOB    }, {  2,  1,  0 }, { -2,  1,  0 }, {  1,  2,  0 },
             { -1,  2,  0 }, {  3,  1,  0 }, { -3,  1,  0 }, {  1,  3,  0 }, { -1,  3,  0 }, {  2,  2,  0 },
             { -2,  2,  0 }, {  4,  1,  1 }, { -4,  1,  1 }, {  1,  4,  0 }, { -1,  4,  0 }, {  5,  1,  1 },
             { -5,  1,  1 }, {  1,  5,  0 }, { -1,  5,  0 }, {  3,  2,  0 }, { -3,  2,  0 }, {  2,  3,  0 },
             { -2,  3,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, {  6,  1,  1 }, { -6,  1,  1 }, {  2,  4,  0 },
             { -2,  4,  0 }, {  1,  7,  0 }, { -1,  7,  0 }, {  4,  2,  1 }, { -4,  2,  1 }, {  7,  1,  2 },
             { -7,  1,  2 }, {  3,  3,  0 }, { -3,  3,  0 }, {  1,  8,  0 }, { -1,  8,  0 }, {  2,  5,  0 },
             { -2,  5,  0 }, {  8,  1,  2 }, { -8,  1,  2 }, {  1,  9,  0 }, { -1,  9,  0 }, {  3,  4,  0 },
             { -3,  4,  0 }, {  2,  6,  0 }, { -2,  6,  0 }, {  5,  2,  1 }, { -5,  2,  1 }, {  1, 10,  0 },
             { -1, 10,  0 }, {  9,  1,  2 }, { -9,  1,  2 }, {  4,  3,  1 }, { -4,  3,  1 }
         },
         //level_add
         { 0,10, 6, 5, 4, 3, 3, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         3, //inc_limit
         10 //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {  1,  1,  0 }, { -1,  1,  0 }, {     EOB    }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 },
             { -3,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, {  4,  1,  0 }, { -4,  1,  0 }, {  5,  1,  0 },
             { -5,  1,  0 }, {  2,  2,  0 }, { -2,  2,  0 }, {  1,  3,  0 }, { -1,  3,  0 }, {  6,  1,  0 },
             { -6,  1,  0 }, {  3,  2,  0 }, { -3,  2,  0 }, {  7,  1,  1 }, { -7,  1,  1 }, {  1,  4,  0 },
             { -1,  4,  0 }, {  8,  1,  1 }, { -8,  1,  1 }, {  2,  3,  0 }, { -2,  3,  0 }, {  4,  2,  0 },
             { -4,  2,  0 }, {  1,  5,  0 }, { -1,  5,  0 }, {  9,  1,  1 }, { -9,  1,  1 }, {  5,  2,  0 },
             { -5,  2,  0 }, {  2,  4,  0 }, { -2,  4,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, { 10,  1,  2 },
             {-10,  1,  2 }, {  3,  3,  0 }, { -3,  3,  0 }, { 11,  1,  2 }, {-11,  1,  2 }, {  1,  7,  0 },
             { -1,  7,  0 }, {  6,  2,  0 }, { -6,  2,  0 }, {  3,  4,  0 }, { -3,  4,  0 }, {  2,  5,  0 },
             { -2,  5,  0 }, { 12,  1,  2 }, {-12,  1,  2 }, {  4,  3,  0 }, { -4,  3,  0 }
         },
         //level_add
         { 0, 13, 7, 5, 4, 3, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         6, //inc_limit
         7  //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {      EOB    }, {  1,  1,  0 }, {  -1,  1,  0 }, {  2,  1,  0 }, {  -2,  1,  0 }, {  3,  1,  0 },
             {  -3,  1,  0 }, {  4,  1,  0 }, {  -4,  1,  0 }, {  5,  1,  0 }, {  -5,  1,  0 }, {  1,  2,  0 },
             {  -1,  2,  0 }, {  6,  1,  0 }, {  -6,  1,  0 }, {  7,  1,  0 }, {  -7,  1,  0 }, {  8,  1,  0 },
             {  -8,  1,  0 }, {  2,  2,  0 }, {  -2,  2,  0 }, {  9,  1,  0 }, {  -9,  1,  0 }, {  1,  3,  0 },
             {  -1,  3,  0 }, { 10,  1,  1 }, { -10,  1,  1 }, {  3,  2,  0 }, {  -3,  2,  0 }, { 11,  1,  1 },
             { -11,  1,  1 }, {  4,  2,  0 }, {  -4,  2,  0 }, { 12,  1,  1 }, { -12,  1,  1 }, {  1,  4,  0 },
             {  -1,  4,  0 }, {  2,  3,  0 }, {  -2,  3,  0 }, { 13,  1,  1 }, { -13,  1,  1 }, {  5,  2,  0 },
             {  -5,  2,  0 }, { 14,  1,  1 }, { -14,  1,  1 }, {  6,  2,  0 }, {  -6,  2,  0 }, {  1,  5,  0 },
             {  -1,  5,  0 }, { 15,  1,  1 }, { -15,  1,  1 }, {  3,  3,  0 }, {  -3,  3,  0 }, { 16,  1,  1 },
             { -16,  1,  1 }, {  2,  4,  0 }, {  -2,  4,  0 }, {  7,  2,  0 }, {  -7,  2,  0 }
         },
         //level_add
         { 0, 17, 8, 4, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         9, //inc_limit
         5  //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {      EOB    }, {  1,  1,  0 }, {  -1,  1,  0 }, {  2,  1,  0 }, {  -2,  1,  0 }, {   3,  1,  0 },
             {  -3,  1,  0 }, {  4,  1,  0 }, {  -4,  1,  0 }, {  5,  1,  0 }, {  -5,  1,  0 }, {   6,  1,  0 },
             {  -6,  1,  0 }, {  7,  1,  0 }, {  -7,  1,  0 }, {  1,  2,  0 }, {  -1,  2,  0 }, {   8,  1,  0 },
             {  -8,  1,  0 }, {  9,  1,  0 }, {  -9,  1,  0 }, { 10,  1,  0 }, { -10,  1,  0 }, {  11,  1,  0 },
             { -11,  1,  0 }, { 12,  1,  0 }, { -12,  1,  0 }, {  2,  2,  0 }, {  -2,  2,  0 }, {  13,  1,  0 },
             { -13,  1,  0 }, {  1,  3,  0 }, {  -1,  3,  0 }, { 14,  1,  0 }, { -14,  1,  0 }, {  15,  1,  0 },
             { -15,  1,  0 }, {  3,  2,  0 }, {  -3,  2,  0 }, { 16,  1,  0 }, { -16,  1,  0 }, {  17,  1,  0 },
             { -17,  1,  0 }, { 18,  1,  0 }, { -18,  1,  0 }, {  4,  2,  0 }, {  -4,  2,  0 }, {  19,  1,  0 },
             { -19,  1,  0 }, { 20,  1,  0 }, { -20,  1,  0 }, {  2,  3,  0 }, {  -2,  3,  0 }, {   1,  4,  0 },
             {  -1,  4,  0 }, {  5,  2,  0 }, {  -5,  2,  0 }, { 21,  1,  0 }, { -21,  1,  0 }
         },
         //level_add
         { 0, 22, 6, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         2, //golomb_order
         INT_MAX, //inc_limit
         4 //max_run
     }
ef07ac1e
 };
 
 static const struct dec_2dvlc chroma_dec[5] = {
185c2ef8
     {
         { //level / run
             {  1,  1,  1 }, { -1,  1,  1 }, {  1,  2,  1 }, { -1,  2,  1 }, {  1,  3,  1 }, { -1,  3,  1 },
             {  1,  4,  1 }, { -1,  4,  1 }, {  1,  5,  1 }, { -1,  5,  1 }, {  1,  6,  1 }, { -1,  6,  1 },
             {  1,  7,  1 }, { -1,  7,  1 }, {  2,  1,  2 }, { -2,  1,  2 }, {  1,  8,  1 }, { -1,  8,  1 },
             {  1,  9,  1 }, { -1,  9,  1 }, {  1, 10,  1 }, { -1, 10,  1 }, {  1, 11,  1 }, { -1, 11,  1 },
             {  1, 12,  1 }, { -1, 12,  1 }, {  1, 13,  1 }, { -1, 13,  1 }, {  1, 14,  1 }, { -1, 14,  1 },
             {  1, 15,  1 }, { -1, 15,  1 }, {  3,  1,  3 }, { -3,  1,  3 }, {  1, 16,  1 }, { -1, 16,  1 },
             {  1, 17,  1 }, { -1, 17,  1 }, {  1, 18,  1 }, { -1, 18,  1 }, {  1, 19,  1 }, { -1, 19,  1 },
             {  1, 20,  1 }, { -1, 20,  1 }, {  1, 21,  1 }, { -1, 21,  1 }, {  1, 22,  1 }, { -1, 22,  1 },
             {  2,  2,  2 }, { -2,  2,  2 }, {  1, 23,  1 }, { -1, 23,  1 }, {  1, 24,  1 }, { -1, 24,  1 },
             {  1, 25,  1 }, { -1, 25,  1 }, {  4,  1,  3 }, { -4,  1,  3 }, {   EOB    }
         },
         //level_add
         { 0, 5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1 },
         2, //golomb_order
         0, //inc_limit
         25 //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {     EOB    }, {  1,  1,  0 }, { -1,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, {  2,  1,  1 },
             { -2,  1,  1 }, {  1,  3,  0 }, { -1,  3,  0 }, {  1,  4,  0 }, { -1,  4,  0 }, {  1,  5,  0 },
             { -1,  5,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, {  3,  1,  2 }, { -3,  1,  2 }, {  1,  7,  0 },
             { -1,  7,  0 }, {  1,  8,  0 }, { -1,  8,  0 }, {  2,  2,  1 }, { -2,  2,  1 }, {  1,  9,  0 },
             { -1,  9,  0 }, {  1, 10,  0 }, { -1, 10,  0 }, {  1, 11,  0 }, { -1, 11,  0 }, {  4,  1,  2 },
             { -4,  1,  2 }, {  1, 12,  0 }, { -1, 12,  0 }, {  1, 13,  0 }, { -1, 13,  0 }, {  1, 14,  0 },
             { -1, 14,  0 }, {  2,  3,  1 }, { -2,  3,  1 }, {  1, 15,  0 }, { -1, 15,  0 }, {  2,  4,  1 },
             { -2,  4,  1 }, {  5,  1,  3 }, { -5,  1,  3 }, {  3,  2,  2 }, { -3,  2,  2 }, {  1, 16,  0 },
             { -1, 16,  0 }, {  1, 17,  0 }, { -1, 17,  0 }, {  1, 18,  0 }, { -1, 18,  0 }, {  2,  5,  1 },
             { -2,  5,  1 }, {  1, 19,  0 }, { -1, 19,  0 }, {  1, 20,  0 }, { -1, 20,  0 }
         },
         //level_add
         { 0, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1 },
         0, //golomb_order
         1, //inc_limit
         20 //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {  1,  1,  0 }, { -1,  1,  0 }, {     EOB    }, {  2,  1,  0 }, { -2,  1,  0 }, {  1,  2,  0 },
             { -1,  2,  0 }, {  3,  1,  1 }, { -3,  1,  1 }, {  1,  3,  0 }, { -1,  3,  0 }, {  4,  1,  1 },
             { -4,  1,  1 }, {  2,  2,  0 }, { -2,  2,  0 }, {  1,  4,  0 }, { -1,  4,  0 }, {  5,  1,  2 },
             { -5,  1,  2 }, {  1,  5,  0 }, { -1,  5,  0 }, {  3,  2,  1 }, { -3,  2,  1 }, {  2,  3,  0 },
             { -2,  3,  0 }, {  1,  6,  0 }, { -1,  6,  0 }, {  6,  1,  2 }, { -6,  1,  2 }, {  1,  7,  0 },
             { -1,  7,  0 }, {  2,  4,  0 }, { -2,  4,  0 }, {  7,  1,  2 }, { -7,  1,  2 }, {  1,  8,  0 },
             { -1,  8,  0 }, {  4,  2,  1 }, { -4,  2,  1 }, {  1,  9,  0 }, { -1,  9,  0 }, {  3,  3,  1 },
             { -3,  3,  1 }, {  2,  5,  0 }, { -2,  5,  0 }, {  2,  6,  0 }, { -2,  6,  0 }, {  8,  1,  2 },
             { -8,  1,  2 }, {  1, 10,  0 }, { -1, 10,  0 }, {  1, 11,  0 }, { -1, 11,  0 }, {  9,  1,  2 },
             { -9,  1,  2 }, {  5,  2,  2 }, { -5,  2,  2 }, {  3,  4,  1 }, { -3,  4,  1 },
         },
         //level_add
         { 0,10, 6, 4, 4, 3, 3, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         1, //golomb_order
         2, //inc_limit
         11 //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {     EOB    }, {  1,  1,  0 }, { -1,  1,  0 }, {  2,  1,  0 }, { -2,  1,  0 }, {  3,  1,  0 },
             { -3,  1,  0 }, {  4,  1,  0 }, { -4,  1,  0 }, {  1,  2,  0 }, { -1,  2,  0 }, {  5,  1,  1 },
             { -5,  1,  1 }, {  2,  2,  0 }, { -2,  2,  0 }, {  6,  1,  1 }, { -6,  1,  1 }, {  1,  3,  0 },
             { -1,  3,  0 }, {  7,  1,  1 }, { -7,  1,  1 }, {  3,  2,  0 }, { -3,  2,  0 }, {  8,  1,  1 },
             { -8,  1,  1 }, {  1,  4,  0 }, { -1,  4,  0 }, {  2,  3,  0 }, { -2,  3,  0 }, {  9,  1,  1 },
             { -9,  1,  1 }, {  4,  2,  0 }, { -4,  2,  0 }, {  1,  5,  0 }, { -1,  5,  0 }, { 10,  1,  1 },
             {-10,  1,  1 }, {  3,  3,  0 }, { -3,  3,  0 }, {  5,  2,  1 }, { -5,  2,  1 }, {  2,  4,  0 },
             { -2,  4,  0 }, { 11,  1,  1 }, {-11,  1,  1 }, {  1,  6,  0 }, { -1,  6,  0 }, { 12,  1,  1 },
             {-12,  1,  1 }, {  1,  7,  0 }, { -1,  7,  0 }, {  6,  2,  1 }, { -6,  2,  1 }, { 13,  1,  1 },
             {-13,  1,  1 }, {  2,  5,  0 }, { -2,  5,  0 }, {  1,  8,  0 }, { -1,  8,  0 },
         },
         //level_add
         { 0, 14, 7, 4, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         1, //golomb_order
         4, //inc_limit
         8  //max_run
ef07ac1e
     },
185c2ef8
     {
         { //level / run
             {      EOB    }, {  1,  1,  0 }, {  -1,  1,  0 }, {  2,  1,  0 }, {  -2,  1,  0 }, {  3,  1,  0 },
             {  -3,  1,  0 }, {  4,  1,  0 }, {  -4,  1,  0 }, {  5,  1,  0 }, {  -5,  1,  0 }, {  6,  1,  0 },
             {  -6,  1,  0 }, {  7,  1,  0 }, {  -7,  1,  0 }, {  8,  1,  0 }, {  -8,  1,  0 }, {  1,  2,  0 },
             {  -1,  2,  0 }, {  9,  1,  0 }, {  -9,  1,  0 }, { 10,  1,  0 }, { -10,  1,  0 }, { 11,  1,  0 },
             { -11,  1,  0 }, {  2,  2,  0 }, {  -2,  2,  0 }, { 12,  1,  0 }, { -12,  1,  0 }, { 13,  1,  0 },
             { -13,  1,  0 }, {  3,  2,  0 }, {  -3,  2,  0 }, { 14,  1,  0 }, { -14,  1,  0 }, {  1,  3,  0 },
             {  -1,  3,  0 }, { 15,  1,  0 }, { -15,  1,  0 }, {  4,  2,  0 }, {  -4,  2,  0 }, { 16,  1,  0 },
             { -16,  1,  0 }, { 17,  1,  0 }, { -17,  1,  0 }, {  5,  2,  0 }, {  -5,  2,  0 }, {  1,  4,  0 },
             {  -1,  4,  0 }, {  2,  3,  0 }, {  -2,  3,  0 }, { 18,  1,  0 }, { -18,  1,  0 }, {  6,  2,  0 },
             {  -6,  2,  0 }, { 19,  1,  0 }, { -19,  1,  0 }, {  1,  5,  0 }, {  -1,  5,  0 },
         },
         //level_add
         { 0, 20, 7, 3, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
         0, //golomb_order
         INT_MAX, //inc_limit
         5, //max_run
     }
ef07ac1e
 };
 
 #undef EOB
 
844d9012
 /*****************************************************************************
  *
  * motion vector prediction
  *
  ****************************************************************************/
 
185c2ef8
 static inline void store_mvs(AVSContext *h)
 {
     h->col_mv[h->mbidx * 4 + 0] = h->mv[MV_FWD_X0];
     h->col_mv[h->mbidx * 4 + 1] = h->mv[MV_FWD_X1];
     h->col_mv[h->mbidx * 4 + 2] = h->mv[MV_FWD_X2];
     h->col_mv[h->mbidx * 4 + 3] = h->mv[MV_FWD_X3];
844d9012
 }
 
e685e8ea
 static inline void mv_pred_direct(AVSContext *h, cavs_vector *pmv_fw,
185c2ef8
                                   cavs_vector *col_mv)
 {
e685e8ea
     cavs_vector *pmv_bw = pmv_fw + MV_BWD_OFFS;
844d9012
     int den = h->direct_den[col_mv->ref];
     int m = col_mv->x >> 31;
 
     pmv_fw->dist = h->dist[1];
     pmv_bw->dist = h->dist[0];
     pmv_fw->ref = 1;
     pmv_bw->ref = 0;
     /* scale the co-located motion vector according to its temporal span */
185c2ef8
     pmv_fw->x =     (((den + (den * col_mv->x * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;
     pmv_bw->x = m - (((den + (den * col_mv->x * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);
844d9012
     m = col_mv->y >> 31;
185c2ef8
     pmv_fw->y =     (((den + (den * col_mv->y * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;
     pmv_bw->y = m - (((den + (den * col_mv->y * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);
844d9012
 }
 
185c2ef8
 static inline void mv_pred_sym(AVSContext *h, cavs_vector *src,
                                enum cavs_block size)
 {
e685e8ea
     cavs_vector *dst = src + MV_BWD_OFFS;
844d9012
 
     /* backward mv is the scaled and negated forward mv */
     dst->x = -((src->x * h->sym_factor + 256) >> 9);
     dst->y = -((src->y * h->sym_factor + 256) >> 9);
     dst->ref = 0;
     dst->dist = h->dist[0];
     set_mvs(dst, size);
 }
 
 /*****************************************************************************
  *
  * residual data decoding
  *
  ****************************************************************************/
 
 /** kth-order exponential golomb code */
185c2ef8
 static inline int get_ue_code(GetBitContext *gb, int order)
 {
cf48b006
     unsigned ret = get_ue_golomb(gb);
     if (ret >= ((1U<<31)>>order)) {
         av_log(NULL, AV_LOG_ERROR, "get_ue_code: value too larger\n");
         return AVERROR_INVALIDDATA;
     }
185c2ef8
     if (order) {
cf48b006
         return (ret<<order) + get_bits(gb, order);
844d9012
     }
cf48b006
     return ret;
844d9012
 }
 
88bd7fdc
 static inline int dequant(AVSContext *h, int16_t *level_buf, uint8_t *run_buf,
                           int16_t *dst, int mul, int shift, int coeff_num)
185c2ef8
 {
a6d9f9e6
     int round = 1 << (shift - 1);
     int pos = -1;
     const uint8_t *scantab = h->scantable.permutated;
 
     /* inverse scan and dequantization */
185c2ef8
     while (--coeff_num >= 0) {
a6d9f9e6
         pos += run_buf[coeff_num];
185c2ef8
         if (pos > 63) {
7d848264
             av_log(h->avctx, AV_LOG_ERROR,
185c2ef8
                    "position out of block bounds at pic %d MB(%d,%d)\n",
7d848264
                    h->cur.poc, h->mbx, h->mby);
a6d9f9e6
             return -1;
         }
185c2ef8
         dst[scantab[pos]] = (level_buf[coeff_num] * mul + round) >> shift;
a6d9f9e6
     }
     return 0;
 }
 
844d9012
 /**
  * decode coefficients from one 8x8 block, dequantize, inverse transform
  *  and add them to sample block
  * @param r pointer to 2D VLC table
  * @param esc_golomb_order escape codes are k-golomb with this order k
  * @param qp quantizer
  * @param dst location of sample block
  * @param stride line stride in frame buffer
  */
 static int decode_residual_block(AVSContext *h, GetBitContext *gb,
9506090d
                                  const struct dec_2dvlc *r, int esc_golomb_order,
185c2ef8
                                  int qp, uint8_t *dst, int stride)
 {
6481a360
     int i, esc_code, level, mask;
     unsigned int level_code, run;
88bd7fdc
     int16_t level_buf[65];
6138ed77
     uint8_t run_buf[65];
88bd7fdc
     int16_t *block = h->block;
844d9012
 
6ddda83c
     for (i = 0; i < 65; i++) {
185c2ef8
         level_code = get_ue_code(gb, r->golomb_order);
         if (level_code >= ESCAPE_CODE) {
             run      = ((level_code - ESCAPE_CODE) >> 1) + 1;
961a1a81
             if(run > 64)
                 return -1;
185c2ef8
             esc_code = get_ue_code(gb, esc_golomb_order);
             level    = esc_code + (run > r->max_run ? 1 : r->level_add[run]);
             while (level > r->inc_limit)
844d9012
                 r++;
185c2ef8
             mask  = -(level_code & 1);
             level = (level ^ mask) - mask;
844d9012
         } else {
             level = r->rltab[level_code][0];
185c2ef8
             if (!level) //end of block signal
844d9012
                 break;
185c2ef8
             run = r->rltab[level_code][1];
             r  += r->rltab[level_code][2];
844d9012
         }
         level_buf[i] = level;
185c2ef8
         run_buf[i]   = run;
844d9012
     }
ef07ac1e
     if (dequant(h, level_buf, run_buf, block, dequant_mul[qp],
                 dequant_shift[qp], i))
844d9012
         return -1;
185c2ef8
     h->cdsp.cavs_idct8_add(dst, block, stride);
7d848264
     h->dsp.clear_block(block);
844d9012
     return 0;
 }
 
 
185c2ef8
 static inline void decode_residual_chroma(AVSContext *h)
 {
     if (h->cbp & (1 << 4))
7d848264
         decode_residual_block(h, &h->gb, chroma_dec, 0,
ef07ac1e
                               cavs_chroma_qp[h->qp], h->cu, h->c_stride);
185c2ef8
     if (h->cbp & (1 << 5))
7d848264
         decode_residual_block(h, &h->gb, chroma_dec, 0,
ef07ac1e
                               cavs_chroma_qp[h->qp], h->cv, h->c_stride);
844d9012
 }
 
185c2ef8
 static inline int decode_residual_inter(AVSContext *h)
 {
844d9012
     int block;
 
     /* get coded block pattern */
7d848264
     int cbp = get_ue_golomb(&h->gb);
6ddda83c
     if (cbp > 63U) {
7d848264
         av_log(h->avctx, AV_LOG_ERROR, "illegal inter cbp\n");
844d9012
         return -1;
     }
     h->cbp = cbp_tab[cbp][1];
 
     /* get quantizer */
185c2ef8
     if (h->cbp && !h->qp_fixed)
7d848264
         h->qp = (h->qp + get_se_golomb(&h->gb)) & 63;
185c2ef8
     for (block = 0; block < 4; block++)
         if (h->cbp & (1 << block))
7d848264
             decode_residual_block(h, &h->gb, inter_dec, 0, h->qp,
844d9012
                                   h->cy + h->luma_scan[block], h->l_stride);
     decode_residual_chroma(h);
 
     return 0;
 }
 
 /*****************************************************************************
  *
  * macroblock level
  *
  ****************************************************************************/
 
185c2ef8
 static inline void set_mv_intra(AVSContext *h)
 {
a6d9f9e6
     h->mv[MV_FWD_X0] = ff_cavs_intra_mv;
     set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
     h->mv[MV_BWD_X0] = ff_cavs_intra_mv;
     set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
fb0cb11f
     if (h->cur.f->pict_type != AV_PICTURE_TYPE_B)
a6d9f9e6
         h->col_type_base[h->mbidx] = I_8X8;
 }
 
185c2ef8
 static int decode_mb_i(AVSContext *h, int cbp_code)
 {
7d848264
     GetBitContext *gb = &h->gb;
4a71da0f
     unsigned pred_mode_uv;
     int block;
844d9012
     uint8_t top[18];
     uint8_t *left = NULL;
     uint8_t *d;
 
5d2b15b8
     ff_cavs_init_mb(h);
844d9012
 
     /* get intra prediction modes from stream */
185c2ef8
     for (block = 0; block < 4; block++) {
         int nA, nB, predpred;
ef07ac1e
         int pos = scan3x3[block];
844d9012
 
185c2ef8
         nA = h->pred_mode_Y[pos - 1];
         nB = h->pred_mode_Y[pos - 3];
         predpred = FFMIN(nA, nB);
         if (predpred == NOT_AVAIL) // if either is not available
844d9012
             predpred = INTRA_L_LP;
185c2ef8
         if (!get_bits1(gb)) {
             int rem_mode = get_bits(gb, 2);
             predpred     = rem_mode + (rem_mode >= predpred);
844d9012
         }
         h->pred_mode_Y[pos] = predpred;
     }
     pred_mode_uv = get_ue_golomb(gb);
185c2ef8
     if (pred_mode_uv > 6) {
7d848264
         av_log(h->avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n");
844d9012
         return -1;
     }
5d2b15b8
     ff_cavs_modify_mb_i(h, &pred_mode_uv);
844d9012
 
     /* get coded block pattern */
fb0cb11f
     if (h->cur.f->pict_type == AV_PICTURE_TYPE_I)
844d9012
         cbp_code = get_ue_golomb(gb);
6ddda83c
     if (cbp_code > 63U) {
7d848264
         av_log(h->avctx, AV_LOG_ERROR, "illegal intra cbp\n");
844d9012
         return -1;
     }
     h->cbp = cbp_tab[cbp_code][0];
185c2ef8
     if (h->cbp && !h->qp_fixed)
844d9012
         h->qp = (h->qp + get_se_golomb(gb)) & 63; //qp_delta
 
     /* luma intra prediction interleaved with residual decode/transform/add */
185c2ef8
     for (block = 0; block < 4; block++) {
844d9012
         d = h->cy + h->luma_scan[block];
5d2b15b8
         ff_cavs_load_intra_pred_luma(h, top, &left, block);
ef07ac1e
         h->intra_pred_l[h->pred_mode_Y[scan3x3[block]]]
844d9012
             (d, top, left, h->l_stride);
185c2ef8
         if (h->cbp & (1<<block))
ef07ac1e
             decode_residual_block(h, gb, intra_dec, 1, h->qp, d, h->l_stride);
844d9012
     }
 
     /* chroma intra prediction */
5d2b15b8
     ff_cavs_load_intra_pred_chroma(h);
185c2ef8
     h->intra_pred_c[pred_mode_uv](h->cu, &h->top_border_u[h->mbx * 10],
844d9012
                                   h->left_border_u, h->c_stride);
185c2ef8
     h->intra_pred_c[pred_mode_uv](h->cv, &h->top_border_v[h->mbx * 10],
844d9012
                                   h->left_border_v, h->c_stride);
 
     decode_residual_chroma(h);
185c2ef8
     ff_cavs_filter(h, I_8X8);
844d9012
     set_mv_intra(h);
     return 0;
 }
 
185c2ef8
 static inline void set_intra_mode_default(AVSContext *h)
 {
     if (h->stream_revision > 0) {
a6d9f9e6
         h->pred_mode_Y[3] =  h->pred_mode_Y[6] = NOT_AVAIL;
185c2ef8
         h->top_pred_Y[h->mbx * 2 + 0] = h->top_pred_Y[h->mbx * 2 + 1] = NOT_AVAIL;
a6d9f9e6
     } else {
         h->pred_mode_Y[3] =  h->pred_mode_Y[6] = INTRA_L_LP;
185c2ef8
         h->top_pred_Y[h->mbx * 2 + 0] = h->top_pred_Y[h->mbx * 2 + 1] = INTRA_L_LP;
a6d9f9e6
     }
 }
 
185c2ef8
 static void decode_mb_p(AVSContext *h, enum cavs_mb mb_type)
 {
7d848264
     GetBitContext *gb = &h->gb;
844d9012
     int ref[4];
 
5d2b15b8
     ff_cavs_init_mb(h);
185c2ef8
     switch (mb_type) {
844d9012
     case P_SKIP:
         ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_PSKIP,  BLK_16X16, 0);
         break;
     case P_16X16:
         ref[0] = h->ref_flag ? 0 : get_bits1(gb);
185c2ef8
         ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, ref[0]);
844d9012
         break;
     case P_16X8:
         ref[0] = h->ref_flag ? 0 : get_bits1(gb);
         ref[2] = h->ref_flag ? 0 : get_bits1(gb);
         ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP,    BLK_16X8, ref[0]);
         ff_cavs_mv(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT,   BLK_16X8, ref[2]);
         break;
     case P_8X16:
         ref[0] = h->ref_flag ? 0 : get_bits1(gb);
         ref[1] = h->ref_flag ? 0 : get_bits1(gb);
185c2ef8
         ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT,     BLK_8X16, ref[0]);
         ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, ref[1]);
844d9012
         break;
     case P_8X8:
         ref[0] = h->ref_flag ? 0 : get_bits1(gb);
         ref[1] = h->ref_flag ? 0 : get_bits1(gb);
         ref[2] = h->ref_flag ? 0 : get_bits1(gb);
         ref[3] = h->ref_flag ? 0 : get_bits1(gb);
         ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_MEDIAN,   BLK_8X8, ref[0]);
         ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_MEDIAN,   BLK_8X8, ref[1]);
         ff_cavs_mv(h, MV_FWD_X2, MV_FWD_X1, MV_PRED_MEDIAN,   BLK_8X8, ref[2]);
         ff_cavs_mv(h, MV_FWD_X3, MV_FWD_X0, MV_PRED_MEDIAN,   BLK_8X8, ref[3]);
     }
     ff_cavs_inter(h, mb_type);
     set_intra_mode_default(h);
     store_mvs(h);
185c2ef8
     if (mb_type != P_SKIP)
844d9012
         decode_residual_inter(h);
185c2ef8
     ff_cavs_filter(h, mb_type);
6847ab43
     h->col_type_base[h->mbidx] = mb_type;
844d9012
 }
 
6ddda83c
 static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type)
185c2ef8
 {
844d9012
     int block;
bef01ca0
     enum cavs_sub_mb sub_type[4];
844d9012
     int flags;
 
5d2b15b8
     ff_cavs_init_mb(h);
844d9012
 
     /* reset all MVs */
     h->mv[MV_FWD_X0] = ff_cavs_dir_mv;
     set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
     h->mv[MV_BWD_X0] = ff_cavs_dir_mv;
     set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
185c2ef8
     switch (mb_type) {
844d9012
     case B_SKIP:
     case B_DIRECT:
185c2ef8
         if (!h->col_type_base[h->mbidx]) {
844d9012
             /* intra MB at co-location, do in-plane prediction */
             ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_BSKIP, BLK_16X16, 1);
             ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_BSKIP, BLK_16X16, 0);
         } else
             /* direct prediction from co-located P MB, block-wise */
185c2ef8
             for (block = 0; block < 4; block++)
                 mv_pred_direct(h, &h->mv[mv_scan[block]],
                                &h->col_mv[h->mbidx * 4 + block]);
844d9012
         break;
     case B_FWD_16X16:
         ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1);
         break;
     case B_SYM_16X16:
         ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1);
         mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_16X16);
         break;
     case B_BWD_16X16:
         ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_MEDIAN, BLK_16X16, 0);
         break;
     case B_8X8:
185c2ef8
         for (block = 0; block < 4; block++)
7d848264
             sub_type[block] = get_bits(&h->gb, 2);
185c2ef8
         for (block = 0; block < 4; block++) {
             switch (sub_type[block]) {
844d9012
             case B_SUB_DIRECT:
185c2ef8
                 if (!h->col_type_base[h->mbidx]) {
844d9012
                     /* intra MB at co-location, do in-plane prediction */
185c2ef8
                     ff_cavs_mv(h, mv_scan[block], mv_scan[block] - 3,
                                MV_PRED_BSKIP, BLK_8X8, 1);
                     ff_cavs_mv(h, mv_scan[block] + MV_BWD_OFFS,
                                mv_scan[block] - 3 + MV_BWD_OFFS,
                                MV_PRED_BSKIP, BLK_8X8, 0);
844d9012
                 } else
185c2ef8
                     mv_pred_direct(h, &h->mv[mv_scan[block]],
                                    &h->col_mv[h->mbidx * 4 + block]);
844d9012
                 break;
             case B_SUB_FWD:
185c2ef8
                 ff_cavs_mv(h, mv_scan[block], mv_scan[block] - 3,
                            MV_PRED_MEDIAN, BLK_8X8, 1);
844d9012
                 break;
             case B_SUB_SYM:
185c2ef8
                 ff_cavs_mv(h, mv_scan[block], mv_scan[block] - 3,
                            MV_PRED_MEDIAN, BLK_8X8, 1);
844d9012
                 mv_pred_sym(h, &h->mv[mv_scan[block]], BLK_8X8);
                 break;
             }
         }
185c2ef8
         for (block = 0; block < 4; block++) {
             if (sub_type[block] == B_SUB_BWD)
                 ff_cavs_mv(h, mv_scan[block] + MV_BWD_OFFS,
                            mv_scan[block] + MV_BWD_OFFS - 3,
                            MV_PRED_MEDIAN, BLK_8X8, 0);
844d9012
         }
         break;
     default:
7ea5dbcb
         if (mb_type <= B_SYM_16X16) {
ca95d1b3
             av_log(h->avctx, AV_LOG_ERROR, "Invalid mb_type %d in B frame\n", mb_type);
7ea5dbcb
             return AVERROR_INVALIDDATA;
         }
         av_assert2(mb_type < B_8X8);
844d9012
         flags = ff_cavs_partition_flags[mb_type];
185c2ef8
         if (mb_type & 1) { /* 16x8 macroblock types */
             if (flags & FWD0)
844d9012
                 ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP,  BLK_16X8, 1);
185c2ef8
             if (flags & SYM0)
844d9012
                 mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_16X8);
185c2ef8
             if (flags & FWD1)
844d9012
                 ff_cavs_mv(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT, BLK_16X8, 1);
185c2ef8
             if (flags & SYM1)
844d9012
                 mv_pred_sym(h, &h->mv[MV_FWD_X2], BLK_16X8);
185c2ef8
             if (flags & BWD0)
844d9012
                 ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_TOP,  BLK_16X8, 0);
185c2ef8
             if (flags & BWD1)
844d9012
                 ff_cavs_mv(h, MV_BWD_X2, MV_BWD_A1, MV_PRED_LEFT, BLK_16X8, 0);
         } else {          /* 8x16 macroblock types */
185c2ef8
             if (flags & FWD0)
844d9012
                 ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, 1);
185c2ef8
             if (flags & SYM0)
844d9012
                 mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_8X16);
185c2ef8
             if (flags & FWD1)
                 ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, 1);
             if (flags & SYM1)
844d9012
                 mv_pred_sym(h, &h->mv[MV_FWD_X1], BLK_8X16);
185c2ef8
             if (flags & BWD0)
844d9012
                 ff_cavs_mv(h, MV_BWD_X0, MV_BWD_B3, MV_PRED_LEFT, BLK_8X16, 0);
185c2ef8
             if (flags & BWD1)
                 ff_cavs_mv(h, MV_BWD_X1, MV_BWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, 0);
844d9012
         }
     }
     ff_cavs_inter(h, mb_type);
     set_intra_mode_default(h);
185c2ef8
     if (mb_type != B_SKIP)
844d9012
         decode_residual_inter(h);
185c2ef8
     ff_cavs_filter(h, mb_type);
ba9e9605
 
     return 0;
844d9012
 }
 
 /*****************************************************************************
  *
  * slice level
  *
  ****************************************************************************/
 
185c2ef8
 static inline int decode_slice_header(AVSContext *h, GetBitContext *gb)
 {
     if (h->stc > 0xAF)
7d848264
         av_log(h->avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc);
71e78e1f
 
     if (h->stc >= h->mb_height)
         return -1;
 
185c2ef8
     h->mby   = h->stc;
     h->mbidx = h->mby * h->mb_width;
b9fce052
 
     /* mark top macroblocks as unavailable */
185c2ef8
     h->flags &= ~(B_AVAIL | C_AVAIL);
     if ((h->mby == 0) && (!h->qp_fixed)) {
844d9012
         h->qp_fixed = get_bits1(gb);
185c2ef8
         h->qp       = get_bits(gb, 6);
844d9012
     }
     /* inter frame or second slice can have weighting params */
fb0cb11f
     if ((h->cur.f->pict_type != AV_PICTURE_TYPE_I) ||
185c2ef8
         (!h->pic_structure && h->mby >= h->mb_width / 2))
         if (get_bits1(gb)) { //slice_weighting_flag
7d848264
             av_log(h->avctx, AV_LOG_ERROR,
844d9012
                    "weighted prediction not yet supported\n");
         }
     return 0;
 }
 
185c2ef8
 static inline int check_for_slice(AVSContext *h)
 {
7d848264
     GetBitContext *gb = &h->gb;
844d9012
     int align;
b9fce052
 
185c2ef8
     if (h->mbx)
88db5551
         return 0;
844d9012
     align = (-get_bits_count(gb)) & 7;
cd3356ff
     /* check for stuffing byte */
185c2ef8
     if (!align && (show_bits(gb, 8) == 0x80))
470de55a
         align = 8;
185c2ef8
     if ((show_bits_long(gb, 24 + align) & 0xFFFFFF) == 0x000001) {
         skip_bits_long(gb, 24 + align);
         h->stc = get_bits(gb, 8);
4a71da0f
         if (h->stc >= h->mb_height)
             return 0;
185c2ef8
         decode_slice_header(h, gb);
88db5551
         return 1;
844d9012
     }
88db5551
     return 0;
844d9012
 }
 
 /*****************************************************************************
  *
  * frame level
  *
  ****************************************************************************/
 
185c2ef8
 static int decode_pic(AVSContext *h)
 {
     int skip_count    = -1;
eee8c94f
     int ret;
bef01ca0
     enum cavs_mb mb_type;
844d9012
 
7d848264
     skip_bits(&h->gb, 16);//bbv_dwlay
185c2ef8
     if (h->stc == PIC_PB_START_CODE) {
fb0cb11f
         h->cur.f->pict_type = get_bits(&h->gb, 2) + AV_PICTURE_TYPE_I;
         if (h->cur.f->pict_type > AV_PICTURE_TYPE_B) {
7d848264
             av_log(h->avctx, AV_LOG_ERROR, "illegal picture type\n");
844d9012
             return -1;
         }
         /* make sure we have the reference frames we need */
7d848264
         if (!h->DPB[0].f->data[0] ||
fb0cb11f
            (!h->DPB[1].f->data[0] && h->cur.f->pict_type == AV_PICTURE_TYPE_B))
844d9012
             return -1;
     } else {
fb0cb11f
         h->cur.f->pict_type = AV_PICTURE_TYPE_I;
7d848264
         if (get_bits1(&h->gb))
             skip_bits(&h->gb, 24);//time_code
35122bd9
         /* old sample clips were all progressive and no low_delay,
            bump stream revision if detected otherwise */
7d848264
         if (h->low_delay || !(show_bits(&h->gb, 9) & 1))
35122bd9
             h->stream_revision = 1;
         /* similarly test top_field_first and repeat_first_field */
7d848264
         else if (show_bits(&h->gb, 11) & 3)
35122bd9
             h->stream_revision = 1;
185c2ef8
         if (h->stream_revision > 0)
7d848264
             skip_bits(&h->gb, 1); //marker_bit
844d9012
     }
     /* release last B frame */
7d848264
     if (h->cur.f->data[0])
         h->avctx->release_buffer(h->avctx, h->cur.f);
844d9012
 
ca95d1b3
     if ((ret = ff_get_buffer(h->avctx, h->cur.f)) < 0)
eee8c94f
         return ret;
7d848264
 
     if (!h->edge_emu_buffer) {
         int alloc_size = FFALIGN(FFABS(h->cur.f->linesize[0]) + 32, 32);
         h->edge_emu_buffer = av_mallocz(alloc_size * 2 * 24);
         if (!h->edge_emu_buffer)
             return AVERROR(ENOMEM);
     }
844d9012
 
642a655f
     if ((ret = ff_cavs_init_pic(h)) < 0)
         return ret;
7d848264
     h->cur.poc = get_bits(&h->gb, 8) * 2;
844d9012
 
     /* get temporal distances and MV scaling factors */
fb0cb11f
     if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
7d848264
         h->dist[0] = (h->cur.poc - h->DPB[0].poc  + 512) % 512;
844d9012
     } else {
7d848264
         h->dist[0] = (h->DPB[0].poc  - h->cur.poc + 512) % 512;
844d9012
     }
7d848264
     h->dist[1] = (h->cur.poc - h->DPB[1].poc  + 512) % 512;
844d9012
     h->scale_den[0] = h->dist[0] ? 512/h->dist[0] : 0;
     h->scale_den[1] = h->dist[1] ? 512/h->dist[1] : 0;
fb0cb11f
     if (h->cur.f->pict_type == AV_PICTURE_TYPE_B) {
185c2ef8
         h->sym_factor = h->dist[0] * h->scale_den[1];
844d9012
     } else {
185c2ef8
         h->direct_den[0] = h->dist[0] ? 16384 / h->dist[0] : 0;
         h->direct_den[1] = h->dist[1] ? 16384 / h->dist[1] : 0;
844d9012
     }
 
7d848264
     if (h->low_delay)
         get_ue_golomb(&h->gb); //bbv_check_times
     h->progressive   = get_bits1(&h->gb);
4ca6f4b2
     h->pic_structure = 1;
185c2ef8
     if (!h->progressive)
7d848264
         h->pic_structure = get_bits1(&h->gb);
185c2ef8
     if (!h->pic_structure && h->stc == PIC_PB_START_CODE)
7d848264
         skip_bits1(&h->gb);     //advanced_pred_mode_disable
     skip_bits1(&h->gb);        //top_field_first
     skip_bits1(&h->gb);        //repeat_first_field
     h->qp_fixed = get_bits1(&h->gb);
     h->qp       = get_bits(&h->gb, 6);
fb0cb11f
     if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) {
185c2ef8
         if (!h->progressive && !h->pic_structure)
7d848264
             skip_bits1(&h->gb);//what is this?
         skip_bits(&h->gb, 4);   //reserved bits
844d9012
     } else {
fb0cb11f
         if (!(h->cur.f->pict_type == AV_PICTURE_TYPE_B && h->pic_structure == 1))
7d848264
             h->ref_flag        = get_bits1(&h->gb);
         skip_bits(&h->gb, 4);   //reserved bits
         h->skip_mode_flag      = get_bits1(&h->gb);
844d9012
     }
7d848264
     h->loop_filter_disable     = get_bits1(&h->gb);
     if (!h->loop_filter_disable && get_bits1(&h->gb)) {
         h->alpha_offset        = get_se_golomb(&h->gb);
         h->beta_offset         = get_se_golomb(&h->gb);
844d9012
     } else {
         h->alpha_offset = h->beta_offset  = 0;
     }
fb0cb11f
     if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) {
844d9012
         do {
b9fce052
             check_for_slice(h);
844d9012
             decode_mb_i(h, 0);
185c2ef8
         } while (ff_cavs_next_mb(h));
fb0cb11f
     } else if (h->cur.f->pict_type == AV_PICTURE_TYPE_P) {
844d9012
         do {
185c2ef8
             if (check_for_slice(h))
88db5551
                 skip_count = -1;
185c2ef8
             if (h->skip_mode_flag && (skip_count < 0))
7d848264
                 skip_count = get_ue_golomb(&h->gb);
185c2ef8
             if (h->skip_mode_flag && skip_count--) {
                 decode_mb_p(h, P_SKIP);
88db5551
             } else {
7d848264
                 mb_type = get_ue_golomb(&h->gb) + P_SKIP + h->skip_mode_flag;
185c2ef8
                 if (mb_type > P_8X8)
88db5551
                     decode_mb_i(h, mb_type - P_8X8 - 1);
                 else
185c2ef8
                     decode_mb_p(h, mb_type);
88db5551
             }
185c2ef8
         } while (ff_cavs_next_mb(h));
ce5e49b0
     } else { /* AV_PICTURE_TYPE_B */
844d9012
         do {
185c2ef8
             if (check_for_slice(h))
88db5551
                 skip_count = -1;
185c2ef8
             if (h->skip_mode_flag && (skip_count < 0))
7d848264
                 skip_count = get_ue_golomb(&h->gb);
185c2ef8
             if (h->skip_mode_flag && skip_count--) {
                 decode_mb_b(h, B_SKIP);
88db5551
             } else {
7d848264
                 mb_type = get_ue_golomb(&h->gb) + B_SKIP + h->skip_mode_flag;
185c2ef8
                 if (mb_type > B_8X8)
88db5551
                     decode_mb_i(h, mb_type - B_8X8 - 1);
                 else
185c2ef8
                     decode_mb_b(h, mb_type);
88db5551
             }
185c2ef8
         } while (ff_cavs_next_mb(h));
844d9012
     }
fb0cb11f
     if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
7d848264
         if (h->DPB[1].f->data[0])
             h->avctx->release_buffer(h->avctx, h->DPB[1].f);
         FFSWAP(AVSFrame, h->cur, h->DPB[1]);
         FFSWAP(AVSFrame, h->DPB[0], h->DPB[1]);
844d9012
     }
     return 0;
 }
 
 /*****************************************************************************
  *
  * headers and interface
  *
  ****************************************************************************/
 
185c2ef8
 static int decode_seq_header(AVSContext *h)
 {
844d9012
     int frame_rate_code;
25715064
     int width, height;
844d9012
 
7d848264
     h->profile = get_bits(&h->gb, 8);
     h->level   = get_bits(&h->gb, 8);
     skip_bits1(&h->gb); //progressive sequence
c20a6963
 
7d848264
     width  = get_bits(&h->gb, 14);
     height = get_bits(&h->gb, 14);
     if ((h->width || h->height) && (h->width != width || h->height != height)) {
         av_log_missing_feature(h->avctx, "Width/height changing in CAVS", 0);
c20a6963
         return AVERROR_PATCHWELCOME;
25715064
     }
f9505923
     if (width <= 0 || height <= 0) {
ca95d1b3
         av_log(h->avctx, AV_LOG_ERROR, "Dimensions invalid\n");
f9505923
         return AVERROR_INVALIDDATA;
     }
7d848264
     h->width  = width;
     h->height = height;
 
     skip_bits(&h->gb, 2); //chroma format
     skip_bits(&h->gb, 3); //sample_precision
     h->aspect_ratio = get_bits(&h->gb, 4);
     frame_rate_code = get_bits(&h->gb, 4);
     skip_bits(&h->gb, 18); //bit_rate_lower
     skip_bits1(&h->gb);    //marker_bit
     skip_bits(&h->gb, 12); //bit_rate_upper
     h->low_delay =  get_bits1(&h->gb);
     h->mb_width  = (h->width  + 15) >> 4;
     h->mb_height = (h->height + 15) >> 4;
     h->avctx->time_base.den = ff_mpeg12_frame_rate_tab[frame_rate_code].num;
     h->avctx->time_base.num = ff_mpeg12_frame_rate_tab[frame_rate_code].den;
     h->avctx->width  = h->width;
     h->avctx->height = h->height;
185c2ef8
     if (!h->top_qp)
844d9012
         ff_cavs_init_top_lines(h);
     return 0;
 }
 
185c2ef8
 static void cavs_flush(AVCodecContext * avctx)
 {
844d9012
     AVSContext *h = avctx->priv_data;
     h->got_keyframe = 0;
 }
 
df9b9567
 static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
185c2ef8
                              AVPacket *avpkt)
 {
     AVSContext *h      = avctx->priv_data;
7a00bbad
     const uint8_t *buf = avpkt->data;
185c2ef8
     int buf_size       = avpkt->size;
     AVFrame *picture   = data;
     uint32_t stc       = -1;
844d9012
     int input_size;
     const uint8_t *buf_end;
     const uint8_t *buf_ptr;
 
     if (buf_size == 0) {
7d848264
         if (!h->low_delay && h->DPB[0].f->data[0]) {
df9b9567
             *got_frame = 1;
7d848264
             *picture = *h->DPB[0].f;
             if (h->cur.f->data[0])
                 avctx->release_buffer(avctx, h->cur.f);
             FFSWAP(AVSFrame, h->cur, h->DPB[0]);
844d9012
         }
         return 0;
     }
 
     buf_ptr = buf;
     buf_end = buf + buf_size;
     for(;;) {
185c2ef8
         buf_ptr = avpriv_mpv_find_start_code(buf_ptr, buf_end, &stc);
         if ((stc & 0xFFFFFE00) || buf_ptr == buf_end)
7d848264
             return FFMAX(0, buf_ptr - buf);
185c2ef8
         input_size = (buf_end - buf_ptr) * 8;
         switch (stc) {
844d9012
         case CAVS_START_CODE:
7d848264
             init_get_bits(&h->gb, buf_ptr, input_size);
844d9012
             decode_seq_header(h);
             break;
         case PIC_I_START_CODE:
185c2ef8
             if (!h->got_keyframe) {
7d848264
                 if(h->DPB[0].f->data[0])
                     avctx->release_buffer(avctx, h->DPB[0].f);
                 if(h->DPB[1].f->data[0])
                     avctx->release_buffer(avctx, h->DPB[1].f);
844d9012
                 h->got_keyframe = 1;
             }
         case PIC_PB_START_CODE:
df9b9567
             *got_frame = 0;
185c2ef8
             if (!h->got_keyframe)
844d9012
                 break;
ec0965be
             if(!h->top_qp)
                 break;
7d848264
             init_get_bits(&h->gb, buf_ptr, input_size);
844d9012
             h->stc = stc;
185c2ef8
             if (decode_pic(h))
844d9012
                 break;
df9b9567
             *got_frame = 1;
fb0cb11f
             if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
7d848264
                 if (h->DPB[1].f->data[0]) {
                     *picture = *h->DPB[1].f;
844d9012
                 } else {
df9b9567
                     *got_frame = 0;
844d9012
                 }
             } else
7d848264
                 *picture = *h->cur.f;
844d9012
             break;
         case EXT_START_CODE:
185c2ef8
             //mpeg_decode_extension(avctx, buf_ptr, input_size);
844d9012
             break;
         case USER_START_CODE:
185c2ef8
             //mpeg_decode_user_data(avctx, buf_ptr, input_size);
844d9012
             break;
         default:
d934de5c
             if (stc <= SLICE_MAX_START_CODE) {
7d848264
                 init_get_bits(&h->gb, buf_ptr, input_size);
                 decode_slice_header(h, &h->gb);
844d9012
             }
             break;
         }
     }
 }
 
e7e2df27
 AVCodec ff_cavs_decoder = {
ec6402b7
     .name           = "cavs",
     .type           = AVMEDIA_TYPE_VIDEO,
36ef5369
     .id             = AV_CODEC_ID_CAVS,
ec6402b7
     .priv_data_size = sizeof(AVSContext),
     .init           = ff_cavs_init,
     .close          = ff_cavs_end,
     .decode         = cavs_decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
00c3b67b
     .flush          = cavs_flush,
0177b7d2
     .long_name      = NULL_IF_CONFIG_SMALL("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)"),
844d9012
 };