11package org .wysaid .nativePort ;
22
3+ import android .util .Log ;
4+
5+ import org .wysaid .common .Common ;
6+
37import java .nio .ShortBuffer ;
48
59/**
@@ -13,23 +17,167 @@ public class CGEFrameRecorder extends CGEFrameRenderer {
1317 NativeLibraryLoader .load ();
1418 }
1519
20+ /**
21+ * Video quality presets for adaptive bitrate calculation
22+ */
23+ public enum VideoQuality {
24+ LOW , // Suitable for network sharing, smaller file size
25+ MEDIUM , // Balance between quality and size
26+ HIGH , // High quality (recommended for most use cases)
27+ ULTRA // Ultra high quality (near lossless)
28+ }
29+
30+ // Track output dimensions for bitrate calculation
31+ private int mOutputWidth = 0 ;
32+ private int mOutputHeight = 0 ;
33+
1634 public CGEFrameRecorder () {
1735 super (0 ); //avoid multiple creation.
1836 mNativeAddress = nativeCreateRecorder ();
1937 }
2038
39+ @ Override
40+ public boolean init (int srcWidth , int srcHeight , int dstWidth , int dstHeight ) {
41+ boolean result = super .init (srcWidth , srcHeight , dstWidth , dstHeight );
42+ if (result ) {
43+ mOutputWidth = dstWidth ;
44+ mOutputHeight = dstHeight ;
45+ }
46+ return result ;
47+ }
48+
49+ /**
50+ * Calculate recommended bitrate based on resolution and quality preset
51+ * @param width video width
52+ * @param height video height
53+ * @param quality quality preset
54+ * @return recommended bitrate in bps
55+ */
56+ private int calculateBitrate (int width , int height , VideoQuality quality ) {
57+ int baseBitrate = getBaseBitrate (width , height );
58+
59+ // Adjust based on quality setting
60+ switch (quality ) {
61+ case LOW :
62+ return (int ) (baseBitrate * 0.5 ); // 50%
63+ case MEDIUM :
64+ return (int ) (baseBitrate * 0.75 ); // 75%
65+ case HIGH :
66+ return baseBitrate ; // 100%
67+ case ULTRA :
68+ return (int ) (baseBitrate * 1.5 ); // 150%
69+ default :
70+ return baseBitrate ;
71+ }
72+ }
73+
74+ private static int getBaseBitrate (int width , int height ) {
75+ int pixels = width * height ;
76+ int baseBitrate ;
77+
78+ // Base bitrate based on resolution
79+ if (pixels <= 640 * 480 ) { // VGA (~0.3 MP)
80+ baseBitrate = 2_000_000 ; // 2 Mbps
81+ } else if (pixels <= 1280 * 720 ) { // 720p (~0.9 MP)
82+ baseBitrate = 5_000_000 ; // 5 Mbps
83+ } else if (pixels <= 1920 * 1080 ) { // 1080p (~2 MP)
84+ baseBitrate = 10_000_000 ; // 10 Mbps
85+ } else if (pixels <= 2560 * 1440 ) { // 1440p (~3.7 MP)
86+ baseBitrate = 16_000_000 ; // 16 Mbps
87+ } else { // 4K+ (8 MP+)
88+ baseBitrate = 40_000_000 ; // 40 Mbps
89+ }
90+ return baseBitrate ;
91+ }
92+
2193 ///////////////// Video recording related ////////////////////
2294
95+ /**
96+ * Start recording with adaptive bitrate based on resolution (HIGH quality)
97+ * For custom quality, use {@link #startRecording(int, String, VideoQuality)}
98+ * @param fps frames per second
99+ * @param filename output file path
100+ * @return true if recording started successfully
101+ * @deprecated Default bitrate changed from 1.65 Mbps to adaptive HIGH (~10 Mbps for 1080p).
102+ * Use {@link #startRecording(int, String, VideoQuality)} for explicit control.
103+ */
104+ @ Deprecated
23105 public boolean startRecording (int fps , String filename ) {
24- return startRecording (fps , 1650000 , filename );
106+ Log .w (Common .LOG_TAG ,
107+ "startRecording: Using HIGH quality preset (~10Mbps for 1080p). " +
108+ "Previous default was 1.65Mbps. Use startRecording(fps, filename, VideoQuality) for explicit control." );
109+ return startRecording (fps , filename , VideoQuality .HIGH );
110+ }
111+
112+ /**
113+ * Start recording with specified quality preset (recommended)
114+ * @param fps frames per second
115+ * @param filename output file path
116+ * @param quality video quality preset (LOW/MEDIUM/HIGH/ULTRA)
117+ * @return true if recording started successfully
118+ */
119+ public boolean startRecording (int fps , String filename , VideoQuality quality ) {
120+ // Use default 1080p if dimensions not set
121+ int width = (mOutputWidth > 0 ) ? mOutputWidth : 1920 ;
122+ int height = (mOutputHeight > 0 ) ? mOutputHeight : 1080 ;
123+
124+ if (mOutputWidth <= 0 || mOutputHeight <= 0 ) {
125+ Log .w (Common .LOG_TAG ,
126+ String .format ("startRecording: Output dimensions not initialized, defaulting to %dx%d. " +
127+ "Call init() or use startRecording(fps, filename, width, height, quality) for accurate bitrate." ,
128+ width , height ));
129+ }
130+
131+ int bitrate = calculateBitrate (width , height , quality );
132+ return startRecording (fps , bitrate , filename );
25133 }
26134
135+ /**
136+ * Start recording with specified quality and explicit dimensions
137+ * @param fps frames per second
138+ * @param filename output file path
139+ * @param width video width (for bitrate calculation)
140+ * @param height video height (for bitrate calculation)
141+ * @param quality video quality preset
142+ * @return true if recording started successfully
143+ */
144+ public boolean startRecording (int fps , String filename , int width , int height , VideoQuality quality ) {
145+ int bitrate = calculateBitrate (width , height , quality );
146+ return startRecording (fps , bitrate , filename );
147+ }
148+
149+ /**
150+ * Start recording with manual bitrate specification (advanced usage)
151+ * @param fps frames per second
152+ * @param bitRate bitrate in bps
153+ * @param filename output file path
154+ * @return true if recording started successfully
155+ */
27156 public boolean startRecording (int fps , int bitRate , String filename ) {
28157 if (mNativeAddress != 0 )
29158 return nativeStartRecording (mNativeAddress , fps , filename , bitRate );
30159 return false ;
31160 }
32161
162+ /**
163+ * Get recommended bitrate for specified quality
164+ * @param quality video quality preset
165+ * @return recommended bitrate in bps
166+ */
167+ public int getRecommendedBitrate (VideoQuality quality ) {
168+ int width = (mOutputWidth > 0 ) ? mOutputWidth : 1920 ;
169+ int height = (mOutputHeight > 0 ) ? mOutputHeight : 1080 ;
170+
171+ if (mOutputWidth <= 0 || mOutputHeight <= 0 ) {
172+ Log .w (Common .LOG_TAG ,
173+ String .format ("getRecommendedBitrate: Output dimensions not initialized, using default %dx%d. " +
174+ "Call init() first for resolution-specific bitrate." ,
175+ width , height ));
176+ }
177+
178+ return calculateBitrate (width , height , quality );
179+ }
180+
33181 public boolean isRecordingStarted () {
34182 if (mNativeAddress != 0 )
35183 return nativeIsRecordingStarted (mNativeAddress );
0 commit comments