Bug 1535584 - Restore UpdateCodecFrameSize to vp9_impl.cc; r=bwc a=pascalc
authorDan Minor <dminor@mozilla.com>
Thu, 21 Mar 2019 15:48:46 +0000
changeset 522700 851a8b3844769ddc6d484be1eb8d40ab69f1ae8c
parent 522699 8c19d4132c70122a35d3115c0af65e3bf14cee1d
child 522701 6075989112d0fa68e5bad0617e2bcd7085109506
push id10907
push userarchaeopteryx@coole-files.de
push dateMon, 25 Mar 2019 11:57:16 +0000
treeherdermozilla-beta@851a8b384476 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbwc, pascalc
bugs1535584
milestone67.0
Bug 1535584 - Restore UpdateCodecFrameSize to vp9_impl.cc; r=bwc a=pascalc Differential Revision: https://phabricator.services.mozilla.com/D23713
media/webrtc/trunk/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
--- a/media/webrtc/trunk/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
@@ -496,16 +496,25 @@ int VP9EncoderImpl::Encode(const VideoFr
   if (encoded_complete_callback_ == nullptr) {
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
   }
   FrameType frame_type = kVideoFrameDelta;
   // We only support one stream at the moment.
   if (frame_types && frame_types->size() > 0) {
     frame_type = (*frame_types)[0];
   }
+
+  if (input_image.width() != codec_.width ||
+      input_image.height() != codec_.height) {
+    int ret = UpdateCodecFrameSize(input_image);
+    if (ret < 0) {
+      return ret;
+    }
+  }
+
   RTC_DCHECK_EQ(input_image.width(), raw_->d_w);
   RTC_DCHECK_EQ(input_image.height(), raw_->d_h);
 
   // Set input image for use in the callback.
   // This was necessary since you need some information from input_image.
   // You can save only the necessary information (such as timestamp) instead of
   // doing this.
   input_image_ = &input_image;
@@ -556,16 +565,55 @@ int VP9EncoderImpl::Encode(const VideoFr
                        VPX_DL_REALTIME)) {
     return WEBRTC_VIDEO_CODEC_ERROR;
   }
   timestamp_ += duration;
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
+int VP9EncoderImpl::UpdateCodecFrameSize(
+    const VideoFrame& input_image) {
+  RTC_LOG(LS_INFO) << "Reconfiging VP from " <<
+          codec_.width << "x" << codec_.height << " to " <<
+          input_image.width() << "x" << input_image.height();
+  // Preserve latest bitrate/framerate setting
+  uint32_t old_bitrate_kbit = config_->rc_target_bitrate;
+  uint32_t old_framerate = codec_.maxFramerate;
+
+  codec_.width = input_image.width();
+  codec_.height = input_image.height();
+
+  vpx_img_free(raw_);
+  raw_ = vpx_img_wrap(NULL, VPX_IMG_FMT_I420, codec_.width, codec_.height,
+                      1, NULL);
+  // Update encoder context for new frame size.
+  config_->g_w = codec_.width;
+  config_->g_h = codec_.height;
+
+  // Determine number of threads based on the image size and #cores.
+  config_->g_threads = NumberOfThreads(codec_.width, codec_.height,
+                                       num_cores_);
+  // Update the cpu_speed setting for resolution change.
+  cpu_speed_ = GetCpuSpeed(codec_.width, codec_.height);
+
+  // NOTE: We would like to do this the same way vp8 does it
+  // (with vpx_codec_enc_config_set()), but that causes asserts
+  // in AQ 3 (cyclic); and in AQ 0 it works, but on a resize to smaller
+  // than 1/2 x 1/2 original it asserts in convolve().  Given these
+  // bugs in trying to do it the "right" way, we basically re-do
+  // the initialization.
+  vpx_codec_destroy(encoder_); // clean up old state
+  int result = InitAndSetControlSettings(&codec_);
+  if (result == WEBRTC_VIDEO_CODEC_OK) {
+    return SetRates(old_bitrate_kbit, old_framerate);
+  }
+  return result;
+}
+
 void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
                                            const vpx_codec_cx_pkt& pkt,
                                            uint32_t timestamp) {
   RTC_CHECK(codec_specific != nullptr);
   codec_specific->codecType = kVideoCodecVP9;
   codec_specific->codec_name = ImplementationName();
   CodecSpecificInfoVP9* vp9_info = &(codec_specific->codecSpecific.VP9);
   // TODO(asapersson): Set correct value.