OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 // This file contains an implementation of a VP9 bitstream parser. | 5 // This file contains an implementation of a VP9 bitstream parser. |
6 // | 6 // |
7 // VERBOSE level: | 7 // VERBOSE level: |
8 // 1 something wrong in bitstream | 8 // 1 something wrong in bitstream |
9 // 2 parsing steps | 9 // 2 parsing steps |
10 // 3 parsed values (selected) | 10 // 3 parsed values (selected) |
(...skipping 18 matching lines...) Expand all Loading... |
29 return !show_existing_frame && frame_type == KEYFRAME; | 29 return !show_existing_frame && frame_type == KEYFRAME; |
30 } | 30 } |
31 | 31 |
32 bool Vp9FrameHeader::IsIntra() const { | 32 bool Vp9FrameHeader::IsIntra() const { |
33 return !show_existing_frame && (frame_type == KEYFRAME || intra_only); | 33 return !show_existing_frame && (frame_type == KEYFRAME || intra_only); |
34 } | 34 } |
35 | 35 |
36 Vp9Parser::FrameInfo::FrameInfo(const uint8_t* ptr, off_t size) | 36 Vp9Parser::FrameInfo::FrameInfo(const uint8_t* ptr, off_t size) |
37 : ptr(ptr), size(size) {} | 37 : ptr(ptr), size(size) {} |
38 | 38 |
39 Vp9FrameContextManager::Vp9FrameContextManager() : weak_ptr_factory_(this) {} | 39 bool Vp9FrameContext::IsValid() const { |
40 | |
41 Vp9FrameContextManager::~Vp9FrameContextManager() {} | |
42 | |
43 bool Vp9FrameContextManager::IsValidFrameContext( | |
44 const Vp9FrameContext& context) { | |
45 // probs should be in [1, 255] range. | 40 // probs should be in [1, 255] range. |
46 static_assert(sizeof(Vp9Prob) == 1, | 41 static_assert(sizeof(Vp9Prob) == 1, |
47 "following checks assuming Vp9Prob is single byte"); | 42 "following checks assuming Vp9Prob is single byte"); |
48 if (memchr(context.tx_probs_8x8, 0, sizeof(context.tx_probs_8x8))) | 43 if (memchr(tx_probs_8x8, 0, sizeof(tx_probs_8x8))) |
49 return false; | 44 return false; |
50 if (memchr(context.tx_probs_16x16, 0, sizeof(context.tx_probs_16x16))) | 45 if (memchr(tx_probs_16x16, 0, sizeof(tx_probs_16x16))) |
51 return false; | 46 return false; |
52 if (memchr(context.tx_probs_32x32, 0, sizeof(context.tx_probs_32x32))) | 47 if (memchr(tx_probs_32x32, 0, sizeof(tx_probs_32x32))) |
53 return false; | 48 return false; |
54 | 49 |
55 for (auto& a : context.coef_probs) { | 50 for (auto& a : coef_probs) { |
56 for (auto& ai : a) { | 51 for (auto& ai : a) { |
57 for (auto& aj : ai) { | 52 for (auto& aj : ai) { |
58 for (auto& ak : aj) { | 53 for (auto& ak : aj) { |
59 int max_l = (ak == aj[0]) ? 3 : 6; | 54 int max_l = (ak == aj[0]) ? 3 : 6; |
60 for (int l = 0; l < max_l; l++) { | 55 for (int l = 0; l < max_l; l++) { |
61 for (auto& x : ak[l]) { | 56 for (auto& x : ak[l]) { |
62 if (x == 0) | 57 if (x == 0) |
63 return false; | 58 return false; |
64 } | 59 } |
65 } | 60 } |
66 } | 61 } |
67 } | 62 } |
68 } | 63 } |
69 } | 64 } |
70 if (memchr(context.skip_prob, 0, sizeof(context.skip_prob))) | 65 if (memchr(skip_prob, 0, sizeof(skip_prob))) |
71 return false; | 66 return false; |
72 if (memchr(context.inter_mode_probs, 0, sizeof(context.inter_mode_probs))) | 67 if (memchr(inter_mode_probs, 0, sizeof(inter_mode_probs))) |
73 return false; | 68 return false; |
74 if (memchr(context.interp_filter_probs, 0, | 69 if (memchr(interp_filter_probs, 0, sizeof(interp_filter_probs))) |
75 sizeof(context.interp_filter_probs))) | |
76 return false; | 70 return false; |
77 if (memchr(context.is_inter_prob, 0, sizeof(context.is_inter_prob))) | 71 if (memchr(is_inter_prob, 0, sizeof(is_inter_prob))) |
78 return false; | 72 return false; |
79 if (memchr(context.comp_mode_prob, 0, sizeof(context.comp_mode_prob))) | 73 if (memchr(comp_mode_prob, 0, sizeof(comp_mode_prob))) |
80 return false; | 74 return false; |
81 if (memchr(context.single_ref_prob, 0, sizeof(context.single_ref_prob))) | 75 if (memchr(single_ref_prob, 0, sizeof(single_ref_prob))) |
82 return false; | 76 return false; |
83 if (memchr(context.comp_ref_prob, 0, sizeof(context.comp_ref_prob))) | 77 if (memchr(comp_ref_prob, 0, sizeof(comp_ref_prob))) |
84 return false; | 78 return false; |
85 if (memchr(context.y_mode_probs, 0, sizeof(context.y_mode_probs))) | 79 if (memchr(y_mode_probs, 0, sizeof(y_mode_probs))) |
86 return false; | 80 return false; |
87 if (memchr(context.uv_mode_probs, 0, sizeof(context.uv_mode_probs))) | 81 if (memchr(uv_mode_probs, 0, sizeof(uv_mode_probs))) |
88 return false; | 82 return false; |
89 if (memchr(context.partition_probs, 0, sizeof(context.partition_probs))) | 83 if (memchr(partition_probs, 0, sizeof(partition_probs))) |
90 return false; | 84 return false; |
91 if (memchr(context.mv_joint_probs, 0, sizeof(context.mv_joint_probs))) | 85 if (memchr(mv_joint_probs, 0, sizeof(mv_joint_probs))) |
92 return false; | 86 return false; |
93 if (memchr(context.mv_sign_prob, 0, sizeof(context.mv_sign_prob))) | 87 if (memchr(mv_sign_prob, 0, sizeof(mv_sign_prob))) |
94 return false; | 88 return false; |
95 if (memchr(context.mv_class_probs, 0, sizeof(context.mv_class_probs))) | 89 if (memchr(mv_class_probs, 0, sizeof(mv_class_probs))) |
96 return false; | 90 return false; |
97 if (memchr(context.mv_class0_bit_prob, 0, sizeof(context.mv_class0_bit_prob))) | 91 if (memchr(mv_class0_bit_prob, 0, sizeof(mv_class0_bit_prob))) |
98 return false; | 92 return false; |
99 if (memchr(context.mv_bits_prob, 0, sizeof(context.mv_bits_prob))) | 93 if (memchr(mv_bits_prob, 0, sizeof(mv_bits_prob))) |
100 return false; | 94 return false; |
101 if (memchr(context.mv_class0_fr_probs, 0, sizeof(context.mv_class0_fr_probs))) | 95 if (memchr(mv_class0_fr_probs, 0, sizeof(mv_class0_fr_probs))) |
102 return false; | 96 return false; |
103 if (memchr(context.mv_fr_probs, 0, sizeof(context.mv_fr_probs))) | 97 if (memchr(mv_fr_probs, 0, sizeof(mv_fr_probs))) |
104 return false; | 98 return false; |
105 if (memchr(context.mv_class0_hp_prob, 0, sizeof(context.mv_class0_hp_prob))) | 99 if (memchr(mv_class0_hp_prob, 0, sizeof(mv_class0_hp_prob))) |
106 return false; | 100 return false; |
107 if (memchr(context.mv_hp_prob, 0, sizeof(context.mv_hp_prob))) | 101 if (memchr(mv_hp_prob, 0, sizeof(mv_hp_prob))) |
108 return false; | 102 return false; |
109 | 103 |
110 return true; | 104 return true; |
111 } | 105 } |
112 | 106 |
113 const Vp9FrameContext& Vp9FrameContextManager::frame_context() const { | 107 Vp9Parser::Context::Vp9FrameContextManager::Vp9FrameContextManager() |
| 108 : weak_ptr_factory_(this) {} |
| 109 |
| 110 Vp9Parser::Context::Vp9FrameContextManager::~Vp9FrameContextManager() {} |
| 111 |
| 112 const Vp9FrameContext& |
| 113 Vp9Parser::Context::Vp9FrameContextManager::frame_context() const { |
114 DCHECK(initialized_); | 114 DCHECK(initialized_); |
115 DCHECK(!needs_client_update_); | 115 DCHECK(!needs_client_update_); |
116 return frame_context_; | 116 return frame_context_; |
117 } | 117 } |
118 | 118 |
119 void Vp9FrameContextManager::Reset() { | 119 void Vp9Parser::Context::Vp9FrameContextManager::Reset() { |
120 initialized_ = false; | 120 initialized_ = false; |
121 needs_client_update_ = false; | 121 needs_client_update_ = false; |
122 weak_ptr_factory_.InvalidateWeakPtrs(); | 122 weak_ptr_factory_.InvalidateWeakPtrs(); |
123 } | 123 } |
124 | 124 |
125 Vp9FrameContextManager::ContextRefreshCallback | 125 void Vp9Parser::Context::Vp9FrameContextManager::SetNeedsClientUpdate() { |
126 Vp9FrameContextManager::SetNeedsClientUpdate() { | |
127 DCHECK(!needs_client_update_); | 126 DCHECK(!needs_client_update_); |
128 initialized_ = true; | 127 initialized_ = true; |
129 needs_client_update_ = true; | 128 needs_client_update_ = true; |
130 | |
131 return base::Bind(&Vp9FrameContextManager::UpdateFromClient, | |
132 weak_ptr_factory_.GetWeakPtr()); | |
133 } | 129 } |
134 | 130 |
135 void Vp9FrameContextManager::Update(const Vp9FrameContext& frame_context) { | 131 Vp9Parser::ContextRefreshCallback |
| 132 Vp9Parser::Context::Vp9FrameContextManager::GetUpdateCb() { |
| 133 if (needs_client_update_) |
| 134 return base::Bind(&Vp9FrameContextManager::UpdateFromClient, |
| 135 weak_ptr_factory_.GetWeakPtr()); |
| 136 else |
| 137 return Vp9Parser::ContextRefreshCallback(); |
| 138 } |
| 139 |
| 140 void Vp9Parser::Context::Vp9FrameContextManager::Update( |
| 141 const Vp9FrameContext& frame_context) { |
136 // DCHECK because we can trust values from our parser. | 142 // DCHECK because we can trust values from our parser. |
137 DCHECK(IsValidFrameContext(frame_context)); | 143 DCHECK(frame_context.IsValid()); |
138 initialized_ = true; | 144 initialized_ = true; |
139 frame_context_ = frame_context; | 145 frame_context_ = frame_context; |
140 | 146 |
141 // For frame context we are updating, it may be still awaiting previous | 147 // For frame context we are updating, it may be still awaiting previous |
142 // ContextRefreshCallback. Because we overwrite the value of context here and | 148 // ContextRefreshCallback. Because we overwrite the value of context here and |
143 // previous ContextRefreshCallback no longer matters, invalidate the weak ptr | 149 // previous ContextRefreshCallback no longer matters, invalidate the weak ptr |
144 // to prevent previous ContextRefreshCallback run. | 150 // to prevent previous ContextRefreshCallback run. |
145 // With this optimization, we may be able to parse more frames while previous | 151 // With this optimization, we may be able to parse more frames while previous |
146 // are still decoding. | 152 // are still decoding. |
147 weak_ptr_factory_.InvalidateWeakPtrs(); | 153 weak_ptr_factory_.InvalidateWeakPtrs(); |
148 needs_client_update_ = false; | 154 needs_client_update_ = false; |
149 } | 155 } |
150 | 156 |
151 void Vp9FrameContextManager::UpdateFromClient( | 157 void Vp9Parser::Context::Vp9FrameContextManager::UpdateFromClient( |
152 const Vp9FrameContext& frame_context) { | 158 const Vp9FrameContext& frame_context) { |
153 DVLOG(2) << "Got external frame_context update"; | 159 DVLOG(2) << "Got external frame_context update"; |
154 DCHECK(needs_client_update_); | 160 DCHECK(needs_client_update_); |
155 if (!IsValidFrameContext(frame_context)) { | 161 if (!frame_context.IsValid()) { |
156 DLOG(ERROR) << "Invalid prob value in frame_context"; | 162 DLOG(ERROR) << "Invalid prob value in frame_context"; |
157 return; | 163 return; |
158 } | 164 } |
159 needs_client_update_ = false; | 165 needs_client_update_ = false; |
160 initialized_ = true; | 166 initialized_ = true; |
161 frame_context_ = frame_context; | 167 frame_context_ = frame_context; |
162 } | 168 } |
163 | 169 |
164 void Vp9Parser::Context::Reset() { | 170 void Vp9Parser::Context::Reset() { |
165 memset(&segmentation, 0, sizeof(segmentation)); | 171 memset(&segmentation_, 0, sizeof(segmentation_)); |
166 memset(&loop_filter, 0, sizeof(loop_filter)); | 172 memset(&loop_filter_, 0, sizeof(loop_filter_)); |
167 memset(&ref_slots, 0, sizeof(ref_slots)); | 173 memset(&ref_slots_, 0, sizeof(ref_slots_)); |
168 for (auto& manager : frame_context_managers) | 174 for (auto& manager : frame_context_managers_) |
169 manager.Reset(); | 175 manager.Reset(); |
170 } | 176 } |
171 | 177 |
| 178 void Vp9Parser::Context::MarkFrameContextForUpdate(size_t frame_context_idx) { |
| 179 DCHECK_LT(frame_context_idx, arraysize(frame_context_managers_)); |
| 180 frame_context_managers_[frame_context_idx].SetNeedsClientUpdate(); |
| 181 } |
| 182 |
| 183 void Vp9Parser::Context::UpdateFrameContext( |
| 184 size_t frame_context_idx, |
| 185 const Vp9FrameContext& frame_context) { |
| 186 DCHECK_LT(frame_context_idx, arraysize(frame_context_managers_)); |
| 187 frame_context_managers_[frame_context_idx].Update(frame_context); |
| 188 } |
| 189 |
| 190 const Vp9Parser::ReferenceSlot& Vp9Parser::Context::GetRefSlot( |
| 191 size_t ref_type) const { |
| 192 DCHECK_LT(ref_type, arraysize(ref_slots_)); |
| 193 return ref_slots_[ref_type]; |
| 194 } |
| 195 |
| 196 void Vp9Parser::Context::UpdateRefSlot( |
| 197 size_t ref_type, |
| 198 const Vp9Parser::ReferenceSlot& ref_slot) { |
| 199 DCHECK_LT(ref_type, arraysize(ref_slots_)); |
| 200 ref_slots_[ref_type] = ref_slot; |
| 201 } |
| 202 |
172 Vp9Parser::Vp9Parser(bool parsing_compressed_header) | 203 Vp9Parser::Vp9Parser(bool parsing_compressed_header) |
173 : parsing_compressed_header_(parsing_compressed_header) { | 204 : parsing_compressed_header_(parsing_compressed_header) { |
174 Reset(); | 205 Reset(); |
175 } | 206 } |
176 | 207 |
177 Vp9Parser::~Vp9Parser() {} | 208 Vp9Parser::~Vp9Parser() {} |
178 | 209 |
179 void Vp9Parser::SetStream(const uint8_t* stream, off_t stream_size) { | 210 void Vp9Parser::SetStream(const uint8_t* stream, off_t stream_size) { |
180 DCHECK(stream); | 211 DCHECK(stream); |
181 stream_ = stream; | 212 stream_ = stream; |
182 bytes_left_ = stream_size; | 213 bytes_left_ = stream_size; |
183 frames_.clear(); | 214 frames_.clear(); |
184 } | 215 } |
185 | 216 |
186 void Vp9Parser::Reset() { | 217 void Vp9Parser::Reset() { |
187 stream_ = nullptr; | 218 stream_ = nullptr; |
188 bytes_left_ = 0; | 219 bytes_left_ = 0; |
189 frames_.clear(); | 220 frames_.clear(); |
190 | 221 |
191 context_.Reset(); | 222 context_.Reset(); |
192 } | 223 } |
193 | 224 |
194 Vp9Parser::Result Vp9Parser::ParseNextFrame( | 225 Vp9Parser::Result Vp9Parser::ParseNextFrame(Vp9FrameHeader* fhdr) { |
195 Vp9FrameHeader* fhdr, | |
196 Vp9FrameContextManager::ContextRefreshCallback* context_refresh_cb) { | |
197 DCHECK(fhdr); | 226 DCHECK(fhdr); |
198 DCHECK(!parsing_compressed_header_ || context_refresh_cb); | |
199 DVLOG(2) << "ParseNextFrame"; | 227 DVLOG(2) << "ParseNextFrame"; |
200 | 228 |
201 // If |curr_frame_info_| is valid, uncompressed header was parsed into | 229 // If |curr_frame_info_| is valid, uncompressed header was parsed into |
202 // |curr_frame_header_| and we are awaiting context update to proceed with | 230 // |curr_frame_header_| and we are awaiting context update to proceed with |
203 // compressed header parsing. | 231 // compressed header parsing. |
204 if (!curr_frame_info_.IsValid()) { | 232 if (!curr_frame_info_.IsValid()) { |
205 if (frames_.empty()) { | 233 if (frames_.empty()) { |
206 // No frames to be decoded, if there is no more stream, request more. | 234 // No frames to be decoded, if there is no more stream, request more. |
207 if (!stream_) | 235 if (!stream_) |
208 return kEOStream; | 236 return kEOStream; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 DVLOG(1) << "header_size_in_bytes=" | 272 DVLOG(1) << "header_size_in_bytes=" |
245 << curr_frame_header_.header_size_in_bytes | 273 << curr_frame_header_.header_size_in_bytes |
246 << " is larger than bytes left in buffer: " | 274 << " is larger than bytes left in buffer: " |
247 << curr_frame_info_.size - | 275 << curr_frame_info_.size - |
248 curr_frame_header_.uncompressed_header_size; | 276 curr_frame_header_.uncompressed_header_size; |
249 return kInvalidStream; | 277 return kInvalidStream; |
250 } | 278 } |
251 } | 279 } |
252 | 280 |
253 if (parsing_compressed_header_) { | 281 if (parsing_compressed_header_) { |
254 Vp9FrameContextManager& context_to_load = | 282 size_t frame_context_idx = curr_frame_header_.frame_context_idx; |
255 context_.frame_context_managers[curr_frame_header_.frame_context_idx]; | 283 const Context::Vp9FrameContextManager& context_to_load = |
| 284 context_.frame_context_managers_[frame_context_idx]; |
256 if (!context_to_load.initialized()) { | 285 if (!context_to_load.initialized()) { |
257 // 8.2 Frame order constraints | 286 // 8.2 Frame order constraints |
258 // must load an initialized set of probabilities. | 287 // must load an initialized set of probabilities. |
259 DVLOG(1) << "loading uninitialized frame context, index=" | 288 DVLOG(1) << "loading uninitialized frame context, index=" |
260 << curr_frame_header_.frame_context_idx; | 289 << frame_context_idx; |
261 return kInvalidStream; | 290 return kInvalidStream; |
262 } | 291 } |
263 if (context_to_load.needs_client_update()) { | 292 if (context_to_load.needs_client_update()) { |
264 DVLOG(3) << "waiting frame_context_idx=" | 293 DVLOG(3) << "waiting frame_context_idx=" << frame_context_idx |
265 << static_cast<int>(curr_frame_header_.frame_context_idx) | |
266 << " to update"; | 294 << " to update"; |
267 return kAwaitingRefresh; | 295 return kAwaitingRefresh; |
268 } | 296 } |
269 curr_frame_header_.initial_frame_context = | 297 curr_frame_header_.initial_frame_context = |
270 curr_frame_header_.frame_context = context_to_load.frame_context(); | 298 curr_frame_header_.frame_context = context_to_load.frame_context(); |
271 | 299 |
272 Vp9CompressedHeaderParser compressed_parser; | 300 Vp9CompressedHeaderParser compressed_parser; |
273 if (!compressed_parser.Parse( | 301 if (!compressed_parser.Parse( |
274 curr_frame_info_.ptr + curr_frame_header_.uncompressed_header_size, | 302 curr_frame_info_.ptr + curr_frame_header_.uncompressed_header_size, |
275 curr_frame_header_.header_size_in_bytes, &curr_frame_header_)) { | 303 curr_frame_header_.header_size_in_bytes, &curr_frame_header_)) { |
276 return kInvalidStream; | 304 return kInvalidStream; |
277 } | 305 } |
278 | 306 |
279 if (curr_frame_header_.refresh_frame_context) { | 307 if (curr_frame_header_.refresh_frame_context) { |
280 Vp9FrameContextManager& frame_context_manager = | |
281 context_.frame_context_managers[curr_frame_header_.frame_context_idx]; | |
282 | |
283 // In frame parallel mode, we can refresh the context without decoding | 308 // In frame parallel mode, we can refresh the context without decoding |
284 // tile data. | 309 // tile data. |
285 if (curr_frame_header_.frame_parallel_decoding_mode) { | 310 if (curr_frame_header_.frame_parallel_decoding_mode) { |
286 frame_context_manager.Update(curr_frame_header_.frame_context); | 311 context_.UpdateFrameContext(frame_context_idx, |
| 312 curr_frame_header_.frame_context); |
287 } else { | 313 } else { |
288 *context_refresh_cb = frame_context_manager.SetNeedsClientUpdate(); | 314 context_.MarkFrameContextForUpdate(frame_context_idx); |
289 } | 315 } |
290 } | 316 } |
291 } | 317 } |
292 | 318 |
293 SetupSegmentationDequant(); | 319 SetupSegmentationDequant(); |
294 SetupLoopFilter(); | 320 SetupLoopFilter(); |
295 UpdateSlots(); | 321 UpdateSlots(); |
296 | 322 |
297 *fhdr = curr_frame_header_; | 323 *fhdr = curr_frame_header_; |
298 curr_frame_info_.Reset(); | 324 curr_frame_info_.Reset(); |
299 return kOk; | 325 return kOk; |
300 } | 326 } |
301 | 327 |
| 328 Vp9Parser::ContextRefreshCallback Vp9Parser::GetContextRefreshCb( |
| 329 size_t frame_context_idx) { |
| 330 DCHECK_LT(frame_context_idx, arraysize(context_.frame_context_managers_)); |
| 331 auto& frame_context_manager = |
| 332 context_.frame_context_managers_[frame_context_idx]; |
| 333 |
| 334 return frame_context_manager.GetUpdateCb(); |
| 335 } |
| 336 |
302 // Annex B Superframes | 337 // Annex B Superframes |
303 std::deque<Vp9Parser::FrameInfo> Vp9Parser::ParseSuperframe() { | 338 std::deque<Vp9Parser::FrameInfo> Vp9Parser::ParseSuperframe() { |
304 const uint8_t* stream = stream_; | 339 const uint8_t* stream = stream_; |
305 off_t bytes_left = bytes_left_; | 340 off_t bytes_left = bytes_left_; |
306 | 341 |
307 // Make sure we don't parse stream_ more than once. | 342 // Make sure we don't parse stream_ more than once. |
308 stream_ = nullptr; | 343 stream_ = nullptr; |
309 bytes_left_ = 0; | 344 bytes_left_ = 0; |
310 | 345 |
311 if (bytes_left < 1) | 346 if (bytes_left < 1) |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 "quantizer lookup arrays of incorrect size"); | 473 "quantizer lookup arrays of incorrect size"); |
439 | 474 |
440 static size_t ClampQ(size_t q) { | 475 static size_t ClampQ(size_t q) { |
441 return std::min(std::max(static_cast<size_t>(0), q), | 476 return std::min(std::max(static_cast<size_t>(0), q), |
442 arraysize(kDcQLookup) - 1); | 477 arraysize(kDcQLookup) - 1); |
443 } | 478 } |
444 | 479 |
445 // 8.6.1 Dequantization functions | 480 // 8.6.1 Dequantization functions |
446 size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant, | 481 size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant, |
447 size_t segid) const { | 482 size_t segid) const { |
448 const Vp9SegmentationParams& segmentation = context_.segmentation; | 483 const Vp9SegmentationParams& segmentation = context_.segmentation(); |
449 | 484 |
450 if (segmentation.FeatureEnabled(segid, | 485 if (segmentation.FeatureEnabled(segid, |
451 Vp9SegmentationParams::SEG_LVL_ALT_Q)) { | 486 Vp9SegmentationParams::SEG_LVL_ALT_Q)) { |
452 int16_t feature_data = | 487 int16_t feature_data = |
453 segmentation.FeatureData(segid, Vp9SegmentationParams::SEG_LVL_ALT_Q); | 488 segmentation.FeatureData(segid, Vp9SegmentationParams::SEG_LVL_ALT_Q); |
454 size_t q_index = segmentation.abs_or_delta_update | 489 size_t q_index = segmentation.abs_or_delta_update |
455 ? feature_data | 490 ? feature_data |
456 : quant.base_q_idx + feature_data; | 491 : quant.base_q_idx + feature_data; |
457 return ClampQ(q_index); | 492 return ClampQ(q_index); |
458 } | 493 } |
459 | 494 |
460 return quant.base_q_idx; | 495 return quant.base_q_idx; |
461 } | 496 } |
462 | 497 |
463 // 8.6.1 Dequantization functions | 498 // 8.6.1 Dequantization functions |
464 void Vp9Parser::SetupSegmentationDequant() { | 499 void Vp9Parser::SetupSegmentationDequant() { |
465 const Vp9QuantizationParams& quant = curr_frame_header_.quant_params; | 500 const Vp9QuantizationParams& quant = curr_frame_header_.quant_params; |
466 Vp9SegmentationParams& segmentation = context_.segmentation; | 501 Vp9SegmentationParams& segmentation = context_.segmentation_; |
467 | 502 |
468 DLOG_IF(ERROR, curr_frame_header_.bit_depth > 8) | 503 DLOG_IF(ERROR, curr_frame_header_.bit_depth > 8) |
469 << "bit_depth > 8 is not supported " | 504 << "bit_depth > 8 is not supported " |
470 "yet, kDcQLookup and kAcQLookup " | 505 "yet, kDcQLookup and kAcQLookup " |
471 "need extended"; | 506 "need extended"; |
472 if (segmentation.enabled) { | 507 if (segmentation.enabled) { |
473 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) { | 508 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) { |
474 const size_t q_index = GetQIndex(quant, i); | 509 const size_t q_index = GetQIndex(quant, i); |
475 segmentation.y_dequant[i][0] = | 510 segmentation.y_dequant[i][0] = |
476 kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)]; | 511 kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)]; |
(...skipping 15 matching lines...) Expand all Loading... |
492 } | 527 } |
493 } | 528 } |
494 | 529 |
495 static int ClampLf(int lf) { | 530 static int ClampLf(int lf) { |
496 const int kMaxLoopFilterLevel = 63; | 531 const int kMaxLoopFilterLevel = 63; |
497 return std::min(std::max(0, lf), kMaxLoopFilterLevel); | 532 return std::min(std::max(0, lf), kMaxLoopFilterLevel); |
498 } | 533 } |
499 | 534 |
500 // 8.8.1 Loop filter frame init process | 535 // 8.8.1 Loop filter frame init process |
501 void Vp9Parser::SetupLoopFilter() { | 536 void Vp9Parser::SetupLoopFilter() { |
502 Vp9LoopFilterParams& loop_filter = context_.loop_filter; | 537 Vp9LoopFilterParams& loop_filter = context_.loop_filter_; |
503 if (!loop_filter.level) | 538 if (!loop_filter.level) |
504 return; | 539 return; |
505 | 540 |
506 int scale = loop_filter.level < 32 ? 1 : 2; | 541 int scale = loop_filter.level < 32 ? 1 : 2; |
507 | 542 |
508 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) { | 543 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) { |
509 int level = loop_filter.level; | 544 int level = loop_filter.level; |
510 Vp9SegmentationParams& segmentation = context_.segmentation; | 545 const Vp9SegmentationParams& segmentation = context_.segmentation(); |
511 | 546 |
512 if (segmentation.FeatureEnabled(i, Vp9SegmentationParams::SEG_LVL_ALT_LF)) { | 547 if (segmentation.FeatureEnabled(i, Vp9SegmentationParams::SEG_LVL_ALT_LF)) { |
513 int feature_data = | 548 int feature_data = |
514 segmentation.FeatureData(i, Vp9SegmentationParams::SEG_LVL_ALT_LF); | 549 segmentation.FeatureData(i, Vp9SegmentationParams::SEG_LVL_ALT_LF); |
515 level = ClampLf(segmentation.abs_or_delta_update ? feature_data | 550 level = ClampLf(segmentation.abs_or_delta_update ? feature_data |
516 : level + feature_data); | 551 : level + feature_data); |
517 } | 552 } |
518 | 553 |
519 if (!loop_filter.delta_enabled) { | 554 if (!loop_filter.delta_enabled) { |
520 memset(loop_filter.lvl[i], level, sizeof(loop_filter.lvl[i])); | 555 memset(loop_filter.lvl[i], level, sizeof(loop_filter.lvl[i])); |
(...skipping 12 matching lines...) Expand all Loading... |
533 } | 568 } |
534 } | 569 } |
535 } | 570 } |
536 } | 571 } |
537 } | 572 } |
538 | 573 |
539 void Vp9Parser::UpdateSlots() { | 574 void Vp9Parser::UpdateSlots() { |
540 // 8.10 Reference frame update process | 575 // 8.10 Reference frame update process |
541 for (size_t i = 0; i < kVp9NumRefFrames; i++) { | 576 for (size_t i = 0; i < kVp9NumRefFrames; i++) { |
542 if (curr_frame_header_.RefreshFlag(i)) { | 577 if (curr_frame_header_.RefreshFlag(i)) { |
543 ReferenceSlot& ref = context_.ref_slots[i]; | 578 ReferenceSlot ref_slot; |
544 ref.initialized = true; | 579 ref_slot.initialized = true; |
545 | 580 |
546 ref.frame_width = curr_frame_header_.frame_width; | 581 ref_slot.frame_width = curr_frame_header_.frame_width; |
547 ref.frame_height = curr_frame_header_.frame_height; | 582 ref_slot.frame_height = curr_frame_header_.frame_height; |
548 ref.subsampling_x = curr_frame_header_.subsampling_x; | 583 ref_slot.subsampling_x = curr_frame_header_.subsampling_x; |
549 ref.subsampling_y = curr_frame_header_.subsampling_y; | 584 ref_slot.subsampling_y = curr_frame_header_.subsampling_y; |
550 ref.bit_depth = curr_frame_header_.bit_depth; | 585 ref_slot.bit_depth = curr_frame_header_.bit_depth; |
551 | 586 |
552 ref.profile = curr_frame_header_.profile; | 587 ref_slot.profile = curr_frame_header_.profile; |
553 ref.color_space = curr_frame_header_.color_space; | 588 ref_slot.color_space = curr_frame_header_.color_space; |
| 589 context_.UpdateRefSlot(i, ref_slot); |
554 } | 590 } |
555 } | 591 } |
556 } | 592 } |
557 | 593 |
558 } // namespace media | 594 } // namespace media |
OLD | NEW |