audio: Add deepbuffer function for u-linux. [1/1]

PD#TV-131643

Problem:
Two-way audio uses system sound at the same time.

Solution:
Audio_hal support deepbuffer.
PS: this should co-work with new MS12 library contained:
2024.3.13/Dolby MS12 v2 for P/R/S/T Master
443dc8f4 Merge "audio: Add DeepBuffer function. [1/1]".

Verify:
t5w.

Change-Id: Ic017bd24a0dc7bf8514c5d892c04a6e23883f621
Signed-off-by: yuliang.hu <yuliang.hu@amlogic.com>
diff --git a/audio_hal/audio_hw.c b/audio_hal/audio_hw.c
index 5703c6e..131ea38 100644
--- a/audio_hal/audio_hw.c
+++ b/audio_hal/audio_hw.c
@@ -6604,19 +6604,19 @@
     pthread_mutex_lock(&adev->lock);
     uint64_t enter_ns = 0;
     uint64_t leave_ns = 0;
-
+    bool is_deep_buf = aml_out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
 
     struct timespec ts;
     clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
-    AM_LOGI_IF(adev->debug_flag, "[%lld.%9ld -- %d] mixer_aux_buffer_write %zu", (long long)ts.tv_sec, ts.tv_nsec, gettid(), bytes);
+    AM_LOGI_IF(adev->debug_flag, "[%lld.%9ld -- %d] mixer_aux_buffer_write %zu, is_deep_buf:%d", (long long)ts.tv_sec, ts.tv_nsec, gettid(), bytes, is_deep_buf);
 
     if (eDolbyMS12Lib == adev->dolby_lib_type && continuous_mode(adev)) {
         enter_ns = aml_audio_get_systime_ns();
     }
 
     if (adev->debug_flag > 1) {
-        ALOGD("%s:%d size:%zu, dolby_lib_type:0x%x, frame_size:%zu",
-        __func__, __LINE__, bytes, adev->dolby_lib_type, frame_size);
+        ALOGD("%s:%d size:%zu, dolby_lib_type:0x%x, frame_size:%zu, is_deep_buf:%d",
+        __func__, __LINE__, bytes, adev->dolby_lib_type, frame_size, is_deep_buf);
     }
 
     if (aml_out->standby) {
@@ -6642,7 +6642,11 @@
          *the system tone voice should not be mixed
          */
         if (is_bypass_dolbyms12(stream)) {
-            ms12->sys_audio_skip += bytes / frame_size;
+            if (is_deep_buf) {
+                ms12->deep_buf_audio_skip += bytes / frame_size;
+            } else {
+                ms12->sys_audio_skip += bytes / frame_size;
+            }
             usleep(bytes * 1000000 /frame_size/out_get_sample_rate(&stream->common)*5/6);
         } else {
             /*
@@ -6693,7 +6697,11 @@
 
             while (bytes_remaining && adev->ms12.dolby_ms12_enable && retry < 20) {
                 size_t used_size = 0;
-                ret = dolby_ms12_system_process(stream, (char *)buffer + bytes_written, bytes_remaining, &used_size);
+                if (is_deep_buf) {
+                    ret = dolby_ms12_deep_buffer_process(stream, (char *)buffer + bytes_written, bytes_remaining, &used_size);
+                } else {
+                    ret = dolby_ms12_system_process(stream, (char *)buffer + bytes_written, bytes_remaining, &used_size);
+                }
                 if (!ret) {
                     bytes_remaining -= used_size;
                     bytes_written += used_size;
@@ -6706,8 +6714,13 @@
                 }
             }
             if (bytes_remaining) {
-                ms12->sys_audio_skip += bytes_remaining / frame_size;
-                ALOGI("bytes_remaining =%zu totoal skip =%"PRIu64"", bytes_remaining, ms12->sys_audio_skip);
+                if (is_deep_buf) {
+                    ms12->deep_buf_audio_skip += bytes_remaining / frame_size;
+                    AM_LOGI("deep buf : bytes_remaining =%zu total skip =%" PRIu64 "", bytes_remaining, ms12->deep_buf_audio_skip);
+                } else {
+                    ms12->sys_audio_skip += bytes_remaining / frame_size;
+                    AM_LOGI("sys audio : bytes_remaining =%zu totoal skip =%"PRIu64"", bytes_remaining, ms12->sys_audio_skip);
+                }
             }
         }
     } else {
@@ -6718,7 +6731,11 @@
         }
         /*these data is skip for ms12, we still need calculate it*/
         if (eDolbyMS12Lib == adev->dolby_lib_type_last) {
-            ms12->sys_audio_skip += bytes / frame_size;
+            if (is_deep_buf) {
+                ms12->deep_buf_audio_skip += bytes / frame_size;
+            } else {
+                ms12->sys_audio_skip += bytes / frame_size;
+            }
         }
     }
     aml_out->input_bytes_size += bytes;
@@ -6737,7 +6754,11 @@
            */
         alsa_latency_frame = adev->ms12.latency_frame;
         int system_latency = 0;
-        system_latency = dolby_ms12_get_system_buffer_avail(NULL) / frame_size;
+        if (is_deep_buf) {
+            system_latency = dolby_ms12_get_deep_buffer_avail_frames(NULL);
+        } else {
+            system_latency = dolby_ms12_get_system_buffer_avail(NULL) / frame_size;
+        }
 
         if (adev->compensate_video_enable) {
             alsa_latency_frame = 0;
@@ -6747,15 +6768,16 @@
             aml_out->last_frames_position -= alsa_latency_frame;
         }
         if (adev->debug_flag > 1) {
-            ALOGI("%s stream audio presentation %"PRIu64" latency_frame %d.ms12 system latency_frame %d,total frame=%" PRId64 " %" PRId64 " ms",
-                  __func__,aml_out->last_frames_position, alsa_latency_frame, system_latency,aml_out->frame_write_sum, aml_out->frame_write_sum/48);
+            AM_LOGI("is_deep_buf:%d stream audio presentation %"PRIu64" latency_frame %d.ms12 system latency_frame %d,total frame=%" PRId64 " %" PRId64 " ms",
+                  is_deep_buf, aml_out->last_frames_position, alsa_latency_frame, system_latency,aml_out->frame_write_sum, aml_out->frame_write_sum/48);
         }
     } else {
         aml_out->last_frames_position = aml_out->frame_write_sum;
     }
 
     clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
