Get CamcorderProfile from incoming video size (#477)
parent
8b66d5b575
commit
0c7726d5c5
@ -0,0 +1,68 @@ |
|||||||
|
package com.otaliastudios.cameraview; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.media.CamcorderProfile; |
||||||
|
import android.os.Build; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Comparator; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
|
||||||
|
/** |
||||||
|
* Wraps the {@link android.media.CamcorderProfile} static utilities. |
||||||
|
*/ |
||||||
|
class CamcorderProfiles { |
||||||
|
|
||||||
|
@SuppressLint("UseSparseArrays") |
||||||
|
private static Map<Size, Integer> sizeToProfileMap = new HashMap<>(); |
||||||
|
|
||||||
|
static { |
||||||
|
sizeToProfileMap.put(new Size(176, 144), CamcorderProfile.QUALITY_QCIF); |
||||||
|
sizeToProfileMap.put(new Size(320, 240), CamcorderProfile.QUALITY_QVGA); |
||||||
|
sizeToProfileMap.put(new Size(352, 288), CamcorderProfile.QUALITY_CIF); |
||||||
|
sizeToProfileMap.put(new Size(720, 480), CamcorderProfile.QUALITY_480P); |
||||||
|
sizeToProfileMap.put(new Size(1280, 720), CamcorderProfile.QUALITY_720P); |
||||||
|
sizeToProfileMap.put(new Size(1920, 1080), CamcorderProfile.QUALITY_1080P); |
||||||
|
if (Build.VERSION.SDK_INT >= 21) { |
||||||
|
sizeToProfileMap.put(new Size(3840, 2160), CamcorderProfile.QUALITY_2160P); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a CamcorderProfile that's somewhat coherent with the target size, |
||||||
|
* to ensure we get acceptable video/audio parameters for MediaRecorders (most notably the bitrate). |
||||||
|
* |
||||||
|
* @param cameraId the camera id |
||||||
|
* @param targetSize the target video size |
||||||
|
* @return a profile |
||||||
|
*/ |
||||||
|
@NonNull |
||||||
|
static CamcorderProfile get(int cameraId, @NonNull Size targetSize) { |
||||||
|
final int targetArea = targetSize.getWidth() * targetSize.getHeight(); |
||||||
|
List<Size> sizes = new ArrayList<>(sizeToProfileMap.keySet()); |
||||||
|
Collections.sort(sizes, new Comparator<Size>() { |
||||||
|
@Override |
||||||
|
public int compare(Size s1, Size s2) { |
||||||
|
int a1 = Math.abs(s1.getWidth() * s1.getHeight() - targetArea); |
||||||
|
int a2 = Math.abs(s2.getWidth() * s2.getHeight() - targetArea); |
||||||
|
//noinspection UseCompareMethod
|
||||||
|
return (a1 < a2) ? -1 : ((a1 == a2) ? 0 : 1); |
||||||
|
} |
||||||
|
}); |
||||||
|
while (sizes.size() > 0) { |
||||||
|
Size candidate = sizes.remove(0); |
||||||
|
//noinspection ConstantConditions
|
||||||
|
int quality = sizeToProfileMap.get(candidate); |
||||||
|
if (CamcorderProfile.hasProfile(cameraId, quality)) { |
||||||
|
return CamcorderProfile.get(cameraId, quality); |
||||||
|
} |
||||||
|
} |
||||||
|
// Should never happen, but fallback to low.
|
||||||
|
return CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_LOW); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue