blob: 5a89590c0eab0178724e387832ad579ce09558bc [file] [log] [blame]
Niels Möllerf9063782018-02-20 16:09:48 +01001/*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "modules/video_coding/encoder_database.h"
12
13#include "rtc_base/checks.h"
14#include "rtc_base/logging.h"
15
16namespace webrtc {
17
18namespace {
19const size_t kDefaultPayloadSize = 1440;
20}
21
22VCMEncoderDataBase::VCMEncoderDataBase(
23 VCMEncodedFrameCallback* encoded_frame_callback)
24 : number_of_cores_(0),
25 max_payload_size_(kDefaultPayloadSize),
Niels Möllerf9063782018-02-20 16:09:48 +010026 pending_encoder_reset_(true),
27 send_codec_(),
Niels Möllerf9063782018-02-20 16:09:48 +010028 external_encoder_(nullptr),
29 internal_source_(false),
30 encoded_frame_callback_(encoded_frame_callback) {}
31
32VCMEncoderDataBase::~VCMEncoderDataBase() {
33 DeleteEncoder();
34}
35
36// Assuming only one registered encoder - since only one used, no need for more.
37bool VCMEncoderDataBase::SetSendCodec(const VideoCodec* send_codec,
38 int number_of_cores,
39 size_t max_payload_size) {
40 RTC_DCHECK(send_codec);
41 if (max_payload_size == 0) {
42 max_payload_size = kDefaultPayloadSize;
43 }
44 RTC_DCHECK_GE(number_of_cores, 1);
Niels Möllerf9063782018-02-20 16:09:48 +010045 // Make sure the start bit rate is sane...
46 RTC_DCHECK_LE(send_codec->startBitrate, 1000000);
Niels Möllerf9063782018-02-20 16:09:48 +010047 bool reset_required = pending_encoder_reset_;
48 if (number_of_cores_ != number_of_cores) {
49 number_of_cores_ = number_of_cores;
50 reset_required = true;
51 }
52 if (max_payload_size_ != max_payload_size) {
53 max_payload_size_ = max_payload_size;
54 reset_required = true;
55 }
56
57 VideoCodec new_send_codec;
58 memcpy(&new_send_codec, send_codec, sizeof(new_send_codec));
59
60 if (new_send_codec.maxBitrate == 0) {
61 // max is one bit per pixel
62 new_send_codec.maxBitrate = (static_cast<int>(send_codec->height) *
63 static_cast<int>(send_codec->width) *
64 static_cast<int>(send_codec->maxFramerate)) /
65 1000;
66 if (send_codec->startBitrate > new_send_codec.maxBitrate) {
67 // But if the user tries to set a higher start bit rate we will
68 // increase the max accordingly.
69 new_send_codec.maxBitrate = send_codec->startBitrate;
70 }
71 }
72
73 if (new_send_codec.startBitrate > new_send_codec.maxBitrate)
74 new_send_codec.startBitrate = new_send_codec.maxBitrate;
75
76 if (!reset_required) {
77 reset_required = RequiresEncoderReset(new_send_codec);
78 }
79
80 memcpy(&send_codec_, &new_send_codec, sizeof(send_codec_));
81
82 if (!reset_required) {
83 return true;
84 }
85
86 // If encoder exists, will destroy it and create new one.
87 DeleteEncoder();
Niels Möllerf9063782018-02-20 16:09:48 +010088 ptr_encoder_.reset(new VCMGenericEncoder(
89 external_encoder_, encoded_frame_callback_, internal_source_));
90 encoded_frame_callback_->SetInternalSource(internal_source_);
91 if (ptr_encoder_->InitEncode(&send_codec_, number_of_cores_,
92 max_payload_size_) < 0) {
93 RTC_LOG(LS_ERROR) << "Failed to initialize video encoder.";
94 DeleteEncoder();
95 return false;
96 }
97
Niels Möllerf9063782018-02-20 16:09:48 +010098 pending_encoder_reset_ = false;
99
100 return true;
101}
102
Niels Möllerbf3dbb42018-03-16 13:38:46 +0100103void VCMEncoderDataBase::DeregisterExternalEncoder() {
104 DeleteEncoder();
105 memset(&send_codec_, 0, sizeof(VideoCodec));
Niels Möllerf9063782018-02-20 16:09:48 +0100106 external_encoder_ = nullptr;
107 internal_source_ = false;
Niels Möllerf9063782018-02-20 16:09:48 +0100108}
109
110void VCMEncoderDataBase::RegisterExternalEncoder(VideoEncoder* external_encoder,
Niels Möllerf9063782018-02-20 16:09:48 +0100111 bool internal_source) {
112 // Since only one encoder can be used at a given time, only one external
113 // encoder can be registered/used.
Niels Möllerbf3dbb42018-03-16 13:38:46 +0100114 RTC_CHECK(external_encoder_ == nullptr);
Niels Möllerf9063782018-02-20 16:09:48 +0100115 external_encoder_ = external_encoder;
Niels Möllerf9063782018-02-20 16:09:48 +0100116 internal_source_ = internal_source;
117 pending_encoder_reset_ = true;
118}
119
120bool VCMEncoderDataBase::RequiresEncoderReset(
121 const VideoCodec& new_send_codec) {
122 if (!ptr_encoder_)
123 return true;
124
Niels Möllerbf3dbb42018-03-16 13:38:46 +0100125 // Does not check startBitrate, maxFramerate or plType
Niels Möllerf9063782018-02-20 16:09:48 +0100126 if (new_send_codec.codecType != send_codec_.codecType ||
Niels Möllerf9063782018-02-20 16:09:48 +0100127 new_send_codec.width != send_codec_.width ||
128 new_send_codec.height != send_codec_.height ||
129 new_send_codec.maxBitrate != send_codec_.maxBitrate ||
130 new_send_codec.minBitrate != send_codec_.minBitrate ||
131 new_send_codec.qpMax != send_codec_.qpMax ||
132 new_send_codec.numberOfSimulcastStreams !=
133 send_codec_.numberOfSimulcastStreams ||
134 new_send_codec.mode != send_codec_.mode) {
135 return true;
136 }
137
138 switch (new_send_codec.codecType) {
139 case kVideoCodecVP8:
Niels Möllerdef1ef52018-03-19 13:48:44 +0100140 if (new_send_codec.VP8() != *send_codec_.VP8()) {
Niels Möllerf9063782018-02-20 16:09:48 +0100141 return true;
142 }
143 break;
Niels Möllerdef1ef52018-03-19 13:48:44 +0100144
Niels Möllerf9063782018-02-20 16:09:48 +0100145 case kVideoCodecVP9:
Niels Möllerdef1ef52018-03-19 13:48:44 +0100146 if (new_send_codec.VP9() != *send_codec_.VP9()) {
Niels Möllerf9063782018-02-20 16:09:48 +0100147 return true;
148 }
149 break;
Niels Möllerdef1ef52018-03-19 13:48:44 +0100150
Niels Möllerf9063782018-02-20 16:09:48 +0100151 case kVideoCodecH264:
Niels Möllerdef1ef52018-03-19 13:48:44 +0100152 if (new_send_codec.H264() != *send_codec_.H264()) {
Niels Möllerf9063782018-02-20 16:09:48 +0100153 return true;
154 }
155 break;
Niels Möllerdef1ef52018-03-19 13:48:44 +0100156
Kári Tristan Helgason84ccb2d2018-08-16 14:35:26 +0200157 default:
Niels Möllerf9063782018-02-20 16:09:48 +0100158 break;
Niels Möllerf9063782018-02-20 16:09:48 +0100159 }
160
Niels Möllerdef1ef52018-03-19 13:48:44 +0100161 for (unsigned char i = 0; i < new_send_codec.numberOfSimulcastStreams; ++i) {
162 if (new_send_codec.simulcastStream[i] != send_codec_.simulcastStream[i])
163 return true;
Niels Möllerf9063782018-02-20 16:09:48 +0100164 }
165 return false;
166}
167
168VCMGenericEncoder* VCMEncoderDataBase::GetEncoder() {
169 return ptr_encoder_.get();
170}
171
Niels Möllerf9063782018-02-20 16:09:48 +0100172void VCMEncoderDataBase::DeleteEncoder() {
173 if (!ptr_encoder_)
174 return;
175 ptr_encoder_->Release();
176 ptr_encoder_.reset();
177}
178
179bool VCMEncoderDataBase::MatchesCurrentResolution(int width, int height) const {
180 return send_codec_.width == width && send_codec_.height == height;
181}
182
183} // namespace webrtc