/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 | | |