Home | History | Annotate | Download | only in apprtc
      1 /*
      2  *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 package org.appspot.apprtc;
     12 
     13 import android.app.Fragment;
     14 import android.os.Bundle;
     15 import android.util.TypedValue;
     16 import android.view.LayoutInflater;
     17 import android.view.View;
     18 import android.view.ViewGroup;
     19 import android.widget.ImageButton;
     20 import android.widget.TextView;
     21 
     22 import org.webrtc.StatsReport;
     23 
     24 import java.util.HashMap;
     25 import java.util.Map;
     26 
     27 /**
     28  * Fragment for HUD statistics display.
     29  */
     30 public class HudFragment extends Fragment {
     31   private View controlView;
     32   private TextView encoderStatView;
     33   private TextView hudViewBwe;
     34   private TextView hudViewConnection;
     35   private TextView hudViewVideoSend;
     36   private TextView hudViewVideoRecv;
     37   private ImageButton toggleDebugButton;
     38   private boolean videoCallEnabled;
     39   private boolean displayHud;
     40   private volatile boolean isRunning;
     41   private final CpuMonitor cpuMonitor = new CpuMonitor();
     42 
     43   @Override
     44   public View onCreateView(LayoutInflater inflater, ViewGroup container,
     45       Bundle savedInstanceState) {
     46     controlView = inflater.inflate(R.layout.fragment_hud, container, false);
     47 
     48     // Create UI controls.
     49     encoderStatView = (TextView) controlView.findViewById(R.id.encoder_stat_call);
     50     hudViewBwe = (TextView) controlView.findViewById(R.id.hud_stat_bwe);
     51     hudViewConnection = (TextView) controlView.findViewById(R.id.hud_stat_connection);
     52     hudViewVideoSend = (TextView) controlView.findViewById(R.id.hud_stat_video_send);
     53     hudViewVideoRecv = (TextView) controlView.findViewById(R.id.hud_stat_video_recv);
     54     toggleDebugButton = (ImageButton) controlView.findViewById(R.id.button_toggle_debug);
     55 
     56     toggleDebugButton.setOnClickListener(new View.OnClickListener() {
     57       @Override
     58       public void onClick(View view) {
     59         if (displayHud) {
     60           int visibility = (hudViewBwe.getVisibility() == View.VISIBLE)
     61               ? View.INVISIBLE : View.VISIBLE;
     62           hudViewsSetProperties(visibility);
     63         }
     64       }
     65     });
     66 
     67     return controlView;
     68   }
     69 
     70   @Override
     71   public void onStart() {
     72     super.onStart();
     73 
     74     Bundle args = getArguments();
     75     if (args != null) {
     76       videoCallEnabled = args.getBoolean(CallActivity.EXTRA_VIDEO_CALL, true);
     77       displayHud = args.getBoolean(CallActivity.EXTRA_DISPLAY_HUD, false);
     78     }
     79     int visibility = displayHud ? View.VISIBLE : View.INVISIBLE;
     80     encoderStatView.setVisibility(visibility);
     81     toggleDebugButton.setVisibility(visibility);
     82     hudViewsSetProperties(View.INVISIBLE);
     83     isRunning = true;
     84   }
     85 
     86   @Override
     87   public void onStop() {
     88     isRunning = false;
     89     super.onStop();
     90   }
     91 
     92   private void hudViewsSetProperties(int visibility) {
     93     hudViewBwe.setVisibility(visibility);
     94     hudViewConnection.setVisibility(visibility);
     95     hudViewVideoSend.setVisibility(visibility);
     96     hudViewVideoRecv.setVisibility(visibility);
     97     hudViewBwe.setTextSize(TypedValue.COMPLEX_UNIT_PT, 5);
     98     hudViewConnection.setTextSize(TypedValue.COMPLEX_UNIT_PT, 5);
     99     hudViewVideoSend.setTextSize(TypedValue.COMPLEX_UNIT_PT, 5);
    100     hudViewVideoRecv.setTextSize(TypedValue.COMPLEX_UNIT_PT, 5);
    101   }
    102 
    103   private Map<String, String> getReportMap(StatsReport report) {
    104     Map<String, String> reportMap = new HashMap<String, String>();
    105     for (StatsReport.Value value : report.values) {
    106       reportMap.put(value.name, value.value);
    107     }
    108     return reportMap;
    109   }
    110 
    111   public void updateEncoderStatistics(final StatsReport[] reports) {
    112     if (!isRunning || !displayHud) {
    113       return;
    114     }
    115     StringBuilder encoderStat = new StringBuilder(128);
    116     StringBuilder bweStat = new StringBuilder();
    117     StringBuilder connectionStat = new StringBuilder();
    118     StringBuilder videoSendStat = new StringBuilder();
    119     StringBuilder videoRecvStat = new StringBuilder();
    120     String fps = null;
    121     String targetBitrate = null;
    122     String actualBitrate = null;
    123 
    124     for (StatsReport report : reports) {
    125       if (report.type.equals("ssrc") && report.id.contains("ssrc")
    126           && report.id.contains("send")) {
    127         // Send video statistics.
    128         Map<String, String> reportMap = getReportMap(report);
    129         String trackId = reportMap.get("googTrackId");
    130         if (trackId != null && trackId.contains(PeerConnectionClient.VIDEO_TRACK_ID)) {
    131           fps = reportMap.get("googFrameRateSent");
    132           videoSendStat.append(report.id).append("\n");
    133           for (StatsReport.Value value : report.values) {
    134             String name = value.name.replace("goog", "");
    135             videoSendStat.append(name).append("=").append(value.value).append("\n");
    136           }
    137         }
    138       } else if (report.type.equals("ssrc") && report.id.contains("ssrc")
    139           && report.id.contains("recv")) {
    140         // Receive video statistics.
    141         Map<String, String> reportMap = getReportMap(report);
    142         // Check if this stat is for video track.
    143         String frameWidth = reportMap.get("googFrameWidthReceived");
    144         if (frameWidth != null) {
    145           videoRecvStat.append(report.id).append("\n");
    146           for (StatsReport.Value value : report.values) {
    147             String name = value.name.replace("goog", "");
    148             videoRecvStat.append(name).append("=").append(value.value).append("\n");
    149           }
    150         }
    151       } else if (report.id.equals("bweforvideo")) {
    152         // BWE statistics.
    153         Map<String, String> reportMap = getReportMap(report);
    154         targetBitrate = reportMap.get("googTargetEncBitrate");
    155         actualBitrate = reportMap.get("googActualEncBitrate");
    156 
    157         bweStat.append(report.id).append("\n");
    158         for (StatsReport.Value value : report.values) {
    159           String name = value.name.replace("goog", "").replace("Available", "");
    160           bweStat.append(name).append("=").append(value.value).append("\n");
    161         }
    162       } else if (report.type.equals("googCandidatePair")) {
    163         // Connection statistics.
    164         Map<String, String> reportMap = getReportMap(report);
    165         String activeConnection = reportMap.get("googActiveConnection");
    166         if (activeConnection != null && activeConnection.equals("true")) {
    167           connectionStat.append(report.id).append("\n");
    168           for (StatsReport.Value value : report.values) {
    169             String name = value.name.replace("goog", "");
    170             connectionStat.append(name).append("=").append(value.value).append("\n");
    171           }
    172         }
    173       }
    174     }
    175     hudViewBwe.setText(bweStat.toString());
    176     hudViewConnection.setText(connectionStat.toString());
    177     hudViewVideoSend.setText(videoSendStat.toString());
    178     hudViewVideoRecv.setText(videoRecvStat.toString());
    179 
    180     if (videoCallEnabled) {
    181       if (fps != null) {
    182         encoderStat.append("Fps:  ").append(fps).append("\n");
    183       }
    184       if (targetBitrate != null) {
    185         encoderStat.append("Target BR: ").append(targetBitrate).append("\n");
    186       }
    187       if (actualBitrate != null) {
    188         encoderStat.append("Actual BR: ").append(actualBitrate).append("\n");
    189       }
    190     }
    191 
    192     if (cpuMonitor.sampleCpuUtilization()) {
    193       encoderStat.append("CPU%: ")
    194           .append(cpuMonitor.getCpuCurrent()).append("/")
    195           .append(cpuMonitor.getCpuAvg3()).append("/")
    196           .append(cpuMonitor.getCpuAvgAll());
    197     }
    198     encoderStatView.setText(encoderStat.toString());
    199   }
    200 }
    201