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
3 // found in the LICENSE file.
4
5 #include <algorithm>
6 #include <limits>
7
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/callback_helpers.h"
11 #include "base/macros.h"
12 #include "base/numerics/safe_conversions.h"
13 #include "base/optional.h"
14 #include "base/stl_util.h"
15 #include "h264_decoder.h"
16
17 namespace media {
18
H264Accelerator()19 H264Decoder::H264Accelerator::H264Accelerator() {}
20
~H264Accelerator()21 H264Decoder::H264Accelerator::~H264Accelerator() {}
22
H264Decoder(H264Accelerator * accelerator)23 H264Decoder::H264Decoder(H264Accelerator* accelerator)
24 : max_frame_num_(0),
25 max_pic_num_(0),
26 max_long_term_frame_idx_(0),
27 max_num_reorder_frames_(0),
28 accelerator_(accelerator) {
29 DCHECK(accelerator_);
30 Reset();
31 state_ = kNeedStreamMetadata;
32 }
33
~H264Decoder()34 H264Decoder::~H264Decoder() {}
35
Reset()36 void H264Decoder::Reset() {
37 curr_pic_ = nullptr;
38 curr_nalu_ = nullptr;
39 curr_slice_hdr_ = nullptr;
40 curr_sps_id_ = -1;
41 curr_pps_id_ = -1;
42
43 prev_frame_num_ = -1;
44 prev_ref_frame_num_ = -1;
45 prev_frame_num_offset_ = -1;
46 prev_has_memmgmnt5_ = false;
47
48 prev_ref_has_memmgmnt5_ = false;
49 prev_ref_top_field_order_cnt_ = -1;
50 prev_ref_pic_order_cnt_msb_ = -1;
51 prev_ref_pic_order_cnt_lsb_ = -1;
52 prev_ref_field_ = H264Picture::FIELD_NONE;
53
54 ref_pic_list_p0_.clear();
55 ref_pic_list_b0_.clear();
56 ref_pic_list_b1_.clear();
57 dpb_.Clear();
58 parser_.Reset();
59 accelerator_->Reset();
60 last_output_poc_ = std::numeric_limits<int>::min();
61
62 // If we are in kDecoding, we can resume without processing an SPS.
63 if (state_ == kDecoding)
64 state_ = kAfterReset;
65 }
66
PrepareRefPicLists(const H264SliceHeader * slice_hdr)67 void H264Decoder::PrepareRefPicLists(const H264SliceHeader* slice_hdr) {
68 ConstructReferencePicListsP(slice_hdr);
69 ConstructReferencePicListsB(slice_hdr);
70 }
71
ModifyReferencePicLists(const H264SliceHeader * slice_hdr,H264Picture::Vector * ref_pic_list0,H264Picture::Vector * ref_pic_list1)72 bool H264Decoder::ModifyReferencePicLists(const H264SliceHeader* slice_hdr,
73 H264Picture::Vector* ref_pic_list0,
74 H264Picture::Vector* ref_pic_list1) {
75 ref_pic_list0->clear();
76 ref_pic_list1->clear();
77
78 // Fill reference picture lists for B and S/SP slices.
79 if (slice_hdr->IsPSlice() || slice_hdr->IsSPSlice()) {
80 *ref_pic_list0 = ref_pic_list_p0_;
81 return ModifyReferencePicList(slice_hdr, 0, ref_pic_list0);
82 } else if (slice_hdr->IsBSlice()) {
83 *ref_pic_list0 = ref_pic_list_b0_;
84 *ref_pic_list1 = ref_pic_list_b1_;
85 return ModifyReferencePicList(slice_hdr, 0, ref_pic_list0) &&
86 ModifyReferencePicList(slice_hdr, 1, ref_pic_list1);
87 }
88
89 return true;
90 }
91
DecodePicture()92 bool H264Decoder::DecodePicture() {
93 DCHECK(curr_pic_.get());
94
95 DVLOG(4) << "Decoding POC " << curr_pic_->pic_order_cnt;
96 return accelerator_->SubmitDecode(curr_pic_);
97 }
98
InitNonexistingPicture(scoped_refptr<H264Picture> pic,int frame_num)99 bool H264Decoder::InitNonexistingPicture(scoped_refptr<H264Picture> pic,
100 int frame_num) {
101 pic->nonexisting = true;
102 pic->nal_ref_idc = 1;
103 pic->frame_num = pic->pic_num = frame_num;
104 pic->adaptive_ref_pic_marking_mode_flag = false;
105 pic->ref = true;
106 pic->long_term_reference_flag = false;
107 pic->field = H264Picture::FIELD_NONE;
108
109 return CalculatePicOrderCounts(pic);
110 }
111
InitCurrPicture(const H264SliceHeader * slice_hdr)112 bool H264Decoder::InitCurrPicture(const H264SliceHeader* slice_hdr) {
113 DCHECK(curr_pic_.get());
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;
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
162 if (!CalculatePicOrderCounts(curr_pic_))
163 return false;
164
165 curr_pic_->long_term_reference_flag = slice_hdr->long_term_reference_flag;
166 curr_pic_->adaptive_ref_pic_marking_mode_flag =
167 slice_hdr->adaptive_ref_pic_marking_mode_flag;
168
169 // If the slice header indicates we will have to perform reference marking
170 // process after this picture is decoded, store required data for that
171 // purpose.
172 if (slice_hdr->adaptive_ref_pic_marking_mode_flag) {
173 static_assert(sizeof(curr_pic_->ref_pic_marking) ==
174 sizeof(slice_hdr->ref_pic_marking),
175 "Array sizes of ref pic marking do not match.");
176 memcpy(curr_pic_->ref_pic_marking, slice_hdr->ref_pic_marking,
177 sizeof(curr_pic_->ref_pic_marking));
178 }
179
180 return true;
181 }
182
CalculatePicOrderCounts(scoped_refptr<H264Picture> pic)183 bool H264Decoder::CalculatePicOrderCounts(scoped_refptr<H264Picture> pic) {
184 const H264SPS* sps = parser_.GetSPS(curr_sps_id_);
185 if (!sps)
186 return false;
187
188 switch (pic->pic_order_cnt_type) {
189 case 0: {
190 // See spec 8.2.1.1.
191 int prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb;
192
193 if (pic->idr) {
194 prev_pic_order_cnt_msb = prev_pic_order_cnt_lsb = 0;
195 } else {
196 if (prev_ref_has_memmgmnt5_) {
197 if (prev_ref_field_ != H264Picture::FIELD_BOTTOM) {
198 prev_pic_order_cnt_msb = 0;
199 prev_pic_order_cnt_lsb = prev_ref_top_field_order_cnt_;
200 } else {
201 prev_pic_order_cnt_msb = 0;
202 prev_pic_order_cnt_lsb = 0;
203 }
204 } else {
205 prev_pic_order_cnt_msb = prev_ref_pic_order_cnt_msb_;
206 prev_pic_order_cnt_lsb = prev_ref_pic_order_cnt_lsb_;
207 }
208 }
209
210 int max_pic_order_cnt_lsb =
211 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
212 DCHECK_NE(max_pic_order_cnt_lsb, 0);
213 if ((pic->pic_order_cnt_lsb < prev_pic_order_cnt_lsb) &&
214 (prev_pic_order_cnt_lsb - pic->pic_order_cnt_lsb >=
215 max_pic_order_cnt_lsb / 2)) {
216 pic->pic_order_cnt_msb = prev_pic_order_cnt_msb + max_pic_order_cnt_lsb;
217 } else if ((pic->pic_order_cnt_lsb > prev_pic_order_cnt_lsb) &&
218 (pic->pic_order_cnt_lsb - prev_pic_order_cnt_lsb >
219 max_pic_order_cnt_lsb / 2)) {
220 pic->pic_order_cnt_msb = prev_pic_order_cnt_msb - max_pic_order_cnt_lsb;
221 } else {
222 pic->pic_order_cnt_msb = prev_pic_order_cnt_msb;
223 }
224
225 if (pic->field != H264Picture::FIELD_BOTTOM) {
226 pic->top_field_order_cnt =
227 pic->pic_order_cnt_msb + pic->pic_order_cnt_lsb;
228 }
229
230 if (pic->field != H264Picture::FIELD_TOP) {
231 if (pic->field == H264Picture::FIELD_NONE) {
232 pic->bottom_field_order_cnt =
233 pic->top_field_order_cnt + pic->delta_pic_order_cnt_bottom;
234 } else {
235 pic->bottom_field_order_cnt =
236 pic->pic_order_cnt_msb + pic->pic_order_cnt_lsb;
237 }
238 }
239 break;
240 }
241
242 case 1: {
243 // See spec 8.2.1.2.
244 if (prev_has_memmgmnt5_)
245 prev_frame_num_offset_ = 0;
246
247 if (pic->idr)
248 pic->frame_num_offset = 0;
249 else if (prev_frame_num_ > pic->frame_num)
250 pic->frame_num_offset = prev_frame_num_offset_ + max_frame_num_;
251 else
252 pic->frame_num_offset = prev_frame_num_offset_;
253
254 int abs_frame_num = 0;
255 if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
256 abs_frame_num = pic->frame_num_offset + pic->frame_num;
257 else
258 abs_frame_num = 0;
259
260 if (pic->nal_ref_idc == 0 && abs_frame_num > 0)
261 --abs_frame_num;
262
263 int expected_pic_order_cnt = 0;
264 if (abs_frame_num > 0) {
265 if (sps->num_ref_frames_in_pic_order_cnt_cycle == 0) {
266 DVLOG(1) << "Invalid num_ref_frames_in_pic_order_cnt_cycle "
267 << "in stream";
268 return false;
269 }
270
271 int pic_order_cnt_cycle_cnt =
272 (abs_frame_num - 1) / sps->num_ref_frames_in_pic_order_cnt_cycle;
273 int frame_num_in_pic_order_cnt_cycle =
274 (abs_frame_num - 1) % sps->num_ref_frames_in_pic_order_cnt_cycle;
275
276 expected_pic_order_cnt = pic_order_cnt_cycle_cnt *
277 sps->expected_delta_per_pic_order_cnt_cycle;
278 // frame_num_in_pic_order_cnt_cycle is verified < 255 in parser
279 for (int i = 0; i <= frame_num_in_pic_order_cnt_cycle; ++i)
280 expected_pic_order_cnt += sps->offset_for_ref_frame[i];
281 }
282
283 if (!pic->nal_ref_idc)
284 expected_pic_order_cnt += sps->offset_for_non_ref_pic;
285
286 if (pic->field == H264Picture::FIELD_NONE) {
287 pic->top_field_order_cnt =
288 expected_pic_order_cnt + pic->delta_pic_order_cnt0;
289 pic->bottom_field_order_cnt = pic->top_field_order_cnt +
290 sps->offset_for_top_to_bottom_field +
291 pic->delta_pic_order_cnt1;
292 } else if (pic->field != H264Picture::FIELD_BOTTOM) {
293 pic->top_field_order_cnt =
294 expected_pic_order_cnt + pic->delta_pic_order_cnt0;
295 } else {
296 pic->bottom_field_order_cnt = expected_pic_order_cnt +
297 sps->offset_for_top_to_bottom_field +
298 pic->delta_pic_order_cnt0;
299 }
300 break;
301 }
302
303 case 2: {
304 // See spec 8.2.1.3.
305 if (prev_has_memmgmnt5_)
306 prev_frame_num_offset_ = 0;
307
308 if (pic->idr)
309 pic->frame_num_offset = 0;
310 else if (prev_frame_num_ > pic->frame_num)
311 pic->frame_num_offset = prev_frame_num_offset_ + max_frame_num_;
312 else
313 pic->frame_num_offset = prev_frame_num_offset_;
314
315 int temp_pic_order_cnt;
316 if (pic->idr) {
317 temp_pic_order_cnt = 0;
318 } else if (!pic->nal_ref_idc) {
319 temp_pic_order_cnt = 2 * (pic->frame_num_offset + pic->frame_num) - 1;
320 } else {
321 temp_pic_order_cnt = 2 * (pic->frame_num_offset + pic->frame_num);
322 }
323
324 if (pic->field == H264Picture::FIELD_NONE) {
325 pic->top_field_order_cnt = temp_pic_order_cnt;
326 pic->bottom_field_order_cnt = temp_pic_order_cnt;
327 } else if (pic->field == H264Picture::FIELD_BOTTOM) {
328 pic->bottom_field_order_cnt = temp_pic_order_cnt;
329 } else {
330 pic->top_field_order_cnt = temp_pic_order_cnt;
331 }
332 break;
333 }
334
335 default:
336 DVLOG(1) << "Invalid pic_order_cnt_type: " << sps->pic_order_cnt_type;
337 return false;
338 }
339
340 switch (pic->field) {
341 case H264Picture::FIELD_NONE:
342 pic->pic_order_cnt =
343 std::min(pic->top_field_order_cnt, pic->bottom_field_order_cnt);
344 break;
345 case H264Picture::FIELD_TOP:
346 pic->pic_order_cnt = pic->top_field_order_cnt;
347 break;
348 case H264Picture::FIELD_BOTTOM:
349 pic->pic_order_cnt = pic->bottom_field_order_cnt;
350 break;
351 }
352
353 return true;
354 }
355
UpdatePicNums(int frame_num)356 void H264Decoder::UpdatePicNums(int frame_num) {
357 for (auto& pic : dpb_) {
358 if (!pic->ref)
359 continue;
360
361 // 8.2.4.1. Assumes non-interlaced stream.
362 DCHECK_EQ(pic->field, H264Picture::FIELD_NONE);
363 if (pic->long_term) {
364 pic->long_term_pic_num = pic->long_term_frame_idx;
365 } else {
366 if (pic->frame_num > frame_num)
367 pic->frame_num_wrap = pic->frame_num - max_frame_num_;
368 else
369 pic->frame_num_wrap = pic->frame_num;
370
371 pic->pic_num = pic->frame_num_wrap;
372 }
373 }
374 }
375
376 struct PicNumDescCompare {
operator ()media::PicNumDescCompare377 bool operator()(const scoped_refptr<H264Picture>& a,
378 const scoped_refptr<H264Picture>& b) const {
379 return a->pic_num > b->pic_num;
380 }
381 };
382
383 struct LongTermPicNumAscCompare {
operator ()media::LongTermPicNumAscCompare384 bool operator()(const scoped_refptr<H264Picture>& a,
385 const scoped_refptr<H264Picture>& b) const {
386 return a->long_term_pic_num < b->long_term_pic_num;
387 }
388 };
389
ConstructReferencePicListsP(const H264SliceHeader * slice_hdr)390 void H264Decoder::ConstructReferencePicListsP(
391 const H264SliceHeader* slice_hdr) {
392 // RefPicList0 (8.2.4.2.1) [[1] [2]], where:
393 // [1] shortterm ref pics sorted by descending pic_num,
394 // [2] longterm ref pics by ascending long_term_pic_num.
395 ref_pic_list_p0_.clear();
396
397 // First get the short ref pics...
398 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_p0_);
399 size_t num_short_refs = ref_pic_list_p0_.size();
400
401 // and sort them to get [1].
402 std::sort(ref_pic_list_p0_.begin(), ref_pic_list_p0_.end(),
403 PicNumDescCompare());
404
405 // Now get long term pics and sort them by long_term_pic_num to get [2].
406 dpb_.GetLongTermRefPicsAppending(&ref_pic_list_p0_);
407 std::sort(ref_pic_list_p0_.begin() + num_short_refs, ref_pic_list_p0_.end(),
408 LongTermPicNumAscCompare());
409 }
410
411 struct POCAscCompare {
operator ()media::POCAscCompare412 bool operator()(const scoped_refptr<H264Picture>& a,
413 const scoped_refptr<H264Picture>& b) const {
414 return a->pic_order_cnt < b->pic_order_cnt;
415 }
416 };
417
418 struct POCDescCompare {
operator ()media::POCDescCompare419 bool operator()(const scoped_refptr<H264Picture>& a,
420 const scoped_refptr<H264Picture>& b) const {
421 return a->pic_order_cnt > b->pic_order_cnt;
422 }
423 };
424
ConstructReferencePicListsB(const H264SliceHeader * slice_hdr)425 void H264Decoder::ConstructReferencePicListsB(
426 const H264SliceHeader* slice_hdr) {
427 // RefPicList0 (8.2.4.2.3) [[1] [2] [3]], where:
428 // [1] shortterm ref pics with POC < curr_pic's POC sorted by descending POC,
429 // [2] shortterm ref pics with POC > curr_pic's POC by ascending POC,
430 // [3] longterm ref pics by ascending long_term_pic_num.
431 ref_pic_list_b0_.clear();
432 ref_pic_list_b1_.clear();
433 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_b0_);
434 size_t num_short_refs = ref_pic_list_b0_.size();
435
436 // First sort ascending, this will put [1] in right place and finish [2].
437 std::sort(ref_pic_list_b0_.begin(), ref_pic_list_b0_.end(), POCAscCompare());
438
439 // Find first with POC > curr_pic's POC to get first element in [2]...
440 H264Picture::Vector::iterator iter;
441 iter = std::upper_bound(ref_pic_list_b0_.begin(), ref_pic_list_b0_.end(),
442 curr_pic_.get(), POCAscCompare());
443
444 // and sort [1] descending, thus finishing sequence [1] [2].
445 std::sort(ref_pic_list_b0_.begin(), iter, POCDescCompare());
446
447 // Now add [3] and sort by ascending long_term_pic_num.
448 dpb_.GetLongTermRefPicsAppending(&ref_pic_list_b0_);
449 std::sort(ref_pic_list_b0_.begin() + num_short_refs, ref_pic_list_b0_.end(),
450 LongTermPicNumAscCompare());
451
452 // RefPicList1 (8.2.4.2.4) [[1] [2] [3]], where:
453 // [1] shortterm ref pics with POC > curr_pic's POC sorted by ascending POC,
454 // [2] shortterm ref pics with POC < curr_pic's POC by descending POC,
455 // [3] longterm ref pics by ascending long_term_pic_num.
456
457 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_b1_);
458 num_short_refs = ref_pic_list_b1_.size();
459
460 // First sort by descending POC.
461 std::sort(ref_pic_list_b1_.begin(), ref_pic_list_b1_.end(), POCDescCompare());
462
463 // Find first with POC < curr_pic's POC to get first element in [2]...
464 iter = std::upper_bound(ref_pic_list_b1_.begin(), ref_pic_list_b1_.end(),
465 curr_pic_.get(), POCDescCompare());
466
467 // and sort [1] ascending.
468 std::sort(ref_pic_list_b1_.begin(), iter, POCAscCompare());
469
470 // Now add [3] and sort by ascending long_term_pic_num
471 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_b1_);
472 std::sort(ref_pic_list_b1_.begin() + num_short_refs, ref_pic_list_b1_.end(),
473 LongTermPicNumAscCompare());
474
475 // If lists identical, swap first two entries in RefPicList1 (spec 8.2.4.2.3)
476 if (ref_pic_list_b1_.size() > 1 &&
477 std::equal(ref_pic_list_b0_.begin(), ref_pic_list_b0_.end(),
478 ref_pic_list_b1_.begin()))
479 std::swap(ref_pic_list_b1_[0], ref_pic_list_b1_[1]);
480 }
481
482 // See 8.2.4
PicNumF(const scoped_refptr<H264Picture> & pic)483 int H264Decoder::PicNumF(const scoped_refptr<H264Picture>& pic) {
484 if (!pic)
485 return -1;
486
487 if (!pic->long_term)
488 return pic->pic_num;
489 else
490 return max_pic_num_;
491 }
492
493 // See 8.2.4
LongTermPicNumF(const scoped_refptr<H264Picture> & pic)494 int H264Decoder::LongTermPicNumF(const scoped_refptr<H264Picture>& pic) {
495 if (pic->ref && pic->long_term)
496 return pic->long_term_pic_num;
497 else
498 return 2 * (max_long_term_frame_idx_ + 1);
499 }
500
501 // Shift elements on the |v| starting from |from| to |to|, inclusive,
502 // one position to the right and insert pic at |from|.
ShiftRightAndInsert(H264Picture::Vector * v,int from,int to,const scoped_refptr<H264Picture> & pic)503 static void ShiftRightAndInsert(H264Picture::Vector* v,
504 int from,
505 int to,
506 const scoped_refptr<H264Picture>& pic) {
507 // Security checks, do not disable in Debug mode.
508 CHECK(from <= to);
509 CHECK(to <= std::numeric_limits<int>::max() - 2);
510 // Additional checks. Debug mode ok.
511 DCHECK(v);
512 DCHECK(pic);
513 DCHECK((to + 1 == static_cast<int>(v->size())) ||
514 (to + 2 == static_cast<int>(v->size())));
515
516 v->resize(to + 2);
517
518 for (int i = to + 1; i > from; --i)
519 (*v)[i] = (*v)[i - 1];
520
521 (*v)[from] = pic;
522 }
523
ModifyReferencePicList(const H264SliceHeader * slice_hdr,int list,H264Picture::Vector * ref_pic_listx)524 bool H264Decoder::ModifyReferencePicList(const H264SliceHeader* slice_hdr,
525 int list,
526 H264Picture::Vector* ref_pic_listx) {
527 bool ref_pic_list_modification_flag_lX;
528 int num_ref_idx_lX_active_minus1;
529 const H264ModificationOfPicNum* list_mod;
530
531 // This can process either ref_pic_list0 or ref_pic_list1, depending on
532 // the list argument. Set up pointers to proper list to be processed here.
533 if (list == 0) {
534 ref_pic_list_modification_flag_lX =
535 slice_hdr->ref_pic_list_modification_flag_l0;
536 num_ref_idx_lX_active_minus1 = slice_hdr->num_ref_idx_l0_active_minus1;
537 list_mod = slice_hdr->ref_list_l0_modifications;
538 } else {
539 ref_pic_list_modification_flag_lX =
540 slice_hdr->ref_pic_list_modification_flag_l1;
541 num_ref_idx_lX_active_minus1 = slice_hdr->num_ref_idx_l1_active_minus1;
542 list_mod = slice_hdr->ref_list_l1_modifications;
543 }
544
545 // Resize the list to the size requested in the slice header.
546 // Note that per 8.2.4.2 it's possible for num_ref_idx_lX_active_minus1 to
547 // indicate there should be more ref pics on list than we constructed.
548 // Those superfluous ones should be treated as non-reference and will be
549 // initialized to nullptr, which must be handled by clients.
550 DCHECK_GE(num_ref_idx_lX_active_minus1, 0);
551 ref_pic_listx->resize(num_ref_idx_lX_active_minus1 + 1);
552
553 if (!ref_pic_list_modification_flag_lX)
554 return true;
555
556 // Spec 8.2.4.3:
557 // Reorder pictures on the list in a way specified in the stream.
558 int pic_num_lx_pred = curr_pic_->pic_num;
559 int ref_idx_lx = 0;
560 int pic_num_lx_no_wrap;
561 int pic_num_lx;
562 bool done = false;
563 scoped_refptr<H264Picture> pic;
564 for (int i = 0; i < H264SliceHeader::kRefListModSize && !done; ++i) {
565 switch (list_mod->modification_of_pic_nums_idc) {
566 case 0:
567 case 1:
568 // Modify short reference picture position.
569 if (list_mod->modification_of_pic_nums_idc == 0) {
570 // Subtract given value from predicted PicNum.
571 pic_num_lx_no_wrap =
572 pic_num_lx_pred -
573 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1);
574 // Wrap around max_pic_num_ if it becomes < 0 as result
575 // of subtraction.
576 if (pic_num_lx_no_wrap < 0)
577 pic_num_lx_no_wrap += max_pic_num_;
578 } else {
579 // Add given value to predicted PicNum.
580 pic_num_lx_no_wrap =
581 pic_num_lx_pred +
582 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1);
583 // Wrap around max_pic_num_ if it becomes >= max_pic_num_ as result
584 // of the addition.
585 if (pic_num_lx_no_wrap >= max_pic_num_)
586 pic_num_lx_no_wrap -= max_pic_num_;
587 }
588
589 // For use in next iteration.
590 pic_num_lx_pred = pic_num_lx_no_wrap;
591
592 if (pic_num_lx_no_wrap > curr_pic_->pic_num)
593 pic_num_lx = pic_num_lx_no_wrap - max_pic_num_;
594 else
595 pic_num_lx = pic_num_lx_no_wrap;
596
597 DCHECK_LT(num_ref_idx_lX_active_minus1 + 1,
598 H264SliceHeader::kRefListModSize);
599 pic = dpb_.GetShortRefPicByPicNum(pic_num_lx);
600 if (!pic) {
601 DVLOG(1) << "Malformed stream, no pic num " << pic_num_lx;
602 return false;
603 }
604 ShiftRightAndInsert(ref_pic_listx, ref_idx_lx,
605 num_ref_idx_lX_active_minus1, pic);
606 ref_idx_lx++;
607
608 for (int src = ref_idx_lx, dst = ref_idx_lx;
609 src <= num_ref_idx_lX_active_minus1 + 1; ++src) {
610 if (PicNumF((*ref_pic_listx)[src]) != pic_num_lx)
611 (*ref_pic_listx)[dst++] = (*ref_pic_listx)[src];
612 }
613 break;
614
615 case 2:
616 // Modify long term reference picture position.
617 DCHECK_LT(num_ref_idx_lX_active_minus1 + 1,
618 H264SliceHeader::kRefListModSize);
619 pic = dpb_.GetLongRefPicByLongTermPicNum(list_mod->long_term_pic_num);
620 if (!pic) {
621 DVLOG(1) << "Malformed stream, no pic num "
622 << list_mod->long_term_pic_num;
623 return false;
624 }
625 ShiftRightAndInsert(ref_pic_listx, ref_idx_lx,
626 num_ref_idx_lX_active_minus1, pic);
627 ref_idx_lx++;
628
629 for (int src = ref_idx_lx, dst = ref_idx_lx;
630 src <= num_ref_idx_lX_active_minus1 + 1; ++src) {
631 if (LongTermPicNumF((*ref_pic_listx)[src]) !=
632 static_cast<int>(list_mod->long_term_pic_num))
633 (*ref_pic_listx)[dst++] = (*ref_pic_listx)[src];
634 }
635 break;
636
637 case 3:
638 // End of modification list.
639 done = true;
640 break;
641
642 default:
643 // May be recoverable.
644 DVLOG(1) << "Invalid modification_of_pic_nums_idc="
645 << list_mod->modification_of_pic_nums_idc
646 << " in position " << i;
647 break;
648 }
649
650 ++list_mod;
651 }
652
653 // Per NOTE 2 in 8.2.4.3.2, the ref_pic_listx size in the above loop is
654 // temporarily made one element longer than the required final list.
655 // Resize the list back to its required size.
656 ref_pic_listx->resize(num_ref_idx_lX_active_minus1 + 1);
657
658 return true;
659 }
660
OutputPic(scoped_refptr<H264Picture> pic)661 void H264Decoder::OutputPic(scoped_refptr<H264Picture> pic) {
662 DCHECK(!pic->outputted);
663 pic->outputted = true;
664
665 if (pic->nonexisting) {
666 DVLOG(4) << "Skipping output, non-existing frame_num: " << pic->frame_num;
667 return;
668 }
669
670 DVLOG_IF(1, pic->pic_order_cnt < last_output_poc_)
671 << "Outputting out of order, likely a broken stream: "
672 << last_output_poc_ << " -> " << pic->pic_order_cnt;
673 last_output_poc_ = pic->pic_order_cnt;
674
675 DVLOG(4) << "Posting output task for POC: " << pic->pic_order_cnt;
676 accelerator_->OutputPicture(pic);
677 }
678
ClearDPB()679 void H264Decoder::ClearDPB() {
680 // Clear DPB contents, marking the pictures as unused first.
681 dpb_.Clear();
682 last_output_poc_ = std::numeric_limits<int>::min();
683 }
684
OutputAllRemainingPics()685 bool H264Decoder::OutputAllRemainingPics() {
686 // Output all pictures that are waiting to be outputted.
687 FinishPrevFrameIfPresent();
688 H264Picture::Vector to_output;
689 dpb_.GetNotOutputtedPicsAppending(&to_output);
690 // Sort them by ascending POC to output in order.
691 std::sort(to_output.begin(), to_output.end(), POCAscCompare());
692
693 for (auto& pic : to_output)
694 OutputPic(pic);
695
696 return true;
697 }
698
Flush()699 bool H264Decoder::Flush() {
700 DVLOG(2) << "Decoder flush";
701
702 if (!OutputAllRemainingPics())
703 return false;
704
705 ClearDPB();
706 DVLOG(2) << "Decoder flush finished";
707 return true;
708 }
709
StartNewFrame(const H264SliceHeader * slice_hdr)710 bool H264Decoder::StartNewFrame(const H264SliceHeader* slice_hdr) {
711 // TODO posciak: add handling of max_num_ref_frames per spec.
712 CHECK(curr_pic_.get());
713 DCHECK(slice_hdr);
714
715 curr_pps_id_ = slice_hdr->pic_parameter_set_id;
716 const H264PPS* pps = parser_.GetPPS(curr_pps_id_);
717 if (!pps)
718 return false;
719
720 curr_sps_id_ = pps->seq_parameter_set_id;
721 const H264SPS* sps = parser_.GetSPS(curr_sps_id_);
722 if (!sps)
723 return false;
724
725 max_frame_num_ = 1 << (sps->log2_max_frame_num_minus4 + 4);
726 int frame_num = slice_hdr->frame_num;
727 if (slice_hdr->idr_pic_flag)
728 prev_ref_frame_num_ = 0;
729
730 // 7.4.3
731 if (frame_num != prev_ref_frame_num_ &&
732 frame_num != (prev_ref_frame_num_ + 1) % max_frame_num_) {
733 if (!HandleFrameNumGap(frame_num))
734 return false;
735 }
736
737 if (!InitCurrPicture(slice_hdr))
738 return false;
739
740 UpdatePicNums(frame_num);
741 PrepareRefPicLists(slice_hdr);
742
743 if (!accelerator_->SubmitFrameMetadata(sps, pps, dpb_, ref_pic_list_p0_,
744 ref_pic_list_b0_, ref_pic_list_b1_,
745 curr_pic_.get()))
746 return false;
747
748 return true;
749 }
750
HandleMemoryManagementOps(scoped_refptr<H264Picture> pic)751 bool H264Decoder::HandleMemoryManagementOps(scoped_refptr<H264Picture> pic) {
752 // 8.2.5.4
753 for (size_t i = 0; i < arraysize(pic->ref_pic_marking); ++i) {
754 // Code below does not support interlaced stream (per-field pictures).
755 H264DecRefPicMarking* ref_pic_marking = &pic->ref_pic_marking[i];
756 scoped_refptr<H264Picture> to_mark;
757 int pic_num_x;
758
759 switch (ref_pic_marking->memory_mgmnt_control_operation) {
760 case 0:
761 // Normal end of operations' specification.
762 return true;
763
764 case 1:
765 // Mark a short term reference picture as unused so it can be removed
766 // if outputted.
767 pic_num_x =
768 pic->pic_num - (ref_pic_marking->difference_of_pic_nums_minus1 + 1);
769 to_mark = dpb_.GetShortRefPicByPicNum(pic_num_x);
770 if (to_mark) {
771 to_mark->ref = false;
772 } else {
773 DVLOG(1) << "Invalid short ref pic num to unmark";
774 return false;
775 }
776 break;
777
778 case 2:
779 // Mark a long term reference picture as unused so it can be removed
780 // if outputted.
781 to_mark = dpb_.GetLongRefPicByLongTermPicNum(
782 ref_pic_marking->long_term_pic_num);
783 if (to_mark) {
784 to_mark->ref = false;
785 } else {
786 DVLOG(1) << "Invalid long term ref pic num to unmark";
787 return false;
788 }
789 break;
790
791 case 3:
792 // Mark a short term reference picture as long term reference.
793 pic_num_x =
794 pic->pic_num - (ref_pic_marking->difference_of_pic_nums_minus1 + 1);
795 to_mark = dpb_.GetShortRefPicByPicNum(pic_num_x);
796 if (to_mark) {
797 DCHECK(to_mark->ref && !to_mark->long_term);
798 to_mark->long_term = true;
799 to_mark->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
800 } else {
801 DVLOG(1) << "Invalid short term ref pic num to mark as long ref";
802 return false;
803 }
804 break;
805
806 case 4: {
807 // Unmark all reference pictures with long_term_frame_idx over new max.
808 max_long_term_frame_idx_ =
809 ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
810 H264Picture::Vector long_terms;
811 dpb_.GetLongTermRefPicsAppending(&long_terms);
812 for (size_t i = 0; i < long_terms.size(); ++i) {
813 scoped_refptr<H264Picture>& long_term_pic = long_terms[i];
814 DCHECK(long_term_pic->ref && long_term_pic->long_term);
815 // Ok to cast, max_long_term_frame_idx is much smaller than 16bit.
816 if (long_term_pic->long_term_frame_idx >
817 static_cast<int>(max_long_term_frame_idx_))
818 long_term_pic->ref = false;
819 }
820 break;
821 }
822
823 case 5:
824 // Unmark all reference pictures.
825 dpb_.MarkAllUnusedForRef();
826 max_long_term_frame_idx_ = -1;
827 pic->mem_mgmt_5 = true;
828 break;
829
830 case 6: {
831 // Replace long term reference pictures with current picture.
832 // First unmark if any existing with this long_term_frame_idx...
833 H264Picture::Vector long_terms;
834 dpb_.GetLongTermRefPicsAppending(&long_terms);
835 for (size_t i = 0; i < long_terms.size(); ++i) {
836 scoped_refptr<H264Picture>& long_term_pic = long_terms[i];
837 DCHECK(long_term_pic->ref && long_term_pic->long_term);
838 // Ok to cast, long_term_frame_idx is much smaller than 16bit.
839 if (long_term_pic->long_term_frame_idx ==
840 static_cast<int>(ref_pic_marking->long_term_frame_idx))
841 long_term_pic->ref = false;
842 }
843
844 // and mark the current one instead.
845 pic->ref = true;
846 pic->long_term = true;
847 pic->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
848 break;
849 }
850
851 default:
852 // Would indicate a bug in parser.
853 NOTREACHED();
854 }
855 }
856
857 return true;
858 }
859
860 // This method ensures that DPB does not overflow, either by removing
861 // reference pictures as specified in the stream, or using a sliding window
862 // procedure to remove the oldest one.
863 // It also performs marking and unmarking pictures as reference.
864 // See spac 8.2.5.1.
ReferencePictureMarking(scoped_refptr<H264Picture> pic)865 bool H264Decoder::ReferencePictureMarking(scoped_refptr<H264Picture> pic) {
866 // If the current picture is an IDR, all reference pictures are unmarked.
867 if (pic->idr) {
868 dpb_.MarkAllUnusedForRef();
869
870 if (pic->long_term_reference_flag) {
871 pic->long_term = true;
872 pic->long_term_frame_idx = 0;
873 max_long_term_frame_idx_ = 0;
874 } else {
875 pic->long_term = false;
876 max_long_term_frame_idx_ = -1;
877 }
878
879 return true;
880 }
881
882 // Not an IDR. If the stream contains instructions on how to discard pictures
883 // from DPB and how to mark/unmark existing reference pictures, do so.
884 // Otherwise, fall back to default sliding window process.
885 if (pic->adaptive_ref_pic_marking_mode_flag) {
886 DCHECK(!pic->nonexisting);
887 return HandleMemoryManagementOps(pic);
888 } else {
889 return SlidingWindowPictureMarking();
890 }
891 }
892
SlidingWindowPictureMarking()893 bool H264Decoder::SlidingWindowPictureMarking() {
894 const H264SPS* sps = parser_.GetSPS(curr_sps_id_);
895 if (!sps)
896 return false;
897
898 // 8.2.5.3. Ensure the DPB doesn't overflow by discarding the oldest picture.
899 int num_ref_pics = dpb_.CountRefPics();
900 DCHECK_LE(num_ref_pics, std::max<int>(sps->max_num_ref_frames, 1));
901 if (num_ref_pics == std::max<int>(sps->max_num_ref_frames, 1)) {
902 // Max number of reference pics reached, need to remove one of the short
903 // term ones. Find smallest frame_num_wrap short reference picture and mark
904 // it as unused.
905 scoped_refptr<H264Picture> to_unmark =
906 dpb_.GetLowestFrameNumWrapShortRefPic();
907 if (!to_unmark) {
908 DVLOG(1) << "Couldn't find a short ref picture to unmark";
909 return false;
910 }
911
912 to_unmark->ref = false;
913 }
914
915 return true;
916 }
917
FinishPicture(scoped_refptr<H264Picture> pic)918 bool H264Decoder::FinishPicture(scoped_refptr<H264Picture> pic) {
919 // Finish processing the picture.
920 // Start by storing previous picture data for later use.
921 if (pic->ref) {
922 ReferencePictureMarking(pic);
923 prev_ref_has_memmgmnt5_ = pic->mem_mgmt_5;
924 prev_ref_top_field_order_cnt_ = pic->top_field_order_cnt;
925 prev_ref_pic_order_cnt_msb_ = pic->pic_order_cnt_msb;
926 prev_ref_pic_order_cnt_lsb_ = pic->pic_order_cnt_lsb;
927 prev_ref_field_ = pic->field;
928 prev_ref_frame_num_ = pic->frame_num;
929 }
930 prev_frame_num_ = pic->frame_num;
931 prev_has_memmgmnt5_ = pic->mem_mgmt_5;
932 prev_frame_num_offset_ = pic->frame_num_offset;
933
934 // Remove unused (for reference or later output) pictures from DPB, marking
935 // them as such.
936 dpb_.DeleteUnused();
937
938 DVLOG(4) << "Finishing picture frame_num: " << pic->frame_num
939 << ", entries in DPB: " << dpb_.size();
940
941 // The ownership of pic will either be transferred to DPB - if the picture is
942 // still needed (for output and/or reference) - or we will release it
943 // immediately if we manage to output it here and won't have to store it for
944 // future reference.
945
946 // Get all pictures that haven't been outputted yet.
947 H264Picture::Vector not_outputted;
948 dpb_.GetNotOutputtedPicsAppending(¬_outputted);
949 // Include the one we've just decoded.
950 not_outputted.push_back(pic);
951
952 // Sort in output order.
953 std::sort(not_outputted.begin(), not_outputted.end(), POCAscCompare());
954
955 // Try to output as many pictures as we can. A picture can be output,
956 // if the number of decoded and not yet outputted pictures that would remain
957 // in DPB afterwards would at least be equal to max_num_reorder_frames.
958 // If the outputted picture is not a reference picture, it doesn't have
959 // to remain in the DPB and can be removed.
960 H264Picture::Vector::iterator output_candidate = not_outputted.begin();
961 size_t num_remaining = not_outputted.size();
962 while (num_remaining > max_num_reorder_frames_ ||
963 // If the condition below is used, this is an invalid stream. We should
964 // not be forced to output beyond max_num_reorder_frames in order to
965 // make room in DPB to store the current picture (if we need to do so).
966 // However, if this happens, ignore max_num_reorder_frames and try
967 // to output more. This may cause out-of-order output, but is not
968 // fatal, and better than failing instead.
969 ((dpb_.IsFull() && (!pic->outputted || pic->ref)) && num_remaining)) {
970 DVLOG_IF(1, num_remaining <= max_num_reorder_frames_)
971 << "Invalid stream: max_num_reorder_frames not preserved";
972
973 OutputPic(*output_candidate);
974
975 if (!(*output_candidate)->ref) {
976 // Current picture hasn't been inserted into DPB yet, so don't remove it
977 // if we managed to output it immediately.
978 int outputted_poc = (*output_candidate)->pic_order_cnt;
979 if (outputted_poc != pic->pic_order_cnt)
980 dpb_.DeleteByPOC(outputted_poc);
981 }
982
983 ++output_candidate;
984 --num_remaining;
985 }
986
987 // If we haven't managed to output the picture that we just decoded, or if
988 // it's a reference picture, we have to store it in DPB.
989 if (!pic->outputted || pic->ref) {
990 if (dpb_.IsFull()) {
991 // If we haven't managed to output anything to free up space in DPB
992 // to store this picture, it's an error in the stream.
993 DVLOG(1) << "Could not free up space in DPB!";
994 return false;
995 }
996
997 dpb_.StorePic(pic);
998 }
999
1000 return true;
1001 }
1002
LevelToMaxDpbMbs(int level)1003 static int LevelToMaxDpbMbs(int level) {
1004 // See table A-1 in spec.
1005 switch (level) {
1006 case 10:
1007 return 396;
1008 case 11:
1009 return 900;
1010 case 12: // fallthrough
1011 case 13: // fallthrough
1012 case 20:
1013 return 2376;
1014 case 21:
1015 return 4752;
1016 case 22: // fallthrough
1017 case 30:
1018 return 8100;
1019 case 31:
1020 return 18000;
1021 case 32:
1022 return 20480;
1023 case 40: // fallthrough
1024 case 41:
1025 return 32768;
1026 case 42:
1027 return 34816;
1028 case 50:
1029 return 110400;
1030 case 51: // fallthrough
1031 case 52:
1032 return 184320;
1033 default:
1034 DVLOG(1) << "Invalid codec level (" << level << ")";
1035 return 0;
1036 }
1037 }
1038
UpdateMaxNumReorderFrames(const H264SPS * sps)1039 bool H264Decoder::UpdateMaxNumReorderFrames(const H264SPS* sps) {
1040 if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) {
1041 max_num_reorder_frames_ =
1042 base::checked_cast<size_t>(sps->max_num_reorder_frames);
1043 if (max_num_reorder_frames_ > dpb_.max_num_pics()) {
1044 DVLOG(1)
1045 << "max_num_reorder_frames present, but larger than MaxDpbFrames ("
1046 << max_num_reorder_frames_ << " > " << dpb_.max_num_pics() << ")";
1047 max_num_reorder_frames_ = 0;
1048 return false;
1049 }
1050 return true;
1051 }
1052
1053 // max_num_reorder_frames not present, infer from profile/constraints
1054 // (see VUI semantics in spec).
1055 if (sps->constraint_set3_flag) {
1056 switch (sps->profile_idc) {
1057 case 44:
1058 case 86:
1059 case 100:
1060 case 110:
1061 case 122:
1062 case 244:
1063 max_num_reorder_frames_ = 0;
1064 break;
1065 default:
1066 max_num_reorder_frames_ = dpb_.max_num_pics();
1067 break;
1068 }
1069 } else {
1070 max_num_reorder_frames_ = dpb_.max_num_pics();
1071 }
1072
1073 return true;
1074 }
1075
ProcessSPS(int sps_id,bool * need_new_buffers)1076 bool H264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) {
1077 DVLOG(4) << "Processing SPS id:" << sps_id;
1078
1079 const H264SPS* sps = parser_.GetSPS(sps_id);
1080 if (!sps)
1081 return false;
1082
1083 *need_new_buffers = false;
1084
1085 if (sps->frame_mbs_only_flag == 0) {
1086 DVLOG(1) << "frame_mbs_only_flag != 1 not supported";
1087 return false;
1088 }
1089
1090 Size new_pic_size = sps->GetCodedSize().value_or(Size());
1091 if (new_pic_size.IsEmpty()) {
1092 DVLOG(1) << "Invalid picture size";
1093 return false;
1094 }
1095
1096 int width_mb = new_pic_size.width() / 16;
1097 int height_mb = new_pic_size.height() / 16;
1098
1099 // Verify that the values are not too large before multiplying.
1100 if (std::numeric_limits<int>::max() / width_mb < height_mb) {
1101 DVLOG(1) << "Picture size is too big: " << new_pic_size.ToString();
1102 return false;
1103 }
1104
1105 int level = sps->level_idc;
1106 int max_dpb_mbs = LevelToMaxDpbMbs(level);
1107 if (max_dpb_mbs == 0)
1108 return false;
1109
1110 size_t max_dpb_size = std::min(max_dpb_mbs / (width_mb * height_mb),
1111 static_cast<int>(H264DPB::kDPBMaxSize));
1112 if (max_dpb_size == 0) {
1113 DVLOG(1) << "Invalid DPB Size";
1114 return false;
1115 }
1116
1117 if ((pic_size_ != new_pic_size) || (dpb_.max_num_pics() != max_dpb_size)) {
1118 if (!Flush())
1119 return false;
1120 DVLOG(1) << "Codec level: " << level << ", DPB size: " << max_dpb_size
1121 << ", Picture size: " << new_pic_size.ToString();
1122 *need_new_buffers = true;
1123 pic_size_ = new_pic_size;
1124 dpb_.set_max_num_pics(max_dpb_size);
1125 }
1126
1127 if (!UpdateMaxNumReorderFrames(sps))
1128 return false;
1129 DVLOG(1) << "max_num_reorder_frames: " << max_num_reorder_frames_;
1130
1131 return true;
1132 }
1133
FinishPrevFrameIfPresent()1134 bool H264Decoder::FinishPrevFrameIfPresent() {
1135 // If we already have a frame waiting to be decoded, decode it and finish.
1136 if (curr_pic_) {
1137 if (!DecodePicture())
1138 return false;
1139
1140 scoped_refptr<H264Picture> pic = curr_pic_;
1141 curr_pic_ = nullptr;
1142 return FinishPicture(pic);
1143 }
1144
1145 return true;
1146 }
1147
HandleFrameNumGap(int frame_num)1148 bool H264Decoder::HandleFrameNumGap(int frame_num) {
1149 const H264SPS* sps = parser_.GetSPS(curr_sps_id_);
1150 if (!sps)
1151 return false;
1152
1153 if (!sps->gaps_in_frame_num_value_allowed_flag) {
1154 DVLOG(1) << "Invalid frame_num: " << frame_num;
1155 return false;
1156 }
1157
1158 DVLOG(2) << "Handling frame_num gap: " << prev_ref_frame_num_ << "->"
1159 << frame_num;
1160
1161 // 7.4.3/7-23
1162 int unused_short_term_frame_num = (prev_ref_frame_num_ + 1) % max_frame_num_;
1163 while (unused_short_term_frame_num != frame_num) {
1164 scoped_refptr<H264Picture> pic = new H264Picture();
1165 if (!InitNonexistingPicture(pic, unused_short_term_frame_num))
1166 return false;
1167
1168 UpdatePicNums(unused_short_term_frame_num);
1169
1170 if (!FinishPicture(pic))
1171 return false;
1172
1173 unused_short_term_frame_num++;
1174 unused_short_term_frame_num %= max_frame_num_;
1175 }
1176
1177 return true;
1178 }
1179
IsNewPrimaryCodedPicture(const H264SliceHeader * slice_hdr) const1180 bool H264Decoder::IsNewPrimaryCodedPicture(
1181 const H264SliceHeader* slice_hdr) const {
1182 if (!curr_pic_)
1183 return true;
1184
1185 // 7.4.1.2.4, assumes non-interlaced.
1186 if (slice_hdr->frame_num != curr_pic_->frame_num ||
1187 slice_hdr->pic_parameter_set_id != curr_pps_id_ ||
1188 slice_hdr->nal_ref_idc != curr_pic_->nal_ref_idc ||
1189 slice_hdr->idr_pic_flag != curr_pic_->idr ||
1190 (slice_hdr->idr_pic_flag &&
1191 (slice_hdr->idr_pic_id != curr_pic_->idr_pic_id ||
1192 // If we have two consecutive IDR slices, and the second one has
1193 // first_mb_in_slice == 0, treat it as a new picture.
1194 // Per spec, idr_pic_id should not be equal in this case (and we should
1195 // have hit the condition above instead, see spec 7.4.3 on idr_pic_id),
1196 // but some encoders neglect changing idr_pic_id for two consecutive
1197 // IDRs. Work around this by checking if the next slice contains the
1198 // zeroth macroblock, i.e. data that belongs to the next picture.
1199 slice_hdr->first_mb_in_slice == 0)))
1200 return true;
1201
1202 const H264SPS* sps = parser_.GetSPS(curr_sps_id_);
1203 if (!sps)
1204 return false;
1205
1206 if (sps->pic_order_cnt_type == curr_pic_->pic_order_cnt_type) {
1207 if (curr_pic_->pic_order_cnt_type == 0) {
1208 if (slice_hdr->pic_order_cnt_lsb != curr_pic_->pic_order_cnt_lsb ||
1209 slice_hdr->delta_pic_order_cnt_bottom !=
1210 curr_pic_->delta_pic_order_cnt_bottom)
1211 return true;
1212 } else if (curr_pic_->pic_order_cnt_type == 1) {
1213 if (slice_hdr->delta_pic_order_cnt0 != curr_pic_->delta_pic_order_cnt0 ||
1214 slice_hdr->delta_pic_order_cnt1 != curr_pic_->delta_pic_order_cnt1)
1215 return true;
1216 }
1217 }
1218
1219 return false;
1220 }
1221
PreprocessCurrentSlice()1222 bool H264Decoder::PreprocessCurrentSlice() {
1223 const H264SliceHeader* slice_hdr = curr_slice_hdr_.get();
1224 DCHECK(slice_hdr);
1225
1226 if (IsNewPrimaryCodedPicture(slice_hdr)) {
1227 // New picture, so first finish the previous one before processing it.
1228 if (!FinishPrevFrameIfPresent())
1229 return false;
1230
1231 DCHECK(!curr_pic_);
1232
1233 if (slice_hdr->first_mb_in_slice != 0) {
1234 DVLOG(1) << "ASO/invalid stream, first_mb_in_slice: "
1235 << slice_hdr->first_mb_in_slice;
1236 return false;
1237 }
1238
1239 // If the new picture is an IDR, flush DPB.
1240 if (slice_hdr->idr_pic_flag) {
1241 // Output all remaining pictures, unless we are explicitly instructed
1242 // not to do so.
1243 if (!slice_hdr->no_output_of_prior_pics_flag) {
1244 if (!Flush())
1245 return false;
1246 }
1247 dpb_.Clear();
1248 last_output_poc_ = std::numeric_limits<int>::min();
1249 }
1250 }
1251
1252 return true;
1253 }
1254
ProcessCurrentSlice()1255 bool H264Decoder::ProcessCurrentSlice() {
1256 DCHECK(curr_pic_);
1257
1258 const H264SliceHeader* slice_hdr = curr_slice_hdr_.get();
1259 DCHECK(slice_hdr);
1260
1261 if (slice_hdr->field_pic_flag == 0)
1262 max_pic_num_ = max_frame_num_;
1263 else
1264 max_pic_num_ = 2 * max_frame_num_;
1265
1266 H264Picture::Vector ref_pic_list0, ref_pic_list1;
1267 if (!ModifyReferencePicLists(slice_hdr, &ref_pic_list0, &ref_pic_list1))
1268 return false;
1269
1270 const H264PPS* pps = parser_.GetPPS(curr_pps_id_);
1271 if (!pps)
1272 return false;
1273
1274 if (!accelerator_->SubmitSlice(pps, slice_hdr, ref_pic_list0, ref_pic_list1,
1275 curr_pic_.get(), slice_hdr->nalu_data,
1276 slice_hdr->nalu_size))
1277 return false;
1278
1279 return true;
1280 }
1281
1282 #define SET_ERROR_AND_RETURN() \
1283 do { \
1284 DVLOG(1) << "Error during decode"; \
1285 state_ = kError; \
1286 return H264Decoder::kDecodeError; \
1287 } while (0)
1288
SetStream(const uint8_t * ptr,size_t size)1289 void H264Decoder::SetStream(const uint8_t* ptr, size_t size) {
1290 DCHECK(ptr);
1291 DCHECK(size);
1292
1293 DVLOG(4) << "New input stream at: " << (void*)ptr << " size: " << size;
1294 parser_.SetStream(ptr, size);
1295 }
1296
Decode()1297 H264Decoder::DecodeResult H264Decoder::Decode() {
1298 if (state_ == kError) {
1299 DVLOG(1) << "Decoder in error state";
1300 return kDecodeError;
1301 }
1302
1303 while (1) {
1304 H264Parser::Result par_res;
1305
1306 if (!curr_nalu_) {
1307 curr_nalu_.reset(new H264NALU());
1308 par_res = parser_.AdvanceToNextNALU(curr_nalu_.get());
1309 if (par_res == H264Parser::kEOStream)
1310 return kRanOutOfStreamData;
1311 else if (par_res != H264Parser::kOk)
1312 SET_ERROR_AND_RETURN();
1313
1314 DVLOG(4) << "New NALU: " << static_cast<int>(curr_nalu_->nal_unit_type);
1315 }
1316
1317 switch (curr_nalu_->nal_unit_type) {
1318 case H264NALU::kNonIDRSlice:
1319 // We can't resume from a non-IDR slice.
1320 if (state_ != kDecoding)
1321 break;
1322
1323 // else fallthrough
1324 case H264NALU::kIDRSlice: {
1325 // TODO(posciak): the IDR may require an SPS that we don't have
1326 // available. For now we'd fail if that happens, but ideally we'd like
1327 // to keep going until the next SPS in the stream.
1328 if (state_ == kNeedStreamMetadata) {
1329 // We need an SPS, skip this IDR and keep looking.
1330 break;
1331 }
1332
1333 // If after reset, we should be able to recover from an IDR.
1334 state_ = kDecoding;
1335
1336 if (!curr_slice_hdr_) {
1337 curr_slice_hdr_.reset(new H264SliceHeader());
1338 par_res =
1339 parser_.ParseSliceHeader(*curr_nalu_, curr_slice_hdr_.get());
1340 if (par_res != H264Parser::kOk)
1341 SET_ERROR_AND_RETURN();
1342
1343 if (!PreprocessCurrentSlice())
1344 SET_ERROR_AND_RETURN();
1345 }
1346
1347 if (!curr_pic_) {
1348 // New picture/finished previous one, try to start a new one
1349 // or tell the client we need more surfaces.
1350 curr_pic_ = accelerator_->CreateH264Picture();
1351 if (!curr_pic_)
1352 return kRanOutOfSurfaces;
1353
1354 if (!StartNewFrame(curr_slice_hdr_.get()))
1355 SET_ERROR_AND_RETURN();
1356 }
1357
1358 if (!ProcessCurrentSlice())
1359 SET_ERROR_AND_RETURN();
1360
1361 curr_slice_hdr_.reset();
1362 break;
1363 }
1364
1365 case H264NALU::kSPS: {
1366 int sps_id;
1367
1368 if (!FinishPrevFrameIfPresent())
1369 SET_ERROR_AND_RETURN();
1370
1371 par_res = parser_.ParseSPS(&sps_id);
1372 if (par_res != H264Parser::kOk)
1373 SET_ERROR_AND_RETURN();
1374
1375 bool need_new_buffers = false;
1376 if (!ProcessSPS(sps_id, &need_new_buffers))
1377 SET_ERROR_AND_RETURN();
1378
1379 if (state_ == kNeedStreamMetadata)
1380 state_ = kAfterReset;
1381
1382 if (need_new_buffers) {
1383 curr_pic_ = nullptr;
1384 curr_nalu_ = nullptr;
1385 ref_pic_list_p0_.clear();
1386 ref_pic_list_b0_.clear();
1387 ref_pic_list_b1_.clear();
1388
1389 return kAllocateNewSurfaces;
1390 }
1391 break;
1392 }
1393
1394 case H264NALU::kPPS: {
1395 int pps_id;
1396
1397 if (!FinishPrevFrameIfPresent())
1398 SET_ERROR_AND_RETURN();
1399
1400 par_res = parser_.ParsePPS(&pps_id);
1401 if (par_res != H264Parser::kOk)
1402 SET_ERROR_AND_RETURN();
1403
1404 break;
1405 }
1406
1407 case H264NALU::kAUD:
1408 case H264NALU::kEOSeq:
1409 case H264NALU::kEOStream:
1410 if (state_ != kDecoding)
1411 break;
1412
1413 if (!FinishPrevFrameIfPresent())
1414 SET_ERROR_AND_RETURN();
1415
1416 break;
1417
1418 default:
1419 DVLOG(4) << "Skipping NALU type: " << curr_nalu_->nal_unit_type;
1420 break;
1421 }
1422
1423 DVLOG(4) << "NALU done";
1424 curr_nalu_.reset();
1425 }
1426 }
1427
GetPicSize() const1428 Size H264Decoder::GetPicSize() const {
1429 return pic_size_;
1430 }
1431
GetRequiredNumOfPictures() const1432 size_t H264Decoder::GetRequiredNumOfPictures() const {
1433 return dpb_.max_num_pics() + kPicsInPipeline;
1434 }
1435
1436 } // namespace media
1437