LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/video_coding/codecs/vp8 - default_temporal_layers.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 223 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
       2             : *
       3             : *  Use of this source code is governed by a BSD-style license
       4             : *  that can be found in the LICENSE file in the root of the source
       5             : *  tree. An additional intellectual property rights grant can be found
       6             : *  in the file PATENTS.  All contributing project authors may
       7             : *  be found in the AUTHORS file in the root of the source tree.
       8             : */
       9             : 
      10             : #include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h"
      11             : 
      12             : #include <assert.h>
      13             : #include <stdlib.h>
      14             : #include <string.h>
      15             : 
      16             : #include <algorithm>
      17             : #include <vector>
      18             : 
      19             : #include "webrtc/base/checks.h"
      20             : #include "webrtc/modules/include/module_common_types.h"
      21             : #include "webrtc/modules/video_coding/include/video_codec_interface.h"
      22             : #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
      23             : 
      24             : #include "vpx/vpx_encoder.h"
      25             : #include "vpx/vp8cx.h"
      26             : 
      27             : namespace webrtc {
      28             : 
      29           0 : DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers,
      30           0 :                                              uint8_t initial_tl0_pic_idx)
      31             :     : number_of_temporal_layers_(number_of_temporal_layers),
      32             :       temporal_ids_length_(0),
      33             :       temporal_pattern_length_(0),
      34             :       tl0_pic_idx_(initial_tl0_pic_idx),
      35             :       pattern_idx_(255),
      36             :       timestamp_(0),
      37           0 :       last_base_layer_sync_(false) {
      38           0 :   RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers);
      39           0 :   RTC_CHECK_GE(number_of_temporal_layers, 0);
      40           0 :   memset(temporal_ids_, 0, sizeof(temporal_ids_));
      41           0 :   memset(temporal_pattern_, 0, sizeof(temporal_pattern_));
      42           0 : }
      43             : 
      44           0 : int DefaultTemporalLayers::CurrentLayerId() const {
      45           0 :   assert(temporal_ids_length_ > 0);
      46           0 :   int index = pattern_idx_ % temporal_ids_length_;
      47           0 :   assert(index >= 0);
      48           0 :   return temporal_ids_[index];
      49             : }
      50             : 
      51           0 : std::vector<uint32_t> DefaultTemporalLayers::OnRatesUpdated(
      52             :     int bitrate_kbps,
      53             :     int max_bitrate_kbps,
      54             :     int framerate) {
      55           0 :   std::vector<uint32_t> bitrates;
      56           0 :   const int num_layers = std::max(1, number_of_temporal_layers_);
      57           0 :   for (int i = 0; i < num_layers; ++i) {
      58             :     float layer_bitrate =
      59           0 :         bitrate_kbps * kVp8LayerRateAlloction[num_layers - 1][i];
      60           0 :     bitrates.push_back(static_cast<uint32_t>(layer_bitrate + 0.5));
      61             :   }
      62           0 :   new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>(bitrates);
      63             : 
      64             :   // Allocation table is of aggregates, transform to individual rates.
      65           0 :   uint32_t sum = 0;
      66           0 :   for (int i = 0; i < num_layers; ++i) {
      67           0 :     uint32_t layer_bitrate = bitrates[i];
      68           0 :     RTC_DCHECK_LE(sum, bitrates[i]);
      69           0 :     bitrates[i] -= sum;
      70           0 :     sum = layer_bitrate;
      71             : 
      72           0 :     if (sum >= static_cast<uint32_t>(bitrate_kbps)) {
      73             :       // Sum adds up; any subsequent layers will be 0.
      74           0 :       bitrates.resize(i + 1);
      75           0 :       break;
      76             :     }
      77             :   }
      78             : 
      79           0 :   return bitrates;
      80             : }
      81             : 
      82           0 : bool DefaultTemporalLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) {
      83           0 :   if (!new_bitrates_kbps_)
      84           0 :     return false;
      85             : 
      86           0 :   switch (number_of_temporal_layers_) {
      87             :     case 0:
      88             :       FALLTHROUGH();
      89             :     case 1:
      90           0 :       temporal_ids_length_ = 1;
      91           0 :       temporal_ids_[0] = 0;
      92           0 :       cfg->ts_number_layers = number_of_temporal_layers_;
      93           0 :       cfg->ts_periodicity = temporal_ids_length_;
      94           0 :       cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0];
      95           0 :       cfg->ts_rate_decimator[0] = 1;
      96           0 :       memcpy(cfg->ts_layer_id, temporal_ids_,
      97           0 :              sizeof(unsigned int) * temporal_ids_length_);
      98           0 :       temporal_pattern_length_ = 1;
      99           0 :       temporal_pattern_[0] = kTemporalUpdateLastRefAll;
     100           0 :       break;
     101             :     case 2:
     102           0 :       temporal_ids_length_ = 2;
     103           0 :       temporal_ids_[0] = 0;
     104           0 :       temporal_ids_[1] = 1;
     105           0 :       cfg->ts_number_layers = number_of_temporal_layers_;
     106           0 :       cfg->ts_periodicity = temporal_ids_length_;
     107             :       // Split stream 60% 40%.
     108             :       // Bitrate API for VP8 is the agregated bitrate for all lower layers.
     109           0 :       cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0];
     110           0 :       cfg->ts_target_bitrate[1] = (*new_bitrates_kbps_)[1];
     111           0 :       cfg->ts_rate_decimator[0] = 2;
     112           0 :       cfg->ts_rate_decimator[1] = 1;
     113           0 :       memcpy(cfg->ts_layer_id, temporal_ids_,
     114           0 :              sizeof(unsigned int) * temporal_ids_length_);
     115           0 :       temporal_pattern_length_ = 8;
     116           0 :       temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef;
     117           0 :       temporal_pattern_[1] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
     118           0 :       temporal_pattern_[2] = kTemporalUpdateLastRefAltRef;
     119           0 :       temporal_pattern_[3] = kTemporalUpdateGoldenRefAltRef;
     120           0 :       temporal_pattern_[4] = kTemporalUpdateLastRefAltRef;
     121           0 :       temporal_pattern_[5] = kTemporalUpdateGoldenRefAltRef;
     122           0 :       temporal_pattern_[6] = kTemporalUpdateLastRefAltRef;
     123           0 :       temporal_pattern_[7] = kTemporalUpdateNone;
     124           0 :       break;
     125             :     case 3:
     126           0 :       temporal_ids_length_ = 4;
     127           0 :       temporal_ids_[0] = 0;
     128           0 :       temporal_ids_[1] = 2;
     129           0 :       temporal_ids_[2] = 1;
     130           0 :       temporal_ids_[3] = 2;
     131           0 :       cfg->ts_number_layers = number_of_temporal_layers_;
     132           0 :       cfg->ts_periodicity = temporal_ids_length_;
     133             :       // Split stream 40% 20% 40%.
     134             :       // Bitrate API for VP8 is the agregated bitrate for all lower layers.
     135           0 :       cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0];
     136           0 :       cfg->ts_target_bitrate[1] = (*new_bitrates_kbps_)[1];
     137           0 :       cfg->ts_target_bitrate[2] = (*new_bitrates_kbps_)[2];
     138           0 :       cfg->ts_rate_decimator[0] = 4;
     139           0 :       cfg->ts_rate_decimator[1] = 2;
     140           0 :       cfg->ts_rate_decimator[2] = 1;
     141           0 :       memcpy(cfg->ts_layer_id, temporal_ids_,
     142           0 :              sizeof(unsigned int) * temporal_ids_length_);
     143           0 :       temporal_pattern_length_ = 8;
     144           0 :       temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef;
     145           0 :       temporal_pattern_[1] = kTemporalUpdateNoneNoRefGoldenRefAltRef;
     146           0 :       temporal_pattern_[2] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
     147           0 :       temporal_pattern_[3] = kTemporalUpdateNone;
     148           0 :       temporal_pattern_[4] = kTemporalUpdateLastRefAltRef;
     149           0 :       temporal_pattern_[5] = kTemporalUpdateNone;
     150           0 :       temporal_pattern_[6] = kTemporalUpdateGoldenRefAltRef;
     151           0 :       temporal_pattern_[7] = kTemporalUpdateNone;
     152           0 :       break;
     153             :     case 4:
     154           0 :       temporal_ids_length_ = 8;
     155           0 :       temporal_ids_[0] = 0;
     156           0 :       temporal_ids_[1] = 3;
     157           0 :       temporal_ids_[2] = 2;
     158           0 :       temporal_ids_[3] = 3;
     159           0 :       temporal_ids_[4] = 1;
     160           0 :       temporal_ids_[5] = 3;
     161           0 :       temporal_ids_[6] = 2;
     162           0 :       temporal_ids_[7] = 3;
     163             :       // Split stream 25% 15% 20% 40%.
     164             :       // Bitrate API for VP8 is the agregated bitrate for all lower layers.
     165           0 :       cfg->ts_number_layers = 4;
     166           0 :       cfg->ts_periodicity = temporal_ids_length_;
     167           0 :       cfg->ts_target_bitrate[0] = (*new_bitrates_kbps_)[0];
     168           0 :       cfg->ts_target_bitrate[1] = (*new_bitrates_kbps_)[1];
     169           0 :       cfg->ts_target_bitrate[2] = (*new_bitrates_kbps_)[2];
     170           0 :       cfg->ts_target_bitrate[3] = (*new_bitrates_kbps_)[3];
     171           0 :       cfg->ts_rate_decimator[0] = 8;
     172           0 :       cfg->ts_rate_decimator[1] = 4;
     173           0 :       cfg->ts_rate_decimator[2] = 2;
     174           0 :       cfg->ts_rate_decimator[3] = 1;
     175           0 :       memcpy(cfg->ts_layer_id, temporal_ids_,
     176           0 :              sizeof(unsigned int) * temporal_ids_length_);
     177           0 :       temporal_pattern_length_ = 16;
     178           0 :       temporal_pattern_[0] = kTemporalUpdateLast;
     179           0 :       temporal_pattern_[1] = kTemporalUpdateNone;
     180           0 :       temporal_pattern_[2] = kTemporalUpdateAltrefWithoutDependency;
     181           0 :       temporal_pattern_[3] = kTemporalUpdateNone;
     182           0 :       temporal_pattern_[4] = kTemporalUpdateGoldenWithoutDependency;
     183           0 :       temporal_pattern_[5] = kTemporalUpdateNone;
     184           0 :       temporal_pattern_[6] = kTemporalUpdateAltref;
     185           0 :       temporal_pattern_[7] = kTemporalUpdateNone;
     186           0 :       temporal_pattern_[8] = kTemporalUpdateLast;
     187           0 :       temporal_pattern_[9] = kTemporalUpdateNone;
     188           0 :       temporal_pattern_[10] = kTemporalUpdateAltref;
     189           0 :       temporal_pattern_[11] = kTemporalUpdateNone;
     190           0 :       temporal_pattern_[12] = kTemporalUpdateGolden;
     191           0 :       temporal_pattern_[13] = kTemporalUpdateNone;
     192           0 :       temporal_pattern_[14] = kTemporalUpdateAltref;
     193           0 :       temporal_pattern_[15] = kTemporalUpdateNone;
     194           0 :       break;
     195             :     default:
     196           0 :       RTC_NOTREACHED();
     197           0 :       return false;
     198             :   }
     199             : 
     200           0 :   new_bitrates_kbps_ = rtc::Optional<std::vector<uint32_t>>();
     201             : 
     202           0 :   return true;
     203             : }
     204             : 
     205           0 : int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) {
     206           0 :   assert(number_of_temporal_layers_ > 0);
     207           0 :   assert(kMaxTemporalPattern >= temporal_pattern_length_);
     208           0 :   assert(0 < temporal_pattern_length_);
     209           0 :   int flags = 0;
     210           0 :   int patternIdx = ++pattern_idx_ % temporal_pattern_length_;
     211           0 :   assert(kMaxTemporalPattern >= patternIdx);
     212           0 :   switch (temporal_pattern_[patternIdx]) {
     213             :     case kTemporalUpdateLast:
     214           0 :       flags |= VP8_EFLAG_NO_UPD_GF;
     215           0 :       flags |= VP8_EFLAG_NO_UPD_ARF;
     216           0 :       flags |= VP8_EFLAG_NO_REF_GF;
     217           0 :       flags |= VP8_EFLAG_NO_REF_ARF;
     218           0 :       break;
     219             :     case kTemporalUpdateGoldenWithoutDependency:
     220           0 :       flags |= VP8_EFLAG_NO_REF_GF;
     221             :       // Deliberately no break here.
     222             :       FALLTHROUGH();
     223             :     case kTemporalUpdateGolden:
     224           0 :       flags |= VP8_EFLAG_NO_REF_ARF;
     225           0 :       flags |= VP8_EFLAG_NO_UPD_ARF;
     226           0 :       flags |= VP8_EFLAG_NO_UPD_LAST;
     227           0 :       break;
     228             :     case kTemporalUpdateAltrefWithoutDependency:
     229           0 :       flags |= VP8_EFLAG_NO_REF_ARF;
     230           0 :       flags |= VP8_EFLAG_NO_REF_GF;
     231             :       // Deliberately no break here.
     232             :       FALLTHROUGH();
     233             :     case kTemporalUpdateAltref:
     234           0 :       flags |= VP8_EFLAG_NO_UPD_GF;
     235           0 :       flags |= VP8_EFLAG_NO_UPD_LAST;
     236           0 :       break;
     237             :     case kTemporalUpdateNoneNoRefAltref:
     238           0 :       flags |= VP8_EFLAG_NO_REF_ARF;
     239             :       // Deliberately no break here.
     240             :       FALLTHROUGH();
     241             :     case kTemporalUpdateNone:
     242           0 :       flags |= VP8_EFLAG_NO_UPD_GF;
     243           0 :       flags |= VP8_EFLAG_NO_UPD_ARF;
     244           0 :       flags |= VP8_EFLAG_NO_UPD_LAST;
     245           0 :       flags |= VP8_EFLAG_NO_UPD_ENTROPY;
     246           0 :       break;
     247             :     case kTemporalUpdateNoneNoRefGoldenRefAltRef:
     248           0 :       flags |= VP8_EFLAG_NO_REF_GF;
     249           0 :       flags |= VP8_EFLAG_NO_UPD_GF;
     250           0 :       flags |= VP8_EFLAG_NO_UPD_ARF;
     251           0 :       flags |= VP8_EFLAG_NO_UPD_LAST;
     252           0 :       flags |= VP8_EFLAG_NO_UPD_ENTROPY;
     253           0 :       break;
     254             :     case kTemporalUpdateGoldenWithoutDependencyRefAltRef:
     255           0 :       flags |= VP8_EFLAG_NO_REF_GF;
     256           0 :       flags |= VP8_EFLAG_NO_UPD_ARF;
     257           0 :       flags |= VP8_EFLAG_NO_UPD_LAST;
     258           0 :       break;
     259             :     case kTemporalUpdateLastRefAltRef:
     260           0 :       flags |= VP8_EFLAG_NO_UPD_GF;
     261           0 :       flags |= VP8_EFLAG_NO_UPD_ARF;
     262           0 :       flags |= VP8_EFLAG_NO_REF_GF;
     263           0 :       break;
     264             :     case kTemporalUpdateGoldenRefAltRef:
     265           0 :       flags |= VP8_EFLAG_NO_UPD_ARF;
     266           0 :       flags |= VP8_EFLAG_NO_UPD_LAST;
     267           0 :       break;
     268             :     case kTemporalUpdateLastAndGoldenRefAltRef:
     269           0 :       flags |= VP8_EFLAG_NO_UPD_ARF;
     270           0 :       flags |= VP8_EFLAG_NO_REF_GF;
     271           0 :       break;
     272             :     case kTemporalUpdateLastRefAll:
     273           0 :       flags |= VP8_EFLAG_NO_UPD_ARF;
     274           0 :       flags |= VP8_EFLAG_NO_UPD_GF;
     275           0 :       break;
     276             :   }
     277           0 :   return flags;
     278             : }
     279             : 
     280           0 : void DefaultTemporalLayers::PopulateCodecSpecific(
     281             :     bool base_layer_sync,
     282             :     CodecSpecificInfoVP8* vp8_info,
     283             :     uint32_t timestamp) {
     284           0 :   assert(number_of_temporal_layers_ > 0);
     285           0 :   assert(0 < temporal_ids_length_);
     286             : 
     287           0 :   if (number_of_temporal_layers_ == 1) {
     288           0 :     vp8_info->temporalIdx = kNoTemporalIdx;
     289           0 :     vp8_info->layerSync = false;
     290           0 :     vp8_info->tl0PicIdx = kNoTl0PicIdx;
     291             :   } else {
     292           0 :     if (base_layer_sync) {
     293           0 :       vp8_info->temporalIdx = 0;
     294           0 :       vp8_info->layerSync = true;
     295             :     } else {
     296           0 :       vp8_info->temporalIdx = CurrentLayerId();
     297             :       TemporalReferences temporal_reference =
     298           0 :           temporal_pattern_[pattern_idx_ % temporal_pattern_length_];
     299             : 
     300           0 :       if (temporal_reference == kTemporalUpdateAltrefWithoutDependency ||
     301           0 :           temporal_reference == kTemporalUpdateGoldenWithoutDependency ||
     302             :           temporal_reference ==
     303           0 :               kTemporalUpdateGoldenWithoutDependencyRefAltRef ||
     304           0 :           temporal_reference == kTemporalUpdateNoneNoRefGoldenRefAltRef ||
     305           0 :           (temporal_reference == kTemporalUpdateNone &&
     306           0 :            number_of_temporal_layers_ == 4)) {
     307           0 :         vp8_info->layerSync = true;
     308             :       } else {
     309           0 :         vp8_info->layerSync = false;
     310             :       }
     311             :     }
     312           0 :     if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) {
     313             :       // Regardless of pattern the frame after a base layer sync will always
     314             :       // be a layer sync.
     315           0 :       vp8_info->layerSync = true;
     316             :     }
     317           0 :     if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) {
     318           0 :       timestamp_ = timestamp;
     319           0 :       tl0_pic_idx_++;
     320             :     }
     321           0 :     last_base_layer_sync_ = base_layer_sync;
     322           0 :     vp8_info->tl0PicIdx = tl0_pic_idx_;
     323             :   }
     324           0 : }
     325             : 
     326           0 : TemporalLayers* TemporalLayersFactory::Create(
     327             :     int simulcast_id,
     328             :     int temporal_layers,
     329             :     uint8_t initial_tl0_pic_idx) const {
     330             :   TemporalLayers* tl =
     331           0 :       new DefaultTemporalLayers(temporal_layers, initial_tl0_pic_idx);
     332           0 :   if (listener_)
     333           0 :     listener_->OnTemporalLayersCreated(simulcast_id, tl);
     334           0 :   return tl;
     335             : }
     336             : 
     337           0 : void TemporalLayersFactory::SetListener(TemporalLayersListener* listener) {
     338           0 :   listener_ = listener;
     339           0 : }
     340             : 
     341             : }  // namespace webrtc

Generated by: LCOV version 1.13