Coverage Report

Created: 2025-07-23 08:18

/src/x265/source/common/slice.cpp
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
 * Copyright (C) 2013-2020 MulticoreWare, Inc
3
 *
4
 * Authors: Steve Borho <steve@borho.org>
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
19
 *
20
 * This program is also available under a commercial proprietary license.
21
 * For more information, contact us at license @ x265.com.
22
 *****************************************************************************/
23
24
#include "common.h"
25
#include "frame.h"
26
#include "piclist.h"
27
#include "picyuv.h"
28
#include "slice.h"
29
30
using namespace X265_NS;
31
32
#if ENABLE_MULTIVIEW
33
void Slice::createInterLayerReferencePictureSet(PicList& picList, PicList& refPicSetInterLayer0, PicList& refPicSetInterLayer1)
34
{
35
36
    for (int i = 0; i < 1; i++)
37
    {
38
        Frame* refPic = picList.getPOC(m_poc, 0);
39
        int viewIdCur = 0;
40
        int viewIdZero = 1;
41
        int viewIdRef = 1;
42
43
        if ((viewIdCur <= viewIdZero && viewIdCur <= viewIdRef) || (viewIdCur >= viewIdZero && viewIdCur >= viewIdRef))
44
        {
45
            refPicSetInterLayer0.pushBackSubDPB(*refPic);
46
        }
47
        else
48
        {
49
            refPicSetInterLayer1.pushBackSubDPB(*refPic);
50
        }
51
    }
52
}
53
#endif
54
55
#if ENABLE_MULTIVIEW
56
void Slice::setRefPicList(PicList& picList, int sLayerId, PicList& refPicSetInterLayer0, PicList& refPicSetInterLayer1)
57
#else
58
void Slice::setRefPicList(PicList& picList, int sLayerId)
59
#endif
60
0
{
61
0
    if (m_sliceType == I_SLICE)
62
0
    {
63
0
        memset(m_refFrameList, 0, sizeof(m_refFrameList));
64
0
        memset(m_refReconPicList, 0, sizeof(m_refReconPicList));
65
0
        memset(m_refPOCList, 0, sizeof(m_refPOCList));
66
0
        m_numRefIdx[1] = m_numRefIdx[0] = 0;
67
68
#if ENABLE_SCC_EXT
69
        bool checkNumPocTotalCurr = m_param->bEnableSCC ? false : true;
70
        if (!checkNumPocTotalCurr)
71
        {
72
            if (m_rps.numberOfPictures == 0)
73
            {
74
                Frame* prevPic = picList.getPOC(X265_MAX(0, m_poc - 1));
75
                if (prevPic->m_poc != X265_MAX(0, m_poc - 1))
76
                {
77
                    prevPic = picList.getPOC(m_poc);
78
                }
79
                m_lastEncPic = prevPic;
80
            }
81
            return;
82
        }
83
#endif
84
85
0
        return;
86
0
    }
87
88
#if ENABLE_SCC_EXT || ENABLE_MULTIVIEW || ENABLE_ALPHA
89
    /*Reset the number of references for I-slice marked as P-slice*/
90
    if ((m_param->bEnableSCC || sLayerId) && m_sliceType != m_origSliceType)
91
    {
92
        memset(m_refFrameList, 0, sizeof(m_refFrameList));
93
        memset(m_refReconPicList, 0, sizeof(m_refReconPicList));
94
        memset(m_refPOCList, 0, sizeof(m_refPOCList));
95
        m_numRefIdx[0] = 1;
96
    }
97
#endif
98
99
#if ENABLE_SCC_EXT
100
    bool checkNumPocTotalCurr = m_param->bEnableSCC ? false : true;
101
    if (!checkNumPocTotalCurr && m_rps.numberOfPictures == 0)
102
    {
103
        Frame* prevPic = picList.getPOC(X265_MAX(0, m_poc - 1));
104
        if (prevPic && prevPic->m_poc != X265_MAX(0, m_poc - 1))
105
        {
106
            prevPic = picList.getPOC(m_poc);
107
108
        }
109
        m_lastEncPic = prevPic;
110
    }
111
#endif
112
113
0
    Frame* refPic = NULL;
114
0
    Frame* refPicSetStCurr0[MAX_NUM_REF];
115
0
    Frame* refPicSetStCurr1[MAX_NUM_REF];
116
0
    Frame* refPicSetLtCurr[MAX_NUM_REF];
117
0
    int numPocStCurr0 = 0;
118
0
    int numPocStCurr1 = 0;
119
0
    int numPocLtCurr = 0;
120
0
    int i;
121
122
0
    for (i = 0; i < m_rps.numberOfNegativePictures; i++)
123
0
    {
124
0
        if (m_rps.bUsed[i] && m_origSliceType != I_SLICE)
125
0
        {
126
0
            refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i], m_rps.deltaPOC[i] ? sLayerId : 0);
127
0
            refPicSetStCurr0[numPocStCurr0] = refPic;
128
0
            numPocStCurr0++;
129
0
        }
