Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(605)

Side by Side Diff: content/common/gpu/media/h264_decoder.cc

Issue 1369673002: H264Decoder: Handle gaps in frame_num. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "base/numerics/safe_conversions.h" 11 #include "base/numerics/safe_conversions.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "content/common/gpu/media/h264_decoder.h" 13 #include "content/common/gpu/media/h264_decoder.h"
14 14
15 namespace content { 15 namespace content {
16 16
17 H264Decoder::H264Accelerator::H264Accelerator() { 17 H264Decoder::H264Accelerator::H264Accelerator() {
18 } 18 }
19 19
20 H264Decoder::H264Accelerator::~H264Accelerator() { 20 H264Decoder::H264Accelerator::~H264Accelerator() {
21 } 21 }
22 22
23 H264Decoder::H264Decoder(H264Accelerator* accelerator) 23 H264Decoder::H264Decoder(H264Accelerator* accelerator)
24 : max_pic_order_cnt_lsb_(0), 24 : max_frame_num_(0),
25 max_frame_num_(0),
26 max_pic_num_(0), 25 max_pic_num_(0),
27 max_long_term_frame_idx_(0), 26 max_long_term_frame_idx_(0),
28 max_num_reorder_frames_(0), 27 max_num_reorder_frames_(0),
29 curr_sps_id_(-1),
30 curr_pps_id_(-1),
31 accelerator_(accelerator) { 28 accelerator_(accelerator) {
32 DCHECK(accelerator_); 29 DCHECK(accelerator_);
33 Reset(); 30 Reset();
34 state_ = kNeedStreamMetadata; 31 state_ = kNeedStreamMetadata;
35 } 32 }
36 33
37 H264Decoder::~H264Decoder() { 34 H264Decoder::~H264Decoder() {
38 } 35 }
39 36
40 void H264Decoder::Reset() { 37 void H264Decoder::Reset() {
41 curr_pic_ = nullptr; 38 curr_pic_ = nullptr;
42 curr_nalu_ = nullptr; 39 curr_nalu_ = nullptr;
43 curr_slice_hdr_ = nullptr; 40 curr_slice_hdr_ = nullptr;
41 curr_sps_id_ = -1;
42 curr_pps_id_ = -1;
44 43
45 frame_num_ = 0;
46 prev_frame_num_ = -1; 44 prev_frame_num_ = -1;
45 prev_ref_frame_num_ = -1;
47 prev_frame_num_offset_ = -1; 46 prev_frame_num_offset_ = -1;
47 prev_has_memmgmnt5_ = false;
48 48
49 prev_ref_has_memmgmnt5_ = false; 49 prev_ref_has_memmgmnt5_ = false;
50 prev_ref_top_field_order_cnt_ = -1; 50 prev_ref_top_field_order_cnt_ = -1;
51 prev_ref_pic_order_cnt_msb_ = -1; 51 prev_ref_pic_order_cnt_msb_ = -1;
52 prev_ref_pic_order_cnt_lsb_ = -1; 52 prev_ref_pic_order_cnt_lsb_ = -1;
53 prev_ref_field_ = H264Picture::FIELD_NONE; 53 prev_ref_field_ = H264Picture::FIELD_NONE;
54 54
55 ref_pic_list_p0_.clear(); 55 ref_pic_list_p0_.clear();
56 ref_pic_list_b0_.clear(); 56 ref_pic_list_b0_.clear();
57 ref_pic_list_b1_.clear(); 57 ref_pic_list_b1_.clear();
58 dpb_.Clear(); 58 dpb_.Clear();
59 parser_.Reset(); 59 parser_.Reset();
60 accelerator_->Reset(); 60 accelerator_->Reset();
61 last_output_poc_ = std::numeric_limits<int>::min(); 61 last_output_poc_ = std::numeric_limits<int>::min();
62 62
63 // If we are in kDecoding, we can resume without processing an SPS. 63 // If we are in kDecoding, we can resume without processing an SPS.
64 if (state_ == kDecoding) 64 if (state_ == kDecoding)
65 state_ = kAfterReset; 65 state_ = kAfterReset;
66 } 66 }
67 67
68 void H264Decoder::PrepareRefPicLists(media::H264SliceHeader* slice_hdr) { 68 void H264Decoder::PrepareRefPicLists(const media::H264SliceHeader* slice_hdr) {
69 ConstructReferencePicListsP(slice_hdr); 69 ConstructReferencePicListsP(slice_hdr);
70 ConstructReferencePicListsB(slice_hdr); 70 ConstructReferencePicListsB(slice_hdr);
71 } 71 }
72 72
73 bool H264Decoder::ModifyReferencePicLists(media::H264SliceHeader* slice_hdr, 73 bool H264Decoder::ModifyReferencePicLists(
74 H264Picture::Vector* ref_pic_list0, 74 const media::H264SliceHeader* slice_hdr,
75 H264Picture::Vector* ref_pic_list1) { 75 H264Picture::Vector* ref_pic_list0,
76 H264Picture::Vector* ref_pic_list1) {
76 ref_pic_list0->clear(); 77 ref_pic_list0->clear();
77 ref_pic_list1->clear(); 78 ref_pic_list1->clear();
78 79
79 // Fill reference picture lists for B and S/SP slices. 80 // Fill reference picture lists for B and S/SP slices.
80 if (slice_hdr->IsPSlice() || slice_hdr->IsSPSlice()) { 81 if (slice_hdr->IsPSlice() || slice_hdr->IsSPSlice()) {
81 *ref_pic_list0 = ref_pic_list_p0_; 82 *ref_pic_list0 = ref_pic_list_p0_;
82 return ModifyReferencePicList(slice_hdr, 0, ref_pic_list0); 83 return ModifyReferencePicList(slice_hdr, 0, ref_pic_list0);
83 } else if (slice_hdr->IsBSlice()) { 84 } else if (slice_hdr->IsBSlice()) {
84 *ref_pic_list0 = ref_pic_list_b0_; 85 *ref_pic_list0 = ref_pic_list_b0_;
85 *ref_pic_list1 = ref_pic_list_b1_; 86 *ref_pic_list1 = ref_pic_list_b1_;
86 return ModifyReferencePicList(slice_hdr, 0, ref_pic_list0) && 87 return ModifyReferencePicList(slice_hdr, 0, ref_pic_list0) &&
87 ModifyReferencePicList(slice_hdr, 1, ref_pic_list1); 88 ModifyReferencePicList(slice_hdr, 1, ref_pic_list1);
88 } 89 }
89 90
90 return true; 91 return true;
91 } 92 }
92 93
93 bool H264Decoder::DecodePicture() { 94 bool H264Decoder::DecodePicture() {
94 DCHECK(curr_pic_.get()); 95 DCHECK(curr_pic_.get());
95 96
96 DVLOG(4) << "Decoding POC " << curr_pic_->pic_order_cnt; 97 DVLOG(4) << "Decoding POC " << curr_pic_->pic_order_cnt;
97 return accelerator_->SubmitDecode(curr_pic_); 98 return accelerator_->SubmitDecode(curr_pic_);
98 } 99 }
99 100
100 bool H264Decoder::InitCurrPicture(media::H264SliceHeader* slice_hdr) { 101 bool H264Decoder::InitNonexistingPicture(scoped_refptr<H264Picture> pic,
xhwang 2015/10/12 18:01:17 nit: in media code, we pass const-ref of scoped_re
Pawel Osciak 2015/10/13 01:23:22 Yes, I'd like to do that too, but for now wanted t
102 int frame_num) {
103 pic->nonexisting = true;
104 pic->nal_ref_idc = 1;
105 pic->frame_num = pic->pic_num = frame_num;
106 pic->adaptive_ref_pic_marking_mode_flag = false;
107 pic->ref = true;
108 pic->long_term_reference_flag = false;
109 pic->field = H264Picture::FIELD_NONE;
110
111 return CalculatePicOrderCounts(pic);
112 }
113
114 bool H264Decoder::InitCurrPicture(const media::H264SliceHeader* slice_hdr) {
101 DCHECK(curr_pic_.get()); 115 DCHECK(curr_pic_.get());
102 116
103 curr_pic_->idr = slice_hdr->idr_pic_flag; 117 curr_pic_->idr = slice_hdr->idr_pic_flag;
118 if (curr_pic_->idr)
119 curr_pic_->idr_pic_id = slice_hdr->idr_pic_id;
104 120
105 if (slice_hdr->field_pic_flag) { 121 if (slice_hdr->field_pic_flag) {
106 curr_pic_->field = slice_hdr->bottom_field_flag ? H264Picture::FIELD_BOTTOM 122 curr_pic_->field = slice_hdr->bottom_field_flag ? H264Picture::FIELD_BOTTOM
107 : H264Picture::FIELD_TOP; 123 : H264Picture::FIELD_TOP;
108 } else { 124 } else {
109 curr_pic_->field = H264Picture::FIELD_NONE; 125 curr_pic_->field = H264Picture::FIELD_NONE;
110 } 126 }
111 127
128 if (curr_pic_->field != H264Picture::FIELD_NONE) {
129 DVLOG(1) << "Interlaced video not supported.";
130 return false;
131 }
132
133 curr_pic_->nal_ref_idc = slice_hdr->nal_ref_idc;
112 curr_pic_->ref = slice_hdr->nal_ref_idc != 0; 134 curr_pic_->ref = slice_hdr->nal_ref_idc != 0;
113 // This assumes non-interlaced stream. 135 // This assumes non-interlaced stream.
114 curr_pic_->frame_num = curr_pic_->pic_num = slice_hdr->frame_num; 136 curr_pic_->frame_num = curr_pic_->pic_num = slice_hdr->frame_num;
115 137
116 if (!CalculatePicOrderCounts(slice_hdr)) 138 DCHECK_NE(curr_sps_id_, -1);
139 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_);
140 if (!sps)
141 return false;
142
143 curr_pic_->pic_order_cnt_type = sps->pic_order_cnt_type;
144 switch (curr_pic_->pic_order_cnt_type) {
xhwang 2015/10/12 18:01:17 nit: can you have an enum for |pic_order_cnt_type|
Pawel Osciak 2015/10/13 01:23:22 This is intentional, as the H264 spec uses "pic or
145 case 0:
146 curr_pic_->pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb;
147 curr_pic_->delta_pic_order_cnt_bottom =
148 slice_hdr->delta_pic_order_cnt_bottom;
149 break;
150
151 case 1:
152 curr_pic_->delta_pic_order_cnt0 = slice_hdr->delta_pic_order_cnt0;
153 curr_pic_->delta_pic_order_cnt1 = slice_hdr->delta_pic_order_cnt1;
154 break;
155
156 case 2:
157 break;
158
159 default:
160 NOTREACHED();
161 return false;
162 }
163
164 if (!CalculatePicOrderCounts(curr_pic_))
117 return false; 165 return false;
118 166
119 curr_pic_->long_term_reference_flag = slice_hdr->long_term_reference_flag; 167 curr_pic_->long_term_reference_flag = slice_hdr->long_term_reference_flag;
120 curr_pic_->adaptive_ref_pic_marking_mode_flag = 168 curr_pic_->adaptive_ref_pic_marking_mode_flag =
121 slice_hdr->adaptive_ref_pic_marking_mode_flag; 169 slice_hdr->adaptive_ref_pic_marking_mode_flag;
122 170
123 // If the slice header indicates we will have to perform reference marking 171 // If the slice header indicates we will have to perform reference marking
124 // process after this picture is decoded, store required data for that 172 // process after this picture is decoded, store required data for that
125 // purpose. 173 // purpose.
126 if (slice_hdr->adaptive_ref_pic_marking_mode_flag) { 174 if (slice_hdr->adaptive_ref_pic_marking_mode_flag) {
127 static_assert(sizeof(curr_pic_->ref_pic_marking) == 175 static_assert(sizeof(curr_pic_->ref_pic_marking) ==
128 sizeof(slice_hdr->ref_pic_marking), 176 sizeof(slice_hdr->ref_pic_marking),
129 "Array sizes of ref pic marking do not match."); 177 "Array sizes of ref pic marking do not match.");
130 memcpy(curr_pic_->ref_pic_marking, slice_hdr->ref_pic_marking, 178 memcpy(curr_pic_->ref_pic_marking, slice_hdr->ref_pic_marking,
131 sizeof(curr_pic_->ref_pic_marking)); 179 sizeof(curr_pic_->ref_pic_marking));
132 } 180 }
133 181
134 return true; 182 return true;
135 } 183 }
136 184
137 bool H264Decoder::CalculatePicOrderCounts(media::H264SliceHeader* slice_hdr) { 185 bool H264Decoder::CalculatePicOrderCounts(scoped_refptr<H264Picture> pic) {
138 DCHECK_NE(curr_sps_id_, -1);
139 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_); 186 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_);
187 if (!sps)
188 return false;
140 189
141 int pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb; 190 switch (pic->pic_order_cnt_type) {
142 curr_pic_->pic_order_cnt_lsb = pic_order_cnt_lsb; 191 case 0: {
xhwang 2015/10/12 18:01:17 ditto
143
144 switch (sps->pic_order_cnt_type) {
145 case 0:
146 // See spec 8.2.1.1. 192 // See spec 8.2.1.1.
147 int prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb; 193 int prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb;
148 if (slice_hdr->idr_pic_flag) { 194
195 if (pic->idr) {
149 prev_pic_order_cnt_msb = prev_pic_order_cnt_lsb = 0; 196 prev_pic_order_cnt_msb = prev_pic_order_cnt_lsb = 0;
150 } else { 197 } else {
151 if (prev_ref_has_memmgmnt5_) { 198 if (prev_ref_has_memmgmnt5_) {
152 if (prev_ref_field_ != H264Picture::FIELD_BOTTOM) { 199 if (prev_ref_field_ != H264Picture::FIELD_BOTTOM) {
153 prev_pic_order_cnt_msb = 0; 200 prev_pic_order_cnt_msb = 0;
154 prev_pic_order_cnt_lsb = prev_ref_top_field_order_cnt_; 201 prev_pic_order_cnt_lsb = prev_ref_top_field_order_cnt_;
155 } else { 202 } else {
156 prev_pic_order_cnt_msb = 0; 203 prev_pic_order_cnt_msb = 0;
157 prev_pic_order_cnt_lsb = 0; 204 prev_pic_order_cnt_lsb = 0;
158 } 205 }
159 } else { 206 } else {
160 prev_pic_order_cnt_msb = prev_ref_pic_order_cnt_msb_; 207 prev_pic_order_cnt_msb = prev_ref_pic_order_cnt_msb_;
161 prev_pic_order_cnt_lsb = prev_ref_pic_order_cnt_lsb_; 208 prev_pic_order_cnt_lsb = prev_ref_pic_order_cnt_lsb_;
162 } 209 }
163 } 210 }
164 211
165 DCHECK_NE(max_pic_order_cnt_lsb_, 0); 212 int max_pic_order_cnt_lsb =
166 if ((pic_order_cnt_lsb < prev_pic_order_cnt_lsb) && 213 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
167 (prev_pic_order_cnt_lsb - pic_order_cnt_lsb >= 214 DCHECK_NE(max_pic_order_cnt_lsb, 0);
168 max_pic_order_cnt_lsb_ / 2)) { 215 if ((pic->pic_order_cnt_lsb < prev_pic_order_cnt_lsb) &&
169 curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb + 216 (prev_pic_order_cnt_lsb - pic->pic_order_cnt_lsb >=
170 max_pic_order_cnt_lsb_; 217 max_pic_order_cnt_lsb / 2)) {
171 } else if ((pic_order_cnt_lsb > prev_pic_order_cnt_lsb) && 218 pic->pic_order_cnt_msb = prev_pic_order_cnt_msb + max_pic_order_cnt_lsb;
172 (pic_order_cnt_lsb - prev_pic_order_cnt_lsb > 219 } else if ((pic->pic_order_cnt_lsb > prev_pic_order_cnt_lsb) &&
173 max_pic_order_cnt_lsb_ / 2)) { 220 (pic->pic_order_cnt_lsb - prev_pic_order_cnt_lsb >
174 curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb - 221 max_pic_order_cnt_lsb / 2)) {
175 max_pic_order_cnt_lsb_; 222 pic->pic_order_cnt_msb = prev_pic_order_cnt_msb - max_pic_order_cnt_lsb;
176 } else { 223 } else {
177 curr_pic_->pic_order_cnt_msb = prev_pic_order_cnt_msb; 224 pic->pic_order_cnt_msb = prev_pic_order_cnt_msb;
178 } 225 }
179 226
180 if (curr_pic_->field != H264Picture::FIELD_BOTTOM) { 227 if (pic->field != H264Picture::FIELD_BOTTOM) {
181 curr_pic_->top_field_order_cnt = curr_pic_->pic_order_cnt_msb + 228 pic->top_field_order_cnt =
182 pic_order_cnt_lsb; 229 pic->pic_order_cnt_msb + pic->pic_order_cnt_lsb;
183 } 230 }
184 231
185 if (curr_pic_->field != H264Picture::FIELD_TOP) { 232 if (pic->field != H264Picture::FIELD_TOP) {
186 // TODO posciak: perhaps replace with pic->field? 233 if (pic->field == H264Picture::FIELD_NONE) {
187 if (!slice_hdr->field_pic_flag) { 234 pic->bottom_field_order_cnt =
188 curr_pic_->bottom_field_order_cnt = curr_pic_->top_field_order_cnt + 235 pic->top_field_order_cnt + pic->delta_pic_order_cnt_bottom;
189 slice_hdr->delta_pic_order_cnt_bottom;
190 } else { 236 } else {
191 curr_pic_->bottom_field_order_cnt = curr_pic_->pic_order_cnt_msb + 237 pic->bottom_field_order_cnt =
192 pic_order_cnt_lsb; 238 pic->pic_order_cnt_msb + pic->pic_order_cnt_lsb;
193 } 239 }
194 } 240 }
195 break; 241 break;
242 }
196 243
197 case 1: { 244 case 1: {
198 // See spec 8.2.1.2. 245 // See spec 8.2.1.2.
199 if (prev_has_memmgmnt5_) 246 if (prev_has_memmgmnt5_)
200 prev_frame_num_offset_ = 0; 247 prev_frame_num_offset_ = 0;
201 248
202 if (slice_hdr->idr_pic_flag) 249 if (pic->idr)
203 curr_pic_->frame_num_offset = 0; 250 pic->frame_num_offset = 0;
204 else if (prev_frame_num_ > slice_hdr->frame_num) 251 else if (prev_frame_num_ > pic->frame_num)
205 curr_pic_->frame_num_offset = prev_frame_num_offset_ + max_frame_num_; 252 pic->frame_num_offset = prev_frame_num_offset_ + max_frame_num_;
206 else 253 else
207 curr_pic_->frame_num_offset = prev_frame_num_offset_; 254 pic->frame_num_offset = prev_frame_num_offset_;
208 255
209 int abs_frame_num = 0; 256 int abs_frame_num = 0;
210 if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0) 257 if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
211 abs_frame_num = curr_pic_->frame_num_offset + slice_hdr->frame_num; 258 abs_frame_num = pic->frame_num_offset + pic->frame_num;
212 else 259 else
213 abs_frame_num = 0; 260 abs_frame_num = 0;
214 261
215 if (slice_hdr->nal_ref_idc == 0 && abs_frame_num > 0) 262 if (pic->nal_ref_idc == 0 && abs_frame_num > 0)
216 --abs_frame_num; 263 --abs_frame_num;
217 264
218 int expected_pic_order_cnt = 0; 265 int expected_pic_order_cnt = 0;
219 if (abs_frame_num > 0) { 266 if (abs_frame_num > 0) {
220 if (sps->num_ref_frames_in_pic_order_cnt_cycle == 0) { 267 if (sps->num_ref_frames_in_pic_order_cnt_cycle == 0) {
221 DVLOG(1) << "Invalid num_ref_frames_in_pic_order_cnt_cycle " 268 DVLOG(1) << "Invalid num_ref_frames_in_pic_order_cnt_cycle "
222 << "in stream"; 269 << "in stream";
223 return false; 270 return false;
224 } 271 }
225 272
226 int pic_order_cnt_cycle_cnt = (abs_frame_num - 1) / 273 int pic_order_cnt_cycle_cnt = (abs_frame_num - 1) /
227 sps->num_ref_frames_in_pic_order_cnt_cycle; 274 sps->num_ref_frames_in_pic_order_cnt_cycle;
228 int frame_num_in_pic_order_cnt_cycle = (abs_frame_num - 1) % 275 int frame_num_in_pic_order_cnt_cycle = (abs_frame_num - 1) %
229 sps->num_ref_frames_in_pic_order_cnt_cycle; 276 sps->num_ref_frames_in_pic_order_cnt_cycle;
230 277
231 expected_pic_order_cnt = pic_order_cnt_cycle_cnt * 278 expected_pic_order_cnt = pic_order_cnt_cycle_cnt *
232 sps->expected_delta_per_pic_order_cnt_cycle; 279 sps->expected_delta_per_pic_order_cnt_cycle;
233 // frame_num_in_pic_order_cnt_cycle is verified < 255 in parser 280 // frame_num_in_pic_order_cnt_cycle is verified < 255 in parser
234 for (int i = 0; i <= frame_num_in_pic_order_cnt_cycle; ++i) 281 for (int i = 0; i <= frame_num_in_pic_order_cnt_cycle; ++i)
235 expected_pic_order_cnt += sps->offset_for_ref_frame[i]; 282 expected_pic_order_cnt += sps->offset_for_ref_frame[i];
236 } 283 }
237 284
238 if (!slice_hdr->nal_ref_idc) 285 if (!pic->nal_ref_idc)
239 expected_pic_order_cnt += sps->offset_for_non_ref_pic; 286 expected_pic_order_cnt += sps->offset_for_non_ref_pic;
240 287
241 if (!slice_hdr->field_pic_flag) { 288 if (pic->field == H264Picture::FIELD_NONE) {
242 curr_pic_->top_field_order_cnt = expected_pic_order_cnt + 289 pic->top_field_order_cnt =
243 slice_hdr->delta_pic_order_cnt0; 290 expected_pic_order_cnt + pic->delta_pic_order_cnt0;
244 curr_pic_->bottom_field_order_cnt = curr_pic_->top_field_order_cnt + 291 pic->bottom_field_order_cnt = pic->top_field_order_cnt +
245 sps->offset_for_top_to_bottom_field + 292 sps->offset_for_top_to_bottom_field +
246 slice_hdr->delta_pic_order_cnt1; 293 pic->delta_pic_order_cnt1;
247 } else if (!slice_hdr->bottom_field_flag) { 294 } else if (pic->field != H264Picture::FIELD_BOTTOM) {
248 curr_pic_->top_field_order_cnt = expected_pic_order_cnt + 295 pic->top_field_order_cnt =
249 slice_hdr->delta_pic_order_cnt0; 296 expected_pic_order_cnt + pic->delta_pic_order_cnt0;
250 } else { 297 } else {
251 curr_pic_->bottom_field_order_cnt = expected_pic_order_cnt + 298 pic->bottom_field_order_cnt = expected_pic_order_cnt +
252 sps->offset_for_top_to_bottom_field + 299 sps->offset_for_top_to_bottom_field +
253 slice_hdr->delta_pic_order_cnt0; 300 pic->delta_pic_order_cnt0;
254 } 301 }
255 break; 302 break;
256 } 303 }
257 304
258 case 2: 305 case 2: {
259 // See spec 8.2.1.3. 306 // See spec 8.2.1.3.
260 if (prev_has_memmgmnt5_) 307 if (prev_has_memmgmnt5_)
261 prev_frame_num_offset_ = 0; 308 prev_frame_num_offset_ = 0;
262 309
263 if (slice_hdr->idr_pic_flag) 310 if (pic->idr)
264 curr_pic_->frame_num_offset = 0; 311 pic->frame_num_offset = 0;
265 else if (prev_frame_num_ > slice_hdr->frame_num) 312 else if (prev_frame_num_ > pic->frame_num)
266 curr_pic_->frame_num_offset = prev_frame_num_offset_ + max_frame_num_; 313 pic->frame_num_offset = prev_frame_num_offset_ + max_frame_num_;
267 else 314 else
268 curr_pic_->frame_num_offset = prev_frame_num_offset_; 315 pic->frame_num_offset = prev_frame_num_offset_;
269 316
270 int temp_pic_order_cnt; 317 int temp_pic_order_cnt;
271 if (slice_hdr->idr_pic_flag) { 318 if (pic->idr) {
272 temp_pic_order_cnt = 0; 319 temp_pic_order_cnt = 0;
273 } else if (!slice_hdr->nal_ref_idc) { 320 } else if (!pic->nal_ref_idc) {
274 temp_pic_order_cnt = 321 temp_pic_order_cnt = 2 * (pic->frame_num_offset + pic->frame_num) - 1;
275 2 * (curr_pic_->frame_num_offset + slice_hdr->frame_num) - 1;
276 } else { 322 } else {
277 temp_pic_order_cnt = 2 * (curr_pic_->frame_num_offset + 323 temp_pic_order_cnt = 2 * (pic->frame_num_offset + pic->frame_num);
278 slice_hdr->frame_num);
279 } 324 }
280 325
281 if (!slice_hdr->field_pic_flag) { 326 if (pic->field == H264Picture::FIELD_NONE) {
282 curr_pic_->top_field_order_cnt = temp_pic_order_cnt; 327 pic->top_field_order_cnt = temp_pic_order_cnt;
283 curr_pic_->bottom_field_order_cnt = temp_pic_order_cnt; 328 pic->bottom_field_order_cnt = temp_pic_order_cnt;
284 } else if (slice_hdr->bottom_field_flag) { 329 } else if (pic->field == H264Picture::FIELD_BOTTOM) {
285 curr_pic_->bottom_field_order_cnt = temp_pic_order_cnt; 330 pic->bottom_field_order_cnt = temp_pic_order_cnt;
286 } else { 331 } else {
287 curr_pic_->top_field_order_cnt = temp_pic_order_cnt; 332 pic->top_field_order_cnt = temp_pic_order_cnt;
288 } 333 }
289 break; 334 break;
335 }
290 336
291 default: 337 default:
292 DVLOG(1) << "Invalid pic_order_cnt_type: " << sps->pic_order_cnt_type; 338 DVLOG(1) << "Invalid pic_order_cnt_type: " << sps->pic_order_cnt_type;
293 return false; 339 return false;
294 } 340 }
295 341
296 switch (curr_pic_->field) { 342 switch (pic->field) {
297 case H264Picture::FIELD_NONE: 343 case H264Picture::FIELD_NONE:
298 curr_pic_->pic_order_cnt = std::min(curr_pic_->top_field_order_cnt, 344 pic->pic_order_cnt =
299 curr_pic_->bottom_field_order_cnt); 345 std::min(pic->top_field_order_cnt, pic->bottom_field_order_cnt);
300 break; 346 break;
301 case H264Picture::FIELD_TOP: 347 case H264Picture::FIELD_TOP:
302 curr_pic_->pic_order_cnt = curr_pic_->top_field_order_cnt; 348 pic->pic_order_cnt = pic->top_field_order_cnt;
303 break; 349 break;
304 case H264Picture::FIELD_BOTTOM: 350 case H264Picture::FIELD_BOTTOM:
305 curr_pic_->pic_order_cnt = curr_pic_->bottom_field_order_cnt; 351 pic->pic_order_cnt = pic->bottom_field_order_cnt;
306 break; 352 break;
307 } 353 }
308 354
309 return true; 355 return true;
310 } 356 }
311 357
312 void H264Decoder::UpdatePicNums() { 358 void H264Decoder::UpdatePicNums(int frame_num) {
313 for (auto& pic : dpb_) { 359 for (auto& pic : dpb_) {
314 if (!pic->ref) 360 if (!pic->ref)
315 continue; 361 continue;
316 362
317 // Below assumes non-interlaced stream. 363 // 8.2.4.1. Assumes non-interlaced stream.
318 DCHECK_EQ(pic->field, H264Picture::FIELD_NONE); 364 DCHECK_EQ(pic->field, H264Picture::FIELD_NONE);
319 if (pic->long_term) { 365 if (pic->long_term) {
320 pic->long_term_pic_num = pic->long_term_frame_idx; 366 pic->long_term_pic_num = pic->long_term_frame_idx;
321 } else { 367 } else {
322 if (pic->frame_num > frame_num_) 368 if (pic->frame_num > frame_num)
323 pic->frame_num_wrap = pic->frame_num - max_frame_num_; 369 pic->frame_num_wrap = pic->frame_num - max_frame_num_;
324 else 370 else
325 pic->frame_num_wrap = pic->frame_num; 371 pic->frame_num_wrap = pic->frame_num;
326 372
327 pic->pic_num = pic->frame_num_wrap; 373 pic->pic_num = pic->frame_num_wrap;
328 } 374 }
329 } 375 }
330 } 376 }
331 377
332 struct PicNumDescCompare { 378 struct PicNumDescCompare {
333 bool operator()(const scoped_refptr<H264Picture>& a, 379 bool operator()(const scoped_refptr<H264Picture>& a,
334 const scoped_refptr<H264Picture>& b) const { 380 const scoped_refptr<H264Picture>& b) const {
335 return a->pic_num > b->pic_num; 381 return a->pic_num > b->pic_num;
336 } 382 }
337 }; 383 };
338 384
339 struct LongTermPicNumAscCompare { 385 struct LongTermPicNumAscCompare {
340 bool operator()(const scoped_refptr<H264Picture>& a, 386 bool operator()(const scoped_refptr<H264Picture>& a,
341 const scoped_refptr<H264Picture>& b) const { 387 const scoped_refptr<H264Picture>& b) const {
342 return a->long_term_pic_num < b->long_term_pic_num; 388 return a->long_term_pic_num < b->long_term_pic_num;
343 } 389 }
344 }; 390 };
345 391
346 void H264Decoder::ConstructReferencePicListsP( 392 void H264Decoder::ConstructReferencePicListsP(
347 media::H264SliceHeader* slice_hdr) { 393 const media::H264SliceHeader* slice_hdr) {
348 // RefPicList0 (8.2.4.2.1) [[1] [2]], where: 394 // RefPicList0 (8.2.4.2.1) [[1] [2]], where:
349 // [1] shortterm ref pics sorted by descending pic_num, 395 // [1] shortterm ref pics sorted by descending pic_num,
350 // [2] longterm ref pics by ascending long_term_pic_num. 396 // [2] longterm ref pics by ascending long_term_pic_num.
351 ref_pic_list_p0_.clear(); 397 ref_pic_list_p0_.clear();
352 398
353 // First get the short ref pics... 399 // First get the short ref pics...
354 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_p0_); 400 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_p0_);
355 size_t num_short_refs = ref_pic_list_p0_.size(); 401 size_t num_short_refs = ref_pic_list_p0_.size();
356 402
357 // and sort them to get [1]. 403 // and sort them to get [1].
(...skipping 14 matching lines...) Expand all
372 }; 418 };
373 419
374 struct POCDescCompare { 420 struct POCDescCompare {
375 bool operator()(const scoped_refptr<H264Picture>& a, 421 bool operator()(const scoped_refptr<H264Picture>& a,
376 const scoped_refptr<H264Picture>& b) const { 422 const scoped_refptr<H264Picture>& b) const {
377 return a->pic_order_cnt > b->pic_order_cnt; 423 return a->pic_order_cnt > b->pic_order_cnt;
378 } 424 }
379 }; 425 };
380 426
381 void H264Decoder::ConstructReferencePicListsB( 427 void H264Decoder::ConstructReferencePicListsB(
382 media::H264SliceHeader* slice_hdr) { 428 const media::H264SliceHeader* slice_hdr) {
383 // RefPicList0 (8.2.4.2.3) [[1] [2] [3]], where: 429 // RefPicList0 (8.2.4.2.3) [[1] [2] [3]], where:
384 // [1] shortterm ref pics with POC < curr_pic's POC sorted by descending POC, 430 // [1] shortterm ref pics with POC < curr_pic's POC sorted by descending POC,
385 // [2] shortterm ref pics with POC > curr_pic's POC by ascending POC, 431 // [2] shortterm ref pics with POC > curr_pic's POC by ascending POC,
386 // [3] longterm ref pics by ascending long_term_pic_num. 432 // [3] longterm ref pics by ascending long_term_pic_num.
387 ref_pic_list_b0_.clear(); 433 ref_pic_list_b0_.clear();
388 ref_pic_list_b1_.clear(); 434 ref_pic_list_b1_.clear();
389 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_b0_); 435 dpb_.GetShortTermRefPicsAppending(&ref_pic_list_b0_);
390 size_t num_short_refs = ref_pic_list_b0_.size(); 436 size_t num_short_refs = ref_pic_list_b0_.size();
391 437
392 // First sort ascending, this will put [1] in right place and finish [2]. 438 // First sort ascending, this will put [1] in right place and finish [2].
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 (to + 2 == static_cast<int>(v->size()))); 516 (to + 2 == static_cast<int>(v->size())));
471 517
472 v->resize(to + 2); 518 v->resize(to + 2);
473 519
474 for (int i = to + 1; i > from; --i) 520 for (int i = to + 1; i > from; --i)
475 (*v)[i] = (*v)[i - 1]; 521 (*v)[i] = (*v)[i - 1];
476 522
477 (*v)[from] = pic; 523 (*v)[from] = pic;
478 } 524 }
479 525
480 bool H264Decoder::ModifyReferencePicList(media::H264SliceHeader* slice_hdr, 526 bool H264Decoder::ModifyReferencePicList(
481 int list, 527 const media::H264SliceHeader* slice_hdr,
482 H264Picture::Vector* ref_pic_listx) { 528 int list,
529 H264Picture::Vector* ref_pic_listx) {
483 bool ref_pic_list_modification_flag_lX; 530 bool ref_pic_list_modification_flag_lX;
484 int num_ref_idx_lX_active_minus1; 531 int num_ref_idx_lX_active_minus1;
485 media::H264ModificationOfPicNum* list_mod; 532 const media::H264ModificationOfPicNum* list_mod;
486 533
487 // This can process either ref_pic_list0 or ref_pic_list1, depending on 534 // This can process either ref_pic_list0 or ref_pic_list1, depending on
488 // the list argument. Set up pointers to proper list to be processed here. 535 // the list argument. Set up pointers to proper list to be processed here.
489 if (list == 0) { 536 if (list == 0) {
490 ref_pic_list_modification_flag_lX = 537 ref_pic_list_modification_flag_lX =
491 slice_hdr->ref_pic_list_modification_flag_l0; 538 slice_hdr->ref_pic_list_modification_flag_l0;
492 num_ref_idx_lX_active_minus1 = 539 num_ref_idx_lX_active_minus1 =
493 slice_hdr->num_ref_idx_l0_active_minus1; 540 slice_hdr->num_ref_idx_l0_active_minus1;
494 list_mod = slice_hdr->ref_list_l0_modifications; 541 list_mod = slice_hdr->ref_list_l0_modifications;
495 } else { 542 } else {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 // Resize the list back to its required size. 658 // Resize the list back to its required size.
612 ref_pic_listx->resize(num_ref_idx_lX_active_minus1 + 1); 659 ref_pic_listx->resize(num_ref_idx_lX_active_minus1 + 1);
613 660
614 return true; 661 return true;
615 } 662 }
616 663
617 void H264Decoder::OutputPic(scoped_refptr<H264Picture> pic) { 664 void H264Decoder::OutputPic(scoped_refptr<H264Picture> pic) {
618 DCHECK(!pic->outputted); 665 DCHECK(!pic->outputted);
619 pic->outputted = true; 666 pic->outputted = true;
620 667
668 if (pic->nonexisting) {
669 DVLOG(4) << "Skipping output, non-existing frame_num: " << pic->frame_num;
670 return;
671 }
672
621 DVLOG_IF(1, pic->pic_order_cnt < last_output_poc_) 673 DVLOG_IF(1, pic->pic_order_cnt < last_output_poc_)
622 << "Outputting out of order, likely a broken stream"; 674 << "Outputting out of order, likely a broken stream: "
675 << last_output_poc_ << " -> " << pic->pic_order_cnt;
623 last_output_poc_ = pic->pic_order_cnt; 676 last_output_poc_ = pic->pic_order_cnt;
624 677
625 DVLOG(4) << "Posting output task for POC: " << pic->pic_order_cnt; 678 DVLOG(4) << "Posting output task for POC: " << pic->pic_order_cnt;
626 accelerator_->OutputPicture(pic); 679 accelerator_->OutputPicture(pic);
627 } 680 }
628 681
629 void H264Decoder::ClearDPB() { 682 void H264Decoder::ClearDPB() {
630 // Clear DPB contents, marking the pictures as unused first. 683 // Clear DPB contents, marking the pictures as unused first.
631 dpb_.Clear(); 684 dpb_.Clear();
632 last_output_poc_ = std::numeric_limits<int>::min(); 685 last_output_poc_ = std::numeric_limits<int>::min();
(...skipping 17 matching lines...) Expand all
650 DVLOG(2) << "Decoder flush"; 703 DVLOG(2) << "Decoder flush";
651 704
652 if (!OutputAllRemainingPics()) 705 if (!OutputAllRemainingPics())
653 return false; 706 return false;
654 707
655 ClearDPB(); 708 ClearDPB();
656 DVLOG(2) << "Decoder flush finished"; 709 DVLOG(2) << "Decoder flush finished";
657 return true; 710 return true;
658 } 711 }
659 712
660 bool H264Decoder::StartNewFrame(media::H264SliceHeader* slice_hdr) { 713 bool H264Decoder::StartNewFrame(const media::H264SliceHeader* slice_hdr) {
661 // TODO posciak: add handling of max_num_ref_frames per spec. 714 // TODO posciak: add handling of max_num_ref_frames per spec.
662 CHECK(curr_pic_.get()); 715 CHECK(curr_pic_.get());
716 DCHECK(slice_hdr);
717
718 curr_pps_id_ = slice_hdr->pic_parameter_set_id;
719 const media::H264PPS* pps = parser_.GetPPS(curr_pps_id_);
720 if (!pps)
721 return false;
722
723 curr_sps_id_ = pps->seq_parameter_set_id;
724 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_);
725 if (!sps)
726 return false;
727
728 max_frame_num_ = 1 << (sps->log2_max_frame_num_minus4 + 4);
729 int frame_num = slice_hdr->frame_num;
730 if (slice_hdr->idr_pic_flag)
731 prev_ref_frame_num_ = 0;
732
733 // 7.4.3
734 if (frame_num != prev_ref_frame_num_ &&
735 frame_num != (prev_ref_frame_num_ + 1) % max_frame_num_) {
736 if (!HandleFrameNumGap(frame_num))
737 return false;
738 }
663 739
664 if (!InitCurrPicture(slice_hdr)) 740 if (!InitCurrPicture(slice_hdr))
665 return false; 741 return false;
666 742
667 DCHECK_GT(max_frame_num_, 0); 743 UpdatePicNums(frame_num);
668
669 UpdatePicNums();
670 DCHECK(slice_hdr);
671 PrepareRefPicLists(slice_hdr); 744 PrepareRefPicLists(slice_hdr);
672 745
673 const media::H264PPS* pps = parser_.GetPPS(curr_pps_id_);
674 DCHECK(pps);
675 const media::H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id);
676 DCHECK(sps);
677
678 if (!accelerator_->SubmitFrameMetadata(sps, pps, dpb_, ref_pic_list_p0_, 746 if (!accelerator_->SubmitFrameMetadata(sps, pps, dpb_, ref_pic_list_p0_,
679 ref_pic_list_b0_, ref_pic_list_b1_, 747 ref_pic_list_b0_, ref_pic_list_b1_,
680 curr_pic_.get())) 748 curr_pic_.get()))
681 return false; 749 return false;
682 750
683 return true; 751 return true;
684 } 752 }
685 753
686 bool H264Decoder::HandleMemoryManagementOps() { 754 bool H264Decoder::HandleMemoryManagementOps(scoped_refptr<H264Picture> pic) {
687 // 8.2.5.4 755 // 8.2.5.4
688 for (unsigned int i = 0; i < arraysize(curr_pic_->ref_pic_marking); ++i) { 756 for (size_t i = 0; i < arraysize(pic->ref_pic_marking); ++i) {
689 // Code below does not support interlaced stream (per-field pictures). 757 // Code below does not support interlaced stream (per-field pictures).
690 media::H264DecRefPicMarking* ref_pic_marking = 758 media::H264DecRefPicMarking* ref_pic_marking = &pic->ref_pic_marking[i];
691 &curr_pic_->ref_pic_marking[i];
692 scoped_refptr<H264Picture> to_mark; 759 scoped_refptr<H264Picture> to_mark;
693 int pic_num_x; 760 int pic_num_x;
694 761
695 switch (ref_pic_marking->memory_mgmnt_control_operation) { 762 switch (ref_pic_marking->memory_mgmnt_control_operation) {
696 case 0: 763 case 0:
697 // Normal end of operations' specification. 764 // Normal end of operations' specification.
698 return true; 765 return true;
699 766
700 case 1: 767 case 1:
701 // Mark a short term reference picture as unused so it can be removed 768 // Mark a short term reference picture as unused so it can be removed
702 // if outputted. 769 // if outputted.
703 pic_num_x = curr_pic_->pic_num - 770 pic_num_x =
704 (ref_pic_marking->difference_of_pic_nums_minus1 + 1); 771 pic->pic_num - (ref_pic_marking->difference_of_pic_nums_minus1 + 1);
705 to_mark = dpb_.GetShortRefPicByPicNum(pic_num_x); 772 to_mark = dpb_.GetShortRefPicByPicNum(pic_num_x);
706 if (to_mark) { 773 if (to_mark) {
707 to_mark->ref = false; 774 to_mark->ref = false;
708 } else { 775 } else {
709 DVLOG(1) << "Invalid short ref pic num to unmark"; 776 DVLOG(1) << "Invalid short ref pic num to unmark";
710 return false; 777 return false;
711 } 778 }
712 break; 779 break;
713 780
714 case 2: 781 case 2:
715 // Mark a long term reference picture as unused so it can be removed 782 // Mark a long term reference picture as unused so it can be removed
716 // if outputted. 783 // if outputted.
717 to_mark = dpb_.GetLongRefPicByLongTermPicNum( 784 to_mark = dpb_.GetLongRefPicByLongTermPicNum(
718 ref_pic_marking->long_term_pic_num); 785 ref_pic_marking->long_term_pic_num);
719 if (to_mark) { 786 if (to_mark) {
720 to_mark->ref = false; 787 to_mark->ref = false;
721 } else { 788 } else {
722 DVLOG(1) << "Invalid long term ref pic num to unmark"; 789 DVLOG(1) << "Invalid long term ref pic num to unmark";
723 return false; 790 return false;
724 } 791 }
725 break; 792 break;
726 793
727 case 3: 794 case 3:
728 // Mark a short term reference picture as long term reference. 795 // Mark a short term reference picture as long term reference.
729 pic_num_x = curr_pic_->pic_num - 796 pic_num_x =
730 (ref_pic_marking->difference_of_pic_nums_minus1 + 1); 797 pic->pic_num - (ref_pic_marking->difference_of_pic_nums_minus1 + 1);
731 to_mark = dpb_.GetShortRefPicByPicNum(pic_num_x); 798 to_mark = dpb_.GetShortRefPicByPicNum(pic_num_x);
732 if (to_mark) { 799 if (to_mark) {
733 DCHECK(to_mark->ref && !to_mark->long_term); 800 DCHECK(to_mark->ref && !to_mark->long_term);
734 to_mark->long_term = true; 801 to_mark->long_term = true;
735 to_mark->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; 802 to_mark->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
736 } else { 803 } else {
737 DVLOG(1) << "Invalid short term ref pic num to mark as long ref"; 804 DVLOG(1) << "Invalid short term ref pic num to mark as long ref";
738 return false; 805 return false;
739 } 806 }
740 break; 807 break;
741 808
742 case 4: { 809 case 4: {
743 // Unmark all reference pictures with long_term_frame_idx over new max. 810 // Unmark all reference pictures with long_term_frame_idx over new max.
744 max_long_term_frame_idx_ = 811 max_long_term_frame_idx_ =
745 ref_pic_marking->max_long_term_frame_idx_plus1 - 1; 812 ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
746 H264Picture::Vector long_terms; 813 H264Picture::Vector long_terms;
747 dpb_.GetLongTermRefPicsAppending(&long_terms); 814 dpb_.GetLongTermRefPicsAppending(&long_terms);
748 for (size_t i = 0; i < long_terms.size(); ++i) { 815 for (size_t i = 0; i < long_terms.size(); ++i) {
749 scoped_refptr<H264Picture>& pic = long_terms[i]; 816 scoped_refptr<H264Picture>& long_term_pic = long_terms[i];
750 DCHECK(pic->ref && pic->long_term); 817 DCHECK(long_term_pic->ref && long_term_pic->long_term);
751 // Ok to cast, max_long_term_frame_idx is much smaller than 16bit. 818 // Ok to cast, max_long_term_frame_idx is much smaller than 16bit.
752 if (pic->long_term_frame_idx > 819 if (long_term_pic->long_term_frame_idx >
753 static_cast<int>(max_long_term_frame_idx_)) 820 static_cast<int>(max_long_term_frame_idx_))
754 pic->ref = false; 821 long_term_pic->ref = false;
755 } 822 }
756 break; 823 break;
757 } 824 }
758 825
759 case 5: 826 case 5:
760 // Unmark all reference pictures. 827 // Unmark all reference pictures.
761 dpb_.MarkAllUnusedForRef(); 828 dpb_.MarkAllUnusedForRef();
762 max_long_term_frame_idx_ = -1; 829 max_long_term_frame_idx_ = -1;
763 curr_pic_->mem_mgmt_5 = true; 830 pic->mem_mgmt_5 = true;
764 break; 831 break;
765 832
766 case 6: { 833 case 6: {
767 // Replace long term reference pictures with current picture. 834 // Replace long term reference pictures with current picture.
768 // First unmark if any existing with this long_term_frame_idx... 835 // First unmark if any existing with this long_term_frame_idx...
769 H264Picture::Vector long_terms; 836 H264Picture::Vector long_terms;
770 dpb_.GetLongTermRefPicsAppending(&long_terms); 837 dpb_.GetLongTermRefPicsAppending(&long_terms);
771 for (size_t i = 0; i < long_terms.size(); ++i) { 838 for (size_t i = 0; i < long_terms.size(); ++i) {
772 scoped_refptr<H264Picture>& pic = long_terms[i]; 839 scoped_refptr<H264Picture>& long_term_pic = long_terms[i];
773 DCHECK(pic->ref && pic->long_term); 840 DCHECK(long_term_pic->ref && long_term_pic->long_term);
774 // Ok to cast, long_term_frame_idx is much smaller than 16bit. 841 // Ok to cast, long_term_frame_idx is much smaller than 16bit.
775 if (pic->long_term_frame_idx == 842 if (long_term_pic->long_term_frame_idx ==
776 static_cast<int>(ref_pic_marking->long_term_frame_idx)) 843 static_cast<int>(ref_pic_marking->long_term_frame_idx))
777 pic->ref = false; 844 long_term_pic->ref = false;
778 } 845 }
779 846
780 // and mark the current one instead. 847 // and mark the current one instead.
781 curr_pic_->ref = true; 848 pic->ref = true;
782 curr_pic_->long_term = true; 849 pic->long_term = true;
783 curr_pic_->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; 850 pic->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
784 break; 851 break;
785 } 852 }
786 853
787 default: 854 default:
788 // Would indicate a bug in parser. 855 // Would indicate a bug in parser.
789 NOTREACHED(); 856 NOTREACHED();
790 } 857 }
791 } 858 }
792 859
793 return true; 860 return true;
794 } 861 }
795 862
796 // This method ensures that DPB does not overflow, either by removing 863 // This method ensures that DPB does not overflow, either by removing
797 // reference pictures as specified in the stream, or using a sliding window 864 // reference pictures as specified in the stream, or using a sliding window
798 // procedure to remove the oldest one. 865 // procedure to remove the oldest one.
799 // It also performs marking and unmarking pictures as reference. 866 // It also performs marking and unmarking pictures as reference.
800 // See spac 8.2.5.1. 867 // See spac 8.2.5.1.
801 void H264Decoder::ReferencePictureMarking() { 868 bool H264Decoder::ReferencePictureMarking(scoped_refptr<H264Picture> pic) {
802 if (curr_pic_->idr) { 869 // If the current picture is an IDR, all reference pictures are unmarked.
803 // If current picture is an IDR, all reference pictures are unmarked. 870 if (pic->idr) {
804 dpb_.MarkAllUnusedForRef(); 871 dpb_.MarkAllUnusedForRef();
805 872
806 if (curr_pic_->long_term_reference_flag) { 873 if (pic->long_term_reference_flag) {
807 curr_pic_->long_term = true; 874 pic->long_term = true;
808 curr_pic_->long_term_frame_idx = 0; 875 pic->long_term_frame_idx = 0;
809 max_long_term_frame_idx_ = 0; 876 max_long_term_frame_idx_ = 0;
810 } else { 877 } else {
811 curr_pic_->long_term = false; 878 pic->long_term = false;
812 max_long_term_frame_idx_ = -1; 879 max_long_term_frame_idx_ = -1;
813 } 880 }
881
882 return true;
883 }
884
885 // Not an IDR. If the stream contains instructions on how to discard pictures
886 // from DPB and how to mark/unmark existing reference pictures, do so.
887 // Otherwise, fall back to default sliding window process.
888 if (pic->adaptive_ref_pic_marking_mode_flag) {
889 DCHECK(!pic->nonexisting);
890 return HandleMemoryManagementOps(pic);
814 } else { 891 } else {
815 if (!curr_pic_->adaptive_ref_pic_marking_mode_flag) { 892 return SlidingWindowPictureMarking();
816 // If non-IDR, and the stream does not indicate what we should do to
817 // ensure DPB doesn't overflow, discard oldest picture.
818 // See spec 8.2.5.3.
819 if (curr_pic_->field == H264Picture::FIELD_NONE) {
820 DCHECK_LE(
821 dpb_.CountRefPics(),
822 std::max<int>(parser_.GetSPS(curr_sps_id_)->max_num_ref_frames, 1));
823 if (dpb_.CountRefPics() ==
824 std::max<int>(parser_.GetSPS(curr_sps_id_)->max_num_ref_frames,
825 1)) {
826 // Max number of reference pics reached,
827 // need to remove one of the short term ones.
828 // Find smallest frame_num_wrap short reference picture and mark
829 // it as unused.
830 scoped_refptr<H264Picture> to_unmark =
831 dpb_.GetLowestFrameNumWrapShortRefPic();
832 if (to_unmark == NULL) {
833 DVLOG(1) << "Couldn't find a short ref picture to unmark";
834 return;
835 }
836 to_unmark->ref = false;
837 }
838 } else {
839 // Shouldn't get here.
840 DVLOG(1) << "Interlaced video not supported.";
841 }
842 } else {
843 // Stream has instructions how to discard pictures from DPB and how
844 // to mark/unmark existing reference pictures. Do it.
845 // Spec 8.2.5.4.
846 if (curr_pic_->field == H264Picture::FIELD_NONE) {
847 HandleMemoryManagementOps();
848 } else {
849 // Shouldn't get here.
850 DVLOG(1) << "Interlaced video not supported.";
851 }
852 }
853 } 893 }
854 } 894 }
855 895
856 bool H264Decoder::FinishPicture() { 896 bool H264Decoder::SlidingWindowPictureMarking() {
857 DCHECK(curr_pic_.get()); 897 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_);
898 if (!sps)
899 return false;
858 900
859 // Finish processing previous picture. 901 // 8.2.5.3. Ensure the DPB doesn't overflow by discarding the oldest picture.
860 // Start by storing previous reference picture data for later use, 902 int num_ref_pics = dpb_.CountRefPics();
861 // if picture being finished is a reference picture. 903 DCHECK_LE(num_ref_pics, std::max<int>(sps->max_num_ref_frames, 1));
862 if (curr_pic_->ref) { 904 if (num_ref_pics == std::max<int>(sps->max_num_ref_frames, 1)) {
863 ReferencePictureMarking(); 905 // Max number of reference pics reached, need to remove one of the short
864 prev_ref_has_memmgmnt5_ = curr_pic_->mem_mgmt_5; 906 // term ones. Find smallest frame_num_wrap short reference picture and mark
865 prev_ref_top_field_order_cnt_ = curr_pic_->top_field_order_cnt; 907 // it as unused.
866 prev_ref_pic_order_cnt_msb_ = curr_pic_->pic_order_cnt_msb; 908 scoped_refptr<H264Picture> to_unmark =
867 prev_ref_pic_order_cnt_lsb_ = curr_pic_->pic_order_cnt_lsb; 909 dpb_.GetLowestFrameNumWrapShortRefPic();
868 prev_ref_field_ = curr_pic_->field; 910 if (!to_unmark) {
911 DVLOG(1) << "Couldn't find a short ref picture to unmark";
912 return false;
913 }
914
915 to_unmark->ref = false;
869 } 916 }
870 prev_has_memmgmnt5_ = curr_pic_->mem_mgmt_5; 917
871 prev_frame_num_offset_ = curr_pic_->frame_num_offset; 918 return true;
919 }
920
921 bool H264Decoder::FinishPicture(scoped_refptr<H264Picture> pic) {
922 // Finish processing the picture.
923 // Start by storing previous picture data for later use.
924 if (pic->ref) {
925 ReferencePictureMarking(pic);
926 prev_ref_has_memmgmnt5_ = pic->mem_mgmt_5;
927 prev_ref_top_field_order_cnt_ = pic->top_field_order_cnt;
928 prev_ref_pic_order_cnt_msb_ = pic->pic_order_cnt_msb;
929 prev_ref_pic_order_cnt_lsb_ = pic->pic_order_cnt_lsb;
930 prev_ref_field_ = pic->field;
931 prev_ref_frame_num_ = pic->frame_num;
932 }
933 prev_frame_num_ = pic->frame_num;
934 prev_has_memmgmnt5_ = pic->mem_mgmt_5;
935 prev_frame_num_offset_ = pic->frame_num_offset;
872 936
873 // Remove unused (for reference or later output) pictures from DPB, marking 937 // Remove unused (for reference or later output) pictures from DPB, marking
874 // them as such. 938 // them as such.
875 dpb_.DeleteUnused(); 939 dpb_.DeleteUnused();
876 940
877 DVLOG(4) << "Finishing picture, entries in DPB: " << dpb_.size(); 941 DVLOG(4) << "Finishing picture frame_num: " << pic->frame_num
942 << ", entries in DPB: " << dpb_.size();
878 943
879 // Whatever happens below, curr_pic_ will stop managing the pointer to the 944 // The ownership of pic will either be transferred to DPB - if the picture is
880 // picture after this. The ownership will either be transferred to DPB, if 945 // still needed (for output and/or reference) - or we will release it
881 // the image is still needed (for output and/or reference), or the memory 946 // immediately if we manage to output it here and won't have to store it for
882 // will be released if we manage to output it here without having to store 947 // future reference.
883 // it for future reference.
884 scoped_refptr<H264Picture> pic = curr_pic_;
885 curr_pic_ = nullptr;
886 948
887 // Get all pictures that haven't been outputted yet. 949 // Get all pictures that haven't been outputted yet.
888 H264Picture::Vector not_outputted; 950 H264Picture::Vector not_outputted;
889 dpb_.GetNotOutputtedPicsAppending(&not_outputted); 951 dpb_.GetNotOutputtedPicsAppending(&not_outputted);
890 // Include the one we've just decoded. 952 // Include the one we've just decoded.
891 not_outputted.push_back(pic); 953 not_outputted.push_back(pic);
892 954
893 // Sort in output order. 955 // Sort in output order.
894 std::sort(not_outputted.begin(), not_outputted.end(), POCAscCompare()); 956 std::sort(not_outputted.begin(), not_outputted.end(), POCAscCompare());
895 957
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 break; 1059 break;
998 } 1060 }
999 } else { 1061 } else {
1000 max_num_reorder_frames_ = dpb_.max_num_pics(); 1062 max_num_reorder_frames_ = dpb_.max_num_pics();
1001 } 1063 }
1002 1064
1003 return true; 1065 return true;
1004 } 1066 }
1005 1067
1006 bool H264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) { 1068 bool H264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) {
1069 DVLOG(4) << "Processing SPS id:" << sps_id;
1070
1007 const media::H264SPS* sps = parser_.GetSPS(sps_id); 1071 const media::H264SPS* sps = parser_.GetSPS(sps_id);
1008 DCHECK(sps); 1072 if (!sps)
1009 DVLOG(4) << "Processing SPS"; 1073 return false;
xhwang 2015/10/12 18:01:17 In what case could this fail? (wondering why we re
Pawel Osciak 2015/10/13 01:23:22 Previously we were using std::map::operator[], whi
1010 1074
1011 *need_new_buffers = false; 1075 *need_new_buffers = false;
1012 1076
1013 if (sps->frame_mbs_only_flag == 0) { 1077 if (sps->frame_mbs_only_flag == 0) {
1014 DVLOG(1) << "frame_mbs_only_flag != 1 not supported"; 1078 DVLOG(1) << "frame_mbs_only_flag != 1 not supported";
1015 return false; 1079 return false;
1016 } 1080 }
1017 1081
1018 if (sps->gaps_in_frame_num_value_allowed_flag) {
1019 DVLOG(1) << "Gaps in frame numbers not supported";
1020 return false;
1021 }
1022
1023 curr_sps_id_ = sps->seq_parameter_set_id;
1024
1025 // Calculate picture height/width in macroblocks and pixels 1082 // Calculate picture height/width in macroblocks and pixels
1026 // (spec 7.4.2.1.1, 7.4.3). 1083 // (spec 7.4.2.1.1, 7.4.3).
1027 int width_mb = sps->pic_width_in_mbs_minus1 + 1; 1084 int width_mb = sps->pic_width_in_mbs_minus1 + 1;
1028 int height_mb = (2 - sps->frame_mbs_only_flag) * 1085 int height_mb = (2 - sps->frame_mbs_only_flag) *
1029 (sps->pic_height_in_map_units_minus1 + 1); 1086 (sps->pic_height_in_map_units_minus1 + 1);
1030 1087
1031 gfx::Size new_pic_size(16 * width_mb, 16 * height_mb); 1088 gfx::Size new_pic_size(16 * width_mb, 16 * height_mb);
1032 if (new_pic_size.IsEmpty()) { 1089 if (new_pic_size.IsEmpty()) {
1033 DVLOG(1) << "Invalid picture size: " << new_pic_size.ToString(); 1090 DVLOG(1) << "Invalid picture size: " << new_pic_size.ToString();
1034 return false; 1091 return false;
1035 } 1092 }
1036 1093
1037 if (!pic_size_.IsEmpty() && new_pic_size == pic_size_) { 1094 if (!pic_size_.IsEmpty() && new_pic_size == pic_size_) {
1038 // Already have surfaces and this SPS keeps the same resolution, 1095 // Already have surfaces and this SPS keeps the same resolution,
1039 // no need to request a new set. 1096 // no need to request a new set.
1040 return true; 1097 return true;
1041 } 1098 }
1042 1099
1043 pic_size_ = new_pic_size; 1100 pic_size_ = new_pic_size;
1044 DVLOG(1) << "New picture size: " << pic_size_.ToString(); 1101 DVLOG(1) << "New picture size: " << pic_size_.ToString();
1045 1102
1046 max_pic_order_cnt_lsb_ = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1047 max_frame_num_ = 1 << (sps->log2_max_frame_num_minus4 + 4);
1048
1049 int level = sps->level_idc; 1103 int level = sps->level_idc;
1050 int max_dpb_mbs = LevelToMaxDpbMbs(level); 1104 int max_dpb_mbs = LevelToMaxDpbMbs(level);
1051 if (max_dpb_mbs == 0) 1105 if (max_dpb_mbs == 0)
1052 return false; 1106 return false;
1053 1107
1054 size_t max_dpb_size = std::min(max_dpb_mbs / (width_mb * height_mb), 1108 size_t max_dpb_size = std::min(max_dpb_mbs / (width_mb * height_mb),
1055 static_cast<int>(H264DPB::kDPBMaxSize)); 1109 static_cast<int>(H264DPB::kDPBMaxSize));
1056 DVLOG(1) << "Codec level: " << level << ", DPB size: " << max_dpb_size; 1110 DVLOG(1) << "Codec level: " << level << ", DPB size: " << max_dpb_size;
1057 if (max_dpb_size == 0) { 1111 if (max_dpb_size == 0) {
1058 DVLOG(1) << "Invalid DPB Size"; 1112 DVLOG(1) << "Invalid DPB Size";
1059 return false; 1113 return false;
1060 } 1114 }
1061 1115
1062 dpb_.set_max_num_pics(max_dpb_size); 1116 dpb_.set_max_num_pics(max_dpb_size);
1063 1117
1064 if (!UpdateMaxNumReorderFrames(sps)) 1118 if (!UpdateMaxNumReorderFrames(sps))
1065 return false; 1119 return false;
1066 DVLOG(1) << "max_num_reorder_frames: " << max_num_reorder_frames_; 1120 DVLOG(1) << "max_num_reorder_frames: " << max_num_reorder_frames_;
1067 1121
1068 *need_new_buffers = true; 1122 *need_new_buffers = true;
1069 return true; 1123 return true;
1070 } 1124 }
1071 1125
1072 bool H264Decoder::ProcessPPS(int pps_id) {
1073 const media::H264PPS* pps = parser_.GetPPS(pps_id);
1074 DCHECK(pps);
1075
1076 curr_pps_id_ = pps->pic_parameter_set_id;
1077
1078 return true;
1079 }
1080
1081 bool H264Decoder::FinishPrevFrameIfPresent() { 1126 bool H264Decoder::FinishPrevFrameIfPresent() {
1082 // If we already have a frame waiting to be decoded, decode it and finish. 1127 // If we already have a frame waiting to be decoded, decode it and finish.
1083 if (curr_pic_ != NULL) { 1128 if (curr_pic_ != NULL) {
1084 if (!DecodePicture()) 1129 if (!DecodePicture())
1085 return false; 1130 return false;
1086 return FinishPicture(); 1131
1132 scoped_refptr<H264Picture> pic = curr_pic_;
1133 curr_pic_ = nullptr;
1134 return FinishPicture(pic);
1087 } 1135 }
1088 1136
1089 return true; 1137 return true;
1090 } 1138 }
1091 1139
1092 bool H264Decoder::PreprocessSlice(media::H264SliceHeader* slice_hdr) { 1140 bool H264Decoder::HandleFrameNumGap(int frame_num) {
1093 prev_frame_num_ = frame_num_; 1141 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_);
1094 frame_num_ = slice_hdr->frame_num; 1142 if (!sps)
1143 return false;
1095 1144
1096 if (prev_frame_num_ > 0 && prev_frame_num_ < frame_num_ - 1) { 1145 if (!sps->gaps_in_frame_num_value_allowed_flag) {
1097 DVLOG(1) << "Gap in frame_num!"; 1146 DVLOG(1) << "Invalid frame_num: " << frame_num;
1098 return false; 1147 return false;
1099 } 1148 }
1100 1149
1150 DVLOG(2) << "Handling frame_num gap: " << prev_ref_frame_num_ << "->"
1151 << frame_num;
1152
1153 // 7.4.3/7-23
1154 int unused_short_term_frame_num = (prev_ref_frame_num_ + 1) % max_frame_num_;
1155 while (unused_short_term_frame_num != frame_num) {
1156 scoped_refptr<H264Picture> pic = new H264Picture();
1157 if (!InitNonexistingPicture(pic, unused_short_term_frame_num))
xhwang 2015/10/12 18:01:17 Can we follow the RAII (https://en.wikipedia.org/w
Pawel Osciak 2015/10/13 01:23:22 My intention with H264Picture was to keep it as PO
1158 return false;
1159
1160 UpdatePicNums(unused_short_term_frame_num);
1161
1162 if (!FinishPicture(pic))
1163 return false;
1164
1165 unused_short_term_frame_num++;
1166 unused_short_term_frame_num %= max_frame_num_;
1167 }
1168
1169 return true;
1170 }
1171
1172 bool H264Decoder::IsNewPrimaryCodedPicture(
1173 const media::H264SliceHeader* slice_hdr) const {
1174 if (!curr_pic_)
1175 return true;
1176
1177 // 7.4.1.2.4, assumes non-interlaced.
1178 if (slice_hdr->frame_num != curr_pic_->frame_num ||
1179 slice_hdr->pic_parameter_set_id != curr_pps_id_ ||
1180 slice_hdr->nal_ref_idc != curr_pic_->nal_ref_idc ||
1181 slice_hdr->idr_pic_flag != curr_pic_->idr ||
1182 (slice_hdr->idr_pic_flag &&
1183 slice_hdr->idr_pic_id != curr_pic_->idr_pic_id))
1184 return true;
1185
1186 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_);
1187 if (!sps)
1188 return false;
1189
1190 if (sps->pic_order_cnt_type == curr_pic_->pic_order_cnt_type) {
1191 if (curr_pic_->pic_order_cnt_type == 0) {
1192 if (slice_hdr->pic_order_cnt_lsb != curr_pic_->pic_order_cnt_lsb ||
1193 slice_hdr->delta_pic_order_cnt_bottom !=
1194 curr_pic_->delta_pic_order_cnt_bottom)
1195 return true;
1196 } else if (curr_pic_->pic_order_cnt_type == 1) {
1197 if (slice_hdr->delta_pic_order_cnt0 != curr_pic_->delta_pic_order_cnt0 ||
1198 slice_hdr->delta_pic_order_cnt1 != curr_pic_->delta_pic_order_cnt1)
1199 return true;
1200 }
1201 }
1202
1203 return false;
1204 }
1205
1206 bool H264Decoder::PreprocessCurrentSlice() {
1207 const media::H264SliceHeader* slice_hdr = curr_slice_hdr_.get();
1208 DCHECK(slice_hdr);
1209
1210 if (IsNewPrimaryCodedPicture(slice_hdr)) {
1211 // New picture, so first finish the previous one before processing it.
1212 if (!FinishPrevFrameIfPresent())
1213 return false;
1214
1215 DCHECK(!curr_pic_);
1216
1217 if (slice_hdr->first_mb_in_slice != 0) {
1218 DVLOG(1) << "ASO/invalid stream, first_mb_in_slice: "
1219 << slice_hdr->first_mb_in_slice;
1220 return false;
1221 }
1222
1223 // If the new picture is an IDR, flush DPB.
1224 if (slice_hdr->idr_pic_flag) {
1225 // Output all remaining pictures, unless we are explicitly instructed
1226 // not to do so.
1227 if (!slice_hdr->no_output_of_prior_pics_flag) {
1228 if (!Flush())
1229 return false;
1230 }
1231 dpb_.Clear();
1232 last_output_poc_ = std::numeric_limits<int>::min();
1233 }
1234 }
1235
1236 return true;
1237 }
1238
1239 bool H264Decoder::ProcessCurrentSlice() {
1240 DCHECK(curr_pic_);
1241
1242 const media::H264SliceHeader* slice_hdr = curr_slice_hdr_.get();
1243 DCHECK(slice_hdr);
1244
1101 if (slice_hdr->field_pic_flag == 0) 1245 if (slice_hdr->field_pic_flag == 0)
1102 max_pic_num_ = max_frame_num_; 1246 max_pic_num_ = max_frame_num_;
1103 else 1247 else
1104 max_pic_num_ = 2 * max_frame_num_; 1248 max_pic_num_ = 2 * max_frame_num_;
1105 1249
1106 // TODO posciak: switch to new picture detection per 7.4.1.2.4.
1107 if (curr_pic_ != NULL && slice_hdr->first_mb_in_slice != 0) {
1108 // More slice data of the current picture.
1109 return true;
1110 } else {
1111 // A new frame, so first finish the previous one before processing it...
1112 if (!FinishPrevFrameIfPresent())
1113 return false;
1114 }
1115
1116 // If the new frame is an IDR, output what's left to output and clear DPB
1117 if (slice_hdr->idr_pic_flag) {
1118 // (unless we are explicitly instructed not to do so).
1119 if (!slice_hdr->no_output_of_prior_pics_flag) {
1120 // Output DPB contents.
1121 if (!Flush())
1122 return false;
1123 }
1124 dpb_.Clear();
1125 last_output_poc_ = std::numeric_limits<int>::min();
1126 }
1127
1128 return true;
1129 }
1130
1131 bool H264Decoder::ProcessSlice(media::H264SliceHeader* slice_hdr) {
1132 DCHECK(curr_pic_.get());
1133 H264Picture::Vector ref_pic_list0, ref_pic_list1; 1250 H264Picture::Vector ref_pic_list0, ref_pic_list1;
1134
1135 if (!ModifyReferencePicLists(slice_hdr, &ref_pic_list0, &ref_pic_list1)) 1251 if (!ModifyReferencePicLists(slice_hdr, &ref_pic_list0, &ref_pic_list1))
1136 return false; 1252 return false;
1137 1253
1138 const media::H264PPS* pps = parser_.GetPPS(slice_hdr->pic_parameter_set_id); 1254 const media::H264PPS* pps = parser_.GetPPS(curr_pps_id_);
1139 DCHECK(pps); 1255 if (!pps)
1256 return false;
1140 1257
1141 if (!accelerator_->SubmitSlice(pps, slice_hdr, ref_pic_list0, ref_pic_list1, 1258 if (!accelerator_->SubmitSlice(pps, slice_hdr, ref_pic_list0, ref_pic_list1,
1142 curr_pic_.get(), slice_hdr->nalu_data, 1259 curr_pic_.get(), slice_hdr->nalu_data,
1143 slice_hdr->nalu_size)) 1260 slice_hdr->nalu_size))
1144 return false; 1261 return false;
1145 1262
1146 curr_slice_hdr_.reset();
1147 return true; 1263 return true;
1148 } 1264 }
1149 1265
1150 #define SET_ERROR_AND_RETURN() \ 1266 #define SET_ERROR_AND_RETURN() \
1151 do { \ 1267 do { \
1152 DVLOG(1) << "Error during decode"; \ 1268 DVLOG(1) << "Error during decode"; \
1153 state_ = kError; \ 1269 state_ = kError; \
1154 return H264Decoder::kDecodeError; \ 1270 return H264Decoder::kDecodeError; \
1155 } while (0) 1271 } while (0)
1156 1272
1157 void H264Decoder::SetStream(const uint8_t* ptr, size_t size) { 1273 void H264Decoder::SetStream(const uint8_t* ptr, size_t size) {
1158 DCHECK(ptr); 1274 DCHECK(ptr);
1159 DCHECK(size); 1275 DCHECK(size);
1160 1276
1161 DVLOG(4) << "New input stream at: " << (void*)ptr << " size: " << size; 1277 DVLOG(4) << "New input stream at: " << (void*)ptr << " size: " << size;
1162 parser_.SetStream(ptr, size); 1278 parser_.SetStream(ptr, size);
1163 } 1279 }
1164 1280
1165 H264Decoder::DecodeResult H264Decoder::Decode() { 1281 H264Decoder::DecodeResult H264Decoder::Decode() {
1166 DCHECK_NE(state_, kError); 1282 if (state_ == kError) {
1283 DVLOG(1) << "Decoder in error state";
1284 return kDecodeError;
1285 }
1167 1286
1168 while (1) { 1287 while (1) {
1169 media::H264Parser::Result par_res; 1288 media::H264Parser::Result par_res;
1170 1289
1171 if (!curr_nalu_) { 1290 if (!curr_nalu_) {
1172 curr_nalu_.reset(new media::H264NALU()); 1291 curr_nalu_.reset(new media::H264NALU());
1173 par_res = parser_.AdvanceToNextNALU(curr_nalu_.get()); 1292 par_res = parser_.AdvanceToNextNALU(curr_nalu_.get());
1174 if (par_res == media::H264Parser::kEOStream) 1293 if (par_res == media::H264Parser::kEOStream)
1175 return kRanOutOfStreamData; 1294 return kRanOutOfStreamData;
1176 else if (par_res != media::H264Parser::kOk) 1295 else if (par_res != media::H264Parser::kOk)
1177 SET_ERROR_AND_RETURN(); 1296 SET_ERROR_AND_RETURN();
1297
1298 DVLOG(4) << "New NALU: " << static_cast<int>(curr_nalu_->nal_unit_type);
1178 } 1299 }
1179 1300
1180 DVLOG(4) << "NALU found: " << static_cast<int>(curr_nalu_->nal_unit_type);
1181
1182 switch (curr_nalu_->nal_unit_type) { 1301 switch (curr_nalu_->nal_unit_type) {
1183 case media::H264NALU::kNonIDRSlice: 1302 case media::H264NALU::kNonIDRSlice:
1184 // We can't resume from a non-IDR slice. 1303 // We can't resume from a non-IDR slice.
1185 if (state_ != kDecoding) 1304 if (state_ != kDecoding)
1186 break; 1305 break;
1187 // else fallthrough 1306 // else fallthrough
1188 case media::H264NALU::kIDRSlice: { 1307 case media::H264NALU::kIDRSlice: {
1189 // TODO(posciak): the IDR may require an SPS that we don't have 1308 // TODO(posciak): the IDR may require an SPS that we don't have
1190 // available. For now we'd fail if that happens, but ideally we'd like 1309 // available. For now we'd fail if that happens, but ideally we'd like
1191 // to keep going until the next SPS in the stream. 1310 // to keep going until the next SPS in the stream.
1192 if (state_ == kNeedStreamMetadata) { 1311 if (state_ == kNeedStreamMetadata) {
1193 // We need an SPS, skip this IDR and keep looking. 1312 // We need an SPS, skip this IDR and keep looking.
1194 break; 1313 break;
1195 } 1314 }
1196 1315
1197 // If after reset, we should be able to recover from an IDR. 1316 // If after reset, we should be able to recover from an IDR.
1317 state_ = kDecoding;
1318
1198 if (!curr_slice_hdr_) { 1319 if (!curr_slice_hdr_) {
1199 curr_slice_hdr_.reset(new media::H264SliceHeader()); 1320 curr_slice_hdr_.reset(new media::H264SliceHeader());
1200 par_res = 1321 par_res =
1201 parser_.ParseSliceHeader(*curr_nalu_, curr_slice_hdr_.get()); 1322 parser_.ParseSliceHeader(*curr_nalu_, curr_slice_hdr_.get());
1202 if (par_res != media::H264Parser::kOk) 1323 if (par_res != media::H264Parser::kOk)
1203 SET_ERROR_AND_RETURN(); 1324 SET_ERROR_AND_RETURN();
1204 1325
1205 if (!PreprocessSlice(curr_slice_hdr_.get())) 1326 if (!PreprocessCurrentSlice())
1206 SET_ERROR_AND_RETURN(); 1327 SET_ERROR_AND_RETURN();
1207 } 1328 }
1208 1329
1209 if (!curr_pic_) { 1330 if (!curr_pic_) {
1210 // New picture/finished previous one, try to start a new one 1331 // New picture/finished previous one, try to start a new one
1211 // or tell the client we need more surfaces. 1332 // or tell the client we need more surfaces.
1212 curr_pic_ = accelerator_->CreateH264Picture(); 1333 curr_pic_ = accelerator_->CreateH264Picture();
1213 if (!curr_pic_) 1334 if (!curr_pic_)
1214 return kRanOutOfSurfaces; 1335 return kRanOutOfSurfaces;
1215 1336
1216 if (!StartNewFrame(curr_slice_hdr_.get())) 1337 if (!StartNewFrame(curr_slice_hdr_.get()))
1217 SET_ERROR_AND_RETURN(); 1338 SET_ERROR_AND_RETURN();
1218 } 1339 }
1219 1340
1220 if (!ProcessSlice(curr_slice_hdr_.get())) 1341 if (!ProcessCurrentSlice())
1221 SET_ERROR_AND_RETURN(); 1342 SET_ERROR_AND_RETURN();
1222 1343
1223 state_ = kDecoding; 1344 curr_slice_hdr_.reset();
1224 break; 1345 break;
1225 } 1346 }
1226 1347
1227 case media::H264NALU::kSPS: { 1348 case media::H264NALU::kSPS: {
1228 int sps_id; 1349 int sps_id;
1229 1350
1230 if (!FinishPrevFrameIfPresent()) 1351 if (!FinishPrevFrameIfPresent())
1231 SET_ERROR_AND_RETURN(); 1352 SET_ERROR_AND_RETURN();
1232 1353
1233 par_res = parser_.ParseSPS(&sps_id); 1354 par_res = parser_.ParseSPS(&sps_id);
(...skipping 27 matching lines...) Expand all
1261 1382
1262 int pps_id; 1383 int pps_id;
1263 1384
1264 if (!FinishPrevFrameIfPresent()) 1385 if (!FinishPrevFrameIfPresent())
1265 SET_ERROR_AND_RETURN(); 1386 SET_ERROR_AND_RETURN();
1266 1387
1267 par_res = parser_.ParsePPS(&pps_id); 1388 par_res = parser_.ParsePPS(&pps_id);
1268 if (par_res != media::H264Parser::kOk) 1389 if (par_res != media::H264Parser::kOk)
1269 SET_ERROR_AND_RETURN(); 1390 SET_ERROR_AND_RETURN();
1270 1391
1271 if (!ProcessPPS(pps_id))
1272 SET_ERROR_AND_RETURN();
1273 break; 1392 break;
1274 } 1393 }
1275 1394
1276 default: 1395 default:
1277 DVLOG(4) << "Skipping NALU type: " << curr_nalu_->nal_unit_type; 1396 DVLOG(4) << "Skipping NALU type: " << curr_nalu_->nal_unit_type;
1278 break; 1397 break;
1279 } 1398 }
1280 1399
1281 DVLOG(4) << "Dropping nalu"; 1400 DVLOG(4) << "NALU done";
1282 curr_nalu_.reset(); 1401 curr_nalu_.reset();
1283 } 1402 }
1284 } 1403 }
1285 1404
1286 gfx::Size H264Decoder::GetPicSize() const { 1405 gfx::Size H264Decoder::GetPicSize() const {
1287 return pic_size_; 1406 return pic_size_;
1288 } 1407 }
1289 1408
1290 size_t H264Decoder::GetRequiredNumOfPictures() const { 1409 size_t H264Decoder::GetRequiredNumOfPictures() const {
1291 return dpb_.max_num_pics() + kPicsInPipeline; 1410 return dpb_.max_num_pics() + kPicsInPipeline;
1292 } 1411 }
1293 1412
1294 } // namespace content 1413 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698