/* * Copyright 2015 The WebRTC Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ package org.appspot.apprtc; import android.app.Fragment; import android.os.Bundle; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.TextView; import org.webrtc.StatsReport; import java.util.HashMap; import java.util.Map; /** * Fragment for HUD statistics display. */ public class HudFragment extends Fragment { private View controlView; private TextView encoderStatView; private TextView hudViewBwe; private TextView hudViewConnection; private TextView hudViewVideoSend; private TextView hudViewVideoRecv; private ImageButton toggleDebugButton; private boolean videoCallEnabled; private boolean displayHud; private volatile boolean isRunning; private final CpuMonitor cpuMonitor = new CpuMonitor(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { controlView = inflater.inflate(R.layout.fragment_hud, container, false); // Create UI controls. encoderStatView = (TextView) controlView.findViewById(R.id.encoder_stat_call); hudViewBwe = (TextView) controlView.findViewById(R.id.hud_stat_bwe); hudViewConnection = (TextView) controlView.findViewById(R.id.hud_stat_connection); hudViewVideoSend = (TextView) controlView.findViewById(R.id.hud_stat_video_send); hudViewVideoRecv = (TextView) controlView.findViewById(R.id.hud_stat_video_recv); toggleDebugButton = (ImageButton) controlView.findViewById(R.id.button_toggle_debug); toggleDebugButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (displayHud) { int visibility = (hudViewBwe.getVisibility() == View.VISIBLE) ? View.INVISIBLE : View.VISIBLE; hudViewsSetProperties(visibility); } } }); return controlView; } @Override public void onStart() { super.onStart(); Bundle args = getArguments(); if (args != null) { videoCallEnabled = args.getBoolean(CallActivity.EXTRA_VIDEO_CALL, true); displayHud = args.getBoolean(CallActivity.EXTRA_DISPLAY_HUD, false); } int visibility = displayHud ? View.VISIBLE : View.INVISIBLE; encoderStatView.setVisibility(visibility); toggleDebugButton.setVisibility(visibility); hudViewsSetProperties(View.INVISIBLE); isRunning = true; } @Override public void onStop() { isRunning = false; super.onStop(); } private void hudViewsSetProperties(int visibility) { hudViewBwe.setVisibility(visibility); hudViewConnection.setVisibility(visibility); hudViewVideoSend.setVisibility(visibility); hudViewVideoRecv.setVisibility(visibility); hudViewBwe.setTextSize(TypedValue.COMPLEX_UNIT_PT, 5); hudViewConnection.setTextSize(TypedValue.COMPLEX_UNIT_PT, 5); hudViewVideoSend.setTextSize(TypedValue.COMPLEX_UNIT_PT, 5); hudViewVideoRecv.setTextSize(TypedValue.COMPLEX_UNIT_PT, 5); } private Map getReportMap(StatsReport report) { Map reportMap = new HashMap(); for (StatsReport.Value value : report.values) { reportMap.put(value.name, value.value); } return reportMap; } public void updateEncoderStatistics(final StatsReport[] reports) { if (!isRunning || !displayHud) { return; } StringBuilder encoderStat = new StringBuilder(128); StringBuilder bweStat = new StringBuilder(); StringBuilder connectionStat = new StringBuilder(); StringBuilder videoSendStat = new StringBuilder(); StringBuilder videoRecvStat = new StringBuilder(); String fps = null; String targetBitrate = null; String actualBitrate = null; for (StatsReport report : reports) { if (report.type.equals("ssrc") && report.id.contains("ssrc") && report.id.contains("send")) { // Send video statistics. Map reportMap = getReportMap(report); String trackId = reportMap.get("googTrackId"); if (trackId != null && trackId.contains(PeerConnectionClient.VIDEO_TRACK_ID)) { fps = reportMap.get("googFrameRateSent"); videoSendStat.append(report.id).append("\n"); for (StatsReport.Value value : report.values) { String name = value.name.replace("goog", ""); videoSendStat.append(name).append("=").append(value.value).append("\n"); } } } else if (report.type.equals("ssrc") && report.id.contains("ssrc") && report.id.contains("recv")) { // Receive video statistics. Map reportMap = getReportMap(report); // Check if this stat is for video track. String frameWidth = reportMap.get("googFrameWidthReceived"); if (frameWidth != null) { videoRecvStat.append(report.id).append("\n"); for (StatsReport.Value value : report.values) { String name = value.name.replace("goog", ""); videoRecvStat.append(name).append("=").append(value.value).append("\n"); } } } else if (report.id.equals("bweforvideo")) { // BWE statistics. Map reportMap = getReportMap(report); targetBitrate = reportMap.get("googTargetEncBitrate"); actualBitrate = reportMap.get("googActualEncBitrate"); bweStat.append(report.id).append("\n"); for (StatsReport.Value value : report.values) { String name = value.name.replace("goog", "").replace("Available", ""); bweStat.append(name).append("=").append(value.value).append("\n"); } } else if (report.type.equals("googCandidatePair")) { // Connection statistics. Map reportMap = getReportMap(report); String activeConnection = reportMap.get("googActiveConnection"); if (activeConnection != null && activeConnection.equals("true")) { connectionStat.append(report.id).append("\n"); for (StatsReport.Value value : report.values) { String name = value.name.replace("goog", ""); connectionStat.append(name).append("=").append(value.value).append("\n"); } } } } hudViewBwe.setText(bweStat.toString()); hudViewConnection.setText(connectionStat.toString()); hudViewVideoSend.setText(videoSendStat.toString()); hudViewVideoRecv.setText(videoRecvStat.toString()); if (videoCallEnabled) { if (fps != null) { encoderStat.append("Fps: ").append(fps).append("\n"); } if (targetBitrate != null) { encoderStat.append("Target BR: ").append(targetBitrate).append("\n"); } if (actualBitrate != null) { encoderStat.append("Actual BR: ").append(actualBitrate).append("\n"); } } if (cpuMonitor.sampleCpuUtilization()) { encoderStat.append("CPU%: ") .append(cpuMonitor.getCpuCurrent()).append("/") .append(cpuMonitor.getCpuAvg3()).append("/") .append(cpuMonitor.getCpuAvgAll()); } encoderStatView.setText(encoderStat.toString()); } }