diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto
index f6c57b1e4..40da75a5d 100644
--- a/libs/hbb_common/protos/message.proto
+++ b/libs/hbb_common/protos/message.proto
@@ -479,10 +479,18 @@ message OptionMessage {
 }
 
 message TestDelay {
+  enum CodecFormat {
+    Unknown = 0;
+    VP8 = 1;
+    VP9 = 2;
+    H264 = 3;
+    H265 = 4;
+  }
   int64 time = 1;
   bool from_client = 2;
   uint32 last_delay = 3;
   uint32 target_bitrate = 4;
+  CodecFormat codec_format = 5;
 }
 
 message PublicKey {
diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs
index 1dad08701..6e9d1a8b9 100644
--- a/libs/scrap/src/common/codec.rs
+++ b/libs/scrap/src/common/codec.rs
@@ -12,7 +12,7 @@ use crate::vpxcodec::*;
 use hbb_common::{
     anyhow::anyhow,
     log,
-    message_proto::{video_frame, Message, VP9s, VideoCodecState},
+    message_proto::{video_frame, Message, VP9s, VideoCodecState, test_delay},
     ResultType,
 };
 #[cfg(feature = "hwcodec")]
@@ -52,6 +52,8 @@ pub trait EncoderApi {
     fn use_yuv(&self) -> bool;
 
     fn set_bitrate(&mut self, bitrate: u32) -> ResultType<()>;
+
+    fn get_codec_format(&self) -> test_delay::CodecFormat;
 }
 
 pub struct DecoderCfg {
diff --git a/libs/scrap/src/common/hwcodec.rs b/libs/scrap/src/common/hwcodec.rs
index 945de6335..70d944a33 100644
--- a/libs/scrap/src/common/hwcodec.rs
+++ b/libs/scrap/src/common/hwcodec.rs
@@ -6,7 +6,7 @@ use hbb_common::{
     anyhow::{anyhow, Context},
     config::HwCodecConfig,
     lazy_static, log,
-    message_proto::{H264s, H265s, Message, VideoFrame, H264, H265},
+    message_proto::{test_delay, H264s, H265s, Message, VideoFrame, H264, H265},
     ResultType,
 };
 use hwcodec::{
@@ -143,6 +143,13 @@ impl EncoderApi for HwEncoder {
         self.encoder.set_bitrate((bitrate * 1000) as _).ok();
         Ok(())
     }
+
+    fn get_codec_format(&self) -> test_delay::CodecFormat {
+        match self.format {
+            DataFormat::H264 => test_delay::CodecFormat::H264,
+            DataFormat::H265 => test_delay::CodecFormat::H265,
+        }
+    }
 }
 
 impl HwEncoder {
diff --git a/libs/scrap/src/common/vpxcodec.rs b/libs/scrap/src/common/vpxcodec.rs
index 2943419e4..a44078eba 100644
--- a/libs/scrap/src/common/vpxcodec.rs
+++ b/libs/scrap/src/common/vpxcodec.rs
@@ -3,7 +3,7 @@
 // https://github.com/rust-av/vpx-rs/blob/master/src/decoder.rs
 
 use hbb_common::anyhow::{anyhow, Context};
-use hbb_common::message_proto::{Message, VP9s, VideoFrame, VP9};
+use hbb_common::message_proto::{Message, VP9s, VideoFrame, VP9, test_delay};
 use hbb_common::ResultType;
 
 use crate::codec::EncoderApi;
@@ -27,6 +27,7 @@ impl Default for VpxVideoCodecId {
 
 pub struct VpxEncoder {
     ctx: vpx_codec_ctx_t,
+    format: VpxVideoCodecId,
     width: usize,
     height: usize,
 }
@@ -96,14 +97,17 @@ impl EncoderApi for VpxEncoder {
     {
         match cfg {
             crate::codec::EncoderCfg::VPX(config) => {
+                let format;
                 let i;
                 if cfg!(feature = "VP8") {
                     i = match config.codec {
                         VpxVideoCodecId::VP8 => call_vpx_ptr!(vpx_codec_vp8_cx()),
                         VpxVideoCodecId::VP9 => call_vpx_ptr!(vpx_codec_vp9_cx()),
                     };
+                    format = config.codec;
                 } else {
                     i = call_vpx_ptr!(vpx_codec_vp9_cx());
+                    format = VpxVideoCodecId::VP9;
                 }
                 let mut c = unsafe { std::mem::MaybeUninit::zeroed().assume_init() };
                 call_vpx!(vpx_codec_enc_config_default(i, &mut c, 0));
@@ -190,6 +194,7 @@ impl EncoderApi for VpxEncoder {
 
                 Ok(Self {
                     ctx,
+                    format,
                     width: config.width as _,
                     height: config.height as _,
                 })
@@ -228,6 +233,13 @@ impl EncoderApi for VpxEncoder {
         call_vpx!(vpx_codec_enc_config_set(&mut self.ctx, &new_enc_cfg));
         return Ok(());
     }
+
+    fn get_codec_format(&self) -> test_delay::CodecFormat {
+        match self.format {
+            VpxVideoCodecId::VP8 => test_delay::CodecFormat::VP8,
+            VpxVideoCodecId::VP9 => test_delay::CodecFormat::VP9
+        }
+    }
 }
 
 impl VpxEncoder {
diff --git a/src/server/connection.rs b/src/server/connection.rs
index 46c730092..f8bf5d16a 100644
--- a/src/server/connection.rs
+++ b/src/server/connection.rs
@@ -380,6 +380,7 @@ impl Connection {
                             time,
                             last_delay:qos.current_delay,
                             target_bitrate:qos.target_bitrate,
+                            codec_format:qos.codec_format.into(),
                             ..Default::default()
                         });
                         conn.inner.send(msg_out.into());
diff --git a/src/server/video_service.rs b/src/server/video_service.rs
index 10ddf3223..9a42c6c31 100644
--- a/src/server/video_service.rs
+++ b/src/server/video_service.rs
@@ -72,11 +72,11 @@ pub struct VideoQoS {
     height: u32,
     user_image_quality: u32,
     current_image_quality: u32,
-
+    enable_abr: bool,
+    pub codec_format: test_delay::CodecFormat,
     pub current_delay: u32,
     pub fps: u8,             // abr
     pub target_bitrate: u32, // abr
-
     updated: bool,
     state: DelayState,
     debounce_count: u32,
@@ -110,6 +110,8 @@ impl Default for VideoQoS {
             fps: FPS,
             user_image_quality: ImageQuality::Balanced.as_percent(),
             current_image_quality: ImageQuality::Balanced.as_percent(),
+            enable_abr: false,
+            codec_format: Default::default(),
             width: 0,
             height: 0,
             current_delay: 0,
@@ -145,14 +147,16 @@ impl VideoQoS {
 
         self.current_delay = delay / 2 + self.current_delay / 2;
         log::trace!(
-            "VideoQoS update_network_delay:{}, {}, state:{:?},count:{}",
+            "VideoQoS update_network_delay:{}, {}, state:{:?}",
             self.current_delay,
             delay,
             self.state,
-            self.debounce_count
         );
 
         // ABR
+        if !self.enable_abr {
+            return;
+        }
         let current_state = DelayState::from_delay(self.current_delay);
         if current_state != self.state && self.debounce_count > 5 {
             log::debug!(
@@ -544,7 +548,6 @@ fn run(sp: GenericService) -> ResultType<()> {
     video_qos.set_size(width as _, height as _);
     let mut spf = video_qos.spf();
     let bitrate = video_qos.generate_bitrate()?;
-    drop(video_qos);
 
     log::info!("init bitrate={}", bitrate);
 
@@ -571,6 +574,9 @@ fn run(sp: GenericService) -> ResultType<()> {
         Err(err) => bail!("Failed to create encoder: {}", err),
     }
 
+    video_qos.codec_format = encoder.get_codec_format();
+    drop(video_qos);
+
     let privacy_mode_id = *PRIVACY_MODE_CONN_ID.lock().unwrap();
     #[cfg(not(windows))]
     let captuerer_privacy_mode_id = privacy_mode_id;
diff --git a/src/ui/remote.rs b/src/ui/remote.rs
index 22ae5f505..fefc42f98 100644
--- a/src/ui/remote.rs
+++ b/src/ui/remote.rs
@@ -240,6 +240,7 @@ struct QualityStatus {
     fps: i32,
     delay: i32,
     target_bitrate: i32,
+    codec_format: test_delay::CodecFormat,
 }
 
 impl Default for QualityStatus {
@@ -249,6 +250,7 @@ impl Default for QualityStatus {
             fps: -1,
             delay: -1,
             target_bitrate: -1,
+            codec_format: test_delay::CodecFormat::Unknown,
         }
     }
 }
@@ -269,13 +271,21 @@ impl Handler {
     }
 
     fn update_quality_status(&self, status: QualityStatus) {
+        let codec_format = match status.codec_format {
+            test_delay::CodecFormat::Unknown => "Unknown",
+            test_delay::CodecFormat::VP8 => "VP8",
+            test_delay::CodecFormat::VP9 => "VP9",
+            test_delay::CodecFormat::H264 => "H264",
+            test_delay::CodecFormat::H265 => "H265",
+        }; 
         self.call2(
             "updateQualityStatus",
             &make_args!(
                 status.speed,
                 status.fps,
                 status.delay,
-                status.target_bitrate
+                status.target_bitrate,
+                codec_format
             ),
         );
     }
@@ -2604,6 +2614,7 @@ impl Interface for Handler {
             self.update_quality_status(QualityStatus {
                 delay: t.last_delay as _,
                 target_bitrate: t.target_bitrate as _,
+                codec_format: t.codec_format.enum_value_or_default(),
                 ..Default::default()
             });
             let mut msg_out = Message::new();
diff --git a/src/ui/remote.tis b/src/ui/remote.tis
index cc5727755..dc2470ac1 100644
--- a/src/ui/remote.tis
+++ b/src/ui/remote.tis
@@ -482,16 +482,20 @@ class QualityMonitor: Reactor.Component
             <div>
                 Target Bitrate: {qualityMonitorData[3]}kb
             </div>
+            <div>
+                Codec: {qualityMonitorData[4]}
+            </div>
         </div>;
     }
 }
 
 $(#quality-monitor).content(<QualityMonitor />);
-handler.updateQualityStatus = function(speed, fps, delay, bitrate) {
+handler.updateQualityStatus = function(speed, fps, delay, bitrate, codec_format) {
     speed ? qualityMonitorData[0] = speed:null;
     fps > -1 ? qualityMonitorData[1] = fps:null;
     delay > -1 ? qualityMonitorData[2] = delay:null;
     bitrate > -1 ? qualityMonitorData[3] = bitrate:null;
+    codec_format != "Unknown" ? qualityMonitorData[4] = codec_format:null;
     qualityMonitor.update();
 }