-    AM_LOGI_IF(adev->debug_flag, "[%lld.%9ld] write %zu bytes, system level %zu ms", (long long)ts.tv_sec, ts.tv_nsec, bytes, dolby_ms12_get_system_buffer_avail(NULL) / frame_size / 48);
+    AM_LOGI_IF(adev->debug_flag && !is_deep_buf, "[%lld.%9ld] write %zu bytes, system level %zu ms", (long long)ts.tv_sec, ts.tv_nsec, bytes, dolby_ms12_get_system_buffer_avail(NULL) / frame_size / 48);
+    AM_LOGI_IF(adev->debug_flag && is_deep_buf, "[%lld.%9ld] write %zu bytes, deep_buffer level %d ms", (long long)ts.tv_sec, ts.tv_nsec, bytes, dolby_ms12_get_deep_buffer_avail_frames(NULL) / 48);
 
 
 #ifndef BUILD_LINUX
@@ -7314,7 +7336,11 @@
         if (aml_out->is_normal_pcm) {
             size_t frame_size = audio_stream_out_frame_size(stream);
             if (frame_size != 0) {
-                adev->sys_audio_frame_written = aml_out->input_bytes_size / frame_size;
+                if (aml_out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
+                    adev->deep_buf_audio_frame_written = aml_out->input_bytes_size / frame_size;
+                } else {
+                    adev->sys_audio_frame_written = aml_out->input_bytes_size / frame_size;
+                }
             }
         }
     }
