blob: 84cb1b5b505f4afd87fe7cc9764527651b7b2af9
1 | #include <stdio.h> |
2 | #include <stdarg.h> |
3 | #include <string.h> |
4 | #include <android/log.h> |
5 | #include <cutils/properties.h> |
6 | #include "DTSHD_mediasource.h" |
7 | |
8 | extern "C" int read_buffer(unsigned char *buffer,int size); |
9 | |
10 | #define LOG_TAG "DTSHD_Medissource" |
11 | #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) |
12 | #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) |
13 | |
14 | |
15 | namespace android { |
16 | static int AML_Match_DTS_SyncWord(uint32_t ui32Temp0, uint32_t ui32Temp1) |
17 | { |
18 | /* 16-bit bit core stream*/ |
19 | if( ui32Temp0 == AML_DCA_SW_CORE_16 || ui32Temp0 == AML_DCA_SW_CORE_14 || |
20 | ui32Temp0 == AML_DCA_SW_CORE_16M || ui32Temp0 == AML_DCA_SW_CORE_14M || |
21 | ui32Temp0 == AML_DCA_SW_SUBSTREAM|| ui32Temp0 ==AML_DCA_SW_SUBSTREAM_M) |
22 | { |
23 | return 1; |
24 | } |
25 | |
26 | if ((ui32Temp0 & 0xffffff00) == (AML_DCA_SW_CORE_24 & 0xffffff00) && |
27 | ((ui32Temp1 >> 16) & 0xFF)== (AML_DCA_SW_CORE_24 & 0xFF)) |
28 | { |
29 | return 1; |
30 | } |
31 | return 0; |
32 | } |
33 | static int AML_DCA_Estimate_Frame_size( unsigned char *buf,int size,int *syncpos) |
34 | { |
35 | int i32Index=0; |
36 | int result=0; |
37 | unsigned int ui32Sword0=0,ui32Sword1=0; |
38 | unsigned int ui32Sword0_save=0; |
39 | int first_sync_Detected=0,first_sync_pos=-1; |
40 | int frame_size=0; |
41 | *syncpos=0; |
42 | for (i32Index=0; i32Index+7<size;i32Index++) |
43 | { |
44 | ui32Sword0 = buf[i32Index]; ui32Sword0 <<= 8; |
45 | ui32Sword0 |= buf[i32Index + 1]; ui32Sword0 <<= 8; |
46 | ui32Sword0 |= buf[i32Index + 2]; ui32Sword0 <<= 8; |
47 | ui32Sword0 |= buf[i32Index + 3]; |
48 | |
49 | ui32Sword1 = buf[i32Index + 4]; ui32Sword1 <<= 8; |
50 | ui32Sword1 |= buf[i32Index + 5]; ui32Sword1 <<= 8; |
51 | ui32Sword1 |= buf[i32Index + 6]; ui32Sword1 <<= 8; |
52 | ui32Sword1 |= buf[i32Index + 7]; |
53 | |
54 | result=AML_Match_DTS_SyncWord(ui32Sword0,ui32Sword1); |
55 | |
56 | if (result) { |
57 | ALOGI("SyncWord detect: ui32Sync_word/0x%x ui32Sync_word2/0x%x ",ui32Sword0,ui32Sword1); |
58 | if (first_sync_Detected == 0) |
59 | { |
60 | first_sync_Detected=1; |
61 | first_sync_pos=i32Index; |
62 | ui32Sword0_save=ui32Sword0; |
63 | ALOGI("first_sync_pos/%d ",first_sync_pos); |
64 | }else if(first_sync_Detected == 1){ |
65 | if (ui32Sword0_save == ui32Sword0) |
66 | { |
67 | frame_size=i32Index-first_sync_pos; |
68 | ALOGI("FrameSize detect: %d/bytes",frame_size); |
69 | break; |
70 | } |
71 | } |
72 | } |
73 | } |
74 | |
75 | if (frame_size == 0) |
76 | { |
77 | ALOGE("[%s %d ]FrameSize detect Falied,used defualt value/1024\n",__FUNCTION__,__LINE__); |
78 | frame_size=1024; |
79 | }else{ |
80 | frame_size += 4; |
81 | } |
82 | *syncpos=first_sync_pos; |
83 | return frame_size; |
84 | } |
85 | |
86 | Dtshd_MediaSource::Dtshd_MediaSource(void *read_buffer) |
87 | { |
88 | ALOGI("%s %d \n",__FUNCTION__,__LINE__); |
89 | mStarted=false; |
90 | mMeta=new MetaData; |
91 | mDataSource=NULL; |
92 | mGroup=NULL; |
93 | mBytesReaded=0; |
94 | mCurrentTimeUs=0; |
95 | pStop_ReadBuf_Flag=NULL; |
96 | fpread_buffer=(fp_read_buffer)read_buffer; |
97 | sample_rate=0; |
98 | ChNum=0; |
99 | frame_size=0; |
100 | bytes_readed_sum_pre=0; |
101 | bytes_readed_sum=0; |
102 | FrameSizeDetectFlag=0; |
103 | FirFraBuf=NULL; |
104 | FirFraBuf_Len=0; |
105 | FirFraBuf_Offset=0; |
106 | FrameNumReaded=0; |
107 | mMeta->setInt32(kKeyChannelCount,/* audec->channels > 0?audec->channels:*/2); |
108 | mMeta->setInt32(kKeySampleRate, /*audec->samplerate> 0?audec->samplerate:*/48000); |
109 | } |
110 | |
111 | |
112 | Dtshd_MediaSource::~Dtshd_MediaSource() |
113 | { |
114 | ALOGI("%s %d \n",__FUNCTION__,__LINE__); |
115 | if (FirFraBuf) |
116 | free(FirFraBuf); |
117 | if (mStarted) { |
118 | stop(); |
119 | } |
120 | } |
121 | |
122 | |
123 | int Dtshd_MediaSource::GetSampleRate() |
124 | { |
125 | return sample_rate; |
126 | } |
127 | |
128 | int Dtshd_MediaSource::GetChNum() |
129 | { |
130 | return ChNum; |
131 | } |
132 | int Dtshd_MediaSource::SetSampleRate(int samplerate) |
133 | { |
134 | sample_rate = samplerate; |
135 | return OK ; |
136 | } |
137 | |
138 | int* Dtshd_MediaSource::Get_pStop_ReadBuf_Flag() |
139 | { |
140 | return pStop_ReadBuf_Flag; |
141 | } |
142 | |
143 | int Dtshd_MediaSource::Set_pStop_ReadBuf_Flag(int *pStop) |
144 | { |
145 | pStop_ReadBuf_Flag = pStop; |
146 | return 0; |
147 | } |
148 | |
149 | int Dtshd_MediaSource::GetReadedBytes() |
150 | { |
151 | return frame_size; |
152 | } |
153 | |
154 | sp<MetaData> Dtshd_MediaSource::getFormat() |
155 | { |
156 | ALOGI("%s %d \n",__FUNCTION__,__LINE__); |
157 | return mMeta; |
158 | } |
159 | |
160 | status_t Dtshd_MediaSource::start(MetaData *params) |
161 | { |
162 | ALOGI("%s %d \n",__FUNCTION__,__LINE__); |
163 | mGroup = new MediaBufferGroup; |
164 | mGroup->add_buffer(new MediaBuffer(AML_DCA_INPUT_DATA_LEN_PTIME)); |
165 | mStarted = true; |
166 | return OK; |
167 | } |
168 | |
169 | status_t Dtshd_MediaSource::stop() |
170 | { |
171 | ALOGI("%s %d \n",__FUNCTION__,__LINE__); |
172 | delete mGroup; |
173 | mGroup = NULL; |
174 | mStarted = false; |
175 | return OK; |
176 | } |
177 | |
178 | |
179 | int Dtshd_MediaSource::MediaSourceRead_buffer(unsigned char *buffer,int size) |
180 | { |
181 | int readcnt=0; |
182 | int readsum=0; |
183 | if (fpread_buffer != NULL) |
184 | { |
185 | int sleep_time=0; |
186 | while ((readsum < size)&& (*pStop_ReadBuf_Flag == 0)) |
187 | { |
188 | readcnt=fpread_buffer(buffer+readsum,size-readsum); |
189 | if (readcnt < (size-readsum)) |
190 | { |
191 | sleep_time++; |
192 | usleep(10000); |
193 | } |
194 | readsum+=readcnt; |
195 | if ((sleep_time > 0) && (sleep_time%100 == 0) ) |
196 | { //wait for max 10s to get audio data |
197 | ALOGE("[%s] Can't get data from audiobuffer,wait for %d ms\n ", __FUNCTION__,sleep_time*10); |
198 | } |
199 | } |
200 | bytes_readed_sum +=readsum; |
201 | if (*pStop_ReadBuf_Flag == 1) |
202 | { |
203 | ALOGI("[%s] End of Stream: *pStop_ReadBuf_Flag==1\n ", __FUNCTION__); |
204 | } |
205 | return readsum; |
206 | }else{ |
207 | ALOGE("[%s]ERR: fpread_buffer=NULL\n ", __FUNCTION__); |
208 | return 0; |
209 | } |
210 | } |
211 | |
212 | |
213 | status_t Dtshd_MediaSource::read(MediaBuffer **out, const ReadOptions *options) |
214 | { |
215 | *out = NULL; |
216 | int read_bytes_per_time; |
217 | MediaBuffer *buffer; |
218 | int byte_readed=0; |
219 | status_t err; |
220 | if (!FrameSizeDetectFlag) |
221 | { |
222 | FirFraBuf=(unsigned char*)malloc(AML_DCA_INPUT_DATA_LEN_PTIME); |
223 | if (FirFraBuf == NULL) |
224 | { |
225 | ALOGE("[%s %d] mallco memory for <FirFraBuf> failed!\n",__FUNCTION__,__LINE__); |
226 | return ERROR_END_OF_STREAM; |
227 | } |
228 | FirFraBuf_Len=AML_DCA_INPUT_DATA_LEN_PTIME; |
229 | if (MediaSourceRead_buffer(FirFraBuf,FirFraBuf_Len) != FirFraBuf_Len) |
230 | { |
231 | ALOGE("[%s %d] Stream Lengh <%d> Err!\n",__FUNCTION__,__LINE__,FirFraBuf_Len); |
232 | return ERROR_END_OF_STREAM; |
233 | } |
234 | |
235 | frame_size= AML_DCA_Estimate_Frame_size(FirFraBuf,FirFraBuf_Len,&FirFraBuf_Offset); |
236 | if (frame_size == 0) |
237 | { |
238 | ALOGE("[%s %d] Detect Frame_size Err!\n",__FUNCTION__,__LINE__); |
239 | return ERROR_END_OF_STREAM; |
240 | } |
241 | FrameSizeDetectFlag=1; |
242 | } |
243 | |
244 | err = mGroup->acquire_buffer(&buffer); |
245 | if (err != OK) { |
246 | ALOGE("[%s %d] mGroup->acquire_buffer ERR!\n",__FUNCTION__,__LINE__); |
247 | return err; |
248 | } |
249 | |
250 | if (FrameNumReaded == 0 && FirFraBuf_Offset > 0) |
251 | { |
252 | int pre_suspend_bytes=0; |
253 | int redunt=FirFraBuf_Offset%4; |
254 | if(redunt) |
255 | pre_suspend_bytes=4-redunt; |
256 | unsigned char zarray[32]={0}; |
257 | memcpy((unsigned char*)(buffer->data()),FirFraBuf,FirFraBuf_Offset); |
258 | memcpy((unsigned char*)(buffer->data())+FirFraBuf_Offset, zarray, pre_suspend_bytes); |
259 | memcpy((unsigned char*)(buffer->data())+FirFraBuf_Offset+pre_suspend_bytes,FirFraBuf+FirFraBuf_Offset, frame_size); |
260 | memcpy(zarray,FirFraBuf,32); |
261 | ALOGI("[%s %d] pre_suspend_bytes/%d %s \n",__FUNCTION__,__LINE__,pre_suspend_bytes,zarray); |
262 | |
263 | buffer->set_range(0, pre_suspend_bytes+FirFraBuf_Offset+frame_size); |
264 | buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); |
265 | buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); |
266 | *out = buffer; |
267 | FirFraBuf_Offset+=frame_size; |
268 | FrameNumReaded++; |
269 | return OK; |
270 | } |
271 | |
272 | if (FirFraBuf_Offset < FirFraBuf_Len) |
273 | { |
274 | if (FirFraBuf_Len-FirFraBuf_Offset >= frame_size) |
275 | { |
276 | byte_readed=frame_size; |
277 | }else{ |
278 | byte_readed=(FirFraBuf_Len-FirFraBuf_Offset); |
279 | } |
280 | memcpy((unsigned char*)(buffer->data()),FirFraBuf+FirFraBuf_Offset,byte_readed); |
281 | FirFraBuf_Offset+=byte_readed; |
282 | if (MediaSourceRead_buffer((unsigned char*)(buffer->data())+byte_readed,frame_size-byte_readed) != (frame_size-byte_readed)) |
283 | { |
284 | buffer->release(); |
285 | buffer = NULL; |
286 | return ERROR_END_OF_STREAM; |
287 | } |
288 | |
289 | buffer->set_range(0,frame_size); |
290 | }else{ |
291 | //for dtshd coceless high samplerate stream ,framesize got maybe inaccurate and causes frozen issues |
292 | //some coceless stream framesize about 100 bytes and need push scores of frames to decoder and paser out |
293 | //one real dts frame,so change the framesize to 10k. |
294 | if (sample_rate == 96000) |
295 | frame_size = AML_DCA_INPUT_DATA_LEN_PTIME; |
296 | if (MediaSourceRead_buffer((unsigned char*)(buffer->data()), frame_size) != frame_size) |
297 | { |
298 | buffer->release(); |
299 | buffer = NULL; |
300 | return ERROR_END_OF_STREAM; |
301 | } |
302 | |
303 | buffer->set_range(0,frame_size); |
304 | } |
305 | |
306 | buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); |
307 | buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); |
308 | *out = buffer; |
309 | FrameNumReaded++; |
310 | return OK; |
311 | } |
312 | |
313 | |
314 | } // namespace android |
315 | |
316 | |
317 |