diff --git a/modules/video_coding/codecs/vp8/main/interface/vp8.h b/modules/video_coding/codecs/vp8/main/interface/vp8.h index 073547f84e..c3eb00f307 100644 --- a/modules/video_coding/codecs/vp8/main/interface/vp8.h +++ b/modules/video_coding/codecs/vp8/main/interface/vp8.h @@ -94,7 +94,8 @@ public: // - callback : Callback object which handles encoded images. // // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise. - virtual WebRtc_Word32 RegisterEncodeCompleteCallback(EncodedImageCallback* callback); + virtual WebRtc_Word32 RegisterEncodeCompleteCallback(EncodedImageCallback* + callback); // Inform the encoder of the new packet loss rate in the network // @@ -112,7 +113,8 @@ public: // - frameRate : The target frame rate // // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise. - virtual WebRtc_Word32 SetRates(WebRtc_UWord32 newBitRateKbit, WebRtc_UWord32 frameRate); + virtual WebRtc_Word32 SetRates(WebRtc_UWord32 newBitRateKbit, + WebRtc_UWord32 frameRate); // Get version number for the codec. // @@ -125,13 +127,23 @@ public: // // Return value : >0 - Length of written string. // <0 - WEBRTC_VIDEO_CODEC_ERR_SIZE - virtual WebRtc_Word32 Version(WebRtc_Word8 *version, WebRtc_Word32 length) const; - static WebRtc_Word32 VersionStatic(WebRtc_Word8 *version, WebRtc_Word32 length); + virtual WebRtc_Word32 Version(WebRtc_Word8 *version, + WebRtc_Word32 length) const; + static WebRtc_Word32 VersionStatic(WebRtc_Word8 *version, + WebRtc_Word32 length); private: // Call encoder initialize function and set speed. WebRtc_Word32 InitAndSetSpeed(); +// Determine maximum target for Intra frames +// +// Input: +// - optimalBuffersize : Optimal buffer size +// Return Value : Max target size for Intra frames represented as +// percentage of the per frame bandwidth + WebRtc_Word32 MaxIntraTarget(WebRtc_Word32 optimalBuffersize); + EncodedImage _encodedImage; EncodedImageCallback* _encodedCompleteCallback; WebRtc_Word32 _width; @@ -197,7 +209,8 @@ public: // - callback : Callback object which handles decoded images. // // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise. - virtual WebRtc_Word32 RegisterDecodeCompleteCallback(DecodedImageCallback* callback); + virtual WebRtc_Word32 RegisterDecodeCompleteCallback(DecodedImageCallback* + callback); // Free decoder memory. // @@ -213,7 +226,9 @@ public: // WEBRTC_VIDEO_CODEC_UNINITIALIZED // WEBRTC_VIDEO_CODEC_ERROR virtual WebRtc_Word32 Reset(); - virtual WebRtc_Word32 SetCodecConfigParameters(WebRtc_UWord8* /*buffer*/, WebRtc_Word32 /*size*/) { return -1; } + virtual WebRtc_Word32 SetCodecConfigParameters(WebRtc_UWord8* /*buffer*/, + WebRtc_Word32 /*size*/) + { return -1; } // Create a copy of the codec and its internal state. // diff --git a/modules/video_coding/codecs/vp8/main/source/vp8.cc b/modules/video_coding/codecs/vp8/main/source/vp8.cc index d7d7c1d91c..7f1b1adf0c 100644 --- a/modules/video_coding/codecs/vp8/main/source/vp8.cc +++ b/modules/video_coding/codecs/vp8/main/source/vp8.cc @@ -260,7 +260,8 @@ VP8Encoder::InitEncode(const VideoCodec* inst, _cfg->g_w = inst->width; _cfg->g_h = inst->height; - if (_maxBitRateKbit > 0 && inst->startBitrate > static_cast(_maxBitRateKbit)) + if (_maxBitRateKbit > 0 && + inst->startBitrate > static_cast(_maxBitRateKbit)) { _cfg->rc_target_bitrate = _maxBitRateKbit; } @@ -285,17 +286,21 @@ VP8Encoder::InitEncode(const VideoCodec* inst, _cfg->rc_resize_allowed = 0; _cfg->rc_min_quantizer = 4; _cfg->rc_max_quantizer = 56; - _cfg->rc_undershoot_pct = 98; + _cfg->rc_undershoot_pct = 100; + _cfg->rc_overshoot_pct = 15; _cfg->rc_buf_initial_sz = 500; _cfg->rc_buf_optimal_sz = 600; _cfg->rc_buf_sz = 1000; + _cfg->rc_max_intra_bitrate_pct = MaxIntraTarget(_cfg->rc_buf_optimal_sz); + #ifdef DEV_PIC_LOSS // this can only be off if we know we use feedback if (_pictureLossIndicationOn) { - _cfg->kf_mode = VPX_KF_DISABLED; // don't generate key frame unless we tell you + // don't generate key frame unless we tell you + _cfg->kf_mode = VPX_KF_DISABLED; } else #endif @@ -349,6 +354,23 @@ VP8Encoder::InitAndSetSpeed() return WEBRTC_VIDEO_CODEC_OK; } +WebRtc_Word32 +VP8Encoder::MaxIntraTarget(WebRtc_Word32 optimalBuffersize) +{ + // Set max to 1 / 2 of the optimal buffer level (normalize by target BR). + // Max target size = 0.5 * optimalBufferSize * targetBR[Kbps]. + // This values is presented in percentage of perFrameBw. + // perFrameBw = targetBR[Kbps] * 1000 / frameRate. + // The target in % is as follows: + WebRtc_Word32 targetPct = (optimalBuffersize >> 1) * _maxFrameRate / 10; + + // Don't go below 3 times the per frame bandwidth. + const WebRtc_Word32 minIntraTh = 300; + targetPct = (targetPct < minIntraTh) ? minIntraTh: targetPct; + + return targetPct; +} + WebRtc_Word32 VP8Encoder::Encode(const RawImage& inputImage, const void* codecSpecificInfo, @@ -386,11 +408,13 @@ VP8Encoder::Encode(const RawImage& inputImage, #ifdef DEV_PIC_LOSS if (_feedbackModeOn && codecSpecificInfo) { - const CodecSpecificInfo* info = static_cast(codecSpecificInfo); + const CodecSpecificInfo* info = static_cast(codecSpecificInfo); if (info->codecType == kVideoCodecVP8) { - // codecSpecificInfo will contain received RPSI and SLI picture IDs - // this will help us decide on when to switch type of reference frame + // codecSpecificInfo will contain received RPSI and SLI + // picture IDs. This will help us decide on when to switch type + // of reference frame // if we receive SLI // force using an old golden or altref as a reference @@ -644,10 +668,13 @@ VP8Decoder::InitDecode(const VideoCodec* inst, { return WEBRTC_VIDEO_CODEC_MEMORY; } + + // TODO(mikhal): evaluate post-proc settings // config post-processing settings for decoder ppcfg.post_proc_flag = VP8_DEBLOCK; - ppcfg.deblocking_level = 5; //Strength of deblocking filter. Valid range:[0,16] - //ppcfg.NoiseLevel = 1; //Noise intensity. Valid range: [0,7] + // Strength of deblocking filter. Valid range:[0,16] + ppcfg.deblocking_level = 5; + // ppcfg.NoiseLevel = 1; //Noise intensity. Valid range: [0,7] vpx_codec_control(_decoder, VP8_SET_POSTPROC, &ppcfg); // Save the VideoCodec instance for later; mainly for duplicating the decoder. @@ -706,7 +733,8 @@ VP8Decoder::Decode(const EncodedImage& inputImage, // scan for number of bytes used for picture ID WebRtc_UWord8 numberOfBytes; - for (numberOfBytes = 0;(inputImage._buffer[numberOfBytes] & 0x80 )&& numberOfBytes < 8; numberOfBytes++) + for (numberOfBytes = 0;(inputImage._buffer[numberOfBytes] & 0x80 ) && + numberOfBytes < 8; numberOfBytes++) { pictureID += inputImage._buffer[numberOfBytes] & 0x7f; pictureID <<= 7; @@ -726,8 +754,8 @@ VP8Decoder::Decode(const EncodedImage& inputImage, // we remove the picture ID here if (vpx_codec_decode(_decoder, - inputImage._buffer+numberOfBytes, - inputImage._length-numberOfBytes, + inputImage._buffer + numberOfBytes, + inputImage._length - numberOfBytes, 0, VPX_DL_REALTIME)) { @@ -777,7 +805,7 @@ VP8Decoder::Decode(const EncodedImage& inputImage, img = vpx_codec_get_frame(_decoder, &_iter); // Allocate memory for decoded image - WebRtc_UWord32 requiredSize = (3*img->h * img->w) >> 1; + WebRtc_UWord32 requiredSize = (3 * img->h * img->w) >> 1; if (_decodedImage._buffer != NULL) { delete [] _decodedImage._buffer;