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