| Index: media/filters/vp9_parser.cc
|
| diff --git a/media/filters/vp9_parser.cc b/media/filters/vp9_parser.cc
|
| index 288301bc525fbf6a6f5e817518ce11396a69664e..7075f21d9c310f9f322ab727aecc9a67e5b8614f 100644
|
| --- a/media/filters/vp9_parser.cc
|
| +++ b/media/filters/vp9_parser.cc
|
| @@ -36,23 +36,18 @@ bool Vp9FrameHeader::IsIntra() const {
|
| Vp9Parser::FrameInfo::FrameInfo(const uint8_t* ptr, off_t size)
|
| : ptr(ptr), size(size) {}
|
|
|
| -Vp9FrameContextManager::Vp9FrameContextManager() : weak_ptr_factory_(this) {}
|
| -
|
| -Vp9FrameContextManager::~Vp9FrameContextManager() {}
|
| -
|
| -bool Vp9FrameContextManager::IsValidFrameContext(
|
| - const Vp9FrameContext& context) {
|
| +bool Vp9FrameContext::IsValid() const {
|
| // probs should be in [1, 255] range.
|
| static_assert(sizeof(Vp9Prob) == 1,
|
| "following checks assuming Vp9Prob is single byte");
|
| - if (memchr(context.tx_probs_8x8, 0, sizeof(context.tx_probs_8x8)))
|
| + if (memchr(tx_probs_8x8, 0, sizeof(tx_probs_8x8)))
|
| return false;
|
| - if (memchr(context.tx_probs_16x16, 0, sizeof(context.tx_probs_16x16)))
|
| + if (memchr(tx_probs_16x16, 0, sizeof(tx_probs_16x16)))
|
| return false;
|
| - if (memchr(context.tx_probs_32x32, 0, sizeof(context.tx_probs_32x32)))
|
| + if (memchr(tx_probs_32x32, 0, sizeof(tx_probs_32x32)))
|
| return false;
|
|
|
| - for (auto& a : context.coef_probs) {
|
| + for (auto& a : coef_probs) {
|
| for (auto& ai : a) {
|
| for (auto& aj : ai) {
|
| for (auto& ak : aj) {
|
| @@ -67,74 +62,85 @@ bool Vp9FrameContextManager::IsValidFrameContext(
|
| }
|
| }
|
| }
|
| - if (memchr(context.skip_prob, 0, sizeof(context.skip_prob)))
|
| + if (memchr(skip_prob, 0, sizeof(skip_prob)))
|
| return false;
|
| - if (memchr(context.inter_mode_probs, 0, sizeof(context.inter_mode_probs)))
|
| + if (memchr(inter_mode_probs, 0, sizeof(inter_mode_probs)))
|
| return false;
|
| - if (memchr(context.interp_filter_probs, 0,
|
| - sizeof(context.interp_filter_probs)))
|
| + if (memchr(interp_filter_probs, 0, sizeof(interp_filter_probs)))
|
| return false;
|
| - if (memchr(context.is_inter_prob, 0, sizeof(context.is_inter_prob)))
|
| + if (memchr(is_inter_prob, 0, sizeof(is_inter_prob)))
|
| return false;
|
| - if (memchr(context.comp_mode_prob, 0, sizeof(context.comp_mode_prob)))
|
| + if (memchr(comp_mode_prob, 0, sizeof(comp_mode_prob)))
|
| return false;
|
| - if (memchr(context.single_ref_prob, 0, sizeof(context.single_ref_prob)))
|
| + if (memchr(single_ref_prob, 0, sizeof(single_ref_prob)))
|
| return false;
|
| - if (memchr(context.comp_ref_prob, 0, sizeof(context.comp_ref_prob)))
|
| + if (memchr(comp_ref_prob, 0, sizeof(comp_ref_prob)))
|
| return false;
|
| - if (memchr(context.y_mode_probs, 0, sizeof(context.y_mode_probs)))
|
| + if (memchr(y_mode_probs, 0, sizeof(y_mode_probs)))
|
| return false;
|
| - if (memchr(context.uv_mode_probs, 0, sizeof(context.uv_mode_probs)))
|
| + if (memchr(uv_mode_probs, 0, sizeof(uv_mode_probs)))
|
| return false;
|
| - if (memchr(context.partition_probs, 0, sizeof(context.partition_probs)))
|
| + if (memchr(partition_probs, 0, sizeof(partition_probs)))
|
| return false;
|
| - if (memchr(context.mv_joint_probs, 0, sizeof(context.mv_joint_probs)))
|
| + if (memchr(mv_joint_probs, 0, sizeof(mv_joint_probs)))
|
| return false;
|
| - if (memchr(context.mv_sign_prob, 0, sizeof(context.mv_sign_prob)))
|
| + if (memchr(mv_sign_prob, 0, sizeof(mv_sign_prob)))
|
| return false;
|
| - if (memchr(context.mv_class_probs, 0, sizeof(context.mv_class_probs)))
|
| + if (memchr(mv_class_probs, 0, sizeof(mv_class_probs)))
|
| return false;
|
| - if (memchr(context.mv_class0_bit_prob, 0, sizeof(context.mv_class0_bit_prob)))
|
| + if (memchr(mv_class0_bit_prob, 0, sizeof(mv_class0_bit_prob)))
|
| return false;
|
| - if (memchr(context.mv_bits_prob, 0, sizeof(context.mv_bits_prob)))
|
| + if (memchr(mv_bits_prob, 0, sizeof(mv_bits_prob)))
|
| return false;
|
| - if (memchr(context.mv_class0_fr_probs, 0, sizeof(context.mv_class0_fr_probs)))
|
| + if (memchr(mv_class0_fr_probs, 0, sizeof(mv_class0_fr_probs)))
|
| return false;
|
| - if (memchr(context.mv_fr_probs, 0, sizeof(context.mv_fr_probs)))
|
| + if (memchr(mv_fr_probs, 0, sizeof(mv_fr_probs)))
|
| return false;
|
| - if (memchr(context.mv_class0_hp_prob, 0, sizeof(context.mv_class0_hp_prob)))
|
| + if (memchr(mv_class0_hp_prob, 0, sizeof(mv_class0_hp_prob)))
|
| return false;
|
| - if (memchr(context.mv_hp_prob, 0, sizeof(context.mv_hp_prob)))
|
| + if (memchr(mv_hp_prob, 0, sizeof(mv_hp_prob)))
|
| return false;
|
|
|
| return true;
|
| }
|
|
|
| -const Vp9FrameContext& Vp9FrameContextManager::frame_context() const {
|
| +Vp9Parser::Context::Vp9FrameContextManager::Vp9FrameContextManager()
|
| + : weak_ptr_factory_(this) {}
|
| +
|
| +Vp9Parser::Context::Vp9FrameContextManager::~Vp9FrameContextManager() {}
|
| +
|
| +const Vp9FrameContext&
|
| +Vp9Parser::Context::Vp9FrameContextManager::frame_context() const {
|
| DCHECK(initialized_);
|
| DCHECK(!needs_client_update_);
|
| return frame_context_;
|
| }
|
|
|
| -void Vp9FrameContextManager::Reset() {
|
| +void Vp9Parser::Context::Vp9FrameContextManager::Reset() {
|
| initialized_ = false;
|
| needs_client_update_ = false;
|
| weak_ptr_factory_.InvalidateWeakPtrs();
|
| }
|
|
|
| -Vp9FrameContextManager::ContextRefreshCallback
|
| -Vp9FrameContextManager::SetNeedsClientUpdate() {
|
| +void Vp9Parser::Context::Vp9FrameContextManager::SetNeedsClientUpdate() {
|
| DCHECK(!needs_client_update_);
|
| initialized_ = true;
|
| needs_client_update_ = true;
|
| +}
|
|
|
| - return base::Bind(&Vp9FrameContextManager::UpdateFromClient,
|
| - weak_ptr_factory_.GetWeakPtr());
|
| +Vp9Parser::ContextRefreshCallback
|
| +Vp9Parser::Context::Vp9FrameContextManager::GetUpdateCb() {
|
| + if (needs_client_update_)
|
| + return base::Bind(&Vp9FrameContextManager::UpdateFromClient,
|
| + weak_ptr_factory_.GetWeakPtr());
|
| + else
|
| + return Vp9Parser::ContextRefreshCallback();
|
| }
|
|
|
| -void Vp9FrameContextManager::Update(const Vp9FrameContext& frame_context) {
|
| +void Vp9Parser::Context::Vp9FrameContextManager::Update(
|
| + const Vp9FrameContext& frame_context) {
|
| // DCHECK because we can trust values from our parser.
|
| - DCHECK(IsValidFrameContext(frame_context));
|
| + DCHECK(frame_context.IsValid());
|
| initialized_ = true;
|
| frame_context_ = frame_context;
|
|
|
| @@ -148,11 +154,11 @@ void Vp9FrameContextManager::Update(const Vp9FrameContext& frame_context) {
|
| needs_client_update_ = false;
|
| }
|
|
|
| -void Vp9FrameContextManager::UpdateFromClient(
|
| +void Vp9Parser::Context::Vp9FrameContextManager::UpdateFromClient(
|
| const Vp9FrameContext& frame_context) {
|
| DVLOG(2) << "Got external frame_context update";
|
| DCHECK(needs_client_update_);
|
| - if (!IsValidFrameContext(frame_context)) {
|
| + if (!frame_context.IsValid()) {
|
| DLOG(ERROR) << "Invalid prob value in frame_context";
|
| return;
|
| }
|
| @@ -162,13 +168,38 @@ void Vp9FrameContextManager::UpdateFromClient(
|
| }
|
|
|
| void Vp9Parser::Context::Reset() {
|
| - memset(&segmentation, 0, sizeof(segmentation));
|
| - memset(&loop_filter, 0, sizeof(loop_filter));
|
| - memset(&ref_slots, 0, sizeof(ref_slots));
|
| - for (auto& manager : frame_context_managers)
|
| + memset(&segmentation_, 0, sizeof(segmentation_));
|
| + memset(&loop_filter_, 0, sizeof(loop_filter_));
|
| + memset(&ref_slots_, 0, sizeof(ref_slots_));
|
| + for (auto& manager : frame_context_managers_)
|
| manager.Reset();
|
| }
|
|
|
| +void Vp9Parser::Context::MarkFrameContextForUpdate(size_t frame_context_idx) {
|
| + DCHECK_LT(frame_context_idx, arraysize(frame_context_managers_));
|
| + frame_context_managers_[frame_context_idx].SetNeedsClientUpdate();
|
| +}
|
| +
|
| +void Vp9Parser::Context::UpdateFrameContext(
|
| + size_t frame_context_idx,
|
| + const Vp9FrameContext& frame_context) {
|
| + DCHECK_LT(frame_context_idx, arraysize(frame_context_managers_));
|
| + frame_context_managers_[frame_context_idx].Update(frame_context);
|
| +}
|
| +
|
| +const Vp9Parser::ReferenceSlot& Vp9Parser::Context::GetRefSlot(
|
| + size_t ref_type) const {
|
| + DCHECK_LT(ref_type, arraysize(ref_slots_));
|
| + return ref_slots_[ref_type];
|
| +}
|
| +
|
| +void Vp9Parser::Context::UpdateRefSlot(
|
| + size_t ref_type,
|
| + const Vp9Parser::ReferenceSlot& ref_slot) {
|
| + DCHECK_LT(ref_type, arraysize(ref_slots_));
|
| + ref_slots_[ref_type] = ref_slot;
|
| +}
|
| +
|
| Vp9Parser::Vp9Parser(bool parsing_compressed_header)
|
| : parsing_compressed_header_(parsing_compressed_header) {
|
| Reset();
|
| @@ -192,11 +223,8 @@ void Vp9Parser::Reset() {
|
| context_.Reset();
|
| }
|
|
|
| -Vp9Parser::Result Vp9Parser::ParseNextFrame(
|
| - Vp9FrameHeader* fhdr,
|
| - Vp9FrameContextManager::ContextRefreshCallback* context_refresh_cb) {
|
| +Vp9Parser::Result Vp9Parser::ParseNextFrame(Vp9FrameHeader* fhdr) {
|
| DCHECK(fhdr);
|
| - DCHECK(!parsing_compressed_header_ || context_refresh_cb);
|
| DVLOG(2) << "ParseNextFrame";
|
|
|
| // If |curr_frame_info_| is valid, uncompressed header was parsed into
|
| @@ -252,18 +280,18 @@ Vp9Parser::Result Vp9Parser::ParseNextFrame(
|
| }
|
|
|
| if (parsing_compressed_header_) {
|
| - Vp9FrameContextManager& context_to_load =
|
| - context_.frame_context_managers[curr_frame_header_.frame_context_idx];
|
| + size_t frame_context_idx = curr_frame_header_.frame_context_idx;
|
| + const Context::Vp9FrameContextManager& context_to_load =
|
| + context_.frame_context_managers_[frame_context_idx];
|
| if (!context_to_load.initialized()) {
|
| // 8.2 Frame order constraints
|
| // must load an initialized set of probabilities.
|
| DVLOG(1) << "loading uninitialized frame context, index="
|
| - << curr_frame_header_.frame_context_idx;
|
| + << frame_context_idx;
|
| return kInvalidStream;
|
| }
|
| if (context_to_load.needs_client_update()) {
|
| - DVLOG(3) << "waiting frame_context_idx="
|
| - << static_cast<int>(curr_frame_header_.frame_context_idx)
|
| + DVLOG(3) << "waiting frame_context_idx=" << frame_context_idx
|
| << " to update";
|
| return kAwaitingRefresh;
|
| }
|
| @@ -278,15 +306,13 @@ Vp9Parser::Result Vp9Parser::ParseNextFrame(
|
| }
|
|
|
| if (curr_frame_header_.refresh_frame_context) {
|
| - Vp9FrameContextManager& frame_context_manager =
|
| - context_.frame_context_managers[curr_frame_header_.frame_context_idx];
|
| -
|
| // In frame parallel mode, we can refresh the context without decoding
|
| // tile data.
|
| if (curr_frame_header_.frame_parallel_decoding_mode) {
|
| - frame_context_manager.Update(curr_frame_header_.frame_context);
|
| + context_.UpdateFrameContext(frame_context_idx,
|
| + curr_frame_header_.frame_context);
|
| } else {
|
| - *context_refresh_cb = frame_context_manager.SetNeedsClientUpdate();
|
| + context_.MarkFrameContextForUpdate(frame_context_idx);
|
| }
|
| }
|
| }
|
| @@ -300,6 +326,15 @@ Vp9Parser::Result Vp9Parser::ParseNextFrame(
|
| return kOk;
|
| }
|
|
|
| +Vp9Parser::ContextRefreshCallback Vp9Parser::GetContextRefreshCb(
|
| + size_t frame_context_idx) {
|
| + DCHECK_LT(frame_context_idx, arraysize(context_.frame_context_managers_));
|
| + auto& frame_context_manager =
|
| + context_.frame_context_managers_[frame_context_idx];
|
| +
|
| + return frame_context_manager.GetUpdateCb();
|
| +}
|
| +
|
| // Annex B Superframes
|
| std::deque<Vp9Parser::FrameInfo> Vp9Parser::ParseSuperframe() {
|
| const uint8_t* stream = stream_;
|
| @@ -446,7 +481,7 @@ static size_t ClampQ(size_t q) {
|
| // 8.6.1 Dequantization functions
|
| size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant,
|
| size_t segid) const {
|
| - const Vp9SegmentationParams& segmentation = context_.segmentation;
|
| + const Vp9SegmentationParams& segmentation = context_.segmentation();
|
|
|
| if (segmentation.FeatureEnabled(segid,
|
| Vp9SegmentationParams::SEG_LVL_ALT_Q)) {
|
| @@ -464,7 +499,7 @@ size_t Vp9Parser::GetQIndex(const Vp9QuantizationParams& quant,
|
| // 8.6.1 Dequantization functions
|
| void Vp9Parser::SetupSegmentationDequant() {
|
| const Vp9QuantizationParams& quant = curr_frame_header_.quant_params;
|
| - Vp9SegmentationParams& segmentation = context_.segmentation;
|
| + Vp9SegmentationParams& segmentation = context_.segmentation_;
|
|
|
| DLOG_IF(ERROR, curr_frame_header_.bit_depth > 8)
|
| << "bit_depth > 8 is not supported "
|
| @@ -500,7 +535,7 @@ static int ClampLf(int lf) {
|
|
|
| // 8.8.1 Loop filter frame init process
|
| void Vp9Parser::SetupLoopFilter() {
|
| - Vp9LoopFilterParams& loop_filter = context_.loop_filter;
|
| + Vp9LoopFilterParams& loop_filter = context_.loop_filter_;
|
| if (!loop_filter.level)
|
| return;
|
|
|
| @@ -508,7 +543,7 @@ void Vp9Parser::SetupLoopFilter() {
|
|
|
| for (size_t i = 0; i < Vp9SegmentationParams::kNumSegments; ++i) {
|
| int level = loop_filter.level;
|
| - Vp9SegmentationParams& segmentation = context_.segmentation;
|
| + const Vp9SegmentationParams& segmentation = context_.segmentation();
|
|
|
| if (segmentation.FeatureEnabled(i, Vp9SegmentationParams::SEG_LVL_ALT_LF)) {
|
| int feature_data =
|
| @@ -541,17 +576,18 @@ void Vp9Parser::UpdateSlots() {
|
| // 8.10 Reference frame update process
|
| for (size_t i = 0; i < kVp9NumRefFrames; i++) {
|
| if (curr_frame_header_.RefreshFlag(i)) {
|
| - ReferenceSlot& ref = context_.ref_slots[i];
|
| - ref.initialized = true;
|
| -
|
| - ref.frame_width = curr_frame_header_.frame_width;
|
| - ref.frame_height = curr_frame_header_.frame_height;
|
| - ref.subsampling_x = curr_frame_header_.subsampling_x;
|
| - ref.subsampling_y = curr_frame_header_.subsampling_y;
|
| - ref.bit_depth = curr_frame_header_.bit_depth;
|
| -
|
| - ref.profile = curr_frame_header_.profile;
|
| - ref.color_space = curr_frame_header_.color_space;
|
| + ReferenceSlot ref_slot;
|
| + ref_slot.initialized = true;
|
| +
|
| + ref_slot.frame_width = curr_frame_header_.frame_width;
|
| + ref_slot.frame_height = curr_frame_header_.frame_height;
|
| + ref_slot.subsampling_x = curr_frame_header_.subsampling_x;
|
| + ref_slot.subsampling_y = curr_frame_header_.subsampling_y;
|
| + ref_slot.bit_depth = curr_frame_header_.bit_depth;
|
| +
|
| + ref_slot.profile = curr_frame_header_.profile;
|
| + ref_slot.color_space = curr_frame_header_.color_space;
|
| + context_.UpdateRefSlot(i, ref_slot);
|
| }
|
| }
|
| }
|
|
|