diff --git a/audio_hal/audio_hw.h b/audio_hal/audio_hw.h
index d78b620..3305d68 100644
--- a/audio_hal/audio_hw.h
+++ b/audio_hal/audio_hw.h
@@ -544,6 +544,7 @@
     int ms12_thread_priority;
 
     uint64_t  sys_audio_frame_written;
+    uint64_t  deep_buf_audio_frame_written;
     struct aec_t *aec;
     struct aec_context *aml_aec;
     bool bt_wbs;
diff --git a/audio_hal/audio_hw_ms12_v2.c b/audio_hal/audio_hw_ms12_v2.c
index 086852e..d52aa8a 100644
--- a/audio_hal/audio_hw_ms12_v2.c
+++ b/audio_hal/audio_hw_ms12_v2.c
@@ -75,6 +75,8 @@
   so we choose 84ms now
 */
 #define MS12_SYS_INPUT_BUF_NS  (40000000LL)
+#define MS12_DEEP_BUF_INPUT_BUF_NS  (32000000LL)
+
 
 #define NANO_SECOND_PER_SECOND 1000000000LL
 #define NANO_SECOND_PER_MILLISECOND 1000000LL
@@ -83,6 +85,7 @@
 
 #define MS12_MAIN_BUF_INCREASE_TIME_MS (0)
 #define MS12_SYS_BUF_INCREASE_TIME_MS (32)
+#define MS12_DEEP_BUF_INCREASE_TIME_MS (32)
 #define DDPI_UDC_COMP_LINE 2
 
 #define MS12_PCM_FRAME_SIZE         (6144)
@@ -102,6 +105,7 @@
 #define DUMP_MS12_INPUT_APP              0x400
 #define DUMP_MS12_INPUT_ASSOCIATE        0x800
 #define DUMP_MS12_PROCESS_CALLBACK_PCM   0x1000
+#define DUMP_MS12_INPUT_DEEP_BUF         0x2000
 
 #define MS12_OUTPUT_SPEAKER_PCM_FILE     "ms12_speaker_pcm.raw"
 #define MS12_OUTPUT_SPDIF_PCM_FILE       "ms12_spdif_pcm.raw"
@@ -112,6 +116,7 @@
 #define MS12_OUTPUT_BITSTREAM_MAT_WI_MLP_FILE   "ms12_bitstream_wi_mlp.mat"
 #define MS12_OUTPUT_SPEAKER_DAPMODE_FILE     "/data/vendor/audiohal/ms12_speaker_dapmode.pcm"
 #define MS12_INPUT_SYS_PCM_FILE          "ms12_input_sys.pcm"
+#define MS12_INPUT_DEEP_BUF_PCM_FILE     "ms12_input_deepbuf.pcm"
 #define MS12_INPUT_SYS_MAIN_FILE         "ms12_input_main.raw"
 #define MS12_INPUT_SYS_ASSOCIATE_FILE    "ms12_input_associate.raw"
 #define MS12_INPUT_SYS_APP_FILE          "ms12_input_app.pcm"
@@ -1189,13 +1194,15 @@
 
     }
     ms12->sys_audio_base_pos = adev->sys_audio_frame_written;
+    ms12->deep_buf_audio_base_pos = adev->deep_buf_audio_frame_written;
     ms12->sys_audio_skip     = 0;
+    ms12->deep_buf_audio_skip = 0;
     ms12->dap_pcm_frames     = 0;
     ms12->stereo_pcm_frames  = 0;
     ms12->master_pcm_frames  = 0;
     ms12->b_legacy_ddpout    = dolby_ms12_get_ddp_5_1_out();
     ms12->main_volume        = 1.0f;
-    ALOGI("set ms12 sys pos =%" PRId64 "", ms12->sys_audio_base_pos);
+    ALOGI("set ms12 sys pos =%" PRId64 ", set ms12 deep buf pos =%" PRId64 "", ms12->sys_audio_base_pos, ms12->deep_buf_audio_base_pos);
 
     ms12->iec61937_ddp_buf = aml_audio_calloc(1, MS12_DDP_FRAME_SIZE);
     if (ms12->iec61937_ddp_buf == NULL) {
@@ -1789,6 +1796,85 @@
     return ret;
 }
 
