blob: adf279924ab494791d20fe5ec2099f2a239c6edc
1 | #include <stdio.h> |
2 | #include <stdarg.h> |
3 | #include <string.h> |
4 | #include <android/log.h> |
5 | #include <cutils/properties.h> |
6 | #include "MP3_mediasource.h" |
7 | |
8 | extern "C" int read_buffer(unsigned char *buffer,int size); |
9 | |
10 | #define LOG_TAG "MP3_Mediasource" |
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 | #define kMaxReadBytes 4096 |
15 | #define MaxFrameSize 4096 |
16 | static const uint32_t kMask = 0xfffe0c00; |
17 | |
18 | namespace android { |
19 | |
20 | uint32_t U32_AT(const uint8_t *ptr) |
21 | { |
22 | return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]; |
23 | } |
24 | inline bool MP3_MediaSource::GetMPEGAudioFrameSize(uint32_t header, int *frame_size, |
25 | int *out_sampling_rate, int *out_channels, int *out_bitrate, int *out_num_samples) { |
26 | *frame_size = 0; |
27 | |
28 | if (out_sampling_rate) { |
29 | *out_sampling_rate = 0; |
30 | } |
31 | |
32 | if (out_channels) { |
33 | *out_channels = 0; |
34 | } |
35 | |
36 | if (out_bitrate) { |
37 | *out_bitrate = 0; |
38 | } |
39 | |
40 | if (out_num_samples) { |
41 | *out_num_samples = 1152; |
42 | } |
43 | |
44 | if ((header & 0xffe00000) != 0xffe00000) { |
45 | return false; |
46 | } |
47 | |
48 | unsigned version = (header >> 19) & 3; |
49 | |
50 | if (version == 0x01) { |
51 | return false; |
52 | } |
53 | |
54 | unsigned layer = (header >> 17) & 3; |
55 | |
56 | if (layer == 0x00) { |
57 | return false; |
58 | } |
59 | |
60 | unsigned protection = (header >> 16) & 1; |
61 | |
62 | unsigned bitrate_index = (header >> 12) & 0x0f; |
63 | |
64 | if (bitrate_index == 0 || bitrate_index == 0x0f) { |
65 | // Disallow "free" bitrate. |
66 | return false; |
67 | } |
68 | |
69 | unsigned sampling_rate_index = (header >> 10) & 3; |
70 | |
71 | if (sampling_rate_index == 3) { |
72 | return false; |
73 | } |
74 | |
75 | static const int kSamplingRateV1[] = { 44100, 48000, 32000 }; |
76 | int sampling_rate = kSamplingRateV1[sampling_rate_index]; |
77 | if (version == 2 /* V2 */) { |
78 | sampling_rate /= 2; |
79 | } else if (version == 0 /* V2.5 */) { |
80 | sampling_rate /= 4; |
81 | } |
82 | |
83 | unsigned padding = (header >> 9) & 1; |
84 | |
85 | if (layer == 3) { |
86 | // layer I |
87 | |
88 | static const int kBitrateV1[] = { |
89 | 32, 64, 96, 128, 160, 192, 224, 256, |
90 | 288, 320, 352, 384, 416, 448 |
91 | }; |
92 | |
93 | static const int kBitrateV2[] = { |
94 | 32, 48, 56, 64, 80, 96, 112, 128, |
95 | 144, 160, 176, 192, 224, 256 |
96 | }; |
97 | |
98 | int bitrate = |
99 | (version == 3 /* V1 */) |
100 | ? kBitrateV1[bitrate_index - 1] |
101 | : kBitrateV2[bitrate_index - 1]; |
102 | |
103 | if (out_bitrate) { |
104 | *out_bitrate = bitrate; |
105 | } |
106 | |
107 | *frame_size = (12000 * bitrate / sampling_rate + padding) * 4; |
108 | |
109 | if (out_num_samples) { |
110 | *out_num_samples = 384; |
111 | } |
112 | } else { |
113 | // layer II or III |
114 | |
115 | static const int kBitrateV1L2[] = { |
116 | 32, 48, 56, 64, 80, 96, 112, 128, |
117 | 160, 192, 224, 256, 320, 384 |
118 | }; |
119 | |
120 | static const int kBitrateV1L3[] = { |
121 | 32, 40, 48, 56, 64, 80, 96, 112, |
122 | 128, 160, 192, 224, 256, 320 |
123 | }; |
124 | |
125 | static const int kBitrateV2[] = { |
126 | 8, 16, 24, 32, 40, 48, 56, 64, |
127 | 80, 96, 112, 128, 144, 160 |
128 | }; |
129 | |
130 | int bitrate; |
131 | if (version == 3 /* V1 */) { |
132 | bitrate = (layer == 2 /* L2 */) |
133 | ? kBitrateV1L2[bitrate_index - 1] |
134 | : kBitrateV1L3[bitrate_index - 1]; |
135 | |
136 | if (out_num_samples) { |
137 | *out_num_samples = 1152; |
138 | } |
139 | } else { |
140 | // V2 (or 2.5) |
141 | |
142 | bitrate = kBitrateV2[bitrate_index - 1]; |
143 | if (out_num_samples) { |
144 | *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152; |
145 | } |
146 | } |
147 | |
148 | if (out_bitrate) { |
149 | *out_bitrate = bitrate; |
150 | } |
151 | |
152 | if (version == 3 /* V1 */) { |
153 | *frame_size = 144000 * bitrate / sampling_rate + padding; |
154 | } else { |
155 | // V2 or V2.5 |
156 | size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000; |
157 | *frame_size = tmp * bitrate / sampling_rate + padding; |
158 | } |
159 | } |
160 | |
161 | if (out_sampling_rate) { |
162 | *out_sampling_rate = sampling_rate; |
163 | } |
164 | |
165 | if (out_channels) { |
166 | int channel_mode = (header >> 6) & 3; |
167 | |
168 | *out_channels = (channel_mode == 3) ? 1 : 2; |
169 | } |
170 | |
171 | return true; |
172 | } |
173 | int MP3_MediaSource::MediaSourceRead_buffer(unsigned char *buffer,int size) |
174 | { |
175 | int readcnt=0; |
176 | int readsum=0; |
177 | |
178 | if(fpread_buffer!=NULL){ |
179 | int sleep_time=0; |
180 | while((readsum<size) && (*pStop_ReadBuf_Flag==0)){ |
181 | readcnt=fpread_buffer(buffer+readsum,size-readsum); |
182 | if(readcnt<(size-readsum)){ |
183 | sleep_time++; |
184 | usleep(10000); |
185 | } |
186 | readsum+=readcnt; |
187 | if((sleep_time>0) && (sleep_time%100==0)){ //wait for max 10s to get audio data |
188 | ALOGE("[%s] Can't get data from audiobuffer,wait for %d ms\n ", __FUNCTION__,sleep_time*10); |
189 | } |
190 | } |
191 | bytes_readed_sum +=readsum; |
192 | if(*pStop_ReadBuf_Flag==1) |
193 | { |
194 | ALOGI("[%s] End of Stream: *pStop_ReadBuf_Flag==1\n ", __FUNCTION__); |
195 | } |
196 | return readsum; |
197 | }else{ |
198 | ALOGE("[%s]ERR: fpread_buffer=NULL\n ", __FUNCTION__); |
199 | return 0; |
200 | } |
201 | } |
202 | |
203 | unsigned int MP3_MediaSource::Find_header(unsigned char *buffer, int *frame_size, |
204 | int *out_sampling_rate, int *out_channels,int *out_bitrate, int *out_num_samples) |
205 | { |
206 | unsigned int readedbytes = 0; |
207 | unsigned char header_buffer[5]; |
208 | |
209 | readedbytes = MediaSourceRead_buffer(header_buffer,4); |
210 | |
211 | if (readedbytes < 4) |
212 | { |
213 | ALOGI("Read MP3 header is fail [%s %d]",__FUNCTION__,__LINE__); |
214 | return 0; |
215 | } |
216 | |
217 | while(1){ |
218 | uint32_t header = U32_AT((const uint8_t *)header_buffer); |
219 | if(GetMPEGAudioFrameSize(header, frame_size, out_sampling_rate,out_channels, |
220 | out_bitrate, out_num_samples)){ |
221 | break; |
222 | } |
223 | MediaSourceRead_buffer(&header_buffer[4],1); |
224 | memmove(&header_buffer[0],&header_buffer[1],4); |
225 | readedbytes++; |
226 | if (*pStop_ReadBuf_Flag==1){ |
227 | ALOGI("Stop_ReadBuf_Flag==1 stop read_buf [%s %d]",__FUNCTION__,__LINE__); |
228 | return 0; |
229 | } |
230 | } |
231 | memcpy(&buffer[0],&header_buffer[0],4); |
232 | return readedbytes; |
233 | } |
234 | |
235 | bool MP3_MediaSource::refind_header(unsigned char *buffer, int *frame_size, unsigned char *header_buffer, |
236 | int offset, int *readbytes) |
237 | { |
238 | int readedbytes; |
239 | unsigned char *pos_buffer = buffer; |
240 | |
241 | memcpy(&header_buffer[0],pos_buffer,4); |
242 | pos_buffer += 4; |
243 | |
244 | for(readedbytes = 4; readedbytes < offset; readedbytes++){ |
245 | uint32_t header = U32_AT((const uint8_t *)header_buffer); |
246 | |
247 | if(GetMPEGAudioFrameSize(header, frame_size, NULL,NULL,NULL, NULL)){ |
248 | *readbytes = readedbytes; |
249 | return true; |
250 | } |
251 | memcpy(&header_buffer[4],pos_buffer++,1); |
252 | memmove(&header_buffer[0],&header_buffer[1],4); |
253 | if (*pStop_ReadBuf_Flag==1){ |
254 | ALOGI("Stop_ReadBuf_Flag==1 stop read_buf [%s %d]",__FUNCTION__,__LINE__); |
255 | return false; |
256 | } |
257 | } |
258 | return false; |
259 | } |
260 | |
261 | |
262 | unsigned int MP3_MediaSource::Resync(uint32_t pos) |
263 | { |
264 | unsigned char header_buffer[10]; |
265 | uint32_t first_header = 0; |
266 | uint32_t test_header = 0; |
267 | int offset = 0; |
268 | int readbytes = 0; |
269 | uint32_t counter = 0; |
270 | int framesize = 0; |
271 | uint32_t position = pos; |
272 | uint8_t *buffer; |
273 | int left_bytes = 0; |
274 | ResyncOccurFlag=2; |
275 | SyncWordPosArray[0] = bytes_readed_sum; |
276 | BeginResync: |
277 | |
278 | ALOGI("Resync start!\n"); |
279 | left_bytes = 0; |
280 | buffer = buf; |
281 | offset = 0; |
282 | Resync_framesize[0] = 0; |
283 | Resync_framesize[1] = 0; |
284 | Resync_framesize[2] = 0; |
285 | |
286 | if(position == 0){ |
287 | readbytes = Find_header(header_buffer,&framesize,NULL,NULL,NULL,NULL); |
288 | first_header = U32_AT((const uint8_t *)header_buffer); |
289 | memcpy(buf,&header_buffer[0],4); |
290 | Resync_framesize[0] = framesize; |
291 | }else{ |
292 | Resync_framesize[0] = framesize = frame_size; |
293 | } |
294 | SyncWordPosArray[1] = bytes_readed_sum-4;//first syncword pos: |
295 | first_header = U32_AT((const uint8_t *)header_buffer); |
296 | position = 0; |
297 | |
298 | if(MediaSourceRead_buffer(buf+4,framesize-4) != (framesize-4)){ |
299 | ALOGE("Read MP3 data is fail [%s %d]",__FUNCTION__,__LINE__); |
300 | return ERROR_END_OF_STREAM; |
301 | } |
302 | offset += framesize; |
303 | Resynced_flag = 1; |
304 | |
305 | //ALOGI("first offset = [%d]\n",offset); |
306 | |
307 | do{ |
308 | readbytes = MediaSourceRead_buffer(header_buffer,4); |
309 | memcpy(buffer+offset,&header_buffer[0],4); |
310 | offset += 4; |
311 | test_header = U32_AT((const uint8_t *)header_buffer); |
312 | |
313 | Compare: |
314 | if(!GetMPEGAudioFrameSize(test_header,&framesize,NULL,NULL,NULL,NULL) || |
315 | (test_header & kMask != first_header & kMask)) |
316 | { |
317 | if(refind_header(buffer+4, &framesize, &header_buffer[0],offset-4,&readbytes) == false) |
318 | { |
319 | goto BeginResync; //can't find first header in loaded data |
320 | }else{ |
321 | first_header = U32_AT((const uint8_t *)header_buffer); //reset the first header |
322 | Resynced_flag = 1; |
323 | Resync_framesize[0] = framesize; |
324 | Resync_framesize[1] = 0; |
325 | offset -= readbytes; |
326 | memmove(buffer,buffer+readbytes,offset); |
327 | if(framesize > offset){ |
328 | readbytes = MediaSourceRead_buffer(buffer+offset,framesize - offset); |
329 | offset = framesize; |
330 | continue; |
331 | }else{ |
332 | test_header = U32_AT((const uint8_t *)(buffer+framesize)); |
333 | } goto Compare; |
334 | } |
335 | }else{ |
336 | Resynced_flag ++; |
337 | SyncWordPosArray[Resynced_flag] = bytes_readed_sum-4;//first syncword pos: |
338 | if(Resynced_flag > 3){ |
339 | ALOGI("Resynced out![%s %d]",__FUNCTION__,__LINE__); |
340 | Resynced_flag = 3; |
341 | break; |
342 | } |
343 | |
344 | left_bytes = offset - 4 - Resync_framesize[0] - Resync_framesize[1]; |
345 | Resync_framesize[Resynced_flag-1] = framesize; |
346 | |
347 | if(left_bytes == 0){ |
348 | readbytes = MediaSourceRead_buffer(buffer+offset,framesize - 4); |
349 | offset += (framesize - 4); |
350 | }else if((left_bytes < framesize) && (left_bytes > 0)){ |
351 | readbytes = MediaSourceRead_buffer(buffer+offset,framesize - left_bytes - 4); |
352 | offset += (framesize - left_bytes - 4); |
353 | }else if(left_bytes > framesize){ |
354 | test_header = U32_AT((const uint8_t *)(buffer+framesize+Resync_framesize[Resynced_flag-2])); |
355 | goto Compare; |
356 | }else{ |
357 | ALOGE("offset [%d] is invalid!left_bytes [%d] framesize [%d] [%s %d]", |
358 | offset,left_bytes,framesize,__FUNCTION__,__LINE__); |
359 | } |
360 | } |
361 | } while (Resynced_flag != 3); |
362 | ALOGI("SyncWordPosArray:%lld/ %lld/ %lld/ %lld/ %lld", |
363 | SyncWordPosArray[0],SyncWordPosArray[1],SyncWordPosArray[2],SyncWordPosArray[3],SyncWordPosArray[4]); |
364 | Resync_pos = 0; |
365 | return first_header; |
366 | } |
367 | |
368 | int MP3_MediaSource::set_MP3_MetaData(aml_audio_dec_t *audec) |
369 | { |
370 | mMeta->setInt32(kKeyChannelCount, audec->channels); |
371 | ChNum = audec->channels; |
372 | mMeta->setInt32(kKeySampleRate, audec->samplerate); |
373 | sample_rate = audec->samplerate; |
374 | |
375 | ALOGI("channel_number = [%d], samplerate = [%d]\n",ChNum,sample_rate); |
376 | |
377 | return 0; |
378 | } |
379 | |
380 | |
381 | //------------------------------------------------------------------------- |
382 | MP3_MediaSource::MP3_MediaSource(void *read_buffer, aml_audio_dec_t *audec, int *exit) |
383 | { |
384 | ALOGI("[%s] in line (%d) \n",__FUNCTION__,__LINE__); |
385 | mStarted=false; |
386 | mMeta=new MetaData; |
387 | mDataSource=NULL; |
388 | mGroup=NULL; |
389 | mCurrentTimeUs=0; |
390 | pStop_ReadBuf_Flag=exit; |
391 | fpread_buffer=(fp_read_buffer)read_buffer; |
392 | sample_rate=0; |
393 | ChNum=0; |
394 | frame_size=0; |
395 | bitrate = 0; |
396 | num_samples = 0; |
397 | Resynced_flag = 0; |
398 | buf = NULL; |
399 | mFixedHeader = 0; |
400 | start_flag = 1; |
401 | |
402 | set_MP3_MetaData(audec); |
403 | buf=(uint8_t *) malloc (sizeof(uint8_t)*kMaxReadBytes); |
404 | ResyncOccurFlag=0; |
405 | memset(SyncWordPosArray,0,sizeof(int64_t)*5); |
406 | if(buf == NULL){ |
407 | ALOGE("Malloc buffer is fail! [%s] [%d]\n",__FUNCTION__,__LINE__); |
408 | } |
409 | |
410 | } |
411 | |
412 | MP3_MediaSource::~MP3_MediaSource() |
413 | { |
414 | ALOGI("[%s] in line (%d) \n",__FUNCTION__,__LINE__); |
415 | |
416 | free( buf ); |
417 | buf = NULL; |
418 | |
419 | if (mStarted) |
420 | stop(); |
421 | } |
422 | int MP3_MediaSource::GetSampleRate() |
423 | { |
424 | return sample_rate; |
425 | } |
426 | |
427 | int MP3_MediaSource::GetChNum() |
428 | { |
429 | return ChNum; |
430 | } |
431 | |
432 | int* MP3_MediaSource::Get_pStop_ReadBuf_Flag() |
433 | { |
434 | return pStop_ReadBuf_Flag; |
435 | } |
436 | |
437 | int MP3_MediaSource::Set_pStop_ReadBuf_Flag(int *pStop) |
438 | { |
439 | pStop_ReadBuf_Flag = pStop; |
440 | return 0; |
441 | } |
442 | |
443 | int MP3_MediaSource::GetReadedBytes() |
444 | { int bytes_used = 0; |
445 | |
446 | if(ResyncOccurFlag){ |
447 | if(ResyncOccurFlag==2){ |
448 | bytes_used=SyncWordPosArray[ResyncOccurFlag]-SyncWordPosArray[0]; |
449 | }else{ |
450 | bytes_used=SyncWordPosArray[ResyncOccurFlag]-SyncWordPosArray[ResyncOccurFlag-1]; |
451 | } |
452 | ResyncOccurFlag++; |
453 | if(ResyncOccurFlag==5) |
454 | ResyncOccurFlag=0; |
455 | }else{ |
456 | bytes_used=frame_size;//bytes_readed_sum-bytes_readed_sum_pre; |
457 | } |
458 | if(bytes_used<0) |
459 | { |
460 | ALOGI("[%s]WARING: bytes_readed_sum(%lld) < bytes_readed_sum_pre(%lld) \n",__FUNCTION__, |
461 | bytes_readed_sum,bytes_readed_sum_pre); |
462 | bytes_used=0; |
463 | } |
464 | bytes_readed_sum_pre=bytes_readed_sum; |
465 | return bytes_used; |
466 | } |
467 | |
468 | sp<MetaData> MP3_MediaSource::getFormat() { |
469 | ALOGI("[%s] in line (%d) \n",__FUNCTION__,__LINE__); |
470 | return mMeta; |
471 | } |
472 | |
473 | status_t MP3_MediaSource::start(MetaData *params) |
474 | { |
475 | ALOGI("[%s] in line (%d) \n",__FUNCTION__,__LINE__); |
476 | mGroup = new MediaBufferGroup; |
477 | mGroup->add_buffer(new MediaBuffer(MaxFrameSize)); |
478 | mStarted = true; |
479 | return OK; |
480 | } |
481 | |
482 | status_t MP3_MediaSource::stop() |
483 | { |
484 | ALOGI("[%s] in line (%d) \n",__FUNCTION__,__LINE__); |
485 | delete mGroup; |
486 | mGroup = NULL; |
487 | mStarted = false; |
488 | return OK; |
489 | } |
490 | |
491 | status_t MP3_MediaSource::read(MediaBuffer **out, const ReadOptions *options) |
492 | { |
493 | *out = NULL; |
494 | uint32_t readedbytes = 0; |
495 | unsigned char header_buffer[5]; |
496 | frame_size = 0; |
497 | uint32_t header = 0; |
498 | |
499 | if (*pStop_ReadBuf_Flag==1){ |
500 | ALOGI("Stop_ReadBuf_Flag==1 stop read_buf [%s %d]",__FUNCTION__,__LINE__); |
501 | return ERROR_END_OF_STREAM; |
502 | } |
503 | |
504 | if(start_flag == 1){ |
505 | ALOGI("Start Resync the begin of stream [%s %d]",__FUNCTION__,__LINE__); |
506 | mFixedHeader = Resync(0); |
507 | start_flag = 0; |
508 | } |
509 | |
510 | MediaBuffer *buffer; |
511 | status_t err = mGroup->acquire_buffer(&buffer); |
512 | if (err != OK) { |
513 | return err; |
514 | } |
515 | |
516 | Read_data: |
517 | |
518 | if(Resynced_flag){ //read data from resync buffer |
519 | if (*pStop_ReadBuf_Flag==1){ |
520 | ALOGI("Stop_ReadBuf_Flag==1 stop read_buf [%s %d]",__FUNCTION__,__LINE__); |
521 | buffer->release(); |
522 | buffer = NULL; |
523 | return ERROR_END_OF_STREAM; |
524 | } |
525 | frame_size = Resync_framesize[3-Resynced_flag]; |
526 | memcpy((unsigned char*)(buffer->data()),&buf[Resync_pos],frame_size); |
527 | Resync_pos += frame_size; |
528 | Resynced_flag--; |
529 | }else{ |
530 | readedbytes = Find_header(header_buffer,&frame_size,&sample_rate,&ChNum,&bitrate,&num_samples); |
531 | |
532 | uint32_t header = U32_AT((const uint8_t *)header_buffer); |
533 | |
534 | if((header & kMask) != (mFixedHeader & kMask)){ |
535 | if (*pStop_ReadBuf_Flag==1){ |
536 | ALOGI("Stop_ReadBuf_Flag==1 stop read_buf [%s %d]",__FUNCTION__,__LINE__); |
537 | buffer->release(); |
538 | buffer = NULL; |
539 | return ERROR_END_OF_STREAM; |
540 | } |
541 | while(ResyncOccurFlag && *pStop_ReadBuf_Flag==0 ) |
542 | usleep(10000); |
543 | mFixedHeader = Resync(4); |
544 | memcpy(&buf[0],&header_buffer[0],4); |
545 | ALOGI("[%s]Resync the MP3! \n",__FUNCTION__); |
546 | goto Read_data; |
547 | } |
548 | |
549 | //ALOGI("frame_size = %d,sample_rate = %d,ChNum = %d, bitrate = %d, num_samples = %d readedbytes = %d\n", |
550 | // frame_size,sample_rate,ChNum,bitrate,num_samples,readedbytes); |
551 | |
552 | if(frame_size<=0) |
553 | { |
554 | ALOGE("WARNING: Invalid frame_size %d \n",frame_size); |
555 | return ERROR_END_OF_STREAM; |
556 | } |
557 | |
558 | memcpy((unsigned char*)(buffer->data()),&header_buffer[0],4); |
559 | |
560 | if (MediaSourceRead_buffer(((unsigned char*)buffer->data()+4),(frame_size-4)) != (frame_size-4)){ |
561 | buffer->release(); |
562 | buffer = NULL; |
563 | return ERROR_END_OF_STREAM; |
564 | } |
565 | } |
566 | |
567 | buffer->set_range(0, frame_size); |
568 | buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs); |
569 | buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); |
570 | |
571 | *out = buffer; |
572 | return OK; |
573 | } |
574 | |
575 | |
576 | |
577 | |
578 | } // namespace android |
579 | |
580 |