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

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

Powered by Google App Engine
This is Rietveld 408576698