From 26762e3e40f682d37f33fd797383de1c7562f855 Mon Sep 17 00:00:00 2001 From: "marpan@webrtc.org" Date: Fri, 2 Mar 2012 16:48:36 +0000 Subject: [PATCH] Allow for spatial-downsampling without reinitializaing encoder. Change of frame size will automatically trigger new key frame in codec. This feature is set off in video engine until we upgrade to a newer version of libvpx. Review URL: https://webrtc-codereview.appspot.com/427003 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1827 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../codecs/vp8/main/interface/vp8.h | 4 +++ .../codecs/vp8/main/source/vp8.cc | 33 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/modules/video_coding/codecs/vp8/main/interface/vp8.h b/src/modules/video_coding/codecs/vp8/main/interface/vp8.h index 89cf06750..3ee312b6c 100644 --- a/src/modules/video_coding/codecs/vp8/main/interface/vp8.h +++ b/src/modules/video_coding/codecs/vp8/main/interface/vp8.h @@ -109,6 +109,10 @@ class VP8Encoder : public VideoEncoder { // Call encoder initialize function and set control settings. int InitAndSetControlSettings(); + // Update frame size for codec. + int UpdateCodecFrameSize(WebRtc_UWord32 input_image_width, + WebRtc_UWord32 input_image_height); + void PopulateCodecSpecific(CodecSpecificInfo* codec_specific, const vpx_codec_cx_pkt& pkt); diff --git a/src/modules/video_coding/codecs/vp8/main/source/vp8.cc b/src/modules/video_coding/codecs/vp8/main/source/vp8.cc index a477237b1..c2748961e 100644 --- a/src/modules/video_coding/codecs/vp8/main/source/vp8.cc +++ b/src/modules/video_coding/codecs/vp8/main/source/vp8.cc @@ -324,6 +324,15 @@ int VP8Encoder::Encode(const RawImage& input_image, if (encoded_complete_callback_ == NULL) { return WEBRTC_VIDEO_CODEC_UNINITIALIZED; } + + // Check for change in frame size. + if (input_image._width != codec_.width || + input_image._height != codec_.height) { + int ret = UpdateCodecFrameSize(input_image._width, input_image._height); + if (ret < 0) { + return ret; + } + } // image in vpx_image_t format raw_->planes[PLANE_Y] = input_image._buffer; raw_->planes[PLANE_U] = &input_image._buffer[codec_.height * codec_.width]; @@ -376,6 +385,30 @@ int VP8Encoder::Encode(const RawImage& input_image, #endif } +int VP8Encoder::UpdateCodecFrameSize(WebRtc_UWord32 input_image_width, + WebRtc_UWord32 input_image_height) { + codec_.width = input_image_width; + codec_.height = input_image_height; + + raw_->w = codec_.width; + raw_->h = codec_.height; + raw_->d_w = codec_.width; + raw_->d_h = codec_.height; + raw_->stride[VPX_PLANE_Y] = codec_.width; + raw_->stride[VPX_PLANE_U] = codec_.width / 2; + raw_->stride[VPX_PLANE_V] = codec_.width / 2; + vpx_img_set_rect(raw_, 0, 0, codec_.width, codec_.height); + + // Update encoder context for new frame size. + // Change of frame size will automatically trigger a key frame. + config_->g_w = codec_.width; + config_->g_h = codec_.height; + if (vpx_codec_enc_config_set(encoder_, config_)) { + return WEBRTC_VIDEO_CODEC_ERROR; + } + return WEBRTC_VIDEO_CODEC_OK; +} + void VP8Encoder::PopulateCodecSpecific(CodecSpecificInfo* codec_specific, const vpx_codec_cx_pkt& pkt) { assert(codec_specific != NULL);