Coverage Report

Created: 2026-04-01 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vvenc/source/Lib/EncoderLib/VLCWriter.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
The copyright in this software is being made available under the Clear BSD
3
License, included below. No patent rights, trademark rights and/or 
4
other Intellectual Property Rights other than the copyrights concerning 
5
the Software are granted under this license.
6
7
The Clear BSD License
8
9
Copyright (c) 2019-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVenC Authors.
10
All rights reserved.
11
12
Redistribution and use in source and binary forms, with or without modification,
13
are permitted (subject to the limitations in the disclaimer below) provided that
14
the following conditions are met:
15
16
     * Redistributions of source code must retain the above copyright notice,
17
     this list of conditions and the following disclaimer.
18
19
     * Redistributions in binary form must reproduce the above copyright
20
     notice, this list of conditions and the following disclaimer in the
21
     documentation and/or other materials provided with the distribution.
22
23
     * Neither the name of the copyright holder nor the names of its
24
     contributors may be used to endorse or promote products derived from this
25
     software without specific prior written permission.
26
27
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
28
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
29
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
31
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
32
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
36
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
POSSIBILITY OF SUCH DAMAGE.
39
40
41
------------------------------------------------------------------------------------------- */
42
43
44
/** \file     VLCWriter.cpp
45
 *  \brief    Writer for high level syntax
46
 */
47
48
#include "VLCWriter.h"
49
#include "SEIwrite.h"
50
#include "CommonLib/CommonDef.h"
51
#include "CommonLib/Unit.h"
52
#include "CommonLib/Picture.h" // th remove this
53
#include "CommonLib/dtrace_next.h"
54
55
//! \ingroup EncoderLib
56
//! \{
57
58
namespace vvenc {
59
60
#if ENABLE_TRACING
61
62
void  VLCWriter::xWriteSCodeTr (int value, uint32_t  length, const char *pSymbolName)
63
{
64
  xWriteSCode (value,length);
65
  if( g_HLSTraceEnable )
66
  {
67
    if( length<10 )
68
    {
69
      DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d)  : %d\n", pSymbolName, length, value );
70
    }
71
    else
72
    {
73
      DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %d\n", pSymbolName, length, value );
74
    }
75
  }
76
}
77
78
void  VLCWriter::xWriteCodeTr (uint32_t value, uint32_t  length, const char *pSymbolName)
79
{
80
  xWriteCode (value,length);
81
82
  if( g_HLSTraceEnable )
83
  {
84
    if( length < 10 )
85
    {
86
      DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d)  : %d\n", pSymbolName, length, value );
87
    }
88
    else
89
    {
90
      DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %d\n", pSymbolName, length, value );
91
    }
92
  }
