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