Coverage Report

Created: 2022-08-24 06:17

/src/libde265/libde265/contextmodel.cc
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * H.265 video codec.
3
 * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
4
 *
5
 * This file is part of libde265.
6
 *
7
 * libde265 is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Lesser General Public License as
9
 * published by the Free Software Foundation, either version 3 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * libde265 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
15
 * GNU Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with libde265.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "slice.h"
22
#include <assert.h>
23
#include <iomanip>
24
#include <sstream>
25
26
bool D = false;
27
28
context_model_table::context_model_table()
29
  : model(NULL), refcnt(NULL)
30
49.6k
{
31
49.6k
}
32
33
34
context_model_table::context_model_table(const context_model_table& src)
35
0
{
36
0
  if (D) printf("%p c'tor = %p\n",this,&src);
37
38
0
  if (src.refcnt) {
39
0
    (*(src.refcnt))++;
40
0
  }
41
42
0
  refcnt = src.refcnt;
43
0
  model  = src.model;
44
0
}
45
46
47
context_model_table::~context_model_table()
48
50.7k
{
49
50.7k
  if (D) printf("%p destructor\n",this);
50
51
50.7k
  if (refcnt) {
52
23.8k
    (*refcnt)--;
53
23.8k
    if (*refcnt==0) {
54
23.8k
      if (D) printf("mfree %p\n",model);
55
23.8k
      delete[] model;
56
23.8k
      delete refcnt;
57
23.8k
    }
58
23.8k
  }
59
50.7k
}
60
61
62
void context_model_table::init(int initType, int QPY)
63
3.69k
{
64
3.69k
  if (D) printf("%p init\n",this);
65
66
3.69k
  decouple_or_alloc_with_empty_data();
67
68
3.69k
  initialize_CABAC_models(model, initType, QPY);
69
3.69k
}
70
71
72
void context_model_table::release()
73
61.9k
{
74
61.9k
  if (D) printf("%p release %p\n",this,refcnt);
75
76
61.9k
  if (!refcnt) { return; }
77
78
  // if (*refcnt == 1) { return; } <- keep memory for later, but does not work when we believe that we freed the memory and nulled all references
79
80
19.8k
  (*refcnt)--;
81
19.8k
  if (*refcnt==0) {
82
0
    delete[] model;
83
0
    delete refcnt;
84
0
  }
85
86
19.8k
  model = nullptr;
87
19.8k
  refcnt= nullptr;
88
19.8k
}
89
90
91
void context_model_table::decouple()
92
20.1k
{
93
20.1k
  if (D) printf("%p decouple (%p)\n",this,refcnt);
94
95
20.1k
  assert(refcnt); // not necessarily so, but we never use it on an unitialized object
96
97
20.1k
  if (*refcnt > 1) {
98
20.1k
    (*refcnt)--;
99
100
20.1k
    context_model* oldModel = model;
101
102
20.1k
    model = new context_model[CONTEXT_MODEL_TABLE_LENGTH];
103
20.1k
    refcnt= new int;
104
20.1k
    *refcnt=1;
105
106
20.1k
    memcpy(model,oldModel,sizeof(context_model)*CONTEXT_MODEL_TABLE_LENGTH);
107
20.1k
  }
108
20.1k
}
109
110
111
context_model_table context_model_table::transfer()
112
0
{
113
0
  context_model_table newtable;
114
0
  newtable.model = model;
115
0
  newtable.refcnt= refcnt;
116
117
0
  model =nullptr;
118
0
  refcnt=nullptr;
119
120
0
  return newtable;
121
0
}
122
123
124
context_model_table& context_model_table::operator=(const context_model_table& src)
125
41.0k
{
126
41.0k
  if (D) printf("%p assign = %p\n",this,&src);
127
128
  // assert(src.refcnt); // not necessarily so, but we never use it on an unitialized object
129
130
41.0k
  if (!src.refcnt) {
131
994
    release();
132
994
    return *this;
133
994
  }
134
135
40.0k
  (*(src.refcnt))++;
136
137
40.0k
  release();
138
139
40.0k
  model = src.model;
140
40.0k
  refcnt= src.refcnt;
141
142
40.0k
  return *this;
143
41.0k
}
144
145
146
bool context_model_table::operator==(const context_model_table& b) const
147
0
{
148
0
  if (b.model == model) return true;
149
0
  if (b.model == nullptr || model == nullptr) return false;
150
151
0
  for (int i=0;i<CONTEXT_MODEL_TABLE_LENGTH;i++) {
152
0
    if (!(b.model[i] == model[i])) return false;
153
0
  }
154
155
0
  return true;
156
0
}
157
158
159
std::string context_model_table::debug_dump() const
160
0
{
161
0
  int hash = 0;
162
0
  for (int i=0;i<CONTEXT_MODEL_TABLE_LENGTH;i++) {
163
0
    hash ^= ((i+7)*model[i].state) & 0xFFFF;
164
0
  }
165
166
0
  std::stringstream sstr;
167
0
  sstr << std::hex << hash;
168
0
  return sstr.str();
169
0
}
170
171
172
void context_model_table::decouple_or_alloc_with_empty_data()
173
3.71k
{
174
3.71k
  if (refcnt && *refcnt==1) { return; }
175
176
3.71k
  if (refcnt) {
177
0
    assert(*refcnt>1);
178
0
    (*refcnt)--;
179
0
  }
180
181
3.71k
  if (D) printf("%p (alloc)\n",this);
182
183
3.71k
  model = new context_model[CONTEXT_MODEL_TABLE_LENGTH];
184
3.71k
  refcnt= new int;
185
3.71k
  *refcnt=1;
186
3.71k
}
187
188
189
190
191
192
193
static void set_initValue(int SliceQPY,
194
                          context_model* model, int initValue, int nContexts)
