OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 pic->frame_num = pic->pic_num = frame_num; | 103 pic->frame_num = pic->pic_num = frame_num; |
104 pic->adaptive_ref_pic_marking_mode_flag = false; | 104 pic->adaptive_ref_pic_marking_mode_flag = false; |
105 pic->ref = true; | 105 pic->ref = true; |
106 pic->long_term_reference_flag = false; | 106 pic->long_term_reference_flag = false; |
107 pic->field = H264Picture::FIELD_NONE; | 107 pic->field = H264Picture::FIELD_NONE; |
108 | 108 |
109 return CalculatePicOrderCounts(pic); | 109 return CalculatePicOrderCounts(pic); |
110 } | 110 } |
111 | 111 |
112 bool H264Decoder::InitCurrPicture(const H264SliceHeader* slice_hdr) { | 112 bool H264Decoder::InitCurrPicture(const H264SliceHeader* slice_hdr) { |
113 DCHECK(curr_pic_.get()); | 113 if (!InitPictureFromSliceHeader(curr_sps_id_, parser_, slice_hdr, curr_pic_)) |
114 | |
115 curr_pic_->idr = slice_hdr->idr_pic_flag; | |
116 if (curr_pic_->idr) | |
117 curr_pic_->idr_pic_id = slice_hdr->idr_pic_id; | |
118 | |
119 if (slice_hdr->field_pic_flag) { | |
120 curr_pic_->field = slice_hdr->bottom_field_flag ? H264Picture::FIELD_BOTTOM | |
121 : H264Picture::FIELD_TOP; | |
122 } else { | |
123 curr_pic_->field = H264Picture::FIELD_NONE; | |
124 } | |
125 | |
126 if (curr_pic_->field != H264Picture::FIELD_NONE) { | |
127 DVLOG(1) << "Interlaced video not supported."; | |
128 return false; | 114 return false; |
129 } | |
130 | |
131 curr_pic_->nal_ref_idc = slice_hdr->nal_ref_idc; | |
132 curr_pic_->ref = slice_hdr->nal_ref_idc != 0; | |
133 // This assumes non-interlaced stream. | |
134 curr_pic_->frame_num = curr_pic_->pic_num = slice_hdr->frame_num; | |
135 | |
136 DCHECK_NE(curr_sps_id_, -1); | |
137 const H264SPS* sps = parser_.GetSPS(curr_sps_id_); | |
138 if (!sps) | |
139 return false; | |
140 | |
141 curr_pic_->pic_order_cnt_type = sps->pic_order_cnt_type; | |
142 switch (curr_pic_->pic_order_cnt_type) { | |
143 case 0: | |
144 curr_pic_->pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb; | |
145 curr_pic_->delta_pic_order_cnt_bottom = | |
146 slice_hdr->delta_pic_order_cnt_bottom; | |
147 break; | |
148 | |
149 case 1: | |
150 curr_pic_->delta_pic_order_cnt0 = slice_hdr->delta_pic_order_cnt0; | |
151 curr_pic_->delta_pic_order_cnt1 = slice_hdr->delta_pic_order_cnt1; | |
152 break; | |
153 | |
154 case 2: | |
155 break; | |
156 | |
157 default: | |
158 NOTREACHED(); | |
159 return false; | |
160 } | |
161 | 115 |
162 if (!CalculatePicOrderCounts(curr_pic_)) | 116 if (!CalculatePicOrderCounts(curr_pic_)) |
163 return false; | 117 return false; |
164 | 118 |
165 curr_pic_->long_term_reference_flag = slice_hdr->long_term_reference_flag; | 119 curr_pic_->long_term_reference_flag = slice_hdr->long_term_reference_flag; |
166 curr_pic_->adaptive_ref_pic_marking_mode_flag = | 120 curr_pic_->adaptive_ref_pic_marking_mode_flag = |
167 slice_hdr->adaptive_ref_pic_marking_mode_flag; | 121 slice_hdr->adaptive_ref_pic_marking_mode_flag; |
168 | 122 |
169 // If the slice header indicates we will have to perform reference marking | 123 // If the slice header indicates we will have to perform reference marking |
170 // process after this picture is decoded, store required data for that | 124 // process after this picture is decoded, store required data for that |
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1173 if (!FinishPicture(pic)) | 1127 if (!FinishPicture(pic)) |
1174 return false; | 1128 return false; |
1175 | 1129 |
1176 unused_short_term_frame_num++; | 1130 unused_short_term_frame_num++; |
1177 unused_short_term_frame_num %= max_frame_num_; | 1131 unused_short_term_frame_num %= max_frame_num_; |
1178 } | 1132 } |
1179 | 1133 |
1180 return true; | 1134 return true; |
1181 } | 1135 } |
1182 | 1136 |
1183 bool H264Decoder::IsNewPrimaryCodedPicture( | |
1184 const H264SliceHeader* slice_hdr) const { | |
1185 if (!curr_pic_) | |
1186 return true; | |
1187 | |
1188 // 7.4.1.2.4, assumes non-interlaced. | |
1189 if (slice_hdr->frame_num != curr_pic_->frame_num || | |
1190 slice_hdr->pic_parameter_set_id != curr_pps_id_ || | |
1191 slice_hdr->nal_ref_idc != curr_pic_->nal_ref_idc || | |
1192 slice_hdr->idr_pic_flag != curr_pic_->idr || | |
1193 (slice_hdr->idr_pic_flag && | |
1194 (slice_hdr->idr_pic_id != curr_pic_->idr_pic_id || | |
1195 // If we have two consecutive IDR slices, and the second one has | |
1196 // first_mb_in_slice == 0, treat it as a new picture. | |
1197 // Per spec, idr_pic_id should not be equal in this case (and we should | |
1198 // have hit the condition above instead, see spec 7.4.3 on idr_pic_id), | |
1199 // but some encoders neglect changing idr_pic_id for two consecutive | |
1200 // IDRs. Work around this by checking if the next slice contains the | |
1201 // zeroth macroblock, i.e. data that belongs to the next picture. | |
1202 slice_hdr->first_mb_in_slice == 0))) | |
1203 return true; | |
1204 | |
1205 const H264SPS* sps = parser_.GetSPS(curr_sps_id_); | |
1206 if (!sps) | |
1207 return false; | |
1208 | |
1209 if (sps->pic_order_cnt_type == curr_pic_->pic_order_cnt_type) { | |
1210 if (curr_pic_->pic_order_cnt_type == 0) { | |
1211 if (slice_hdr->pic_order_cnt_lsb != curr_pic_->pic_order_cnt_lsb || | |
1212 slice_hdr->delta_pic_order_cnt_bottom != | |
1213 curr_pic_->delta_pic_order_cnt_bottom) | |
1214 return true; | |
1215 } else if (curr_pic_->pic_order_cnt_type == 1) { | |
1216 if (slice_hdr->delta_pic_order_cnt0 != curr_pic_->delta_pic_order_cnt0 || | |
1217 slice_hdr->delta_pic_order_cnt1 != curr_pic_->delta_pic_order_cnt1) | |
1218 return true; | |
1219 } | |
1220 } | |
1221 | |
1222 return false; | |
1223 } | |
1224 | |
1225 bool H264Decoder::PreprocessCurrentSlice() { | 1137 bool H264Decoder::PreprocessCurrentSlice() { |
1226 const H264SliceHeader* slice_hdr = curr_slice_hdr_.get(); | 1138 const H264SliceHeader* slice_hdr = curr_slice_hdr_.get(); |
1227 DCHECK(slice_hdr); | 1139 DCHECK(slice_hdr); |
1228 | 1140 |
1229 if (IsNewPrimaryCodedPicture(slice_hdr)) { | 1141 if (IsNewPrimaryCodedPicture(curr_pic_, curr_pps_id_, curr_sps_id_, parser_, |
1142 slice_hdr)) { | |
1230 // New picture, so first finish the previous one before processing it. | 1143 // New picture, so first finish the previous one before processing it. |
1231 if (!FinishPrevFrameIfPresent()) | 1144 if (!FinishPrevFrameIfPresent()) |
1232 return false; | 1145 return false; |
1233 | 1146 |
1234 DCHECK(!curr_pic_); | 1147 DCHECK(!curr_pic_); |
1235 | 1148 |
1236 if (slice_hdr->first_mb_in_slice != 0) { | 1149 if (slice_hdr->first_mb_in_slice != 0) { |
1237 DVLOG(1) << "ASO/invalid stream, first_mb_in_slice: " | 1150 DVLOG(1) << "ASO/invalid stream, first_mb_in_slice: " |
1238 << slice_hdr->first_mb_in_slice; | 1151 << slice_hdr->first_mb_in_slice; |
1239 return false; | 1152 return false; |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1432 } | 1345 } |
1433 | 1346 |
1434 gfx::Size H264Decoder::GetPicSize() const { | 1347 gfx::Size H264Decoder::GetPicSize() const { |
1435 return pic_size_; | 1348 return pic_size_; |
1436 } | 1349 } |
1437 | 1350 |
1438 size_t H264Decoder::GetRequiredNumOfPictures() const { | 1351 size_t H264Decoder::GetRequiredNumOfPictures() const { |
1439 return dpb_.max_num_pics() + kPicsInPipeline; | 1352 return dpb_.max_num_pics() + kPicsInPipeline; |
1440 } | 1353 } |
1441 | 1354 |
1355 // static | |
1356 bool H264Decoder::InitPictureFromSliceHeader(int curr_sps_id, | |
Pawel Osciak
2016/12/20 08:34:22
Perhaps we could instead return a scoped_refptr<H2
emircan
2017/01/03 19:29:00
Done.
| |
1357 const H264Parser& parser, | |
Pawel Osciak
2016/12/20 08:34:22
Perhaps we could pass the SPS directly to the meth
emircan
2017/01/03 19:29:00
Done. Note that I kept param as |const H264SPS* sp
| |
1358 const H264SliceHeader* slice_hdr, | |
1359 scoped_refptr<H264Picture> pic) { | |
1360 DCHECK(pic.get()); | |
1361 | |
1362 pic->idr = slice_hdr->idr_pic_flag; | |
1363 if (pic->idr) | |
1364 pic->idr_pic_id = slice_hdr->idr_pic_id; | |
1365 | |
1366 if (slice_hdr->field_pic_flag) { | |
1367 pic->field = slice_hdr->bottom_field_flag ? H264Picture::FIELD_BOTTOM | |
1368 : H264Picture::FIELD_TOP; | |
1369 } else { | |
1370 pic->field = H264Picture::FIELD_NONE; | |
1371 } | |
1372 | |
1373 if (pic->field != H264Picture::FIELD_NONE) { | |
1374 DVLOG(1) << "Interlaced video not supported."; | |
1375 return false; | |
1376 } | |
1377 | |
1378 pic->nal_ref_idc = slice_hdr->nal_ref_idc; | |
1379 pic->ref = slice_hdr->nal_ref_idc != 0; | |
1380 // This assumes non-interlaced stream. | |
1381 pic->frame_num = pic->pic_num = slice_hdr->frame_num; | |
1382 | |
1383 DCHECK_NE(curr_sps_id, -1); | |
1384 const H264SPS* sps = parser.GetSPS(curr_sps_id); | |
1385 if (!sps) | |
1386 return false; | |
1387 | |
1388 pic->pic_order_cnt_type = sps->pic_order_cnt_type; | |
1389 switch (pic->pic_order_cnt_type) { | |
1390 case 0: | |
1391 pic->pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb; | |
1392 pic->delta_pic_order_cnt_bottom = slice_hdr->delta_pic_order_cnt_bottom; | |
1393 break; | |
1394 | |
1395 case 1: | |
1396 pic->delta_pic_order_cnt0 = slice_hdr->delta_pic_order_cnt0; | |
1397 pic->delta_pic_order_cnt1 = slice_hdr->delta_pic_order_cnt1; | |
1398 break; | |
1399 | |
1400 case 2: | |
1401 break; | |
1402 | |
1403 default: | |
1404 NOTREACHED(); | |
1405 return false; | |
1406 } | |
1407 return true; | |
1408 } | |
1409 | |
1410 // static | |
1411 bool H264Decoder::IsNewPrimaryCodedPicture(scoped_refptr<H264Picture> curr_pic, | |
Pawel Osciak
2016/12/20 08:34:22
const scoped_refptr<>& ?
emircan
2017/01/03 19:29:00
I came across to this in an earlier review that pa
| |
1412 int curr_pps_id, | |
1413 int curr_sps_id, | |
1414 const H264Parser& parser, | |
Pawel Osciak
2016/12/20 08:34:22
Here we should be able to also pass an SPS only, w
emircan
2017/01/03 19:29:00
Done.
| |
1415 const H264SliceHeader* slice_hdr) { | |
Pawel Osciak
2016/12/20 08:34:22
Since we are not changing the structure, could we
emircan
2017/01/03 19:29:00
Done.
| |
1416 if (!curr_pic) | |
1417 return true; | |
1418 | |
1419 // 7.4.1.2.4, assumes non-interlaced. | |
1420 if (slice_hdr->frame_num != curr_pic->frame_num || | |
1421 slice_hdr->pic_parameter_set_id != curr_pps_id || | |
1422 slice_hdr->nal_ref_idc != curr_pic->nal_ref_idc || | |
1423 slice_hdr->idr_pic_flag != curr_pic->idr || | |
1424 (slice_hdr->idr_pic_flag && | |
1425 (slice_hdr->idr_pic_id != curr_pic->idr_pic_id || | |
1426 // If we have two consecutive IDR slices, and the second one has | |
1427 // first_mb_in_slice == 0, treat it as a new picture. | |
1428 // Per spec, idr_pic_id should not be equal in this case (and we should | |
1429 // have hit the condition above instead, see spec 7.4.3 on idr_pic_id), | |
1430 // but some encoders neglect changing idr_pic_id for two consecutive | |
1431 // IDRs. Work around this by checking if the next slice contains the | |
1432 // zeroth macroblock, i.e. data that belongs to the next picture. | |
1433 slice_hdr->first_mb_in_slice == 0))) | |
1434 return true; | |
1435 | |
1436 const H264SPS* sps = parser.GetSPS(curr_sps_id); | |
1437 if (!sps) | |
1438 return false; | |
1439 | |
1440 if (sps->pic_order_cnt_type == curr_pic->pic_order_cnt_type) { | |
1441 if (curr_pic->pic_order_cnt_type == 0) { | |
1442 if (slice_hdr->pic_order_cnt_lsb != curr_pic->pic_order_cnt_lsb || | |
1443 slice_hdr->delta_pic_order_cnt_bottom != | |
1444 curr_pic->delta_pic_order_cnt_bottom) | |
1445 return true; | |
1446 } else if (curr_pic->pic_order_cnt_type == 1) { | |
1447 if (slice_hdr->delta_pic_order_cnt0 != curr_pic->delta_pic_order_cnt0 || | |
1448 slice_hdr->delta_pic_order_cnt1 != curr_pic->delta_pic_order_cnt1) | |
1449 return true; | |
1450 } | |
1451 } | |
1452 | |
1453 return false; | |
1454 } | |
1455 | |
1442 } // namespace media | 1456 } // namespace media |
OLD | NEW |