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