195
528k
{
196
528k
  int slopeIdx = initValue >> 4;
197
528k
  int intersecIdx = initValue & 0xF;
198
528k
  int m = slopeIdx*5 - 45;
199
528k
  int n = (intersecIdx<<3) - 16;
200
528k
  int preCtxState = Clip3(1,126, ((m*Clip3(0,51, SliceQPY))>>4)+n);
201
202
  // logtrace(LogSlice,"QP=%d slopeIdx=%d intersecIdx=%d m=%d n=%d\n",SliceQPY,slopeIdx,intersecIdx,m,n);
203
204
1.08M
  for (int i=0;i<nContexts;i++) {
205
557k
    model[i].MPSbit=(preCtxState<=63) ? 0 : 1;
206
557k
    model[i].state = model[i].MPSbit ? (preCtxState-64) : (63-preCtxState);
207
208
    // model state will always be between [0;62]
209
210
557k
    assert(model[i].state <= 62);
211
557k
  }
212
528k
}
213
214
215
static const int initValue_split_cu_flag[3][3] = {
216
  { 139,141,157 },
217
  { 107,139,126 },
218
  { 107,139,126 },
219
};
220
static const int initValue_cu_skip_flag[2][3] = {
221
  { 197,185,201 },
222
  { 197,185,201 },
223
};
224
static const int initValue_part_mode[9] = { 184,154,139, 154,154,154, 139,154,154 };
225
static const int initValue_prev_intra_luma_pred_flag[3] = { 184,154,183 };
226
static const int initValue_intra_chroma_pred_mode[3] = { 63,152,152 };
227
static const int initValue_cbf_luma[4] = { 111,141,153,111 };
228
static const int initValue_cbf_chroma[12] = { 94,138,182,154,149,107,167,154,149,92,167,154 };
229
static const int initValue_split_transform_flag[9] = { 153,138,138, 124,138,94, 224,167,122 }; // FIX712
230
static const int initValue_last_significant_coefficient_prefix[54] = {
231
    110,110,124,125,140,153,125,127,140,109,111,143,127,111, 79,108,123, 63,
232
    125,110, 94,110, 95, 79,125,111,110, 78,110,111,111, 95, 94,108,123,108,
233
    125,110,124,110, 95, 94,125,111,111, 79,125,126,111,111, 79,108,123, 93
234
  };
