1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 113f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h> 123f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <math.h> 133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org 14fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org#include <sstream> 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string> 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 175e8ee6f8a182dd36d0c9f273f180d015a056cef4andrew@webrtc.org#include "webrtc/modules/video_capture/include/video_capture_factory.h" 18281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/tick_util.h" 19281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/test/testsupport/fileutils.h" 20281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/test/testsupport/frame_reader.h" 21281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/test/testsupport/frame_writer.h" 22281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/test/testsupport/perf_test.h" 23281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h" 24281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h" 25281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/test/auto_test/primitives/framedrop_primitives.h" 26281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/test/auto_test/primitives/general_primitives.h" 27281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/test/libvietest/include/tb_external_transport.h" 28281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/test/libvietest/include/tb_interfaces.h" 29281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/test/libvietest/include/vie_external_render_filter.h" 30281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/test/libvietest/include/vie_to_file_renderer.h" 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 32e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.orgenum { kWaitTimeForFinalDecodeMs = 100 }; 33e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org 34e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org// Writes the frames to be encoded to file and tracks which frames are sent in 35e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org// external transport on the local side and reports them to the 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// FrameDropDetector class. 375600f6e86d3994726249fd1c77377c1d8534f107phoglund@webrtc.orgclass LocalRendererEffectFilter : public webrtc::ExternalRendererEffectFilter { 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public: 395600f6e86d3994726249fd1c77377c1d8534f107phoglund@webrtc.org LocalRendererEffectFilter(webrtc::ExternalRenderer* renderer, 405600f6e86d3994726249fd1c77377c1d8534f107phoglund@webrtc.org FrameDropDetector* frame_drop_detector) 415600f6e86d3994726249fd1c77377c1d8534f107phoglund@webrtc.org : ExternalRendererEffectFilter(renderer), 425600f6e86d3994726249fd1c77377c1d8534f107phoglund@webrtc.org frame_drop_detector_(frame_drop_detector) {} 439d10769e109601915022fea44ec392645c3b0704wu@webrtc.org int Transform(int size, 449d10769e109601915022fea44ec392645c3b0704wu@webrtc.org unsigned char* frame_buffer, 459d10769e109601915022fea44ec392645c3b0704wu@webrtc.org int64_t ntp_time_ms, 469d10769e109601915022fea44ec392645c3b0704wu@webrtc.org unsigned int timestamp, 479d10769e109601915022fea44ec392645c3b0704wu@webrtc.org unsigned int width, 485600f6e86d3994726249fd1c77377c1d8534f107phoglund@webrtc.org unsigned int height) { 495dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org frame_drop_detector_->ReportFrameState( 505dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org FrameDropDetector::kCreated, 519d10769e109601915022fea44ec392645c3b0704wu@webrtc.org timestamp, 525dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org webrtc::TickTime::MicrosecondTimestamp()); 535600f6e86d3994726249fd1c77377c1d8534f107phoglund@webrtc.org return webrtc::ExternalRendererEffectFilter::Transform( 549d10769e109601915022fea44ec392645c3b0704wu@webrtc.org size, frame_buffer, ntp_time_ms, timestamp, width, height); 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private: 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FrameDropDetector* frame_drop_detector_; 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Tracks which frames are sent in external transport on the local side 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// and reports them to the FrameDropDetector class. 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass FrameSentCallback : public SendFrameCallback { 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public: 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org explicit FrameSentCallback(FrameDropDetector* frame_drop_detector) 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : frame_drop_detector_(frame_drop_detector) {} 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org virtual ~FrameSentCallback() {} 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org virtual void FrameSent(unsigned int rtp_timestamp) { 685dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org frame_drop_detector_->ReportFrameState( 695dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org FrameDropDetector::kSent, 705dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org rtp_timestamp, 715dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org webrtc::TickTime::MicrosecondTimestamp()); 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private: 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FrameDropDetector* frame_drop_detector_; 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Tracks which frames are received in external transport on the remote side 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// and reports them to the FrameDropDetector class. 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass FrameReceivedCallback : public ReceiveFrameCallback { 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public: 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org explicit FrameReceivedCallback(FrameDropDetector* frame_drop_detector) 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : frame_drop_detector_(frame_drop_detector) {} 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org virtual ~FrameReceivedCallback() {} 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org virtual void FrameReceived(unsigned int rtp_timestamp) { 865dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org frame_drop_detector_->ReportFrameState( 875dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org FrameDropDetector::kReceived, 885dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org rtp_timestamp, 895dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org webrtc::TickTime::MicrosecondTimestamp()); 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private: 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FrameDropDetector* frame_drop_detector_; 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Tracks when frames are decoded on the remote side (received from the 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// jitter buffer) and reports them to the FrameDropDetector class. 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass DecodedTimestampEffectFilter : public webrtc::ViEEffectFilter { 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public: 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org explicit DecodedTimestampEffectFilter(FrameDropDetector* frame_drop_detector) 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : frame_drop_detector_(frame_drop_detector) {} 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org virtual ~DecodedTimestampEffectFilter() {} 1039d10769e109601915022fea44ec392645c3b0704wu@webrtc.org virtual int Transform(int size, 1049d10769e109601915022fea44ec392645c3b0704wu@webrtc.org unsigned char* frame_buffer, 1059d10769e109601915022fea44ec392645c3b0704wu@webrtc.org int64_t ntp_time_ms, 1069d10769e109601915022fea44ec392645c3b0704wu@webrtc.org unsigned int timestamp, 1079d10769e109601915022fea44ec392645c3b0704wu@webrtc.org unsigned int width, 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned int height) { 1095dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org frame_drop_detector_->ReportFrameState( 1105dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org FrameDropDetector::kDecoded, 1119d10769e109601915022fea44ec392645c3b0704wu@webrtc.org timestamp, 1125dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org webrtc::TickTime::MicrosecondTimestamp()); 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private: 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FrameDropDetector* frame_drop_detector_; 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 120fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.orgclass Statistics { 121fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org public: 122fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org Statistics() : sum_(0.0f), sum_squared_(0.0f), count_(0) {}; 123fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org 124fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org void AddSample(float sample) { 125fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org sum_ += sample; 126fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org sum_squared_ += sample * sample; 127fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org ++count_; 128fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org } 129fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org 130fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org float Mean() { 131fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org if (count_ == 0) 132fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org return -1.0f; 133fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org return sum_ / count_; 134fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org } 135fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org 136fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org float Variance() { 137fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org if (count_ == 0) 138fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org return -1.0f; 139fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org return sum_squared_ / count_ - Mean() * Mean(); 140fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org } 141fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org 142fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org std::string AsString() { 143fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org std::stringstream ss; 144fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org ss << (Mean() >= 0 ? Mean() : -1) << ", " << 145fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org (Variance() >= 0 ? sqrt(Variance()) : -1); 146fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org return ss.str(); 147fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org } 148fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org 149fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org private: 150fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org float sum_; 151fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org float sum_squared_; 152fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org int count_; 153fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org}; 154fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid TestFullStack(const TbInterfaces& interfaces, 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int capture_id, 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int video_channel, 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int width, 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int height, 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int bit_rate_kbps, 161137ed6cceec64fbed8ac72fcbbf44b6e2bb15fa5stefan@webrtc.org const NetworkParameters& network, 162e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org FrameDropDetector* frame_drop_detector, 163e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org ViEToFileRenderer* remote_file_renderer, 164e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org ViEToFileRenderer* local_file_renderer) { 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::VideoEngine *video_engine_interface = interfaces.video_engine; 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::ViEBase *base_interface = interfaces.base; 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::ViECapture *capture_interface = interfaces.capture; 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::ViERender *render_interface = interfaces.render; 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::ViECodec *codec_interface = interfaces.codec; 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::ViENetwork *network_interface = interfaces.network; 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // *************************************************************** 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Engine ready. Begin testing class 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // *************************************************************** 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::VideoCodec video_codec; 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(&video_codec, 0, sizeof (webrtc::VideoCodec)); 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set up all receive codecs. This basically setup the codec interface 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // to be able to recognize all receive codecs based on payload type. 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int idx = 0; idx < codec_interface->NumberOfCodecs(); idx++) { 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, codec_interface->GetCodec(idx, video_codec)); 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SetSuitableResolution(&video_codec, width, height); 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, codec_interface->SetReceiveCodec(video_channel, video_codec)); 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Configure External transport to simulate network interference: 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org TbExternalTransport external_transport(*interfaces.network, video_channel, 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org NULL); 190137ed6cceec64fbed8ac72fcbbf44b6e2bb15fa5stefan@webrtc.org external_transport.SetNetworkParameters(network); 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FrameSentCallback frame_sent_callback(frame_drop_detector); 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FrameReceivedCallback frame_received_callback(frame_drop_detector); 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org external_transport.RegisterSendFrameCallback(&frame_sent_callback); 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org external_transport.RegisterReceiveFrameCallback(&frame_received_callback); 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, network_interface->RegisterSendTransport(video_channel, 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org external_transport)); 198e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org RenderToFile(interfaces.render, video_channel, remote_file_renderer); 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, base_interface->StartReceive(video_channel)); 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Setup only the VP8 codec, which is what we'll use. 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::VideoCodec codec; 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(FindSpecificCodec(webrtc::kVideoCodecVP8, codec_interface, 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &codec)); 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org codec.startBitrate = bit_rate_kbps; 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org codec.maxBitrate = bit_rate_kbps; 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org codec.width = width; 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org codec.height = height; 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, codec_interface->SetSendCodec(video_channel, codec)); 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::ViEImageProcess *image_process = 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::ViEImageProcess::GetInterface(video_engine_interface); 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(image_process); 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 215e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org // Setup the effect filters. 216e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org // Local rendering at the send-side is done in an effect filter to avoid 217e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org // synchronization issues with the remote renderer. 2185600f6e86d3994726249fd1c77377c1d8534f107phoglund@webrtc.org LocalRendererEffectFilter local_renderer_filter(local_file_renderer, 2195600f6e86d3994726249fd1c77377c1d8534f107phoglund@webrtc.org frame_drop_detector); 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, image_process->RegisterSendEffectFilter(video_channel, 221e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org local_renderer_filter)); 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org DecodedTimestampEffectFilter decode_filter(frame_drop_detector); 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, image_process->RegisterRenderEffectFilter(video_channel, 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org decode_filter)); 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Send video. 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, base_interface->StartSend(video_channel)); 2273b7da1e4adc84f84f1896f91d697d43e7015fdf9asapersson@webrtc.org AutoTestSleep(kAutoTestFullStackSleepTimeMs); 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("Done!"); 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // *************************************************************** 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Testing finished. Tear down Video Engine 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // *************************************************************** 234e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org EXPECT_EQ(0, capture_interface->DisconnectCaptureDevice(video_channel)); 235e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org 236137ed6cceec64fbed8ac72fcbbf44b6e2bb15fa5stefan@webrtc.org const int one_way_delay_99_percentile = network.mean_one_way_delay + 237137ed6cceec64fbed8ac72fcbbf44b6e2bb15fa5stefan@webrtc.org 3 * network.std_dev_one_way_delay; 238137ed6cceec64fbed8ac72fcbbf44b6e2bb15fa5stefan@webrtc.org 239e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org // Wait for the last packet to arrive before we tear down the receiver. 240137ed6cceec64fbed8ac72fcbbf44b6e2bb15fa5stefan@webrtc.org AutoTestSleep(2 * one_way_delay_99_percentile); 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, base_interface->StopSend(video_channel)); 242e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org while (!external_transport.EmptyQueue()) { 243137ed6cceec64fbed8ac72fcbbf44b6e2bb15fa5stefan@webrtc.org AutoTestSleep(one_way_delay_99_percentile); 244e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org } 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, base_interface->StopReceive(video_channel)); 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, network_interface->DeregisterSendTransport(video_channel)); 247e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org // Wait for the last frame to be decoded and rendered. There is no guarantee 248e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org // this wait time will be long enough. Ideally we would wait for at least one 249e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org // "receive-side delay", which is what the video coding module calculates 250e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org // based on network statistics etc. We don't have access to that value here. 251e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org AutoTestSleep(kWaitTimeForFinalDecodeMs); 252e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org // Must stop the frame drop detectors in the right order to avoid getting 253e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org // frames which for instance are rendered but not decoded. 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, render_interface->StopRender(video_channel)); 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, render_interface->RemoveRenderer(video_channel)); 256e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org EXPECT_EQ(0, image_process->DeregisterRenderEffectFilter(video_channel)); 257e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org EXPECT_EQ(0, image_process->DeregisterSendEffectFilter(video_channel)); 258e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org image_process->Release(); 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, base_interface->DeleteChannel(video_channel)); 260e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org 261e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org // Collect transport statistics. 26267879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org int32_t num_rtp_packets = 0; 26367879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org int32_t num_dropped_packets = 0; 26467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org int32_t num_rtcp_packets = 0; 265eef4fd5c2263a5d9594c076c765abfe1e34b85f8stefan@webrtc.org std::map<uint8_t, int> packet_counters; 266e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org external_transport.GetStats(num_rtp_packets, num_dropped_packets, 267eef4fd5c2263a5d9594c076c765abfe1e34b85f8stefan@webrtc.org num_rtcp_packets, &packet_counters); 268e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org ViETest::Log("RTP packets : %5d", num_rtp_packets); 269e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org ViETest::Log("Dropped packets: %5d", num_dropped_packets); 270e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org ViETest::Log("RTCP packets : %5d", num_rtcp_packets); 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid FixOutputFileForComparison(const std::string& output_file, 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int frame_length_in_bytes, 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const std::vector<Frame*>& frames) { 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::test::FrameReaderImpl frame_reader(output_file, 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_length_in_bytes); 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const std::string temp_file = output_file + ".fixed"; 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::test::FrameWriterImpl frame_writer(temp_file, frame_length_in_bytes); 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_reader.Init(); 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_writer.Init(); 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ASSERT_FALSE(frames.front()->dropped_at_render) << "It should not be " 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "possible to drop the first frame. Both because we don't have anything " 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "useful to fill that gap with and it is impossible to detect it without " 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "any previous timestamps to compare with."; 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 28867879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint8_t* last_frame_data = new uint8_t[frame_length_in_bytes]; 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Process the file and write frame duplicates for all dropped frames. 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (std::vector<Frame*>::const_iterator it = frames.begin(); 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org it != frames.end(); ++it) { 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((*it)->dropped_at_render) { 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Write the previous frame to the output file: 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(frame_writer.WriteFrame(last_frame_data)); 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(frame_reader.ReadFrame(last_frame_data)); 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(frame_writer.WriteFrame(last_frame_data)); 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete[] last_frame_data; 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_reader.Close(); 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_writer.Close(); 3043f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org ASSERT_EQ(0, remove(output_file.c_str())); 3053f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org ASSERT_EQ(0, rename(temp_file.c_str(), output_file.c_str())); 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3085dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.orgvoid FrameDropDetector::ReportFrameState(State state, unsigned int timestamp, 3095dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org int64_t report_time_us) { 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dirty_ = true; 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (state) { 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kCreated: { 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int number = created_frames_vector_.size(); 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Frame* frame = new Frame(number, timestamp); 3155dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org frame->created_timestamp_in_us_ = report_time_us; 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org created_frames_vector_.push_back(frame); 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org created_frames_[timestamp] = frame; 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_created_frames_++; 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kSent: 3225dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org sent_frames_[timestamp] = report_time_us; 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (timestamp_diff_ == 0) { 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // When the first created frame arrives we calculate the fixed 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // difference between the timestamps of the frames entering and leaving 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // the encoder. This diff is used to identify the frames from the 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // created_frames_ map. 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org timestamp_diff_ = 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org timestamp - created_frames_vector_.front()->frame_timestamp_; 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_sent_frames_++; 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kReceived: 3345dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org received_frames_[timestamp] = report_time_us; 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_received_frames_++; 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kDecoded: 3385dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org decoded_frames_[timestamp] = report_time_us; 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_decoded_frames_++; 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kRendered: 3425dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org rendered_frames_[timestamp] = report_time_us; 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_rendered_frames_++; 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid FrameDropDetector::CalculateResults() { 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Fill in all fields of the Frame objects in the created_frames_ map. 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Iterate over the maps from converted timestamps to the arrival timestamps. 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::map<unsigned int, int64_t>::const_iterator it; 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (it = sent_frames_.begin(); it != sent_frames_.end(); ++it) { 353e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org unsigned int created_timestamp = it->first - timestamp_diff_; 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org created_frames_[created_timestamp]->sent_timestamp_in_us_ = it->second; 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (it = received_frames_.begin(); it != received_frames_.end(); ++it) { 357e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org unsigned int created_timestamp = it->first - timestamp_diff_; 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org created_frames_[created_timestamp]->received_timestamp_in_us_ = it->second; 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (it = decoded_frames_.begin(); it != decoded_frames_.end(); ++it) { 361e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org unsigned int created_timestamp = it->first - timestamp_diff_; 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org created_frames_[created_timestamp]->decoded_timestamp_in_us_ =it->second; 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (it = rendered_frames_.begin(); it != rendered_frames_.end(); ++it) { 365e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org unsigned int created_timestamp = it->first - timestamp_diff_; 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org created_frames_[created_timestamp]->rendered_timestamp_in_us_ = it->second; 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Find out where the frames were not present in the different states. 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dropped_frames_at_send_ = 0; 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dropped_frames_at_receive_ = 0; 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dropped_frames_at_decode_ = 0; 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dropped_frames_at_render_ = 0; 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (std::vector<Frame*>::const_iterator it = created_frames_vector_.begin(); 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org it != created_frames_vector_.end(); ++it) { 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoded_timestamp = (*it)->frame_timestamp_ + timestamp_diff_; 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (sent_frames_.find(encoded_timestamp) == sent_frames_.end()) { 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->dropped_at_send = true; 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dropped_frames_at_send_++; 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (received_frames_.find(encoded_timestamp) == received_frames_.end()) { 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->dropped_at_receive = true; 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dropped_frames_at_receive_++; 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (decoded_frames_.find(encoded_timestamp) == decoded_frames_.end()) { 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->dropped_at_decode = true; 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dropped_frames_at_decode_++; 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rendered_frames_.find(encoded_timestamp) == rendered_frames_.end()) { 389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->dropped_at_render = true; 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dropped_frames_at_render_++; 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dirty_ = false; 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 396fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.orgvoid FrameDropDetector::PrintReport(const std::string& test_label) { 397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(!dirty_); 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("Frame Drop Detector report:"); 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Created frames: %ld", created_frames_.size()); 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Sent frames: %ld", sent_frames_.size()); 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Received frames: %ld", received_frames_.size()); 402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Decoded frames: %ld", decoded_frames_.size()); 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Rendered frames: %ld", rendered_frames_.size()); 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Display all frames and stats for them: 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org long last_created = 0; 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org long last_sent = 0; 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org long last_received = 0; 409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org long last_decoded = 0; 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org long last_rendered = 0; 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("\nDeltas between sent frames and drop status:"); 412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("Unit: Microseconds"); 413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("Frame Created Sent Received Decoded Rendered " 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Dropped at Dropped at Dropped at Dropped at"); 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" nbr delta delta delta delta delta " 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " Send? Receive? Decode? Render?"); 417eaa05c8e5401589db411b3e129c59dc976978472stefan@webrtc.org Statistics rendering_stats; 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (std::vector<Frame*>::const_iterator it = created_frames_vector_.begin(); 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org it != created_frames_vector_.end(); ++it) { 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int created_delta = 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>((*it)->created_timestamp_in_us_ - last_created); 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int sent_delta = (*it)->dropped_at_send ? -1 : 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>((*it)->sent_timestamp_in_us_ - last_sent); 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int received_delta = (*it)->dropped_at_receive ? -1 : 425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>((*it)->received_timestamp_in_us_ - last_received); 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int decoded_delta = (*it)->dropped_at_decode ? -1 : 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>((*it)->decoded_timestamp_in_us_ - last_decoded); 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int rendered_delta = (*it)->dropped_at_render ? -1 : 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>((*it)->rendered_timestamp_in_us_ - last_rendered); 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set values to -1 for the first frame: 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((*it)->number_ == 0) { 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org created_delta = -1; 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sent_delta = -1; 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org received_delta = -1; 436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org decoded_delta = -1; 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rendered_delta = -1; 438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("%5d %8d %8d %8d %8d %8d %10s %10s %10s %10s", 440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->number_, 441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org created_delta, 442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sent_delta, 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org received_delta, 444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org decoded_delta, 445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rendered_delta, 446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->dropped_at_send ? "DROPPED" : " ", 447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->dropped_at_receive ? "DROPPED" : " ", 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->dropped_at_decode ? "DROPPED" : " ", 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->dropped_at_render ? "DROPPED" : " "); 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_created = (*it)->created_timestamp_in_us_; 451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!(*it)->dropped_at_send) { 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_sent = (*it)->sent_timestamp_in_us_; 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!(*it)->dropped_at_receive) { 455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_received = (*it)->received_timestamp_in_us_; 456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!(*it)->dropped_at_decode) { 458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_decoded = (*it)->decoded_timestamp_in_us_; 459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!(*it)->dropped_at_render) { 461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_rendered = (*it)->rendered_timestamp_in_us_; 462eaa05c8e5401589db411b3e129c59dc976978472stefan@webrtc.org rendering_stats.AddSample(rendered_delta / 1000.0f); 463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("\nLatency between states (-1 means N/A because of drop):"); 466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("Unit: Microseconds"); 467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("Frame Created Sent Received Decoded Total " 468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " Total"); 469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" nbr ->Sent ->Received ->Decoded ->Rendered latency " 470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " latency"); 471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" (incl network)" 472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "(excl network)"); 473fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org Statistics latency_incl_network_stats; 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (std::vector<Frame*>::const_iterator it = created_frames_vector_.begin(); 475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org it != created_frames_vector_.end(); ++it) { 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int created_to_sent = (*it)->dropped_at_send ? -1 : 477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>((*it)->sent_timestamp_in_us_ - 478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->created_timestamp_in_us_); 479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int sent_to_received = (*it)->dropped_at_receive ? -1 : 480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>((*it)->received_timestamp_in_us_ - 481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->sent_timestamp_in_us_); 482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int received_to_decoded = (*it)->dropped_at_decode ? -1 : 483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>((*it)->decoded_timestamp_in_us_ - 484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->received_timestamp_in_us_); 485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int decoded_to_render = (*it)->dropped_at_render ? -1 : 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>((*it)->rendered_timestamp_in_us_ - 487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->decoded_timestamp_in_us_); 488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int total_latency_incl_network = (*it)->dropped_at_render ? -1 : 489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>((*it)->rendered_timestamp_in_us_ - 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->created_timestamp_in_us_); 491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int total_latency_excl_network = (*it)->dropped_at_render ? -1 : 492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>((*it)->rendered_timestamp_in_us_ - 493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->created_timestamp_in_us_ - sent_to_received); 494fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org if (total_latency_incl_network >= 0) 495fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org latency_incl_network_stats.AddSample(total_latency_incl_network / 496fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org 1000.0f); 497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("%5d %9d %9d %9d %9d %12d %12d", 498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->number_, 499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org created_to_sent, 500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sent_to_received, 501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org received_to_decoded, 502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org decoded_to_render, 503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org total_latency_incl_network, 504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org total_latency_excl_network); 505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 506fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org 5076b04e5488d1b46fe1e12b6443b5238bfa7a13161phoglund@webrtc.org // Plot all measurements in the same graph since they share the same value 5086b04e5488d1b46fe1e12b6443b5238bfa7a13161phoglund@webrtc.org // range. 509fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org webrtc::test::PrintResultMeanAndError( 5106b04e5488d1b46fe1e12b6443b5238bfa7a13161phoglund@webrtc.org "total_delay_incl_network", "", test_label, 511fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org latency_incl_network_stats.AsString(), "ms", false); 512eaa05c8e5401589db411b3e129c59dc976978472stefan@webrtc.org webrtc::test::PrintResultMeanAndError( 5136b04e5488d1b46fe1e12b6443b5238bfa7a13161phoglund@webrtc.org "time_between_rendered_frames", "", test_label, 514eaa05c8e5401589db411b3e129c59dc976978472stefan@webrtc.org rendering_stats.AsString(), "ms", false); 515eaa05c8e5401589db411b3e129c59dc976978472stefan@webrtc.org 516fb2953b8f5d77b0e0f85fe11f8ae249f3bbbeafbstefan@webrtc.org 517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Find and print the dropped frames. 518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("\nTotal # dropped frames at:"); 519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Send : %d", dropped_frames_at_send_); 520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Receive: %d", dropped_frames_at_receive_); 521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Decode : %d", dropped_frames_at_decode_); 522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Render : %d", dropped_frames_at_render_); 523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid FrameDropDetector::PrintDebugDump() { 526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(!dirty_); 527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("\nPrintDebugDump: Frame objects:"); 528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("Frame FrTimeStamp Created Sent Received Decoded" 529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " Rendered "); 530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (std::vector<Frame*>::const_iterator it = created_frames_vector_.begin(); 531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org it != created_frames_vector_.end(); ++it) { 532e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org ViETest::Log("%5d %11u %11lld %11lld %11lld %11lld %11lld", 533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->number_, 534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->frame_timestamp_, 535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->created_timestamp_in_us_, 536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->sent_timestamp_in_us_, 537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->received_timestamp_in_us_, 538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->decoded_timestamp_in_us_, 539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (*it)->rendered_timestamp_in_us_); 540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::vector<int> mismatch_frame_num_list; 542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (std::vector<Frame*>::const_iterator it = created_frames_vector_.begin(); 543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org it != created_frames_vector_.end(); ++it) { 544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((*it)->dropped_at_render != (*it)->dropped_at_decode) { 545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mismatch_frame_num_list.push_back((*it)->number_); 546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (mismatch_frame_num_list.size() > 0) { 549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("\nDecoded/Rendered mismatches:"); 550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("Frame FrTimeStamp Created Sent Received " 551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Decoded Rendered "); 552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (std::vector<int>::const_iterator it = mismatch_frame_num_list.begin(); 553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org it != mismatch_frame_num_list.end(); ++it) { 554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Frame* frame = created_frames_vector_[*it]; 555e3ada29f8b0ea194ccd6b56faa9fdc5fb26c8bc5stefan@webrtc.org ViETest::Log("%5d %11u %11lld %11lld %11lld %11lld %11lld", 556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame->number_, 557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame->frame_timestamp_, 558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame->created_timestamp_in_us_, 559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame->sent_timestamp_in_us_, 560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame->received_timestamp_in_us_, 561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame->decoded_timestamp_in_us_, 562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame->rendered_timestamp_in_us_); 563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log("\nReportFrameState method invocations:"); 567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Created : %d", num_created_frames_); 568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Send : %d", num_sent_frames_); 569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Received: %d", num_received_frames_); 570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Decoded : %d", num_decoded_frames_); 571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViETest::Log(" Rendered: %d", num_rendered_frames_); 572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgconst std::vector<Frame*>& FrameDropDetector::GetAllFrames() { 575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(!dirty_); 576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return created_frames_vector_; 577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint FrameDropDetector::GetNumberOfFramesDroppedAt(State state) { 580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(!dirty_); 581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (state) { 582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kSent: 583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return dropped_frames_at_send_; 584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kReceived: 585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return dropped_frames_at_receive_; 586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kDecoded: 587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return dropped_frames_at_decode_; 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kRendered: 589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return dropped_frames_at_render_; 590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint FrameDropMonitoringRemoteFileRenderer::DeliverFrame( 596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned char *buffer, int buffer_size, uint32_t time_stamp, 5979d10769e109601915022fea44ec392645c3b0704wu@webrtc.org int64_t ntp_time_ms, int64_t render_time, void* /*handle*/) { 5985dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org // |render_time| provides the ideal render time for this frame. If that time 5995dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org // has already passed we will render it immediately. 6005dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org int64_t report_render_time_us = render_time * 1000; 6015dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org int64_t time_now_us = webrtc::TickTime::MicrosecondTimestamp(); 6025dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org if (render_time < (time_now_us + 500) / 1000) { 6035dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org report_render_time_us = time_now_us; 6045dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org } 6055dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org // Register that this frame has been rendered. 606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_drop_detector_->ReportFrameState(FrameDropDetector::kRendered, 6075dee0551c0a2d86cf524e80c033936d3827a20c6stefan@webrtc.org time_stamp, report_render_time_us); 608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return ViEToFileRenderer::DeliverFrame(buffer, buffer_size, 6099d10769e109601915022fea44ec392645c3b0704wu@webrtc.org time_stamp, ntp_time_ms, 6109d10769e109601915022fea44ec392645c3b0704wu@webrtc.org render_time, NULL); 611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint FrameDropMonitoringRemoteFileRenderer::FrameSizeChange( 614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned int width, unsigned int height, unsigned int number_of_streams) { 615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return ViEToFileRenderer::FrameSizeChange(width, height, number_of_streams); 616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 617