video_stream_encoder.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. #include "video_stream_encoder.h"
  2. #include <algorithm>
  3. #include <limits>
  4. #include <numeric>
  5. #include <utility>
  6. #include "video_encoder.h"
  7. #include "stdint.h"
  8. #include "base/rate_statistics.h"
  9. #include "base/video_coding_clock.h"
  10. #include "base/video_coding_type_defines.h"
  11. #include "base/video_coding_log.h"
  12. #include "base/video_frame_type.h"
  13. #include "../video_statics/video_stats.h"
  14. namespace video_coding {
  15. // Time interval for logging frame counts.
  16. static const int64_t kFrameLogIntervalMs = 60000;
  17. static const int kMinFramerateFps = 2;
  18. // Averaging window spanning 90 frames at default 30fps, matching old media
  19. // optimization module defaults.
  20. static const int64_t kFrameRateAvergingWindowSizeMs = (1000 / 30) * 90;
  21. static const size_t kDefaultPayloadSize = 1440;
  22. static const size_t kDefaultProcessIntervalMs = 1000;
  23. bool RequiresEncoderReset(const VideoEncoderConfig *previous_send_codec,
  24. const VideoEncoderConfig *new_send_codec) {
  25. // Does not check startBitrate or maxFramerate.
  26. if (new_send_codec->encode_id != previous_send_codec->encode_id ||
  27. new_send_codec->width != previous_send_codec->width ||
  28. new_send_codec->height != previous_send_codec->height ||
  29. new_send_codec->max_bitrate != previous_send_codec->max_bitrate ||
  30. new_send_codec->min_bitrate != previous_send_codec->min_bitrate ||
  31. new_send_codec->max_qp != previous_send_codec->max_qp) {
  32. return true;
  33. }
  34. return false;
  35. }
  36. typedef struct _VideoFrameInfo {
  37. int width;
  38. int height;
  39. }VideoFrameInfo;
  40. int video_frame_info_pixel_count(VideoFrameInfo * obj) {
  41. return obj->width * obj->height;
  42. }
  43. typedef struct _EncoderRateSettings {
  44. // Target bitrate, per spatial/temporal layer.
  45. // A target bitrate of 0bps indicates a layer should not be encoded at all.
  46. //单位:bps
  47. int bitrate;
  48. // Target framerate, in fps. A value <= 0.0 is invalid and should be
  49. // interpreted as framerate target not available. In this case the encoder
  50. // should fall back to the max framerate specified in |codec_settings| of
  51. // the last InitEncode() call.
  52. double framerate_fps;
  53. }EncoderRateSettings;
  54. // Used to signal the encoder about reason a frame is dropped.
  55. // kDroppedByMediaOptimizations - dropped by MediaOptimizations (for rate
  56. // limiting purposes).
  57. // kDroppedByEncoder - dropped by encoder's internal rate limiter.
  58. enum DropReason {
  59. kDroppedByMediaOptimizations,
  60. kDroppedByEncoder
  61. };
  62. typedef struct _VideoStreamEncoder {
  63. //func object
  64. FrameDropper *frame_dropper_;
  65. VideoEncoder *encoder_;
  66. RateStatistics *input_framerate_;
  67. //输入根据分配fps丢帧累计值
  68. int64_t input_accumulator_;
  69. int64_t last_input_frame_ms_;
  70. //config
  71. VideoEncoderObserver encoder_stats_observer_;
  72. //其中target bitrate为encoder初始化设置带宽
  73. VideoEncoderConfig encoder_config_;
  74. //带宽探测,动态设置编码带宽
  75. EncoderRateSettings last_encoder_rate_settings_;
  76. EncoderRateSettings allocation_encoder_rate_settings_;
  77. int continue_bitrate_inc_count;
  78. int continue_bitrate_dec_count;
  79. VideoFrameInfo last_frame_info_;
  80. int64_t last_parameters_update_ms_;
  81. int64_t last_encode_info_ms_;
  82. size_t max_data_payload_length_;
  83. bool encoder_initialized_;
  84. // Set when configuration must create a new encoder object, e.g.,
  85. // because of a codec change.
  86. bool pending_encoder_creation_;
  87. int64_t last_frame_log_ms_;
  88. int captured_frame_count_;
  89. // TODO(sprang): Change actually support keyframe per simulcast stream, or
  90. // turn this into a simple bool |pending_keyframe_request_|.
  91. VideoFrameType next_frame_type_;
  92. }VideoStreamEncoder;
  93. VideoStreamEncoder *video_stream_encoder_new(
  94. VideoEncoderObserver* encoder_stats_observer)
  95. {
  96. video_coding_debug(VIDEO_CODING_DEBUG_ENABLE, "video_stream_encoder_new.");
  97. VideoStreamEncoder *obj = (VideoStreamEncoder *)malloc(sizeof(VideoStreamEncoder));
  98. memset(obj, 0, sizeof(VideoStreamEncoder));
  99. if (encoder_stats_observer != NULL) {
  100. memcpy(&obj->encoder_stats_observer_, encoder_stats_observer, sizeof(VideoEncoderObserver));
  101. }
  102. obj->encoder_initialized_ = false;
  103. obj->max_data_payload_length_ = 0;
  104. obj->last_frame_log_ms_ = TimeInMilliseconds();
  105. obj->captured_frame_count_ = 0;
  106. obj->input_framerate_ = rate_statistics_new(kFrameRateAvergingWindowSizeMs, 1000);
  107. obj->next_frame_type_ = kVideoFrameDelta;
  108. //reset value
  109. obj->last_encoder_rate_settings_.bitrate = -1;
  110. obj->last_encoder_rate_settings_.framerate_fps = -1;
  111. obj->allocation_encoder_rate_settings_.bitrate = -1;
  112. obj->allocation_encoder_rate_settings_.framerate_fps = -1;
  113. obj->frame_dropper_ = frame_dropper_new();
  114. return obj;
  115. }
  116. void video_stream_encoder_destroy(VideoStreamEncoder *obj) {
  117. if (obj != NULL) {
  118. frame_dropper_destroy(obj->frame_dropper_);
  119. obj->frame_dropper_ = NULL;
  120. rate_statistics_destroy(obj->input_framerate_);
  121. obj->input_framerate_ = NULL;
  122. video_encoder_destroy(obj->encoder_);
  123. obj->encoder_ = NULL;
  124. free(obj);
  125. video_coding_debug(VIDEO_CODING_DEBUG_ENABLE, "video_stream_encoder_destroy.");
  126. }
  127. }
  128. void video_stream_encoder_release_encoder(VideoStreamEncoder *obj) {
  129. if ((obj->encoder_ == NULL) || !obj->encoder_initialized_) {
  130. return;
  131. }
  132. video_encoder_destroy(obj->encoder_);
  133. obj->encoder_ = NULL;
  134. obj->encoder_initialized_ = false;
  135. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER, "video_stream_encoder_release_encoder.");
  136. }
  137. void video_stream_encoder_stop(VideoStreamEncoder *obj) {
  138. video_stream_encoder_release_encoder(obj);
  139. //reset value
  140. obj->last_encoder_rate_settings_.bitrate = -1;
  141. obj->last_encoder_rate_settings_.framerate_fps = -1;
  142. obj->allocation_encoder_rate_settings_.bitrate = -1;
  143. obj->allocation_encoder_rate_settings_.framerate_fps = -1;
  144. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER, "video_stream_encoder_stop.");
  145. }
  146. static uint32_t video_stream_encoder_get_input_framerate_fps(VideoStreamEncoder *obj) {
  147. const uint32_t default_fps = 30;
  148. uint32_t input_fps = rate_statistics_rate(obj->input_framerate_, TimeInMilliseconds());
  149. if (input_fps == absl_nullopt_uint32) {
  150. return default_fps;
  151. }
  152. return input_fps;
  153. }
  154. void video_stream_encoder_set_encoder_rates(VideoStreamEncoder *obj,
  155. const EncoderRateSettings *rate_settings) {
  156. const bool settings_changes = ((obj->last_encoder_rate_settings_.bitrate == -1) ||
  157. (obj->last_encoder_rate_settings_.framerate_fps == -1) ||
  158. (rate_settings->bitrate != obj->last_encoder_rate_settings_.bitrate) ||
  159. (rate_settings->framerate_fps != obj->last_encoder_rate_settings_.framerate_fps));
  160. if (settings_changes) {
  161. memcpy(&obj->last_encoder_rate_settings_, rate_settings, sizeof(EncoderRateSettings));
  162. }
  163. if (!obj->encoder_) {
  164. return;
  165. }
  166. // |bitrate_allocation| is 0 it means that the network is down or the send
  167. // pacer is full. We currently only report this if the encoder has an internal
  168. // source. If the encoder does not have an internal source, higher levels
  169. // are expected to not call AddVideoFrame. We do this since its unclear
  170. // how current encoder implementations behave when given a zero target
  171. // bitrate.
  172. // TODO(perkj): Make sure all known encoder implementations handle zero
  173. // target bitrate and remove this check.
  174. if (rate_settings->bitrate == 0) {
  175. return;
  176. }
  177. if (settings_changes) {
  178. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER, "video_stream_encoder_set_encoder_rates, new encoder setting bitrate: %d, framerate_fps: %lf.",
  179. rate_settings->bitrate, rate_settings->framerate_fps);
  180. video_stats_sender_on_encoder_rate_changed((int)rate_settings->framerate_fps, rate_settings->bitrate);
  181. video_encoder_set_rates(obj->encoder_, rate_settings->bitrate / 1000, rate_settings->framerate_fps);
  182. }
  183. }
  184. // TODO(bugs.webrtc.org/8807): Currently this always does a hard
  185. // reconfiguration, but this isn't always necessary. Add in logic to only update
  186. // the VideoBitrateAllocator and call OnEncoderConfigurationChanged with a
  187. // "soft" reconfiguration.
  188. static void video_stream_encoder_reconfigure_encoder(VideoStreamEncoder *obj) {
  189. // Keep the same encoder, as long as the video_format is unchanged.
  190. // Encoder creation block is split in two since EncoderInfo needed to start
  191. // CPU adaptation with the correct settings should be polled after
  192. // encoder_->InitEncode().
  193. bool success = true;
  194. if (obj->pending_encoder_creation_) {
  195. video_stream_encoder_release_encoder(obj);
  196. obj->encoder_ = video_encoder_new();
  197. if (video_encoder_init_encode(obj->encoder_, &obj->encoder_config_, obj->max_data_payload_length_ > 0
  198. ? obj->max_data_payload_length_
  199. : kDefaultPayloadSize) != 0) {
  200. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  201. "video_stream_encoder_reconfigure_encoder Failed to initialize the encoder associated with codec type: %d",
  202. obj->encoder_config_.encode_id);
  203. video_stream_encoder_release_encoder(obj);
  204. success = false;
  205. }
  206. else {
  207. obj->encoder_initialized_ = true;
  208. }
  209. obj->last_encode_info_ms_ = absl_nullopt_int64;
  210. }
  211. if (success) {
  212. obj->next_frame_type_ = kVideoFrameKey;
  213. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  214. "video_stream_encoder_reconfigure_encoder max bitrate: %ukbps start bitrate: %ukbps max frame rate: %u max payload size: %d",
  215. obj->encoder_config_.max_bitrate, obj->encoder_config_.target_bitrate,
  216. obj->encoder_config_.max_framerate, obj->max_data_payload_length_);
  217. }
  218. else {
  219. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER, "video_stream_encoder_reconfigure_encoder Failed to configure encoder.");
  220. }
  221. if (obj->pending_encoder_creation_) {
  222. obj->pending_encoder_creation_ = false;
  223. }
  224. frame_dropper_reset(obj->frame_dropper_);
  225. frame_dropper_set_rates(obj->frame_dropper_, obj->encoder_config_.target_bitrate, obj->encoder_config_.max_framerate);
  226. // Get the current target framerate, ie the maximum framerate as specified by
  227. // the current codec configuration, or any limit imposed by cpu adaption in
  228. // maintain-resolution or balanced mode. This is used to make sure overuse
  229. // detection doesn't needlessly trigger in low and/or variable framerate
  230. // scenarios.
  231. int target_framerate = std::min<int>(
  232. obj->encoder_config_.max_framerate, obj->last_encoder_rate_settings_.framerate_fps);
  233. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER, "video_stream_encoder_reconfigure_encoder target_framerate: %d.", target_framerate);
  234. }
  235. void video_stream_encoder_configure_encoder(VideoStreamEncoder *obj, VideoEncoderConfig *config,
  236. size_t max_data_payload_length) {
  237. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER, "video_stream_encoder_configure_encoder.");
  238. obj->pending_encoder_creation_ = !obj->encoder_ || RequiresEncoderReset(&obj->encoder_config_, config);
  239. memcpy(&obj->encoder_config_, config, sizeof(VideoEncoderConfig));
  240. obj->max_data_payload_length_ = max_data_payload_length;
  241. if (obj->pending_encoder_creation_) {
  242. video_stream_encoder_reconfigure_encoder(obj);
  243. }
  244. }
  245. void video_stream_encoder_on_dropped_frame(VideoStreamEncoder *obj, DropReason reason) {
  246. switch (reason) {
  247. case kDroppedByMediaOptimizations: {
  248. if (obj->encoder_stats_observer_.OnFrameDropped != NULL) {
  249. obj->encoder_stats_observer_.OnFrameDropped(kMediaOptimization, obj->encoder_stats_observer_.userdata);
  250. }
  251. break;
  252. }
  253. case kDroppedByEncoder: {
  254. if (obj->encoder_stats_observer_.OnFrameDropped != NULL) {
  255. obj->encoder_stats_observer_.OnFrameDropped(kEncoder, obj->encoder_stats_observer_.userdata);
  256. }
  257. break;
  258. }
  259. }
  260. }
  261. void video_stream_encoder_on_discarded_frame(VideoStreamEncoder *obj) {
  262. if (obj->encoder_stats_observer_.OnFrameDropped != NULL) {
  263. obj->encoder_stats_observer_.OnFrameDropped(kSource, obj->encoder_stats_observer_.userdata);
  264. }
  265. }
  266. void video_stream_encoder_run_post_encode(VideoStreamEncoder *obj, const EncodedImage *encoded_image,
  267. int64_t time_sent_us) {
  268. int encode_duration_us;
  269. encode_duration_us =
  270. // TODO(nisse): Maybe use capture_time_ms_ rather than encode_start_ms_?
  271. kNumMicrosecsPerMillisec *
  272. (encoded_image->encode_finish_ms -
  273. encoded_image->encode_start_ms);
  274. // Run post encode tasks, such as overuse detection and frame rate/drop
  275. // stats for internal encoders.
  276. const size_t frame_size = encoded_image->size_;
  277. const bool keyframe = encoded_image->key_frame;
  278. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  279. "video_stream_encoder_run_post_encode encode_duration_us: %d frame_size: %d keyframe: %d qp_: %d.",
  280. encode_duration_us, frame_size, keyframe, encoded_image->qp_);
  281. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  282. "video_stream_encoder_run_post_encode time_sent_us: %I64d.",
  283. time_sent_us);
  284. if (frame_size > 0) {
  285. frame_dropper_fill(obj->frame_dropper_, frame_size, !keyframe);
  286. }
  287. }
  288. static void video_stream_encoder_on_encoded_image(VideoStreamEncoder *obj,
  289. const EncodedImage *encoded_image) {
  290. //TRACE_EVENT_INSTANT1("webrtc", "VCMEncodedFrameCallback::Encoded",
  291. // "timestamp", encoded_image.Timestamp());
  292. // Encoded is called on whatever thread the real encoder implementation run
  293. // on. In the case of hardware encoders, there might be several encoders
  294. // running in parallel on different threads.
  295. if (obj->encoder_stats_observer_.OnEncodedImage != NULL) {
  296. obj->encoder_stats_observer_.OnEncodedImage(encoded_image, obj->encoder_stats_observer_.userdata);
  297. }
  298. video_stream_encoder_run_post_encode(obj, encoded_image, TimeInMicroseconds());
  299. }
  300. static void video_stream_encoder_encode_video_frame(VideoStreamEncoder *obj, unsigned pt, const video_frame *video_frame,
  301. int64_t time_when_posted_us) {
  302. //TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(),
  303. // "Encode");
  304. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  305. "video_stream_encoder_encode_video_frame time_when_posted_us: %I64d.",
  306. time_when_posted_us);
  307. obj->last_encode_info_ms_ = TimeInMilliseconds();
  308. if (!obj->encoder_initialized_) {
  309. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER, "video_stream_encoder_encode_video_frame encoder not initialized.");
  310. return;
  311. }
  312. EncodedImage *image = video_encoder_encode(obj->encoder_, pt, video_frame, obj->next_frame_type_ == kVideoFrameKey);
  313. if (image == NULL) {
  314. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER, "video_stream_encoder_encode_video_frame Failed to encode frame.");
  315. return;
  316. }
  317. video_stream_encoder_on_encoded_image(obj, image);
  318. obj->next_frame_type_ = kVideoFrameDelta;
  319. }
  320. /* 编码前,判断是否丢帧:一种是在输入丢帧,一种是frame_dropper判断要丢帧 */
  321. static void video_stream_encoder_maybe_encode_video_frame(VideoStreamEncoder *obj, unsigned pt, const video_frame *frame,
  322. int64_t time_when_posted_us) {
  323. int64_t now_ms = TimeInMilliseconds();
  324. //do source cap framerate drop
  325. int target_framerate = std::min<int>(
  326. obj->encoder_config_.max_framerate, obj->allocation_encoder_rate_settings_.framerate_fps);
  327. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  328. "video_stream_encoder_maybe_encode_video_frame, target_framerate: %d now_ms: %I64d.", target_framerate, now_ms);
  329. if (obj->last_input_frame_ms_ != 0 && target_framerate != -1) {
  330. int64_t avg_frame_ms = 1000 / target_framerate;
  331. int64_t elapse_ms = now_ms - obj->last_input_frame_ms_;
  332. obj->input_accumulator_ += avg_frame_ms - elapse_ms;
  333. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  334. "video_stream_encoder_maybe_encode_video_frame, avg_frame_ms: %I64d elapse_ms: %I64d input_accumulator: %I64d.", avg_frame_ms, elapse_ms, obj->input_accumulator_);
  335. if (obj->input_accumulator_ > avg_frame_ms) {
  336. video_stream_encoder_on_discarded_frame(obj);
  337. video_stats_sender_on_frame_dropped(1, 0);
  338. obj->input_accumulator_ -= avg_frame_ms;
  339. obj->last_input_frame_ms_ = now_ms;
  340. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  341. "video_stream_encoder_maybe_encode_video_frame, do source cap framerate drop with input_accumulator_: %I64d.",
  342. obj->input_accumulator_);
  343. return;
  344. }
  345. }
  346. obj->last_input_frame_ms_ = now_ms;
  347. if (frame->width != obj->last_frame_info_.width ||
  348. frame->height != obj->last_frame_info_.height) {
  349. obj->last_frame_info_.height = frame->height;
  350. obj->last_frame_info_.width = frame->width;
  351. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER, "video_stream_encoder_maybe_encode_video_frame Video frame parameters changed: dimensions= %d x %d.",
  352. obj->last_frame_info_.width, obj->last_frame_info_.height);
  353. }
  354. //updata encoder framerate with input
  355. // Update input frame rate before we start using it. If we update it after
  356. // any potential frame drop we are going to artificially increase frame sizes.
  357. // Poll the rate before updating, otherwise we risk the rate being estimated
  358. // a little too high at the start of the call when then window is small.
  359. uint32_t framerate_fps = video_stream_encoder_get_input_framerate_fps(obj);
  360. rate_statistics_update(obj->input_framerate_, 1u, TimeInMilliseconds());
  361. if (now_ms - obj->last_parameters_update_ms_ >= kDefaultProcessIntervalMs) {
  362. // Clone rate settings before update, so that SetEncoderRates() will
  363. // actually detect the change between the input and
  364. // |last_encoder_rate_setings_|, triggering the call to SetRate() on the
  365. // encoder.
  366. if ((obj->last_encoder_rate_settings_.bitrate != -1) && (obj->last_encoder_rate_settings_.framerate_fps != -1)) {
  367. EncoderRateSettings *new_rate_settings = &obj->last_encoder_rate_settings_;
  368. new_rate_settings->framerate_fps = static_cast<double>(framerate_fps);
  369. video_stream_encoder_set_encoder_rates(obj, new_rate_settings);
  370. }
  371. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  372. "video_stream_encoder_maybe_encode_video_frame, update framerate_setting:%u.", framerate_fps);
  373. obj->last_parameters_update_ms_ = now_ms;
  374. }
  375. //do MediaOptimization framerate drop
  376. frame_dropper_leak(obj->frame_dropper_, framerate_fps);
  377. // Frame dropping is enabled if frame dropping is not force-disabled, and
  378. // rate controller is not trusted.
  379. const bool frame_dropping_enabled = true;
  380. frame_dropper_enable(obj->frame_dropper_, frame_dropping_enabled);
  381. if (frame_dropping_enabled && frame_dropper_drop_frame(obj->frame_dropper_)) {
  382. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  383. "video_stream_encoder_maybe_encode_video_frame Drop Frame: target bitrate %d, input frame rate :%u.",
  384. obj->last_encoder_rate_settings_.bitrate, framerate_fps);
  385. video_stream_encoder_on_dropped_frame(obj, kDroppedByMediaOptimizations);
  386. video_stats_sender_on_frame_dropped(0, 1);
  387. return;
  388. }
  389. video_stream_encoder_encode_video_frame(obj, pt, frame, time_when_posted_us);
  390. }
  391. void video_stream_encoder_on_frame(VideoStreamEncoder *obj, unsigned pt, const video_frame *video_frame) {
  392. int64_t current_time_us = TimeInMicroseconds();
  393. int64_t current_time_ms = current_time_us / kNumMicrosecsPerMillisec;
  394. bool log_stats = false;
  395. if (current_time_ms - obj->last_frame_log_ms_ > kFrameLogIntervalMs) {
  396. obj->last_frame_log_ms_ = current_time_ms;
  397. log_stats = true;
  398. }
  399. int64_t post_time_us = TimeInMicroseconds();
  400. if (obj->encoder_stats_observer_.OnIncomingFrame != NULL) {
  401. obj->encoder_stats_observer_.OnIncomingFrame(video_frame->width,
  402. video_frame->height, obj->encoder_stats_observer_.userdata);
  403. }
  404. ++obj->captured_frame_count_;
  405. video_stream_encoder_maybe_encode_video_frame(obj, pt, video_frame, post_time_us);
  406. if (log_stats) {
  407. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  408. "video_stream_encoder_on_frame Number of frames: captured %d.",
  409. obj->captured_frame_count_);
  410. obj->captured_frame_count_ = 0;
  411. }
  412. }
  413. void video_stream_encoder_send_key_frame(VideoStreamEncoder *obj) {
  414. //TRACE_EVENT0("webrtc", "OnKeyFrameRequest");
  415. obj->next_frame_type_ = kVideoFrameKey;
  416. }
  417. //动态更新编码参数,适应网络状态
  418. void video_stream_encoder_on_bitrate_updated(VideoStreamEncoder *obj, uint32_t target_bitrate,
  419. uint32_t link_allocation,
  420. uint8_t fraction_lost,
  421. int64_t round_trip_time_ms) {
  422. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  423. "video_stream_encoder_on_bitrate_updated. bitrate %u, packet loss %u, rtt %I64d.",
  424. target_bitrate, fraction_lost, round_trip_time_ms);
  425. if (obj->allocation_encoder_rate_settings_.bitrate != -1 && obj->allocation_encoder_rate_settings_.framerate_fps != -1) {
  426. uint32_t framerate_fps = video_stream_encoder_get_input_framerate_fps(obj);
  427. float cur_fps_ratio = framerate_fps / (float)obj->encoder_config_.max_framerate;
  428. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  429. "video_stream_encoder_on_bitrate_updated. input_framerate_fps %u cur_fps_ratio:%f.",
  430. framerate_fps, cur_fps_ratio);
  431. if (target_bitrate > obj->allocation_encoder_rate_settings_.bitrate) {
  432. obj->continue_bitrate_inc_count++;
  433. obj->continue_bitrate_dec_count = 0;
  434. }
  435. else if (target_bitrate < obj->allocation_encoder_rate_settings_.bitrate) {
  436. obj->continue_bitrate_inc_count = 0;
  437. obj->continue_bitrate_dec_count++;
  438. }
  439. //调整策略:
  440. //带宽分配已经达到最大值90%(反馈的值与max因为header有一定偏差),此时需要提升fps
  441. if (target_bitrate >= obj->encoder_config_.max_bitrate * 1000 * 0.9) {
  442. obj->allocation_encoder_rate_settings_.framerate_fps = obj->encoder_config_.max_framerate;
  443. obj->allocation_encoder_rate_settings_.bitrate = obj->encoder_config_.max_bitrate * 1000;
  444. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  445. "video_stream_encoder_on_bitrate_updated. bitrate %u >= max_bitrate %u' 90%, use max send.",
  446. target_bitrate, obj->encoder_config_.max_bitrate * 1000);
  447. }
  448. else {
  449. //高带宽,升码率直到max_bitrate
  450. if (obj->continue_bitrate_inc_count >= 2 && target_bitrate >= 70000) {
  451. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  452. "video_stream_encoder_on_bitrate_updated. continue_bitrate_inc_count >= 2, bitrate %u, last_bitrate %f, use new bitrate send.",
  453. target_bitrate, (float)obj->allocation_encoder_rate_settings_.bitrate*cur_fps_ratio);
  454. obj->allocation_encoder_rate_settings_.bitrate = target_bitrate;
  455. obj->allocation_encoder_rate_settings_.framerate_fps = obj->encoder_config_.max_framerate;
  456. }
  457. //低带宽:先降帧率,帧率降到最低仍不够,降低码率
  458. else if (obj->continue_bitrate_dec_count >= 3 || target_bitrate < 70000) {
  459. float fps_ratio = (float)obj->encoder_config_.min_framerate / (float)obj->encoder_config_.max_framerate;
  460. float ratio_bitrate = (float)obj->allocation_encoder_rate_settings_.bitrate*fps_ratio;
  461. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  462. "video_stream_encoder_on_bitrate_updated. continue_bitrate_dec_count >= 3, bitrate %d ,last_bitrate %f.",
  463. target_bitrate, (float)obj->allocation_encoder_rate_settings_.bitrate*cur_fps_ratio);
  464. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  465. "video_stream_encoder_on_bitrate_updated. continue_bitrate_dec_count >= 3, fps_ratio %f ratio_bitrate %f.",
  466. fps_ratio, ratio_bitrate);
  467. obj->allocation_encoder_rate_settings_.framerate_fps = obj->encoder_config_.min_framerate;
  468. //obj->allocation_encoder_rate_settings_.bitrate = target_bitrate/fps_ratio;
  469. obj->allocation_encoder_rate_settings_.bitrate =
  470. target_bitrate > obj->encoder_config_.min_bitrate * 1000 ? target_bitrate : obj->encoder_config_.min_bitrate * 1000;
  471. video_coding_debug(VIDEO_CODING_DEBUG_STREAM_ENCODER,
  472. "video_stream_encoder_on_bitrate_updated. continue_bitrate_dec_count >= 3, new bitrate %d, new framerate_fps %lf.",
  473. obj->allocation_encoder_rate_settings_.bitrate, obj->allocation_encoder_rate_settings_.framerate_fps);
  474. }
  475. else {
  476. obj->allocation_encoder_rate_settings_.bitrate = target_bitrate;
  477. }
  478. }
  479. }
  480. else {
  481. obj->allocation_encoder_rate_settings_.framerate_fps = obj->encoder_config_.max_framerate;
  482. obj->allocation_encoder_rate_settings_.bitrate = target_bitrate;
  483. }
  484. /*if (target_bitrate < obj->encoder_config_.min_bitrate){
  485. obj->allocation_encoder_rate_settings_.framerate_fps = obj->encoder_config_.min_framerate;
  486. obj->allocation_encoder_rate_settings_.bitrate = obj->encoder_config_.min_bitrate;
  487. } else {
  488. obj->allocation_encoder_rate_settings_.framerate_fps = obj->encoder_config_.max_framerate;
  489. obj->allocation_encoder_rate_settings_.bitrate = target_bitrate;
  490. }*/
  491. frame_dropper_set_rates(obj->frame_dropper_, (obj->allocation_encoder_rate_settings_.bitrate + 500) / 1000,
  492. obj->allocation_encoder_rate_settings_.framerate_fps);
  493. EncoderRateSettings new_rate_settings = { obj->allocation_encoder_rate_settings_.bitrate, obj->allocation_encoder_rate_settings_.framerate_fps };
  494. video_stream_encoder_set_encoder_rates(obj, &new_rate_settings);
  495. }
  496. }