Imported Upstream version 1.4
[deb_x265.git] / source / common / slice.cpp
1 /*****************************************************************************
2 * Copyright (C) 2014 x265 project
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;
31
32 void Slice::setRefPicList(PicList& picList)
33 {
34 if (m_sliceType == I_SLICE)
35 {
36 ::memset(m_refPicList, 0, sizeof(m_refPicList));
37 m_numRefIdx[1] = m_numRefIdx[0] = 0;
38 return;
39 }
40
41 Frame* refPic = NULL;
42 Frame* refPicSetStCurr0[MAX_NUM_REF];
43 Frame* refPicSetStCurr1[MAX_NUM_REF];
44 Frame* refPicSetLtCurr[MAX_NUM_REF];
45 int numPocStCurr0 = 0;
46 int numPocStCurr1 = 0;
47 int numPocLtCurr = 0;
48 int i;
49
50 for (i = 0; i < m_rps.numberOfNegativePictures; i++)
51 {
52 if (m_rps.bUsed[i])
53 {
54 refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i]);
55 refPicSetStCurr0[numPocStCurr0] = refPic;
56 numPocStCurr0++;
57 }
58 }
59
60 for (; i < m_rps.numberOfNegativePictures + m_rps.numberOfPositivePictures; i++)
61 {
62 if (m_rps.bUsed[i])
63 {
64 refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i]);
65 refPicSetStCurr1[numPocStCurr1] = refPic;
66 numPocStCurr1++;
67 }
68 }
69
70 X265_CHECK(m_rps.numberOfPictures == m_rps.numberOfNegativePictures + m_rps.numberOfPositivePictures,
71 "unexpected picture in RPS\n");
72
73 // ref_pic_list_init
74 Frame* rpsCurrList0[MAX_NUM_REF + 1];
75 Frame* rpsCurrList1[MAX_NUM_REF + 1];
76 int numPocTotalCurr = numPocStCurr0 + numPocStCurr1 + numPocLtCurr;
77
78 int cIdx = 0;
79 for (i = 0; i < numPocStCurr0; i++, cIdx++)
80 rpsCurrList0[cIdx] = refPicSetStCurr0[i];
81
82 for (i = 0; i < numPocStCurr1; i++, cIdx++)
83 rpsCurrList0[cIdx] = refPicSetStCurr1[i];
84
85 for (i = 0; i < numPocLtCurr; i++, cIdx++)
86 rpsCurrList0[cIdx] = refPicSetLtCurr[i];
87
88 X265_CHECK(cIdx == numPocTotalCurr, "RPS index check fail\n");
89
90 if (m_sliceType == B_SLICE)
91 {
92 cIdx = 0;
93 for (i = 0; i < numPocStCurr1; i++, cIdx++)
94 rpsCurrList1[cIdx] = refPicSetStCurr1[i];
95
96 for (i = 0; i < numPocStCurr0; i++, cIdx++)
97 rpsCurrList1[cIdx] = refPicSetStCurr0[i];
98
99 for (i = 0; i < numPocLtCurr; i++, cIdx++)
100 rpsCurrList1[cIdx] = refPicSetLtCurr[i];
101
102 X265_CHECK(cIdx == numPocTotalCurr, "RPS index check fail\n");
103 }
104
105 for (int rIdx = 0; rIdx < m_numRefIdx[0]; rIdx++)
106 {
107 cIdx = rIdx % numPocTotalCurr;
108 X265_CHECK(cIdx >= 0 && cIdx < numPocTotalCurr, "RPS index check fail\n");
109 m_refPicList[0][rIdx] = rpsCurrList0[cIdx];
110 }
111
112 if (m_sliceType != B_SLICE)
113 {
114 m_numRefIdx[1] = 0;
115 ::memset(m_refPicList[1], 0, sizeof(m_refPicList[1]));
116 }
117 else
118 {
119 for (int rIdx = 0; rIdx < m_numRefIdx[1]; rIdx++)
120 {
121 cIdx = rIdx % numPocTotalCurr;
122 X265_CHECK(cIdx >= 0 && cIdx < numPocTotalCurr, "RPS index check fail\n");
123 m_refPicList[1][rIdx] = rpsCurrList1[cIdx];
124 }
125 }
126
127 for (int dir = 0; dir < 2; dir++)
128 for (int numRefIdx = 0; numRefIdx < m_numRefIdx[dir]; numRefIdx++)
129 m_refPOCList[dir][numRefIdx] = m_refPicList[dir][numRefIdx]->m_poc;
130 }
131
132 void Slice::disableWeights()
133 {
134 for (int l = 0; l < 2; l++)
135 for (int i = 0; i < MAX_NUM_REF; i++)
136 for (int yuv = 0; yuv < 3; yuv++)
137 {
138 WeightParam& wp = m_weightPredTable[l][i][yuv];
139 wp.bPresentFlag = false;
140 wp.log2WeightDenom = 0;
141 wp.inputWeight = 1;
142 wp.inputOffset = 0;
143 }
144 }
145
146 /* Sorts the deltaPOC and Used by current values in the RPS based on the
147 * deltaPOC values. deltaPOC values are sorted with -ve values before the +ve
148 * values. -ve values are in decreasing order. +ve values are in increasing
149 * order */
150 void RPS::sortDeltaPOC()
151 {
152 // sort in increasing order (smallest first)
153 for (int j = 1; j < numberOfPictures; j++)
154 {
155 int dPOC = deltaPOC[j];
156 bool used = bUsed[j];
157 for (int k = j - 1; k >= 0; k--)
158 {
159 int temp = deltaPOC[k];
160 if (dPOC < temp)
161 {
162 deltaPOC[k + 1] = temp;
163 bUsed[k + 1] = bUsed[k];
164 deltaPOC[k] = dPOC;
165 bUsed[k] = used;
166 }
167 }
168 }
169
170 // flip the negative values to largest first
171 int numNegPics = numberOfNegativePictures;
172 for (int j = 0, k = numNegPics - 1; j < numNegPics >> 1; j++, k--)
173 {
174 int dPOC = deltaPOC[j];
175 bool used = bUsed[j];
176 deltaPOC[j] = deltaPOC[k];
177 bUsed[j] = bUsed[k];
178 deltaPOC[k] = dPOC;
179 bUsed[k] = used;
180 }
181 }
182
183 uint32_t Slice::realEndAddress(uint32_t endCUAddr) const
184 {
185 // Calculate end address
186 uint32_t internalAddress = (endCUAddr - 1) % NUM_CU_PARTITIONS;
187 uint32_t externalAddress = (endCUAddr - 1) / NUM_CU_PARTITIONS;
188 uint32_t xmax = m_sps->picWidthInLumaSamples - (externalAddress % m_sps->numCuInWidth) * g_maxCUSize;
189 uint32_t ymax = m_sps->picHeightInLumaSamples - (externalAddress / m_sps->numCuInWidth) * g_maxCUSize;
190
191 while (g_zscanToPelX[internalAddress] >= xmax || g_zscanToPelY[internalAddress] >= ymax)
192 internalAddress--;
193
194 internalAddress++;
195 if (internalAddress == NUM_CU_PARTITIONS)
196 {
197 internalAddress = 0;
198 externalAddress++;
199 }
200
201 return externalAddress * NUM_CU_PARTITIONS + internalAddress;
202 }
203
204