+/*
+ *@brief dolby ms12 deep buffer process
+ *
+ * input parameters
+ *     stream: audio_stream_out handle
+ *     buffer: data buffer address
+ *     bytes: data size
+ * output parameters
+ *     use_size: buffer used size
+ */
+int dolby_ms12_deep_buffer_process(
+    struct audio_stream_out *stream
+    , const void *buffer
+    , size_t bytes
+    , size_t *use_size)
+{
+    struct aml_stream_out *aml_out = (struct aml_stream_out *)stream;
+    struct aml_audio_device *adev = aml_out->dev;
+    struct dolby_ms12_desc *ms12 = &(adev->ms12);
+    int mixer_default_samplerate = 48000;
+    int dolby_ms12_input_bytes = 0;
+    int ms12_output_size = 0;
+    int ret = -1;
+
+    if (get_debug_value(AML_DEBUG_AUDIOHAL_LEVEL_DETECT)) {
+        check_audio_level("ms12_deep_buf", buffer, bytes);
+    }
+
+    pthread_mutex_lock(&ms12->lock);
+    if (ms12->dolby_ms12_enable) {
+
+        if (ms12->tv_tuning_flag && ms12->input_config_format == AUDIO_FORMAT_MAT) {
+            ALOGW("MS12 use -tv_tuning Flag to activate a special processing graph for TV tuning purposes!\n");
+            ALOGW("System sound is Mute as design!\n");
+            pthread_mutex_unlock(&ms12->lock);
+            return ret;
+        }
+        /*set the dolby ms12 debug level*/
+        dolby_ms12_enable_debug();
+
+        //Dual input, here get the system data
+        dolby_ms12_input_bytes =
+            dolby_ms12_input_deep_buffer(
+                ms12->dolby_ms12_ptr
+                , buffer
+                , bytes
+                , AUDIO_FORMAT_PCM_16_BIT
+                , aml_out->hal_ch
+                , mixer_default_samplerate);
+        if (dolby_ms12_input_bytes > 0) {
+            *use_size = dolby_ms12_input_bytes;
+            ret = 0;
+        }else {
+            *use_size = 0;
+            ret = -1;
+        }
+    }
+    if (get_ms12_dump_enable(DUMP_MS12_INPUT_DEEP_BUF)) {
+        aml_dump_audio_bitstreams(MS12_INPUT_DEEP_BUF_PCM_FILE, (void*)buffer, *use_size);
+    }
+    pthread_mutex_unlock(&ms12->lock);
+
+    if (adev->continuous_audio_mode == 1) {
+        uint64_t input_ns = 0;
+        input_ns = (uint64_t)(*use_size) * NANO_SECOND_PER_SECOND / aml_out->hal_frame_size / mixer_default_samplerate;
+
+        if (ms12->deep_buf_virtual_buf_handle == NULL) {
+            //aml_audio_sleep(input_ns/1000);
+            if (input_ns == 0) {
+                input_ns = (uint64_t)(bytes) * NANO_SECOND_PER_SECOND / aml_out->hal_frame_size / mixer_default_samplerate;
+            }
+            audio_virtual_buf_open(&ms12->deep_buf_virtual_buf_handle, "ms12 deep buf input", MS12_DEEP_BUF_INPUT_BUF_NS, MS12_DEEP_BUF_INPUT_BUF_NS, MS12_DEEP_BUF_INCREASE_TIME_MS);
+        }
+        audio_virtual_buf_process(ms12->deep_buf_virtual_buf_handle, input_ns);
+    }
+
+    return ret;
+}
+
 
 /*
  *@brief dolby ms12 app process
@@ -4133,6 +4219,7 @@
         update_drc_parameter_when_output_config_changed(ms12 , adev->decoder_drc_control);
     }
     ms12->sys_audio_base_pos = adev->sys_audio_frame_written;
+    ms12->deep_buf_audio_base_pos = adev->deep_buf_audio_frame_written;
     ms12->sys_audio_skip = 0;
     ms12->dap_pcm_frames = 0;
     ms12->stereo_pcm_frames = 0;
diff --git a/audio_hal/audio_hw_ms12_v2.h b/audio_hal/audio_hw_ms12_v2.h
index c88e338..75ce815 100644
--- a/audio_hal/audio_hw_ms12_v2.h
+++ b/audio_hal/audio_hw_ms12_v2.h
@@ -161,6 +161,12 @@
     , size_t bytes
     , size_t *used_size);
 
+int dolby_ms12_deep_buffer_process(
+    struct audio_stream_out *stream
+    , const void *buffer
+    , size_t bytes
+    , size_t *used_size);
+
 enum MS12_PCM_TYPE {
     NORMAL_LPCM = 0,
     DAP_LPCM = 1,
diff --git a/decoder/libms12_v24/include/DolbyMS12.h b/decoder/libms12_v24/include/DolbyMS12.h
index be81c1f..5314592 100644
--- a/decoder/libms12_v24/include/DolbyMS12.h
+++ b/decoder/libms12_v24/include/DolbyMS12.h
@@ -100,6 +100,14 @@
         , int audio_stream_out_channel_num
         , int audio_stream_out_sample_rate
     );
+    virtual int     DolbyMS12InputDeepBuffer(
+        void *dolbyMS12_pointer
+        , const void *audio_stream_out_buffer //ms12 input buffer
+        , size_t audio_stream_out_buffer_size //ms12 input buffer size
+        , int audio_stream_out_format
+        , int audio_stream_out_channel_num
+        , int audio_stream_out_sample_rate
+    );
     virtual int     DolbyMS12InputApp(
         void *dolbyMS12_pointer
         , const void *audio_stream_out_buffer //ms12 input buffer
@@ -151,6 +159,8 @@
     virtual int     DolbyMS12GetAppBufferAvail(int * max_size);
     virtual int     DolbyMS12GetSystemBufferAvail(int * max_size);
 
+    virtual int     DolbyMS12GetDeepBufferAvailFrames(int * max_size);
+
     virtual int     DolbyMS12GetGain(int);
 
     virtual int     DolbyMS12SetMainVolume(float volume);
@@ -169,6 +179,7 @@
     virtual void DumpDolbyMS12Info(int);
 
     virtual unsigned long long DolbyMS12GetNBytesConsumedSysSound(void);
+    virtual unsigned long long DolbyMS12GetFramesConsumedDeepBufferAudio(void);
 
     virtual int DolbyMS12GetTotalNFramesDelay(void *);
 
diff --git a/decoder/libms12_v24/include/aml_audio_ms12.h b/decoder/libms12_v24/include/aml_audio_ms12.h
index 5951c92..6458508 100644
--- a/decoder/libms12_v24/include/aml_audio_ms12.h
+++ b/decoder/libms12_v24/include/aml_audio_ms12.h
@@ -293,6 +293,9 @@
     float dap_out_drc_target_volume;
 
     bool mch_output_enable;
+    void *deep_buf_virtual_buf_handle;
+    uint64_t deep_buf_audio_base_pos;
+    uint64_t deep_buf_audio_skip;
 };
 
 
diff --git a/decoder/libms12_v24/include/dolby_ms12.h b/decoder/libms12_v24/include/dolby_ms12.h
index 49dcb15..60d9d85 100644
--- a/decoder/libms12_v24/include/dolby_ms12.h
+++ b/decoder/libms12_v24/include/dolby_ms12.h
@@ -93,6 +93,13 @@
                             , int audio_stream_out_channel_num
                             , int audio_stream_out_sample_rate);
 
+int dolby_ms12_input_deep_buffer(void *dolby_mS12_pointer
+                            , const void *audio_stream_out_buffer
+                            , size_t audio_stream_out_buffer_size
+                            , int audio_stream_out_format
+                            , int audio_stream_out_channel_num
+                            , int audio_stream_out_sample_rate);
+
 int dolby_ms12_input_app(void *dolby_mS12_pointer
                             , const void *audio_stream_out_buffer
                             , size_t audio_stream_out_buffer_size
@@ -185,6 +192,8 @@
 */
 int dolby_ms12_get_system_buffer_avail(int * max_size);
 
