| 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 |