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 curr_frame_info_.Reset(); | 221 curr_frame_info_.Reset(); |
191 | 222 |
192 context_.Reset(); | 223 context_.Reset(); |
193 } | 224 } |
194 | 225 |
195 Vp9Parser::Result Vp9Parser::ParseNextFrame( | 226 Vp9Parser::Result Vp9Parser::ParseNextFrame(Vp9FrameHeader* fhdr) { |
196 Vp9FrameHeader* fhdr, | |
197 Vp9FrameContextManager::ContextRefreshCallback* context_refresh_cb) { | |
198 DCHECK(fhdr); | 227 DCHECK(fhdr); |
199 DCHECK(!parsing_compressed_header_ || context_refresh_cb); | |
200 DVLOG(2) << "ParseNextFrame"; | 228 DVLOG(2) << "ParseNextFrame"; |
201 | 229 |
202 // If |curr_frame_info_| is valid, uncompressed header was parsed into | 230 // If |curr_frame_info_| is valid, uncompressed header was parsed into |
203 // |curr_frame_header_| and we are awaiting context update to proceed with | 231 // |curr_frame_header_| and we are awaiting context update to proceed with |
204 // compressed header parsing. | 232 // compressed header parsing. |
205 if (!curr_frame_info_.IsValid()) { | 233 if (!curr_frame_info_.IsValid()) { |
206 if (frames_.empty()) { | 234 if (frames_.empty()) { |
207 // No frames to be decoded, if there is no more stream, request more. | 235 // No frames to be decoded, if there is no more stream, request more. |
208 if (!stream_) | 236 if (!stream_) |
209 return kEOStream; | 237 return kEOStream; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 DVLOG(1) << "header_size_in_bytes=" | 273 DVLOG(1) << "header_size_in_bytes=" |
246 << curr_frame_header_.header_size_in_bytes | 274 << curr_frame_header_.header_size_in_bytes |
247 << " is larger than bytes left in buffer: " | 275 << " is larger than bytes left in buffer: " |
248 << curr_frame_info_.size - | 276 << curr_frame_info_.size - |
249 curr_frame_header_.uncompressed_header_size; | 277 curr_frame_header_.uncompressed_header_size; |
250 return kInvalidStream; | 278 return kInvalidStream; |
251 } | 279 } |
252 } | 280 } |
253 | 281 |
254 if (parsing_compressed_header_) { | 282 if (parsing_compressed_header_) { |
255 Vp9FrameContextManager& context_to_load = | 283 size_t frame_context_idx = curr_frame_header_.frame_context_idx; |
256 context_.frame_context_managers[curr_frame_header_.frame_context_idx]; | 284 const Context::Vp9FrameContextManager& context_to_load = |
| 285 context_.frame_context_managers_[frame_context_idx]; |
257 if (!context_to_load.initialized()) { | 286 if (!context_to_load.initialized()) { |
258 // 8.2 Frame order constraints | 287 // 8.2 Frame order constraints |
259 // must load an initialized set of probabilities. | 288 // must load an initialized set of probabilities. |
260 DVLOG(1) << "loading uninitialized frame context, index=" | 289 DVLOG(1) << "loading uninitialized frame context, index=" |
261 << curr_frame_header_.frame_context_idx; | 290 << frame_context_idx; |
262 return kInvalidStream; | 291 return kInvalidStream; |
263 } | 292 } |
264 if (context_to_load.needs_client_update()) { | 293 if (context_to_load.needs_client_update()) { |
265 DVLOG(3) << "waiting frame_context_idx=" | 294 DVLOG(3) << "waiting frame_context_idx=" << frame_context_idx |
266 << static_cast<int>(curr_frame_header_.frame_context_idx) | |
267 << " to update"; | 295 << " to update"; |
268 return kAwaitingRefresh; | 296 return kAwaitingRefresh; |
269 } | 297 } |
270 curr_frame_header_.initial_frame_context = | 298 curr_frame_header_.initial_frame_context = |
271 curr_frame_header_.frame_context = context_to_load.frame_context(); | 299 curr_frame_header_.frame_context = context_to_load.frame_context(); |
272 | 300 |
273 Vp9CompressedHeaderParser compressed_parser; | 301 Vp9CompressedHeaderParser compressed_parser; |
274 if (!compressed_parser.Parse( | 302 if (!compressed_parser.Parse( |
275 curr_frame_info_.ptr + curr_frame_header_.uncompressed_header_size, | 303 curr_frame_info_.ptr + curr_frame_header_.uncompressed_header_size, |
276 curr_frame_header_.header_size_in_bytes, &curr_frame_header_)) { | 304 curr_frame_header_.header_size_in_bytes, &curr_frame_header_)) { |
277 return kInvalidStream; | 305 return kInvalidStream; |
278 } | 306 } |
279 | 307 |
280 if (curr_frame_header_.refresh_frame_context) { | 308 if (curr_frame_header_.refresh_frame_context) { |
281 Vp9FrameContextManager& frame_context_manager = | |
282 context_.frame_context_managers[curr_frame_header_.frame_context_idx]; | |
283 | |
284 // In frame parallel mode, we can refresh the context without decoding | 309 // In frame parallel mode, we can refresh the context without decoding |
285 // tile data. | 310 // tile data. |
286 if (curr_frame_header_.frame_parallel_decoding_mode) { | 311 if (curr_frame_header_.frame_parallel_decoding_mode) { |
287 frame_context_manager.Update(curr_frame_header_.frame_context); | 312 context_.UpdateFrameContext(frame_context_idx, |
| 313 curr_frame_header_.frame_context); |
288 } else { | 314 } else { |
289 *context_refresh_cb = frame_context_manager.SetNeedsClientUpdate(); | 315 context_.MarkFrameContextForUpdate(frame_context_idx); |
290 } | 316 } |
291 } | 317 } |
292 } | 318 } |
293 | 319 |
294 SetupSegmentationDequant(); | 320 SetupSegmentationDequant(); |
295 SetupLoopFilter(); | 321 SetupLoopFilter(); |
296 UpdateSlots(); | 322 UpdateSlots(); |
297 | 323 |
298 *fhdr = curr_frame_header_; | 324 *fhdr = curr_frame_header_; |
299 curr_frame_info_.Reset(); | 325 curr_frame_info_.Reset(); |
300 return kOk; | 326 return kOk; |
301 } | 327 } |
302 | 328 |
| 329 Vp9Parser::ContextRefreshCallback Vp9Parser::GetContextRefreshCb( |
| 330 size_t frame_context_idx) { |
| 331 DCHECK_LT(frame_context_idx, arraysize(context_.frame_context_managers_)); |
| 332 auto& frame_context_manager = |
| 333 context_.frame_context_managers_[frame_context_idx]; |
| 334 |
| 335 return frame_context_manager.GetUpdateCb(); |
| 336 } |
| 337 |
303 // Annex B Superframes | 338 // Annex B Superframes |
304 std::deque<Vp9Parser::FrameInfo> Vp9Parser::ParseSuperframe() { | 339 std::deque<Vp9Parser::FrameInfo> Vp9Parser::ParseSuperframe() { |
305 const uint8_t* stream = stream_; | 340 const uint8_t* stream = stream_; |
306 off_t bytes_left = bytes_left_; | 341 off_t bytes_left = bytes_left_; |
307 | 342 |
308 // Make sure we don't parse stream_ more than once. | 343 // Make sure we don't parse stream_ more than once. |
309 stream_ = nullptr; | 344 stream_ = nullptr; |
310 bytes_left_ = 0; | 345 bytes_left_ = 0; |
311 | 346 |
312 if (bytes_left < 1) | 347 if (bytes_left < 1) |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 "quantizer lookup arrays of incorrect size"); | 474 "quantizer lookup arrays of incorrect size"); |
440 | 475 |
441 static size_t ClampQ(size_t q) { | 476 static size_t ClampQ(size_t q) { |
442 return std::min(std::max(static_cast<size_t>(0), q), | 477 return std::min(std::max(static_cast<size_t>(0), q), |
443 arraysize(kDcQLookup) - 1); | 478 arraysize(kDcQLookup) - 1); |
444 } | 479 } |
445 | 480 |
446 // 8.6.1 Dequantization functions | 481 // 8.6.1 Dequantization functions |
447 size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant, | 482 size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant, |
448 size_t segid) const { | 483 size_t segid) const { |
449 const Vp9SegmentationParams& segmentation = context_.segmentation; | 484 const Vp9SegmentationParams& segmentation = context_.segmentation(); |
450 | 485 |
451 if (segmentation.FeatureEnabled(segid, | 486 if (segmentation.FeatureEnabled(segid, |
452 Vp9SegmentationParams::SEG_LVL_ALT_Q)) { | 487 Vp9SegmentationParams::SEG_LVL_ALT_Q)) { |
453 int16_t feature_data = | 488 int16_t feature_data = |
454 segmentation.FeatureData(segid, Vp9SegmentationParams::SEG_LVL_ALT_Q); | 489 segmentation.FeatureData(segid, Vp9SegmentationParams::SEG_LVL_ALT_Q); |
455 size_t q_index = segmentation.abs_or_delta_update | 490 size_t q_index = segmentation.abs_or_delta_update |
456 ? feature_data | 491 ? feature_data |
457 : quant.base_q_idx + feature_data; | 492 : quant.base_q_idx + feature_data; |
458 return ClampQ(q_index); | 493 return ClampQ(q_index); |
459 } | 494 } |
460 | 495 |
461 return quant.base_q_idx; | 496 return quant.base_q_idx; |
462 } | 497 } |
463 | 498 |
464 // 8.6.1 Dequantization functions | 499 // 8.6.1 Dequantization functions |
465 void Vp9Parser::SetupSegmentationDequant() { | 500 void Vp9Parser::SetupSegmentationDequant() { |
466 const Vp9QuantizationParams& quant = curr_frame_header_.quant_params; | 501 const Vp9QuantizationParams& quant = curr_frame_header_.quant_params; |
467 Vp9SegmentationParams& segmentation = context_.segmentation; | 502 Vp9SegmentationParams& segmentation = context_.segmentation_; |
468 | 503 |
469 DLOG_IF(ERROR, curr_frame_header_.bit_depth > 8) | 504 DLOG_IF(ERROR, curr_frame_header_.bit_depth > 8) |
470 << "bit_depth > 8 is not supported " | 505 << "bit_depth > 8 is not supported " |
471 "yet, kDcQLookup and kAcQLookup " | 506 "yet, kDcQLookup and kAcQLookup " |
472 "need extended"; | 507 "need extended"; |
473 if (segmentation.enabled) { | 508 if (segmentation.enabled) { |
474 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) { | 509 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) { |
475 const size_t q_index = GetQIndex(quant, i); | 510 const size_t q_index = GetQIndex(quant, i); |
476 segmentation.y_dequant[i][0] = | 511 segmentation.y_dequant[i][0] = |
477 kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)]; | 512 kDcQLookup[ClampQ(q_index + quant.delta_q_y_dc)]; |
(...skipping 15 matching lines...) Expand all Loading... |
493 } | 528 } |
494 } | 529 } |
495 | 530 |
496 static int ClampLf(int lf) { | 531 static int ClampLf(int lf) { |
497 const int kMaxLoopFilterLevel = 63; | 532 const int kMaxLoopFilterLevel = 63; |
498 return std::min(std::max(0, lf), kMaxLoopFilterLevel); | 533 return std::min(std::max(0, lf), kMaxLoopFilterLevel); |
499 } | 534 } |
500 | 535 |
501 // 8.8.1 Loop filter frame init process | 536 // 8.8.1 Loop filter frame init process |
502 void Vp9Parser::SetupLoopFilter() { | 537 void Vp9Parser::SetupLoopFilter() { |
503 Vp9LoopFilterParams& loop_filter = context_.loop_filter; | 538 Vp9LoopFilterParams& loop_filter = context_.loop_filter_; |
504 if (!loop_filter.level) | 539 if (!loop_filter.level) |
505 return; | 540 return; |
506 | 541 |
507 int scale = loop_filter.level < 32 ? 1 : 2; | 542 int scale = loop_filter.level < 32 ? 1 : 2; |
508 | 543 |
509 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) { | 544 for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) { |
510 int level = loop_filter.level; | 545 int level = loop_filter.level; |
511 Vp9SegmentationParams& segmentation = context_.segmentation; | 546 const Vp9SegmentationParams& segmentation = context_.segmentation(); |
512 | 547 |
513 if (segmentation.FeatureEnabled(i, Vp9SegmentationParams::SEG_LVL_ALT_LF)) { | 548 if (segmentation.FeatureEnabled(i, Vp9SegmentationParams::SEG_LVL_ALT_LF)) { |
514 int feature_data = | 549 int feature_data = |
515 segmentation.FeatureData(i, Vp9SegmentationParams::SEG_LVL_ALT_LF); | 550 segmentation.FeatureData(i, Vp9SegmentationParams::SEG_LVL_ALT_LF); |
516 level = ClampLf(segmentation.abs_or_delta_update ? feature_data | 551 level = ClampLf(segmentation.abs_or_delta_update ? feature_data |
517 : level + feature_data); | 552 : level + feature_data); |
518 } | 553 } |
519 | 554 |
520 if (!loop_filter.delta_enabled) { | 555 if (!loop_filter.delta_enabled) { |
521 memset(loop_filter.lvl[i], level, sizeof(loop_filter.lvl[i])); | 556 memset(loop_filter.lvl[i], level, sizeof(loop_filter.lvl[i])); |
(...skipping 12 matching lines...) Expand all Loading... |
534 } | 569 } |
535 } | 570 } |
536 } | 571 } |
537 } | 572 } |
538 } | 573 } |
539 | 574 |
540 void Vp9Parser::UpdateSlots() { | 575 void Vp9Parser::UpdateSlots() { |
541 // 8.10 Reference frame update process | 576 // 8.10 Reference frame update process |
542 for (size_t i = 0; i < kVp9NumRefFrames; i++) { | 577 for (size_t i = 0; i < kVp9NumRefFrames; i++) { |
543 if (curr_frame_header_.RefreshFlag(i)) { | 578 if (curr_frame_header_.RefreshFlag(i)) { |
544 ReferenceSlot& ref = context_.ref_slots[i]; | 579 ReferenceSlot ref_slot; |
545 ref.initialized = true; | 580 ref_slot.initialized = true; |
546 | 581 |
547 ref.frame_width = curr_frame_header_.frame_width; | 582 ref_slot.frame_width = curr_frame_header_.frame_width; |
548 ref.frame_height = curr_frame_header_.frame_height; | 583 ref_slot.frame_height = curr_frame_header_.frame_height; |
549 ref.subsampling_x = curr_frame_header_.subsampling_x; | 584 ref_slot.subsampling_x = curr_frame_header_.subsampling_x; |
550 ref.subsampling_y = curr_frame_header_.subsampling_y; | 585 ref_slot.subsampling_y = curr_frame_header_.subsampling_y; |
551 ref.bit_depth = curr_frame_header_.bit_depth; | 586 ref_slot.bit_depth = curr_frame_header_.bit_depth; |
552 | 587 |
553 ref.profile = curr_frame_header_.profile; | 588 ref_slot.profile = curr_frame_header_.profile; |
554 ref.color_space = curr_frame_header_.color_space; | 589 ref_slot.color_space = curr_frame_header_.color_space; |
| 590 context_.UpdateRefSlot(i, ref_slot); |
555 } | 591 } |
556 } | 592 } |
557 } | 593 } |
558 | 594 |
559 } // namespace media | 595 } // namespace media |
OLD | NEW |