+int dolby_ms12_get_deep_buffer_avail_frames(int * max_size);
+
 int dolby_ms12_get_gain(int idx);
 
 /*@@
@@ -252,6 +261,8 @@
 */
 unsigned long long dolby_ms12_get_consumed_sys_audio();
 
+unsigned long long dolby_ms12_get_consumed_deep_buffer_audio();
+
 /*@@
     @brief get the total delay(which means frame nums)
 */
diff --git a/decoder/libms12_v24/src/DolbyMS12.cpp b/decoder/libms12_v24/src/DolbyMS12.cpp
index 862582c..21fd25d 100644
--- a/decoder/libms12_v24/src/DolbyMS12.cpp
+++ b/decoder/libms12_v24/src/DolbyMS12.cpp
@@ -47,6 +47,7 @@
 
 int (*FuncDolbyMS12InputAssociate)(void *, const void *, size_t, int, int, int);
 int (*FuncDolbyMS12InputSystem)(void *, const void *, size_t, int, int, int);
+int (*FuncDolbyMS12InputDeepBuffer)(void *, const void *, size_t, int, int, int);
 int (*FuncDolbyMS12InputApp)(void *, const void *, size_t, int, int, int);
 int (*FuncDolbyMS12DapProcess)(void *, const void *, size_t, int, int, int);
 
