Bug 1535584 - Restore UpdateCodecFrameSize to vp9_impl.cc; r=bwc
authorDan Minor <dminor@mozilla.com>
Thu, 21 Mar 2019 15:48:46 +0000
changeset 527364 0898f9cfe09273e1d86c38abdd576cdf273009f0
parent 527363 91b886baa72d47280c5a0f5cca15f1c70d92f22f
child 527365 76ec247785a8ce6a79199ddbc5fc57f125c6857d
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbwc
bugs1535584
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1535584 - Restore UpdateCodecFrameSize to vp9_impl.cc; r=bwc 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.