Refactoring temporal layers implementation and adding VideoCodecMode for easier control of codec settings.
Review URL: https://webrtc-codereview.appspot.com/1105007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3528 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
/* 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
|
||||
@ -7,26 +7,27 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "temporal_layers.h"
|
||||
#include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cassert>
|
||||
|
||||
#include "modules/interface/module_common_types.h"
|
||||
#include "modules/video_coding/codecs/interface/video_codec_interface.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_common_types.h"
|
||||
#include "webrtc/modules/interface/module_common_types.h"
|
||||
#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
|
||||
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
|
||||
|
||||
#include "vpx/vpx_encoder.h"
|
||||
#include "vpx/vp8cx.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
TemporalLayers::TemporalLayers(int numberOfTemporalLayers)
|
||||
DefaultTemporalLayers::DefaultTemporalLayers(int numberOfTemporalLayers,
|
||||
uint8_t initial_tl0_pic_idx)
|
||||
: number_of_temporal_layers_(numberOfTemporalLayers),
|
||||
temporal_ids_length_(0),
|
||||
temporal_pattern_length_(0),
|
||||
tl0_pic_idx_(rand()),
|
||||
tl0_pic_idx_(initial_tl0_pic_idx),
|
||||
pattern_idx_(255),
|
||||
timestamp_(0),
|
||||
last_base_layer_sync_(false) {
|
||||
@ -35,8 +36,9 @@ TemporalLayers::TemporalLayers(int numberOfTemporalLayers)
|
||||
memset(temporal_pattern_, 0, sizeof(temporal_pattern_));
|
||||
}
|
||||
|
||||
bool TemporalLayers::ConfigureBitrates(int bitrateKbit,
|
||||
vpx_codec_enc_cfg_t* cfg) {
|
||||
bool DefaultTemporalLayers::ConfigureBitrates(int bitrateKbit,
|
||||
int framerate,
|
||||
vpx_codec_enc_cfg_t* cfg) {
|
||||
switch (number_of_temporal_layers_) {
|
||||
case 0:
|
||||
case 1:
|
||||
@ -156,7 +158,7 @@ bool TemporalLayers::ConfigureBitrates(int bitrateKbit,
|
||||
return true;
|
||||
}
|
||||
|
||||
int TemporalLayers::EncodeFlags() {
|
||||
int DefaultTemporalLayers::EncodeFlags(uint32_t timestamp) {
|
||||
assert(number_of_temporal_layers_ > 0);
|
||||
assert(kMaxTemporalPattern >= temporal_pattern_length_);
|
||||
assert(0 < temporal_pattern_length_);
|
||||
@ -228,9 +230,10 @@ int TemporalLayers::EncodeFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
void TemporalLayers::PopulateCodecSpecific(bool base_layer_sync,
|
||||
CodecSpecificInfoVP8 *vp8_info,
|
||||
uint32_t timestamp) {
|
||||
void DefaultTemporalLayers::PopulateCodecSpecific(
|
||||
bool base_layer_sync,
|
||||
CodecSpecificInfoVP8 *vp8_info,
|
||||
uint32_t timestamp) {
|
||||
assert(number_of_temporal_layers_ > 0);
|
||||
assert(0 < temporal_ids_length_);
|
||||
|
||||
@ -0,0 +1,87 @@
|
||||
/* 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.
|
||||
*/
|
||||
/*
|
||||
* This file defines classes for doing temporal layers with VP8.
|
||||
*/
|
||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_DEFAULT_TEMPORAL_LAYERS_H_
|
||||
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_DEFAULT_TEMPORAL_LAYERS_H_
|
||||
|
||||
#include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class DefaultTemporalLayers : public TemporalLayers {
|
||||
public:
|
||||
DefaultTemporalLayers(int number_of_temporal_layers,
|
||||
uint8_t initial_tl0_pic_idx);
|
||||
virtual ~DefaultTemporalLayers() {}
|
||||
|
||||
// Returns the recommended VP8 encode flags needed. May refresh the decoder
|
||||
// and/or update the reference buffers.
|
||||
virtual int EncodeFlags(uint32_t timestamp);
|
||||
|
||||
virtual bool ConfigureBitrates(int bitrate_kbit,
|
||||
int framerate,
|
||||
vpx_codec_enc_cfg_t* cfg);
|
||||
|
||||
virtual void PopulateCodecSpecific(bool base_layer_sync,
|
||||
CodecSpecificInfoVP8* vp8_info,
|
||||
uint32_t timestamp);
|
||||
|
||||
virtual void FrameEncoded(unsigned int size, uint32_t timestamp) {}
|
||||
|
||||
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,
|
||||
// First enhancement layer with alt ref dependency.
|
||||
kTemporalUpdateGoldenRefAltRef = 10,
|
||||
// First enhancement layer with alt ref dependency.
|
||||
kTemporalUpdateGoldenWithoutDependencyRefAltRef = 9,
|
||||
// Base layer with alt ref dependency.
|
||||
kTemporalUpdateLastRefAltRef = 8,
|
||||
// Highest enhacement layer without dependency on golden with alt ref
|
||||
// dependency.
|
||||
kTemporalUpdateNoneNoRefGoldenRefAltRef = 7,
|
||||
// Second layer and last frame in cycle, for 2 layers.
|
||||
kTemporalUpdateNoneNoRefAltref = 6,
|
||||
// Highest enhancement layer.
|
||||
kTemporalUpdateNone = 5,
|
||||
// Second enhancement layer.
|
||||
kTemporalUpdateAltref = 4,
|
||||
// Second enhancement layer without dependency on previous frames in
|
||||
// the second enhancement layer.
|
||||
kTemporalUpdateAltrefWithoutDependency = 3,
|
||||
// First enhancement layer.
|
||||
kTemporalUpdateGolden = 2,
|
||||
// First enhancement layer without dependency on previous frames in
|
||||
// the first enhancement layer.
|
||||
kTemporalUpdateGoldenWithoutDependency = 1,
|
||||
// Base layer.
|
||||
kTemporalUpdateLast = 0,
|
||||
};
|
||||
enum { kMaxTemporalPattern = 16 };
|
||||
|
||||
int number_of_temporal_layers_;
|
||||
int temporal_ids_length_;
|
||||
int temporal_ids_[kMaxTemporalPattern];
|
||||
int temporal_pattern_length_;
|
||||
TemporalReferences temporal_pattern_[kMaxTemporalPattern];
|
||||
uint8_t tl0_pic_idx_;
|
||||
uint8_t pattern_idx_;
|
||||
uint32_t timestamp_;
|
||||
bool last_base_layer_sync_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_DEFAULT_TEMPORAL_LAYERS_H_
|
||||
@ -10,8 +10,8 @@
|
||||
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "temporal_layers.h"
|
||||
#include "video_codec_interface.h"
|
||||
#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
|
||||
#include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h"
|
||||
|
||||
#include "vpx/vpx_encoder.h"
|
||||
#include "vpx/vp8cx.h"
|
||||
@ -63,10 +63,10 @@ enum {
|
||||
};
|
||||
|
||||
TEST(TemporalLayersTest, 2Layers) {
|
||||
TemporalLayers tl(2);
|
||||
DefaultTemporalLayers tl(2, 0);
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
CodecSpecificInfoVP8 vp8_info;
|
||||
tl.ConfigureBitrates(500, &cfg);
|
||||
tl.ConfigureBitrates(500, 30, &cfg);
|
||||
|
||||
int expected_flags[16] = { kTemporalUpdateLastAndGoldenRefAltRef,
|
||||
kTemporalUpdateGoldenWithoutDependencyRefAltRef,
|
||||
@ -92,19 +92,21 @@ TEST(TemporalLayersTest, 2Layers) {
|
||||
{ false, true, false, false, false, false, false, false,
|
||||
false, true, false, false, false, false, false, false };
|
||||
|
||||
uint32_t timestamp = 0;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
EXPECT_EQ(expected_flags[i], tl.EncodeFlags());
|
||||
EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
|
||||
tl.PopulateCodecSpecific(false, &vp8_info, 0);
|
||||
EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
|
||||
EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
|
||||
timestamp += 3000;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TemporalLayersTest, 3Layers) {
|
||||
TemporalLayers tl(3);
|
||||
DefaultTemporalLayers tl(3, 0);
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
CodecSpecificInfoVP8 vp8_info;
|
||||
tl.ConfigureBitrates(500, &cfg);
|
||||
tl.ConfigureBitrates(500, 30, &cfg);
|
||||
|
||||
int expected_flags[16] = { kTemporalUpdateLastAndGoldenRefAltRef,
|
||||
kTemporalUpdateNoneNoRefGolden,
|
||||
@ -130,19 +132,21 @@ TEST(TemporalLayersTest, 3Layers) {
|
||||
{ false, true, true, false, false, false, false, false,
|
||||
false, true, true, false, false, false, false, false };
|
||||
|
||||
unsigned int timestamp = 0;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
EXPECT_EQ(expected_flags[i], tl.EncodeFlags());
|
||||
EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
|
||||
tl.PopulateCodecSpecific(false, &vp8_info, 0);
|
||||
EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
|
||||
EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
|
||||
timestamp += 3000;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TemporalLayersTest, 4Layers) {
|
||||
TemporalLayers tl(4);
|
||||
DefaultTemporalLayers tl(4, 0);
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
CodecSpecificInfoVP8 vp8_info;
|
||||
tl.ConfigureBitrates(500, &cfg);
|
||||
tl.ConfigureBitrates(500, 30, &cfg);
|
||||
int expected_flags[16] = {
|
||||
kTemporalUpdateLast,
|
||||
kTemporalUpdateNone,
|
||||
@ -168,19 +172,21 @@ TEST(TemporalLayersTest, 4Layers) {
|
||||
{ false, true, true, true, true, true, false, true,
|
||||
false, true, false, true, false, true, false, true };
|
||||
|
||||
uint32_t timestamp = 0;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
EXPECT_EQ(expected_flags[i], tl.EncodeFlags());
|
||||
EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
|
||||
tl.PopulateCodecSpecific(false, &vp8_info, 0);
|
||||
EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
|
||||
EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
|
||||
timestamp += 3000;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TemporalLayersTest, KeyFrame) {
|
||||
TemporalLayers tl(3);
|
||||
DefaultTemporalLayers tl(3, 0);
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
CodecSpecificInfoVP8 vp8_info;
|
||||
tl.ConfigureBitrates(500, &cfg);
|
||||
tl.ConfigureBitrates(500, 30, &cfg);
|
||||
|
||||
int expected_flags[8] = {
|
||||
kTemporalUpdateLastAndGoldenRefAltRef,
|
||||
@ -195,13 +201,15 @@ TEST(TemporalLayersTest, KeyFrame) {
|
||||
int expected_temporal_idx[8] =
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 2};
|
||||
|
||||
uint32_t timestamp = 0;
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
EXPECT_EQ(expected_flags[i], tl.EncodeFlags());
|
||||
EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
|
||||
tl.PopulateCodecSpecific(true, &vp8_info, 0);
|
||||
EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
|
||||
EXPECT_EQ(true, vp8_info.layerSync);
|
||||
timestamp += 3000;
|
||||
}
|
||||
EXPECT_EQ(expected_flags[7], tl.EncodeFlags());
|
||||
EXPECT_EQ(expected_flags[7], tl.EncodeFlags(timestamp));
|
||||
tl.PopulateCodecSpecific(false, &vp8_info, 0);
|
||||
EXPECT_EQ(expected_temporal_idx[7], vp8_info.temporalIdx);
|
||||
EXPECT_EQ(true, vp8_info.layerSync);
|
||||
@ -7,14 +7,15 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
/*
|
||||
* This file defines classes for doing temporal layers with VP8.
|
||||
* This file defines the interface for doing temporal layers with VP8.
|
||||
*/
|
||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_
|
||||
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_
|
||||
|
||||
#include <typedefs.h>
|
||||
#include "webrtc/common_video/interface/video_image.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
// VPX forward declaration
|
||||
// libvpx forward declaration.
|
||||
typedef struct vpx_codec_enc_cfg vpx_codec_enc_cfg_t;
|
||||
|
||||
namespace webrtc {
|
||||
@ -23,64 +24,23 @@ struct CodecSpecificInfoVP8;
|
||||
|
||||
class TemporalLayers {
|
||||
public:
|
||||
TemporalLayers(int number_of_temporal_layers);
|
||||
virtual ~TemporalLayers() {}
|
||||
|
||||
// Returns the recommended VP8 encode flags needed. May refresh the decoder
|
||||
// and/or update the reference buffers.
|
||||
int EncodeFlags();
|
||||
virtual int EncodeFlags(uint32_t timestamp) = 0;
|
||||
|
||||
bool ConfigureBitrates(int bitrate_kbit, vpx_codec_enc_cfg_t* cfg);
|
||||
virtual bool ConfigureBitrates(int bitrate_kbit,
|
||||
int framerate,
|
||||
vpx_codec_enc_cfg_t* cfg) = 0;
|
||||
|
||||
void PopulateCodecSpecific(bool base_layer_sync,
|
||||
CodecSpecificInfoVP8* vp8_info,
|
||||
uint32_t timestamp);
|
||||
virtual void PopulateCodecSpecific(bool base_layer_sync,
|
||||
CodecSpecificInfoVP8* vp8_info,
|
||||
uint32_t timestamp) = 0;
|
||||
|
||||
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,
|
||||
// First enhancement layer with alt ref dependency.
|
||||
kTemporalUpdateGoldenRefAltRef = 10,
|
||||
// First enhancement layer with alt ref dependency.
|
||||
kTemporalUpdateGoldenWithoutDependencyRefAltRef = 9,
|
||||
// Base layer with alt ref dependency.
|
||||
kTemporalUpdateLastRefAltRef = 8,
|
||||
// Highest enhacement layer without dependency on golden with alt ref
|
||||
// dependency.
|
||||
kTemporalUpdateNoneNoRefGoldenRefAltRef = 7,
|
||||
// Second layer and last frame in cycle, for 2 layers.
|
||||
kTemporalUpdateNoneNoRefAltref = 6,
|
||||
// Highest enhancement layer.
|
||||
kTemporalUpdateNone = 5,
|
||||
// Second enhancement layer.
|
||||
kTemporalUpdateAltref = 4,
|
||||
// Second enhancement layer without dependency on previous frames in
|
||||
// the second enhancement layer.
|
||||
kTemporalUpdateAltrefWithoutDependency = 3,
|
||||
// First enhancement layer.
|
||||
kTemporalUpdateGolden = 2,
|
||||
// First enhancement layer without dependency on previous frames in
|
||||
// the first enhancement layer.
|
||||
kTemporalUpdateGoldenWithoutDependency = 1,
|
||||
// Base layer.
|
||||
kTemporalUpdateLast = 0,
|
||||
};
|
||||
enum { kMaxTemporalPattern = 16 };
|
||||
|
||||
int number_of_temporal_layers_;
|
||||
int temporal_ids_length_;
|
||||
int temporal_ids_[kMaxTemporalPattern];
|
||||
int temporal_pattern_length_;
|
||||
TemporalReferences temporal_pattern_[kMaxTemporalPattern];
|
||||
uint8_t tl0_pic_idx_;
|
||||
uint8_t pattern_idx_;
|
||||
uint32_t timestamp_;
|
||||
bool last_base_layer_sync_;
|
||||
virtual void FrameEncoded(unsigned int size, uint32_t timestamp) = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_
|
||||
|
||||
|
||||
@ -25,8 +25,9 @@
|
||||
'target_name': 'webrtc_vp8',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
|
||||
'<(webrtc_root)/common_video/common_video.gyp:common_video',
|
||||
'<(webrtc_root)/modules/video_coding/utility/video_coding_utility.gyp:video_coding_utility',
|
||||
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
|
||||
],
|
||||
'include_dirs': [
|
||||
'include',
|
||||
@ -54,8 +55,9 @@
|
||||
}],
|
||||
['use_temporal_layers==1', {
|
||||
'sources': [
|
||||
'default_temporal_layers.cc',
|
||||
'default_temporal_layers.h',
|
||||
'temporal_layers.h',
|
||||
'temporal_layers.cc',
|
||||
],
|
||||
}],
|
||||
],
|
||||
@ -113,8 +115,8 @@
|
||||
'<(DEPTH)/third_party/libvpx/source/libvpx',
|
||||
],
|
||||
'sources': [
|
||||
'default_temporal_layers_unittest.cc',
|
||||
'reference_picture_selection_unittest.cc',
|
||||
'temporal_layers_unittest.cc',
|
||||
],
|
||||
'conditions': [
|
||||
['build_libvpx==1', {
|
||||
|
||||
@ -25,8 +25,8 @@
|
||||
|
||||
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
||||
#include "webrtc/modules/interface/module_common_types.h"
|
||||
#include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h"
|
||||
#include "webrtc/modules/video_coding/codecs/vp8/reference_picture_selection.h"
|
||||
#include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
|
||||
#include "webrtc/system_wrappers/interface/tick_util.h"
|
||||
#include "webrtc/system_wrappers/interface/trace_event.h"
|
||||
|
||||
@ -113,7 +113,7 @@ int VP8EncoderImpl::SetRates(uint32_t new_bitrate_kbit,
|
||||
config_->rc_target_bitrate = new_bitrate_kbit; // in kbit/s
|
||||
|
||||
#if WEBRTC_LIBVPX_VERSION >= 971
|
||||
temporal_layers_->ConfigureBitrates(new_bitrate_kbit, config_);
|
||||
temporal_layers_->ConfigureBitrates(new_bitrate_kbit, new_framerate, config_);
|
||||
#endif
|
||||
codec_.maxFramerate = new_framerate;
|
||||
|
||||
@ -163,7 +163,7 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
|
||||
int num_temporal_layers = inst->codecSpecific.VP8.numberOfTemporalLayers > 1 ?
|
||||
inst->codecSpecific.VP8.numberOfTemporalLayers : 1;
|
||||
assert(temporal_layers_ == NULL);
|
||||
temporal_layers_ = new TemporalLayers(num_temporal_layers);
|
||||
temporal_layers_ = new DefaultTemporalLayers(num_temporal_layers, rand());
|
||||
#endif
|
||||
// random start 16 bits is enough.
|
||||
picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF;
|
||||
@ -190,7 +190,8 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
|
||||
config_->rc_target_bitrate = inst->startBitrate; // in kbit/s
|
||||
|
||||
#if WEBRTC_LIBVPX_VERSION >= 971
|
||||
temporal_layers_->ConfigureBitrates(inst->startBitrate, config_);
|
||||
temporal_layers_->ConfigureBitrates(inst->startBitrate, inst->maxFramerate,
|
||||
config_);
|
||||
#endif
|
||||
// setting the time base of the codec
|
||||
config_->g_timebase.num = 1;
|
||||
@ -365,7 +366,7 @@ int VP8EncoderImpl::Encode(const I420VideoFrame& input_image,
|
||||
|
||||
int flags = 0;
|
||||
#if WEBRTC_LIBVPX_VERSION >= 971
|
||||
flags |= temporal_layers_->EncodeFlags();
|
||||
flags |= temporal_layers_->EncodeFlags(input_image.timestamp());
|
||||
#endif
|
||||
bool send_keyframe = (frame_type == kKeyFrame);
|
||||
if (send_keyframe) {
|
||||
|
||||
Reference in New Issue
Block a user