@@ -65,6 +66,7 @@
 
 int (*FuncDolbyMS12GetAppBufferAvail)(int *);
 int (*FuncDolbyMS12GetSystemBufferAvail)(int *);
+int (*FuncDolbyMS12GetDeepBufferAvailFrames)(int *);
 
 int (*FuncDolbyMS12GetGain)(int);
 int (*FuncDolbyMS12Config)(ms12_config_type_t, ms12_config_t *);
@@ -74,6 +76,7 @@
 
 void (*FuncDolbyMS12SetDebugLevel)(int);
 unsigned long long (*FuncDolbyMS12GetNBytesConsumedSysSound)(void);
+unsigned long long (*FuncDolbyMS12GetFramesConsumedDeepBufferAudio)(void);
 int (*FuncDolbyMS12GetTotalNFramesDelay)(void *);
 int (*FuncDumpDolbyMS12Info)(int);
 char * (*FunDolbMS12GetVersion)(void);
@@ -156,6 +159,11 @@
         goto ERROR;
     }
 
+    FuncDolbyMS12InputDeepBuffer = (int (*)(void *, const void *, size_t, int, int, int)) dlsym(mDolbyMS12LibHandle, "ms12_input_deepbuffer");
+    if (!FuncDolbyMS12InputDeepBuffer) {
+        ALOGE("%s, dlsym ms12_input_deepbuffer fail\n", __FUNCTION__);
+    }
+
     FuncDolbyMS12InputApp = (int (*)(void *, const void *, size_t, int, int, int)) dlsym(mDolbyMS12LibHandle, "ms12_input_app");
     if (!FuncDolbyMS12InputApp) {
         ALOGE("%s, dlsym ms12_input_app fail\n", __FUNCTION__);
@@ -236,6 +244,11 @@
         goto ERROR;
     }
 
+    FuncDolbyMS12GetDeepBufferAvailFrames = (int (*)(int *))  dlsym(mDolbyMS12LibHandle, "get_deep_buffer_avail_frames");
+    if (!FuncDolbyMS12GetDeepBufferAvailFrames) {
+        ALOGE("%s, dlsym get_deep_buffer_avail fail\n", __FUNCTION__);
+    }
+
     FuncDolbyMS12GetGain = (int (*)(int))  dlsym(mDolbyMS12LibHandle, "ms12_get_gain_int");
     if (!FuncDolbyMS12GetGain) {
         ALOGE("%s, dlsym get_system_buffer_avail fail\n", __FUNCTION__);
@@ -277,6 +290,11 @@
         ALOGW("%s, dlsym FuncDolbyMS12GetNBytesConsumedSysSound fail,ignore it as version difference\n", __FUNCTION__);
     }
 
