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 "webrtc/modules/interface/module_common_types.h"
17#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
18#include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
19
20#include "vpx/vpx_encoder.h"
21#include "vpx/vp8cx.h"
22
23namespace webrtc {
24
25DefaultTemporalLayers::DefaultTemporalLayers(int numberOfTemporalLayers,
26                                             uint8_t initial_tl0_pic_idx)
27    : number_of_temporal_layers_(numberOfTemporalLayers),
28      temporal_ids_length_(0),
29      temporal_pattern_length_(0),
30      tl0_pic_idx_(initial_tl0_pic_idx),
31      pattern_idx_(255),
32      timestamp_(0),
33      last_base_layer_sync_(false) {
34  assert(kMaxTemporalStreams >= numberOfTemporalLayers);
35  memset(temporal_ids_, 0, sizeof(temporal_ids_));
36  memset(temporal_pattern_, 0, sizeof(temporal_pattern_));
37}
38
39int DefaultTemporalLayers::CurrentLayerId() const {
40  assert(temporal_ids_length_ > 0);
41  int index = pattern_idx_ % temporal_ids_length_;
42  assert(index >= 0);
43  return temporal_ids_[index];
44 }
45
46bool DefaultTemporalLayers::ConfigureBitrates(int bitrateKbit,
47                                              int max_bitrate_kbit,
48                                              int framerate,
49                                              vpx_codec_enc_cfg_t* cfg) {
50  switch (number_of_temporal_layers_) {
51    case 0:
52    case 1:
53      temporal_ids_length_ = 1;
54      temporal_ids_[0] = 0;
55      cfg->ts_number_layers = number_of_temporal_layers_;
56      cfg->ts_periodicity = temporal_ids_length_;
57      cfg->ts_target_bitrate[0] = bitrateKbit;
58      cfg->ts_rate_decimator[0] = 1;
59      memcpy(cfg->ts_layer_id,
60             temporal_ids_,
61             sizeof(unsigned int) * temporal_ids_length_);
62      temporal_pattern_length_ = 1;
63      temporal_pattern_[0] = kTemporalUpdateLastRefAll;
64      break;
65    case 2:
66      temporal_ids_length_ = 2;
67      temporal_ids_[0] = 0;
68      temporal_ids_[1] = 1;
69      cfg->ts_number_layers = number_of_temporal_layers_;
70      cfg->ts_periodicity = temporal_ids_length_;
71      // Split stream 60% 40%.
72      // Bitrate API for VP8 is the agregated bitrate for all lower layers.
73      cfg->ts_target_bitrate[0] = bitrateKbit * kVp8LayerRateAlloction[1][0];
74      cfg->ts_target_bitrate[1] = bitrateKbit;
75      cfg->ts_rate_decimator[0] = 2;
76      cfg->ts_rate_decimator[1] = 1;
77      memcpy(cfg->ts_layer_id,
78             temporal_ids_,
79             sizeof(unsigned int) * temporal_ids_length_);
80      temporal_pattern_length_ = 8;
81      temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef;
82      temporal_pattern_[1] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
83      temporal_pattern_[2] = kTemporalUpdateLastRefAltRef;
84      temporal_pattern_[3] = kTemporalUpdateGoldenRefAltRef;
85      temporal_pattern_[4] = kTemporalUpdateLastRefAltRef;
86      temporal_pattern_[5] = kTemporalUpdateGoldenRefAltRef;
87      temporal_pattern_[6] = kTemporalUpdateLastRefAltRef;
88      temporal_pattern_[7] = kTemporalUpdateNone;
89      break;
90    case 3:
91      temporal_ids_length_ = 4;
92      temporal_ids_[0] = 0;
93      temporal_ids_[1] = 2;
94      temporal_ids_[2] = 1;
95      temporal_ids_[3] = 2;
96      cfg->ts_number_layers = number_of_temporal_layers_;
97      cfg->ts_periodicity = temporal_ids_length_;
98      // Split stream 40% 20% 40%.
99      // Bitrate API for VP8 is the agregated bitrate for all lower layers.
100      cfg->ts_target_bitrate[0] = bitrateKbit * kVp8LayerRateAlloction[2][0];
101      cfg->ts_target_bitrate[1] = bitrateKbit * kVp8LayerRateAlloction[2][1];
102      cfg->ts_target_bitrate[2] = bitrateKbit;
103      cfg->ts_rate_decimator[0] = 4;
104      cfg->ts_rate_decimator[1] = 2;
105      cfg->ts_rate_decimator[2] = 1;
106      memcpy(cfg->ts_layer_id,
107             temporal_ids_,
108             sizeof(unsigned int) * temporal_ids_length_);
109      temporal_pattern_length_ = 8;
110      temporal_pattern_[0] = kTemporalUpdateLastAndGoldenRefAltRef;
111      temporal_pattern_[1] = kTemporalUpdateNoneNoRefGoldenRefAltRef;
112      temporal_pattern_[2] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
113      temporal_pattern_[3] = kTemporalUpdateNone;
114      temporal_pattern_[4] = kTemporalUpdateLastRefAltRef;
115      temporal_pattern_[5] = kTemporalUpdateNone;
116      temporal_pattern_[6] = kTemporalUpdateGoldenRefAltRef;
117      temporal_pattern_[7] = kTemporalUpdateNone;
118      break;
119    case 4:
120      temporal_ids_length_ = 8;
121      temporal_ids_[0] = 0;
122      temporal_ids_[1] = 3;
123      temporal_ids_[2] = 2;
124      temporal_ids_[3] = 3;
125      temporal_ids_[4] = 1;
126      temporal_ids_[5] = 3;
127      temporal_ids_[6] = 2;
128      temporal_ids_[7] = 3;
129      // Split stream 25% 15% 20% 40%.
130      // Bitrate API for VP8 is the agregated bitrate for all lower layers.
131      cfg->ts_number_layers = 4;
132      cfg->ts_periodicity = temporal_ids_length_;
133      cfg->ts_target_bitrate[0] = bitrateKbit * kVp8LayerRateAlloction[3][0];
134      cfg->ts_target_bitrate[1] = bitrateKbit * kVp8LayerRateAlloction[3][1];
135      cfg->ts_target_bitrate[2] = bitrateKbit * kVp8LayerRateAlloction[3][2];
136      cfg->ts_target_bitrate[3] = bitrateKbit;
137      cfg->ts_rate_decimator[0] = 8;
138      cfg->ts_rate_decimator[1] = 4;
139      cfg->ts_rate_decimator[2] = 2;
140      cfg->ts_rate_decimator[3] = 1;
141      memcpy(cfg->ts_layer_id,
142             temporal_ids_,
143             sizeof(unsigned int) * temporal_ids_length_);
144      temporal_pattern_length_ = 16;
145      temporal_pattern_[0] = kTemporalUpdateLast;
146      temporal_pattern_[1] = kTemporalUpdateNone;
147      temporal_pattern_[2] = kTemporalUpdateAltrefWithoutDependency;
148      temporal_pattern_[3] = kTemporalUpdateNone;
149      temporal_pattern_[4] = kTemporalUpdateGoldenWithoutDependency;
150      temporal_pattern_[5] = kTemporalUpdateNone;
151      temporal_pattern_[6] = kTemporalUpdateAltref;
152      temporal_pattern_[7] = kTemporalUpdateNone;
153      temporal_pattern_[8] = kTemporalUpdateLast;
154      temporal_pattern_[9] = kTemporalUpdateNone;
155      temporal_pattern_[10] = kTemporalUpdateAltref;
156      temporal_pattern_[11] = kTemporalUpdateNone;
157      temporal_pattern_[12] = kTemporalUpdateGolden;
158      temporal_pattern_[13] = kTemporalUpdateNone;
159      temporal_pattern_[14] = kTemporalUpdateAltref;
160      temporal_pattern_[15] = kTemporalUpdateNone;
161      break;
162    default:
163      assert(false);
164      return false;
165  }
166  return true;
167}
168
169int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) {
170  assert(number_of_temporal_layers_ > 0);
171  assert(kMaxTemporalPattern >= temporal_pattern_length_);
172  assert(0 < temporal_pattern_length_);
173  int flags = 0;
174  int patternIdx = ++pattern_idx_ % temporal_pattern_length_;
175  assert(kMaxTemporalPattern >= patternIdx);
176  switch (temporal_pattern_[patternIdx]) {
177    case kTemporalUpdateLast:
178      flags |= VP8_EFLAG_NO_UPD_GF;
179      flags |= VP8_EFLAG_NO_UPD_ARF;
180      flags |= VP8_EFLAG_NO_REF_GF;
181      flags |= VP8_EFLAG_NO_REF_ARF;
182      break;
183    case kTemporalUpdateGoldenWithoutDependency:
184      flags |= VP8_EFLAG_NO_REF_GF;
185      // Deliberately no break here.
186    case kTemporalUpdateGolden:
187      flags |= VP8_EFLAG_NO_REF_ARF;
188      flags |= VP8_EFLAG_NO_UPD_ARF;
189      flags |= VP8_EFLAG_NO_UPD_LAST;
190      break;
191    case kTemporalUpdateAltrefWithoutDependency:
192      flags |= VP8_EFLAG_NO_REF_ARF;
193      flags |= VP8_EFLAG_NO_REF_GF;
194      // Deliberately no break here.
195    case kTemporalUpdateAltref:
196      flags |= VP8_EFLAG_NO_UPD_GF;
197      flags |= VP8_EFLAG_NO_UPD_LAST;
198      break;
199    case kTemporalUpdateNoneNoRefAltref:
200      flags |= VP8_EFLAG_NO_REF_ARF;
201      // Deliberately no break here.
202    case kTemporalUpdateNone:
203      flags |= VP8_EFLAG_NO_UPD_GF;
204      flags |= VP8_EFLAG_NO_UPD_ARF;
205      flags |= VP8_EFLAG_NO_UPD_LAST;
206      flags |= VP8_EFLAG_NO_UPD_ENTROPY;
207      break;
208    case kTemporalUpdateNoneNoRefGoldenRefAltRef:
209      flags |= VP8_EFLAG_NO_REF_GF;
210      flags |= VP8_EFLAG_NO_UPD_GF;
211      flags |= VP8_EFLAG_NO_UPD_ARF;
212      flags |= VP8_EFLAG_NO_UPD_LAST;
213      flags |= VP8_EFLAG_NO_UPD_ENTROPY;
214      break;
215    case kTemporalUpdateGoldenWithoutDependencyRefAltRef:
216      flags |= VP8_EFLAG_NO_REF_GF;
217      flags |= VP8_EFLAG_NO_UPD_ARF;
218      flags |= VP8_EFLAG_NO_UPD_LAST;
219      break;
220    case kTemporalUpdateLastRefAltRef:
221      flags |= VP8_EFLAG_NO_UPD_GF;
222      flags |= VP8_EFLAG_NO_UPD_ARF;
223      flags |= VP8_EFLAG_NO_REF_GF;
224      break;
225    case kTemporalUpdateGoldenRefAltRef:
226      flags |= VP8_EFLAG_NO_UPD_ARF;
227      flags |= VP8_EFLAG_NO_UPD_LAST;
228      break;
229    case kTemporalUpdateLastAndGoldenRefAltRef:
230      flags |= VP8_EFLAG_NO_UPD_ARF;
231      flags |= VP8_EFLAG_NO_REF_GF;
232      break;
233    case kTemporalUpdateLastRefAll:
234      flags |= VP8_EFLAG_NO_UPD_ARF;
235      flags |= VP8_EFLAG_NO_UPD_GF;
236      break;
237  }
238  return flags;
239}
240
241void DefaultTemporalLayers::PopulateCodecSpecific(
242    bool base_layer_sync,
243    CodecSpecificInfoVP8 *vp8_info,
244    uint32_t timestamp) {
245  assert(number_of_temporal_layers_ > 0);
246  assert(0 < temporal_ids_length_);
247
248  if (number_of_temporal_layers_ == 1) {
249    vp8_info->temporalIdx = kNoTemporalIdx;
250    vp8_info->layerSync = false;
251    vp8_info->tl0PicIdx = kNoTl0PicIdx;
252  } else {
253    if (base_layer_sync) {
254    vp8_info->temporalIdx = 0;
255    vp8_info->layerSync = true;
256    } else {
257      vp8_info->temporalIdx = CurrentLayerId();
258      TemporalReferences temporal_reference =
259          temporal_pattern_[pattern_idx_ % temporal_pattern_length_];
260
261      if (temporal_reference == kTemporalUpdateAltrefWithoutDependency ||
262          temporal_reference == kTemporalUpdateGoldenWithoutDependency ||
263          temporal_reference ==
264              kTemporalUpdateGoldenWithoutDependencyRefAltRef ||
265          temporal_reference == kTemporalUpdateNoneNoRefGoldenRefAltRef ||
266          (temporal_reference == kTemporalUpdateNone &&
267              number_of_temporal_layers_ == 4)) {
268        vp8_info->layerSync = true;
269      } else {
270        vp8_info->layerSync = false;
271      }
272    }
273    if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) {
274      // Regardless of pattern the frame after a base layer sync will always
275      // be a layer sync.
276      vp8_info->layerSync = true;
277    }
278    if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) {
279      timestamp_ = timestamp;
280      tl0_pic_idx_++;
281    }
282    last_base_layer_sync_ = base_layer_sync;
283    vp8_info->tl0PicIdx = tl0_pic_idx_;
284  }
285}
286
287TemporalLayers* TemporalLayers::Factory::Create(
288    int temporal_layers,
289    uint8_t initial_tl0_pic_idx) const {
290  return new DefaultTemporalLayers(temporal_layers, initial_tl0_pic_idx);
291}
292}  // namespace webrtc
293