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