Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / video_coding / codecs / vp8 / vp8_impl.cc
index 4901edf..2a2a9d0 100644 (file)
@@ -105,6 +105,7 @@ int VP8EncoderImpl::SetRates(uint32_t new_bitrate_kbit,
   temporal_layers_->ConfigureBitrates(new_bitrate_kbit, codec_.maxBitrate,
                                       new_framerate, config_);
   codec_.maxFramerate = new_framerate;
+  quality_scaler_.ReportFramerate(new_framerate);
 
   // update encoder context
   if (vpx_codec_enc_config_set(encoder_, config_)) {
@@ -174,7 +175,7 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
   // Creating a wrapper to the image - setting image data to NULL. Actual
   // pointer will be set in encode. Setting align to 1, as it is meaningless
   // (actual memory is not allocated).
-  raw_ = vpx_img_wrap(NULL, IMG_FMT_I420, codec_.width, codec_.height,
+  raw_ = vpx_img_wrap(NULL, VPX_IMG_FMT_I420, codec_.width, codec_.height,
                       1, NULL);
   // populate encoder configuration with default values
   if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), config_, 0)) {
@@ -230,8 +231,8 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
       30 : 0;
   config_->rc_end_usage = VPX_CBR;
   config_->g_pass = VPX_RC_ONE_PASS;
-  config_->rc_resize_allowed = inst->codecSpecific.VP8.automaticResizeOn ?
-      1 : 0;
+  // Handle resizing outside of libvpx.
+  config_->rc_resize_allowed = 0;
   config_->rc_min_quantizer = 2;
   config_->rc_max_quantizer = inst->qpMax;
   config_->rc_undershoot_pct = 100;
@@ -272,6 +273,8 @@ int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
   cpu_speed_ = -12;
 #endif
   rps_->Init();
+  quality_scaler_.Init(codec_.qpMax);
+  quality_scaler_.ReportFramerate(codec_.maxFramerate);
   return InitAndSetControlSettings(inst);
 }
 
@@ -296,6 +299,7 @@ int VP8EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) {
   vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT,
                     rc_max_intra_target_);
   inited_ = true;
+
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
@@ -315,15 +319,15 @@ uint32_t VP8EncoderImpl::MaxIntraTarget(uint32_t optimalBuffersize) {
   return (targetPct < minIntraTh) ? minIntraTh: targetPct;
 }
 
-int VP8EncoderImpl::Encode(const I420VideoFrame& input_image,
+int VP8EncoderImpl::Encode(const I420VideoFrame& input_frame,
                            const CodecSpecificInfo* codec_specific_info,
                            const std::vector<VideoFrameType>* frame_types) {
-  TRACE_EVENT1("webrtc", "VP8::Encode", "timestamp", input_image.timestamp());
+  TRACE_EVENT1("webrtc", "VP8::Encode", "timestamp", input_frame.timestamp());
 
   if (!inited_) {
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
   }
-  if (input_image.IsZeroSize()) {
+  if (input_frame.IsZeroSize()) {
     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
   }
   if (encoded_complete_callback_ == NULL) {
@@ -336,25 +340,31 @@ int VP8EncoderImpl::Encode(const I420VideoFrame& input_image,
     frame_type = (*frame_types)[0];
   }
 
+  const I420VideoFrame& frame =
+      config_->rc_dropframe_thresh > 0 &&
+              codec_.codecSpecific.VP8.automaticResizeOn
+          ? quality_scaler_.GetScaledFrame(input_frame)
+          : input_frame;
+
   // Check for change in frame size.
-  if (input_image.width() != codec_.width ||
-      input_image.height() != codec_.height) {
-    int ret = UpdateCodecFrameSize(input_image);
+  if (frame.width() != codec_.width ||
+      frame.height() != codec_.height) {
+    int ret = UpdateCodecFrameSize(frame);
     if (ret < 0) {
       return ret;
     }
   }
   // Image in vpx_image_t format.
-  // Input image is const. VP8's raw image is not defined as const.
-  raw_->planes[PLANE_Y] = const_cast<uint8_t*>(input_image.buffer(kYPlane));
-  raw_->planes[PLANE_U] = const_cast<uint8_t*>(input_image.buffer(kUPlane));
-  raw_->planes[PLANE_V] = const_cast<uint8_t*>(input_image.buffer(kVPlane));
+  // Input frame is const. VP8's raw frame is not defined as const.
+  raw_->planes[VPX_PLANE_Y] = const_cast<uint8_t*>(frame.buffer(kYPlane));
+  raw_->planes[VPX_PLANE_U] = const_cast<uint8_t*>(frame.buffer(kUPlane));
+  raw_->planes[VPX_PLANE_V] = const_cast<uint8_t*>(frame.buffer(kVPlane));
   // TODO(mikhal): Stride should be set in initialization.
-  raw_->stride[VPX_PLANE_Y] = input_image.stride(kYPlane);
-  raw_->stride[VPX_PLANE_U] = input_image.stride(kUPlane);
-  raw_->stride[VPX_PLANE_V] = input_image.stride(kVPlane);
+  raw_->stride[VPX_PLANE_Y] = frame.stride(kYPlane);
+  raw_->stride[VPX_PLANE_U] = frame.stride(kUPlane);
+  raw_->stride[VPX_PLANE_V] = frame.stride(kVPlane);
 
-  int flags = temporal_layers_->EncodeFlags(input_image.timestamp());
+  int flags = temporal_layers_->EncodeFlags(frame.timestamp());
 
   bool send_keyframe = (frame_type == kKeyFrame);
   if (send_keyframe) {
@@ -370,11 +380,11 @@ int VP8EncoderImpl::Encode(const I420VideoFrame& input_image,
             codec_specific_info->codecSpecific.VP8.pictureIdRPSI);
       }
       if (codec_specific_info->codecSpecific.VP8.hasReceivedSLI) {
-        sendRefresh = rps_->ReceivedSLI(input_image.timestamp());
+        sendRefresh = rps_->ReceivedSLI(frame.timestamp());
       }
     }
     flags = rps_->EncodeFlags(picture_id_, sendRefresh,
-                              input_image.timestamp());
+                              frame.timestamp());
   }
 
   // TODO(holmer): Ideally the duration should be the timestamp diff of this
@@ -390,7 +400,7 @@ int VP8EncoderImpl::Encode(const I420VideoFrame& input_image,
   }
   timestamp_ += duration;
 
-  return GetEncodedPartitions(input_image);
+  return GetEncodedPartitions(frame);
 }
 
 int VP8EncoderImpl::UpdateCodecFrameSize(const I420VideoFrame& input_image) {
@@ -480,6 +490,11 @@ int VP8EncoderImpl::GetEncodedPartitions(const I420VideoFrame& input_image) {
     encoded_image_._encodedWidth = codec_.width;
     encoded_complete_callback_->Encoded(encoded_image_, &codec_specific,
                                       &frag_info);
+    int qp;
+    vpx_codec_control(encoder_, VP8E_GET_LAST_QUANTIZER_64, &qp);
+    quality_scaler_.ReportEncodedFrame(qp);
+  } else {
+    quality_scaler_.ReportDroppedFrame();
   }
   return WEBRTC_VIDEO_CODEC_OK;
 }