130
0
    }
131
132
0
    for (; i < m_rps.numberOfNegativePictures + m_rps.numberOfPositivePictures; i++)
133
0
    {
134
0
        if (m_rps.bUsed[i] && m_origSliceType != I_SLICE)
135
0
        {
136
0
            refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i], m_rps.deltaPOC[i] ? sLayerId : 0);
137
0
            refPicSetStCurr1[numPocStCurr1] = refPic;
138
0
            numPocStCurr1++;
139
0
        }
140
0
    }
141
142
0
    X265_CHECK(m_rps.numberOfPictures == m_rps.numberOfNegativePictures + m_rps.numberOfPositivePictures,
143
0
               "unexpected picture in RPS\n");
144
145
    // ref_pic_list_init
146
0
    Frame* rpsCurrList0[MAX_NUM_REF + 1];
147
0
    Frame* rpsCurrList1[MAX_NUM_REF + 1];
148
#if ENABLE_MULTIVIEW
149
    int numPocTotalCurr = numPocStCurr0 + numPocStCurr1 + numPocLtCurr + refPicSetInterLayer0.size() + refPicSetInterLayer1.size();
150
#else
151
0
    int numPocTotalCurr = numPocStCurr0 + numPocStCurr1 + numPocLtCurr;
152
0
#endif
153
154
#if ENABLE_SCC_EXT
155
    if (m_param->bEnableSCC)
156
        numPocTotalCurr++;
157
#endif
158
159
0
    int cIdx = 0;
160
0
    for (i = 0; i < numPocStCurr0; i++, cIdx++)
161
0
        rpsCurrList0[cIdx] = refPicSetStCurr0[i];
162
163
#if ENABLE_MULTIVIEW
164
    if (m_param->numViews > 1)
165
        for (i = 0; i < refPicSetInterLayer0.size(); i++, cIdx++)
166
            rpsCurrList0[cIdx] = refPicSetInterLayer0.getPOC(m_poc, 0);
167
#endif
168
169
0
    for (i = 0; i < numPocStCurr1; i++, cIdx++)
170
0
        rpsCurrList0[cIdx] = refPicSetStCurr1[i];
171
172
0
    for (i = 0; i < numPocLtCurr; i++, cIdx++)
173
0
        rpsCurrList0[cIdx] = refPicSetLtCurr[i];
174
175
#if ENABLE_MULTIVIEW
176
    if (m_param->numViews > 1)
177
        for (i = 0; i < refPicSetInterLayer1.size(); i++, cIdx++)
178
            rpsCurrList0[cIdx] = refPicSetInterLayer1.getPOC(m_poc, 0);
179
#endif
180
181
#if ENABLE_SCC_EXT
182
    if (m_param->bEnableSCC)
183
        rpsCurrList0[cIdx++] = picList.getPOC(m_poc);