235
static const int initValue_coded_sub_block_flag[12] = { 91,171,134,141,121,140,61,154,121,140,61,154 };
236
static const int initValue_significant_coeff_flag[3][42] = {
237
    {
238
      111,  111,  125,  110,  110,   94,  124,  108,  124,  107,  125,  141,  179,  153,  125,  107,
239
      125,  141,  179,  153,  125,  107,  125,  141,  179,  153,  125,  140,  139,  182,  182,  152,
240
      136,  152,  136,  153,  136,  139,  111,  136,  139,  111
241
    },
242
    {
243
      155,  154,  139,  153,  139,  123,  123,   63,  153,  166,  183,  140,  136,  153,  154,  166,
244
      183,  140,  136,  153,  154,  166,  183,  140,  136,  153,  154,  170,  153,  123,  123,  107,
245
      121,  107,  121,  167,  151,  183,  140,  151,  183,  140,
246
    },
247
    {
248
      170,  154,  139,  153,  139,  123,  123,   63,  124,  166,  183,  140,  136,  153,  154,  166,
249
      183,  140,  136,  153,  154,  166,  183,  140,  136,  153,  154,  170,  153,  138,  138,  122,
250
      121,  122,  121,  167,  151,  183,  140,  151,  183,  140
251
    },
252
  };
253
static const int initValue_significant_coeff_flag_skipmode[3][2] = {
254
  { 141,111 }, { 140,140 }, { 140,140 }
255
};
256
257
static const int initValue_coeff_abs_level_greater1_flag[72] = {
258
    140, 92,137,138,140,152,138,139,153, 74,149, 92,139,107,122,152,
259
    140,179,166,182,140,227,122,197,154,196,196,167,154,152,167,182,
260
    182,134,149,136,153,121,136,137,169,194,166,167,154,167,137,182,
261
    154,196,167,167,154,152,167,182,182,134,149,136,153,121,136,122,
262
    169,208,166,167,154,152,167,182
263
  };
264
static const int initValue_coeff_abs_level_greater2_flag[18] = {
265
    138,153,136,167,152,152,107,167, 91,122,107,167,
266
    107,167, 91,107,107,167
267
  };
268
static const int initValue_sao_merge_leftUp_flag[3] = { 153,153,153 };
269
static const int initValue_sao_type_idx_lumaChroma_flag[3] = { 200,185,160 };
270
static const int initValue_cu_qp_delta_abs[2] = { 154,154 };
271
static const int initValue_transform_skip_flag[2] = { 139,139 };
272
static const int initValue_merge_flag[2] = { 110,154 };
273
static const int initValue_merge_idx[2] = { 122,137 };
274
static const int initValue_pred_mode_flag[2] = { 149,134 };
275
static const int initValue_abs_mvd_greater01_flag[4] = { 140,198,169,198 };
276
static const int initValue_mvp_lx_flag[1] = { 168 };
277
static const int initValue_rqt_root_cbf[1] = { 79 };
278
static const int initValue_ref_idx_lX[2] = { 153,153 };
279
static const int initValue_inter_pred_idc[5] = { 95,79,63,31,31 };
280
static const int initValue_cu_transquant_bypass_flag[3] = { 154,154,154 };
281
282
283
static void init_context(int SliceQPY,
284
                         context_model* model,
285
                         const int* initValues, int len)
286
71.4k
{
287
584k
  for (int i=0;i<len;i++)
288
513k
    {
289
513k
      set_initValue(SliceQPY, &model[i], initValues[i], 1);
290
513k
    }
291
71.4k
}
292
293
294
static void init_context_const(int SliceQPY,
295
                               context_model* model,
296
                               int initValue, int len)
297
15.1k
{
298
15.1k
  set_initValue(SliceQPY, model, initValue, len);
299
15.1k
}
300
301
void initialize_CABAC_models(context_model context_model_table[CONTEXT_MODEL_TABLE_LENGTH],
302
                      int initType,
303
                      int QPY)
