Allow for 1 layer case to be set in temporal_layers.
Review URL: https://webrtc-codereview.appspot.com/971007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3188 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -40,7 +40,17 @@ bool TemporalLayers::ConfigureBitrates(int bitrateKbit,
|
||||
switch (number_of_temporal_layers_) {
|
||||
case 0:
|
||||
case 1:
|
||||
// Do nothing.
|
||||
temporal_ids_length_ = 1;
|
||||
temporal_ids_[0] = 0;
|
||||
cfg->ts_number_layers = number_of_temporal_layers_;
|
||||
cfg->ts_periodicity = temporal_ids_length_;
|
||||
cfg->ts_target_bitrate[0] = bitrateKbit;
|
||||
cfg->ts_rate_decimator[0] = 1;
|
||||
memcpy(cfg->ts_layer_id,
|
||||
temporal_ids_,
|
||||
sizeof(unsigned int) * temporal_ids_length_);
|
||||
temporal_pattern_length_ = 1;
|
||||
temporal_pattern_[0] = kTemporalUpdateLastRefAll;
|
||||
break;
|
||||
case 2:
|
||||
temporal_ids_length_ = 2;
|
||||
@ -147,10 +157,9 @@ bool TemporalLayers::ConfigureBitrates(int bitrateKbit,
|
||||
}
|
||||
|
||||
int TemporalLayers::EncodeFlags() {
|
||||
assert(number_of_temporal_layers_ > 1);
|
||||
assert(number_of_temporal_layers_ > 0);
|
||||
assert(kMaxTemporalPattern >= temporal_pattern_length_);
|
||||
assert(0 < temporal_pattern_length_);
|
||||
|
||||
int flags = 0;
|
||||
int patternIdx = ++pattern_idx_ % temporal_pattern_length_;
|
||||
assert(kMaxTemporalPattern >= patternIdx);
|
||||
@ -211,6 +220,10 @@ int TemporalLayers::EncodeFlags() {
|
||||
flags |= VP8_EFLAG_NO_UPD_ARF;
|
||||
flags |= VP8_EFLAG_NO_REF_GF;
|
||||
break;
|
||||
case kTemporalUpdateLastRefAll:
|
||||
flags |= VP8_EFLAG_NO_UPD_ARF;
|
||||
flags |= VP8_EFLAG_NO_UPD_GF;
|
||||
break;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
@ -218,39 +231,47 @@ int TemporalLayers::EncodeFlags() {
|
||||
void TemporalLayers::PopulateCodecSpecific(bool base_layer_sync,
|
||||
CodecSpecificInfoVP8 *vp8_info,
|
||||
uint32_t timestamp) {
|
||||
assert(number_of_temporal_layers_ > 1);
|
||||
assert(number_of_temporal_layers_ > 0);
|
||||
assert(0 < temporal_ids_length_);
|
||||
|
||||
if (base_layer_sync) {
|
||||
if (number_of_temporal_layers_ == 1) {
|
||||
vp8_info->temporalIdx = kNoTemporalIdx;
|
||||
vp8_info->layerSync = false;
|
||||
vp8_info->tl0PicIdx = kNoTl0PicIdx;
|
||||
} else {
|
||||
if (base_layer_sync) {
|
||||
vp8_info->temporalIdx = 0;
|
||||
vp8_info->layerSync = true;
|
||||
} else {
|
||||
vp8_info->temporalIdx = temporal_ids_[pattern_idx_ % temporal_ids_length_];
|
||||
TemporalReferences temporal_reference =
|
||||
temporal_pattern_[pattern_idx_ % temporal_pattern_length_];
|
||||
|
||||
if (temporal_reference == kTemporalUpdateAltrefWithoutDependency ||
|
||||
temporal_reference == kTemporalUpdateGoldenWithoutDependency ||
|
||||
temporal_reference == kTemporalUpdateGoldenWithoutDependencyRefAltRef ||
|
||||
temporal_reference == kTemporalUpdateNoneNoRefGoldenRefAltRef ||
|
||||
(temporal_reference == kTemporalUpdateNone &&
|
||||
number_of_temporal_layers_ == 4)) {
|
||||
vp8_info->layerSync = true;
|
||||
} else {
|
||||
vp8_info->layerSync = false;
|
||||
vp8_info->temporalIdx = temporal_ids_
|
||||
[pattern_idx_ % temporal_ids_length_];
|
||||
TemporalReferences temporal_reference =
|
||||
temporal_pattern_[pattern_idx_ % temporal_pattern_length_];
|
||||
|
||||
if (temporal_reference == kTemporalUpdateAltrefWithoutDependency ||
|
||||
temporal_reference == kTemporalUpdateGoldenWithoutDependency ||
|
||||
temporal_reference ==
|
||||
kTemporalUpdateGoldenWithoutDependencyRefAltRef ||
|
||||
temporal_reference == kTemporalUpdateNoneNoRefGoldenRefAltRef ||
|
||||
(temporal_reference == kTemporalUpdateNone &&
|
||||
number_of_temporal_layers_ == 4)) {
|
||||
vp8_info->layerSync = true;
|
||||
} else {
|
||||
vp8_info->layerSync = false;
|
||||
}
|
||||
}
|
||||
if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) {
|
||||
// Regardless of pattern the frame after a base layer sync will always
|
||||
// be a layer sync.
|
||||
vp8_info->layerSync = true;
|
||||
}
|
||||
if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) {
|
||||
timestamp_ = timestamp;
|
||||
tl0_pic_idx_++;
|
||||
}
|
||||
last_base_layer_sync_ = base_layer_sync;
|
||||
vp8_info->tl0PicIdx = tl0_pic_idx_;
|
||||
}
|
||||
if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) {
|
||||
// Regardless of pattern the frame after a base layer sync will always
|
||||
// be a layer sync.
|
||||
vp8_info->layerSync = true;
|
||||
}
|
||||
if (vp8_info->temporalIdx == 0 && timestamp != timestamp_) {
|
||||
timestamp_ = timestamp;
|
||||
tl0_pic_idx_++;
|
||||
}
|
||||
last_base_layer_sync_ = base_layer_sync;
|
||||
vp8_info->tl0PicIdx = tl0_pic_idx_;
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
|
||||
@ -37,6 +37,9 @@ class TemporalLayers {
|
||||
|
||||
private:
|
||||
enum TemporalReferences {
|
||||
// For 1 layer case: reference all (last, golden, and alt ref), but only
|
||||
// update last.
|
||||
kTemporalUpdateLastRefAll = 12,
|
||||
// First base layer frame for 3 temporal layers, which updates last and
|
||||
// golden with alt ref dependency.
|
||||
kTemporalUpdateLastAndGoldenRefAltRef = 11,
|
||||
|
||||
@ -111,9 +111,7 @@ int VP8EncoderImpl::SetRates(uint32_t new_bitrate_kbit,
|
||||
config_->rc_target_bitrate = new_bitrate_kbit; // in kbit/s
|
||||
|
||||
#if WEBRTC_LIBVPX_VERSION >= 971
|
||||
if (temporal_layers_) {
|
||||
temporal_layers_->ConfigureBitrates(new_bitrate_kbit, config_);
|
||||
}
|
||||
temporal_layers_->ConfigureBitrates(new_bitrate_kbit, config_);
|
||||
#endif
|
||||
codec_.maxFramerate = new_framerate;
|
||||
|
||||
@ -159,12 +157,12 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
|
||||
|
||||
codec_ = *inst;
|
||||
|
||||
int num_temporal_layers = inst->codecSpecific.VP8.numberOfTemporalLayers > 1 ?
|
||||
inst->codecSpecific.VP8.numberOfTemporalLayers : 1;
|
||||
|
||||
#if WEBRTC_LIBVPX_VERSION >= 971
|
||||
if (inst->codecSpecific.VP8.numberOfTemporalLayers > 1) {
|
||||
assert(temporal_layers_ == NULL);
|
||||
temporal_layers_ =
|
||||
new TemporalLayers(inst->codecSpecific.VP8.numberOfTemporalLayers);
|
||||
}
|
||||
assert(temporal_layers_ == NULL);
|
||||
temporal_layers_ = new TemporalLayers(num_temporal_layers);
|
||||
#endif
|
||||
// random start 16 bits is enough.
|
||||
picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF;
|
||||
@ -191,9 +189,7 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
|
||||
config_->rc_target_bitrate = inst->startBitrate; // in kbit/s
|
||||
|
||||
#if WEBRTC_LIBVPX_VERSION >= 971
|
||||
if (temporal_layers_) {
|
||||
temporal_layers_->ConfigureBitrates(inst->startBitrate, config_);
|
||||
}
|
||||
temporal_layers_->ConfigureBitrates(inst->startBitrate, config_);
|
||||
#endif
|
||||
// setting the time base of the codec
|
||||
config_->g_timebase.num = 1;
|
||||
@ -204,8 +200,8 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
|
||||
case kResilienceOff:
|
||||
config_->g_error_resilient = 0;
|
||||
#if WEBRTC_LIBVPX_VERSION >= 971
|
||||
if (temporal_layers_) {
|
||||
// Must be on for temporal layers.
|
||||
if (num_temporal_layers > 1) {
|
||||
// Must be on for temporal layers (i.e., |num_temporal_layers| > 1).
|
||||
config_->g_error_resilient = 1;
|
||||
}
|
||||
#endif
|
||||
@ -363,9 +359,7 @@ int VP8EncoderImpl::Encode(const I420VideoFrame& input_image,
|
||||
|
||||
int flags = 0;
|
||||
#if WEBRTC_LIBVPX_VERSION >= 971
|
||||
if (temporal_layers_) {
|
||||
flags |= temporal_layers_->EncodeFlags();
|
||||
}
|
||||
flags |= temporal_layers_->EncodeFlags();
|
||||
#endif
|
||||
bool send_keyframe = (frame_type == kKeyFrame);
|
||||
if (send_keyframe) {
|
||||
@ -442,17 +436,13 @@ void VP8EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
|
||||
vp8Info->keyIdx = kNoKeyIdx; // TODO(hlundin) populate this
|
||||
vp8Info->nonReference = (pkt.data.frame.flags & VPX_FRAME_IS_DROPPABLE) != 0;
|
||||
#if WEBRTC_LIBVPX_VERSION >= 971
|
||||
if (temporal_layers_) {
|
||||
temporal_layers_->PopulateCodecSpecific(
|
||||
(pkt.data.frame.flags & VPX_FRAME_IS_KEY) ? true : false, vp8Info,
|
||||
timestamp);
|
||||
} else {
|
||||
#endif
|
||||
vp8Info->temporalIdx = kNoTemporalIdx;
|
||||
vp8Info->layerSync = false;
|
||||
vp8Info->tl0PicIdx = kNoTl0PicIdx;
|
||||
#if WEBRTC_LIBVPX_VERSION >= 971
|
||||
}
|
||||
temporal_layers_->PopulateCodecSpecific(
|
||||
(pkt.data.frame.flags & VPX_FRAME_IS_KEY) ? true : false, vp8Info,
|
||||
timestamp);
|
||||
#else
|
||||
vp8Info->temporalIdx = kNoTemporalIdx;
|
||||
vp8Info->layerSync = false;
|
||||
vp8Info->tl0PicIdx = kNoTl0PicIdx;
|
||||
#endif
|
||||
picture_id_ = (picture_id_ + 1) & 0x7FFF; // prepare next
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user