184
#endif
185
186
0
    X265_CHECK(cIdx == numPocTotalCurr, "RPS index check fail\n");
187
188
0
    if (m_sliceType == B_SLICE)
189
0
    {
190
0
        cIdx = 0;
191
0
        for (i = 0; i < numPocStCurr1; i++, cIdx++)
192
0
            rpsCurrList1[cIdx] = refPicSetStCurr1[i];
193
194
#if ENABLE_MULTIVIEW
195
        if (m_param->numViews > 1)
196
            for (i = 0; i < refPicSetInterLayer1.size(); i++, cIdx++)
197
                rpsCurrList1[cIdx] = refPicSetInterLayer1.getPOC(m_poc, 0);
198
#endif
199
200
0
        for (i = 0; i < numPocStCurr0; i++, cIdx++)
201
0
            rpsCurrList1[cIdx] = refPicSetStCurr0[i];
202
203
0
        for (i = 0; i < numPocLtCurr; i++, cIdx++)
204
0
            rpsCurrList1[cIdx] = refPicSetLtCurr[i];
205
206
#if ENABLE_MULTIVIEW
207
        if (m_param->numViews > 1)
208
            for (i = 0; i < refPicSetInterLayer0.size(); i++, cIdx++)
209
                rpsCurrList1[cIdx] = refPicSetInterLayer0.getPOC(m_poc, 0);
210
#endif
211
212
#if  ENABLE_SCC_EXT
213
        if (m_param->bEnableSCC)
214
            rpsCurrList1[cIdx++] = picList.getPOC(m_poc);
215
#endif
216
217
0
        X265_CHECK(cIdx == numPocTotalCurr, "RPS index check fail\n");
218
0
    }
219
220
0
    for (int rIdx = 0; rIdx < m_numRefIdx[0]; rIdx++)
221
0
    {
222
0
        cIdx = rIdx % numPocTotalCurr;
223
0
        X265_CHECK(cIdx >= 0 && cIdx < numPocTotalCurr, "RPS index check fail\n");
224
0
        m_refFrameList[0][rIdx] = rpsCurrList0[cIdx];
225
#if ENABLE_MULTIVIEW
226
        m_refFrameList[0][rIdx] = rpsCurrList0[cIdx];
227
#endif
228
0
    }
229
230
#if  ENABLE_SCC_EXT
231
    if (m_param->bEnableSCC && numPocTotalCurr > m_numRefIdx[0])
232
    {
233
        m_refFrameList[0][m_numRefIdx[0] - 1] = picList.getPOC(m_poc);
234
    }
235
#endif
236
237
0
    if (m_sliceType != B_SLICE)
238
0
    {
239
0
        m_numRefIdx[1] = 0;
240
0
        memset(m_refFrameList[1], 0, sizeof(m_refFrameList[1]));
241
0
    }
242
0
    else
243
0
    {
244
0
        for (int rIdx = 0; rIdx < m_numRefIdx[1]; rIdx++)
245
0
        {
246
0
            cIdx = rIdx % numPocTotalCurr;
247
0
            X265_CHECK(cIdx >= 0 && cIdx < numPocTotalCurr, "RPS index check fail\n");
248
0
            m_refFrameList[1][rIdx] = rpsCurrList1[cIdx];
249
#if ENABLE_MULTIVIEW
250
            m_refFrameList[1][rIdx] = rpsCurrList1[cIdx];
251
#endif
252
0
        }
253
0
    }
254
255
0
    for (int dir = 0; dir < 2; dir++)
256
0
        for (int numRefIdx = 0; numRefIdx < m_numRefIdx[dir]; numRefIdx++)
257
0
            m_refPOCList[dir][numRefIdx] = m_refFrameList[dir][numRefIdx]->m_poc;