93
}
94
95
void  VLCWriter::xWriteUvlcTr (uint32_t value, const char *pSymbolName)
96
{
97
  xWriteUvlc (value);
98
  if( g_HLSTraceEnable )
99
  {
100
    DTRACE( g_trace_ctx, D_HEADER, "%-50s ue(v) : %d\n", pSymbolName, value );
101
  }
102
}
103
104
void  VLCWriter::xWriteSvlcTr (int value, const char *pSymbolName)
105
{
106
  xWriteSvlc(value);
107
  if( g_HLSTraceEnable )
108
  {
109
    DTRACE( g_trace_ctx, D_HEADER, "%-50s se(v) : %d\n", pSymbolName, value );
110
  }
111
}
112
113
void  VLCWriter::xWriteFlagTr(bool flag, const char *pSymbolName)
114
{
115
  xWriteFlag(flag);
116
  if( g_HLSTraceEnable )
117
  {
118
    DTRACE( g_trace_ctx, D_HEADER, "%-50s u(1)  : %d\n", pSymbolName, flag?1:0 );
119
  }
120
}
121
122
bool g_HLSTraceEnable = true;
123
124
#endif
125
126
void VLCWriter::xWriteSCode    ( int code, uint32_t length )
127
0
{
128
0
  assert ( length > 0 && length<=32 );
129
0
  assert( length==32 || (code>=-(1<<(length-1)) && code<(1<<(length-1))) );
130
0
  m_pcBitIf->write( length==32 ? uint32_t(code) : ( uint32_t(code)&((1<<length)-1) ), length );
131
0
}
132
133
void VLCWriter::xWriteCode     ( uint32_t uiCode, uint32_t uiLength )
134
0
{
135
0
  CHECK( uiLength == 0, "Code of length '0' not supported" );
136
0
  m_pcBitIf->write( uiCode, uiLength );
137
0
}
138
139
void VLCWriter::xWriteUvlc     ( uint32_t uiCode )
140
0
{
141
0
  uint32_t uiLength = 1;
142
0
  uint32_t uiTemp = ++uiCode;
143
144
0
  CHECK( !uiTemp, "Integer overflow" );
145
146
0
  while( 1 != uiTemp )
147
0
  {
148
0
    uiTemp >>= 1;
149
0
    uiLength += 2;
150
0
  }
151
  // Take care of cases where uiLength > 32
152
0
  m_pcBitIf->write( 0, uiLength >> 1);
153
0
  m_pcBitIf->write( uiCode, (uiLength+1) >> 1);
154
0
}
155
156
void VLCWriter::xWriteSvlc     ( int iCode )
157
0
{
158
0
  uint32_t uiCode = uint32_t( iCode <= 0 ? (-iCode)<<1 : (iCode<<1)-1);
159
0
  xWriteUvlc( uiCode );
160
0
}
161
162
void VLCWriter::xWriteFlag( bool flag )
163
0
{
164
0
  m_pcBitIf->write( flag?1:0, 1 );
165
0
}
166
167
void VLCWriter::xWriteRbspTrailingBits()
168
0
{
169
0
  WRITE_FLAG( 1, "rbsp_stop_one_bit");
170
0
  int cnt = 0;
171
0
  while (m_pcBitIf->getNumBitsUntilByteAligned())
172
0
  {
173
0
    WRITE_FLAG( 0, "rbsp_alignment_zero_bit");
174
0
    cnt++;
175
0
  }
176
0
  CHECK(cnt>=8, "More than '8' alignment bytes read");
177
0
}
178
179
void HLSWriter::codeAUD(const int audIrapOrGdrAuFlag, const int pictureType)
180
0
{
181
0
  DTRACE( g_trace_ctx, D_HEADER, "=========== Access Unit Delimiter ===========\n" );
182
183
0
  CHECK(pictureType >= 3, "Invalid picture type");
184
0
  WRITE_FLAG(audIrapOrGdrAuFlag, "aud_irap_or_gdr_au_flag");
185
0
  WRITE_CODE(pictureType, 3, "pic_type");
186
0
  xWriteRbspTrailingBits();
187
0
}
188
189
void HLSWriter::xCodeRefPicList( const ReferencePictureList* rpl, bool isLongTermPresent, uint32_t ltLsbBitsCount, const bool isForbiddenZeroDeltaPoc, int rplIdx )
190
0
{
191
0
  uint32_t numRefPic = rpl->numberOfShorttermPictures + rpl->numberOfLongtermPictures + rpl->numberOfInterLayerPictures;
192
0
  WRITE_UVLC(numRefPic, "num_ref_entries[ listIdx ][ rplsIdx ]");
193
194
0
  if (isLongTermPresent && numRefPic > 0 && rplIdx != -1)
195
0
  {
196
0
    WRITE_FLAG(rpl->ltrpInSliceHeader, "ltrp_in_slice_header_flag[ listIdx ][ rplsIdx ]");
197
0
  }
198
0
  int prevDelta = MAX_INT;
199
0
  int deltaValue = 0;
200
0
  bool firstSTRP = true;
201
0
  for (int ii = 0; ii < numRefPic; ii++)
202
0
  {
203
0
    if( rpl->interLayerPresent )
204
0
    {
205
0
      WRITE_FLAG( rpl->isInterLayerRefPic[ii], "inter_layer_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]" );
206
207
0
      if( rpl->isInterLayerRefPic[ii] )
208
0
      {
209
0
        CHECK( rpl->interLayerRefPicIdx[ii] < 0, "Wrong inter-layer reference index" );
210
0
        WRITE_UVLC( rpl->interLayerRefPicIdx[ii], "ilrp_idx[ listIdx ][ rplsIdx ][ i ]" );
211
0
      }
212
0
    }
213
214
0
    if( !rpl->isInterLayerRefPic[ii] )
215
0
    {
216
0
      if (isLongTermPresent)
217
0
      {
218
0
        WRITE_FLAG(!rpl->isLongtermRefPic[ii], "st_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]");
219
0
      }
220
0
      if (!rpl->isLongtermRefPic[ii])
221
0
      {
222
0
        if (firstSTRP)
223
0
        {
224
0
          firstSTRP = false;
225
0
          deltaValue = prevDelta = rpl->refPicIdentifier[ii];
226
0
        }
227
0
        else
228
0
        {
229
0
          deltaValue = rpl->refPicIdentifier[ii] - prevDelta;
230
0
          prevDelta = rpl->refPicIdentifier[ii];
231
0
        }
232
0
        unsigned int absDeltaValue = (deltaValue < 0) ? 0 - deltaValue : deltaValue;
233
0
        if( isForbiddenZeroDeltaPoc || ii == 0 )
234
0
        {
235
0
          CHECK( !absDeltaValue, "Zero delta POC is not used without WP" );
236
0
          WRITE_UVLC( absDeltaValue - 1, "abs_delta_poc_st[ listIdx ][ rplsIdx ][ i ]" );
237
0
        }
238
0
        else
239
0
        WRITE_UVLC(absDeltaValue, "abs_delta_poc_st[ listIdx ][ rplsIdx ][ i ]");
240
0
        if (absDeltaValue > 0)
241
0
        {
242
0
          WRITE_FLAG((deltaValue < 0), "strp_entry_sign_flag[ listIdx ][ rplsIdx ][ i ]");  //0  means negative delta POC : 1 means positive
243
0
        }
244
0
      }
245
0
      else if (!rpl->ltrpInSliceHeader)
246
0
      {
247
0
        WRITE_CODE(rpl->refPicIdentifier[ii], ltLsbBitsCount, "poc_lsb_lt[listIdx][rplsIdx][i]");
248
0
      }
249
0
    }
250
0
  }
251
0
}
252
253
void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS )
254
0
{
255
0
  DTRACE( g_trace_ctx, D_HEADER, "=========== Picture Parameter Set  ===========\n" );
256
257
0
  WRITE_CODE( pcPPS->ppsId, 6,                        "pps_pic_parameter_set_id" );
258
0
  WRITE_CODE( pcPPS->spsId, 4,                        "pps_seq_parameter_set_id" );
259
260
0
  WRITE_FLAG( pcPPS->mixedNaluTypesInPic,             "pps_mixed_nalu_types_in_pic_flag" );
261
262
0
  WRITE_UVLC( pcPPS->picWidthInLumaSamples,           "pic_width_in_luma_samples" );
263
0
  WRITE_UVLC( pcPPS->picHeightInLumaSamples,          "pic_height_in_luma_samples" );
264
265
0
  if( pcPPS->picWidthInLumaSamples == pcSPS->maxPicWidthInLumaSamples && pcPPS->picHeightInLumaSamples == pcSPS->maxPicHeightInLumaSamples )
266
0
  {
267
0
    WRITE_FLAG( 0,                                    "pps_conformance_window_flag" );
268
0
  }
269
0
  else
270
0
  {
271
0
    const Window& conf = pcPPS->conformanceWindow;
272
0
    WRITE_FLAG( conf.enabledFlag,                     "pps_conformance_window_flag" );
273
0
    if( conf.enabledFlag )
274
0
    {
275
0
      WRITE_UVLC( conf.winLeftOffset   / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "conf_win_left_offset" );
276
0
      WRITE_UVLC( conf.winRightOffset  / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "conf_win_right_offset" );
277
0
      WRITE_UVLC( conf.winTopOffset    / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "conf_win_top_offset" );
278
0
      WRITE_UVLC( conf.winBottomOffset / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "conf_win_bottom_offset" );
279
0
    }
280
0
  }
281
282
0
  const Window& scWnd = pcPPS->scalingWindow;
283
0
  WRITE_FLAG( scWnd.enabledFlag,                      "pps_scaling_window_flag" );
284
0
  if( scWnd.enabledFlag )
285
0
  {
286
0
    WRITE_UVLC( scWnd.winLeftOffset   / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "pps_scaling_win_left_offset" );
287
0
    WRITE_UVLC( scWnd.winRightOffset  / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "pps_scaling_win_right_offset" );
288
0
    WRITE_UVLC( scWnd.winTopOffset    / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "pps_scaling_win_top_offset" );
289
0
    WRITE_UVLC( scWnd.winBottomOffset / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "pps_scaling_win_bottom_offset" );
290
0
  }
291
292
0
  WRITE_FLAG( pcPPS->outputFlagPresent,               "pps_output_flag_present_flag" );
293
0
  WRITE_FLAG( pcPPS->noPicPartition,                  "pps_no_pic_partition_flag" );
294
0
  WRITE_FLAG( pcPPS->subPicIdMappingInPps,            "pps_subpic_id_mapping_in_pps_flag" );
295
0
  if( pcPPS->subPicIdMappingInPps )
296
0
  {
297
0
    if( pcPPS->noPicPartition )
298
0
    {
299
0
      WRITE_UVLC( pcPPS->numSubPics - 1,              "pps_num_subpics_minus1" );
300
0
    }
301
0
    WRITE_UVLC( pcPPS->subPicIdLen - 1,               "pps_subpic_id_len_minus1" );
302
303
0
    CHECK((1 << pcPPS->subPicIdLen) < pcPPS->numSubPics, "pps_subpic_id_len exceeds valid range");
304
0
    for( int picIdx = 0; picIdx < pcPPS->numSubPics; picIdx++ )
305
0
    {
306
0
      WRITE_CODE( pcPPS->subPicId[picIdx], pcPPS->subPicIdLen, "pps_subpic_id[i]" );
307
0
    }
308
0
  }
309
310
0
  if( !pcPPS->noPicPartition )
311
0
  {
312
0
    WRITE_CODE( pcPPS->log2CtuSize - 5, 2, "pps_log2_ctu_size_minus5" );
313
0
    WRITE_UVLC( pcPPS->numExpTileCols - 1, "pps_num_exp_tile_columns_minus1" );
314
0
    WRITE_UVLC( pcPPS->numExpTileRows - 1, "pps_num_exp_tile_rows_minus1" );
315
316
0
    for( int colIdx = 0; colIdx < pcPPS->numExpTileCols; colIdx++ )
317
0
    {
318
0
      WRITE_UVLC( pcPPS->tileColWidth[ colIdx ] - 1,    "pps_tile_column_width_minus1[i]" );
319
0
    }
320
0
    for( int rowIdx = 0; rowIdx < pcPPS->numExpTileRows; rowIdx++ )
321
0
    {
322
0
      WRITE_UVLC( pcPPS->tileRowHeight[ rowIdx ] - 1,   "pps_tile_row_height_minus1[i]" );
323
0
    }
324
325
0
    if( pcPPS->numTileCols * pcPPS->numTileRows > 1 )
326
0
    {
327
0
      WRITE_FLAG( pcPPS->loopFilterAcrossTilesEnabled,  "pps_loop_filter_across_tiles_enabled_flag" );
328
0
      WRITE_FLAG( pcPPS->rectSlice ? 1 : 0,             "pps_rect_slice_flag" );
329
0
    }
330
0
    if( pcPPS->rectSlice )
331
0
    {
332
0
      WRITE_FLAG( pcPPS->singleSlicePerSubPic ? 1 : 0,  "pps_single_slice_per_subpic_flag" );
333
0
    }
334
0
    if( pcPPS->rectSlice & !pcPPS->singleSlicePerSubPic )
335
0
    {
336
0
      CHECK( pcPPS->numSlicesInPic > 1, "currently only one slice supported" );
337
0
      WRITE_UVLC( pcPPS->numSlicesInPic - 1,            "pps_num_slices_in_pic_minus1" );
338
0
    }
339
340
0
    if( pcPPS->rectSlice == 0 || pcPPS->singleSlicePerSubPic || pcPPS->numSlicesInPic > 1 )
341
0
    {
342
0
      WRITE_FLAG( pcPPS->loopFilterAcrossSlicesEnabled, "pps_loop_filter_across_slices_enabled_flag" );
343
0
    }
344
0
  }
345
346
0
  WRITE_FLAG( pcPPS->cabacInitPresent,                "pps_cabac_init_present_flag" );
347
0
  WRITE_UVLC( pcPPS->numRefIdxL0DefaultActive-1,      "pps_num_ref_idx_l0_default_active_minus1");
348
0
  WRITE_UVLC( pcPPS->numRefIdxL1DefaultActive-1,      "pps_num_ref_idx_l1_default_active_minus1");
349
0
  WRITE_FLAG( pcPPS->rpl1IdxPresent,                  "pps_rpl1_idx_present_flag");
350
351
0
  WRITE_FLAG( pcPPS->weightPred,                      "pps_weighted_pred_flag" );   // Use of Weighting Prediction (P_SLICE)
352
0
  WRITE_FLAG( pcPPS->weightedBiPred,                  "pps_weighted_bipred_flag" );  // Use of Weighting Bi-Prediction (B_SLICE)
353
0
  WRITE_FLAG( pcPPS->wrapAroundEnabled,               "pps_ref_wraparound_enabled_flag" );
354
0
  if( pcPPS->wrapAroundEnabled )
355
0
  {
356
0
    WRITE_UVLC(pcPPS->picWidthMinusWrapAroundOffset,  "pps_pic_width_minus_wraparound_offset");
357
0
  }
358
359
0
  WRITE_SVLC( pcPPS->picInitQPMinus26,                "pps_init_qp_minus26");
360
0
  WRITE_FLAG( pcPPS->useDQP,                          "pps_cu_qp_delta_enabled_flag" );
361
0
  WRITE_FLAG (pcPPS->usePPSChromaTool,                "pps_chroma_tool_offsets_present_flag");
362
0
  if (pcPPS->usePPSChromaTool)
363
0
  {
364
0
    WRITE_SVLC( pcPPS->chromaQpOffset[COMP_Cb],       "pps_cb_qp_offset" );
365
0
    WRITE_SVLC( pcPPS->chromaQpOffset[COMP_Cr],       "pps_cr_qp_offset" );
366
0
    WRITE_FLAG( pcPPS->jointCbCrQpOffsetPresent,      "pps_joint_cbcr_qp_offset_present_flag");
367
0
    if (pcPPS->jointCbCrQpOffsetPresent)
368
0
    {
369
0
      WRITE_SVLC(pcPPS->chromaQpOffset[COMP_JOINT_CbCr],"pps_joint_cbcr_qp_offset_value");
370
0
    }
371
372
0
    WRITE_FLAG( pcPPS->sliceChromaQpFlag,               "pps_slice_chroma_qp_offsets_present_flag" );
373
374
0
    bool cuChromaQpOffsetEnabled = pcPPS->chromaQpOffsetListLen>0;
375
0
    WRITE_FLAG(cuChromaQpOffsetEnabled,                 "pps_cu_chroma_qp_offset_list_enabled_flag" );
376
0
    if( cuChromaQpOffsetEnabled )
377
0
    {
378
0
      WRITE_UVLC(pcPPS->chromaQpOffsetListLen - 1,      "pps_chroma_qp_offset_list_len_minus1");
379
      /* skip zero index */
380
0
      for (int cuChromaQpOffsetIdx = 0; cuChromaQpOffsetIdx < pcPPS->chromaQpOffsetListLen; cuChromaQpOffsetIdx++)
381
0
      {
382
0
        WRITE_SVLC(pcPPS->getChromaQpOffsetListEntry(cuChromaQpOffsetIdx+1).u.comp.CbOffset,     "pps_cb_qp_offset_list[i]");
383
0
        WRITE_SVLC(pcPPS->getChromaQpOffsetListEntry(cuChromaQpOffsetIdx+1).u.comp.CrOffset,     "pps_cr_qp_offset_list[i]");
384
0
        if (pcPPS->jointCbCrQpOffsetPresent)
385
0
        {
386
0
          WRITE_SVLC(pcPPS->getChromaQpOffsetListEntry(cuChromaQpOffsetIdx + 1).u.comp.JointCbCrOffset, "pps_joint_cbcr_qp_offset_list[i]");
387
0
        }
388
0
      }
389
0
    }
390
0
  }
391
0
  WRITE_FLAG( pcPPS->deblockingFilterControlPresent,    "pps_deblocking_filter_control_present_flag");
392
0
  if(pcPPS->deblockingFilterControlPresent)
393
0
  {
394
0
    WRITE_FLAG( pcPPS->deblockingFilterOverrideEnabled, "pps_deblocking_filter_override_enabled_flag" );
395
0
    WRITE_FLAG( pcPPS->deblockingFilterDisabled,        "pps_deblocking_filter_disabled_flag" );
396
0
    if (!pcPPS->noPicPartition && pcPPS->deblockingFilterOverrideEnabled)
397
0
    {
398
0
      WRITE_FLAG(pcPPS->dbfInfoInPh,                    "pps_dbf_info_in_ph_flag");
399
0
    }
400
401
0
    if(!pcPPS->deblockingFilterDisabled )
402
0
    {
403
0
      WRITE_SVLC( pcPPS->deblockingFilterBetaOffsetDiv2[COMP_Y],            "pps_beta_offset_div2" );
404
0
      WRITE_SVLC( pcPPS->deblockingFilterTcOffsetDiv2[COMP_Y],              "pps_tc_offset_div2" );
405
0
      if( pcPPS->usePPSChromaTool )
406
0
      {
407
0
        WRITE_SVLC( pcPPS->deblockingFilterBetaOffsetDiv2[COMP_Cb],         "pps_cb_beta_offset_div2" );
408
0
        WRITE_SVLC( pcPPS->deblockingFilterTcOffsetDiv2[COMP_Cb],           "pps_cb_tc_offset_div2" );
409
0
        WRITE_SVLC( pcPPS->deblockingFilterBetaOffsetDiv2[COMP_Cr],         "pps_cr_beta_offset_div2" );
410
0
        WRITE_SVLC( pcPPS->deblockingFilterTcOffsetDiv2[COMP_Cr],           "pps_cr_tc_offset_div2" );
411
0
      }
412
0
    }
413
0
  }
414
0
  if ( !pcPPS->noPicPartition )
415
0
  {
416
0
    WRITE_FLAG(pcPPS->rplInfoInPh,                        "pps_rpl_info_in_ph_flag");
417
0
    WRITE_FLAG(pcPPS->saoInfoInPh,                        "pps_sao_info_in_ph_flag");
418
0
    WRITE_FLAG(pcPPS->alfInfoInPh,                        "pps_alf_info_in_ph_flag");
419
0
    if( (pcPPS->weightPred || pcPPS->weightedBiPred) && pcPPS->rplInfoInPh)
420
0
    {
421
0
      WRITE_FLAG(pcPPS->wpInfoInPh,                       "pps_wp_info_in_ph_flag");
422
0
    }
423
0
    WRITE_FLAG(pcPPS->qpDeltaInfoInPh,                    "pps_qp_delta_info_in_ph_flag");
424
0
  }
425
426
0
  WRITE_FLAG( pcPPS->pictureHeaderExtensionPresent,       "pps_picture_header_extension_present_flag");
427
0
  WRITE_FLAG( pcPPS->sliceHeaderExtensionPresent,         "pps_slice_header_extension_present_flag");
428
429
0
  WRITE_FLAG( false,                                      "pps_extension_present_flag" );
430
431
0
  xWriteRbspTrailingBits();
432
0
}
433
434
void HLSWriter::codeAPS( const APS* pcAPS )
435
0
{
436
0
  DTRACE(g_trace_ctx, D_HEADER, "=========== Adaptation Parameter Set  ===========\n");
437
438
0
  WRITE_CODE(pcAPS->apsType, 3,        "aps_params_type");
439
0
  WRITE_CODE(pcAPS->apsId, 5,          "adaptation_parameter_set_id");
440
0
  WRITE_FLAG(pcAPS->chromaPresent, "aps_chroma_present_flag");
441
442
0
  if (pcAPS->apsType == ALF_APS)
443
0
  {
444
0
    codeAlfAps(pcAPS);
445
0
  }
446
0
  else if (pcAPS->apsType == LMCS_APS)
447
0
  {
448
0
    codeLmcsAps (pcAPS );
449
0
  }
450
0
  else if( pcAPS->apsType == SCALING_LIST_APS )
451
0
  {
452
0
    THROW("no support");
453
0
  }
454
0
  else
455
0
  {
456
0
    THROW("invalid APS Type");
457
0
  }
458
0
  WRITE_FLAG(0, "aps_extension_flag");
459
0
  xWriteRbspTrailingBits();
460
0
}
461
462
void HLSWriter::codeAlfAps( const APS* pcAPS )
463
0
{
464
0
  const AlfParam& param = pcAPS->alfParam;
465
466
0
  WRITE_FLAG(param.newFilterFlag[CH_L],                 "alf_luma_new_filter");
467
0
  const CcAlfFilterParam& paramCcAlf = pcAPS->ccAlfParam;
468
0
  if (pcAPS->chromaPresent)
469
0
  {
470
0
    WRITE_FLAG(param.newFilterFlag[CH_C],               "alf_chroma_new_filter");
471
0
    WRITE_FLAG(paramCcAlf.newCcAlfFilter[COMP_Cb - 1],  "alf_cc_cb_filter_signal_flag");
472
0
    WRITE_FLAG(paramCcAlf.newCcAlfFilter[COMP_Cr - 1],  "alf_cc_cr_filter_signal_flag");
473
0
  }
474
475
0
  if (param.newFilterFlag[CH_L])
476
0
  {
477
0
    WRITE_FLAG( param.nonLinearFlag[CH_L],              "alf_luma_clip" );
478
479
0
    WRITE_UVLC(param.numLumaFilters - 1,                "alf_luma_num_filters_signalled_minus1");
480
0
    if (param.numLumaFilters > 1)
481
0
    {
482
0
      const int len = ceilLog2( param.numLumaFilters);
483
0
      for (int i = 0; i < MAX_NUM_ALF_CLASSES; i++)
484
0
      {
485
0
        WRITE_CODE(param.filterCoeffDeltaIdx[i], len,   "alf_luma_coeff_delta_idx" );
486
0
      }
487
0
    }
488
0
    alfFilter(param, false, 0);
489
0
  }
490
491
0
  if (param.newFilterFlag[CH_C])
492
0
  {
493
0
    WRITE_FLAG(param.nonLinearFlag[CH_C],               "alf_nonlinear_enable_flag_chroma");
494
0
    if( VVENC_MAX_NUM_ALF_ALTERNATIVES_CHROMA > 1 )
495
0
    {
496
0
      WRITE_UVLC( param.numAlternativesChroma - 1,      "alf_chroma_num_alts_minus1" );
497
0
    }
498
0
    for( int altIdx=0; altIdx < param.numAlternativesChroma; ++altIdx )
499
0
    {
500
0
      alfFilter(param, true, altIdx);
501
0
    }
502
0
  }
503
504
0
  for (int ccIdx = 0; ccIdx < 2; ccIdx++)
505
0
  {
506
0
    if (paramCcAlf.newCcAlfFilter[ccIdx])
507
0
    {
508
0
      const int filterCount = paramCcAlf.ccAlfFilterCount[ccIdx];
509
0
      CHECK(filterCount > MAX_NUM_CC_ALF_FILTERS, "CC ALF Filter count is too large");
510
0
      CHECK(filterCount == 0,                     "CC ALF Filter count is too small");
511
512
0
      WRITE_UVLC(filterCount - 1, ccIdx == 0 ? "alf_cc_cb_filters_signalled_minus1" : "alf_cc_cr_filters_signalled_minus1");
513
514
0
      for (int filterIdx = 0; filterIdx < filterCount; filterIdx++)
515
0
      {
516
0
        AlfFilterShape alfShape(size_CC_ALF);
517
518
0
        const short *coeff = paramCcAlf.ccAlfCoeff[ccIdx][filterIdx];
519
        // Filter coefficients
520
0
        for (int i = 0; i < alfShape.numCoeff - 1; i++)
521
0
        {
522
0
          if (coeff[i] == 0)
523
0
          {
524
0
            WRITE_CODE(0, CCALF_BITS_PER_COEFF_LEVEL, ccIdx == 0 ? "alf_cc_cb_mapped_coeff_abs" : "alf_cc_cr_mapped_coeff_abs");
525
0
          }
526
0
          else
527
0
          {
528
0
            WRITE_CODE(1 + floorLog2(abs(coeff[i])), CCALF_BITS_PER_COEFF_LEVEL, ccIdx == 0 ? "alf_cc_cb_mapped_coeff_abs" : "alf_cc_cr_mapped_coeff_abs");
529
0
            WRITE_FLAG(coeff[i] < 0 ? 1 : 0, ccIdx == 0 ? "alf_cc_cb_coeff_sign" : "alf_cc_cr_coeff_sign");
530
0
          }
531
0
        }
532
533
0
        DTRACE(g_trace_ctx, D_SYNTAX, "%s coeff filterIdx %d: ", ccIdx == 0 ? "Cb" : "Cr", filterIdx);
534
0
        for (int i = 0; i < alfShape.numCoeff; i++)
535
0
        {
536
0
          DTRACE(g_trace_ctx, D_SYNTAX, "%d ", coeff[i]);
537
0
        }
538
0
        DTRACE(g_trace_ctx, D_SYNTAX, "\n");
539
0
      }
540
0
    }
541
0
  }
542
0
}
543
544
void HLSWriter::codeLmcsAps( const APS* aps )
545
0
{
546
0
  const LmcsParam& param = aps->lmcsParam;
547
0
  WRITE_UVLC(param.reshaperModelMinBinIdx,                          "lmcs_min_bin_idx");
548
0
  WRITE_UVLC(PIC_CODE_CW_BINS - 1 - param.reshaperModelMaxBinIdx,   "lmcs_delta_max_bin_idx");
549
0
  assert(param.maxNbitsNeededDeltaCW > 0);
550
0
  WRITE_UVLC(param.maxNbitsNeededDeltaCW - 1,                       "lmcs_delta_cw_prec_minus1");
551
552
0
  for (int i = param.reshaperModelMinBinIdx; i <= param.reshaperModelMaxBinIdx; i++)
553
0
  {
554
0
    int deltaCW = param.reshaperModelBinCWDelta[i];
555
0
    int signCW = (deltaCW < 0) ? 1 : 0;
556
0
    int absCW = (deltaCW < 0) ? (-deltaCW) : deltaCW;
557
0
    WRITE_CODE(absCW, param.maxNbitsNeededDeltaCW,                  "lmcs_delta_abs_cw[ i ]");
558
0
    if (absCW > 0)
559
0
    {
560
0
      WRITE_FLAG(signCW,                                            "lmcs_delta_sign_cw_flag[ i ]");
561
0
    }
562
0
  }
563
0
  int deltaCRS = aps->chromaPresent ? param.chrResScalingOffset : 0;
564
0
  int signCRS = (deltaCRS < 0) ? 1 : 0;
565
0
  int absCRS = (deltaCRS < 0) ? (-deltaCRS) : deltaCRS;
566
0
  if (aps->chromaPresent)
567
0
  {
568
0
    WRITE_CODE(absCRS, 3,                                           "lmcs_delta_abs_crs");
569
0
  }
570
0
  if (absCRS > 0)
571
0
  {
572
0
    WRITE_FLAG(signCRS,                                             "lmcs_delta_sign_crs_val_flag");
573
0
  }
574
0
}
575
576
void HLSWriter::codeVUI( const VUI *pcVUI, const SPS* pcSPS )
577
0
{
578
#if ENABLE_TRACING
579
  DTRACE( g_trace_ctx, D_HEADER, "----------- vui_parameters -----------\n");
580
#endif
581
582
0
  WRITE_FLAG(pcVUI->progressiveSourceFlag,                "vui_general_progressive_source_flag"         );
583
0
  WRITE_FLAG(pcVUI->interlacedSourceFlag,                 "vui_general_interlaced_source_flag"          );
584
0
  WRITE_FLAG(pcVUI->nonPackedFlag,                        "vui_non_packed_constraint_flag");
585
0
  WRITE_FLAG(pcVUI->nonProjectedFlag,                     "vui_non_projected_constraint_flag");
586
0
  WRITE_FLAG(pcVUI->aspectRatioInfoPresent,               "aspect_ratio_info_present_flag");
587
0
  if (pcVUI->aspectRatioInfoPresent)
588
0
  {
589
0
    WRITE_FLAG(pcVUI->aspectRatioConstantFlag,            "vui_aspect_ratio_constant_flag");   
590
0
    WRITE_CODE(pcVUI->aspectRatioIdc, 8,                  "aspect_ratio_idc" );
591
0
    if (pcVUI->aspectRatioIdc == 255)
592
0
    {
593
0
      WRITE_CODE(pcVUI->sarWidth, 16,                     "sar_width");
594
0
      WRITE_CODE(pcVUI->sarHeight, 16,                    "sar_height");
595
0
    }
596
0
  }
597
0
  WRITE_FLAG(pcVUI->overscanInfoPresent,                  "vui_overscan_info_present_flag");
598
0
  if (pcVUI->overscanInfoPresent)
599
0
  {
600
0
    WRITE_FLAG(pcVUI->overscanAppropriateFlag,            "vui_overscan_appropriate_flag");
601
0
  }
602
0
  WRITE_FLAG(pcVUI->colourDescriptionPresent,             "colour_description_present_flag");
603
0
  if (pcVUI->colourDescriptionPresent)
604
0
  {
605
0
    WRITE_CODE(pcVUI->colourPrimaries, 8,                 "colour_primaries");
606
0
    WRITE_CODE(pcVUI->transferCharacteristics, 8,         "transfer_characteristics");
607
0
    WRITE_CODE(pcVUI->matrixCoefficients, 8,              "matrix_coeffs");
608
0
    WRITE_FLAG(pcVUI->videoFullRangeFlag,                 "vui_video_full_range_flag");
609
0
  }
610
0
  WRITE_FLAG(pcVUI->chromaLocInfoPresent,                 "chroma_loc_info_present_flag");
611
0
  if (pcVUI->chromaLocInfoPresent)
612
0
  {
613
0
    if(pcVUI->progressiveSourceFlag && !pcVUI->interlacedSourceFlag)
614
0
    {
615
0
      WRITE_UVLC(pcVUI->chromaSampleLocType,              "chroma_sample_loc_type");
616
0
    }
617
0
    else
618
0
    {
619
0
      WRITE_UVLC(pcVUI->chromaSampleLocTypeTopField,      "chroma_sample_loc_type_top_field");
620
0
      WRITE_UVLC(pcVUI->chromaSampleLocTypeBottomField,   "chroma_sample_loc_type_bottom_field");
621
0
    }
622
0
  }
623
624
0
  if(!isByteAligned())
625
0
  {
626
0
    WRITE_FLAG(1,   "vui_payload_bit_equal_to_one");
627
0
    while(!isByteAligned())
628
0
    {
629
0
      WRITE_FLAG(0, "vui_payload_bit_equal_to_zero");
630
0
    }
631
0
  }
632
0
}
633
634
void HLSWriter::codeGeneralHrdparameters(const GeneralHrdParams * hrd)
635
0
{
636
0
  WRITE_CODE(hrd->numUnitsInTick, 32,                   "num_units_in_tick");
637
0
  WRITE_CODE(hrd->timeScale, 32,                        "time_scale");
638
0
  WRITE_FLAG(hrd->generalNalHrdParamsPresent,           "general_nal_hrd_parameters_present_flag");
639
0
  WRITE_FLAG(hrd->generalVclHrdParamsPresent,           "general_vcl_hrd_parameters_present_flag");
640
0
  if( hrd->generalNalHrdParamsPresent || hrd->generalVclHrdParamsPresent )
641
0
  {
642
0
    WRITE_FLAG(hrd->generalSamePicTimingInAllOlsFlag,     "general_same_pic_timing_in_all_ols_flag");
643
0
    WRITE_FLAG(hrd->generalDecodingUnitHrdParamsPresent,  "general_decoding_unit_hrd_params_present_flag");
644
0
    if (hrd->generalDecodingUnitHrdParamsPresent)
645
0
    {
646
0
      WRITE_CODE(hrd->tickDivisorMinus2, 8,               "tick_divisor_minus2");
647
0
    }
648
0
    WRITE_CODE(hrd->bitRateScale, 4,                      "bit_rate_scale");
649
0
    WRITE_CODE(hrd->cpbSizeScale, 4,                      "cpb_size_scale");
650
0
    if (hrd->generalDecodingUnitHrdParamsPresent)
651
0
    {
652
0
      WRITE_CODE(hrd->cpbSizeDuScale, 4,                  "cpb_size_du_scale");
653
0
    }
654
0
    WRITE_UVLC(hrd->hrdCpbCntMinus1,                      "hrd_cpb_cnt_minus1");
655
0
  }
656
0
}
657
658
void HLSWriter::codeOlsHrdParameters(const GeneralHrdParams * generalHrd, const OlsHrdParams *olsHrd, const uint32_t firstSubLayer, const uint32_t maxNumSubLayersMinus1)
659
0
{
660
0
  for( int i = firstSubLayer; i <= maxNumSubLayersMinus1; i ++ )
661
0
  {
662
0
    const OlsHrdParams *hrd = &(olsHrd[i]);
663
0
    WRITE_FLAG(hrd->fixedPicRateGeneralFlag,      "fixed_pic_rate_general_flag");
664
665
0
    if (!hrd->fixedPicRateGeneralFlag)
666
0
    {
667
0
      WRITE_FLAG(hrd->fixedPicRateWithinCvsFlag,  "fixed_pic_rate_within_cvs_flag");
668
0
    }
669
0
    if (hrd->fixedPicRateWithinCvsFlag)
670
0
    {
671
0
      WRITE_UVLC(hrd->elementDurationInTcMinus1,  "elemental_duration_in_tc_minus1");
672
0
    }
673
0
    else if ( (generalHrd->generalNalHrdParamsPresent || generalHrd->generalVclHrdParamsPresent) &&generalHrd->hrdCpbCntMinus1 == 0)
674
0
    {
675
0
      WRITE_FLAG(hrd->lowDelayHrdFlag,            "low_delay_hrd_flag");
676
0
    }
677
678
0
    for( int nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ )
679
0
    {
680
0
      if (((nalOrVcl == 0) && (generalHrd->generalNalHrdParamsPresent)) || ((nalOrVcl == 1) && (generalHrd->generalVclHrdParamsPresent)))
681
0
      {
682
0
        for (int j = 0; j <= (generalHrd->hrdCpbCntMinus1); j++)
683
0
        {
684
0
          WRITE_UVLC(hrd->bitRateValueMinus1[j][nalOrVcl], "bit_rate_value_minus1");
685
0
          WRITE_UVLC(hrd->cpbSizeValueMinus1[j][nalOrVcl], "cpb_size_value_minus1");
686
0
          if (generalHrd->generalDecodingUnitHrdParamsPresent)
687
0
          {
688
0
            WRITE_UVLC(hrd->duCpbSizeValueMinus1[j][nalOrVcl], "cpb_size_du_value_minus1");
689
0
            WRITE_UVLC(hrd->duBitRateValueMinus1[j][nalOrVcl], "bit_rate_du_value_minus1");
690
0
          }
691
0
          WRITE_FLAG(hrd->cbrFlag[j][nalOrVcl], "cbr_flag");
692
0
        }
693
0
      }
694
0
    }
695
0
  }
696
0
}
697
698
void HLSWriter::dpb_parameters(int maxSubLayersMinus1, bool subLayerInfoFlag, const SPS *pcSPS)
699
0
{
700
0
  for (uint32_t i = (subLayerInfoFlag ? 0 : maxSubLayersMinus1); i <= maxSubLayersMinus1; i++)
701
0
  {
702
0
    WRITE_UVLC(pcSPS->maxDecPicBuffering[i] - 1,          "dpb_max_dec_pic_buffering_minus1[i]");
703
0
    WRITE_UVLC(pcSPS->numReorderPics[i],                  "dpb_max_num_reorder_pics[i]");
704
0
    WRITE_UVLC(pcSPS->maxLatencyIncreasePlus1[i],         "dpb_max_latency_increase_plus1[i]");
705
0
  }
706
0
}
707
708
void HLSWriter::codeSPS( const SPS* pcSPS )
709
0
{
710
0
  DTRACE( g_trace_ctx, D_HEADER, "=========== Sequence Parameter Set  ===========\n" );
711
712
0
  WRITE_CODE( pcSPS->spsId, 4,                            "sps_seq_parameter_set_id" );
713
0
  WRITE_CODE( pcSPS->vpsId, 4,                            "sps_video_parameter_set_id" );
714
0
  CHECK(pcSPS->maxTLayers == 0, "Maximum number of temporal sub-layers is '0'");
715
716
0
  WRITE_CODE(pcSPS->maxTLayers - 1, 3,                    "sps_max_sub_layers_minus1");
717
0
  WRITE_CODE( int(pcSPS->chromaFormatIdc), 2,             "sps_chroma_format_idc" );
718
0
  WRITE_CODE(floorLog2(pcSPS->CTUSize) - 5, 2,            "sps_log2_ctu_size_minus5");
719
0
  WRITE_FLAG(pcSPS->ptlDpbHrdParamsPresent,               "sps_ptl_dpb_hrd_params_present_flag");
720
721
0
  if (pcSPS->ptlDpbHrdParamsPresent)
722
0
  {
723
0
    codeProfileTierLevel( &pcSPS->profileTierLevel, true, pcSPS->maxTLayers - 1 );
724
0
  }
725
726
0
  WRITE_FLAG(pcSPS->GDR,                                  "sps_gdr_enabled_flag");
727
0
  WRITE_FLAG( pcSPS->rprEnabled,                          "sps_ref_pic_resampling_enabled_flag" );
728
0
  if( pcSPS->rprEnabled )
729
0
  {
730
0
    WRITE_FLAG(pcSPS->resChangeInClvsEnabled, "sps_res_change_in_clvs_allowed_flag");
731
0
  }
732
0
  WRITE_UVLC( pcSPS->maxPicWidthInLumaSamples,            "sps_pic_width_max_in_luma_samples" );
733
0
  WRITE_UVLC( pcSPS->maxPicHeightInLumaSamples,           "sps_pic_height_max_in_luma_samples" );
734
735
0
  const Window& conf = pcSPS->conformanceWindow;
736
0
  WRITE_FLAG( conf.enabledFlag,                           "sps_conformance_window_flag" );
737
0
  if (conf.enabledFlag)
738
0
  {
739
0
    WRITE_UVLC( conf.winLeftOffset   / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "sps_conf_win_left_offset" );
740
0
    WRITE_UVLC( conf.winRightOffset  / SPS::getWinUnitX(pcSPS->chromaFormatIdc ), "sps_conf_win_right_offset" );
741
0
    WRITE_UVLC( conf.winTopOffset    / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "sps_conf_win_top_offset" );
742
0
    WRITE_UVLC( conf.winBottomOffset / SPS::getWinUnitY(pcSPS->chromaFormatIdc ), "sps_conf_win_bottom_offset" );
743
0
  }
744
745
0
  WRITE_FLAG(pcSPS->subPicInfoPresent,                    "sps_subpic_info_present_flag");
746
747
0
  if (pcSPS->subPicInfoPresent)
748
0
  {
749
0
    THROW("no suppport");
750
0
  }
751
752
0
  WRITE_UVLC( pcSPS->bitDepths[ CH_L ] - 8,               "sps_bitdepth_minus8" );
753
0
  WRITE_FLAG( pcSPS->entropyCodingSyncEnabled,            "sps_entropy_coding_sync_enabled_flag" );
754
0
  WRITE_FLAG( pcSPS->entryPointsPresent,                  "sps_entry_point_offsets_present_flag" );
755
0
  WRITE_CODE( pcSPS->bitsForPOC-4, 4,                     "sps_log2_max_pic_order_cnt_lsb_minus4" );
756
0
  WRITE_FLAG( pcSPS->pocMsbFlag,                          "sps_poc_msb_flag");
757
758
0
  if (pcSPS->pocMsbFlag)
759
0
  {
760
0
    WRITE_UVLC(pcSPS->pocMsbLen - 1,                      "sps_poc_msb_len_minus1");
761
0
  }
762
763
0
  WRITE_CODE(0, 2,                                        "sps_num_extra_ph_bits_bytes");
764
0
  WRITE_CODE(0, 2,                                        "sps_num_extra_sh_bits_bytes");
765
766
0
  if (pcSPS->ptlDpbHrdParamsPresent)
767
0
  {
768
0
    if (pcSPS->maxTLayers > 1)
769
0
    {
770
0
      WRITE_FLAG(pcSPS->subLayerDpbParams,                "sps_sublayer_dpb_params_flag");
771
0
    }
772
0
    dpb_parameters(pcSPS->maxTLayers - 1, pcSPS->subLayerDpbParams, pcSPS);
773
0
  }
774
775
0
  WRITE_UVLC(pcSPS->log2MinCodingBlockSize - 2,                           "log2_min_luma_coding_block_size_minus2");
776
0
  WRITE_FLAG(pcSPS->partitionOverrideEnabled,                             "sps_partition_constraints_override_enabled_flag");
777
0
  WRITE_UVLC(Log2(pcSPS->minQTSize[0]) - pcSPS->log2MinCodingBlockSize,   "sps_log2_diff_min_qt_min_cb_intra_slice_luma");
778
0
  WRITE_UVLC(pcSPS->maxMTTDepth[0],                                       "sps_max_mtt_hierarchy_depth_intra_slice_luma");
779
0
  if (pcSPS->maxMTTDepth[0] != 0)
780
0
  {
781
0
    WRITE_UVLC(Log2(pcSPS->maxBTSize[0]) - Log2(pcSPS->minQTSize[0]),     "sps_log2_diff_max_bt_min_qt_intra_slice_luma");
782
0
    WRITE_UVLC(Log2(pcSPS->maxTTSize[0]) - Log2(pcSPS->minQTSize[0]),     "sps_log2_diff_max_tt_min_qt_intra_slice_luma");
783
0
  }
784
0
  if( pcSPS->chromaFormatIdc != CHROMA_400 )
785
0
  {
786
0
    WRITE_FLAG(pcSPS->dualITree,                                          "sps_qtbtt_dual_tree_intra_flag");
787
0
  }
788
0
  if (pcSPS->dualITree)
789
0
  {
790
0
    WRITE_UVLC(Log2(pcSPS->minQTSize[2]) - pcSPS->log2MinCodingBlockSize, "sps_log2_diff_min_qt_min_cb_intra_slice_chroma");
791
0
    WRITE_UVLC(pcSPS->maxMTTDepth[2],                                     "sps_max_mtt_hierarchy_depth_intra_slice_chroma");
792
0
    if (pcSPS->maxMTTDepth[2] != 0)
793
0
    {
794
0
      WRITE_UVLC(Log2(pcSPS->maxBTSize[2]) - Log2(pcSPS->minQTSize[2]),   "sps_log2_diff_max_bt_min_qt_intra_slice_chroma");
795
0
      WRITE_UVLC(Log2(pcSPS->maxTTSize[2]) - Log2(pcSPS->minQTSize[2]),   "sps_log2_diff_max_tt_min_qt_intra_slice_chroma");
796
0
    }
797
0
  }
798
799
0
  WRITE_UVLC(Log2(pcSPS->minQTSize[1]) - pcSPS->log2MinCodingBlockSize,   "sps_log2_diff_min_qt_min_cb_inter_slice");
800
0
  WRITE_UVLC(pcSPS->maxMTTDepth[1],                                       "sps_max_mtt_hierarchy_depth_inter_slice");
801
0
  if (pcSPS->maxMTTDepth[1] != 0)
802
0
  {
803
0
    WRITE_UVLC(Log2(pcSPS->maxBTSize[1]) - Log2(pcSPS->minQTSize[1]),     "sps_log2_diff_max_bt_min_qt_inter_slice");
804
0
    WRITE_UVLC(Log2(pcSPS->maxTTSize[1]) - Log2(pcSPS->minQTSize[1]),     "sps_log2_diff_max_tt_min_qt_inter_slice");
805
0
  }
806
807
0
  if (pcSPS->CTUSize > 32)
808
0
  {
809
0
    WRITE_FLAG( (pcSPS->log2MaxTbSize - 5) != 0,                          "sps_max_luma_transform_size_64_flag" );
810
0
  }
811
0
  WRITE_FLAG(pcSPS->transformSkip,                                        "sps_transform_skip_enabled_flag");
812
0
  if (pcSPS->transformSkip)
813
0
  {
814
0
    WRITE_UVLC(pcSPS->log2MaxTransformSkipBlockSize - 2,                  "sps_log2_transform_skip_max_size_minus2");
815
0
    WRITE_FLAG(pcSPS->BDPCM,                                              "sps_bdpcm_enabled_flag");
816
0
  }
817
0
  WRITE_FLAG( pcSPS->MTS,                                                 "sps_mts_enabled_flag" );
818
0
  if ( pcSPS->MTS )
819
0
  {
820
0
    WRITE_FLAG( pcSPS->MTSIntra,                                          "sps_explicit_mts_intra_enabled_flag" );
821
0
    WRITE_FLAG( pcSPS->MTSInter,                                          "sps_explicit_mts_inter_enabled_flag" );
822
0
  }
823
0
  WRITE_FLAG( pcSPS->LFNST,                                               "sps_lfnst_enabled_flag");
824
825
0
  if (pcSPS->chromaFormatIdc != CHROMA_400)
826
0
  {
827
0
    WRITE_FLAG(pcSPS->jointCbCr,                                          "sps_joint_cbcr_enabled_flag");
828
829
0
    const ChromaQpMappingTable& chromaQpMappingTable = pcSPS->chromaQpMappingTable;
830
0
    WRITE_FLAG(chromaQpMappingTable.m_sameCQPTableForAllChromaFlag,       "same_qp_table_for_chroma");
831
0
    int numQpTables = chromaQpMappingTable.m_sameCQPTableForAllChromaFlag ? 1 : (pcSPS->jointCbCr ? 3 : 2);
832
0
    CHECK(numQpTables != chromaQpMappingTable.m_numQpTables, " numQpTables does not match at encoder side ");
833
0
    for (int i = 0; i < numQpTables; i++)
834
0
    {
835
0
      WRITE_SVLC(chromaQpMappingTable.m_qpTableStartMinus26[i],           "sps_qp_table_starts_minus26");
836
0
      WRITE_UVLC(chromaQpMappingTable.m_numPtsInCQPTableMinus1[i],        "sps_num_points_in_qp_table_minus1");
837
838
0
      for (int j = 0; j <= chromaQpMappingTable.m_numPtsInCQPTableMinus1[i]; j++)
839
0
      {
840
0
        WRITE_UVLC(chromaQpMappingTable.m_deltaQpInValMinus1[i][j],       "sps_delta_qp_in_val_minus1");
841
0
        WRITE_UVLC(chromaQpMappingTable.m_deltaQpOutVal[i][j] ^ chromaQpMappingTable.m_deltaQpInValMinus1[i][j], "sps_delta_qp_diff_val");
842
0
      }
843
0
    }
844
0
  }
845
846
0
  WRITE_FLAG( pcSPS->saoEnabled,                          "sps_sao_enabled_flag");
847
0
  WRITE_FLAG( pcSPS->alfEnabled,                          "sps_alf_enabled_flag" );
848
0
  if (pcSPS->alfEnabled && pcSPS->chromaFormatIdc != CHROMA_400)
849
0
  {
850
0
    WRITE_FLAG( pcSPS->ccalfEnabled,                      "sps_ccalf_enabled_flag" );
851
0
  }
852
0
  WRITE_FLAG(pcSPS->lumaReshapeEnable,                    "sps_lmcs_enable_flag");
853
0
  WRITE_FLAG( pcSPS->weightPred,                          "sps_weighted_pred_flag" );   // Use of Weighting Prediction (P_SLICE)
854
0
  WRITE_FLAG( pcSPS->weightedBiPred,                      "sps_weighted_bipred_flag" );  // Use of Weighting Bi-Prediction (B_SLICE)
855
0
  WRITE_FLAG( pcSPS->longTermRefsPresent,                 "sps_long_term_ref_pics_flag" );
856
0
  if( pcSPS->vpsId > 0 )
857
0
  {
858
0
    WRITE_FLAG( pcSPS->interLayerPresent,                 "sps_inter_layer_ref_pics_present_flag" );
859
0
  }
860
0
  WRITE_FLAG( pcSPS->idrRefParamList,                     "sps_idr_rpl_present_flag" );
861
0
  WRITE_FLAG( pcSPS->rpl1CopyFromRpl0,                    "sps_rpl1_copy_from_rpl0_flag");
862
863
  //Write candidate for List0
864
0
  uint32_t numberOfRPL = (uint32_t)pcSPS->getNumRPL(0);
865
0
  WRITE_UVLC(numberOfRPL,                                 "sps_num_ref_pic_lists_in_sps[0]");
866
0
  for (int ii = 0; ii < numberOfRPL; ii++)
867
0
  {
868
0
    xCodeRefPicList( &pcSPS->rplList[0][ii], pcSPS->longTermRefsPresent, pcSPS->bitsForPOC, !pcSPS->weightPred && !pcSPS->weightedBiPred, ii );
869
0
  }
870
871
  //Write candidate for List1
872
0
  if (!pcSPS->rpl1CopyFromRpl0)
873
0
  {
874
0
    numberOfRPL = (uint32_t)pcSPS->getNumRPL(1);
875
0
    WRITE_UVLC(numberOfRPL,                               "sps_num_ref_pic_lists_in_sps[1]");
876
0
    for (int ii = 0; ii < numberOfRPL; ii++)
877
0
    {
878
0
      xCodeRefPicList( &pcSPS->rplList[1][ii], pcSPS->longTermRefsPresent, pcSPS->bitsForPOC, !pcSPS->weightPred && !pcSPS->weightedBiPred, ii );
879
0
    }
880
0
  }
881
882
0
  WRITE_FLAG( pcSPS->wrapAroundEnabled,                   "sps_ref_wraparound_enabled_flag" );
883
884
0
  WRITE_FLAG( pcSPS->temporalMVPEnabled,                  "sps_temporal_mvp_enabled_flag" );
885
886
0
  if ( pcSPS->temporalMVPEnabled )
887
0
  {
888
0
    WRITE_FLAG( pcSPS->SbtMvp,                            "sps_sbtmvp_enabled_flag");
889
0
  }
890
891
0
  WRITE_FLAG( pcSPS->AMVR,                                "sps_amvr_enabled_flag" );
892
893
0
  WRITE_FLAG( pcSPS->BDOF,                                "sps_bdof_enabled_flag" );
894
0
  if (pcSPS->BDOF)
895
0
  {
896
0
    WRITE_FLAG(pcSPS->BdofPresent,                        "sps_bdof_pic_present_flag");
897
0
  }
898
0
  WRITE_FLAG( pcSPS->SMVD,                                "sps_smvd_enabled_flag" );
899
0
  WRITE_FLAG( pcSPS->DMVR,                                "sps_dmvr_enabled_flag" );
900
0
  if (pcSPS->DMVR)
901
0
  {
902
0
    WRITE_FLAG(pcSPS->DmvrPresent,                        "sps_dmvr_pic_present_flag");
903
0
  }
904
0
  WRITE_FLAG(pcSPS->MMVD,                                 "sps_mmvd_enabled_flag");
905
0
  if ( pcSPS->MMVD )
906
0
  {
907
0
    WRITE_FLAG( pcSPS->fpelMmvd,                          "sps_fpel_mmvd_enabled_flag" );
908
0
  }
909
0
  WRITE_UVLC(MRG_MAX_NUM_CANDS - pcSPS->maxNumMergeCand,  "sps_six_minus_max_num_merge_cand");
910
0
  WRITE_FLAG( pcSPS->SBT,                                 "sps_sbt_enabled_flag" );
911
0
  WRITE_FLAG( pcSPS->Affine,                              "sps_affine_enabled_flag" );
912
0
  if ( pcSPS->Affine )
913
0
  {
914
0
    WRITE_UVLC(AFFINE_MRG_MAX_NUM_CANDS - pcSPS->maxNumAffineMergeCand, "five_minus_max_num_subblock_merge_cand");
915
0
    WRITE_FLAG( pcSPS->AffineType,                        "sps_affine_type_flag" );
916
0
    if (pcSPS->AMVR )
917
0
    {
918
0
      WRITE_FLAG( pcSPS->AffineAmvr,                      "sps_affine_amvr_enabled_flag" );
919
0
    }
920
921
0
    WRITE_FLAG( pcSPS->PROF,                              "sps_affine_prof_enabled_flag" );
922
0
    if (pcSPS->PROF)
923
0
    {
924
0
      WRITE_FLAG(pcSPS->ProfPresent,                      "sps_prof_pic_present_flag" );
925
0
    }
926
0
  }
927
928
0
  WRITE_FLAG(pcSPS->BCW,                                  "sps_bcw_enabled_flag");
929
930
0
  WRITE_FLAG( pcSPS->CIIP,                                "sps_ciip_enabled_flag" );
931
932
0
  if (pcSPS->maxNumMergeCand >= 2)
933
0
  {
934
0
    WRITE_FLAG(pcSPS->GEO,                                "sps_gpm_enabled_flag");
935
0
    if (pcSPS->GEO && pcSPS->maxNumMergeCand >= 3)
936
0
    {
937
0
      WRITE_UVLC(pcSPS->maxNumMergeCand - pcSPS->maxNumGeoCand,   "sps_max_num_merge_cand_minus_max_num_gpm_cand");
938
0
    }
939
0
  }
940
941
0
  WRITE_UVLC(pcSPS->log2ParallelMergeLevelMinus2,         "sps_log2_parallel_merge_level_minus2");
942
0
  WRITE_FLAG( pcSPS->ISP,                                 "sps_isp_enabled_flag");
943
0
  WRITE_FLAG( pcSPS->MRL,                                 "sps_mrl_enabled_flag");
944
0
  WRITE_FLAG( pcSPS->MIP,                                 "sps_mip_enabled_flag");
945
0
  if( pcSPS->chromaFormatIdc != CHROMA_400)
946
0
  {
947
0
    WRITE_FLAG( pcSPS->LMChroma,                          "sps_cclm_enabled_flag" );
948
0
  }
949
0
  if ( pcSPS->chromaFormatIdc == CHROMA_420 )
950
0
  {
951
0
    WRITE_FLAG( pcSPS->horCollocatedChroma,               "sps_chroma_horizontal_collocated_flag" );
952
0
    WRITE_FLAG( pcSPS->verCollocatedChroma,               "sps_chroma_vertical_collocated_flag" );
953
0
  }
954
955
0
  WRITE_FLAG(pcSPS->PLT,                                  "sps_palette_enabled_flag" );
956
957
0
  if (pcSPS->chromaFormatIdc == CHROMA_444)
958
0
  {
959
0
    WRITE_FLAG(pcSPS->PLT,                                "sps_plt_enabled_flag" );
960
0
  }
961
0
  if (pcSPS->chromaFormatIdc == CHROMA_444 && pcSPS->log2MaxTbSize != 6)
962
0
  {
963
0
    WRITE_FLAG(pcSPS->useColorTrans,                      "sps_act_enabled_flag");
964
0
  }
965
0
  if (pcSPS->transformSkip || pcSPS->PLT)
966
0
  {
967
0
    WRITE_UVLC(pcSPS->internalMinusInputBitDepth[CH_L],   "sps_internal_bit_depth_minus_input_bit_depth");
968
0
  }
969
970
0
  WRITE_FLAG(pcSPS->IBC,                                  "sps_ibc_enabled_flag");
971
0
  if( pcSPS->IBC )
972
0
  {
973
0
    WRITE_UVLC(IBC_MRG_MAX_NUM_CANDS - pcSPS->maxNumIBCMergeCand, "six_minus_max_num_ibc_merge_cand");
974
0
  }
975
976
0
  WRITE_FLAG( pcSPS->LADF,                                "sps_ladf_enabled_flag" );
977
0
  if ( pcSPS->LADF )
978
0
  {
979
0
    THROW("no support");
980
0
  }
981
982
0
  WRITE_FLAG( pcSPS->scalingListEnabled,                  "sps_explicit_scaling_list_enabled_flag" );
983
0
  if (pcSPS->LFNST && pcSPS->scalingListEnabled )
984
0
  {
985
0
    WRITE_FLAG(pcSPS->disableScalingMatrixForLfnstBlks,   "sps_scaling_matrix_for_lfnst_disabled_flag");
986
0
  }
987
0
  if (pcSPS->useColorTrans && pcSPS->scalingListEnabled)
988
0
  {
989
0
    WRITE_FLAG(pcSPS->scalingMatrixAlternativeColourSpaceDisabled, "sps_scaling_matrix_for_alternative_colour_space_disabled_flag");
990
0
  }
991
0
  if (pcSPS->scalingMatrixAlternativeColourSpaceDisabled)
992
0
  {
993
0
    WRITE_FLAG(pcSPS->scalingMatrixDesignatedColourSpace, "sps_scaling_matrix_designated_colour_space_flag");
994
0
  }
995
0
  WRITE_FLAG(pcSPS->depQuantEnabled,                      "sps_dep_quant_enabled_flag");
996
0
  WRITE_FLAG(pcSPS->signDataHidingEnabled,                "sps_sign_data_hiding_enabled_flag");
997
998
0
  WRITE_FLAG( pcSPS->virtualBoundariesEnabled,            "sps_virtual_boundaries_enabled_flag" );
999
0
  if( pcSPS->virtualBoundariesEnabled )
1000
0
  {
1001
0
    WRITE_CODE( pcSPS->numVerVirtualBoundaries, 2,        "sps_num_ver_virtual_boundaries");
1002
0
    for( unsigned i = 0; i < pcSPS->numVerVirtualBoundaries; i++ )
1003
0
    {
1004
0
      WRITE_UVLC((pcSPS->virtualBoundariesPosX[i]>>3),    "sps_virtual_boundaries_pos_x");
1005
0
    }
1006
0
    WRITE_CODE(pcSPS->numHorVirtualBoundaries, 2,         "sps_num_hor_virtual_boundaries");
1007
0
    for( unsigned i = 0; i < pcSPS->numHorVirtualBoundaries; i++ )
1008
0
    {
1009
0
      WRITE_UVLC((pcSPS->virtualBoundariesPosY[i]>>3),    "sps_virtual_boundaries_pos_y");
1010
0
    }
1011
0
  }
1012
1013
0
  if (pcSPS->ptlDpbHrdParamsPresent)
1014
0
  {
1015
0
    WRITE_FLAG(pcSPS->hrdParametersPresent,               "sps_timing_hrd_params_present_flag");
1016
1017
0
    if( pcSPS->hrdParametersPresent )
1018
0
    {
1019
0
      codeGeneralHrdparameters(&pcSPS->generalHrdParams);
1020
0
      if ((pcSPS->maxTLayers - 1) > 0)
1021
0
      {
1022
0
        WRITE_FLAG(pcSPS->subLayerParametersPresent,      "sps_sublayer_cpb_params_present_flag");
1023
0
      }
1024
0
      uint32_t firstSubLayer = pcSPS->subLayerParametersPresent ? 0 : (pcSPS->maxTLayers - 1);
1025
0
      codeOlsHrdParameters(&pcSPS->generalHrdParams, pcSPS->olsHrdParams, firstSubLayer, pcSPS->maxTLayers - 1);
1026
0
    }
1027
0
  }
1028
1029
0
  WRITE_FLAG(pcSPS->fieldSeqFlag,                         "sps_field_seq_flag");
1030
1031
0
  WRITE_FLAG( pcSPS->vuiParametersPresent,                "sps_vui_parameters_present_flag" );
1032
0
  if (pcSPS->vuiParametersPresent)
1033
0
  {
1034
0
    OutputBitstream *bs = m_pcBitIf; // save the original ono
1035
0
    OutputBitstream bs_count;
1036
0
    setBitstream(&bs_count);
1037
#if ENABLE_TRACING
1038
    bool traceEnable = g_HLSTraceEnable;
1039
    g_HLSTraceEnable = false;
1040
#endif
1041
0
    codeVUI(&pcSPS->vuiParameters, pcSPS);
1042
#if ENABLE_TRACING
1043
    g_HLSTraceEnable = traceEnable;
1044
#endif
1045
0
    unsigned vui_payload_data_num_bits = bs_count.getNumberOfWrittenBits();
1046
0
    CHECK( vui_payload_data_num_bits % 8 != 0, "Invalid number of VUI payload data bits" );
1047
0
    setBitstream(bs);
1048
0
    WRITE_UVLC((vui_payload_data_num_bits >> 3) - 1,        "sps_vui_payload_size_minus1");
1049
0
    while (!isByteAligned())
1050
0
    {
1051
0
      WRITE_FLAG(0,                                         "sps_vui_alignment_zero_bit");
1052
0
    }
1053
0
    codeVUI(&pcSPS->vuiParameters, pcSPS);
1054
0
  }
1055
1056
0
  bool sps_extension_present_flag=false;
1057
0
  bool sps_extension_flags[NUM_SPS_EXTENSION_FLAGS]={false};
1058
1059
0
  for(int i=0; i<NUM_SPS_EXTENSION_FLAGS; i++)
1060
0
  {
1061
0
    sps_extension_present_flag|=sps_extension_flags[i];
1062
0
  }
1063
1064
0
  WRITE_FLAG( sps_extension_present_flag,                   "sps_extension_present_flag" );
1065
1066
0
  if (sps_extension_present_flag)
1067
0
  {
1068
#if ENABLE_TRACING
1069
    static const char *syntaxStrings[]={ "sps_range_extension_flag",
1070
      "sps_multilayer_extension_flag",
1071
      "sps_extension_6bits[0]",
1072
      "sps_extension_6bits[1]",
1073
      "sps_extension_6bits[2]",
1074
      "sps_extension_6bits[3]",
1075
      "sps_extension_6bits[4]",
1076
      "sps_extension_6bits[5]" };
1077
#endif
1078
1079
0
    for(int i=0; i<NUM_SPS_EXTENSION_FLAGS; i++)
1080
0
    {
1081
0
      WRITE_FLAG( sps_extension_flags[i], syntaxStrings[i] );
1082
0
    }
1083
1084
0
    for(int i=0; i<NUM_SPS_EXTENSION_FLAGS; i++) // loop used so that the order is determined by the enum.
1085
0
    {
1086
0
      if (sps_extension_flags[i])
1087
0
      {
1088
#if 0 // TODO: enable when applicable
1089
        switch (SPSExtensionFlagIndex(i))
1090
        {
1091
        default:
1092
          CHECK(sps_extension_flags[i]!=false, "Unknown PPS extension signalled"); // Should never get here with an active SPS extension flag.
1093
          break;
1094
        }
1095
#endif
1096
0
      }
1097
0
    }
1098
0
  }
1099
0
  xWriteRbspTrailingBits();
1100
0
}
1101
1102
void HLSWriter::codeDCI( const DCI* dci )
1103
0
{
1104
0
  DTRACE( g_trace_ctx, D_HEADER, "=========== Decoding Parameter Set     ===========\n" );
1105
1106
0
  WRITE_CODE( 0,                                    4,        "dci_reserved_zero_5bits" );
1107
0
  uint32_t numPTLs = (uint32_t) dci->profileTierLevel.size();
1108
0
  CHECK (numPTLs<1, "At least one PTL must be available in DPS");
1109
1110
0
  WRITE_CODE( numPTLs - 1,                          4,        "dci_num_ptls_minus1" );
1111
1112
0
  for (int i=0; i< numPTLs; i++)
1113
0
  {
1114
0
    codeProfileTierLevel( &dci->profileTierLevel[i], true, 0 );
1115
0
  }
1116
0
  WRITE_FLAG( 0,                                              "dci_extension_flag" );
1117
0
  xWriteRbspTrailingBits();
1118
0
}
1119
1120
void HLSWriter::codeVPS(const VPS* pcVPS)
1121
0
{
1122
0
  DTRACE( g_trace_ctx, D_HEADER, "=========== Video Parameter Set     ===========\n" );
1123
1124
0
  WRITE_CODE(pcVPS->vpsId,              4,              "vps_video_parameter_set_id");
1125
0
  WRITE_CODE(pcVPS->maxLayers - 1,      6,              "vps_max_layers_minus1");
1126
0
  WRITE_CODE(pcVPS->maxSubLayers - 1,   3,              "vps_max_sublayers_minus1");
1127
0
  if (pcVPS->maxLayers > 1 && pcVPS->maxSubLayers > 1)
1128
0
  {
1129
0
    WRITE_FLAG(pcVPS->defaultPtlDpbHrdMaxTidFlag,        "vps_default_ptl_dpb_hrd_max_tid_flag");
1130
0
  }
1131
0
  if (pcVPS->maxLayers > 1)
1132
0
  {
1133
0
    WRITE_FLAG(pcVPS->allIndependentLayers,             "vps_all_independent_layers_flag");
1134
0
  }
1135
0
  for (uint32_t i = 0; i < pcVPS->maxLayers; i++)
1136
0
  {
1137
0
    WRITE_CODE(pcVPS->layerId[i], 6,                    "vps_layer_id");
1138
0
    if (i > 0 && !pcVPS->allIndependentLayers)
1139
0
    {
1140
0
      WRITE_FLAG(pcVPS->independentLayer[i],            "vps_independent_layer_flag");
1141
0
      if (!pcVPS->independentLayer[i])
1142
0
      {
1143
0
        bool presentFlag = false;
1144
0
        for (int j = 0; j < i; j++)
1145
0
        {
1146
0
          presentFlag |= ((pcVPS->maxTidIlRefPicsPlus1[i][j] != VVENC_MAX_TLAYER) && pcVPS->directRefLayer[i][j]);
1147
0
        }
1148
0
        WRITE_FLAG(presentFlag, "max_tid_ref_present_flag[ i ]");
1149
0
        for (int j = 0; j < i; j++)
1150
0
        {
1151
0
          WRITE_FLAG(pcVPS->directRefLayer[i][j], "vps_direct_ref_layer_flag");
1152
0
          if (presentFlag && pcVPS->directRefLayer[i][j])
1153
0
          {
1154
0
            WRITE_CODE(pcVPS->maxTidIlRefPicsPlus1[i][j], 3, "max_tid_il_ref_pics_plus1[ i ][ j ]");
1155
0
          }
1156
0
        }
1157
0
      }
1158
0
    }
1159
0
  }
1160
0
  if( pcVPS->maxLayers > 1 )
1161
0
  {
1162
0
    if (pcVPS->allIndependentLayers)
1163
0
    {
1164
0
      WRITE_FLAG(pcVPS->eachLayerIsAnOls,               "vps_each_layer_is_an_ols_flag");
1165
0
    }
1166
0
    if (!pcVPS->eachLayerIsAnOls)
1167
0
    {
1168
0
      if (!pcVPS->allIndependentLayers)
1169
0
      {
1170
0
        WRITE_CODE(pcVPS->olsModeIdc, 2,                "vps_ols_mode_idc");
1171
0
      }
1172
0
      if (pcVPS->olsModeIdc == 2)
1173
0
      {
1174
0
        WRITE_CODE(pcVPS->numOutputLayerSets - 2, 8,    "vps_num_output_layer_sets_minus2");
1175
0
        for (uint32_t i = 1; i < pcVPS->numOutputLayerSets; i++)
1176
0
        {
1177
0
          for (uint32_t j = 0; j < pcVPS->maxLayers; j++)
1178
0
          {
1179
0
            WRITE_FLAG(pcVPS->olsOutputLayer[i][j],     "vps_ols_output_layer_flag");
1180
0
          }
1181
0
        }
1182
0
      }
1183
0
    }
1184
0
    CHECK(pcVPS->numPtls - 1 >= pcVPS->totalNumOLSs, "vps_num_ptls_minus1 shall be less than TotalNumOlss");
1185
0
    WRITE_CODE(pcVPS->numPtls - 1, 8,                   "vps_num_ptls_minus1");
1186
0
  }
1187
1188
0
  int totalNumOlss = pcVPS->totalNumOLSs;
1189
0
  for (int i = 0; i < pcVPS->numPtls; i++)
1190
0
  {
1191
0
    if(i > 0)
1192
0
    {
1193
0
      WRITE_FLAG(pcVPS->ptPresent[i],                   "vps_ptl_present_flag");
1194
0
    }
1195
0
    if(!pcVPS->allLayersSameNumSubLayers)
1196
0
    {
1197
0
      WRITE_CODE(pcVPS->ptlMaxTemporalId[i] ,3,         "vps_ptl_max_temporal_id");
1198
0
    }
1199
0
  }
1200
0
  int cnt = 0;
1201
0
  while (m_pcBitIf->getNumBitsUntilByteAligned())
1202
0
  {
1203
0
    WRITE_FLAG( 0,                                      "vps_ptl_reserved_zero_bit");
1204
0
    cnt++;
1205
0
  }
1206
0
  CHECK(cnt>=8, "More than '8' alignment bytes written");
1207
0
  for (int i = 0; i < pcVPS->numPtls; i++)
1208
0
  {
1209
0
    codeProfileTierLevel(&pcVPS->profileTierLevel[i], pcVPS->ptPresent[i], pcVPS->ptlMaxTemporalId[i] - 1);
1210
0
  }
1211
0
  for (int i = 0; i < totalNumOlss; i++)
1212
0
  {
1213
0
    if(pcVPS->numPtls > 1 && pcVPS->numPtls != pcVPS->totalNumOLSs)
1214
0
      WRITE_CODE(pcVPS->olsPtlIdx[i], 8,                "vps_ols_ptl_idx");
1215
0
  }
1216
0
  if( !pcVPS->allIndependentLayers )
1217
0
  {
1218
0
    WRITE_UVLC( pcVPS->numDpbParams,                    "vps_num_dpb_params" );
1219
0
  }
1220
1221
0
  if( pcVPS->numDpbParams > 0 && pcVPS->maxSubLayers > 1 )
1222
0
  {
1223
0
    WRITE_FLAG( pcVPS->sublayerDpbParamsPresent,        "vps_sublayer_dpb_params_present_flag" );
1224
0
  }
1225
1226
0
  for( int i = 0; i < pcVPS->numDpbParams; i++ )
1227
0
  {
1228
0
    if( !pcVPS->allLayersSameNumSubLayers )
1229
0
    {
1230
0
      WRITE_CODE( pcVPS->dpbMaxTemporalId[i], 3,      "vps_dpb_max_temporal_id[i]" );
1231
0
    }
1232
0
    if( pcVPS->maxSubLayers == 1 )
1233
0
    {
1234
0
      CHECK( pcVPS->dpbMaxTemporalId[i] != 0, "When vps_max_sublayers_minus1 is equal to 0, the value of dpb_max_temporal_id[ i ] is inferred to be equal to 0" );
1235
0
    }
1236
0
    else
1237
0
    {
1238
0
      if( pcVPS->defaultPtlDpbHrdMaxTidFlag )
1239
0
      {
1240
0
        CHECK( pcVPS->dpbMaxTemporalId[i] != pcVPS->maxSubLayers - 1, "When vps_max_sublayers_minus1 is greater than 0 and vps_all_layers_same_num_sublayers_flag is equal to 1, the value of dpb_max_temporal_id[ i ] is inferred to be equal to vps_max_sublayers_minus1" );
1241
0
      }
1242
0
      else
1243
0
      {
1244
0
        WRITE_CODE( pcVPS->dpbMaxTemporalId[i], 3,      "vps_dpb_max_temporal_id[i]" );
1245
0
      }
1246
0
    }
1247
1248
0
    for( int j = ( pcVPS->sublayerDpbParamsPresent ? 0 : pcVPS->dpbMaxTemporalId[i] ); j <= pcVPS->dpbMaxTemporalId[i]; j++ )
1249
0
    {
1250
0
      WRITE_UVLC( pcVPS->dpbParameters[i].maxDecPicBuffering[j],      "max_dec_pic_buffering_minus1[i]" );
1251
0
      WRITE_UVLC( pcVPS->dpbParameters[i].numReorderPics[j],          "max_num_reorder_pics[i]" );
1252
0
      WRITE_UVLC( pcVPS->dpbParameters[i].maxLatencyIncreasePlus1[j], "max_latency_increase_plus1[i]" );
1253
0
    }
1254
0
  }
1255
1256
0
  for( int i = 0; i < pcVPS->totalNumOLSs; i++ )
1257
0
  {
1258
0
    if( pcVPS->numLayersInOls[i] > 1 )
1259
0
    {
1260
0
      WRITE_UVLC( pcVPS->olsDpbPicSize[i].width,          "vps_ols_dpb_pic_width[i]" );
1261
0
      WRITE_UVLC( pcVPS->olsDpbPicSize[i].height,         "vps_ols_dpb_pic_height[i]" );
1262
0
      WRITE_CODE( pcVPS->olsDpbChromaFormatIdc[i], 2,     "vps_ols_dpb_chroma_format[i]");
1263
0
      WRITE_UVLC( pcVPS->olsDpbBitDepthMinus8[i],         "vps_ols_dpb_bitdepth_minus8[i]");
1264
0
      if( pcVPS->numDpbParams > 1 && (pcVPS->numDpbParams != pcVPS->numMultiLayeredOlss) )
1265
0
      {
1266
0
        WRITE_UVLC( pcVPS->olsDpbParamsIdx[i],            "vps_ols_dpb_params_idx[i]" );
1267
0
      }
1268
0
    }
1269
0
  }
1270
1271
1272
0
  if (!pcVPS->eachLayerIsAnOls)
1273
0
  {
1274
0
    WRITE_FLAG(pcVPS->generalHrdParamsPresent, "vps_general_hrd_params_present_flag");
1275
0
  }
1276
0
  if (pcVPS->generalHrdParamsPresent)
1277
0
  {
1278
0
    codeGeneralHrdparameters(&pcVPS->generalHrdParams);
1279
0
    if ((pcVPS->maxSubLayers-1) > 0)
1280
0
    {
1281
0
      WRITE_FLAG(pcVPS->sublayerCpbParamsPresent, "vps_sublayer_cpb_params_present_flag");
1282
0
    }
1283
0
    WRITE_UVLC(pcVPS->numOlsHrdParamsMinus1, "vps_num_ols_hrd_params_minus1");
1284
0
    for (int i = 0; i <= pcVPS->numOlsHrdParamsMinus1; i++)
1285
0
    {
1286
0
      if (!pcVPS->defaultPtlDpbHrdMaxTidFlag)
1287
0
      {
1288
0
        WRITE_CODE(pcVPS->hrdMaxTid[i], 3, "vps_hrd_vps_max_tid[i]");
1289
0
      }
1290
0
      uint32_t firstSublayer = pcVPS->sublayerCpbParamsPresent ? 0 : pcVPS->hrdMaxTid[i];
1291
0
      codeOlsHrdParameters(&pcVPS->generalHrdParams, &pcVPS->olsHrdParams[i], firstSublayer, pcVPS->hrdMaxTid[i]);
1292
0
    }
1293
0
    if ((pcVPS->numOlsHrdParamsMinus1 > 0) && ((pcVPS->numOlsHrdParamsMinus1 + 1) != pcVPS->numMultiLayeredOlss))
1294
0
    {
1295
0
      for (int i = 0; i < pcVPS->numMultiLayeredOlss; i++)
1296
0
      {
1297
0
        WRITE_UVLC(pcVPS->olsHrdIdx[i], "vps_ols_hrd_idx[i]");
1298
0
      }
1299
0
    }
1300
0
  }
1301
0
  WRITE_FLAG(0,                                           "vps_extension_flag");
1302
1303
  //future extensions here..
1304
0
  xWriteRbspTrailingBits();
1305
0
}
1306
1307
void HLSWriter::codePictureHeader( const PicHeader* picHeader, bool writeRbspTrailingBits )
1308
0
{
1309
0
  const PPS*  pps = NULL;
1310
0
  const SPS*  sps = NULL;
1311
1312
0
  DTRACE( g_trace_ctx, D_HEADER, "=========== Picture Header ===========\n" );
1313
1314
0
  CodingStructure& cs = *picHeader->pic->cs;
1315
0
  WRITE_FLAG(picHeader->gdrOrIrapPic, "ph_gdr_or_irap_pic_flag");
1316
0
  WRITE_FLAG(picHeader->nonRefPic,    "ph_non_ref_pic_flag");
1317
0
  if (picHeader->gdrOrIrapPic)
1318
0
  {
1319
0
    WRITE_FLAG(picHeader->gdrPic,     "ph_gdr_pic_flag");
1320
0
  }
1321
  // Q0781, two-flags
1322
0
  WRITE_FLAG(picHeader->picInterSliceAllowed,   "ph_inter_slice_allowed_flag");
1323
0
  if (picHeader->picInterSliceAllowed)
1324
0
  {
1325
0
    WRITE_FLAG(picHeader->picIntraSliceAllowed, "ph_intra_slice_allowed_flag");
1326
0
  }
1327
  // parameter sets
1328
0
  WRITE_UVLC(picHeader->ppsId,                  "ph_pic_parameter_set_id");
1329
0
  pps = cs.slice->pps;
1330
0
  CHECK(pps == 0, "Invalid PPS");
1331
0
  sps = cs.slice->sps;
1332
0
  CHECK(sps == 0, "Invalid SPS");
1333
0
  int pocBits = cs.slice->sps->bitsForPOC;
1334
0
  int pocMask = (1 << pocBits) - 1;
1335
0
  WRITE_CODE(cs.slice->poc & pocMask, pocBits,  "ph_pic_order_cnt_lsb");
1336
0
  if( picHeader->gdrPic )
1337
0
  {
1338
0
    WRITE_UVLC(picHeader->recoveryPocCnt,       "ph_recovery_poc_cnt");
1339
0
  }
1340
1341
  // PH extra bits are not written in the reference encoder
1342
  // as these bits are reserved for future extensions
1343
  // for( i = 0; i < NumExtraPhBits; i++ )
1344
  //    ph_extra_bit[ i ]
1345
1346
0
  if (sps->pocMsbFlag)
1347
0
  {
1348
0
    WRITE_FLAG(picHeader->pocMsbPresent,        "ph_poc_msb_present_flag");
1349
0
    if (picHeader->pocMsbPresent)
1350
0
    {
1351
0
      WRITE_CODE(picHeader->pocMsbVal, sps->pocMsbLen, "ph_poc_msb_val");
1352
0
    }
1353
0
  }
1354
1355
   // alf enable flags and aps IDs
1356
0
  if( sps->alfEnabled)
1357
0
  {
1358
0
    if (pps->alfInfoInPh)
1359
0
    {
1360
0
      WRITE_FLAG(picHeader->alfEnabled[COMP_Y],         "ph_alf_enabled_flag");
1361
0
      if (picHeader->alfEnabled[COMP_Y])
1362
0
      {
1363
0
        WRITE_CODE(picHeader->numAlfAps, 3,             "ph_num_alf_aps_ids_luma");
1364
0
        for (int i = 0; i < picHeader->numAlfAps; i++)
1365
0
        {
1366
0
          WRITE_CODE(picHeader->alfApsId[i], 3,         "ph_alf_aps_id_luma");
1367
0
        }
1368
1369
0
        const int alfChromaIdc = picHeader->alfEnabled[COMP_Cb] + picHeader->alfEnabled[COMP_Cr] * 2 ;
1370
0
        if (sps->chromaFormatIdc != CHROMA_400)
1371
0
        {
1372
0
          WRITE_CODE(picHeader->alfEnabled[COMP_Cb], 1, "ph_alf_cb_enabled_flag");
1373
0
          WRITE_CODE(picHeader->alfEnabled[COMP_Cr], 1, "ph_alf_cr_enabled_flag");
1374
0
        }
1375
0
        if (alfChromaIdc)
1376
0
        {
1377
0
          WRITE_CODE(picHeader->alfChromaApsId, 3,      "ph_alf_aps_id_chroma");
1378
0
        }
1379
0
        if (sps->ccalfEnabled)
1380
0
        {
1381
0
          WRITE_FLAG(picHeader->ccalfEnabled[COMP_Cb],  "ph_cc_alf_cb_enabled_flag");
1382
0
          if (picHeader->ccalfEnabled[COMP_Cb])
1383
0
          {
1384
0
            WRITE_CODE(picHeader->ccalfCbApsId, 3,      "ph_cc_alf_cb_aps_id");
1385
0
          }
1386
0
          WRITE_FLAG(picHeader->ccalfEnabled[COMP_Cr],  "ph_cc_alf_cr_enabled_flag");
1387
0
          if (picHeader->ccalfEnabled[COMP_Cr])
1388
0
          {
1389
0
            WRITE_CODE(picHeader->ccalfCrApsId, 3,      "ph_cc_alf_cr_aps_id");
1390
0
          }
1391
0
        }
1392
0
      }
1393
0
    }
1394
0
  }
1395
1396
  // luma mapping / chroma scaling controls
1397
0
  if (sps->lumaReshapeEnable)
1398
0
  {
1399
0
    WRITE_FLAG(picHeader->lmcsEnabled,                  "ph_lmcs_enabled_flag");
1400
0
    if (picHeader->lmcsEnabled)
1401
0
    {
1402
0
      WRITE_CODE(picHeader->lmcsApsId, 2,               "ph_lmcs_aps_id");
1403
0
      if (sps->chromaFormatIdc != CHROMA_400)
1404
0
      {
1405
0
        WRITE_FLAG(picHeader->lmcsChromaResidualScale,  "ph_chroma_residual_scale_flag");
1406
0
      }
1407
0
    }
1408
0
  }
1409
1410
  // quantization scaling lists
1411
0
  if( sps->scalingListEnabled )
1412
0
  {
1413
0
    WRITE_FLAG( picHeader->explicitScalingListEnabled,  "ph_scaling_list_present_flag" );
1414
0
    if( picHeader->explicitScalingListEnabled )
1415
0
    {
1416
0
      WRITE_CODE( picHeader->scalingListApsId, 3,       "ph_scaling_list_aps_id" );
1417
0
    }
1418
0
  }
1419
1420
  // virtual boundaries
1421
0
  if( sps->virtualBoundariesEnabled && !sps->virtualBoundariesPresent )
1422
0
  {
1423
0
    WRITE_FLAG( picHeader->virtualBoundariesEnabled,    "ph_loop_filter_across_virtual_boundaries_disabled_present_flag" );
1424
0
    if( picHeader->virtualBoundariesEnabled )
1425
0
    {
1426
0
      WRITE_CODE(picHeader->numVerVirtualBoundaries, 2, "ph_num_ver_virtual_boundaries");
1427
0
      for( unsigned i = 0; i < picHeader->numVerVirtualBoundaries; i++ )
1428
0
      {
1429
0
        WRITE_UVLC(picHeader->virtualBoundariesPosX[i] >> 3, "ph_virtual_boundaries_pos_x");
1430
0
      }
1431
0
      WRITE_CODE(picHeader->numHorVirtualBoundaries, 2, "ph_num_hor_virtual_boundaries");
1432
0
      for( unsigned i = 0; i < picHeader->numHorVirtualBoundaries; i++ )
1433
0
      {
1434
0
        WRITE_UVLC(picHeader->virtualBoundariesPosY[i]>>3, "ph_virtual_boundaries_pos_y");
1435
0
      }
1436
0
    }
1437
0
  }
1438
1439
  // picture output flag
1440
0
  if( pps->outputFlagPresent && !picHeader->nonRefPic)
1441
0
  {
1442
0
    WRITE_FLAG( picHeader->picOutputFlag, "ph_pic_output_flag" );
1443
0
  }
1444
1445
  // reference picture lists
1446
0
  if (pps->rplInfoInPh)
1447
0
  {
1448
    // List0 and List1
1449
0
    for(int listIdx = 0; listIdx < 2; listIdx++)
1450
0
    {
1451
0
      if(sps->getNumRPL(listIdx) > 0 &&
1452
0
          (listIdx == 0 || (listIdx == 1 && pps->rpl1IdxPresent)))
1453
0
      {
1454
0
        WRITE_FLAG(picHeader->rplIdx[listIdx] != -1 ? 1 : 0, "pic_rpl_sps_flag[i]");
1455
0
      }
1456
0
      else if(sps->getNumRPL(listIdx) == 0)
1457
0
      {
1458
0
        CHECK(picHeader->rplIdx[listIdx] != -1, "rpl_sps_flag[1] will be infer to 0 and this is not what was expected");
1459
0
      }
1460
0
      else if(listIdx == 1)
1461
0
      {
1462
0
        auto rplsSpsFlag0 = picHeader->rplIdx[0] != -1 ? 1 : 0;
1463
0
        auto rplsSpsFlag1 = picHeader->rplIdx[1] != -1 ? 1 : 0;
1464
0
        CHECK(rplsSpsFlag1 != rplsSpsFlag0, "rpl_sps_flag[1] will be infer to 0 and this is not what was expected");
1465
0
      }
1466
1467
0
      if(picHeader->rplIdx[listIdx] != -1)
1468
0
      {
1469
0
        if(sps->getNumRPL(listIdx) > 1 &&
1470
0
            (listIdx == 0 || (listIdx == 1 && pps->rpl1IdxPresent)))
1471
0
        {
1472
0
          int numBits = ceilLog2(sps->getNumRPL( listIdx ));
1473
0
          WRITE_CODE(picHeader->rplIdx[listIdx], numBits, "pic_rpl_idx[i]");
1474
0
        }
1475
0
        else if(sps->getNumRPL(listIdx) == 1)
1476
0
        {
1477
0
          CHECK(picHeader->rplIdx[listIdx] != 0, "RPL1Idx is not signalled but it is not equal to 0");
1478
0
        }
1479
0
        else
1480
0
        {
1481
0
          CHECK(picHeader->rplIdx[1] != picHeader->rplIdx[0], "RPL1Idx is not signalled but it is not the same as RPL0Idx");
1482
0
        }
1483
0
      }
1484
      // explicit RPL in picture header
1485
0
      else
1486
0
      {
1487
0
        xCodeRefPicList( picHeader->pRPL[listIdx], sps->longTermRefsPresent, sps->bitsForPOC, !(sps->weightPred||sps->weightedBiPred), -1 );
1488
0
      }
1489
1490
      // POC MSB cycle signalling for LTRP
1491
0
      if (picHeader->pRPL[listIdx]->numberOfLongtermPictures)
1492
0
      {
1493
0
        for (int i = 0; i < picHeader->pRPL[listIdx]->numberOfLongtermPictures + picHeader->pRPL[listIdx]->numberOfShorttermPictures; i++)
1494
0
        {
1495
0
          if (picHeader->pRPL[listIdx]->isLongtermRefPic[i])
1496
0
          {
1497
0
            if (picHeader->pRPL[listIdx]->ltrpInSliceHeader)
1498
0
            {
1499
0
              WRITE_CODE(picHeader->pRPL[listIdx]->refPicIdentifier[i], sps->bitsForPOC,
1500
0
                         "pic_poc_lsb_lt[listIdx][rplsIdx][j]");
1501
0
            }
1502
0
            WRITE_FLAG(picHeader->pRPL[listIdx]->deltaPocMSBPresent[i], "pic_delta_poc_msb_present_flag[i][j]");
1503
0
            if (picHeader->pRPL[listIdx]->deltaPocMSBPresent[i])
1504
0
            {
1505
0
              WRITE_UVLC(picHeader->pRPL[listIdx]->deltaPocMSBCycleLT[i], "pic_delta_poc_msb_cycle_lt[i][j]");
1506
0
            }
1507
0
          }
1508
0
        }
1509
0
      }
1510
0
    }
1511
0
  }
1512
1513
  // partitioning constraint overrides
1514
0
  if (sps->partitionOverrideEnabled )
1515
0
  {
1516
0
    WRITE_FLAG(picHeader->splitConsOverride, "partition_constraints_override_flag");
1517
0
  }
1518
1519
  // Q0781, two-flags
1520
0
  if (picHeader->picIntraSliceAllowed)
1521
0
  {
1522
0
    if (picHeader->splitConsOverride)
1523
0
    {
1524
0
      WRITE_UVLC(floorLog2(picHeader->minQTSize[0]) - sps->log2MinCodingBlockSize, "pic_log2_diff_min_qt_min_cb_intra_slice_luma");
1525
0
      WRITE_UVLC(picHeader->maxMTTDepth[0], "ph_max_mtt_hierarchy_depth_intra_slice_luma");
1526
0
      if (picHeader->maxMTTDepth[0] != 0)
1527
0
      {
1528
0
        WRITE_UVLC(floorLog2(picHeader->maxBTSize[0]) - floorLog2(picHeader->minQTSize[0]), "ph_log2_diff_max_bt_min_qt_intra_slice_luma");
1529
0
        WRITE_UVLC(floorLog2(picHeader->maxTTSize[0]) - floorLog2(picHeader->minQTSize[0]), "ph_log2_diff_max_tt_min_qt_intra_slice_luma");
1530
0
      }
1531
1532
0
      if (sps->dualITree)
1533
0
      {
1534
0
        WRITE_UVLC(floorLog2(picHeader->minQTSize[2]) - sps->log2MinCodingBlockSize, "ph_log2_diff_min_qt_min_cb_intra_slice_chroma");
1535
0
        WRITE_UVLC(picHeader->maxMTTDepth[2], "ph_max_mtt_hierarchy_depth_intra_slice_chroma");
1536
0
        if (picHeader->maxMTTDepth[2] != 0)
1537
0
        {
1538
0
          WRITE_UVLC(floorLog2(picHeader->maxBTSize[2]) - floorLog2(picHeader->minQTSize[2]), "ph_log2_diff_max_bt_min_qt_intra_slice_chroma");
1539
0
          WRITE_UVLC(floorLog2(picHeader->maxTTSize[2]) - floorLog2(picHeader->minQTSize[2]), "ph_log2_diff_max_tt_min_qt_intra_slice_chroma");
1540
0
        }
1541
0
      }
1542
0
    }
1543
0
  }
1544
0
  if (picHeader->picIntraSliceAllowed )
1545
0
  {
1546
  // delta quantization and chrom and chroma offset
1547
0
    if (pps->useDQP)
1548
0
    {
1549
0
      WRITE_UVLC( picHeader->cuQpDeltaSubdivIntra, "ph_cu_qp_delta_subdiv_intra_slice" );
1550
0
    }
1551
0
    if (pps->chromaQpOffsetListLen )
1552
0
    {
1553
0
      WRITE_UVLC( picHeader->cuChromaQpOffsetSubdivIntra, "ph_cu_chroma_qp_offset_subdiv_intra_slice" );
1554
0
    }
1555
0
  }
1556
1557
0
  if (picHeader->picInterSliceAllowed )
1558
0
  {
1559
0
    if (picHeader->splitConsOverride )
1560
0
    {
1561
0
      WRITE_UVLC(floorLog2(picHeader->minQTSize[1]) - sps->log2MinCodingBlockSize, "ph_log2_diff_min_qt_min_cb_inter_slice");
1562
0
      WRITE_UVLC(picHeader->maxMTTDepth[1], "ph_max_mtt_hierarchy_depth_inter_slice");
1563
0
      if (picHeader->maxMTTDepth[1] != 0)
1564
0
      {
1565
0
        WRITE_UVLC(floorLog2(picHeader->maxBTSize[1]) - floorLog2(picHeader->minQTSize[1]), "ph_log2_diff_max_bt_min_qt_inter_slice");
1566
0
        WRITE_UVLC(floorLog2(picHeader->maxTTSize[1]) - floorLog2(picHeader->minQTSize[1]), "ph_log2_diff_max_tt_min_qt_inter_slice");
1567
0
      }
1568
0
    }
1569
1570
    // delta quantization and chrom and chroma offset
1571
0
    if (pps->useDQP)
1572
0
    {
1573
0
      WRITE_UVLC(picHeader->cuQpDeltaSubdivInter, "ph_cu_qp_delta_subdiv_inter_slice");
1574
0
    }
1575
1576
0
    if (pps->chromaQpOffsetListLen )
1577
0
    {
1578
0
      WRITE_UVLC(picHeader->cuChromaQpOffsetSubdivInter, "ph_cu_chroma_qp_offset_subdiv_inter_slice");
1579
0
    }
1580
1581
    // temporal motion vector prediction
1582
0
    if (sps->temporalMVPEnabled)
1583
0
    {
1584
0
      WRITE_FLAG( picHeader->enableTMVP, "ph_temporal_mvp_enabled_flag" );
1585
0
      if (picHeader->enableTMVP && pps->rplInfoInPh)
1586
0
      {
1587
0
        if (picHeader->pRPL[1]->getNumRefEntries() > 0)
1588
0
        {
1589
0
          WRITE_CODE(picHeader->picColFromL0, 1, "ph_collocated_from_l0_flag");
1590
0
        }
1591
0
        if ((picHeader->picColFromL0 && picHeader->pRPL[0]->getNumRefEntries() > 1) ||
1592
0
          (!picHeader->picColFromL0 && picHeader->pRPL[1]->getNumRefEntries() > 1))
1593
0
        {
1594
0
          WRITE_UVLC(picHeader->colRefIdx, "ph_collocated_ref_idx");
1595
0
        }
1596
0
      }
1597
0
    }
1598
1599
  // full-pel MMVD flag
1600
0
    if (sps->fpelMmvd )
1601
0
    {
1602
0
      WRITE_FLAG( picHeader->disFracMMVD, "ph_fpel_mmvd_enabled_flag" );
1603
0
    }
1604
  // mvd L1 zero flag
1605
0
    if (!pps->rplInfoInPh || picHeader->pRPL[1]->getNumRefEntries() > 0)
1606
0
    {
1607
0
      WRITE_FLAG(picHeader->mvdL1Zero, "ph_mvd_l1_zero_flag");
1608
0
    }
1609
1610
  // picture level BDOF disable flags
1611
0
    if (sps->BdofPresent && (!pps->rplInfoInPh || picHeader->pRPL[1]->getNumRefEntries() > 0))
1612
0
    {
1613
0
      WRITE_FLAG(picHeader->disBdofFlag, "ph_disable_bdof_flag");
1614
0
    }
1615
1616
  // picture level DMVR disable flags
1617
0
    if (sps->DmvrPresent && (!pps->rplInfoInPh || picHeader->pRPL[1]->getNumRefEntries() > 0))
1618
0
    {
1619
0
      WRITE_FLAG(picHeader->disDmvrFlag, "ph_disable_dmvr_flag");
1620
0
    }
1621
1622
  // picture level PROF disable flags
1623
0
    if (sps->ProfPresent)
1624
0
    {
1625
0
      WRITE_FLAG(picHeader->disProfFlag, "ph_disable_prof_flag");
1626
0
    }
1627
1628
0
    if ((pps->weightPred || pps->weightedBiPred) && pps->wpInfoInPh )
1629
0
    {
1630
0
      xCodePredWeightTable(picHeader, pps, sps);
1631
0
    }
1632
0
   }
1633
1634
0
  if (pps->qpDeltaInfoInPh)
1635
0
  {
1636
0
    WRITE_SVLC(picHeader->qpDelta, "ph_qp_delta");
1637
0
  }
1638
1639
  // joint Cb/Cr sign flag
1640
0
  if (sps->jointCbCr )
1641
0
  {
1642
0
    WRITE_FLAG( picHeader->jointCbCrSign, "ph_joint_cbcr_sign_flag" );
1643
0
  }
1644
1645
  // sao enable flags
1646
0
  if(sps->saoEnabled)
1647
0
  {
1648
0
    if (pps->saoInfoInPh)
1649
0
    {
1650
0
      WRITE_FLAG(picHeader->saoEnabled[CH_L], "ph_sao_luma_enabled_flag");
1651
0
      if (sps->chromaFormatIdc != CHROMA_400)
1652
0
      {
1653
0
        WRITE_FLAG(picHeader->saoEnabled[CH_C], "ph_sao_chroma_enabled_flag");
1654
0
      }
1655
0
    }
1656
0
  }
1657
1658
  // deblocking filter controls
1659
0
  if (pps->deblockingFilterControlPresent )
1660
0
  {
1661
0
    if(pps->deblockingFilterOverrideEnabled)
1662
0
    {
1663
0
      if (pps->dbfInfoInPh)
1664
0
      {
1665
0
        WRITE_FLAG ( picHeader->deblockingFilterOverride, "ph_deblocking_filter_override_flag" );
1666
 
1667
0
        if(picHeader->deblockingFilterOverride)
1668
0
        {
1669
0
          WRITE_FLAG( picHeader->deblockingFilterDisable, "ph_deblocking_filter_disabled_flag" );
1670
0
          if( !picHeader->deblockingFilterDisable )
1671
0
          {
1672
0
            WRITE_SVLC( picHeader->deblockingFilterBetaOffsetDiv2[COMP_Y], "ph_beta_offset_div2" );
1673
0
            WRITE_SVLC( picHeader->deblockingFilterTcOffsetDiv2[COMP_Y], "ph_tc_offset_div2" );
1674
0
            if( pps->usePPSChromaTool )
1675
0
            {
1676
0
              WRITE_SVLC( picHeader->deblockingFilterBetaOffsetDiv2[COMP_Cb], "ph_cb_beta_offset_div2" );
1677
0
              WRITE_SVLC( picHeader->deblockingFilterTcOffsetDiv2[COMP_Cb], "ph_cb_tc_offset_div2" );
1678
0
              WRITE_SVLC( picHeader->deblockingFilterBetaOffsetDiv2[COMP_Cr], "ph_cr_beta_offset_div2" );
1679
0
              WRITE_SVLC( picHeader->deblockingFilterTcOffsetDiv2[COMP_Cr], "ph_cr_tc_offset_div2" );
1680
0
            }
1681
0
          }
1682
0
        }
1683
0
      }
1684
0
    }
1685
0
  }
1686
1687
  // picture header extension
1688
0
  if(pps->pictureHeaderExtensionPresent)
1689
0
  {
1690
0
    WRITE_UVLC(0,"ph_extension_length");
1691
0
  }
1692
1693
0
  if ( writeRbspTrailingBits )
1694
0
  {
1695
0
    xWriteRbspTrailingBits();
1696
0
  }
1697
0
}
1698
1699
1700
void HLSWriter::codeSliceHeader( const Slice* slice )
1701
0
{
1702
0
  DTRACE( g_trace_ctx, D_HEADER, "=========== Slice ===========\n" );
1703
1704
0
  CodingStructure& cs        = *slice->pic->cs;
1705
0
  const PicHeader *picHeader = cs.picHeader;
1706
0
  const ChromaFormat format  = slice->sps->chromaFormatIdc;
1707
0
  const uint32_t numberValidComponents = getNumberValidComponents(format);
1708
0
  const bool chromaEnabled = isChromaEnabled(format);
1709
1710
0
  WRITE_FLAG(slice->pictureHeaderInSliceHeader, "sh_picture_header_in_slice_header_flag");
1711
0
  if(slice->pictureHeaderInSliceHeader)
1712
0
  {
1713
0
    codePictureHeader(picHeader, false);
1714
0
  }
1715
1716
0
  if (slice->sps->subPicInfoPresent)
1717
0
  {
1718
0
    uint32_t bitsSubPicId;
1719
0
    if (slice->sps->subPicIdMappingExplicitlySignalled)
1720
0
    {
1721
0
      bitsSubPicId = slice->sps->subPicIdLen;
1722
0
    }
1723
0
    else if (slice->pps->subPicIdMappingInPps)
1724
0
    {
1725
0
      bitsSubPicId = slice->pps->subPicIdLen;
1726
0
    }
1727
0
    else
1728
0
    {
1729
0
      bitsSubPicId = ceilLog2(slice->sps->numSubPics);
1730
0
    }
1731
0
    WRITE_CODE(slice->sliceSubPicId, bitsSubPicId, "sh_subpic_id");
1732
0
  }
1733
1734
0
  if (!slice->pps->rectSlice)
1735
0
  {
1736
0
    THROW("no suppport");
1737
0
  }
1738
0
  else
1739
0
  {
1740
    // slice address is the index of the slice within the current sub-picture
1741
0
    uint32_t currSubPicIdx = slice->pps->getSubPicIdxFromSubPicId( slice->sliceSubPicId );
1742
0
    SubPic currSubPic = slice->pps->subPics[currSubPicIdx];
1743
0
    if( currSubPic.numSlicesInSubPic > 1 )
1744
0
    {
1745
0
      int numSlicesInPreviousSubPics = 0;
1746
0
      for(int sp = 0; sp < currSubPicIdx; sp++)
1747
0
      {
1748
0
        numSlicesInPreviousSubPics += slice->pps->subPics[sp].numSlicesInSubPic;
1749
0
      }
1750
0
      int bitsSliceAddress = ceilLog2(currSubPic.numSlicesInSubPic);
1751
0
      WRITE_CODE( slice->sliceMap.sliceID - numSlicesInPreviousSubPics, bitsSliceAddress, "sh_slice_address");
1752
0
    }
1753
0
  }
1754
1755
0
  if (picHeader->picInterSliceAllowed)
1756
0
  {
1757
0
    WRITE_UVLC(slice->sliceType, "sh_slice_type");
1758
0
  }
1759
0
  if (picHeader->gdrOrIrapPic) //th check this
1760
0
  {
1761
0
    WRITE_FLAG(picHeader->noOutputOfPriorPics, "sh_no_output_of_prior_pics_flag");
1762
0
  }
1763
1764
0
  if (!picHeader->picIntraSliceAllowed )
1765
0
  {
1766
0
    CHECK(slice->sliceType == VVENC_I_SLICE, "when pic_intra_slice_allowed_flag = 0, no I_Slice is allowed");
1767
0
  }
1768
1769
0
  if (slice->sps->alfEnabled && !slice->pps->alfInfoInPh)
1770
0
  {
1771
0
    const int alfEnabled = slice->alfEnabled[COMP_Y];
1772
0
    WRITE_FLAG(alfEnabled, "sh_alf_enabled_flag");
1773
1774
0
    if (alfEnabled)
1775
0
    {
1776
0
      WRITE_CODE(slice->numAps, 3, "sh_num_alf_aps_ids_luma");
1777
0
      for (int i = 0; i < slice->numAps; i++)
1778
0
      {
1779
0
        WRITE_CODE(slice->lumaApsId[i], 3, "sh_alf_aps_id_luma");
1780
0
      }
1781
1782
0
      const int alfChromaIdc = slice->alfEnabled[COMP_Cb] + slice->alfEnabled[COMP_Cr] * 2;
1783
0
      if (chromaEnabled)
1784
0
      {
1785
0
        WRITE_FLAG(slice->alfEnabled[COMP_Cb], "sh_alf_cb_enabled_flag");
1786
0
        WRITE_FLAG(slice->alfEnabled[COMP_Cr], "sh_alf_cr_enabled_flag");
1787
0
      }
1788
0
      if (alfChromaIdc)
1789
0
      {
1790
0
        WRITE_CODE(slice->chromaApsId, 3,      "sh_alf_aps_id_chroma");
1791
0
      }
1792
1793
0
      if (slice->sps->ccalfEnabled)
1794
0
      {
1795
0
        WRITE_FLAG(slice->ccAlfCbEnabled,      "sh_cc_alf_cb_enabled_flag");
1796
0
        if( slice->ccAlfCbEnabled )
1797
0
        {
1798
          // write CC ALF Cb APS ID
1799
0
          WRITE_CODE(slice->ccAlfCbApsId, 3,   "sh_cc_alf_cb_aps_id");
1800
0
        }
1801
        // Cr
1802
0
        WRITE_FLAG(slice->ccAlfCrEnabled,      "sh_cc_alf_cr_enabled_flag");
1803
0
        if( slice->ccAlfCrEnabled )
1804
0
        {
1805
          // write CC ALF Cr APS ID
1806
0
          WRITE_CODE(slice->ccAlfCrApsId, 3,   "sh_cc_alf_cr_aps_id");
1807
0
        }
1808
0
      }
1809
0
    }
1810
0
  }
1811
1812
0
  if (picHeader->lmcsEnabled && !slice->pictureHeaderInSliceHeader)
1813
0
  {
1814
0
    WRITE_FLAG( slice->lmcsEnabled,             "sh_lmcs_enabled_flag");
1815
0
  }
1816
0
  if (picHeader->explicitScalingListEnabled && !slice->pictureHeaderInSliceHeader)
1817
0
  {
1818
0
    WRITE_FLAG(slice->explicitScalingListUsed,  "sh_explicit_scaling_list_used_flag");
1819
0
  }
1820
1821
0
  if(  !slice->pps->rplInfoInPh && (!slice->getIdrPicFlag() || slice->sps->idrRefParamList))
1822
0
  {
1823
0
    int numRPL0 = slice->sps->getNumRPL(0);
1824
    //Write L0 related syntax elements
1825
0
    if (numRPL0 > 0)
1826
0
    {
1827
0
      WRITE_FLAG(slice->rplIdx[0] != -1, "ref_pic_list_sps_flag[0]");
1828
0
    }
1829
0
    if (slice->rplIdx[0] != -1)
1830
0
    {
1831
0
      if (numRPL0 > 1)
1832
0
      {
1833
0
        int numBits = 0;
1834
0
        while ((1 << numBits) < numRPL0)
1835
0
        {
1836
0
          numBits++;
1837
0
        }
1838
0
        WRITE_CODE(slice->rplIdx[0], numBits, "ref_pic_list_idx[0]");
1839
0
      }
1840
0
    }
1841
0
    else
1842
0
    {  //write local RPL0
1843
0
      xCodeRefPicList( slice->rpl[0], slice->sps->longTermRefsPresent, slice->sps->bitsForPOC, !slice->sps->weightPred && !slice->sps->weightedBiPred, -1 );
1844
0
    }
1845
    //Deal POC Msb cycle signalling for LTRP
1846
0
    if (slice->rpl[0]->numberOfLongtermPictures)
1847
0
    {
1848
0
      for (int i = 0; i < slice->rpl[0]->numberOfLongtermPictures + slice->rpl[0]->numberOfShorttermPictures; i++)
1849
0
      {
1850
0
        if (slice->rpl[0]->isLongtermRefPic[i])
1851
0
        {
1852
0
          if (slice->rpl[0]->ltrpInSliceHeader)
1853
0
          {
1854
0
            WRITE_CODE(slice->rpl[0]->refPicIdentifier[i], slice->sps->bitsForPOC, "slice_poc_lsb_lt[listIdx][rplsIdx][j]");
1855
0
          }
1856
0
          WRITE_FLAG(slice->rpl[0]->deltaPocMSBPresent[i], "delta_poc_msb_present_flag[i][j]");
1857
0
          if (slice->rpl[0]->deltaPocMSBPresent[i])
1858
0
          {
1859
0
            WRITE_UVLC(slice->rpl[0]->deltaPocMSBCycleLT[i], "delta_poc_msb_cycle_lt[i][j]");
1860
0
          }
1861
0
        }
1862
0
      }
1863
0
    }
1864
1865
    //Write L1 related syntax elements
1866
0
      if (slice->sps->getNumRPL(1) > 1 && slice->pps->rpl1IdxPresent)
1867
0
      {
1868
0
        WRITE_FLAG(slice->rplIdx[1] != -1 ? 1 : 0, "ref_pic_list_sps_flag[1]");
1869
0
      }
1870
0
      else if (slice->sps->getNumRPL(1) == 0)
1871
0
      {
1872
0
        CHECK(slice->rplIdx[1] != -1, "rpl_sps_flag[1] will be infer to 0 and this is not what was expected");
1873
0
      }
1874
0
      else
1875
0
      {
1876
0
        auto rplsSpsFlag0 = slice->rplIdx[0] != -1 ? 1 : 0;
1877
0
        auto rplsSpsFlag1 = slice->rplIdx[1] != -1 ? 1 : 0;
1878
0
        CHECK(rplsSpsFlag1 != rplsSpsFlag0, "rpl_sps_flag[1] will be infer to 0 and this is not what was expected");
1879
0
      }
1880
1881
0
      if (slice->rplIdx[1] != -1)
1882
0
      {
1883
0
        if (slice->sps->getNumRPL(1) > 1 && slice->pps->rpl1IdxPresent)
1884
0
        {
1885
0
          int numBits = 0;
1886
0
          while ((1 << numBits) < slice->sps->getNumRPL(1))
1887
0
          {
1888
0
            numBits++;
1889
0
          }
1890
0
          WRITE_CODE(slice->rplIdx[1], numBits, "ref_pic_list_idx[1]");
1891
0
        }
1892
0
        else if (slice->sps->getNumRPL(1) == 1)
1893
0
        {
1894
0
          CHECK(slice->rplIdx[1] != 0, "RPL1Idx is not signalled but it is not equal to 0");
1895
0
        }
1896
0
        else
1897
0
        {
1898
0
          CHECK(slice->rplIdx[1] != slice->rplIdx[0], "RPL1Idx is not signalled but it is not the same as RPL0Idx");
1899
0
        }
1900
0
      }
1901
0
      else
1902
0
      {  //write local RPL1
1903
0
        xCodeRefPicList( slice->rpl[1], slice->sps->longTermRefsPresent, slice->sps->bitsForPOC, !(slice->sps->weightPred || slice->sps->weightedBiPred), -1 );
1904
0
      }
1905
      //Deal POC Msb cycle signalling for LTRP
1906
0
      if (slice->rpl[1]->numberOfLongtermPictures)
1907
0
      {
1908
0
        for (int i = 0; i < slice->rpl[1]->numberOfLongtermPictures + slice->rpl[1]->numberOfShorttermPictures; i++)
1909
0
        {
1910
0
          if (slice->rpl[1]->isLongtermRefPic[i])
1911
0
          {
1912
0
            if (slice->rpl[1]->ltrpInSliceHeader)
1913
0
            {
1914
0
              WRITE_CODE(slice->rpl[1]->refPicIdentifier[i], slice->sps->bitsForPOC,
1915
0
                         "slice_poc_lsb_lt[listIdx][rplsIdx][j]");
1916
0
            }
1917
0
            WRITE_FLAG(slice->rpl[1]->deltaPocMSBPresent[i], "delta_poc_msb_present_flag[i][j]");
1918
0
            if (slice->rpl[1]->deltaPocMSBPresent[i])
1919
0
            {
1920
0
              WRITE_UVLC(slice->rpl[1]->deltaPocMSBCycleLT[i], "delta_poc_msb_cycle_lt[i][j]");
1921
0
            }
1922
0
          }
1923
0
        }
1924
0
      }
1925
0
    }
1926
1927
    //check if numrefidxes match the defaults. If not, override
1928
1929
0
    if ((!slice->isIntra() && slice->rpl[0]->getNumRefEntries() > 1) ||
1930
0
        (slice->isInterB() && slice->rpl[1]->getNumRefEntries() > 1) )
1931
0
    {
1932
0
      int defaultL0 = std::min<int>(slice->rpl[0]->getNumRefEntries(), slice->pps->numRefIdxL0DefaultActive);
1933
0
      int defaultL1 = slice->isInterB() ? std::min<int>(slice->rpl[1]->getNumRefEntries(), slice->pps->numRefIdxL1DefaultActive) : 0;
1934
0
      bool overrideFlag = ( slice->numRefIdx[ REF_PIC_LIST_0 ] != defaultL0 || ( slice->isInterB() && slice->numRefIdx[ REF_PIC_LIST_1 ] != defaultL1 ) );
1935
0
      WRITE_FLAG( overrideFlag ? 1 : 0, "num_ref_idx_active_override_flag" );
1936
0
      if( overrideFlag )
1937
0
      {
1938
0
        if(slice->rpl[0]->getNumRefEntries() > 1)
1939
0
        {
1940
0
          WRITE_UVLC( slice->numRefIdx[ REF_PIC_LIST_0 ] - 1, "num_ref_idx_l0_active_minus1" );
1941
0
        }
1942
1943
0
        if( slice->isInterB() && slice->rpl[1]->getNumRefEntries() > 1)
1944
0
        {
1945
0
          WRITE_UVLC( slice->numRefIdx[ REF_PIC_LIST_1 ] - 1, "num_ref_idx_l1_active_minus1" );
1946
0
        }
1947
0
      }
1948
0
    }
1949
1950
0
    if( !slice->isIntra() )
1951
0
    {
1952
0
      if( !slice->isIntra() && slice->pps->cabacInitPresent )
1953
0
      {
1954
0
        const SliceType encCABACTableIdx = slice->encCABACTableIdx;
1955
0
        bool encCabacInitFlag = ( slice->sliceType != encCABACTableIdx && encCABACTableIdx != VVENC_I_SLICE ) ? true : false;
1956
0
        WRITE_FLAG( encCabacInitFlag ? 1 : 0, "sh_cabac_init_flag" );
1957
0
      }
1958
0
    }
1959
1960
0
    if( slice->picHeader->enableTMVP  && !slice->pps->rplInfoInPh)
1961
0
    {
1962
0
      if(!slice->pps->rplInfoInPh)
1963
0
      {
1964
0
        if (slice->sliceType == VVENC_B_SLICE)
1965
0
        {
1966
0
          WRITE_FLAG(slice->colFromL0Flag, "sh_collocated_from_l0_flag");
1967
0
        }
1968
0
      }
1969
1970
0
    if( slice->sliceType != VVENC_I_SLICE &&
1971
0
      ( ( slice->colFromL0Flag == 1 && slice->numRefIdx[ REF_PIC_LIST_0 ] > 1 ) ||
1972
0
        ( slice->colFromL0Flag == 0 && slice->numRefIdx[ REF_PIC_LIST_1 ] > 1 ) ) )
1973
0
    {
1974
0
      WRITE_UVLC( slice->colRefIdx, "sh_collocated_ref_idx" );
1975
0
    }
1976
0
  }
1977
1978
0
  if( ( slice->pps->weightPred && slice->sliceType == VVENC_P_SLICE ) || ( slice->pps->weightedBiPred && slice->sliceType == VVENC_B_SLICE ) )
1979
0
  {
1980
0
    if( !slice->pps->wpInfoInPh )
1981
0
    {
1982
0
      xCodePredWeightTable( slice );
1983
0
    }
1984
0
  }
1985
1986
0
  if (!slice->pps->qpDeltaInfoInPh)
1987
0
  {
1988
0
    WRITE_SVLC(slice->sliceQp - (slice->pps->picInitQPMinus26 + 26), "slice_qp_delta");
1989
0
  }
1990
0
  if (slice->pps->sliceChromaQpFlag)
1991
0
  {
1992
0
    if (numberValidComponents > COMP_Cb)
1993
0
    {
1994
0
      WRITE_SVLC( slice->sliceChromaQpDelta[COMP_Cb], "sh_cb_qp_offset" );
1995
0
    }
1996
0
    if (numberValidComponents > COMP_Cr)
1997
0
    {
1998
0
      WRITE_SVLC( slice->sliceChromaQpDelta[COMP_Cr], "sh_cr_qp_offset" );
1999
0
      if (slice->sps->jointCbCr)
2000
0
      {
2001
0
        WRITE_SVLC( slice->sliceChromaQpDelta[COMP_JOINT_CbCr], "sh_joint_cbcr_qp_offset");
2002
0
      }
2003
0
    }
2004
0
    CHECK(numberValidComponents < COMP_Cr+1, "Too many valid components");
2005
0
  }
2006
2007
0
  if (slice->pps->chromaQpOffsetListLen>0)
2008
0
  {
2009
0
    WRITE_FLAG(slice->chromaQpAdjEnabled, "sh_cu_chroma_qp_offset_enabled_flag");
2010
0
  }
2011
2012
0
  if( slice->sps->saoEnabled && !slice->pps->saoInfoInPh )
2013
0
  {
2014
0
    WRITE_FLAG( slice->saoEnabled[CH_L], "sh_sao_luma_flag" );
2015
0
    if( chromaEnabled )
2016
0
    {
2017
0
      WRITE_FLAG( slice->saoEnabled[CH_C], "sh_sao_chroma_flag" );
2018
0
    }
2019
0
  }
2020
2021
2022
0
  if (slice->pps->deblockingFilterControlPresent && !slice->pps->dbfInfoInPh)
2023
0
  {
2024
0
    if (slice->pps->deblockingFilterOverrideEnabled )
2025
0
    {
2026
0
      WRITE_FLAG(slice->deblockingFilterOverride, "sh_deblocking_params_present_flag");
2027
0
    }
2028
0
    if (slice->deblockingFilterOverride)
2029
0
    {
2030
0
      if (!slice->pps->deblockingFilterDisabled)
2031
0
      {
2032
0
       WRITE_FLAG(slice->deblockingFilterDisable, "sh_deblocking_filter_disabled_flag");
2033
0
      }
2034
0
      if(!slice->deblockingFilterDisable)
2035
0
      {
2036
0
        WRITE_SVLC (slice->deblockingFilterBetaOffsetDiv2[COMP_Y],   "slice_beta_offset_div2");
2037
0
        WRITE_SVLC (slice->deblockingFilterTcOffsetDiv2[COMP_Y],     "slice_tc_offset_div2");
2038
0
        if( slice->pps->usePPSChromaTool )
2039
0
        {
2040
0
          WRITE_SVLC (slice->deblockingFilterBetaOffsetDiv2[COMP_Cb], "slice_cb_beta_offset_div2");
2041
0
          WRITE_SVLC (slice->deblockingFilterTcOffsetDiv2[COMP_Cb],   "slice_cb_tc_offset_div2");
2042
0
          WRITE_SVLC (slice->deblockingFilterBetaOffsetDiv2[COMP_Cr], "slice_cr_beta_offset_div2");
2043
0
          WRITE_SVLC (slice->deblockingFilterTcOffsetDiv2[COMP_Cr],   "slice_cr_tc_offset_div2");
2044
0
        }
2045
0
      }
2046
0
    }
2047
0
  }
2048
2049
  // dependent quantization
2050
0
  if( slice->sps->depQuantEnabled )
2051
0
  {
2052
0
    WRITE_FLAG(slice->depQuantEnabled, "sh_dep_quant_used_flag");
2053
0
  }
2054
2055
  // sign data hiding
2056
0
  if( slice->sps->signDataHidingEnabled && !slice->depQuantEnabled )
2057
0
  {
2058
0
    WRITE_FLAG(slice->signDataHidingEnabled, "sh_sign_data_hiding_used_flag" );
2059
0
  }
2060
0
  if( slice->sps->transformSkip && !slice->depQuantEnabled && !slice->signDataHidingEnabled )
2061
0
  {
2062
0
    WRITE_FLAG(slice->tsResidualCodingDisabled, "sh_ts_residual_coding_disabled_flag");
2063
0
  }
2064
2065
0
  if(slice->pps->sliceHeaderExtensionPresent)
2066
0
  {
2067
0
    WRITE_UVLC(0,"slice_header_extension_length");
2068
0
  }
2069
0
}
2070
2071
void  HLSWriter::codeConstraintInfo  ( const ConstraintInfo* cinfo )
2072
0
{
2073
0
  WRITE_FLAG(cinfo->gciPresent,                         "gci_present_flag");
2074
0
  if (cinfo->gciPresent)
2075
0
  {
2076
0
    WRITE_FLAG(cinfo->intraOnlyConstraintFlag,              "gci_intra_only_constraint_flag");
2077
0
    WRITE_FLAG(cinfo->allLayersIndependentConstraintFlag,   "gci_all_layers_independent_constraint_flag");
2078
0
    WRITE_FLAG(cinfo->onePictureOnlyConstraintFlag,         "gci_one_au_only_constraint_flag");
2079
2080
    /* picture format */
2081
0
    WRITE_CODE(16 - cinfo->maxBitDepthConstraintIdc, 4,     "gci_sixteen_minus_max_bitdepth_constraint_idc");
2082
0
    WRITE_CODE(3 - cinfo->maxChromaFormatConstraintIdc, 2,  "gci_three_minus_max_chroma_format_constraint_idc");
2083
2084
    /* NAL unit type related */
2085
0
    WRITE_FLAG(cinfo->noMixedNaluTypesInPicConstraintFlag,  "gci_no_mixed_nalu_types_in_pic_constraint_flag");
2086
0
    WRITE_FLAG(cinfo->noTrailConstraintFlag,                "gci_no_trail_constraint_flag");
2087
0
    WRITE_FLAG(cinfo->noStsaConstraintFlag,                 "gci_no_stsa_constraint_flag");
2088
0
    WRITE_FLAG(cinfo->noRaslConstraintFlag,                 "gci_no_rasl_constraint_flag");
2089
0
    WRITE_FLAG(cinfo->noRadlConstraintFlag,                 "gci_no_radl_constraint_flag");
2090
0
    WRITE_FLAG(cinfo->noIdrConstraintFlag,                  "gci_no_idr_constraint_flag");
2091
0
    WRITE_FLAG(cinfo->noCraConstraintFlag,                  "gci_no_cra_constraint_flag");
2092
0
    WRITE_FLAG(cinfo->noGdrConstraintFlag,                  "gci_no_gdr_constraint_flag");
2093
0
    WRITE_FLAG(cinfo->noApsConstraintFlag,                  "gci_no_aps_constraint_flag");
2094
0
    WRITE_FLAG(cinfo->noIdrRplConstraintFlag,               "gci_no_idr_rpl_constraint_flag");
2095
2096
    /* tile, slice, subpicture partitioning */
2097
0
    WRITE_FLAG(cinfo->oneTilePerPicConstraintFlag,          "gci_one_tile_per_pic_constraint_flag");
2098
0
    WRITE_FLAG(cinfo->picHeaderInSliceHeaderConstraintFlag, "gci_pic_header_in_slice_header_constraint_flag");
2099
0
    WRITE_FLAG(cinfo->oneSlicePerPicConstraintFlag,         "gci_one_slice_per_pic_constraint_flag");
2100
0
    WRITE_FLAG(cinfo->noRectSliceConstraintFlag,            "gci_no_rectangular_slice_constraint_flag");
2101
0
    WRITE_FLAG(cinfo->oneSlicePerSubpicConstraintFlag,      "gci_one_slice_per_subpic_constraint_flag");
2102
0
    WRITE_FLAG(cinfo->noSubpicInfoConstraintFlag,           "gci_no_subpic_info_constraint_flag");
2103
2104
2105
    /* CTU and block partitioning */
2106
0
    WRITE_CODE(3 - (cinfo->maxLog2CtuSizeConstraintIdc - 5), 2, "gci_three_minus_max_log2_ctu_size_constraint_idc");
2107
0
    WRITE_FLAG(cinfo->noPartitionConstraintsOverrideConstraintFlag, "gci_no_partition_constraints_override_constraint_flag");
2108
0
    WRITE_FLAG(cinfo->noMttConstraintFlag,                  "gci_no_mtt_constraint_flag");
2109
0
    WRITE_FLAG(cinfo->noQtbttDualTreeIntraConstraintFlag,   "gci_no_qtbtt_dual_tree_intra_constraint_flag");
2110
2111
    /* intra */
2112
0
    WRITE_FLAG(cinfo->noPaletteConstraintFlag,              "gci_no_palette_constraint_flag");
2113
0
    WRITE_FLAG(cinfo->noIbcConstraintFlag,                  "gci_no_ibc_constraint_flag");
2114
0
    WRITE_FLAG(cinfo->noIspConstraintFlag,                  "gci_no_isp_constraint_flag");
2115
0
    WRITE_FLAG(cinfo->noMrlConstraintFlag,                  "gci_no_mrl_constraint_flag");
2116
0
    WRITE_FLAG(cinfo->noMipConstraintFlag,                  "gci_no_mip_constraint_flag");
2117
0
    WRITE_FLAG(cinfo->noCclmConstraintFlag,                 "gci_no_cclm_constraint_flag");
2118
2119
    /* inter */
2120
0
    WRITE_FLAG(cinfo->noRprConstraintFlag,                  "gci_no_ref_pic_resampling_constraint_flag");
2121
0
    WRITE_FLAG(cinfo->noResChangeInClvsConstraintFlag,      "gci_no_res_change_in_clvs_constraint_flag");
2122
0
    WRITE_FLAG(cinfo->noWeightedPredictionConstraintFlag,   "gci_no_weighted_prediction_constraint_flag");
2123
0
    WRITE_FLAG(cinfo->noRefWraparoundConstraintFlag,        "gci_no_ref_wraparound_constraint_flag");
2124
0
    WRITE_FLAG(cinfo->noTemporalMvpConstraintFlag,          "gci_no_temporal_mvp_constraint_flag");
2125
0
    WRITE_FLAG(cinfo->noSbtmvpConstraintFlag,               "gci_no_sbtmvp_constraint_flag");
2126
0
    WRITE_FLAG(cinfo->noAmvrConstraintFlag,                 "gci_no_amvr_constraint_flag");
2127
0
    WRITE_FLAG(cinfo->noBdofConstraintFlag,                 "gci_no_bdof_constraint_flag");
2128
0
    WRITE_FLAG(cinfo->noSmvdConstraintFlag,                 "gci_no_smvd_constraint_flag");
2129
0
    WRITE_FLAG(cinfo->noDmvrConstraintFlag,                 "gci_no_dmvr_constraint_flag");
2130
0
    WRITE_FLAG(cinfo->noMmvdConstraintFlag,                 "gci_no_mmvd_constraint_flag");
2131
0
    WRITE_FLAG(cinfo->noAffineMotionConstraintFlag,         "gci_no_affine_motion_constraint_flag");
2132
0
    WRITE_FLAG(cinfo->noProfConstraintFlag,                 "gci_no_prof_constraint_flag");
2133
0
    WRITE_FLAG(cinfo->noBcwConstraintFlag,                  "gci_no_bcw_constraint_flag");
2134
0
    WRITE_FLAG(cinfo->noCiipConstraintFlag,                 "gci_no_ciip_constraint_flag");
2135
0
    WRITE_FLAG(cinfo->noGeoConstraintFlag,                  "gci_no_gpm_constraint_flag");
2136
2137
    /* transform, quantization, residual */
2138
0
    WRITE_FLAG(cinfo->noLumaTransformSize64ConstraintFlag,  "gci_no_luma_transform_size_64_constraint_flag");
2139
0
    WRITE_FLAG(cinfo->noTransformSkipConstraintFlag,        "gci_no_transform_skip_constraint_flag");
2140
0
    WRITE_FLAG(cinfo->noBDPCMConstraintFlag,                "gci_no_bdpcm_constraint_flag");
2141
0
    WRITE_FLAG(cinfo->noMtsConstraintFlag,                  "gci_no_mts_constraint_flag");
2142
0
    WRITE_FLAG(cinfo->noLfnstConstraintFlag,                "gci_no_lfnst_constraint_flag");
2143
0
    WRITE_FLAG(cinfo->noJointCbCrConstraintFlag,            "gci_no_joint_cbcr_constraint_flag");
2144
0
    WRITE_FLAG(cinfo->noSbtConstraintFlag,                  "gci_no_sbt_constraint_flag");
2145
0
    WRITE_FLAG(cinfo->noActConstraintFlag,                  "gci_no_act_constraint_flag");
2146
0
    WRITE_FLAG(cinfo->noExplicitScaleListConstraintFlag,    "gci_no_explicit_scaling_list_constraint_flag");
2147
0
    WRITE_FLAG(cinfo->noDepQuantConstraintFlag,             "gci_no_dep_quant_constraint_flag");
2148
0
    WRITE_FLAG(cinfo->noSignDataHidingConstraintFlag,       "gci_no_sign_data_hiding_constraint_flag");
2149
0
    WRITE_FLAG(cinfo->noQpDeltaConstraintFlag,              "gci_no_qp_delta_constraint_flag");
2150
0
    WRITE_FLAG(cinfo->noChromaQpOffsetConstraintFlag,       "gci_no_chroma_qp_offset_constraint_flag");
2151
2152
    /* loop filter */
2153
0
    WRITE_FLAG(cinfo->noSaoConstraintFlag,                  "gci_no_sao_constraint_flag");
2154
0
    WRITE_FLAG(cinfo->noAlfConstraintFlag,                  "gci_no_alf_constraint_flag");
2155
0
    WRITE_FLAG(cinfo->noCCAlfConstraintFlag,                "gci_no_ccalf_constraint_flag");
2156
0
    WRITE_FLAG(cinfo->noLmcsConstraintFlag,                 "gci_no_lmcs_constraint_flag");
2157
0
    WRITE_FLAG(cinfo->noLadfConstraintFlag,                 "gci_no_ladf_constraint_flag");
2158
0
    WRITE_FLAG(cinfo->noVirtualBoundaryConstraintFlag,      "gci_no_virtual_boundaries_constraint_flag");
2159
2160
    //The value of gci_num_reserved_bits shall be equal to 0 in bitstreams conforming to this version of this Specification.
2161
    //Other values of gci_num_reserved_bits are reserved for future use by ITU-T | ISO/IEC.
2162
0
    WRITE_CODE(0, 8,                                        "gci_num_reserved_bits");
2163
0
  }
2164
2165
0
  while (!isByteAligned())
2166
0
  {
2167
0
    WRITE_FLAG(0, "gci_alignment_zero_bit");
2168
0
  }
2169
0
}
2170
2171
2172
void  HLSWriter::codeProfileTierLevel    ( const ProfileTierLevel* ptl, bool profileTierPresent, int maxNumSubLayersMinus1 )
2173
0
{
2174
0
  if(profileTierPresent)
2175
0
  {
2176
0
    WRITE_CODE( (uint32_t)ptl->profileIdc, 7 ,        "general_profile_idc"                     );
2177
0
    WRITE_FLAG( ptl->tierFlag==vvencTier::VVENC_TIER_HIGH,           "general_tier_flag"                       );
2178
0
  }
2179
2180
0
  WRITE_CODE( (uint32_t)ptl->levelIdc, 8 ,            "general_level_idc");
2181
0
  WRITE_FLAG( ptl->frameOnlyConstraintFlag,           "ptl_frame_only_constraint_flag" );
2182
0
  WRITE_FLAG( ptl->multiLayerEnabledFlag,             "ptl_multilayer_enabled_flag"    );
2183
0
  if(profileTierPresent)
2184
0
  {
2185
0
    codeConstraintInfo( &ptl->constraintInfo );
2186
0
  }
2187
2188
0
  for (int i = maxNumSubLayersMinus1 - 1; i >= 0; i--)
2189
0
  {
2190
0
    WRITE_FLAG( ptl->subLayerLevelPresent[i],         "sub_layer_level_present_flag[i]" );
2191
0
  }
2192
2193
0
  while (!isByteAligned())
2194
0
  {
2195
0
    WRITE_FLAG(0,                                     "ptl_reserved_zero_bit");
2196
0
  }
2197
2198
0
  for (int i = maxNumSubLayersMinus1 - 1; i >= 0; i--)
2199
0
  {
2200
0
    if( ptl->subLayerLevelPresent[i] )
2201
0
    {
2202
0
      WRITE_CODE( (uint32_t)ptl->subLayerLevelIdc[i], 8, "sub_layer_level_idc[i]" );
2203
0
    }
2204
0
  }
2205
2206
0
  if (profileTierPresent)
2207
0
  {
2208
0
    WRITE_CODE(ptl->numSubProfile, 8, "ptl_num_sub_profiles");
2209
0
    for (int i = 0; i < ptl->numSubProfile; i++)
2210
0
    {
2211
0
      WRITE_CODE(ptl->subProfileIdc[i], 32, "general_sub_profile_idc[i]");
2212
0
    }
2213
0
  }
2214
0
}
2215
2216
2217
/**
2218
* Write tiles and wavefront substreams sizes for the slice header (entry points).
2219
*
2220
* \param pSlice Slice structure that contains the substream size information.
2221
*/
2222
void  HLSWriter::codeTilesWPPEntryPoint( Slice* pSlice )
2223
0
{
2224
0
  int numEntryPoints = pSlice->getNumEntryPoints( *pSlice->sps, *pSlice->pps );
2225
0
  if( numEntryPoints == 0 )
2226
0
  {
2227
0
    return;
2228
0
  }
2229
2230
0
  uint32_t maxOffset = 0;
2231
0
  for(int idx=0; idx<pSlice->getNumberOfSubstreamSizes(); idx++)
2232
0
  {
2233
0
    uint32_t offset=pSlice->getSubstreamSize(idx);
2234
0
    if ( offset > maxOffset )
2235
0
    {
2236
0
      maxOffset = offset;
2237
0
    }
2238
0
  }
2239
2240
  // Determine number of bits "offsetLenMinus1+1" required for entry point information
2241
0
  uint32_t offsetLenMinus1 = 0;
2242
0
  while (maxOffset >= (1u << (offsetLenMinus1 + 1)))
2243
0
  {
2244
0
    offsetLenMinus1++;
2245
0
    CHECK(offsetLenMinus1 + 1 >= 32, "Invalid offset length minus 1");
2246
0
  }
2247
2248
0
  if (pSlice->getNumberOfSubstreamSizes()>0)
2249
0
  {
2250
0
    WRITE_UVLC(offsetLenMinus1, "sh_entry_offset_len_minus1");
2251
2252
0
    for (uint32_t idx=0; idx<pSlice->getNumberOfSubstreamSizes(); idx++)
2253
0
    {
2254
0
      WRITE_CODE(pSlice->getSubstreamSize(idx)-1, offsetLenMinus1+1, "sh_entry_point_offset_minus1");
2255
0
    }
2256
0
  }
2257
0
}
2258
2259
2260
// ====================================================================================================================
2261
// Protected member functions
2262
// ====================================================================================================================
2263
2264
//! Code weighted prediction tables
2265
void HLSWriter::xCodePredWeightTable( const Slice* slice )
2266
0
{
2267
0
  WPScalingParam      *wp;
2268
0
  const ChromaFormat  format                = slice->sps->chromaFormatIdc;
2269
0
  const uint32_t      numberValidComponents = getNumberValidComponents(format);
2270
0
  const bool          bChroma               = isChromaEnabled(format);
2271
0
  const int           iNbRef                = (slice->sliceType == VVENC_B_SLICE ) ? (2) : (1);
2272
0
  bool                bDenomCoded           = false;
2273
0
  uint32_t            uiTotalSignalledWeightFlags = 0;
2274
2275
0
  if ( (slice->sliceType==VVENC_P_SLICE && slice->pps->weightPred) || (slice->sliceType==VVENC_B_SLICE && slice->pps->weightedBiPred) )
2276
0
  {
2277
0
    for ( int iNumRef=0 ; iNumRef<iNbRef ; iNumRef++ ) // loop over l0 and l1 syntax elements
2278
0
    {
2279
0
      RefPicList  refPicList = ( iNumRef ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
2280
2281
      // NOTE: wp[].log2WeightDenom and wp[].presentFlag are actually per-channel-type settings.
2282
2283
0
      for ( int iRefIdx=0 ; iRefIdx<slice->numRefIdx[ refPicList ] ; iRefIdx++ )
2284
0
      {
2285
0
        slice->getWpScaling(refPicList, iRefIdx, wp);
2286
0
        if ( !bDenomCoded )
2287
0
        {
2288
0
          int iDeltaDenom;
2289
0
          WRITE_UVLC( wp[COMP_Y].log2WeightDenom, "luma_log2_weight_denom" );
2290
2291
0
          if( bChroma )
2292
0
          {
2293
0
            CHECK( wp[COMP_Cb].log2WeightDenom != wp[COMP_Cr].log2WeightDenom, "Chroma blocks of different size not supported" );
2294
0
            iDeltaDenom = (wp[COMP_Cb].log2WeightDenom - wp[COMP_Y].log2WeightDenom);
2295
0
            WRITE_SVLC( iDeltaDenom, "delta_chroma_log2_weight_denom" );
2296
0
          }
2297
0
          bDenomCoded = true;
2298
0
        }
2299
0
        WRITE_FLAG( wp[COMP_Y].presentFlag, iNumRef==0?"luma_weight_l0_flag[i]":"luma_weight_l1_flag[i]" );
2300
0
        uiTotalSignalledWeightFlags += wp[COMP_Y].presentFlag;
2301
0
      }
2302
0
      if (bChroma)
2303
0
      {
2304
0
        for ( int iRefIdx=0 ; iRefIdx<slice->numRefIdx[ refPicList ] ; iRefIdx++ )
2305
0
        {
2306
0
          slice->getWpScaling( refPicList, iRefIdx, wp );
2307
0
          CHECK( wp[COMP_Cb].presentFlag != wp[COMP_Cr].presentFlag, "Inconsistent settings for chroma channels" );
2308
0
          WRITE_FLAG( wp[COMP_Cb].presentFlag, iNumRef==0?"chroma_weight_l0_flag[i]":"chroma_weight_l1_flag[i]" );
2309
0
          uiTotalSignalledWeightFlags += 2*wp[COMP_Cb].presentFlag;
2310
0
        }
2311
0
      }
2312
2313
0
      for ( int iRefIdx=0 ; iRefIdx<slice->numRefIdx[ refPicList ] ; iRefIdx++ )
2314
0
      {
2315
0
        slice->getWpScaling(refPicList, iRefIdx, wp);
2316
0
        if ( wp[COMP_Y].presentFlag )
2317
0
        {
2318
0
          int iDeltaWeight = (wp[COMP_Y].iWeight - (1<<wp[COMP_Y].log2WeightDenom));
2319
0
          WRITE_SVLC( iDeltaWeight, iNumRef==0?"delta_luma_weight_l0[i]":"delta_luma_weight_l1[i]" );
2320
0
          WRITE_SVLC( wp[COMP_Y].iOffset, iNumRef==0?"luma_offset_l0[i]":"luma_offset_l1[i]" );
2321
0
        }
2322
2323
0
        if ( bChroma )
2324
0
        {
2325
0
          if ( wp[COMP_Cb].presentFlag )
2326
0
          {
2327
0
            for ( int j = COMP_Cb ; j < numberValidComponents ; j++ )
2328
0
            {
2329
0
              CHECK(wp[COMP_Cb].log2WeightDenom != wp[COMP_Cr].log2WeightDenom, "Chroma blocks of different size not supported");
2330
0
              int iDeltaWeight = (wp[j].iWeight - (1<<wp[COMP_Cb].log2WeightDenom));
2331
0
              WRITE_SVLC( iDeltaWeight, iNumRef==0?"delta_chroma_weight_l0[i]":"delta_chroma_weight_l1[i]" );
2332
2333
0
              int range=128;
2334
0
              int pred = ( range - ( ( range*wp[j].iWeight)>>(wp[j].log2WeightDenom) ) );
2335
0
              int iDeltaChroma = (wp[j].iOffset - pred);
2336
0
              WRITE_SVLC( iDeltaChroma, iNumRef==0?"delta_chroma_offset_l0[i]":"delta_chroma_offset_l1[i]" );
2337
0
            }
2338
0
          }
2339
0
        }
2340
0
      }
2341
0
    }
2342
0
    CHECK(uiTotalSignalledWeightFlags>24, "Too many signalled weight flags");
2343
0
  }
2344
0
}
2345
2346
2347
void HLSWriter::xCodePredWeightTable( const PicHeader *picHeader, const PPS *pps, const SPS *sps )
2348
0
{
2349
0
  WPScalingParam  *wp;
2350
0
  const ChromaFormat  format                = sps->chromaFormatIdc;
2351
0
  const uint32_t      numberValidComponents = getNumberValidComponents(format);
2352
0
  const bool          bChroma               = isChromaEnabled(format);
2353
0
  bool                bDenomCoded           = false;
2354
0
  uint32_t            uiTotalSignalledWeightFlags = 0;
2355
0
  uint32_t            numLxWeights                = picHeader->numL0Weights;
2356
0
  bool                moreSyntaxToBeParsed        = true;
2357
0
  for (int iNumRef = 0; iNumRef < NUM_REF_PIC_LIST_01 && moreSyntaxToBeParsed; iNumRef++)   // loop over l0 and l1 syntax elements
2358
0
  {
2359
0
    RefPicList  refPicList = ( iNumRef ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
2360
2361
    // NOTE: wp[].log2WeightDenom and wp[].presentFlag are actually per-channel-type settings.
2362
2363
0
    for ( int iRefIdx=0 ; iRefIdx<numLxWeights ; iRefIdx++ )
2364
0
    {
2365
0
      picHeader->getWpScaling(refPicList, iRefIdx, wp);
2366
0
      if ( !bDenomCoded )
2367
0
      {
2368
0
        int iDeltaDenom;
2369
0
        WRITE_UVLC( wp[COMP_Y].log2WeightDenom, "luma_log2_weight_denom" );
2370
2371
0
        if( bChroma )
2372
0
        {
2373
0
          CHECK( wp[COMP_Cb].log2WeightDenom != wp[COMP_Cr].log2WeightDenom, "Chroma blocks of different size not supported" );
2374
0
          iDeltaDenom = (wp[COMP_Cb].log2WeightDenom - wp[COMP_Y].log2WeightDenom);
2375
0
          WRITE_SVLC( iDeltaDenom, "delta_chroma_log2_weight_denom" );
2376
0
        }
2377
0
        bDenomCoded = true;
2378
0
      }
2379
0
      WRITE_FLAG( wp[COMP_Y].presentFlag, iNumRef==0?"luma_weight_l0_flag[i]":"luma_weight_l1_flag[i]" );
2380
0
      uiTotalSignalledWeightFlags += wp[COMP_Y].presentFlag;
2381
0
    }
2382
0
    if (bChroma)
2383
0
    {
2384
0
      for ( int iRefIdx=0 ; iRefIdx<numLxWeights; iRefIdx++ )
2385
0
      {
2386
0
        picHeader->getWpScaling( refPicList, iRefIdx, wp );
2387
0
        CHECK( wp[COMP_Cb].presentFlag != wp[COMP_Cr].presentFlag, "Inconsistent settings for chroma channels" );
2388
0
        WRITE_FLAG( wp[COMP_Cb].presentFlag, iNumRef==0?"chroma_weight_l0_flag[i]":"chroma_weight_l1_flag[i]" );
2389
0
        uiTotalSignalledWeightFlags += 2*wp[COMP_Cb].presentFlag;
2390
0
      }
2391
0
    }
2392
2393
0
    for ( int iRefIdx=0 ; iRefIdx<numLxWeights; iRefIdx++ )
2394
0
    {
2395
0
      picHeader->getWpScaling(refPicList, iRefIdx, wp);
2396
0
      if ( wp[COMP_Y].presentFlag )
2397
0
      {
2398
0
        int iDeltaWeight = (wp[COMP_Y].iWeight - (1<<wp[COMP_Y].log2WeightDenom));
2399
0
        WRITE_SVLC( iDeltaWeight, iNumRef==0?"delta_luma_weight_l0[i]":"delta_luma_weight_l1[i]" );
2400
0
        WRITE_SVLC( wp[COMP_Y].iOffset, iNumRef==0?"luma_offset_l0[i]":"luma_offset_l1[i]" );
2401
0
      }
2402
2403
0
      if ( bChroma )
2404
0
      {
2405
0
        if ( wp[COMP_Cb].presentFlag )
2406
0
        {
2407
0
          for ( int j = COMP_Cb ; j < numberValidComponents ; j++ )
2408
0
          {
2409
0
            CHECK(wp[COMP_Cb].log2WeightDenom != wp[COMP_Cr].log2WeightDenom, "Chroma blocks of different size not supported");
2410
0
            int iDeltaWeight = (wp[j].iWeight - (1<<wp[COMP_Cb].log2WeightDenom));
2411
0
            WRITE_SVLC( iDeltaWeight, iNumRef==0?"delta_chroma_weight_l0[i]":"delta_chroma_weight_l1[i]" );
2412
2413
0
            int range=128;
2414
0
            int pred = ( range - ( ( range*wp[j].iWeight)>>(wp[j].log2WeightDenom) ) );
2415
0
            int iDeltaChroma = (wp[j].iOffset - pred);
2416
0
            WRITE_SVLC( iDeltaChroma, iNumRef==0?"delta_chroma_offset_l0[i]":"delta_chroma_offset_l1[i]" );
2417
0
          }
2418
0
        }
2419
0
      }
2420
0
    }
2421
0
    if (iNumRef == 0 )
2422
0
    {
2423
0
      numLxWeights = picHeader->numL1Weights;
2424
0
      if (pps->weightedBiPred == 0) 
2425
0
      {
2426
0
        numLxWeights = 0;
2427
0
      }
2428
0
      else if (picHeader->pRPL[1]->getNumRefEntries() > 0)
2429
0
      {
2430
0
        WRITE_UVLC(numLxWeights, "num_l1_weights");
2431
0
      }
2432
0
      moreSyntaxToBeParsed = (numLxWeights == 0) ? false : true;
2433
0
    }
2434
0
  }
2435
0
  CHECK(uiTotalSignalledWeightFlags>24, "Too many signalled weight flags");
2436
0
}
2437
2438
void HLSWriter::alfFilter( const AlfParam& alfParam, const bool isChroma, const int altIdx )
2439
0
{
2440
0
  AlfFilterShape alfShape(isChroma ? 5 : 7);
2441
0
  const short* coeff = isChroma ? alfParam.chromaCoeff[altIdx] : alfParam.lumaCoeff;
2442
0
  const short* clipp = isChroma ? alfParam.chromaClipp[altIdx] : alfParam.lumaClipp;
2443
0
  const int numFilters = isChroma ? 1 : alfParam.numLumaFilters;
2444
2445
  // vlc for all
2446
2447
  // Filter coefficients
2448
0
  for( int ind = 0; ind < numFilters; ++ind )
2449
0
  {
2450
0
    for( int i = 0; i < alfShape.numCoeff - 1; i++ )
2451
0
    {
2452
0
      WRITE_UVLC( abs(coeff[ ind* MAX_NUM_ALF_LUMA_COEFF + i ]), isChroma ? "alf_chroma_coeff_abs" : "alf_luma_coeff_abs" ); //alf_coeff_chroma[i], alf_coeff_luma_delta[i][j]
2453
0
      if( abs( coeff[ ind* MAX_NUM_ALF_LUMA_COEFF + i ] ) != 0 )
2454
0
      {
2455
0
        WRITE_FLAG( ( coeff[ ind* MAX_NUM_ALF_LUMA_COEFF + i ] < 0 ) ? 1 : 0, isChroma ? "alf_chroma_coeff_sign" : "alf_luma_coeff_sign" );
2456
0
      }
2457
0
    }
2458
0
  }
2459
2460
  // Clipping values coding
2461
0
  if( alfParam.nonLinearFlag[isChroma] )
2462
0
  {
2463
0
    for (int ind = 0; ind < numFilters; ++ind)
2464
0
    {
2465
0
      for (int i = 0; i < alfShape.numCoeff - 1; i++)
2466
0
      {
2467
0
        WRITE_CODE(clipp[ind* MAX_NUM_ALF_LUMA_COEFF + i], 2, isChroma ? "alf_chroma_clip_idx" : "alf_luma_clip_idx");
2468
0
      }
2469
0
    }
2470
0
  }
2471
0
}
2472
2473
} // namespace vvenc
2474
2475
//! \}
2476