+    FuncDolbyMS12GetFramesConsumedDeepBufferAudio = (unsigned long long (*)(void))  dlsym(mDolbyMS12LibHandle, "get_frames_consumed_of_deep_buffer_audio");
+    if (!FuncDolbyMS12GetFramesConsumedDeepBufferAudio) {
+        ALOGW("%s, dlsym FuncDolbyMS12GetFramesConsumedDeepBufferAudio fail,ignore it as version difference\n", __FUNCTION__);
+    }
+
     FuncDolbyMS12GetTotalNFramesDelay  = (int (*)(void *))  dlsym(mDolbyMS12LibHandle, "get_ms12_total_nframes_delay");
     if (!FuncDolbyMS12GetTotalNFramesDelay) {
         ALOGW("%s, dlsym get_ms12_total_delay fail, ignore it as version difference\n", __FUNCTION__);
@@ -351,6 +369,7 @@
     FuncDolbyMS12Release = NULL;
     FuncDolbyMS12InitAllParams = NULL;
     FuncDolbyMS12InputSystem = NULL;
+    FuncDolbyMS12InputDeepBuffer = NULL;
 #ifdef REPLACE_OUTPUT_BUFFER_WITH_CALLBACK
     FuncDolbyMS12RegisterOutputCallback = NULL;
 #else
@@ -361,6 +380,7 @@
     FuncDolbyMS12SetQuitFlag = NULL;
     FuncDolbyMS12GetBitstreamOutputSize = NULL;
     FuncDolbyMS12GetSystemBufferAvail = NULL;
+    FuncDolbyMS12GetDeepBufferAvailFrames = NULL;
     FuncDolbyMS12Config = NULL;
     FuncDumpDolbyMS12Info = NULL;
     FuncDolbyMS12GetAudioInfo = NULL;
@@ -368,6 +388,7 @@
     FunDolbMS12GetVersion = NULL;
     FuncDolbyMS12SetDebugLevel = NULL;
     FuncDolbyMS12GetNBytesConsumedSysSound = NULL;
+    FuncDolbyMS12GetFramesConsumedDeepBufferAudio = NULL;
     FuncDolbyMS12GetTotalNFramesDelay = NULL;
 
     /* MAT Encoder API Begin */
@@ -527,6 +548,33 @@
     return ret;
 }
 
+int DolbyMS12::DolbyMS12InputDeepBuffer(
+    void *DolbyMS12Pointer
+    , const void *audio_stream_out_buffer //ms12 input buffer
+    , size_t audio_stream_out_buffer_size //ms12 input buffer size
+    , int audio_stream_out_format
+    , int audio_stream_out_channel_num
+    , int audio_stream_out_sample_rate
+)
+{
+    ALOGV("+%s()", __FUNCTION__);
+    int ret = 0;
+
+    if (!FuncDolbyMS12InputDeepBuffer) {
+        ALOGE("%s(), pls load lib first.\n", __FUNCTION__);
+        return -1;
+    }
+
+    ret = (*FuncDolbyMS12InputDeepBuffer)(DolbyMS12Pointer
+                                      , audio_stream_out_buffer //ms12 input buffer
+                                      , audio_stream_out_buffer_size //ms12 input buffer size
+                                      , audio_stream_out_format
+                                      , audio_stream_out_channel_num
+                                      , audio_stream_out_sample_rate);
+    ALOGV("-%s() ret %d", __FUNCTION__, ret);
+    return ret;
+}
+
 int DolbyMS12::DolbyMS12InputApp(
     void *DolbyMS12Pointer
     , const void *audio_stream_out_buffer //ms12 input buffer
@@ -750,6 +798,20 @@
     return ret;
 }
 
