diff --git a/sdk/video-link-android/build.gradle b/sdk/video-link-android/build.gradle
index 378a09f19..bf3d71bbc 100644
--- a/sdk/video-link-android/build.gradle
+++ b/sdk/video-link-android/build.gradle
@@ -49,7 +49,7 @@ dependencies {
 //        changing = true
 //    }
 //    api 'com.tencent.iot.thirdparty.android:xp2p-sdk:2.4.23'
-    api 'com.tencent.iot.thirdparty.android:xp2p-sdk:2.4.28'
+    api 'com.tencent.iot.thirdparty.android:xp2p-sdk:2.4.30'
     api 'com.tencent.iot.thirdparty.android:media-server:1.0.2'
 }
 
diff --git a/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/encoder/AudioEncoder.java b/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/encoder/AudioEncoder.java
index 848b34753..80b55f90e 100644
--- a/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/encoder/AudioEncoder.java
+++ b/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/encoder/AudioEncoder.java
@@ -4,6 +4,8 @@
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
 import android.media.MediaFormat;
+import android.media.audiofx.AcousticEchoCanceler;
+import android.media.audiofx.AutomaticGainControl;
 import android.os.Build;
 import android.util.Log;
 
@@ -44,6 +46,8 @@ public class AudioEncoder {
     private final String TAG = AudioEncoder.class.getSimpleName();
     private MediaCodec audioCodec;
     private AudioRecord audioRecord;
+    private AcousticEchoCanceler canceler;
+    private AutomaticGainControl control;
 
     private final MicParam micParam;
     private final AudioEncodeParam audioEncodeParam;
@@ -55,9 +59,21 @@ public class AudioEncoder {
 
 
     public AudioEncoder(MicParam micParam, AudioEncodeParam audioEncodeParam) {
+        this(micParam, audioEncodeParam, false, false);
+    }
+
+
+    public AudioEncoder(MicParam micParam, AudioEncodeParam audioEncodeParam, boolean enableAEC, boolean enableAGC) {
         this.micParam = micParam;
         this.audioEncodeParam = audioEncodeParam;
         initAudio();
+        int audioSessionId = audioRecord.getAudioSessionId();
+        if (enableAEC && audioSessionId != 0) {
+            Log.e(TAG, "=====initAEC result: " + initAEC(audioSessionId));
+        }
+        if (enableAGC && audioSessionId != 0) {
+            Log.e(TAG, "=====initAGC result: " + initAGC(audioSessionId));
+        }
     }
 
     public void setOnEncodeListener(OnEncodeListener listener) {
@@ -82,7 +98,6 @@ private void initAudio() {
         }
     }
 
-    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
     public void start() {
         new Thread(this::record).start();
     }
@@ -91,6 +106,44 @@ public void stop() {
         stopEncode = true;
     }
 
+    public boolean isDevicesSupportAEC() {
+        return AcousticEchoCanceler.isAvailable();
+    }
+
+    private boolean initAEC(int audioSession) {
+
+        boolean isDevicesSupportAEC = isDevicesSupportAEC();
+        Log.e(TAG, "isDevicesSupportAEC: "+isDevicesSupportAEC);
+        if (!isDevicesSupportAEC) {
+            return false;
+        }
+        if (canceler != null) {
+            return false;
+        }
+        canceler = AcousticEchoCanceler.create(audioSession);
+        canceler.setEnabled(true);
+        return canceler.getEnabled();
+    }
+
+    public boolean isDevicesSupportAGC() {
+        return AutomaticGainControl.isAvailable();
+    }
+
+    private boolean initAGC(int audioSession) {
+
+        boolean isDevicesSupportAGC = isDevicesSupportAGC();
+        Log.e(TAG, "isDevicesSupportAGC: "+isDevicesSupportAGC);
+        if (!isDevicesSupportAGC) {
+            return false;
+        }
+        if (control != null) {
+            return false;
+        }
+        control = AutomaticGainControl.create(audioSession);
+        control.setEnabled(true);
+        return control.getEnabled();
+    }
+
     private void release() {
         if (audioRecord != null) {
             audioRecord.stop();
@@ -103,6 +156,18 @@ private void release() {
             audioCodec.release();
             audioCodec = null;
         }
+
+        if (canceler != null) {
+            canceler.setEnabled(false);
+            canceler.release();
+            canceler = null;
+        }
+
+        if (control != null) {
+            control.setEnabled(false);
+            control.release();
+            control = null;
+        }
     }
 
     private void addADTStoPacket(ByteBuffer outputBuffer) {
@@ -138,7 +203,6 @@ private void addADTStoPacket(byte[] packet, int packetLen) {
         packet[6] = (byte) 0xFC;
     }
 
-    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
     private void record() {
         if (audioCodec == null) {
             return;
@@ -156,7 +220,12 @@ private void record() {
             // 将 AudioRecord 获取的 PCM 原始数据送入编码器
             int audioInputBufferId = audioCodec.dequeueInputBuffer(0);
             if (audioInputBufferId >= 0) {
-                ByteBuffer inputBuffer = audioCodec.getInputBuffer(audioInputBufferId);
+                ByteBuffer inputBuffer = null;
+                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
+                    inputBuffer = audioCodec.getInputBuffer(audioInputBufferId);
+                } else {
+                    inputBuffer = audioCodec.getInputBuffers()[audioInputBufferId];
+                }
                 int readSize = -1;
                 if (inputBuffer != null) {
                     readSize = audioRecord.read(inputBuffer, bufferSizeInBytes);
@@ -168,7 +237,12 @@ private void record() {
 
             int audioOutputBufferId = audioCodec.dequeueOutputBuffer(audioInfo, 0);
             while (audioOutputBufferId >= 0) {
-                ByteBuffer outputBuffer = audioCodec.getOutputBuffer(audioOutputBufferId);
+                ByteBuffer outputBuffer = null;
+                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
+                    outputBuffer = audioCodec.getOutputBuffer(audioOutputBufferId);
+                } else {
+                    outputBuffer = audioCodec.getOutputBuffers()[audioOutputBufferId];
+                }
                 outputBuffer.position(audioInfo.offset);
                 outputBuffer.limit(audioInfo.offset + audioInfo.size);
                 addADTStoPacket(outputBuffer);
diff --git a/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/encoder/VideoEncoder.java b/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/encoder/VideoEncoder.java
index 19bd19310..0193b0819 100644
--- a/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/encoder/VideoEncoder.java
+++ b/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/encoder/VideoEncoder.java
@@ -4,8 +4,11 @@
 import android.media.MediaCodecInfo;
 import android.media.MediaFormat;
 import android.os.Build;
+import android.os.Bundle;
 import android.util.Log;
 
+import androidx.annotation.RequiresApi;
+
 import com.tencent.iot.video.link.listener.OnEncodeListener;
 import com.tencent.iot.video.link.param.VideoEncodeParam;
 
@@ -19,8 +22,10 @@ public class VideoEncoder {
     private final VideoEncodeParam videoEncodeParam;
     private final ExecutorService executor = Executors.newSingleThreadExecutor();
     private MediaCodec mediaCodec;
+    private MediaFormat mediaFormat;
     private OnEncodeListener encoderListener;
     private long seq = 0L;
+    private int MAX_BITRATE_LENGTH = 1000000;
 
     public VideoEncoder(VideoEncodeParam param) {
         this.videoEncodeParam = param;
@@ -34,7 +39,11 @@ private void initMediaCodec() {
             //TODO 因为获取到的视频帧数据是逆时针旋转了90度的,所以这里宽高需要对调
             MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", videoEncodeParam.getHeight(), videoEncodeParam.getWidth());
             //描述平均位速率(以位/秒为单位)的键。 关联的值是一个整数
-            mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, videoEncodeParam.getBitRate());
+            int bitRate = videoEncodeParam.getBitRate();
+            if (bitRate > MAX_BITRATE_LENGTH) {
+                bitRate = MAX_BITRATE_LENGTH;
+            }
+            mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
             //描述视频格式的帧速率(以帧/秒为单位)的键。帧率,一般在15至30之内,太小容易造成视频卡顿。
             mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, videoEncodeParam.getFrameRate());
             //色彩格式,具体查看相关API,不同设备支持的色彩格式不尽相同
@@ -56,6 +65,32 @@ private void initMediaCodec() {
         }
     }
 
+    //描述平均位速率(以位/秒为单位)的键。 关联的值是一个整数
+    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
+    public void setVideoBitRate(int bitRate) {
+        int nowBitrate = videoEncodeParam.getBitRate();
+        int nowWidth   = videoEncodeParam.getWidth();
+        int nowHeight  = videoEncodeParam.getHeight();
+
+        if ((bitRate > nowWidth * nowHeight) || (bitRate < 10000) || (nowBitrate == bitRate) || (bitRate > MAX_BITRATE_LENGTH)) {
+            return;
+        }
+
+        videoEncodeParam.setBitRate(bitRate);
+
+        try {
+            Bundle params = new Bundle();
+            params.putInt(MediaCodec.PARAMETER_KEY_VIDEO_BITRATE, bitRate);
+            mediaCodec.setParameters(params);
+
+        } catch (IllegalStateException e) {
+            Log.e("TAG", "updateBitrate failed", e);
+        }
+    }
+
+    public int getVideoBitRate() {
+        return videoEncodeParam.getBitRate();
+    }
     /**
      * 将NV21编码成H264
      */