tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CaptureQualityController.java (4128B)


      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.widget.SeekBar;
     14 import android.widget.TextView;
     15 import java.util.Arrays;
     16 import java.util.Collections;
     17 import java.util.Comparator;
     18 import java.util.List;
     19 import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
     20 
     21 /**
     22 * Control capture format based on a seekbar listener.
     23 */
     24 public class CaptureQualityController implements SeekBar.OnSeekBarChangeListener {
     25  private final List<CaptureFormat> formats =
     26      Arrays.asList(new CaptureFormat(1280, 720, 0, 30000), new CaptureFormat(960, 540, 0, 30000),
     27          new CaptureFormat(640, 480, 0, 30000), new CaptureFormat(480, 360, 0, 30000),
     28          new CaptureFormat(320, 240, 0, 30000), new CaptureFormat(256, 144, 0, 30000));
     29  // Prioritize framerate below this threshold and resolution above the threshold.
     30  private static final int FRAMERATE_THRESHOLD = 15;
     31  private TextView captureFormatText;
     32  private CallFragment.OnCallEvents callEvents;
     33  private int width;
     34  private int height;
     35  private int framerate;
     36  private double targetBandwidth;
     37 
     38  public CaptureQualityController(
     39      TextView captureFormatText, CallFragment.OnCallEvents callEvents) {
     40    this.captureFormatText = captureFormatText;
     41    this.callEvents = callEvents;
     42  }
     43 
     44  private final Comparator<CaptureFormat> compareFormats = new Comparator<CaptureFormat>() {
     45    @Override
     46    public int compare(CaptureFormat first, CaptureFormat second) {
     47      int firstFps = calculateFramerate(targetBandwidth, first);
     48      int secondFps = calculateFramerate(targetBandwidth, second);
     49 
     50      if ((firstFps >= FRAMERATE_THRESHOLD && secondFps >= FRAMERATE_THRESHOLD)
     51          || firstFps == secondFps) {
     52        // Compare resolution.
     53        return first.width * first.height - second.width * second.height;
     54      } else {
     55        // Compare fps.
     56        return firstFps - secondFps;
     57      }
     58    }
     59  };
     60 
     61  @Override
     62  public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
     63    if (progress == 0) {
     64      width = 0;
     65      height = 0;
     66      framerate = 0;
     67      captureFormatText.setText(R.string.muted);
     68      return;
     69    }
     70 
     71    // Extract max bandwidth (in millipixels / second).
     72    long maxCaptureBandwidth = java.lang.Long.MIN_VALUE;
     73    for (CaptureFormat format : formats) {
     74      maxCaptureBandwidth =
     75          Math.max(maxCaptureBandwidth, (long) format.width * format.height * format.framerate.max);
     76    }
     77 
     78    // Fraction between 0 and 1.
     79    double bandwidthFraction = (double) progress / 100.0;
     80    // Make a log-scale transformation, still between 0 and 1.
     81    final double kExpConstant = 3.0;
     82    bandwidthFraction =
     83        (Math.exp(kExpConstant * bandwidthFraction) - 1) / (Math.exp(kExpConstant) - 1);
     84    targetBandwidth = bandwidthFraction * maxCaptureBandwidth;
     85 
     86    // Choose the best format given a target bandwidth.
     87    final CaptureFormat bestFormat = Collections.max(formats, compareFormats);
     88    width = bestFormat.width;
     89    height = bestFormat.height;
     90    framerate = calculateFramerate(targetBandwidth, bestFormat);
     91    captureFormatText.setText(
     92        String.format(captureFormatText.getContext().getString(R.string.format_description), width,
     93            height, framerate));
     94  }
     95 
     96  @Override
     97  public void onStartTrackingTouch(SeekBar seekBar) {}
     98 
     99  @Override
    100  public void onStopTrackingTouch(SeekBar seekBar) {
    101    callEvents.onCaptureFormatChange(width, height, framerate);
    102  }
    103 
    104  // Return the highest frame rate possible based on bandwidth and format.
    105  private int calculateFramerate(double bandwidth, CaptureFormat format) {
    106    return (int) Math.round(
    107        Math.min(format.framerate.max, (int) Math.round(bandwidth / (format.width * format.height)))
    108        / 1000.0);
    109  }
    110 }