OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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(¬_outputted); | 948 dpb_.GetNotOutputtedPicsAppending(¬_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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |