You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
302 lines
8.1 KiB
302 lines
8.1 KiB
/*
|
|
* UVCCamera
|
|
* library and sample to access to UVC web camera on non-rooted Android device
|
|
*
|
|
* Copyright (c) 2014-2017 saki t_saki@serenegiant.com
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* All files in the folder are under this Apache License, Version 2.0.
|
|
* Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder
|
|
* may have a different license, see the respective files.
|
|
*/
|
|
|
|
package com.serenegiant.usb;
|
|
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
|
|
import java.util.Locale;
|
|
|
|
public class Size implements Parcelable {
|
|
//
|
|
/**
|
|
* native側のuvc_raw_format_tの値, こっちは主にlibuvc用
|
|
* 9999 is still image
|
|
*/
|
|
public int type;
|
|
/**
|
|
* native側のraw_frame_tの値, androusb用,
|
|
* libuvcは対応していない
|
|
*/
|
|
public int frame_type;
|
|
public int index;
|
|
public int width;
|
|
public int height;
|
|
public int frameIntervalType;
|
|
public int frameIntervalIndex;
|
|
public int[] intervals;
|
|
// ここ以下はframeIntervalTypeとintervalsから#updateFrameRateで計算する
|
|
public float[] fps;
|
|
private String frameRates;
|
|
|
|
/**
|
|
* コンストラクタ
|
|
* @param _type native側のraw_format_tの値, ただし9999は静止画
|
|
* @param _frame_type native側のraw_frame_tの値
|
|
* @param _index
|
|
* @param _width
|
|
* @param _height
|
|
*/
|
|
public Size(final int _type, final int _frame_type, final int _index, final int _width, final int _height) {
|
|
type = _type;
|
|
frame_type = _frame_type;
|
|
index = _index;
|
|
width = _width;
|
|
height = _height;
|
|
frameIntervalType = -1;
|
|
frameIntervalIndex = 0;
|
|
intervals = null;
|
|
updateFrameRate();
|
|
}
|
|
|
|
/**
|
|
* コンストラクタ
|
|
* @param _type native側のraw_format_tの値, ただし9999は静止画
|
|
* @param _frame_type native側のraw_frame_tの値
|
|
* @param _index
|
|
* @param _width
|
|
* @param _height
|
|
* @param _min_intervals
|
|
* @param _max_intervals
|
|
*/
|
|
public Size(final int _type, final int _frame_type, final int _index, final int _width, final int _height, final int _min_intervals, final int _max_intervals, final int _step) {
|
|
type = _type;
|
|
frame_type = _frame_type;
|
|
index = _index;
|
|
width = _width;
|
|
height = _height;
|
|
frameIntervalType = 0;
|
|
frameIntervalIndex = 0;
|
|
intervals = new int[3];
|
|
intervals[0] = _min_intervals;
|
|
intervals[1] = _max_intervals;
|
|
intervals[2] = _step;
|
|
updateFrameRate();
|
|
}
|
|
|
|
/**
|
|
* コンストラクタ
|
|
* @param _type native側のraw_format_tの値, ただし9999は静止画
|
|
* @param _frame_type native側のraw_frame_tの値
|
|
* @param _index
|
|
* @param _width
|
|
* @param _height
|
|
* @param _intervals
|
|
*/
|
|
public Size(final int _type, final int _frame_type, final int _index, final int _width, final int _height, final int[] _intervals) {
|
|
type = _type;
|
|
frame_type = _frame_type;
|
|
index = _index;
|
|
width = _width;
|
|
height = _height;
|
|
final int n = _intervals != null ? _intervals.length : -1;
|
|
if (n > 0) {
|
|
frameIntervalType = n;
|
|
intervals = new int[n];
|
|
System.arraycopy(_intervals, 0, intervals, 0, n);
|
|
} else {
|
|
frameIntervalType = -1;
|
|
intervals = null;
|
|
}
|
|
frameIntervalIndex = 0;
|
|
updateFrameRate();
|
|
}
|
|
|
|
/**
|
|
* コピーコンストラクタ
|
|
* @param other
|
|
*/
|
|
public Size(final Size other) {
|
|
type = other.type;
|
|
frame_type = other.frame_type;
|
|
index = other.index;
|
|
width = other.width;
|
|
height = other.height;
|
|
frameIntervalType = other.frameIntervalType;
|
|
frameIntervalIndex = other.frameIntervalIndex;
|
|
final int n = other.intervals != null ? other.intervals.length : -1;
|
|
if (n > 0) {
|
|
intervals = new int[n];
|
|
System.arraycopy(other.intervals, 0, intervals, 0, n);
|
|
} else {
|
|
intervals = null;
|
|
}
|
|
updateFrameRate();
|
|
}
|
|
|
|
private Size(final Parcel source) {
|
|
// 読み取り順はwriteToParcelでの書き込み順と同じでないとダメ
|
|
type = source.readInt();
|
|
frame_type = source.readInt();
|
|
index = source.readInt();
|
|
width = source.readInt();
|
|
height = source.readInt();
|
|
frameIntervalType = source.readInt();
|
|
frameIntervalIndex = source.readInt();
|
|
if (frameIntervalType >= 0) {
|
|
if (frameIntervalType > 0) {
|
|
intervals = new int[frameIntervalType];
|
|
} else {
|
|
intervals = new int[3];
|
|
}
|
|
source.readIntArray(intervals);
|
|
} else {
|
|
intervals = null;
|
|
}
|
|
updateFrameRate();
|
|
}
|
|
|
|
public Size set(final Size other) {
|
|
if (other != null) {
|
|
type = other.type;
|
|
frame_type = other.frame_type;
|
|
index = other.index;
|
|
width = other.width;
|
|
height = other.height;
|
|
frameIntervalType = other.frameIntervalType;
|
|
frameIntervalIndex = other.frameIntervalIndex;
|
|
final int n = other.intervals != null ? other.intervals.length : -1;
|
|
if (n > 0) {
|
|
intervals = new int[n];
|
|
System.arraycopy(other.intervals, 0, intervals, 0, n);
|
|
} else {
|
|
intervals = null;
|
|
}
|
|
updateFrameRate();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public float getCurrentFrameRate() throws IllegalStateException {
|
|
final int n = fps != null ? fps.length : 0;
|
|
if ((frameIntervalIndex >= 0) && (frameIntervalIndex < n)) {
|
|
return fps[frameIntervalIndex];
|
|
}
|
|
throw new IllegalStateException("unknown frame rate or not ready");
|
|
}
|
|
|
|
public void setCurrentFrameRate(final float frameRate) {
|
|
// 一番近いのを選ぶ
|
|
int index = -1;
|
|
final int n = fps != null ? fps.length : 0;
|
|
for (int i = 0; i < n; i++) {
|
|
if (fps[i] <= frameRate) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
frameIntervalIndex = index;
|
|
}
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(final Parcel dest, final int flags) {
|
|
dest.writeInt(type);
|
|
dest.writeInt(frame_type);
|
|
dest.writeInt(index);
|
|
dest.writeInt(width);
|
|
dest.writeInt(height);
|
|
dest.writeInt(frameIntervalType);
|
|
dest.writeInt(frameIntervalIndex);
|
|
if (intervals != null) {
|
|
dest.writeIntArray(intervals);
|
|
}
|
|
}
|
|
|
|
public void updateFrameRate() {
|
|
final int n = frameIntervalType;
|
|
if (n > 0) {
|
|
fps = new float[n];
|
|
for (int i = 0; i < n; i++) {
|
|
final float _fps = fps[i] = 10000000.0f / intervals[i];
|
|
}
|
|
} else if (n == 0) {
|
|
try {
|
|
final int min = Math.min(intervals[0], intervals[1]);
|
|
final int max = Math.max(intervals[0], intervals[1]);
|
|
final int step = intervals[2];
|
|
if (step > 0) {
|
|
int m = 0;
|
|
for (int i = min; i <= max; i+= step) { m++; }
|
|
fps = new float[m];
|
|
m = 0;
|
|
for (int i = min; i <= max; i+= step) {
|
|
final float _fps = fps[m++] = 10000000.0f / i;
|
|
}
|
|
} else {
|
|
final float max_fps = 10000000.0f / min;
|
|
int m = 0;
|
|
for (float fps = 10000000.0f / min; fps <= max_fps; fps += 1.0f) { m++; }
|
|
fps = new float[m];
|
|
m = 0;
|
|
for (float fps = 10000000.0f / min; fps <= max_fps; fps += 1.0f) {
|
|
this.fps[m++] = fps;
|
|
}
|
|
}
|
|
} catch (final Exception e) {
|
|
// ignore, なんでかminとmaxが0になってるんちゃうかな
|
|
fps = null;
|
|
}
|
|
}
|
|
final int m = fps != null ? fps.length : 0;
|
|
final StringBuilder sb = new StringBuilder();
|
|
sb.append("[");
|
|
for (int i = 0; i < m; i++) {
|
|
sb.append(String.format(Locale.US, "%4.1f", fps[i]));
|
|
if (i < m-1) {
|
|
sb.append(",");
|
|
}
|
|
}
|
|
sb.append("]");
|
|
frameRates = sb.toString();
|
|
if (frameIntervalIndex > m) {
|
|
frameIntervalIndex = 0;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
float frame_rate = 0.0f;
|
|
try {
|
|
frame_rate = getCurrentFrameRate();
|
|
} catch (final Exception e) {
|
|
}
|
|
return String.format(Locale.US, "Size(%dx%d@%4.1f,type:%d,frame:%d,index:%d,%s)", width, height, frame_rate, type, frame_type, index, frameRates);
|
|
}
|
|
|
|
public static final Creator<Size> CREATOR = new Creator<Size>() {
|
|
@Override
|
|
public Size createFromParcel(final Parcel source) {
|
|
return new Size(source);
|
|
}
|
|
@Override
|
|
public Size[] newArray(final int size) {
|
|
return new Size[size];
|
|
}
|
|
};
|
|
}
|
|
|