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 #include <signal.h>
11
12 #include "uvoice_os.h"
13 #include "uvoice_types.h"
14 #include "uvoice_player.h"
15 #include "uvoice_recorder.h"
16
17 #include "uvoice_common.h"
18 #include "uvoice_play.h"
19 #include "uvoice_record.h"
20 #include "uvoice_wave.h"
21
22
23 #define MP3_HEADER_MASK 0xfffe0c00
24 #define MP3_HEADER_SIZE 4
25 #define MP3_HEADER_PACK(ptr) \
26 ((ptr)[0] << 24 | (ptr)[1] << 16 | (ptr)[2] << 8 | (ptr)[3])
27
28 struct mp3_id3v2_desc {
29 char label[3];
30 char version;
31 char revision;
32 char flag;
33 char size[4];
34 };
35
36 struct mp3_id3v2_frame_header {
37 char id[4];
38 char size[4];
39 unsigned short flag;
40 };
41
mp3_id3v1_parse(media_info_t * info,unsigned char * data,int size)42 int mp3_id3v1_parse(media_info_t *info, unsigned char *data, int size)
43 {
44 unsigned char *ptr;
45
46 if (!data || !info) {
47 M_LOGE("arg null !\n");
48 return -1;
49 }
50
51 ptr = data;
52 if (memcmp(ptr, "TAG", 3)) {
53 M_LOGD("no tag\n");
54 return -1;
55 }
56
57 ptr += 3;
58 memcpy(info->name, ptr, 30);
59 ptr += 30;
60 memcpy(info->author, ptr, 30);
61 ptr += 30;
62 memcpy(info->album, ptr, 30);
63 ptr += 30;
64 memcpy(info->year, ptr, 4);
65 ptr += 4;
66 ptr += 30;
67 memcpy(&info->type, ptr, 1);
68 info->valid = 1;
69 M_LOGD("name: %s, author: %s, album: %s, year: %s, type: %u\n",
70 info->name,
71 info->author,
72 info->album, info->year, info->type);
73 return 0;
74 }
75
mp3_id3v2_parse(media_info_t * info,char * data,int size)76 static int mp3_id3v2_parse(media_info_t *info, char *data, int size)
77 {
78 struct mp3_id3v2_desc ID3;
79 struct mp3_id3v2_frame_header header;
80 int id3v2_frame_size;
81
82 if (!info || !data || size < sizeof(ID3)) {
83 M_LOGE("param invalid !\n");
84 return -1;
85 }
86
87 memcpy(&ID3, data, sizeof(ID3));
88 if (ID3.version != 3) {
89 M_LOGW("ID3 not version 3\n");
90 return -1;
91 }
92
93 //M_LOGD("label %s\n", ID3.label);
94 //M_LOGD("version %d\n", ID3.version);
95 //M_LOGD("revision %d\n", ID3.revision);
96 //M_LOGD("flag %d\n", ID3.flag);
97 id3v2_frame_size = ((ID3.size[0] & 0x7f) << 21) |
98 ((ID3.size[1] & 0x7f) << 14) |
99 ((ID3.size[2] & 0x7f) << 7) |
100 (ID3.size[3] & 0x7f);
101 //M_LOGD("size %d\n", id3v2_frame_size);
102
103 unsigned int pos = sizeof(struct mp3_id3v2_desc);
104 unsigned int frame_size = 0;
105 unsigned int frame_pos = 0;
106 unsigned int copy_size = 0;
107 unsigned int end = MIN(id3v2_frame_size, size - pos);
108 int i, j;
109
110 while (pos <= end) {
111 memcpy(&header, data + pos ,
112 sizeof(struct mp3_id3v2_frame_header));
113 frame_size = header.size[0] << 24 |
114 header.size[1] << 16 |
115 header.size[2] << 8 |
116 header.size[3];
117
118 if (frame_size == 0) {
119 pos++;
120 continue;
121 }
122
123 if (!memcmp(header.id, "TIT2", 4)) {
124 pos += frame_size + sizeof(struct mp3_id3v2_frame_header);
125 if (pos > end)
126 break;
127 frame_pos = pos - frame_size;
128 copy_size = MIN(sizeof(info->name) - 1, frame_size);
129 for (i = 0, j = 0; i < copy_size; i++) {
130 if (*(data + frame_pos + i) == '\0')
131 continue;
132 info->name[j++] = *(data + frame_pos + i);
133 }
134 info->name[j] = '\0';
135 //M_LOGD("name: %s\n", info->name);
136 } else if (!memcmp(header.id, "TPE1", 4)) {
137 pos += frame_size + sizeof(struct mp3_id3v2_frame_header);
138 if (pos > end)
139 break;
140 frame_pos = pos - frame_size;
141 copy_size = MIN(sizeof(info->author) - 1, frame_size);
142 for (i = 0, j = 0; i < copy_size; i++) {
143 if (*(data + frame_pos + i) == '\0')
144 continue;
145 info->author[j++] = *(data + frame_pos + i);
146 }
147 info->author[j] = '\0';
148 //M_LOGD("author: %s\n", info->author);
149 } else if (!memcmp(header.id, "TALB", 4)) {
150 pos += frame_size + sizeof(struct mp3_id3v2_frame_header);
151 if (pos > end)
152 break;
153 frame_pos = pos - frame_size;
154 copy_size = MIN(sizeof(info->album) - 1, frame_size);
155 for (i = 0, j = 0; i < copy_size; i++) {
156 if (*(data + frame_pos + i) == '\0')
157 continue;
158 info->album[j++] = *(data + frame_pos + i);
159 }
160 info->album[j] = '\0';
161 //M_LOGD("album: %s\n", info->album);
162 } else if (!memcmp(header.id, "TYER", 4)) {
163 pos += frame_size + sizeof(struct mp3_id3v2_frame_header);
164 if (pos > end)
165 break;
166 frame_pos = pos - frame_size;
167 copy_size = MIN(sizeof(info->year) - 1, frame_size);
168 for (i = 0, j = 0; i < copy_size; i++) {
169 if (*(data + frame_pos + i) == '\0')
170 continue;
171 info->year[j++] = *(data + frame_pos + i);
172 }
173 info->year[j] = '\0';
174 //M_LOGD("year: %s\n", info->year);
175 } else if (!memcmp(header.id, "TCON", 4)) {
176 pos += frame_size + sizeof(struct mp3_id3v2_frame_header);
177 if (pos > end)
178 break;
179 frame_pos = pos - frame_size;
180 char type[32];
181 memset(type, 0, sizeof(type));
182 copy_size = MIN(sizeof(type) - 1, frame_size);
183 for (i = 0, j = 0; i < copy_size; i++) {
184 if (*(data + frame_pos + i) == '\0')
185 continue;
186 type[j++] = *(data + frame_pos + i);
187 }
188 type[j] = '\0';
189 //M_LOGD("type: %s\n", type);
190 } else if (!memcmp(header.id, "TSSE", 4)) {
191 pos += frame_size + sizeof(struct mp3_id3v2_frame_header);
192 if (pos > end)
193 break;
194 frame_pos = pos - frame_size;
195 char tsse[32];
196 memset(tsse, 0, sizeof(tsse));
197 copy_size = MIN(sizeof(tsse) - 1, frame_size);
198 for (i = 0, j = 0; i < copy_size; i++) {
199 if (*(data + frame_pos + i) == '\0')
200 continue;
201 tsse[j++] = *(data + frame_pos + i);
202 }
203 tsse[j] = '\0';
204 //M_LOGD("tsse: %s\n", tsse);
205 } else {
206 pos++;
207 continue;
208 }
209
210 //M_LOGD("frame id %s frame_size %u frame_pos %d\n",
211 // header.id, frame_size, frame_pos);
212 }
213 return 0;
214 }
215
wav_format_check(char * buffer,int size)216 bool wav_format_check(char *buffer, int size)
217 {
218 struct riff_wave_header riff_wave_header;
219 if (buffer && size >= sizeof(riff_wave_header)) {
220 memcpy(&riff_wave_header, buffer,
221 sizeof(riff_wave_header));
222 if (riff_wave_header.riff_id == ID_RIFF &&
223 riff_wave_header.wave_id == ID_WAVE)
224 return true;
225 }
226 return false;
227 }
228
mp3_format_check(char * data,int size)229 bool mp3_format_check(char *data, int size)
230 {
231 if (!data || size < strlen("ID3")) {
232 M_LOGE("arg invalid !\n");
233 return false;
234 }
235
236 if (!memcmp(data, "ID3", strlen("ID3"))) {
237 struct mp3_id3v2_desc ID3;
238 memcpy(&ID3, data, sizeof(struct mp3_id3v2_desc));
239 M_LOGD("ID3 found, version %d\n", ID3.version);
240 if (ID3.version != 3 && ID3.version != 4)
241 return false;
242 media_info_t info;
243 memset(&info, 0, sizeof(info));
244
245 mp3_id3v2_parse(&info, data, size);
246 return true;
247 }
248
249 return false;
250 }
251
aac_format_check(char * buffer,int size)252 bool aac_format_check(char *buffer, int size)
253 {
254 return false;
255 }
256
m4a_format_check(char * buffer,int size)257 bool m4a_format_check(char *buffer, int size)
258 {
259 if (!buffer || size < 8) {
260 M_LOGE("arg invalid !\n");
261 return false;
262 }
263
264 return !memcmp(buffer + 4, "ftyp", strlen("ftyp"));
265 }
266
ogg_format_check(char * buffer,int size)267 bool ogg_format_check(char *buffer, int size)
268 {
269 if (!buffer || size < 4) {
270 M_LOGE("arg invalid !\n");
271 return false;
272 }
273
274 return !memcmp(buffer, "OggS", strlen("OggS"));
275 }
276
wma_format_check(char * buffer,int size)277 bool wma_format_check(char *buffer, int size)
278 {
279 if (!buffer || size < 4) {
280 M_LOGE("arg invalid !\n");
281 return false;
282 }
283
284 return !memcmp(buffer, "MAC ", strlen("MAC "));
285 }
286
amr_format_check(char * buffer,int size)287 bool amr_format_check(char *buffer, int size)
288 {
289 if (!buffer || size < 6) {
290 M_LOGE("arg invalid !\n");
291 return false;
292 }
293
294 return !memcmp(buffer, "#!AMR\n", strlen("#!AMR\n"));
295 }
296
amrwb_format_check(char * buffer,int size)297 bool amrwb_format_check(char *buffer, int size)
298 {
299 if (!buffer || size < 8) {
300 M_LOGE("arg invalid !\n");
301 return false;
302 }
303
304 return !memcmp(buffer, "#!AMR-WB\n", strlen("#!AMR-WB\n"));
305 }
306
ape_format_check(char * buffer,int size)307 bool ape_format_check(char *buffer, int size)
308 {
309 return false;
310 }
311
flac_format_check(char * buffer,int size)312 bool flac_format_check(char *buffer, int size)
313 {
314 if (!buffer || size < 4) {
315 M_LOGE("arg invalid !\n");
316 return false;
317 }
318
319 return !memcmp(buffer, "fLaC", strlen("fLaC"));
320 }
321
suffix_assert(char * str,char * suffix)322 static bool suffix_assert(char *str, char *suffix)
323 {
324 bool ret = false;
325
326 if (!str || !suffix || strlen(str) < strlen(suffix))
327 return ret;
328
329 ret = !memcmp((str + strlen(str) - strlen(suffix)),
330 suffix, strlen(suffix));
331
332 if (!ret) {
333 if (!strncmp(str, "http://", strlen("http://")) ||
334 !strncmp(str, "https://", strlen("https://")))
335 ret = !!strstr(str, suffix);
336 }
337
338 return ret;
339 }
340
format_parse_byname(char * name,media_format_t * format)341 int format_parse_byname(char *name, media_format_t *format)
342 {
343 if (!name || !format) {
344 M_LOGE("arg null !\n");
345 return -1;
346 }
347
348 if (suffix_assert(name, ".mp3") || suffix_assert(name, ".MP3"))
349 *format = MEDIA_FMT_MP3;
350 else if (suffix_assert(name, ".wav") || suffix_assert(name, ".WAV"))
351 *format = MEDIA_FMT_WAV;
352 else if (suffix_assert(name, ".aac") || suffix_assert(name, ".AAC"))
353 *format = MEDIA_FMT_AAC;
354 else if (suffix_assert(name, ".m4a") || suffix_assert(name, ".M4A"))
355 *format = MEDIA_FMT_M4A;
356 else if (suffix_assert(name, ".pcm") || suffix_assert(name, ".PCM"))
357 *format = MEDIA_FMT_PCM;
358 else if (suffix_assert(name, ".spx") || suffix_assert(name, ".SPX"))
359 *format = MEDIA_FMT_SPX;
360 else if (suffix_assert(name, ".ogg") || suffix_assert(name, ".OGG"))
361 *format = MEDIA_FMT_OGG;
362 else if (suffix_assert(name, ".wma") || suffix_assert(name, ".WMA"))
363 *format = MEDIA_FMT_WMA;
364 else if (suffix_assert(name, ".amrwb") || suffix_assert(name, ".AMRWB"))
365 *format = MEDIA_FMT_AMRWB;
366 else if (suffix_assert(name, ".amr") || suffix_assert(name, ".AMR"))
367 *format = MEDIA_FMT_AMR;
368 else if (suffix_assert(name, ".opus") || suffix_assert(name, ".OPUS"))
369 *format = MEDIA_FMT_OPS;
370 else if (suffix_assert(name, ".flac") || suffix_assert(name, ".FLAC"))
371 *format = MEDIA_FMT_FLAC;
372
373 return 0;
374 }
375
376