diff options
author | Peter Boström <pbos@webrtc.org> | 2015-12-18 16:01:11 +0100 |
---|---|---|
committer | Peter Boström <pbos@webrtc.org> | 2015-12-18 15:01:23 +0000 |
commit | b7d9a97ce41022e984348efb5f28bf6dd6c6b779 (patch) | |
tree | 078df9847e254d49fbbaebd18cfe9a8a5a79db74 /webrtc/modules | |
parent | 6c6510afad45baf73850818b4ff660563d7726a5 (diff) | |
download | webrtc-b7d9a97ce41022e984348efb5f28bf6dd6c6b779.tar.gz |
Expose codec implementation names in stats.
Used to distinguish between software/hardware encoders/decoders and
other implementation differences. Useful for tracking quality
regressions related to specific implementations.
BUG=webrtc:4897
R=hta@webrtc.org, mflodman@webrtc.org, stefan@webrtc.org
Review URL: https://codereview.webrtc.org/1406903002 .
Cr-Commit-Position: refs/heads/master@{#11084}
Diffstat (limited to 'webrtc/modules')
14 files changed, 108 insertions, 58 deletions
diff --git a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_decoder.cc b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_decoder.cc index 6d9a4c14c7..a0bbb9e55a 100644 --- a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_decoder.cc +++ b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_decoder.cc @@ -266,6 +266,10 @@ void H264VideoToolboxDecoder::SetVideoFormat( } } +const char* H264VideoToolboxDecoder::ImplementationName() const { + return "VideoToolbox"; +} + } // namespace webrtc #endif // defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED) diff --git a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_decoder.h b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_decoder.h index f54ddb9efd..6d64307a82 100644 --- a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_decoder.h +++ b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_decoder.h @@ -45,6 +45,8 @@ class H264VideoToolboxDecoder : public H264Decoder { int Reset() override; + const char* ImplementationName() const override; + private: int ResetDecompressionSession(); void ConfigureDecompressionSession(); diff --git a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc index d677f8b812..f47f39c115 100644 --- a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc +++ b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.cc @@ -434,6 +434,10 @@ void H264VideoToolboxEncoder::DestroyCompressionSession() { } } +const char* H264VideoToolboxEncoder::ImplementationName() const { + return "VideoToolbox"; +} + } // namespace webrtc #endif // defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED) diff --git a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.h b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.h index f4fb86fa04..269e0411b2 100644 --- a/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.h +++ b/webrtc/modules/video_coding/codecs/h264/h264_video_toolbox_encoder.h @@ -48,6 +48,8 @@ class H264VideoToolboxEncoder : public H264Encoder { int Release() override; + const char* ImplementationName() const override; + private: int ResetCompressionSession(); void ConfigureCompressionSession(); diff --git a/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc b/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc index 605b4d16fe..a608c1025b 100644 --- a/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc +++ b/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc @@ -301,6 +301,10 @@ int VP8EncoderImpl::SetRates(uint32_t new_bitrate_kbit, return WEBRTC_VIDEO_CODEC_OK; } +const char* VP8EncoderImpl::ImplementationName() const { + return "libvpx"; +} + void VP8EncoderImpl::SetStreamState(bool send_stream, int stream_idx) { if (send_stream && !send_stream_[stream_idx]) { @@ -1398,6 +1402,10 @@ int VP8DecoderImpl::Release() { return WEBRTC_VIDEO_CODEC_OK; } +const char* VP8DecoderImpl::ImplementationName() const { + return "libvpx"; +} + int VP8DecoderImpl::CopyReference(VP8DecoderImpl* copy) { // The type of frame to copy should be set in ref_frame_->frame_type // before the call to this function. diff --git a/webrtc/modules/video_coding/codecs/vp8/vp8_impl.h b/webrtc/modules/video_coding/codecs/vp8/vp8_impl.h index 597fb77970..e673ad4e0a 100644 --- a/webrtc/modules/video_coding/codecs/vp8/vp8_impl.h +++ b/webrtc/modules/video_coding/codecs/vp8/vp8_impl.h @@ -58,6 +58,8 @@ class VP8EncoderImpl : public VP8Encoder { void OnDroppedFrame() override {} + const char* ImplementationName() const override; + private: void SetupTemporalLayers(int num_streams, int num_temporal_layers, const VideoCodec& codec); @@ -135,6 +137,8 @@ class VP8DecoderImpl : public VP8Decoder { int Release() override; int Reset() override; + const char* ImplementationName() const override; + private: // Copy reference image from this _decoder to the _decoder in copyTo. Set // which frame type to copy in _refFrame->frame_type before the call to diff --git a/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc b/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc index 21096bd82e..a00af6449d 100644 --- a/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc +++ b/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc @@ -809,6 +809,10 @@ int VP9EncoderImpl::RegisterEncodeCompleteCallback( return WEBRTC_VIDEO_CODEC_OK; } +const char* VP9EncoderImpl::ImplementationName() const { + return "libvpx"; +} + VP9Decoder* VP9Decoder::Create() { return new VP9DecoderImpl(); } @@ -980,4 +984,9 @@ int VP9DecoderImpl::Release() { inited_ = false; return WEBRTC_VIDEO_CODEC_OK; } + +const char* VP9DecoderImpl::ImplementationName() const { + return "libvpx"; +} + } // namespace webrtc diff --git a/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h b/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h index 9a48e74d3e..91475c9e82 100644 --- a/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h +++ b/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h @@ -47,6 +47,8 @@ class VP9EncoderImpl : public VP9Encoder { void OnDroppedFrame() override {} + const char* ImplementationName() const override; + struct LayerFrameRefSettings { int8_t upd_buf = -1; // -1 - no update, 0..7 - update buffer 0..7 int8_t ref_buf1 = -1; // -1 - no reference, 0..7 - reference buffer 0..7 @@ -148,6 +150,8 @@ class VP9DecoderImpl : public VP9Decoder { int Reset() override; + const char* ImplementationName() const override; + private: int ReturnFrame(const vpx_image_t* img, uint32_t timeStamp); diff --git a/webrtc/modules/video_coding/generic_decoder.cc b/webrtc/modules/video_coding/generic_decoder.cc index dc78ec21f2..3c72509c05 100644 --- a/webrtc/modules/video_coding/generic_decoder.cc +++ b/webrtc/modules/video_coding/generic_decoder.cc @@ -19,15 +19,12 @@ namespace webrtc { VCMDecodedFrameCallback::VCMDecodedFrameCallback(VCMTiming& timing, Clock* clock) -: -_critSect(CriticalSectionWrapper::CreateCriticalSection()), -_clock(clock), -_receiveCallback(NULL), -_timing(timing), -_timestampMap(kDecoderFrameMemoryLength), -_lastReceivedPictureID(0) -{ -} + : _critSect(CriticalSectionWrapper::CreateCriticalSection()), + _clock(clock), + _receiveCallback(NULL), + _timing(timing), + _timestampMap(kDecoderFrameMemoryLength), + _lastReceivedPictureID(0) {} VCMDecodedFrameCallback::~VCMDecodedFrameCallback() { @@ -115,6 +112,13 @@ uint64_t VCMDecodedFrameCallback::LastReceivedPictureID() const return _lastReceivedPictureID; } +void VCMDecodedFrameCallback::OnDecoderImplementationName( + const char* implementation_name) { + CriticalSectionScoped cs(_critSect); + if (_receiveCallback) + _receiveCallback->OnDecoderImplementationName(implementation_name); +} + void VCMDecodedFrameCallback::Map(uint32_t timestamp, VCMFrameInformation* frameInfo) { CriticalSectionScoped cs(_critSect); @@ -164,6 +168,7 @@ int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, int64_t nowMs) { frame.FragmentationHeader(), frame.CodecSpecific(), frame.RenderTimeMs()); + _callback->OnDecoderImplementationName(_decoder->ImplementationName()); if (ret < WEBRTC_VIDEO_CODEC_OK) { LOG(LS_WARNING) << "Failed to decode frame with timestamp " diff --git a/webrtc/modules/video_coding/generic_decoder.h b/webrtc/modules/video_coding/generic_decoder.h index 40a9845c94..b23462ffee 100644 --- a/webrtc/modules/video_coding/generic_decoder.h +++ b/webrtc/modules/video_coding/generic_decoder.h @@ -46,6 +46,7 @@ public: virtual int32_t ReceivedDecodedFrame(const uint64_t pictureId); uint64_t LastReceivedPictureID() const; + void OnDecoderImplementationName(const char* implementation_name); void Map(uint32_t timestamp, VCMFrameInformation* frameInfo); int32_t Pop(uint32_t timestamp); @@ -54,9 +55,9 @@ private: // Protect |_receiveCallback| and |_timestampMap|. CriticalSectionWrapper* _critSect; Clock* _clock; - VCMReceiveCallback* _receiveCallback; // Guarded by |_critSect|. + VCMReceiveCallback* _receiveCallback GUARDED_BY(_critSect); VCMTiming& _timing; - VCMTimestampMap _timestampMap; // Guarded by |_critSect|. + VCMTimestampMap _timestampMap GUARDED_BY(_critSect); uint64_t _lastReceivedPictureID; }; diff --git a/webrtc/modules/video_coding/generic_encoder.cc b/webrtc/modules/video_coding/generic_encoder.cc index c8180f35a2..ae5284b9a5 100644 --- a/webrtc/modules/video_coding/generic_encoder.cc +++ b/webrtc/modules/video_coding/generic_encoder.cc @@ -150,6 +150,12 @@ int32_t VCMGenericEncoder::Encode(const VideoFrame& inputFrame, vcm_encoded_frame_callback_->SetRotation(rotation_); int32_t result = encoder_->Encode(inputFrame, codecSpecificInfo, &frameTypes); + + if (vcm_encoded_frame_callback_) { + vcm_encoded_frame_callback_->SignalLastEncoderImplementationUsed( + encoder_->ImplementationName()); + } + if (is_screenshare_ && result == WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT) { // Target bitrate exceeded, encoder state has been reset - try again. @@ -224,7 +230,7 @@ int VCMGenericEncoder::GetTargetFramerate() { ***************************/ VCMEncodedFrameCallback::VCMEncodedFrameCallback( EncodedImageCallback* post_encode_callback) - : _sendCallback(), + : send_callback_(), _mediaOpt(NULL), _payloadType(0), _internalSource(false), @@ -250,27 +256,25 @@ VCMEncodedFrameCallback::~VCMEncodedFrameCallback() int32_t VCMEncodedFrameCallback::SetTransportCallback(VCMPacketizationCallback* transport) { - _sendCallback = transport; + send_callback_ = transport; return VCM_OK; } int32_t VCMEncodedFrameCallback::Encoded( - const EncodedImage& encodedImage, + const EncodedImage& encoded_image, const CodecSpecificInfo* codecSpecificInfo, const RTPFragmentationHeader* fragmentationHeader) { TRACE_EVENT_INSTANT1("webrtc", "VCMEncodedFrameCallback::Encoded", - "timestamp", encodedImage._timeStamp); - RTC_DCHECK(encodedImage._frameType == kVideoFrameKey || - encodedImage._frameType == kVideoFrameDelta); - post_encode_callback_->Encoded(encodedImage, NULL, NULL); + "timestamp", encoded_image._timeStamp); + post_encode_callback_->Encoded(encoded_image, NULL, NULL); - if (_sendCallback == NULL) { + if (send_callback_ == NULL) { return VCM_UNINITIALIZED; } #ifdef DEBUG_ENCODER_BIT_STREAM if (_bitStreamAfterEncoder != NULL) { - fwrite(encodedImage._buffer, 1, encodedImage._length, + fwrite(encoded_image._buffer, 1, encoded_image._length, _bitStreamAfterEncoder); } #endif @@ -283,25 +287,29 @@ int32_t VCMEncodedFrameCallback::Encoded( } rtpVideoHeader.rotation = _rotation; - int32_t callbackReturn = _sendCallback->SendData( - _payloadType, encodedImage, *fragmentationHeader, rtpVideoHeaderPtr); + int32_t callbackReturn = send_callback_->SendData( + _payloadType, encoded_image, *fragmentationHeader, rtpVideoHeaderPtr); if (callbackReturn < 0) { return callbackReturn; } if (_mediaOpt != NULL) { - _mediaOpt->UpdateWithEncodedData(encodedImage); + _mediaOpt->UpdateWithEncodedData(encoded_image); if (_internalSource) return _mediaOpt->DropFrame(); // Signal to encoder to drop next frame. } return VCM_OK; } -void -VCMEncodedFrameCallback::SetMediaOpt( - media_optimization::MediaOptimization *mediaOpt) -{ - _mediaOpt = mediaOpt; +void VCMEncodedFrameCallback::SetMediaOpt( + media_optimization::MediaOptimization* mediaOpt) { + _mediaOpt = mediaOpt; +} + +void VCMEncodedFrameCallback::SignalLastEncoderImplementationUsed( + const char* implementation_name) { + if (send_callback_) + send_callback_->OnEncoderImplementationName(implementation_name); } } // namespace webrtc diff --git a/webrtc/modules/video_coding/generic_encoder.h b/webrtc/modules/video_coding/generic_encoder.h index 0d8ad50b5f..5346b638c3 100644 --- a/webrtc/modules/video_coding/generic_encoder.h +++ b/webrtc/modules/video_coding/generic_encoder.h @@ -62,9 +62,11 @@ public: void SetInternalSource(bool internalSource) { _internalSource = internalSource; }; void SetRotation(VideoRotation rotation) { _rotation = rotation; } + void SignalLastEncoderImplementationUsed( + const char* encoder_implementation_name); private: - VCMPacketizationCallback* _sendCallback; + VCMPacketizationCallback* send_callback_; media_optimization::MediaOptimization* _mediaOpt; uint8_t _payloadType; bool _internalSource; diff --git a/webrtc/modules/video_coding/include/video_coding_defines.h b/webrtc/modules/video_coding/include/video_coding_defines.h index 1b721441e2..d057b554cd 100644 --- a/webrtc/modules/video_coding/include/video_coding_defines.h +++ b/webrtc/modules/video_coding/include/video_coding_defines.h @@ -62,6 +62,8 @@ class VCMPacketizationCallback { const RTPFragmentationHeader& fragmentationHeader, const RTPVideoHeader* rtpVideoHdr) = 0; + virtual void OnEncoderImplementationName(const char* implementation_name) {} + protected: virtual ~VCMPacketizationCallback() { } @@ -77,6 +79,7 @@ class VCMReceiveCallback { } // Called when the current receive codec changes. virtual void OnIncomingPayloadType(int payload_type) {} + virtual void OnDecoderImplementationName(const char* implementation_name) {} protected: virtual ~VCMReceiveCallback() { diff --git a/webrtc/modules/video_coding/video_receiver.cc b/webrtc/modules/video_coding/video_receiver.cc index f7ac4bc862..f074832eff 100644 --- a/webrtc/modules/video_coding/video_receiver.cc +++ b/webrtc/modules/video_coding/video_receiver.cc @@ -287,43 +287,37 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) { VCMEncodedFrame* frame = _receiver.FrameForDecoding( maxWaitTimeMs, nextRenderTimeMs, prefer_late_decoding); - if (frame == NULL) { + if (!frame) return VCM_FRAME_NOT_READY; - } else { - CriticalSectionScoped cs(_receiveCritSect); - // If this frame was too late, we should adjust the delay accordingly - _timing.UpdateCurrentDelay(frame->RenderTimeMs(), - clock_->TimeInMilliseconds()); + CriticalSectionScoped cs(_receiveCritSect); - if (pre_decode_image_callback_) { - EncodedImage encoded_image(frame->EncodedImage()); - int qp = -1; - if (qp_parser_.GetQp(*frame, &qp)) { - encoded_image.qp_ = qp; - } - pre_decode_image_callback_->Encoded( - encoded_image, frame->CodecSpecific(), NULL); + // If this frame was too late, we should adjust the delay accordingly + _timing.UpdateCurrentDelay(frame->RenderTimeMs(), + clock_->TimeInMilliseconds()); + + if (pre_decode_image_callback_) { + EncodedImage encoded_image(frame->EncodedImage()); + int qp = -1; + if (qp_parser_.GetQp(*frame, &qp)) { + encoded_image.qp_ = qp; } + pre_decode_image_callback_->Encoded(encoded_image, frame->CodecSpecific(), + NULL); + } #ifdef DEBUG_DECODER_BIT_STREAM - if (_bitStreamBeforeDecoder != NULL) { - // Write bit stream to file for debugging purposes - if (fwrite( - frame->Buffer(), 1, frame->Length(), _bitStreamBeforeDecoder) != - frame->Length()) { - return -1; - } - } -#endif - const int32_t ret = Decode(*frame); - _receiver.ReleaseFrame(frame); - frame = NULL; - if (ret != VCM_OK) { - return ret; + if (_bitStreamBeforeDecoder != NULL) { + // Write bit stream to file for debugging purposes + if (fwrite(frame->Buffer(), 1, frame->Length(), _bitStreamBeforeDecoder) != + frame->Length()) { + return -1; } } - return VCM_OK; +#endif + const int32_t ret = Decode(*frame); + _receiver.ReleaseFrame(frame); + return ret; } int32_t VideoReceiver::RequestSliceLossIndication( |