blob: ef2bfd98d27105ccdd82d364fae3051645f97c12
1 | #include <stdio.h> |
2 | #include <stdarg.h> |
3 | #include <string.h> |
4 | #include <android/log.h> |
5 | #include <cutils/properties.h> |
6 | #include "DDP_mediasource.h" |
7 | |
8 | extern "C" int read_buffer(unsigned char *buffer,int size); |
9 | |
10 | #define LOG_TAG "DDP_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 | namespace android { |
15 | |
16 | |
17 | DDPerr DDP_MediaSource::ddbs_init(DDPshort * buf, DDPshort bitptr,DDP_BSTRM *p_bstrm) |
18 | { |
19 | p_bstrm->buf = buf; |
20 | p_bstrm->bitptr = bitptr; |
21 | p_bstrm->data = *buf; |
22 | return 0; |
23 | } |
24 | |
25 | |
26 | DDPerr DDP_MediaSource::ddbs_unprj(DDP_BSTRM *p_bstrm,DDPshort *p_data, DDPshort numbits) |
27 | { |
28 | DDPushort data; |
29 | *p_data = (DDPshort)((p_bstrm->data << p_bstrm->bitptr) & msktab[numbits]); |
30 | p_bstrm->bitptr += numbits; |
31 | if (p_bstrm->bitptr >= BITSPERWRD) |
32 | { |
33 | p_bstrm->buf++; |
34 | p_bstrm->data = *p_bstrm->buf; |
35 | p_bstrm->bitptr -= BITSPERWRD; |
36 | data = (DDPushort)p_bstrm->data; |
37 | *p_data |= ((data >> (numbits - p_bstrm->bitptr)) & msktab[numbits]); |
38 | } |
39 | *p_data = (DDPshort)((DDPushort)(*p_data) >> (BITSPERWRD - numbits)); |
40 | return 0; |
41 | } |
42 | |
43 | |
44 | int DDP_MediaSource::Get_ChNum_DD(void *buf)//at least need:56bit(=7 bytes) |
45 | { |
46 | int numch=0; |
47 | DDP_BSTRM bstrm={0}; |
48 | DDP_BSTRM *p_bstrm=&bstrm; |
49 | short tmp=0,acmod,lfeon,fscod,frmsizecod; |
50 | ddbs_init((short*)buf,0,p_bstrm); |
51 | |
52 | ddbs_unprj(p_bstrm, &tmp, 16); |
53 | if (tmp!= SYNCWRD) |
54 | { |
55 | ALOGI("Invalid synchronization word"); |
56 | return 0; |
57 | } |
58 | ddbs_unprj(p_bstrm, &tmp, 16); |
59 | ddbs_unprj(p_bstrm, &fscod, 2); |
60 | if (fscod == MAXFSCOD) |
61 | { |
62 | ALOGI("Invalid sampling rate code"); |
63 | return 0; |
64 | } |
65 | |
66 | if (fscod == 0) sample_rate = 48000; |
67 | else if (fscod == 1) sample_rate = 44100; |
68 | else if (fscod == 2) sample_rate = 32000; |
69 | |
70 | ddbs_unprj(p_bstrm, &frmsizecod, 6); |
71 | if (frmsizecod >= MAXDDDATARATE) |
72 | { |
73 | ALOGI("Invalid frame size code"); |
74 | return 0; |
75 | } |
76 | |
77 | frame_size=frmsizetab[fscod][frmsizecod]; |
78 | |
79 | ddbs_unprj(p_bstrm, &tmp, 5); |
80 | if (!ISDD(tmp)) |
81 | { |
82 | ALOGI("Unsupported bitstream id"); |
83 | return 0; |
84 | } |
85 | |
86 | ddbs_unprj(p_bstrm, &tmp, 3); |
87 | ddbs_unprj(p_bstrm, &acmod, 3); |
88 | |
89 | if ((acmod!= MODE10) && (acmod& 0x1)) |
90 | { |
91 | ddbs_unprj(p_bstrm, &tmp, 2); |
92 | } |
93 | if (acmod& 0x4) |
94 | { |
95 | ddbs_unprj(p_bstrm, &tmp, 2); |
96 | } |
97 | |
98 | if (acmod == MODE20) |
99 | { |
100 | ddbs_unprj(p_bstrm,&tmp, 2); |
101 | } |
102 | ddbs_unprj(p_bstrm, &lfeon, 1); |
103 | |
104 | |
105 | numch = chanary[acmod]; |
106 | //numch+=lfeon; |
107 | ChNumOriginal=numch; |
108 | if (0) |
109 | { |
110 | if (numch >= 3) |
111 | numch = 8; |
112 | else |
113 | numch = 2; |
114 | }else{ |
115 | numch = 2; |
116 | } |
117 | ChNum=numch; |
118 | //ALOGI("DEBUG:numch=%d sample_rate=%d %p [%s %d]",ChNum,sample_rate,this,__FUNCTION__,__LINE__); |
119 | return numch; |
120 | |
121 | } |
122 | int DDP_MediaSource::Get_ChNum_DDP(void *buf)//at least need:40bit(=5 bytes) |
123 | { |
124 | |
125 | int numch=0; |
126 | DDP_BSTRM bstrm={0}; |
127 | DDP_BSTRM *p_bstrm=&bstrm; |
128 | short tmp=0,acmod,lfeon,strmtyp; |
129 | |
130 | ddbs_init((short*)buf,0,p_bstrm); |
131 | |
132 | ddbs_unprj(p_bstrm, &tmp, 16); |
133 | if (tmp!= SYNCWRD) |
134 | { |
135 | ALOGI("Invalid synchronization word"); |
136 | return 0; |
137 | } |
138 | |
139 | ddbs_unprj(p_bstrm, &strmtyp, 2); |
140 | ddbs_unprj(p_bstrm, &tmp, 3); |
141 | ddbs_unprj(p_bstrm, &tmp, 11); |
142 | frame_size=tmp+1; |
143 | //--------------------------- |
144 | if (strmtyp != 0 && strmtyp != 2) |
145 | { |
146 | return 0; |
147 | } |
148 | //--------------------------- |
149 | ddbs_unprj(p_bstrm, &tmp, 2); |
150 | |
151 | if (tmp== 0x3) |
152 | { |
153 | ALOGI("Half sample rate unsupported"); |
154 | return 0; |
155 | }else{ |
156 | if (tmp == 0) sample_rate = 48000; |
157 | else if (tmp == 1) sample_rate = 44100; |
158 | else if (tmp == 2) sample_rate = 32000; |
159 | |
160 | ddbs_unprj(p_bstrm, &tmp, 2); |
161 | } |
162 | |
163 | ddbs_unprj(p_bstrm, &acmod, 3); |
164 | ddbs_unprj(p_bstrm, &lfeon, 1); |
165 | |
166 | numch = chanary[acmod]; |
167 | //numch+=lfeon; |
168 | |
169 | ChNumOriginal=numch; |
170 | if (0) |
171 | { |
172 | if (numch >= 3) |
173 | numch = 8; |
174 | else |
175 | numch = 2; |
176 | }else{ |
177 | numch = 2; |
178 | } |
179 | ChNum=numch; |
180 | //ALOGI("DEBUG:numch=%d sample_rate=%d %p [%s %d]",ChNum,sample_rate,this,__FUNCTION__,__LINE__); |
181 | return numch; |
182 | |
183 | } |
184 | |
185 | |
186 | DDPerr DDP_MediaSource::ddbs_skip( DDP_BSTRM *p_bstrm, DDPshort numbits) |
187 | { |
188 | p_bstrm->bitptr += numbits; |
189 | while (p_bstrm->bitptr >= BITSPERWRD) |
190 | { |
191 | p_bstrm->buf++; |
192 | p_bstrm->data = *p_bstrm->buf; |
193 | p_bstrm->bitptr -= BITSPERWRD; |
194 | } |
195 | |
196 | return 0; |
197 | } |
198 | |
199 | |
200 | DDPerr DDP_MediaSource::ddbs_getbsid(DDP_BSTRM *p_inbstrm, DDPshort *p_bsid) |
201 | { |
202 | DDP_BSTRM bstrm; |
203 | |
204 | ddbs_init(p_inbstrm->buf, p_inbstrm->bitptr, &bstrm); |
205 | ddbs_skip(&bstrm, BS_BITOFFSET); |
206 | ddbs_unprj(&bstrm, p_bsid, 5); |
207 | if (!ISDDP(*p_bsid) && !ISDD(*p_bsid)) |
208 | { |
209 | ALOGI("Unsupported bitstream id"); |
210 | } |
211 | |
212 | return 0; |
213 | } |
214 | |
215 | |
216 | int DDP_MediaSource::Get_ChNum_AC3_Frame(void *buf) |
217 | { |
218 | DDP_BSTRM bstrm={0}; |
219 | DDP_BSTRM *p_bstrm=&bstrm; |
220 | DDPshort bsid; |
221 | int chnum=0; |
222 | uint8_t ptr8[PTR_HEAD_SIZE]; |
223 | |
224 | memcpy(ptr8,buf,PTR_HEAD_SIZE); |
225 | |
226 | |
227 | //ALOGI("LZG->ptr_head:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n", |
228 | // ptr8[0],ptr8[1],ptr8[2], ptr8[3],ptr8[4],ptr8[5] ); |
229 | if ((ptr8[0] == 0x0b) && (ptr8[1] == 0x77)) |
230 | { |
231 | int i; |
232 | uint8_t tmp; |
233 | for (i = 0; i < PTR_HEAD_SIZE; i += 2) |
234 | { |
235 | tmp=ptr8[i]; |
236 | ptr8[i]=ptr8[i+1]; |
237 | ptr8[i+1]=tmp; |
238 | } |
239 | } |
240 | |
241 | |
242 | ddbs_init((short*)ptr8,0,p_bstrm); |
243 | ddbs_getbsid(p_bstrm, &bsid); |
244 | //ALOGI("LZG->bsid=%d \n", bsid ); |
245 | if (ISDDP(bsid)) |
246 | { |
247 | Get_ChNum_DDP(ptr8); |
248 | }else if (ISDD(bsid)){ |
249 | Get_ChNum_DD(ptr8); |
250 | } |
251 | |
252 | return chnum; |
253 | } |
254 | |
255 | //##################################################### |
256 | |
257 | DDP_MediaSource::DDP_MediaSource(void *read_buffer) |
258 | { |
259 | ALOGI("%s %d \n",__FUNCTION__,__LINE__); |
260 | mStarted=false; |
261 | mMeta=new MetaData; |
262 | mDataSource=NULL; |
263 | mGroup=NULL; |
264 | mBytesReaded=0; |
265 | mCurrentTimeUs=0; |
266 | pStop_ReadBuf_Flag=NULL; |
267 | fpread_buffer=(fp_read_buffer)read_buffer; |
268 | sample_rate=0; |
269 | ChNum=0; |
270 | frame_size=0; |
271 | bytes_readed_sum_pre=0; |
272 | bytes_readed_sum=0; |
273 | extractor_cost_bytes = 0; |
274 | extractor_cost_bytes_last = 0; |
275 | mMeta->setInt32(kKeyChannelCount, 2); |
276 | mMeta->setInt32(kKeySampleRate, /*audec->samplerate*/48000); |
277 | memset(frame.rawbuf, 0, 6144); |
278 | memset(frame_length_his,0,sizeof(frame_length_his)); |
279 | frame.len = 0; |
280 | ChNumOriginal=0; |
281 | } |
282 | |
283 | DDP_MediaSource::~DDP_MediaSource() |
284 | { |
285 | ALOGI("%s %d \n",__FUNCTION__,__LINE__); |
286 | if (mStarted) { |
287 | stop(); |
288 | } |
289 | } |
290 | |
291 | int DDP_MediaSource::GetSampleRate() |
292 | { |
293 | return sample_rate; |
294 | } |
295 | int DDP_MediaSource::GetChNumOriginal() |
296 | { |
297 | return ChNumOriginal; |
298 | |
299 | } |
300 | int DDP_MediaSource::GetChNum() |
301 | { |
302 | return ChNum; |
303 | } |
304 | |
305 | int* DDP_MediaSource::Get_pStop_ReadBuf_Flag() |
306 | { |
307 | return pStop_ReadBuf_Flag; |
308 | } |
309 | |
310 | int DDP_MediaSource::Set_pStop_ReadBuf_Flag(int *pStop) |
311 | { |
312 | pStop_ReadBuf_Flag = pStop; |
313 | |
314 | return 0; |
315 | } |
316 | |
317 | int DDP_MediaSource::SetReadedBytes(int size) |
318 | { |
319 | mBytesReaded=size; |
320 | return 0; |
321 | } |
322 | |
323 | int DDP_MediaSource::GetReadedBytes() |
324 | { |
325 | int bytes_used; |
326 | #if 0 |
327 | bytes_used=bytes_readed_sum-bytes_readed_sum_pre; |
328 | if (bytes_used < 0) |
329 | { |
330 | ALOGI("[%s]bytes_readed_sum(%lld) < bytes_readed_sum_pre(%lld) \n",__FUNCTION__,bytes_readed_sum,bytes_readed_sum_pre); |
331 | bytes_used=0; |
332 | } |
333 | bytes_readed_sum_pre=bytes_readed_sum; |
334 | #endif |
335 | bytes_used = extractor_cost_bytes; |
336 | bytes_used -= extractor_cost_bytes_last; |
337 | extractor_cost_bytes_last += bytes_used; |
338 | return bytes_used; |
339 | } |
340 | |
341 | sp<MetaData> DDP_MediaSource::getFormat() { |
342 | ALOGI("%s %d \n",__FUNCTION__,__LINE__); |
343 | return mMeta; |
344 | } |
345 | |
346 | status_t DDP_MediaSource::start(MetaData *params) |
347 | { |
348 | ALOGI("%s %d \n",__FUNCTION__,__LINE__); |
349 | mGroup = new MediaBufferGroup; |
350 | mGroup->add_buffer(new MediaBuffer(4096)); |
351 | mStarted = true; |
352 | return OK; |
353 | } |
354 | |
355 | status_t DDP_MediaSource::stop() |
356 | { |
357 | ALOGI("%s %d \n",__FUNCTION__,__LINE__); |
358 | delete mGroup; |
359 | mGroup = NULL; |
360 | mStarted = false; |
361 | return OK; |
362 | } |
363 | |
364 | |
365 | static int calc_dd_frame_size(int code) |
366 | { |
367 | static const int FrameSize32K[] = { 96, 96, 120, 120, 144, 144, 168, 168, 192, 192, 240, 240, 288, 288, 336, 336, 384, 384, 480, 480, 576, 576, 672, 672, 768, 768, 960, 960, 1152, 1152, 1344, 1344, 1536, 1536, 1728, 1728, 1920, 1920 }; |
368 | static const int FrameSize44K[] = { 69, 70, 87, 88, 104, 105, 121, 122, 139, 140, 174, 175, 208, 209, 243, 244, 278, 279, 348, 349, 417, 418, 487, 488, 557, 558, 696, 697, 835, 836, 975, 976, 114, 1115, 1253, 1254, 1393, 1394 }; |
369 | static const int FrameSize48K[] = { 64, 64, 80, 80, 96, 96, 112, 112, 128, 128, 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448, 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152, 1152, 1280, 1280 }; |
370 | |
371 | int fscod = (code >> 6) & 0x3; |
372 | int frmsizcod = code & 0x3f; |
373 | |
374 | if (fscod == 0) return 2 * FrameSize48K[frmsizcod]; |
375 | if (fscod == 1) return 2 * FrameSize44K[frmsizcod]; |
376 | if (fscod == 2) return 2 * FrameSize32K[frmsizcod]; |
377 | |
378 | return 0; |
379 | } |
380 | int DDP_MediaSource::get_frame_size(void) |
381 | { |
382 | int i; |
383 | unsigned sum = 0; |
384 | unsigned valid_his_num = 0; |
385 | for (i = 0; i < FRAME_RECORD_NUM; i++) { |
386 | if (frame_length_his[i] > 0) { |
387 | valid_his_num ++; |
388 | sum += frame_length_his[i]; |
389 | } |
390 | } |
391 | |
392 | if (valid_his_num == 0) { |
393 | return 768; |
394 | } |
395 | return sum / valid_his_num; |
396 | } |
397 | void DDP_MediaSource::store_frame_size(int lastFrameLen) |
398 | { |
399 | /* record the frame length into the history buffer */ |
400 | int i = 0; |
401 | for (i = 0; i < FRAME_RECORD_NUM - 1; i++) { |
402 | frame_length_his[i] = frame_length_his[i + 1]; |
403 | } |
404 | frame_length_his[FRAME_RECORD_NUM - 1] = lastFrameLen; |
405 | } |
406 | int DDP_MediaSource::MediaSourceRead_buffer(unsigned char *buffer,int size) |
407 | { |
408 | int readcnt=0; |
409 | int readsum=0; |
410 | if(fpread_buffer!=NULL) |
411 | { |
412 | int sleep_time=0; |
413 | while ((readsum < size) && (*pStop_ReadBuf_Flag == 0)) |
414 | { |
415 | readcnt=fpread_buffer(buffer+readsum,size-readsum); |
416 | if (readcnt < (size - readsum)) |
417 | { |
418 | sleep_time++; |
419 | usleep(10000); |
420 | } |
421 | readsum+=readcnt; |
422 | if ((sleep_time > 0) && (sleep_time % 100 == 0)) |
423 | { //wait for max 10s to get audio data |
424 | ALOGE("[%s] Can't get data from audiobuffer,wait for %d ms\n ", __FUNCTION__,sleep_time*10); |
425 | } |
426 | } |
427 | bytes_readed_sum +=readsum; |
428 | if (*pStop_ReadBuf_Flag == 1) |
429 | { |
430 | ALOGI("[%s] End of Stream: *pStop_ReadBuf_Flag==1\n ", __FUNCTION__); |
431 | } |
432 | return readsum; |
433 | }else{ |
434 | ALOGE("[%s]ERR: fpread_buffer=NULL\n ", __FUNCTION__); |
435 | return 0; |
436 | } |
437 | } |
438 | |
439 | status_t DDP_MediaSource::read(MediaBuffer **out, const ReadOptions *options) |
440 | { |
441 | *out = NULL; |
442 | int readdiff = 0; |
443 | int read_delta = 0; |
444 | int read_size =0; |
445 | while(1){ |
446 | frame_size = 0; |
447 | read_size = get_frame_size()+PTR_HEAD_SIZE+read_delta; |
448 | if (read_size > frame.len) |
449 | read_size -= frame.len; |
450 | /*check if the read_size exceed buffer size*/ |
451 | if ((frame.len+read_size) > 6144) { |
452 | read_size = 6144 - frame.len; |
453 | } |
454 | frame.len += MediaSourceRead_buffer(frame.rawbuf + frame.len, read_size/* - frame.len*/); |
455 | if(frame.len < PTR_HEAD_SIZE){ |
456 | ALOGI("WARNING: fpread_buffer read failed [%s %d]!\n",__FUNCTION__,__LINE__); |
457 | return ERROR_END_OF_STREAM; |
458 | } |
459 | |
460 | if (*pStop_ReadBuf_Flag==1){ |
461 | ALOGI("Stop_ReadBuf_Flag==1 stop read_buf [%s %d]",__FUNCTION__,__LINE__); |
462 | return ERROR_END_OF_STREAM; |
463 | } |
464 | |
465 | unsigned short head; |
466 | head = frame.rawbuf[0] << 8 | frame.rawbuf[1]; |
467 | |
468 | if(head == 0x0b77 || head == 0x770b){ |
469 | Get_ChNum_AC3_Frame(frame.rawbuf); |
470 | frame_size=frame_size*2; |
471 | |
472 | if ((frame_size == 0) || (frame_size < PTR_HEAD_SIZE) || (frame_size > 4096)) |
473 | { |
474 | ALOGI("frame_size %d error\n",frame_size); |
475 | memcpy((char*)(frame.rawbuf),(char *)(frame.rawbuf+1), frame.len-1); |
476 | frame.len -= 1; |
477 | readdiff ++; |
478 | continue; |
479 | } |
480 | /* if framesize bigger than current frame size + syncword size.read more */ |
481 | if (frame_size > (frame.len - 2)) { |
482 | ALOGI("frame size %d exceed cached size %d,read more\n",frame_size,frame.len); |
483 | read_delta = frame_size - (frame.len -2); |
484 | continue; |
485 | } |
486 | head = (frame.rawbuf[frame_size] << 8) | frame.rawbuf[frame_size + 1]; |
487 | |
488 | if (head == 0x0b77 || head == 0x770b) { |
489 | ALOGI("next frame is ok,frame size %d\n",frame_size); |
490 | break; |
491 | }else{ |
492 | ALOGI("=====next frame sync word error %x,resync\n",head); |
493 | memmove((char*)(frame.rawbuf),(char *)(frame.rawbuf+1), frame.len-1); |
494 | frame.len -= 1; |
495 | readdiff ++; |
496 | } |
497 | }else{ |
498 | memmove((char*)(frame.rawbuf),(char *)(frame.rawbuf+1), frame.len-1); |
499 | frame.len -= 1; |
500 | readdiff ++; |
501 | } |
502 | } |
503 | read_delta = 0; |
504 | MediaBuffer *buffer; |
505 | status_t err = mGroup->acquire_buffer(&buffer); |
506 | |
507 | if (err != OK) { |
508 | return err; |
509 | } |
510 | |
511 | memcpy((unsigned char*)(buffer->data()), (unsigned char*)frame.rawbuf, frame_size); |
512 | memmove((unsigned char*)frame.rawbuf, (unsigned char*)(frame.rawbuf+frame_size), frame.len - frame_size); |
513 | frame.len -= frame_size; |
514 | buffer->set_range(0, frame_size); |
515 | buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); |
516 | buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); |
517 | |
518 | *out = buffer; |
519 | if (readdiff > 0) |
520 | { |
521 | extractor_cost_bytes += readdiff; |
522 | } |
523 | store_frame_size(frame_size); |
524 | return OK; |
525 | } |
526 | |
527 | } // namespace android |
528 | |
529 |