1 /*****************************************************************************
2 * Copyright (C) 2013 x265 project
4 * Authors: Steve Borho <steve@borho.org>
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.
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.
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.
20 * This program is also available under a commercial proprietary license.
21 * For more information, contact us at license @ x265.com.
22 *****************************************************************************/
26 #include "framedata.h"
36 while (!m_freeList
.empty())
38 Frame
* curFrame
= m_freeList
.popFront();
43 while (!m_picList
.empty())
45 Frame
* curFrame
= m_picList
.popFront();
50 while (m_picSymFreeList
)
52 FrameData
* next
= m_picSymFreeList
->m_freeListNext
;
53 m_picSymFreeList
->destroy();
55 m_picSymFreeList
->m_reconPicYuv
->destroy();
56 delete m_picSymFreeList
->m_reconPicYuv
;
58 delete m_picSymFreeList
;
59 m_picSymFreeList
= next
;
63 // move unreferenced pictures from picList to freeList for recycle
64 void DPB::recycleUnreferenced()
66 Frame
*iterFrame
= m_picList
.first();
70 Frame
*curFrame
= iterFrame
;
71 iterFrame
= iterFrame
->m_next
;
72 if (!curFrame
->m_encData
->m_bHasReferences
&& !curFrame
->m_countRefEncoders
)
74 curFrame
->m_reconRowCount
.set(0);
75 curFrame
->m_bChromaExtended
= false;
77 // iterator is invalidated by remove, restart scan
78 m_picList
.remove(*curFrame
);
79 iterFrame
= m_picList
.first();
81 m_freeList
.pushBack(*curFrame
);
82 curFrame
->m_encData
->m_freeListNext
= m_picSymFreeList
;
83 m_picSymFreeList
= curFrame
->m_encData
;
84 curFrame
->m_encData
= NULL
;
85 curFrame
->m_reconPicYuv
= NULL
;
90 void DPB::prepareEncode(Frame
*newFrame
)
92 Slice
* slice
= newFrame
->m_encData
->m_slice
;
93 slice
->m_poc
= newFrame
->m_poc
;
95 int pocCurr
= slice
->m_poc
;
96 int type
= newFrame
->m_lowres
.sliceType
;
97 bool bIsKeyFrame
= newFrame
->m_lowres
.bKeyframe
;
99 slice
->m_nalUnitType
= getNalUnitType(pocCurr
, bIsKeyFrame
);
100 if (slice
->m_nalUnitType
== NAL_UNIT_CODED_SLICE_IDR_W_RADL
)
102 slice
->m_lastIDR
= m_lastIDR
;
103 slice
->m_sliceType
= IS_X265_TYPE_B(type
) ? B_SLICE
: (type
== X265_TYPE_P
) ? P_SLICE
: I_SLICE
;
105 if (type
== X265_TYPE_B
)
107 // change from _R "referenced" to _N "non-referenced" NAL unit type
108 switch (slice
->m_nalUnitType
)
110 case NAL_UNIT_CODED_SLICE_TRAIL_R
:
111 slice
->m_nalUnitType
= NAL_UNIT_CODED_SLICE_TRAIL_N
;
113 case NAL_UNIT_CODED_SLICE_RADL_R
:
114 slice
->m_nalUnitType
= NAL_UNIT_CODED_SLICE_RADL_N
;
116 case NAL_UNIT_CODED_SLICE_RASL_R
:
117 slice
->m_nalUnitType
= NAL_UNIT_CODED_SLICE_RASL_N
;
124 /* m_bHasReferences starts out as true for non-B pictures, and is set to false
125 * once no more pictures reference it */
126 newFrame
->m_encData
->m_bHasReferences
= IS_REFERENCED(newFrame
);
128 m_picList
.pushFront(*newFrame
);
130 // Do decoding refresh marking if any
131 decodingRefreshMarking(pocCurr
, slice
->m_nalUnitType
);
133 computeRPS(pocCurr
, slice
->isIRAP(), &slice
->m_rps
, slice
->m_sps
->maxDecPicBuffering
);
135 // Mark pictures in m_piclist as unreferenced if they are not included in RPS
136 applyReferencePictureSet(&slice
->m_rps
, pocCurr
);
138 slice
->m_numRefIdx
[0] = X265_MIN(m_maxRefL0
, slice
->m_rps
.numberOfNegativePictures
); // Ensuring L0 contains just the -ve POC
139 slice
->m_numRefIdx
[1] = X265_MIN(m_maxRefL1
, slice
->m_rps
.numberOfPositivePictures
);
140 slice
->setRefPicList(m_picList
);
142 X265_CHECK(slice
->m_sliceType
!= B_SLICE
|| slice
->m_numRefIdx
[1], "B slice without L1 references (non-fatal)\n");
144 if (slice
->m_sliceType
== B_SLICE
)
146 /* TODO: the lookahead should be able to tell which reference picture
147 * had the least motion residual. We should be able to use that here to
148 * select a colocation reference list and index */
149 slice
->m_colFromL0Flag
= false;
150 slice
->m_colRefIdx
= 0;
151 slice
->m_bCheckLDC
= false;
155 slice
->m_bCheckLDC
= true;
156 slice
->m_colFromL0Flag
= true;
157 slice
->m_colRefIdx
= 0;
159 slice
->m_sLFaseFlag
= (SLFASE_CONSTANT
& (1 << (pocCurr
% 31))) > 0;
161 /* Increment reference count of all motion-referenced frames to prevent them
162 * from being recycled. These counts are decremented at the end of
164 int numPredDir
= slice
->isInterP() ? 1 : slice
->isInterB() ? 2 : 0;
165 for (int l
= 0; l
< numPredDir
; l
++)
167 for (int ref
= 0; ref
< slice
->m_numRefIdx
[l
]; ref
++)
169 Frame
*refpic
= slice
->m_refPicList
[l
][ref
];
170 ATOMIC_INC(&refpic
->m_countRefEncoders
);
175 void DPB::computeRPS(int curPoc
, bool isRAP
, RPS
* rps
, unsigned int maxDecPicBuffer
)
177 unsigned int poci
= 0, numNeg
= 0, numPos
= 0;
179 Frame
* iterPic
= m_picList
.first();
181 while (iterPic
&& (poci
< maxDecPicBuffer
- 1))
183 if ((iterPic
->m_poc
!= curPoc
) && iterPic
->m_encData
->m_bHasReferences
)
185 rps
->poc
[poci
] = iterPic
->m_poc
;
186 rps
->deltaPOC
[poci
] = rps
->poc
[poci
] - curPoc
;
187 (rps
->deltaPOC
[poci
] < 0) ? numNeg
++ : numPos
++;
188 rps
->bUsed
[poci
] = !isRAP
;
191 iterPic
= iterPic
->m_next
;
194 rps
->numberOfPictures
= poci
;
195 rps
->numberOfPositivePictures
= numPos
;
196 rps
->numberOfNegativePictures
= numNeg
;
201 /* Marking reference pictures when an IDR/CRA is encountered. */
202 void DPB::decodingRefreshMarking(int pocCurr
, NalUnitType nalUnitType
)
204 if (nalUnitType
== NAL_UNIT_CODED_SLICE_IDR_W_RADL
)
206 /* If the nal_unit_type is IDR, all pictures in the reference picture
207 * list are marked as "unused for reference" */
208 Frame
* iterFrame
= m_picList
.first();
211 if (iterFrame
->m_poc
!= pocCurr
)
212 iterFrame
->m_encData
->m_bHasReferences
= false;
213 iterFrame
= iterFrame
->m_next
;
218 if (m_bRefreshPending
&& pocCurr
> m_pocCRA
)
220 /* If the bRefreshPending flag is true (a deferred decoding refresh
221 * is pending) and the current temporal reference is greater than
222 * the temporal reference of the latest CRA picture (pocCRA), mark
223 * all reference pictures except the latest CRA picture as "unused
224 * for reference" and set the bRefreshPending flag to false */
225 Frame
* iterFrame
= m_picList
.first();
228 if (iterFrame
->m_poc
!= pocCurr
&& iterFrame
->m_poc
!= m_pocCRA
)
229 iterFrame
->m_encData
->m_bHasReferences
= false;
230 iterFrame
= iterFrame
->m_next
;
233 m_bRefreshPending
= false;
235 if (nalUnitType
== NAL_UNIT_CODED_SLICE_CRA
)
237 /* If the nal_unit_type is CRA, set the bRefreshPending flag to true
238 * and pocCRA to the temporal reference of the current picture */
239 m_bRefreshPending
= true;
244 /* Note that the current picture is already placed in the reference list and
245 * its marking is not changed. If the current picture has a nal_ref_idc
246 * that is not 0, it will remain marked as "used for reference" */
249 /** Function for applying picture marking based on the Reference Picture Set */
250 void DPB::applyReferencePictureSet(RPS
*rps
, int curPoc
)
252 // loop through all pictures in the reference picture buffer
253 Frame
* iterFrame
= m_picList
.first();
256 if (iterFrame
->m_poc
!= curPoc
&& iterFrame
->m_encData
->m_bHasReferences
)
258 // loop through all pictures in the Reference Picture Set
259 // to see if the picture should be kept as reference picture
260 bool referenced
= false;
261 for (int i
= 0; i
< rps
->numberOfPositivePictures
+ rps
->numberOfNegativePictures
; i
++)
263 if (iterFrame
->m_poc
== curPoc
+ rps
->deltaPOC
[i
])
270 iterFrame
->m_encData
->m_bHasReferences
= false;
272 iterFrame
= iterFrame
->m_next
;
276 /* deciding the nal_unit_type */
277 NalUnitType
DPB::getNalUnitType(int curPOC
, bool bIsKeyFrame
)
280 return NAL_UNIT_CODED_SLICE_IDR_W_RADL
;
283 return m_bOpenGOP
? NAL_UNIT_CODED_SLICE_CRA
: NAL_UNIT_CODED_SLICE_IDR_W_RADL
;
285 if (m_pocCRA
&& curPOC
< m_pocCRA
)
286 // All leading pictures are being marked as TFD pictures here since
287 // current encoder uses all reference pictures while encoding leading
288 // pictures. An encoder can ensure that a leading picture can be still
289 // decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
290 // controlling the reference pictures used for encoding that leading
291 // picture. Such a leading picture need not be marked as a TFD picture.
292 return NAL_UNIT_CODED_SLICE_RASL_R
;
294 if (m_lastIDR
&& curPOC
< m_lastIDR
)
295 return NAL_UNIT_CODED_SLICE_RADL_R
;
297 return NAL_UNIT_CODED_SLICE_TRAIL_R
;