+int DolbyMS12::DolbyMS12GetDeepBufferAvailFrames(int * max_size)
+{
+    int ret = 0;
+    ALOGV("+%s()", __FUNCTION__);
+    if (!FuncDolbyMS12GetDeepBufferAvailFrames) {
+        ALOGE("%s(), pls load lib first.\n", __FUNCTION__);
+        return ret;
+    }
+
+    ret = (*FuncDolbyMS12GetDeepBufferAvailFrames)(max_size);
+    ALOGV("-%s() ret %d", __FUNCTION__, ret);
+    return ret;
+}
+
 int DolbyMS12::DolbyMS12SetMainVolume(float volume)
 {
     int ret = 0;
@@ -913,6 +975,18 @@
     return ret;
 }
 
+unsigned long long DolbyMS12::DolbyMS12GetFramesConsumedDeepBufferAudio(void)
+{
+    unsigned long long ret = 0;
+    ALOGV("+%s()", __FUNCTION__);
+    if (!FuncDolbyMS12GetFramesConsumedDeepBufferAudio) {
+        return ret;
+    }
+
+    ret = (*FuncDolbyMS12GetFramesConsumedDeepBufferAudio)();
+    ALOGV("-%s() ret %llu", __FUNCTION__, ret);
+    return ret;
+}
 
 int DolbyMS12::DolbyMS12GetTotalNFramesDelay(void *ms12_pointer)
 {
diff --git a/decoder/libms12_v24/src/dolby_ms12.cpp b/decoder/libms12_v24/src/dolby_ms12.cpp
index 88b7e66..9fddada 100644
--- a/decoder/libms12_v24/src/dolby_ms12.cpp
+++ b/decoder/libms12_v24/src/dolby_ms12.cpp
@@ -167,6 +167,27 @@
     }
 }
 
+extern "C" int dolby_ms12_input_deep_buffer(void *dolbyMS12_pointer
+                                       , const void *audio_stream_out_buffer //ms12 input buffer
+                                       , size_t audio_stream_out_buffer_size //ms12 input buffer size
+                                       , int audio_stream_out_format
+                                       , int audio_stream_out_channel_num
+                                       , int audio_stream_out_sample_rate
+                                      )
+{
+    android::DolbyMS12* dolby_ms12_instance = getInstance();
+    if (dolby_ms12_instance)
+        return dolby_ms12_instance->DolbyMS12InputDeepBuffer(dolbyMS12_pointer
+                , audio_stream_out_buffer //ms12 input buffer
+                , audio_stream_out_buffer_size //ms12 input buffer size
+                , audio_stream_out_format
+                , audio_stream_out_channel_num
+                , audio_stream_out_sample_rate);
+    else {
+        return -1;
+    }
+}
+
 extern "C" int dolby_ms12_input_app(void *dolbyMS12_pointer
                                        , const void *audio_stream_out_buffer //ms12 input buffer
                                        , size_t audio_stream_out_buffer_size //ms12 input buffer size
@@ -340,6 +361,17 @@
     }
 }
 
+extern "C" int dolby_ms12_get_deep_buffer_avail_frames(int * max_size)
+{
+    ALOGV("%s()\n", __FUNCTION__);
+    android::DolbyMS12* dolby_ms12_instance = getInstance();
+    if (dolby_ms12_instance) {
+        return dolby_ms12_instance->DolbyMS12GetDeepBufferAvailFrames(max_size);
+    } else {
+        return -1;
+    }
+}
+
 extern "C" int dolby_ms12_set_main_volume(float volume)
 {
     ALOGV("%s()\n", __FUNCTION__);
@@ -465,6 +497,17 @@
     }
 }
 
+extern "C" unsigned long long dolby_ms12_get_consumed_deep_buffer_audio(void)
+{
+    ALOGV("%s()\n", __FUNCTION__);
+    android::DolbyMS12* dolby_ms12_instance = getInstance();
+    if (dolby_ms12_instance) {
+        return dolby_ms12_instance->DolbyMS12GetFramesConsumedDeepBufferAudio();
+    } else {
+        return -1;
+    }
+}
+
 extern "C" int dolby_ms12_get_total_nframes_delay(void *ms12_pointer)
 {
     ALOGV("%s()\n", __FUNCTION__);