258
0
}
259
260
void Slice::disableWeights()
261
0
{
262
0
    for (int l = 0; l < 2; l++)
263
0
        for (int i = 0; i < MAX_NUM_REF; i++)
264
0
            for (int yuv = 0; yuv < 3; yuv++)
265
0
            {
266
0
                WeightParam& wp = m_weightPredTable[l][i][yuv];
267
0
                wp.wtPresent = 0;
268
0
                wp.log2WeightDenom = 0;
269
0
                wp.inputWeight = 1;
270
0
                wp.inputOffset = 0;
271
0
            }
272
0
}
273
274
#if  ENABLE_SCC_EXT
275
bool Slice::isOnlyCurrentPictureAsReference() const
276
{
277
    if (m_sliceType == I_SLICE)
278
    {
279
        return true;
280
    }
281
282
    for (int i = 0; i < m_numRefIdx[0]; i++)
283
    {
284
        if (m_refFrameList[0][i]->m_poc != m_poc)
285
        {
286
            return false;
287
        }
288
    }
289
290
    for (int i = 0; i < m_numRefIdx[1]; i++)
291
    {
292
        if (m_refFrameList[1][i]->m_poc != m_poc)
293
        {
294
            return false;
295
        }
296
    }
297
298
    return true;
299
}
300
#endif
301
302
/* Sorts the deltaPOC and Used by current values in the RPS based on the
303
 * deltaPOC values.  deltaPOC values are sorted with -ve values before the +ve
304
 * values.  -ve values are in decreasing order.  +ve values are in increasing
305
 * order */
306
void RPS::sortDeltaPOC()
307
0
{
308
    // sort in increasing order (smallest first)
309
0
    for (int j = 1; j < numberOfPictures; j++)
310
0
    {
311
0
        int dPOC = deltaPOC[j];
312
0
        bool used = bUsed[j];
313
0
        for (int k = j - 1; k >= 0; k--)
314
0
        {
315
0
            int temp = deltaPOC[k];
316
0
            if (dPOC < temp)
317
0
            {
318
0
                deltaPOC[k + 1] = temp;
319
0
                bUsed[k + 1] = bUsed[k];
320
0
                deltaPOC[k] = dPOC;
321
0
                bUsed[k] = used;
322
0
            }
323
0
        }
324
0
    }
325
326
    // flip the negative values to largest first
327
0
    int numNegPics = numberOfNegativePictures;
328
0
    for (int j = 0, k = numNegPics - 1; j < numNegPics >> 1; j++, k--)
329
0
    {
330
0
        int dPOC = deltaPOC[j];
331
0
        bool used = bUsed[j];
332
0
        deltaPOC[j] = deltaPOC[k];
333
0
        bUsed[j] = bUsed[k];
334
0
        deltaPOC[k] = dPOC;
335
0
        bUsed[k] = used;
336
0
    }
337
0
}
338
339
uint32_t Slice::realEndAddress(uint32_t endCUAddr) const
340
0
{
341
    // Calculate end address
342
0
    uint32_t internalAddress = (endCUAddr - 1) % m_param->num4x4Partitions;
343
0
    uint32_t externalAddress = (endCUAddr - 1) / m_param->num4x4Partitions;
344
0
    uint32_t xmax = m_sps->picWidthInLumaSamples - (externalAddress % m_sps->numCuInWidth) * m_param->maxCUSize;
345
0
    uint32_t ymax = m_sps->picHeightInLumaSamples - (externalAddress / m_sps->numCuInWidth) * m_param->maxCUSize;
346
347
0
    while (g_zscanToPelX[internalAddress] >= xmax || g_zscanToPelY[internalAddress] >= ymax)
348
0
        internalAddress--;
349
350
0
    internalAddress++;
351
0
    if (internalAddress == m_param->num4x4Partitions)
352
0
    {
353
0
        internalAddress = 0;
354
0
        externalAddress++;
355
0
    }
356
357
0
    return externalAddress * m_param->num4x4Partitions + internalAddress;
358
0
}
359
360