| Index: webrtc/examples/androidapp/src/org/appspot/apprtc/CaptureQualityController.java
|
| diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/CaptureQualityController.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/CaptureQualityController.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6886e6eeac1774743c8f9a16441611bd75a29735
|
| --- /dev/null
|
| +++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/CaptureQualityController.java
|
| @@ -0,0 +1,112 @@
|
| +/*
|
| + * 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.widget.SeekBar;
|
| +import android.widget.TextView;
|
| +
|
| +import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
|
| +
|
| +import java.util.Arrays;
|
| +import java.util.Collections;
|
| +import java.util.Comparator;
|
| +import java.util.List;
|
| +
|
| +/**
|
| + * Control capture format based on a seekbar listener.
|
| + */
|
| +public class CaptureQualityController implements SeekBar.OnSeekBarChangeListener {
|
| + private final List<CaptureFormat> formats = Arrays.asList(
|
| + new CaptureFormat(1280, 720, 0, 30000),
|
| + new CaptureFormat(640, 480, 0, 30000),
|
| + new CaptureFormat(320, 240, 0, 30000),
|
| + new CaptureFormat(256, 144, 0, 30000));
|
| + // Prioritize framerate below this threshold and resolution above the threshold.
|
| + private static final int FRAMERATE_THRESHOLD = 15;
|
| + private TextView captureFormatText;
|
| + private CallFragment.OnCallEvents callEvents;
|
| + private int width = 0;
|
| + private int height = 0;
|
| + private int framerate = 0;
|
| + private double targetBandwidth = 0;
|
| +
|
| + public CaptureQualityController(
|
| + TextView captureFormatText, CallFragment.OnCallEvents callEvents) {
|
| + this.captureFormatText = captureFormatText;
|
| + this.callEvents = callEvents;
|
| + }
|
| +
|
| + private final Comparator<CaptureFormat> compareFormats = new Comparator<CaptureFormat>() {
|
| + @Override
|
| + public int compare(CaptureFormat first, CaptureFormat second) {
|
| + int firstFps = calculateFramerate(targetBandwidth, first);
|
| + int secondFps = calculateFramerate(targetBandwidth, second);
|
| +
|
| + if (firstFps >= FRAMERATE_THRESHOLD && secondFps >= FRAMERATE_THRESHOLD
|
| + || firstFps == secondFps) {
|
| + // Compare resolution.
|
| + return first.width * first.height - second.width * second.height;
|
| + } else {
|
| + // Compare fps.
|
| + return firstFps - secondFps;
|
| + }
|
| + }
|
| + };
|
| +
|
| + @Override
|
| + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
| + if (progress == 0) {
|
| + width = 0;
|
| + height = 0;
|
| + framerate = 0;
|
| + captureFormatText.setText("Muted");
|
| + return;
|
| + }
|
| +
|
| + // Extract max bandwidth (in millipixels / second).
|
| + long maxCaptureBandwidth = java.lang.Long.MIN_VALUE;
|
| + for (CaptureFormat format : formats) {
|
| + maxCaptureBandwidth = Math.max(maxCaptureBandwidth,
|
| + (long) format.width * format.height * format.maxFramerate);
|
| + }
|
| +
|
| + // Fraction between 0 and 1.
|
| + double bandwidthFraction = (double) progress / 100.0;
|
| + // Make a log-scale transformation, still between 0 and 1.
|
| + final double kExpConstant = 3.0;
|
| + bandwidthFraction =
|
| + (Math.exp(kExpConstant * bandwidthFraction) - 1) / (Math.exp(kExpConstant) - 1);
|
| + targetBandwidth = bandwidthFraction * maxCaptureBandwidth;
|
| +
|
| + // Choose the best format given a target bandwidth.
|
| + final CaptureFormat bestFormat = Collections.max(formats, compareFormats);
|
| + width = bestFormat.width;
|
| + height = bestFormat.height;
|
| + framerate = calculateFramerate(targetBandwidth, bestFormat);
|
| + captureFormatText.setText(width + "x" + height + " @ " + framerate + "fps");
|
| + }
|
| +
|
| + @Override
|
| + public void onStartTrackingTouch(SeekBar seekBar) {
|
| + }
|
| +
|
| + @Override
|
| + public void onStopTrackingTouch(SeekBar seekBar) {
|
| + callEvents.onCaptureFormatChange(width, height, framerate);
|
| + }
|
| +
|
| + // Return the highest frame rate possible based on bandwidth and format.
|
| + private int calculateFramerate(double bandwidth, CaptureFormat format) {
|
| + return (int) Math.round(Math.min(format.maxFramerate,
|
| + (int) Math.round(bandwidth / (format.width * format.height))) / 1000.0);
|
| + }
|
| +}
|
| +
|
|
|