| Index: modules/video_coding/codecs/vp8/default_temporal_layers.cc
|
| diff --git a/modules/video_coding/codecs/vp8/default_temporal_layers.cc b/modules/video_coding/codecs/vp8/default_temporal_layers.cc
|
| index 6757ba26b3b354841b6a0bd7877feda2f1ddda5f..a0d56428c91c8cb7524dcfc23926d5c8c96f10d8 100644
|
| --- a/modules/video_coding/codecs/vp8/default_temporal_layers.cc
|
| +++ b/modules/video_coding/codecs/vp8/default_temporal_layers.cc
|
| @@ -1,11 +1,11 @@
|
| /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
| -*
|
| -* Use of this source code is governed by a BSD-style license
|
| -* that can be found in the LICENSE file in the root of the source
|
| -* tree. An additional intellectual property rights grant can be found
|
| -* in the file PATENTS. All contributing project authors may
|
| -* be found in the AUTHORS file in the root of the source tree.
|
| -*/
|
| + *
|
| + * Use of this source code is governed by a BSD-style license
|
| + * that can be found in the LICENSE file in the root of the source
|
| + * tree. An additional intellectual property rights grant can be found
|
| + * in the file PATENTS. All contributing project authors may
|
| + * be found in the AUTHORS file in the root of the source tree.
|
| + */
|
|
|
| #include "modules/video_coding/codecs/vp8/default_temporal_layers.h"
|
|
|
| @@ -19,10 +19,11 @@
|
| #include "modules/video_coding/codecs/vp8/include/vp8_common_types.h"
|
| #include "modules/video_coding/include/video_codec_interface.h"
|
| #include "rtc_base/checks.h"
|
| +#include "rtc_base/logging.h"
|
| #include "system_wrappers/include/field_trial.h"
|
|
|
| -#include "vpx/vpx_encoder.h"
|
| #include "vpx/vp8cx.h"
|
| +#include "vpx/vpx_encoder.h"
|
|
|
| namespace webrtc {
|
|
|
| @@ -428,4 +429,142 @@ void TemporalLayersFactory::SetListener(TemporalLayersListener* listener) {
|
| listener_ = listener;
|
| }
|
|
|
| +std::vector<std::vector<uint8_t>> GetTemporalDependencies(
|
| + int num_temporal_layers) {
|
| + switch (num_temporal_layers) {
|
| + case 1:
|
| + return {};
|
| + case 2:
|
| + return {};
|
| + case 3:
|
| + if (field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) {
|
| + return {};
|
| + } else {
|
| + return {};
|
| + }
|
| + case 4:
|
| + return {};
|
| + default:
|
| + RTC_NOTREACHED();
|
| + break;
|
| + }
|
| + RTC_NOTREACHED();
|
| + return {};
|
| +}
|
| +
|
| +DefaultTemporalLayersChecker::DefaultTemporalLayersChecker(
|
| + int num_temporal_layers,
|
| + uint8_t initial_tl0_pic_idx)
|
| + : num_layers_(std::max(1, num_temporal_layers)),
|
| + temporal_ids_(GetTemporalIds(num_layers_)),
|
| + temporal_dependencies_(GetTemporalDependencies(num_layers_)),
|
| + tl0_pic_idx_(initial_tl0_pic_idx),
|
| + pattern_idx_(255) {}
|
| +
|
| +bool DefaultTemporalLayersChecker::CheckOnFrameEncoded(
|
| + bool frame_is_keyframe,
|
| + const CodecSpecificInfoVP8& codec_specific,
|
| + TemporalLayers::FrameConfig& frame_config) {
|
| + ++pattern_idx_;
|
| + if (pattern_idx_ == temporal_ids_.size()) {
|
| + // All no key-frame buffers soud be updated each pattern cycle.
|
| + if (!last_.is_keyframe && !last_.is_updated_this_cycle) {
|
| + LOG(LS_ERROR) << "Last buffer was not updated during pattern cycle.";
|
| + return false;
|
| + }
|
| + if (!arf_.is_keyframe && !arf_.is_updated_this_cycle) {
|
| + LOG(LS_ERROR) << "Arf buffer was not updated during pattern cycle.";
|
| + return false;
|
| + }
|
| + if (!golden_.is_keyframe && !golden_.is_updated_this_cycle) {
|
| + LOG(LS_ERROR) << "Golden buffer was not updated during pattern cycle.";
|
| + return false;
|
| + }
|
| + last_.is_updated_this_cycle = false;
|
| + arf_.is_updated_this_cycle = false;
|
| + golden_.is_updated_this_cycle = false;
|
| + }
|
| +
|
| + if (codec_specific.temporalIdx != temporal_ids_[pattern_idx_]) {
|
| + LOG(LS_ERROR) << "Frame has an incorrect temporal index.";
|
| + return false;
|
| + }
|
| +
|
| + bool need_sync = true;
|
| + std::vector<int> dependencies;
|
| +
|
| + if (frame_config.last_buffer_flags &
|
| + TemporalLayers::BufferFlags::kReference) {
|
| + uint8_t referenced_idx = temporal_ids_[last_.pattern_idx];
|
| + if (!last_.is_keyframe && referenced_idx > 0) {
|
| + need_sync = false;
|
| + }
|
| + if (!last_.is_keyframe) {
|
| + dependencies.push_back(referenced_idx);
|
| + }
|
| + }
|
| +
|
| + if (frame_config.arf_buffer_flags & TemporalLayers::BufferFlags::kReference) {
|
| + uint8_t referenced_idx = temporal_ids_[arf_.pattern_idx];
|
| + if (!arf_.is_keyframe && referenced_idx > 0) {
|
| + need_sync = false;
|
| + }
|
| + if (!arf_.is_keyframe) {
|
| + dependencies.push_back(referenced_idx);
|
| + }
|
| + }
|
| +
|
| + if (frame_config.golden_buffer_flags &
|
| + TemporalLayers::BufferFlags::kReference) {
|
| + uint8_t referenced_idx = temporal_ids_[golden_.pattern_idx];
|
| + if (!golden_.is_keyframe && referenced_idx > 0) {
|
| + need_sync = false;
|
| + }
|
| + if (!golden_.is_keyframe) {
|
| + dependencies.push_back(referenced_idx);
|
| + }
|
| + }
|
| +
|
| + if (need_sync != codec_specific.layerSync) {
|
| + LOG(LS_ERROR) << "Sync bit is set incorrectly on a frame.";
|
| + return false;
|
| + }
|
| +
|
| + std::sort(dependencies.begin(), dependencies.end());
|
| + size_t i, j;
|
| + j = 0;
|
| + for (i = 0; i < dependencies.size(); ++i) {
|
| + while (j < temporal_dependencies_[pattern_idx_].size() &&
|
| + temporal_dependencies_[pattern_idx_][j] < dependencies[i]) {
|
| + ++j;
|
| + }
|
| + if (j == temporal_dependencies_[pattern_idx_].size() ||
|
| + temporal_dependencies_[pattern_idx_][j] != dependencies[i]) {
|
| + }
|
| + }
|
| +
|
| + if (frame_config.last_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
|
| + last_.is_updated_this_cycle = true;
|
| + last_.pattern_idx = pattern_idx_;
|
| + last_.is_keyframe = false;
|
| + }
|
| + if (frame_config.arf_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
|
| + arf_.is_updated_this_cycle = true;
|
| + arf_.pattern_idx = pattern_idx_;
|
| + arf_.is_keyframe = false;
|
| + }
|
| + if (frame_config.golden_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
|
| + golden_.is_updated_this_cycle = true;
|
| + golden_.pattern_idx = pattern_idx_;
|
| + golden_.is_keyframe = false;
|
| + }
|
| + if (frame_is_keyframe) {
|
| + last_.is_keyframe = true;
|
| + arf_.is_keyframe = true;
|
| + golden_.is_keyframe = true;
|
| + }
|
| + tl0_pic_idx_ = codec_specific.tl0PicIdx;
|
| + return true;
|
| +}
|
| +
|
| } // namespace webrtc
|
|
|