summaryrefslogtreecommitdiff
authorLianlian Zhu <lianlian.zhu@amlogic.com>2016-06-27 21:13:30 (GMT)
committer Lianlian Zhu <lianlian.zhu@amlogic.com>2016-06-28 15:14:15 (GMT)
commit0f3fb754c51196651c6bb6ef4fa72d06f6ffb789 (patch)
tree39450cf45d478195e69b279c5de9f57afe76bccc
parent8ef6e484ffe435cf56c2ca2b1295c82253429478 (diff)
downloadaudio-0f3fb754c51196651c6bb6ef4fa72d06f6ffb789.zip
audio-0f3fb754c51196651c6bb6ef4fa72d06f6ffb789.tar.gz
audio-0f3fb754c51196651c6bb6ef4fa72d06f6ffb789.tar.bz2
PD #126976: audio:support dts hdmi-in passthrough
Change-Id: I2ef383ecd1b56be11c747d1b9110bb373b1c06f1
Diffstat
-rw-r--r--libTVaudio/Android.mk3
-rw-r--r--libTVaudio/audio/Android.mk2
-rw-r--r--libTVaudio/audio/DTSHD_media_source.cpp672
-rw-r--r--libTVaudio/audio/DTSHD_media_source.h93
-rw-r--r--libTVaudio/audio/aml_audio.c14
-rw-r--r--libTVaudio/audio/android_out.cpp4
6 files changed, 783 insertions, 5 deletions
diff --git a/libTVaudio/Android.mk b/libTVaudio/Android.mk
index d2d3812..4300cec 100644
--- a/libTVaudio/Android.mk
+++ b/libTVaudio/Android.mk
@@ -30,7 +30,8 @@ LOCAL_SRC_FILES := \
audio/audio_usb_check.cpp \
audio/amaudio_main.cpp \
audio/DDP_media_source.cpp \
- audio/aml_shelf.c
+ audio/aml_shelf.c \
+ audio/DTSHD_media_source.cpp \
LOCAL_CFLAGS := -DANDROID_PLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) -DUSE_SYS_WRITE_SERVICE=1
diff --git a/libTVaudio/audio/Android.mk b/libTVaudio/audio/Android.mk
index eeb030f..2367c0c 100644
--- a/libTVaudio/audio/Android.mk
+++ b/libTVaudio/audio/Android.mk
@@ -21,7 +21,7 @@ LOCAL_SRC_FILES := \
audio_usb_check.cpp \
amaudio_main.cpp \
DDP_media_source.cpp \
-
+ DTSHD_media_source.cpp \
LOCAL_CFLAGS := -DANDROID_PLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION)
LOCAL_MODULE_TAGS := optional
diff --git a/libTVaudio/audio/DTSHD_media_source.cpp b/libTVaudio/audio/DTSHD_media_source.cpp
new file mode 100644
index 0000000..dc31927
--- a/dev/null
+++ b/libTVaudio/audio/DTSHD_media_source.cpp
@@ -0,0 +1,672 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <android/log.h>
+#include <cutils/properties.h>
+#include <pthread.h>
+
+//code here for sys write service
+#ifdef USE_SYS_WRITE_SERVICE
+#include <binder/Binder.h>
+#include <binder/IServiceManager.h>
+#include <utils/Atomic.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/threads.h>
+#include <unistd.h>
+#if ANDROID_PLATFORM_SDK_VERSION >= 21 //5.0
+#include <systemcontrol/ISystemControlService.h>
+#else
+#include <systemwrite/ISystemWriteService.h>
+#endif
+// code end
+#endif
+
+#include "DTSHD_media_source.h"
+#include "aml_audio.h"
+extern struct circle_buffer android_out_buffer;
+extern struct circle_buffer DDP_out_buffer;
+extern struct circle_buffer DD_out_buffer;
+extern int spdif_audio_type;
+namespace android {
+
+#define LOG_TAG "DTSHD_Media_Source"
+
+#ifdef USE_SYS_WRITE_SERVICE
+//code here for system write service
+class DeathNotifier: public IBinder::DeathRecipient
+{
+ public:
+ DeathNotifier() {
+ }
+
+ void binderDied(const wp<IBinder>& who) {
+ ALOGW("system_write died!");
+ }
+};
+
+
+#if ANDROID_PLATFORM_SDK_VERSION >= 21 //5.0
+//used ISystemControlService
+#define SYST_SERVICES_NAME "system_control"
+#else
+//used amSystemWriteService
+#define ISystemControlService ISystemWriteService
+#define SYST_SERVICES_NAME "system_write"
+#endif
+
+static sp<ISystemControlService> amSystemWriteService;
+static sp<DeathNotifier> amDeathNotifier;
+static Mutex amLock;
+static Mutex amgLock;
+
+const sp<ISystemControlService>& getSystemWriteServiceDts()
+{
+ Mutex::Autolock _l(amgLock);
+ if (amSystemWriteService.get() == 0) {
+ sp<IServiceManager> sm = defaultServiceManager();
+#if 0
+ sp<IBinder> binder;
+ do {
+ binder = sm->getService(String16("system_write"));
+ if (binder != 0)
+ break;
+ ALOGW("SystemWriteService not published, waiting...");
+ usleep(500000); // 0.5 s
+ } while(true);
+ if (amDeathNotifier == NULL) {
+ amDeathNotifier = new DeathNotifier();
+ }
+ binder->linkToDeath(amDeathNotifier);
+ amSystemWriteService = interface_cast<ISystemWriteService>(binder);
+#endif
+
+
+ amSystemWriteService = interface_cast<ISystemControlService>(sm->getService(String16(SYST_SERVICES_NAME)));
+
+ }
+ ALOGE_IF(amSystemWriteService==0, "no SystemWrite Service!?");
+
+ return amSystemWriteService;
+}
+void amSystemWriteSetPropertyDts(const char* key, const char* value)
+{
+ const sp<ISystemControlService>& sws = getSystemWriteServiceDts();
+ if (sws != 0) {
+ sws->setProperty(String16(key), String16(value));
+ }
+}
+//code end for system write service
+#endif
+
+//----------------------------DTS Media Source----------------------------------------------
+
+static pthread_mutex_t decode_dev_op_mutex = PTHREAD_MUTEX_INITIALIZER;
+static int decode_ThreadExitFlag = 0; //0:exit from thread; 1:thread looping
+static int decode_ThreadStopFlag = 1; //0:start; 1: stop
+static pthread_t decode_ThreadID = 0;
+
+Dtshd_Media_Source::Dtshd_Media_Source(void) {
+ ALOGI("[%s: %d]\n", __FUNCTION__, __LINE__);
+ mStarted = false;
+ mMeta = new MetaData;
+ mGroup = NULL;
+ mSample_rate = 0;
+ mChNum = 0;
+ mFrame_size = 0;
+ mStop_ReadBuf_Flag = 0; //0:start 1:stop
+
+ mDataSource=NULL;
+ mBytesReaded=0;
+ mCurrentTimeUs=0;
+ bytes_readed_sum_pre=0;
+ bytes_readed_sum=0;
+}
+
+Dtshd_Media_Source::~Dtshd_Media_Source() {
+ ALOGI("%s %d \n",__FUNCTION__,__LINE__);
+ if (mStarted) {
+ stop();
+ }
+}
+
+int Dtshd_Media_Source::GetSampleRate() {
+ ALOGI("[Dtshd_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
+ return mSample_rate;
+}
+int Dtshd_Media_Source::GetChNum() {
+ ALOGI("[Dtshd_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
+ return mChNum;
+}
+
+int Dtshd_Media_Source::Get_Stop_ReadBuf_Flag() {
+ return mStop_ReadBuf_Flag;
+}
+
+int Dtshd_Media_Source::Set_Stop_ReadBuf_Flag(int Stop) {
+ mStop_ReadBuf_Flag = Stop;
+ return 0;
+}
+
+sp<MetaData> Dtshd_Media_Source::getFormat() {
+ ALOGI("[Dtshd_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
+ return mMeta;
+}
+
+status_t Dtshd_Media_Source::start(MetaData *params) {
+ ALOGI("[Dtshd_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
+ mGroup = new MediaBufferGroup;
+ mGroup->add_buffer(new MediaBuffer(4096*2));
+ mStarted = true;
+ return OK;
+}
+
+status_t Dtshd_Media_Source::stop() {
+ ALOGI("[Dtshd_Media_Source::%s: %d]\n", __FUNCTION__, __LINE__);
+ delete mGroup;
+ mGroup = NULL;
+ mStarted = false;
+ return OK;
+}
+
+int Dtshd_Media_Source::MediaSourceRead_buffer(unsigned char *buffer, int size) {
+ int readcnt = -1;
+ int sleep_time = 0;
+ if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
+ ALOGI("[Dtshd_Media_Source::%s] dtshd mediasource stop!\n ", __FUNCTION__);
+ return -1;
+ }
+ while ((readcnt < size) && (mStop_ReadBuf_Flag == 0)
+ && (decode_ThreadStopFlag == 0)) {
+ readcnt = buffer_read(&android_out_buffer, (char*) buffer, size);
+ //ALOGI("readcnt:%d,sleep_time:%d,size:%d",readcnt,sleep_time,size);
+ if (readcnt < 0) {
+ sleep_time++;
+ usleep(1000); //1ms
+ }
+ if (sleep_time > 2000) { //wait for max 1s to get audio data
+ ALOGE("[%s] time out to read audio buffer data! wait for 2s\n ",
+ __FUNCTION__);
+ return -1;
+ }
+ }
+ return readcnt;
+}
+status_t Dtshd_Media_Source::read(MediaBuffer **out, const ReadOptions *options) {
+ *out = NULL;
+ unsigned char ptr_head[4] = { 0 };
+ unsigned char ptr_head2[IEC61937_DTS_HEAD_PTR -4] = { 0 };
+ int SyncFlag = 0;
+ int readedbytes = 0;
+ if (MediaSourceRead_buffer(&ptr_head[0], 4) < 4) {
+ readedbytes = 4;
+ ALOGI("WARNING:read %d bytes failed [%s %d]!\n", readedbytes,
+ __FUNCTION__, __LINE__);
+ return ERROR_END_OF_STREAM;
+ }
+
+ mFrame_size = 0;
+ SyncFlag = 0;
+
+ if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
+ ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__,
+ __LINE__);
+ return ERROR_END_OF_STREAM;
+ }
+ if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
+ ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__,
+ __LINE__);
+ return ERROR_END_OF_STREAM;
+ }
+ while (!SyncFlag) {
+ int i =0;
+ //DTS_SYNCWORD_IEC61937 : 0xF8724E1F
+ if ((ptr_head[0] == 0x72 && ptr_head[ 1] == 0xf8
+ &&ptr_head[2] == 0x1f && ptr_head[3] == 0x4e)||
+ (ptr_head[0] == 0xf8 && ptr_head[1] == 0x72
+ &&ptr_head[2] == 0x4e && ptr_head[3] == 0x1f)) {
+
+ if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
+ ALOGI("Stop Flag is set, stop read_buf [%s %d]",
+ __FUNCTION__, __LINE__);
+ return ERROR_END_OF_STREAM;
+ }
+ SyncFlag = 1;
+ }
+ if (SyncFlag == 0) {
+ ptr_head[0] =ptr_head[1];
+ ptr_head[1] =ptr_head[2];
+ ptr_head[2] =ptr_head[3];
+ if (MediaSourceRead_buffer(&ptr_head[3], 1) < 1) {
+ readedbytes = 1;
+ ALOGI("WARNING: read %d bytes failed [%s %d]!\n",
+ readedbytes, __FUNCTION__, __LINE__);
+ return ERROR_END_OF_STREAM;
+ }
+
+ if ((mStop_ReadBuf_Flag == 1) || (decode_ThreadStopFlag == 1)) {
+ ALOGI("Stop Flag is set, stop read_buf [%s %d]", __FUNCTION__,
+ __LINE__);
+ return ERROR_END_OF_STREAM;
+ }
+ }
+ }
+ if (MediaSourceRead_buffer(&ptr_head2[0], 4) < 4) {
+ readedbytes = 4;
+ ALOGI("WARNING:read %d bytes failed [%s %d]!\n", readedbytes,
+ __FUNCTION__, __LINE__);
+ return ERROR_END_OF_STREAM;
+ }
+ //memcpy(&mFrame_size,ptr_head2+IEC61937_DTS_HEAD_PTR-6,2);
+ //ALOGI("mFrame_size:%d",mFrame_size);
+ //memcpy(&mFrame_size,ptr_head2+IEC61937_DTS_HEAD_PTR-6,2);
+ //ado-no lib only pack dts core data
+ mFrame_size = 2040;
+ MediaBuffer *buffer;
+ status_t err = mGroup->acquire_buffer(&buffer);
+ if (err != OK) {
+ return err;
+ }
+ if (MediaSourceRead_buffer(
+ (unsigned char*) (buffer->data()),
+ mFrame_size) != mFrame_size ) {
+ ALOGI("[%s %d]stream read failed:bytes_req/%d\n", __FUNCTION__,
+ __LINE__, mFrame_size);
+ buffer->release();
+ buffer = NULL;
+ return ERROR_END_OF_STREAM;
+ }
+
+ buffer->set_range(0, mFrame_size);
+ buffer->meta_data()->setInt64(kKeyTime, 0);
+ buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
+
+ *out = buffer;
+ return OK;
+}
+
+
+//-------------------------------OMX codec------------------------------------------------
+
+const char *MEDIA_MIMETYPE_AUDIO_DTS = "audio/dtshd";
+Aml_OMX_DtsCodec::Aml_OMX_DtsCodec(void) {
+ ALOGI("[Aml_OMX_DtsCodec::%s: %d],atype %d\n", __FUNCTION__, __LINE__,spdif_audio_type);
+ m_codec = NULL;
+ status_t m_OMXClientConnectStatus = m_OMXClient.connect();
+ lock_init();
+ locked();
+ buf_decode_offset = 0;
+ buf_decode_offset_pre = 0;
+ if (m_OMXClientConnectStatus != OK) {
+ ALOGE("Err:omx client connect error\n");
+ } else {
+ const char *mine_type = NULL;
+ if (spdif_audio_type == DTSHD || spdif_audio_type == DTS)
+ mine_type = MEDIA_MIMETYPE_AUDIO_DTS;
+
+ m_OMXMediaSource = new Dtshd_Media_Source();
+ sp < MetaData > metadata = m_OMXMediaSource->getFormat();
+ metadata->setCString(kKeyMIMEType, mine_type);
+ m_codec = OMXCodec::Create(m_OMXClient.interface(), metadata, false, // createEncoder
+ m_OMXMediaSource, 0, 0);
+
+ if (m_codec != NULL) {
+ ALOGI("OMXCodec::Create success %s %d \n", __FUNCTION__, __LINE__);
+ } else {
+ ALOGE("Err: OMXCodec::Create failed %s %d \n", __FUNCTION__,
+ __LINE__);
+ }
+ }
+ unlocked();
+}
+
+Aml_OMX_DtsCodec::~Aml_OMX_DtsCodec() {
+}
+
+status_t Aml_OMX_DtsCodec::read(unsigned char *buf, unsigned *size, int *exit) {
+ MediaBuffer *srcBuffer;
+ status_t status;
+ m_OMXMediaSource->Set_Stop_ReadBuf_Flag(*exit);
+
+ if (*exit) {
+ ALOGI("NOTE:exit flag enabled! [%s %d] \n", __FUNCTION__, __LINE__);
+ *size = 0;
+ return OK;
+ }
+
+ status = m_codec->read(&srcBuffer, NULL);
+
+ if (srcBuffer == NULL) {
+ *size = 0;
+ return OK;
+ }
+
+ *size = srcBuffer->range_length();
+
+ if (status == OK && (*size != 0)) {
+ memcpy((unsigned char *) buf,
+ (unsigned char *) srcBuffer->data() + srcBuffer->range_offset(),
+ *size);
+ srcBuffer->set_range(srcBuffer->range_offset() + (*size),
+ srcBuffer->range_length() - (*size));
+ srcBuffer->meta_data()->findInt64(kKeyTime, &buf_decode_offset);
+ }
+
+ if (srcBuffer->range_length() == 0) {
+ srcBuffer->release();
+ srcBuffer = NULL;
+ }
+
+ return OK;
+}
+
+status_t Aml_OMX_DtsCodec::start() {
+ ALOGI("[Aml_OMX_DtsCodec::%s %d] enter!\n", __FUNCTION__, __LINE__);
+ status_t status = m_codec->start();
+ if (status != OK) {
+ ALOGE("Err:OMX client can't start OMX decoder! status=%d (0x%08x)\n",
+ (int) status, (int) status);
+ m_codec.clear();
+ }
+ return status;
+}
+
+void Aml_OMX_DtsCodec::stop() {
+ ALOGI("[Aml_OMX_DtsCodec::%s %d] enter!\n", __FUNCTION__, __LINE__);
+ if (m_codec != NULL) {
+ if (m_OMXMediaSource->Get_Stop_ReadBuf_Flag())
+ m_OMXMediaSource->Set_Stop_ReadBuf_Flag(1);
+ m_codec->pause();
+ m_codec->stop();
+ wp < MediaSource > tmp = m_codec;
+ m_codec.clear();
+ while (tmp.promote() != NULL) {
+ ALOGI("[Aml_OMX_DtsCodec::%s %d]wait m_codec free OK!\n", __FUNCTION__,
+ __LINE__);
+ usleep(1000);
+ }
+ m_OMXClient.disconnect();
+ m_OMXMediaSource.clear();
+ } else
+ ALOGE("m_codec==NULL, m_codec->stop() failed! [%s %d] \n", __FUNCTION__,
+ __LINE__);
+}
+
+void Aml_OMX_DtsCodec::pause() {
+ ALOGI("[Aml_OMX_DtsCodec::%s %d] \n", __FUNCTION__, __LINE__);
+ if (m_codec != NULL)
+ m_codec->pause();
+ else
+ ALOGE("m_codec==NULL, m_codec->pause() failed! [%s %d] \n",
+ __FUNCTION__, __LINE__);
+}
+
+int Aml_OMX_DtsCodec::GetDecBytes() {
+ int used_len = 0;
+ used_len = buf_decode_offset - buf_decode_offset_pre;
+ buf_decode_offset_pre = buf_decode_offset;
+ return used_len;
+}
+
+void Aml_OMX_DtsCodec::lock_init() {
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+ pthread_mutex_init(&lock, &attr);
+ pthread_mutexattr_destroy(&attr);
+}
+void Aml_OMX_DtsCodec::locked() {
+ pthread_mutex_lock (&lock);
+}
+void Aml_OMX_DtsCodec::unlocked() {
+ pthread_mutex_unlock (&lock);
+}
+
+//--------------------------------OMX_Codec_local API-------------------------------------------------
+
+Aml_OMX_DtsCodec *arm_dts_omx_codec = NULL;
+
+void omx_dts_codec_pause() {
+ if (arm_dts_omx_codec != NULL) {
+ arm_dts_omx_codec->locked();
+ arm_dts_omx_codec->pause();
+ arm_dts_omx_codec->unlocked();
+ } else
+ ALOGE("arm_dts_omx_codec==NULL arm_dts_omx_codec->pause failed! %s %d \n",
+ __FUNCTION__, __LINE__);
+}
+
+void omx_dts_codec_read(unsigned char *buf, unsigned *size, int *exit) {
+ if (arm_dts_omx_codec != NULL) {
+ arm_dts_omx_codec->locked();
+ arm_dts_omx_codec->read(buf, size, exit);
+ arm_dts_omx_codec->unlocked();
+ } else
+ ALOGE("arm_dts_omx_codec==NULL arm_dts_omx_codec->read failed! %s %d \n",
+ __FUNCTION__, __LINE__);
+}
+
+int omx_dts_codec_get_declen() {
+ int declen = 0;
+ if (arm_dts_omx_codec != NULL) {
+ arm_dts_omx_codec->locked();
+ declen = arm_dts_omx_codec->GetDecBytes();
+ arm_dts_omx_codec->unlocked();
+ } else {
+ ALOGI(
+ "NOTE:arm_dts_omx_codec==NULL arm_dts_omx_codec_get_declen() return 0! %s %d \n",
+ __FUNCTION__, __LINE__);
+ }
+ return declen;
+}
+
+int omx_dts_codec_get_FS() {
+ if (arm_dts_omx_codec != NULL) {
+ return arm_dts_omx_codec->m_OMXMediaSource->GetSampleRate();
+
+ } else {
+ ALOGI(
+ "NOTE:arm_dts_omx_codec==NULL arm_dts_omx_codec_get_FS() return 0! %s %d \n",
+ __FUNCTION__, __LINE__);
+ return 0;
+ }
+}
+
+int omx_dts_codec_get_Nch() {
+ if (arm_dts_omx_codec != NULL) {
+ return arm_dts_omx_codec->m_OMXMediaSource->GetChNum();
+ } else {
+ ALOGI(
+ "NOTE:arm_dts_omx_codec==NULL arm_dts_omx_codec_get_Nch() return 0! %s %d \n",
+ __FUNCTION__, __LINE__);
+ return 0;
+ }
+}
+
+//--------------------------------------Decoder ThreadLoop--------------------------------------------
+
+void *dts_decode_threadloop(void *args) {
+ unsigned int outlen = 0;
+ unsigned int outlen_raw = 0;
+ unsigned int outlen_pcm = 0;
+ int write_sucessed = 1;
+ int ret = 0;
+ char *tmp = NULL;
+ tmp = (char*)malloc(6144*4+6144+8);
+ if (tmp == NULL) {
+ ALOGE("malloc buffer failed\n");
+ return NULL;
+ }
+ ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__);
+ while (decode_ThreadStopFlag == 0) {
+ if (write_sucessed == 1) {
+ outlen = 0;
+ outlen_raw = 0;
+ outlen_pcm = 0;
+ omx_dts_codec_read((unsigned char*)tmp, &outlen, &(decode_ThreadStopFlag));
+ }
+ if (decode_ThreadStopFlag == 1) {
+ ALOGD("%s, exit threadloop! \n", __FUNCTION__);
+ break;
+ }
+ if (outlen > 8) {
+ memcpy(&outlen_pcm,tmp,4);
+ memcpy(&outlen_raw,tmp+4+outlen_pcm,4);
+ if (outlen_pcm > 0) {
+ ret = buffer_write(&DDP_out_buffer, tmp+4, outlen_pcm);
+ if (ret < 0) {
+ write_sucessed = 0;
+ usleep(10 * 1000); //10ms
+ } else {
+ write_sucessed = 1;
+ }
+ }
+ if (outlen_raw > 0) {
+ //ALOGI("raw data size %d\n",outlen_raw);
+ ret = buffer_write(&DD_out_buffer, tmp+4+outlen_pcm+4, outlen_raw);
+ if (ret < 0) {
+ write_sucessed = 0;
+ ALOGI("raw data write failed\n");
+ usleep(10 * 1000); //10ms
+ } else {
+#if 0
+ FILE *fp1=fopen("/data/audio_raw.wav","a+");
+ if (fp1) {
+ int flen=fwrite((char *)tmp+4+outlen_pcm+4,1,outlen_raw,fp1);
+ ALOGI("flen = %d---bytes_raw=%d ", flen, outlen_raw);
+ fclose(fp1);
+ }else{
+ ALOGI("could not open file:audio_out.pcm");
+ }
+#endif
+ write_sucessed = 1;
+ }
+ }
+ }
+ }
+ decode_ThreadExitFlag = 0;
+ if (tmp) {
+ free(tmp);
+ }
+ ALOGD("%s, exiting...\n", __FUNCTION__);
+ return NULL;
+}
+
+static int start_decode_thread_omx(void) {
+ pthread_attr_t attr;
+ struct sched_param param;
+ int ret = 0;
+
+ ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__);
+ pthread_mutex_lock(&decode_dev_op_mutex);
+ pthread_attr_init(&attr);
+ pthread_attr_setschedpolicy(&attr, SCHED_RR);
+ param.sched_priority = sched_get_priority_max(SCHED_RR);
+ pthread_attr_setschedparam(&attr, &param);
+ decode_ThreadStopFlag = 0;
+ decode_ThreadExitFlag = 1;
+ ret = pthread_create(&decode_ThreadID, &attr, &dts_decode_threadloop, NULL);
+ pthread_attr_destroy(&attr);
+ if (ret != 0) {
+ ALOGE("%s, Create thread fail!\n", __FUNCTION__);
+ pthread_mutex_unlock(&decode_dev_op_mutex);
+ return -1;
+ }
+ pthread_mutex_unlock(&decode_dev_op_mutex);
+ ALOGD("[%s] exiting...\n", __FUNCTION__);
+ return 0;
+}
+
+static int stop_decode_thread_omx(void) {
+ int i = 0, tmp_timeout_count = 1000;
+
+ ALOGI("[%s %d] enter!\n", __FUNCTION__, __LINE__);
+ pthread_mutex_lock(&decode_dev_op_mutex);
+
+ decode_ThreadStopFlag = 1;
+ while (1) {
+ if (decode_ThreadExitFlag == 0)
+ break;
+ if (i >= tmp_timeout_count)
+ break;
+ i++;
+ usleep(1000);
+ }
+ if (i >= tmp_timeout_count) {
+ ALOGE(
+ "%s, Timeout: we have try %d ms, but the aml audio thread's exec flag is still(%d)!!!\n",
+ __FUNCTION__, tmp_timeout_count, decode_ThreadExitFlag);
+ } else {
+ ALOGD("%s, kill decode thread success after try %d ms.\n", __FUNCTION__,
+ i);
+ }
+
+ pthread_join(decode_ThreadID, NULL);
+ decode_ThreadID = 0;
+ ALOGD("%s, aml audio close success.\n", __FUNCTION__);
+ pthread_mutex_unlock(&decode_dev_op_mutex);
+ return 0;
+}
+
+//-------------------------------------external OMX_codec_api-----------------------------------------
+extern "C" {
+int omx_codec_dts_init(void) {
+ int ret = 0;
+ ALOGI("omx_codec_init!\n");
+#ifndef USE_SYS_WRITE_SERVICE
+ ret=property_set("media.libplayer.dtsopt0", "1");
+ ALOGI("property_set<media.libplayer.dtsopt0> ret/%d\n",ret);
+#else
+ amSystemWriteSetPropertyDts("media.libplayer.dtsopt0", "1");
+#endif
+ arm_dts_omx_codec = new android::Aml_OMX_DtsCodec();
+ if (arm_dts_omx_codec == NULL) {
+ ALOGE("Err:arm_dts_omx_codec_init failed!\n");
+ return -1;
+ }
+
+ arm_dts_omx_codec->locked();
+ ret = arm_dts_omx_codec->start();
+ arm_dts_omx_codec->unlocked();
+ if (ret < 0) {
+ goto Exit;
+ }
+
+ ret = start_decode_thread_omx();
+ if (ret == 0)
+ return 0;
+ Exit: arm_dts_omx_codec->stop();
+ delete arm_dts_omx_codec;
+ arm_dts_omx_codec = NULL;
+ return -1;
+}
+
+void omx_codec_dts_close(void) {
+ int ret = 0;
+#ifndef USE_SYS_WRITE_SERVICE
+ ret=property_set("media.libplayer.dtsopt0", "0");
+ ALOGI("property_set<media.libplayer.dtsopt0> ret/%d\n",ret);
+#else
+ amSystemWriteSetPropertyDts("media.libplayer.dtsopt0", "0");
+#endif
+ if (arm_dts_omx_codec == NULL) {
+ ALOGI(
+ "NOTE:arm_dts_omx_codec==NULL arm_dts_omx_codec_close() do nothing! %s %d \n",
+ __FUNCTION__, __LINE__);
+ return;
+ }
+ ALOGI("omx_codec_close!\n");
+ stop_decode_thread_omx();
+ arm_dts_omx_codec->locked();
+ arm_dts_omx_codec->stop();
+ arm_dts_omx_codec->unlocked();
+ delete arm_dts_omx_codec;
+ arm_dts_omx_codec = NULL;
+ return;
+}
+
+}
+}
+
diff --git a/libTVaudio/audio/DTSHD_media_source.h b/libTVaudio/audio/DTSHD_media_source.h
new file mode 100644
index 0000000..bd6ae0d
--- a/dev/null
+++ b/libTVaudio/audio/DTSHD_media_source.h
@@ -0,0 +1,93 @@
+#ifndef MEDIA_DTSHD_MEDIASOURCE_H_
+#define MEDIA_DTSHD_MEDIASOURCE_H_
+
+#include "MediaSource.h"
+#include "DataSource.h"
+#include "MediaBufferGroup.h"
+#include "MetaData.h"
+#include "OMXCodec.h"
+#include "OMX_Index.h"
+#include "OMX_Core.h"
+#include "OMXClient.h"
+namespace android
+{
+
+#define AML_DCA_OMX_DECODER_NUMBUF 2
+#define AML_DCA_SW_CORE_16M 0x7ffe8001
+#define AML_DCA_SW_CORE_14M 0x1fffe800
+#define AML_DCA_SW_CORE_24M 0xfe80007f
+#define AML_DCA_SW_CORE_16 0xfe7f0180
+#define AML_DCA_SW_CORE_14 0xff1f00e8
+#define AML_DCA_SW_CORE_24 0x80fe7f01
+#define AML_DCA_SW_SUBSTREAM_M 0x64582025
+#define AML_DCA_SW_SUBSTREAM 0x58642520
+#define IEC61937_DTS_HEAD_PTR 20
+
+
+class Dtshd_Media_Source : public MediaSource{
+public:
+ Dtshd_Media_Source(void);
+
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop();
+ virtual sp<MetaData> getFormat();
+ virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL);
+
+ //virtual int GetReadedBytes();
+ virtual int GetSampleRate();
+ virtual int GetChNum();
+ virtual int Get_Stop_ReadBuf_Flag();
+ virtual int Set_Stop_ReadBuf_Flag(int pStop);
+ virtual int MediaSourceRead_buffer(unsigned char *buffer, int size);
+
+ int mSample_rate;
+ int mChNum;
+ int mFrame_size;
+ int FrameSizeDetectFlag;
+ int mStop_ReadBuf_Flag;
+ int64_t bytes_readed_sum_pre;
+ int64_t bytes_readed_sum;
+protected:
+ virtual ~Dtshd_Media_Source();
+
+private:
+ bool mStarted;
+ sp<DataSource> mDataSource;
+ sp<MetaData> mMeta;
+ MediaBufferGroup *mGroup;
+ int64_t mCurrentTimeUs;
+ int mBytesReaded;
+ int block_align;
+ Dtshd_Media_Source(const Dtshd_Media_Source &);
+ Dtshd_Media_Source &operator=(const Dtshd_Media_Source &);
+};
+
+class Aml_OMX_DtsCodec {
+public:
+
+ Aml_OMX_DtsCodec(void);
+
+ OMXClient m_OMXClient;
+ sp<Dtshd_Media_Source> m_OMXMediaSource;
+ sp<MediaSource> m_codec;
+
+ int read(unsigned char *buf, unsigned *size, int* exit);
+ status_t start();
+ void pause();
+ void stop();
+ void lock_init();
+ void locked();
+ void unlocked();
+ int GetDecBytes();
+
+ int64_t buf_decode_offset;
+ int64_t buf_decode_offset_pre;
+ pthread_mutex_t lock;
+
+ ~Aml_OMX_DtsCodec();
+};
+
+}
+
+#endif
+
diff --git a/libTVaudio/audio/aml_audio.c b/libTVaudio/audio/aml_audio.c
index 4f862c6..cef7fb7 100644
--- a/libTVaudio/audio/aml_audio.c
+++ b/libTVaudio/audio/aml_audio.c
@@ -240,7 +240,10 @@ static unsigned int gUSBCheckLastFlag = 0;
static unsigned int gUSBCheckFlag = 0;
extern int omx_codec_init(void);
+extern int omx_codec_dts_init(void);
extern void omx_codec_close(void);
+extern void omx_codec_dts_close(void);
+
extern int I2S_state;
#define I2S_IN_AUDIO_TYPE "I2SIN Audio Type"
@@ -1334,7 +1337,9 @@ static int aml_device_close(struct aml_dev *device) {
} else if (out->output_device == CC_OUT_USE_ANDROID) {
release_audiotrack(out);
}
+
omx_codec_close();
+ omx_codec_dts_close();
omx_started = 0;
tmp_buffer_release (&DDP_out_buffer);
tmp_buffer_release (&DD_out_buffer);
@@ -1473,12 +1478,17 @@ err_exit:
out->output_device = CC_OUT_USE_ANDROID;
set_Hardware_resample(4);
digital_raw_enable = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
- omx_codec_init();
+ if (audioin_type == AC3 || audioin_type == EAC3)
+ omx_codec_init();
+ if (audioin_type == DTS || audioin_type == DTSHD)
+ omx_codec_dts_init();
return 0;
}
static int set_rawdata_in_disable(struct aml_stream_out *out) {
+
omx_codec_close();
+ omx_codec_dts_close();
if ((gUSBCheckFlag & AUDIO_DEVICE_OUT_SPEAKER) != 0) {
if (out->user_set_device == CC_OUT_USE_AMAUDIO) {
set_output_deviceID(MODEAMAUDIO);
@@ -1545,7 +1555,7 @@ static int check_audio_type(struct aml_stream_out *out) {
else if (omx_started == 1) {
int digtal_out = amsysfs_get_sysfs_int("/sys/class/audiodsp/digital_raw");
int need_reset_config = 0;
- if (audioin_type == EAC3 && digtal_out != digital_raw_enable) {
+ if ((audioin_type == DTS ||audioin_type == EAC3) && digtal_out != digital_raw_enable) {
ALOGI("DD+ passthrough flag changed from %d to %d\n",digital_raw_enable,digtal_out);
need_reset_config = 1;
}
diff --git a/libTVaudio/audio/android_out.cpp b/libTVaudio/audio/android_out.cpp
index da7f9dd..a20ca72 100644
--- a/libTVaudio/audio/android_out.cpp
+++ b/libTVaudio/audio/android_out.cpp
@@ -214,7 +214,9 @@ static int RawAudioTrackInit(audio_format_t aformat,int sr)
glpTracker_raw = gmpAudioTracker_raw.get();
Status = glpTracker_raw->set(AUDIO_STREAM_MUSIC, sr, aformat,
- AUDIO_CHANNEL_OUT_STEREO, 0, AUDIO_OUTPUT_FLAG_DIRECT,
+ AUDIO_CHANNEL_OUT_STEREO, 0, (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DIRECT
+ | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
+ ,
RawAudioTrackCallback/*NULL*/, NULL, 0, 0, false, 0);
if (Status != NO_ERROR) {
ALOGE("%s, AudioTrack raw set failed.\n", __FUNCTION__);