1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 *
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10
11 #include "uvoice_types.h"
12 #include "uvoice_player.h"
13 #include "uvoice_recorder.h"
14
15 #include "uvoice_os.h"
16 #include "uvoice_common.h"
17 #include "uvoice_play.h"
18 #include "uvoice_record.h"
19 #include "uvoice_format.h"
20
21
22 struct file_loader {
23 char filename[256];
24 os_file_t stream;
25 int file_length;
26 int rd_pos;
27 long seek_offset;
28 os_mutex_t lock;
29 };
30
31 struct file_packer {
32 os_file_t stream;
33 os_mutex_t lock;
34 };
35
file_get_format(void * priv,media_format_t * format)36 static int file_get_format(void *priv, media_format_t *format)
37 {
38 media_loader_t *mloader = (media_loader_t *)priv;
39 struct file_loader *loader;
40 uint8_t *head_buffer;
41 int buffer_size;
42 int file_pos;
43 int ret;
44
45 if (!mloader) {
46 M_LOGE("mloader null !\n");
47 return -1;
48 }
49
50 loader = mloader->loader;
51 if (!loader) {
52 M_LOGE("loader null !\n");
53 return -1;
54 }
55
56 os_mutex_lock(loader->lock, OS_WAIT_FOREVER);
57
58 if (!OS_FILE_OPENING(loader->stream)) {
59 M_LOGE("file not open !\n");
60 os_mutex_unlock(loader->lock);
61 return -1;
62 }
63
64 buffer_size = MIN(512, loader->file_length);
65 head_buffer = snd_zalloc(buffer_size, AFM_EXTN);
66 if (!head_buffer) {
67 M_LOGE("alloc buffer failed !\n");
68 os_mutex_unlock(loader->lock);
69 return -1;
70 }
71
72 file_pos = os_ftell(loader->stream);
73 if (file_pos < 0)
74 file_pos = loader->rd_pos;
75 (void)os_fseek(loader->stream, 0, OS_SEEK_SET);
76 ret = os_fread(head_buffer, 1, buffer_size, loader->stream);
77 if (ret != buffer_size) {
78 M_LOGE("read failed %d!\n", ret);
79 (void)os_fseek(loader->stream, file_pos, OS_SEEK_SET);
80 snd_free(head_buffer);
81 os_mutex_unlock(loader->lock);
82 return -1;
83 }
84 (void)os_fseek(loader->stream, file_pos, OS_SEEK_SET);
85 os_mutex_unlock(loader->lock);
86
87 if (flac_format_check(head_buffer, buffer_size)) {
88 *format = MEDIA_FMT_FLAC;
89 M_LOGD("format FLAC\n");
90 } else if (mp3_format_check(head_buffer, buffer_size)) {
91 *format = MEDIA_FMT_MP3;
92 M_LOGD("format MP3\n");
93 } else if (wav_format_check(head_buffer, buffer_size)) {
94 *format = MEDIA_FMT_WAV;
95 M_LOGD("format WAV\n");
96 } else if (aac_format_check(head_buffer, buffer_size)) {
97 *format = MEDIA_FMT_AAC;
98 M_LOGD("format AAC\n");
99 } else if (m4a_format_check(head_buffer, buffer_size)) {
100 *format = MEDIA_FMT_M4A;
101 M_LOGD("format M4A\n");
102 } else if (ogg_format_check(head_buffer, buffer_size)) {
103 *format = MEDIA_FMT_OGG;
104 M_LOGD("format OGG\n");
105 } else if (wma_format_check(head_buffer, buffer_size)) {
106 *format = MEDIA_FMT_WMA;
107 M_LOGD("format WMA\n");
108 } else if (amrwb_format_check(head_buffer, buffer_size)) {
109 *format = MEDIA_FMT_AMRWB;
110 M_LOGD("format AMR-WB\n");
111 } else if (amr_format_check(head_buffer, buffer_size)) {
112 *format = MEDIA_FMT_AMR;
113 M_LOGD("format AMR\n");
114 }
115
116 snd_free(head_buffer);
117 return 0;
118 }
119
file_get_mediainfo(void * priv,media_info_t * info,media_format_t format)120 static int file_get_mediainfo(void *priv, media_info_t *info,
121 media_format_t format)
122 {
123 media_loader_t *mloader = (media_loader_t *)priv;
124 struct file_loader *loader;
125
126 if (!mloader) {
127 M_LOGE("mloader null !\n");
128 return -1;
129 }
130
131 loader = mloader->loader;
132 if (!loader) {
133 M_LOGE("loader null !\n");
134 return -1;
135 }
136
137 os_mutex_lock(loader->lock, OS_WAIT_FOREVER);
138
139 if (!OS_FILE_OPENING(loader->stream)) {
140 M_LOGE("file not open !\n");
141 os_mutex_unlock(loader->lock);
142 return -1;
143 }
144
145 if (format == MEDIA_FMT_MP3) {
146 if (loader->file_length < 128) {
147 M_LOGE("file too short !\n");
148 os_mutex_unlock(loader->lock);
149 return -1;
150 }
151 char buffer[128];
152 memset(buffer, 0, sizeof(buffer));
153
154 int file_pos = os_ftell(loader->stream);
155 if (file_pos < 0)
156 file_pos = loader->rd_pos;
157 (void)os_fseek(loader->stream, -128, OS_SEEK_END);
158 int ret = os_fread(buffer, 1, 128, loader->stream);
159 if (ret != 128) {
160 M_LOGE("read failed %d!\n", ret);
161 (void)os_fseek(loader->stream, file_pos, OS_SEEK_SET);
162 os_mutex_unlock(loader->lock);
163 return -1;
164 }
165 (void)os_fseek(loader->stream, file_pos, OS_SEEK_SET);
166
167 mp3_id3v1_parse(info, buffer, 128);
168 }
169
170 os_mutex_unlock(loader->lock);
171 return 0;
172 }
173
file_loader_reset(void * priv)174 static int file_loader_reset(void *priv)
175 {
176 media_loader_t *mloader = (media_loader_t *)priv;
177 struct file_loader *loader;
178
179 if (!mloader) {
180 M_LOGE("mloader null !\n");
181 return -1;
182 }
183
184 loader = mloader->loader;
185 if (!loader) {
186 M_LOGE("loader null !\n");
187 return -1;
188 }
189
190 os_mutex_lock(loader->lock, OS_WAIT_FOREVER);
191
192 if (OS_FILE_OPENING(loader->stream)) {
193 M_LOGE("file load not stop !\n");
194 os_mutex_unlock(loader->lock);
195 return -1;
196 }
197
198 loader->rd_pos = 0;
199 loader->seek_offset = 0;
200 loader->file_length = 0;
201 os_mutex_unlock(loader->lock);
202
203 M_LOGD("file load reset\n");
204 return 0;
205 }
206
file_loader_update(struct file_loader * loader,char * sink)207 static int file_loader_update(struct file_loader *loader, char *sink)
208 {
209 int ret;
210
211 if (!loader) {
212 M_LOGE("loader null !\n");
213 return -1;
214 }
215
216 if (!sink) {
217 M_LOGE("sink null!\n");
218 return -1;
219 }
220
221 if (loader->stream) {
222 M_LOGE("prev file not close !\n");
223 return -1;
224 }
225
226 if (strncmp(sink, "fs:", strlen("fs:"))) {
227 M_LOGE("filename invalid !\n");
228 return -1;
229 }
230
231 sink += strlen("fs:");
232 if (strlen(sink) + 1 > sizeof(loader->filename)) {
233 M_LOGE("filename length overrange !\n");
234 return -1;
235 }
236
237 memset(loader->filename, 0, sizeof(loader->filename));
238 memcpy(loader->filename, sink, strlen(sink) + 1);
239 loader->stream = os_fopen(loader->filename, "rb");
240 if (OS_FILE_OPEN_FAIL(loader->stream)) {
241 M_LOGE("open %s failed !\n", loader->filename);
242 return -1;
243 }
244
245 ret = (int)os_fseek(loader->stream, 0, OS_SEEK_END);
246 loader->file_length = os_ftell(loader->stream);
247 if (loader->file_length < 0)
248 loader->file_length = ret;
249 (void)os_fseek(loader->stream, 0, OS_SEEK_SET);
250 loader->rd_pos = 0;
251 loader->seek_offset = 0;
252
253 return 0;
254 }
255
file_loader_read(void * priv,uint8_t * buffer,int nbytes)256 static int file_loader_read(void *priv, uint8_t *buffer, int nbytes)
257 {
258 media_loader_t *mloader = (media_loader_t *)priv;
259 struct file_loader *loader;
260 int ret;
261
262 if (!mloader) {
263 M_LOGE("mloader null !\n");
264 return -1;
265 }
266
267 loader = mloader->loader;
268 if (!loader) {
269 M_LOGE("loader null !\n");
270 return -1;
271 }
272
273 if (mloader->rebase_request) {
274 mloader->rebase_request = 0;
275 loader->seek_offset = loader->rd_pos - mloader->rebase_offset;
276 M_LOGI("read pos rebase %d\n", mloader->rebase_offset);
277 }
278
279 os_mutex_lock(loader->lock, OS_WAIT_FOREVER);
280
281 if (loader->seek_offset != 0) {
282 if (loader->seek_offset > 0) {
283 if (loader->seek_offset <=
284 loader->file_length - loader->rd_pos) {
285 (void)os_fseek(loader->stream, loader->seek_offset,
286 OS_SEEK_CUR);
287 ret = os_ftell(loader->stream);
288 if (ret < 0)
289 loader->rd_pos += loader->seek_offset;
290 else
291 loader->rd_pos = ret;
292 if (mloader->message)
293 mloader->message(mloader->priv,
294 PLAYER_MSG_SEEK_DONE, (void *)loader->seek_offset);
295 }
296 } else {
297 if (abs(loader->seek_offset) <= loader->rd_pos) {
298 (void)os_fseek(loader->stream, loader->seek_offset,
299 OS_SEEK_CUR);
300 ret = os_ftell(loader->stream);
301 if (ret < 0)
302 loader->rd_pos += loader->seek_offset;
303 else
304 loader->rd_pos = ret;
305 if (mloader->message)
306 mloader->message(mloader->priv,
307 PLAYER_MSG_SEEK_DONE, (void *)loader->seek_offset);
308 }
309 }
310 loader->seek_offset = 0;
311 }
312
313 if (os_feof(loader->stream) ||
314 loader->rd_pos >= loader->file_length) {
315 nbytes = 0;
316 M_LOGD("read end\n");
317 goto __exit;
318 } else if (loader->file_length - loader->rd_pos < nbytes) {
319 nbytes = loader->file_length - loader->rd_pos;
320 M_LOGD("read tail %d\n", nbytes);
321 }
322
323 ret = os_fread(buffer, 1, nbytes, loader->stream);
324 if (os_ferror(loader->stream) || ret != nbytes) {
325 M_LOGE("read failed %d!\n", os_ferror(loader->stream));
326 os_mutex_unlock(loader->lock);
327 return -1;
328 }
329
330 loader->rd_pos += nbytes;
331
332 __exit:
333 os_mutex_unlock(loader->lock);
334 return nbytes;
335 }
336
file_loader_action(void * priv,player_action_t action,void * arg)337 static int file_loader_action(void *priv, player_action_t action, void *arg)
338 {
339 media_loader_t *mloader = (media_loader_t *)priv;
340 struct file_loader *loader;
341 int ret;
342
343 if (!mloader) {
344 M_LOGE("mloader null !\n");
345 return -1;
346 }
347
348 loader = mloader->loader;
349 if (!loader) {
350 M_LOGE("loader null !\n");
351 return -1;
352 }
353
354 if (action == PLAYER_START) {
355 os_mutex_lock(loader->lock, OS_WAIT_FOREVER);
356 if (!OS_FILE_OPENING(loader->stream)) {
357 M_LOGD("open %s\n", loader->filename);
358 loader->stream = os_fopen(loader->filename, "rb");
359 if (OS_FILE_OPEN_FAIL(loader->stream)) {
360 M_LOGE("open %s failed !\n", loader->filename);
361 os_mutex_unlock(loader->lock);
362 return -1;
363 }
364 ret = (int)os_fseek(loader->stream, 0, OS_SEEK_END);
365 loader->file_length = os_ftell(loader->stream);
366 if (loader->file_length < 0)
367 loader->file_length = ret;
368 (void)os_fseek(loader->stream, 0, OS_SEEK_SET);
369 loader->rd_pos = 0;
370 loader->seek_offset = 0;
371 M_LOGI("file_length %d\n", loader->file_length);
372 }
373 if (mloader->message) {
374 media_info_t media_info;
375 memset(&media_info, 0, sizeof(media_info_t));
376 media_info.media_size = loader->file_length;
377 mloader->message(mloader->priv,
378 PLAYER_MSG_MEDIA_INFO, &media_info);
379 }
380 os_mutex_unlock(loader->lock);
381 } else if (action == PLAYER_STOP) {
382 os_mutex_lock(loader->lock, OS_WAIT_FOREVER);
383 if (OS_FILE_OPENING(loader->stream)) {
384 M_LOGD("file close\n");
385 os_fclose(loader->stream);
386 loader->stream = NULL;
387 }
388 os_mutex_unlock(loader->lock);
389 } else if (action == PLAYER_RELOAD) {
390 os_mutex_lock(loader->lock, OS_WAIT_FOREVER);
391 if (!OS_FILE_OPENING(loader->stream)) {
392 M_LOGD("file not open\n");
393 os_mutex_unlock(loader->lock);
394 return -1;
395 }
396 M_LOGD("reload from %x\n", (uint32_t)arg);
397 loader->seek_offset = 0;
398 loader->rd_pos = (int)arg;
399 (void)os_fseek(loader->stream, (long)arg, OS_SEEK_SET);
400 os_mutex_unlock(loader->lock);
401 } else if (action == PLAYER_SEEK) {
402 os_mutex_lock(loader->lock, OS_WAIT_FOREVER);
403 loader->seek_offset = (long)arg;
404 os_mutex_unlock(loader->lock);
405 } else if (action == PLAYER_COMPLETE) {
406 os_mutex_lock(loader->lock, OS_WAIT_FOREVER);
407 if (OS_FILE_OPENING(loader->stream)) {
408 M_LOGD("file close\n");
409 os_fclose(loader->stream);
410 loader->stream = OS_FILE_CLOSED;
411 } else {
412 M_LOGW("file not open !\n");
413 }
414 os_mutex_unlock(loader->lock);
415 } else if (action == PLAYER_NEXT) {
416 os_mutex_lock(loader->lock, OS_WAIT_FOREVER);
417 if (file_loader_update(loader, (char *)arg)) {
418 M_LOGE("update failed !\n");
419 os_mutex_unlock(loader->lock);
420 return -1;
421 }
422 os_mutex_unlock(loader->lock);
423 }
424
425 return 0;
426 }
427
file_loader_create(media_loader_t * mloader,char * source)428 int file_loader_create(media_loader_t *mloader, char *source)
429 {
430 struct file_loader *loader;
431 int ret;
432
433 if (!mloader) {
434 M_LOGE("mloader null !\n");
435 return -1;
436 }
437
438 if (!source) {
439 M_LOGE("source null !\n");
440 return -1;
441 }
442
443 if (strncmp(source, "fs:", strlen("fs:"))) {
444 M_LOGE("filename invalid !\n");
445 return -1;
446 }
447
448 source += strlen("fs:");
449
450 loader = snd_zalloc(sizeof(struct file_loader), AFM_EXTN);
451 if (!loader) {
452 M_LOGE("alloc file loader failed !\n");
453 return -1;
454 }
455
456 if (strlen(source) + 1 > sizeof(loader->filename)) {
457 M_LOGE("filename length overrange !\n");
458 snd_free(loader);
459 return -1;
460 }
461
462 memcpy(loader->filename, source, strlen(source) + 1);
463
464 loader->stream = os_fopen(loader->filename, "rb");
465 if (OS_FILE_OPEN_FAIL(loader->stream)) {
466 M_LOGE("open %s failed !\n", loader->filename);
467 snd_free(loader);
468 return -1;
469 }
470 ret = os_fseek(loader->stream, 0, OS_SEEK_END);
471 loader->file_length = os_ftell(loader->stream);
472 if (loader->file_length < 0)
473 loader->file_length = ret;
474 (void)os_fseek(loader->stream, 0, OS_SEEK_SET);
475
476 if (loader->file_length <= 0) {
477 M_LOGE("file lenth %u invalid !\n", loader->file_length);
478 os_fclose(loader->stream);
479 snd_free(loader);
480 return -1;
481 }
482
483 loader->lock = os_mutex_new();
484 loader->seek_offset = 0;
485 loader->rd_pos = 0;
486
487 mloader->read = file_loader_read;
488 mloader->action = file_loader_action;
489 mloader->get_format = file_get_format;
490 mloader->get_mediainfo = file_get_mediainfo;
491 mloader->get_cacheinfo = NULL;
492 mloader->reset = file_loader_reset;
493 mloader->loader = loader;
494
495 M_LOGD("file loader create\n");
496 return 0;
497 }
498
file_loader_release(media_loader_t * mloader)499 int file_loader_release(media_loader_t *mloader)
500 {
501 struct file_loader *loader;
502
503 if (!mloader) {
504 M_LOGE("mloader null !\n");
505 return -1;
506 }
507
508 loader = mloader->loader;
509 if (!loader) {
510 M_LOGE("loader null !\n");
511 return -1;
512 }
513
514 if (OS_FILE_OPENING(loader->stream)) {
515 M_LOGD("file close\n");
516 os_fclose(loader->stream);
517 loader->stream = OS_FILE_CLOSED;
518 }
519
520 os_mutex_free(loader->lock);
521 snd_free(loader);
522 mloader->loader = NULL;
523
524 M_LOGD("file loader release\n");
525 return 0;
526 }
527
file_packer_write(void * priv,uint8_t * buffer,int nbytes)528 static int file_packer_write(void *priv, uint8_t *buffer, int nbytes)
529 {
530 media_packer_t *mpacker = (media_packer_t *)priv;
531 struct file_packer *packer;
532 int ret;
533
534 if (!mpacker) {
535 M_LOGE("mpacker null !\n");
536 return -1;
537 }
538
539 packer = mpacker->packer;
540 if (!packer) {
541 M_LOGE("packer null !\n");
542 return -1;
543 }
544
545 os_mutex_lock(packer->lock, OS_WAIT_FOREVER);
546 ret = os_fwrite(buffer, 1, nbytes, packer->stream);
547 if (os_ferror(packer->stream) || ret != nbytes) {
548 M_LOGE("write failed %d!\n", os_ferror(packer->stream));
549 os_mutex_unlock(packer->lock);
550 return -1;
551 }
552 mpacker->size += nbytes;
553
554 os_mutex_unlock(packer->lock);
555 return nbytes;
556 }
557
file_packer_update(void * priv,uint8_t * buffer,int nbytes,int pos)558 static int file_packer_update(void *priv, uint8_t *buffer,
559 int nbytes, int pos)
560 {
561 media_packer_t *mpacker = (media_packer_t *)priv;
562 struct file_packer *packer;
563 int file_pos;
564 int ret;
565
566 if (!mpacker) {
567 M_LOGE("mpacker null !\n");
568 return -1;
569 }
570
571 packer = mpacker->packer;
572 if (!packer) {
573 M_LOGE("packer null !\n");
574 return -1;
575 }
576
577 os_mutex_lock(packer->lock, OS_WAIT_FOREVER);
578 file_pos = os_ftell(packer->stream);
579 if (file_pos < 0)
580 file_pos = mpacker->size;
581 (void)os_fseek(packer->stream, pos, OS_SEEK_SET);
582
583 ret = os_fwrite(buffer, 1, nbytes, packer->stream);
584 if (os_ferror(packer->stream) || ret != nbytes) {
585 M_LOGE("write failed %d!\n", os_ferror(packer->stream));
586 os_mutex_unlock(packer->lock);
587 return -1;
588 }
589 (void)os_fseek(packer->stream, file_pos, OS_SEEK_SET);
590
591 os_mutex_unlock(packer->lock);
592 return 0;
593 }
594
file_packer_action(void * priv,recorder_action_t action,void * arg)595 static int file_packer_action(void *priv, recorder_action_t action, void *arg)
596 {
597 media_packer_t *mpacker = (media_packer_t *)priv;
598 struct file_packer *packer;
599
600 if (!mpacker) {
601 M_LOGE("mpacker null !\n");
602 return -1;
603 }
604
605 packer = mpacker->packer;
606 if (!packer) {
607 M_LOGE("packer null !\n");
608 return -1;
609 }
610
611 if (action == RECORDER_STOP)
612 M_LOGD("pack size %d\n", mpacker->size);
613
614 return 0;
615 }
616
file_packer_create(media_packer_t * mpacker,char * sink)617 int file_packer_create(media_packer_t *mpacker, char *sink)
618 {
619 struct file_packer *packer;
620
621 if (!mpacker) {
622 M_LOGE("mpacker null !\n");
623 return -1;
624 }
625
626 if (!sink) {
627 M_LOGE("sink null !\n");
628 return -1;
629 }
630
631 if (strncmp(sink, "fs:", strlen("fs:"))) {
632 M_LOGE("filename invalid !\n");
633 return -1;
634 }
635
636 sink += strlen("fs:");
637
638 packer = snd_zalloc(sizeof(struct file_packer), AFM_EXTN);
639 if (!packer) {
640 M_LOGE("alloc file packer failed !\n");
641 return -1;
642 }
643
644 packer->stream = os_fopen(sink, "wb+");
645 if (OS_FILE_OPEN_FAIL(packer->stream)) {
646 M_LOGE("open %s failed !\n", sink);
647 snd_free(packer);
648 return -1;
649 }
650 (void)os_fseek(packer->stream, 0, OS_SEEK_SET);
651
652 packer->lock = os_mutex_new();
653 mpacker->packer = packer;
654 mpacker->pack = file_packer_write;
655 mpacker->update = file_packer_update;
656 mpacker->action = file_packer_action;
657
658 M_LOGD("file packer create\n");
659 return 0;
660 }
661
file_packer_release(media_packer_t * mpacker)662 int file_packer_release(media_packer_t *mpacker)
663 {
664 struct file_packer *packer;
665
666 if (!mpacker) {
667 M_LOGE("mpacker null !\n");
668 return -1;
669 }
670
671 packer = mpacker->packer;
672 if (!packer) {
673 M_LOGE("packer null !\n");
674 return -1;
675 }
676
677 if (OS_FILE_OPENING(packer->stream)) {
678 M_LOGD("file close\n");
679 os_fclose(packer->stream);
680 }
681
682 os_mutex_free(packer->lock);
683 snd_free(packer);
684 mpacker->packer = NULL;
685
686 M_LOGD("file packer release\n");
687 return 0;
688 }
689
690