Index: webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc |
diff --git a/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc b/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc |
index a28f41d101e42bd94645257fb699432e008919e6..e98666d073695016e89a48600ae863d53a768a87 100644 |
--- a/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc |
+++ b/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc |
@@ -24,6 +24,7 @@ extern "C" { |
#include "webrtc/base/criticalsection.h" |
#include "webrtc/base/keep_ref_until_done.h" |
#include "webrtc/base/logging.h" |
+#include "webrtc/system_wrappers/include/metrics.h" |
namespace webrtc { |
@@ -34,6 +35,13 @@ const size_t kYPlaneIndex = 0; |
const size_t kUPlaneIndex = 1; |
const size_t kVPlaneIndex = 2; |
+// Used by histograms. Values of entries should not be changed. |
+enum H264DecoderImplEvent { |
+ kH264DecoderEventInit = 0, |
+ kH264DecoderEventError = 1, |
+ kH264DecoderEventMax = 16, |
hbos
2016/02/23 15:01:22
The example I looked at was WebRTC.Video.Encoder.C
hlundin-webrtc
2016/02/24 09:17:57
I don't know the history behind CodecType. The des
hbos
2016/02/24 11:11:25
Ok. Landed as-is. rkaplow if you know I could adju
rkaplow
2016/02/24 16:10:08
usually people don't even set the numbers here man
|
+}; |
+ |
#if defined(WEBRTC_INITIALIZE_FFMPEG) |
rtc::CriticalSection ffmpeg_init_lock; |
@@ -109,6 +117,7 @@ int H264DecoderImpl::AVGetBuffer2( |
static_cast<unsigned int>(height), 0, nullptr); |
if (ret < 0) { |
LOG(LS_ERROR) << "Invalid picture size " << width << "x" << height; |
+ decoder->ReportError(); |
return ret; |
} |
@@ -158,7 +167,9 @@ void H264DecoderImpl::AVFreeBuffer2(void* opaque, uint8_t* data) { |
} |
H264DecoderImpl::H264DecoderImpl() : pool_(true), |
- decoded_image_callback_(nullptr) { |
+ decoded_image_callback_(nullptr), |
+ has_reported_init_(false), |
+ has_reported_error_(false) { |
} |
H264DecoderImpl::~H264DecoderImpl() { |
@@ -167,8 +178,10 @@ H264DecoderImpl::~H264DecoderImpl() { |
int32_t H264DecoderImpl::InitDecode(const VideoCodec* codec_settings, |
int32_t number_of_cores) { |
+ ReportInit(); |
if (codec_settings && |
codec_settings->codecType != kVideoCodecH264) { |
+ ReportError(); |
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
} |
@@ -186,8 +199,10 @@ int32_t H264DecoderImpl::InitDecode(const VideoCodec* codec_settings, |
// Release necessary in case of re-initializing. |
int32_t ret = Release(); |
- if (ret != WEBRTC_VIDEO_CODEC_OK) |
+ if (ret != WEBRTC_VIDEO_CODEC_OK) { |
+ ReportError(); |
return ret; |
+ } |
RTC_DCHECK(!av_context_); |
// Initialize AVCodecContext. |
@@ -222,12 +237,14 @@ int32_t H264DecoderImpl::InitDecode(const VideoCodec* codec_settings, |
// been compiled/initialized with the correct set of codecs. |
LOG(LS_ERROR) << "FFmpeg H.264 decoder not found."; |
Release(); |
+ ReportError(); |
return WEBRTC_VIDEO_CODEC_ERROR; |
} |
int res = avcodec_open2(av_context_.get(), codec, nullptr); |
if (res < 0) { |
LOG(LS_ERROR) << "avcodec_open2 error: " << res; |
Release(); |
+ ReportError(); |
return WEBRTC_VIDEO_CODEC_ERROR; |
} |
@@ -252,17 +269,23 @@ int32_t H264DecoderImpl::Decode(const EncodedImage& input_image, |
const RTPFragmentationHeader* /*fragmentation*/, |
const CodecSpecificInfo* codec_specific_info, |
int64_t /*render_time_ms*/) { |
- if (!IsInitialized()) |
+ if (!IsInitialized()) { |
+ ReportError(); |
return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
+ } |
if (!decoded_image_callback_) { |
LOG(LS_WARNING) << "InitDecode() has been called, but a callback function " |
"has not been set with RegisterDecodeCompleteCallback()"; |
+ ReportError(); |
return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
} |
- if (!input_image._buffer || !input_image._length) |
+ if (!input_image._buffer || !input_image._length) { |
+ ReportError(); |
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
+ } |
if (codec_specific_info && |
codec_specific_info->codecType != kVideoCodecH264) { |
+ ReportError(); |
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
} |
@@ -282,6 +305,7 @@ int32_t H264DecoderImpl::Decode(const EncodedImage& input_image, |
packet.data = input_image._buffer; |
if (input_image._length > |
static_cast<size_t>(std::numeric_limits<int>::max())) { |
+ ReportError(); |
return WEBRTC_VIDEO_CODEC_ERROR; |
} |
packet.size = static_cast<int>(input_image._length); |
@@ -294,12 +318,14 @@ int32_t H264DecoderImpl::Decode(const EncodedImage& input_image, |
&packet); |
if (result < 0) { |
LOG(LS_ERROR) << "avcodec_decode_video2 error: " << result; |
+ ReportError(); |
return WEBRTC_VIDEO_CODEC_ERROR; |
} |
// |result| is number of bytes used, which should be all of them. |
if (result != packet.size) { |
LOG(LS_ERROR) << "avcodec_decode_video2 consumed " << result << " bytes " |
"when " << packet.size << " bytes were expected."; |
+ ReportError(); |
return WEBRTC_VIDEO_CODEC_ERROR; |
} |
@@ -349,4 +375,22 @@ bool H264DecoderImpl::IsInitialized() const { |
return av_context_ != nullptr; |
} |
+void H264DecoderImpl::ReportInit() { |
+ if (has_reported_init_) |
+ return; |
+ RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.H264DecoderImpl.Event", |
+ kH264DecoderEventInit, |
+ kH264DecoderEventMax); |
+ has_reported_init_ = true; |
+} |
+ |
+void H264DecoderImpl::ReportError() { |
+ if (has_reported_error_) |
+ return; |
+ RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.H264DecoderImpl.Event", |
+ kH264DecoderEventError, |
+ kH264DecoderEventMax); |
+ has_reported_error_ = true; |
+} |
+ |
} // namespace webrtc |