304
3.71k
{
305
3.71k
  context_model* cm = context_model_table; // just an abbreviation
306
307
3.71k
  if (initType > 0) {
308
150
    init_context(QPY, cm+CONTEXT_MODEL_CU_SKIP_FLAG,    initValue_cu_skip_flag[initType-1],  3);
309
150
    init_context(QPY, cm+CONTEXT_MODEL_PRED_MODE_FLAG, &initValue_pred_mode_flag[initType-1], 1);
310
150
    init_context(QPY, cm+CONTEXT_MODEL_MERGE_FLAG,             &initValue_merge_flag[initType-1],1);
311
150
    init_context(QPY, cm+CONTEXT_MODEL_MERGE_IDX,              &initValue_merge_idx[initType-1], 1);
312
150
    init_context(QPY, cm+CONTEXT_MODEL_INTER_PRED_IDC,         initValue_inter_pred_idc,         5);
313
150
    init_context(QPY, cm+CONTEXT_MODEL_REF_IDX_LX,             initValue_ref_idx_lX,             2);
314
150
    init_context(QPY, cm+CONTEXT_MODEL_ABS_MVD_GREATER01_FLAG, &initValue_abs_mvd_greater01_flag[initType == 1 ? 0 : 2], 2);
315
150
    init_context(QPY, cm+CONTEXT_MODEL_MVP_LX_FLAG,            initValue_mvp_lx_flag,            1);
316
150
    init_context(QPY, cm+CONTEXT_MODEL_RQT_ROOT_CBF,           initValue_rqt_root_cbf,           1);
317
318
150
    init_context_const(QPY, cm+CONTEXT_MODEL_RDPCM_FLAG, 139, 2);
319
150
    init_context_const(QPY, cm+CONTEXT_MODEL_RDPCM_DIR,  139, 2);
320
150
  }
321
322
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_SPLIT_CU_FLAG, initValue_split_cu_flag[initType], 3);
323
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_PART_MODE,     &initValue_part_mode[(initType!=2 ? initType : 5)], 4);
324
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_PREV_INTRA_LUMA_PRED_FLAG, &initValue_prev_intra_luma_pred_flag[initType], 1);
325
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_INTRA_CHROMA_PRED_MODE,    &initValue_intra_chroma_pred_mode[initType],    1);
326
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_CBF_LUMA,                  &initValue_cbf_luma[initType == 0 ? 0 : 2],     2);
327
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_CBF_CHROMA,                &initValue_cbf_chroma[initType * 4],            4);
328
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_SPLIT_TRANSFORM_FLAG,      &initValue_split_transform_flag[initType * 3],  3);
329
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_LAST_SIGNIFICANT_COEFFICIENT_X_PREFIX, &initValue_last_significant_coefficient_prefix[initType * 18], 18);
330
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_LAST_SIGNIFICANT_COEFFICIENT_Y_PREFIX, &initValue_last_significant_coefficient_prefix[initType * 18], 18);
331
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_CODED_SUB_BLOCK_FLAG,                  &initValue_coded_sub_block_flag[initType * 4],        4);
332
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_SIGNIFICANT_COEFF_FLAG,              initValue_significant_coeff_flag[initType],    42);
333
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_SIGNIFICANT_COEFF_FLAG+42, initValue_significant_coeff_flag_skipmode[initType], 2);
334
335
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_COEFF_ABS_LEVEL_GREATER1_FLAG,       &initValue_coeff_abs_level_greater1_flag[initType * 24], 24);
336
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_COEFF_ABS_LEVEL_GREATER2_FLAG,       &initValue_coeff_abs_level_greater2_flag[initType *  6],  6);
337
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_SAO_MERGE_FLAG,                      &initValue_sao_merge_leftUp_flag[initType],    1);
338
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_SAO_TYPE_IDX,                        &initValue_sao_type_idx_lumaChroma_flag[initType], 1);
339
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_CU_QP_DELTA_ABS,        initValue_cu_qp_delta_abs,        2);
340
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_TRANSFORM_SKIP_FLAG,    initValue_transform_skip_flag,    2);
341
3.71k
  init_context(QPY, cm+CONTEXT_MODEL_CU_TRANSQUANT_BYPASS_FLAG, &initValue_cu_transquant_bypass_flag[initType], 1);
342
343
3.71k
  init_context_const(QPY, cm+CONTEXT_MODEL_LOG2_RES_SCALE_ABS_PLUS1, 154, 8);
344
3.71k
  init_context_const(QPY, cm+CONTEXT_MODEL_RES_SCALE_SIGN_FLAG,      154, 2);
345
3.71k
  init_context_const(QPY, cm+CONTEXT_MODEL_CU_CHROMA_QP_OFFSET_FLAG, 154, 1);
346
3.71k
  init_context_const(QPY, cm+CONTEXT_MODEL_CU_CHROMA_QP_OFFSET_IDX,  154, 1);
347
3.71k
}