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
14 #include "uvoice_os.h"
15 #include "uvoice_config.h"
16 #include "uvoice_common.h"
17 #include "uvoice_ringbuffer.h"
18 #include "uvoice_play.h"
19 #include "uvoice_format.h"
20
21 #include "uvoice_cache.h"
22
23
24 #if (PLAYER_CACHE_TYPE != 0) && (PLAYER_CACHE_TYPE != 1) && \
25 (PLAYER_CACHE_TYPE != 2)
26 #error "cache type unsupport ! please choose from 0, 1, 2"
27 #endif
28
29 #ifdef MUSICBOX_APP
30 #define NET_CACHE_TASK_PRIORITY UVOICE_TASK_PRI_HIGHEST
31 #else
32 #define NET_CACHE_TASK_PRIORITY UVOICE_TASK_PRI_HIGHER
33 #endif
34
35 #ifndef PLAYER_CACHE_MEM_SIZE
36 #define PLAYER_CACHE_MEM_SIZE 40
37 #endif
38
39 #define NET_CACHE_REBUILD_ENABLE 1
40
41 #define NET_CACHE_FILE_ENABLE 1
42
43
net_cache_file(net_cache_t * nc)44 static int net_cache_file(net_cache_t *nc)
45 {
46 #if NET_CACHE_FILE_ENABLE
47 struct cache_file *cache;
48 int load_size = 0;
49 int rd_ret = 0;
50 int ret;
51
52 if (!nc) {
53 M_LOGE("nc null !\n");
54 return -1;
55 }
56
57 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
58 nc->cache_running = 1;
59 cache = nc->cache;
60 if (!cache) {
61 M_LOGE("cache null !\n");
62 os_mutex_unlock(nc->lock);
63 return -1;
64 }
65
66 if (cache->fp) {
67 os_fclose(cache->fp);
68 cache->fp = NULL;
69 M_LOGD("cache file close\n");
70 }
71
72 cache->fp = os_fopen(nc->cache_config.file_path, "wb+");
73 if (OS_FILE_OPEN_FAIL(cache->fp)) {
74 M_LOGE("open %s failed !\n", nc->cache_config.file_path);
75 nc->cache_running = 0;
76 os_mutex_unlock(nc->lock);
77 return -1;
78 }
79 M_LOGD("cache file open\n");
80
81 cache->wr_pos = 0;
82 (void)os_fseek(cache->fp, cache->wr_pos, OS_SEEK_SET);
83
84 if (nc->head_data_size > 0) {
85 ret = os_fwrite(nc->buffer, 1, nc->head_data_size, cache->fp);
86 if (os_ferror(cache->fp) || ret != nc->head_data_size) {
87 M_LOGE("write head data failed %d!\n",
88 os_ferror(cache->fp));
89 nc->cache_running = 0;
90 os_mutex_unlock(nc->lock);
91 return -1;
92 }
93 cache->wr_pos += nc->head_data_size;
94 nc->load_length += nc->head_data_size;
95 nc->head_data_size = 0;
96 }
97
98 load_size = MIN(nc->buffer_size,
99 nc->content_length - cache->wr_pos);
100
101 M_LOGD("start\n");
102
103 os_mutex_unlock(nc->lock);
104
105 while (1) {
106 rd_ret = nc->cache_load(nc->priv, nc->buffer, load_size);
107 if (rd_ret < 0) {
108 M_LOGE("load failed !\n");
109 nc->cache_cplt = 1;
110 break;
111 } else if (rd_ret == 0) {
112 M_LOGD("load end\n");
113 nc->cache_cplt = 1;
114 break;
115 } else if (rd_ret != load_size) {
116 M_LOGW("load %d ret %d\n", load_size, rd_ret);
117 }
118
119 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
120
121 (void)os_fseek(cache->fp, cache->wr_pos, OS_SEEK_SET);
122 ret = os_fwrite(nc->buffer, 1, rd_ret, cache->fp);
123 if (os_ferror(cache->fp) || ret != rd_ret) {
124 M_LOGE("cache wr failed %d!\n", os_ferror(cache->fp));
125 nc->cache_cplt = 1;
126 os_mutex_unlock(nc->lock);
127 break;
128 }
129 cache->wr_pos += rd_ret;
130
131 if (cache->rd_waiting &&
132 cache->wr_pos - cache->rd_pos >= cache->rd_len) {
133 os_sem_signal(cache->rd_sem);
134 cache->rd_waiting = 0;
135 }
136
137 nc->load_length += rd_ret;
138 if (nc->cache_stop) {
139 if (cache->rd_waiting) {
140 os_sem_signal(cache->rd_sem);
141 cache->rd_waiting = 0;
142 }
143 nc->cache_stop = 0;
144 nc->cache_cplt = 1;
145 os_mutex_unlock(nc->lock);
146 M_LOGD("cache stop\n");
147 break;
148 }
149
150 load_size = MIN(load_size,
151 nc->content_length - nc->load_length);
152
153 if (load_size <= 0) {
154 if (!nc->sequence) {
155 M_LOGD("load end\n");
156 nc->cache_cplt = 1;
157 os_mutex_unlock(nc->lock);
158 break;
159 } else {
160 M_LOGD("request next segment, wr_pos %u load_length %u\n",
161 cache->wr_pos, nc->load_length);
162 os_mutex_unlock(nc->lock);
163 if (nc->event(nc->priv, CACHE_EV_CACHE_CPLT, NULL)) {
164 M_LOGD("request next segment failed !\n");
165 nc->cache_cplt = 1;
166 break;
167 }
168 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
169
170 if (nc->head_data_size > 0) {
171 ret = os_fwrite(nc->buffer,
172 1, nc->head_data_size, cache->fp);
173 if (os_ferror(cache->fp) || ret != nc->head_data_size) {
174 M_LOGE("write head data failed %d!\n",
175 os_ferror(cache->fp));
176 if (nc->cplt_waiting) {
177 nc->cplt_waiting = 0;
178 os_sem_signal(nc->cplt_sem);
179 }
180 nc->cache_running = 0;
181 os_mutex_unlock(nc->lock);
182 return -1;
183 }
184 cache->wr_pos += nc->head_data_size;
185 nc->load_length += nc->head_data_size;
186 M_LOGD("cache seq head data %u\n",
187 nc->head_data_size);
188 M_LOGD("cache next segment, wr_pos %u load_length %u\n",
189 cache->wr_pos, nc->load_length);
190 nc->head_data_size = 0;
191 }
192
193 load_size = MIN(nc->buffer_size,
194 nc->content_length - nc->load_length);
195 if (load_size <= 0) {
196 M_LOGD("load end\n");
197 nc->cache_cplt = 1;
198 os_mutex_unlock(nc->lock);
199 break;
200 }
201 }
202 }
203 os_mutex_unlock(nc->lock);
204 }
205
206 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
207
208 M_LOGD("complete %d/%d\n",
209 nc->load_length, nc->content_length);
210 if (!nc->sequence)
211 nc->event(nc->priv, CACHE_EV_CACHE_CPLT, NULL);
212 if (nc->cplt_waiting) {
213 nc->cplt_waiting = 0;
214 os_sem_signal(nc->cplt_sem);
215 }
216
217 nc->cache_running = 0;
218 os_mutex_unlock(nc->lock);
219 return 0;
220
221 #else
222 return -1;
223 #endif
224 }
225
net_cache_file_read(void * priv,unsigned char * buffer,int nbytes)226 static int net_cache_file_read(void *priv, unsigned char *buffer, int nbytes)
227 {
228 #if NET_CACHE_FILE_ENABLE
229 net_cache_t *nc = (net_cache_t *)priv;
230 struct cache_file *cache;
231 int ret = 0;
232
233 if (!nc) {
234 M_LOGE("nc null !\n");
235 return -1;
236 }
237
238 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
239
240 cache = nc->cache;
241 if (!cache) {
242 M_LOGE("cache null !\n");
243 os_mutex_unlock(nc->lock);
244 return -1;
245 }
246
247 if (!cache->rd_start) {
248 cache->rd_len = MIN(nbytes * 10, nc->content_length);
249 cache->rd_start = 1;
250 M_LOGD("read start\n");
251 } else {
252 cache->rd_len = nbytes;
253 }
254
255 if (nc->seek_offset != 0) {
256 if (nc->seek_offset > 0) {
257 if (nc->seek_offset <= cache->wr_pos - cache->rd_pos) {
258 cache->rd_pos += nc->seek_offset;
259 nc->event(nc->priv, CACHE_EV_SEEK_DONE,
260 (void *)nc->seek_offset);
261 M_LOGD("seek %d bytes\n", nc->seek_offset);
262 }
263 } else {
264 if (abs(nc->seek_offset) <= cache->rd_pos) {
265 cache->rd_pos += nc->seek_offset;
266 nc->event(nc->priv, CACHE_EV_SEEK_DONE,
267 (void *)nc->seek_offset);
268 M_LOGD("seek %d bytes\n", nc->seek_offset);
269 }
270 }
271 nc->seek_offset = 0;
272 }
273
274 while (cache->wr_pos <= cache->rd_pos ||
275 cache->wr_pos - cache->rd_pos < cache->rd_len ||
276 !cache->fp) {
277 if (nc->cache_cplt) {
278 M_LOGD("cache cplt, stop waiting\n");
279 break;
280 }
281
282 M_LOGD("wait cache, rd_len %u rd_pos %u wr_pos %u\n",
283 cache->rd_len, cache->rd_pos, cache->wr_pos);
284 cache->rd_waiting = 1;
285 os_mutex_unlock(nc->lock);
286
287 if (os_sem_wait(cache->rd_sem, 30000)) {
288 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
289 M_LOGE("wait timeout ! rd_len %u rd_pos %u wr_pos %u\n",
290 cache->rd_len, cache->rd_pos, cache->wr_pos);
291 cache->rd_waiting = 0;
292 goto __exit;
293 }
294 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
295 cache->rd_waiting = 0;
296 M_LOGD("wait exit, rd_len %u rd_pos %u wr_pos %u\n",
297 cache->rd_len, cache->rd_pos, cache->wr_pos);
298 }
299
300 if (!cache->fp) {
301 M_LOGE("cache file not open !\n");
302 os_mutex_unlock(nc->lock);
303 return -1;
304 }
305
306 if (nc->cache_cplt) {
307 if (os_feof(cache->fp) || cache->rd_pos >= cache->wr_pos) {
308 nbytes = 0;
309 M_LOGD("read end\n");
310 goto __exit;
311 } else if (cache->wr_pos - cache->rd_pos < nbytes) {
312 nbytes = cache->wr_pos - cache->rd_pos;
313 M_LOGD("read tail %d\n", nbytes);
314 }
315 }
316
317 (void)os_fseek(cache->fp, cache->rd_pos, OS_SEEK_SET);
318 ret = os_fread(buffer, 1, nbytes, cache->fp);
319 if (os_ferror(cache->fp) || ret != nbytes) {
320 M_LOGE("read failed %d!\n", os_ferror(cache->fp));
321 os_mutex_unlock(nc->lock);
322 return -1;
323 }
324
325 cache->rd_pos += nbytes;
326 ret = nbytes;
327
328 __exit:
329 os_mutex_unlock(nc->lock);
330 return ret;
331
332 #else
333 return -1;
334 #endif
335 }
336
net_cache_file_mediainfo(struct cache_file * cache,media_info_t * info,media_format_t format)337 static int net_cache_file_mediainfo(struct cache_file *cache,
338 media_info_t *info, media_format_t format)
339 {
340 #if NET_CACHE_FILE_ENABLE
341 if (!cache) {
342 M_LOGW("cache not enable\n");
343 return -1;
344 }
345
346 if (!cache->fp) {
347 M_LOGE("cache file not open !\n");
348 return -1;
349 }
350
351 if (format == MEDIA_FMT_MP3) {
352 char buffer[128];
353 memset(buffer, 0, sizeof(buffer));
354 (void)os_fseek(cache->fp, -128, OS_SEEK_END);
355 int ret = os_fread(buffer, 1, 128, cache->fp);
356 if (ret != 128) {
357 M_LOGE("read failed %d!\n", ret);
358 return -1;
359 }
360
361 mp3_id3v1_parse(info, buffer, 128);
362 }
363
364 return 0;
365
366 #else
367 return -1;
368 #endif
369 }
370
371
net_cache_file_reset(struct cache_file * cache)372 static int net_cache_file_reset(struct cache_file *cache)
373 {
374 #if NET_CACHE_FILE_ENABLE
375 if (!cache) {
376 M_LOGE("cache null !\n");
377 return -1;
378 }
379
380 if (cache->fp) {
381 os_fclose(cache->fp);
382 cache->fp = NULL;
383 M_LOGD("cache file close\n");
384 }
385
386 cache->rd_pos = 0;
387 cache->wr_pos = 0;
388 cache->rd_waiting = 0;
389 cache->rd_start = 0;
390 cache->rd_len = 0;
391
392 M_LOGD("file cache reset\n");
393 return 0;
394
395 #else
396 return -1;
397 #endif
398 }
399
net_cache_file_init(net_cache_t * nc)400 static int net_cache_file_init(net_cache_t *nc)
401 {
402 #if NET_CACHE_FILE_ENABLE
403 struct cache_file *cache = snd_zalloc(
404 sizeof(struct cache_file), AFM_EXTN);
405 if (!cache) {
406 M_LOGE("alloc cache file failed !\n");
407 return -1;
408 }
409
410 cache->rd_sem = os_sem_new(0);
411 nc->cache_read = net_cache_file_read;
412 nc->cache = cache;
413
414 return 0;
415
416 #else
417 return -1;
418 #endif
419 }
420
net_cache_file_deinit(net_cache_t * nc)421 static int net_cache_file_deinit(net_cache_t *nc)
422 {
423 #if NET_CACHE_FILE_ENABLE
424 struct cache_file *cache;
425
426 if (!nc) {
427 M_LOGE("nc null !\n");
428 return -1;
429 }
430
431 cache = nc->cache;
432 if (!cache) {
433 M_LOGE("cache null !\n");
434 return -1;
435 }
436
437 net_cache_file_reset(cache);
438 os_sem_free(cache->rd_sem);
439 snd_free(cache);
440 nc->cache_read = NULL;
441 nc->cache = NULL;
442
443 return 0;
444
445 #else
446 return -1;
447 #endif
448 }
449
net_cache_mem(net_cache_t * nc)450 static int net_cache_mem(net_cache_t *nc)
451 {
452 struct cache_mem *cache;
453 int load_size;
454 int rd_ret = 0;
455 int wr_ret = 0;
456
457 if (!nc) {
458 M_LOGE("nc null !\n");
459 return -1;
460 }
461
462 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
463
464 nc->cache_running = 1;
465
466 cache = nc->cache;
467 if (!cache) {
468 M_LOGE("cache null !\n");
469 os_mutex_unlock(nc->lock);
470 return -1;
471 }
472
473 if (nc->head_data_size > 0) {
474 if (uvoice_ringbuff_freesize(&cache->rb) < nc->head_data_size) {
475 if (cache->rd_waiting) {
476 os_sem_signal(cache->rd_sem);
477 cache->rd_waiting = 0;
478 }
479
480 cache->wr_len = nc->head_data_size;
481 cache->wr_waiting = 1;
482 os_mutex_unlock(nc->lock);
483
484 os_sem_wait(cache->wr_sem, OS_WAIT_FOREVER);
485
486 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
487 cache->wr_waiting = 0;
488
489 if (nc->cache_stop) {
490 nc->cache_stop = 0;
491 nc->cache_cplt = 1;
492 M_LOGD("cache stop\n");
493 os_mutex_unlock(nc->lock);
494 goto __exit;
495 }
496 }
497 wr_ret = uvoice_ringbuff_fill(&cache->rb,
498 nc->buffer, nc->head_data_size);
499 if (wr_ret < 0) {
500 M_LOGE("fill head data %u failed !\n",
501 nc->head_data_size);
502 nc->cache_running = 0;
503 os_mutex_unlock(nc->lock);
504 return -1;
505 } else if (wr_ret != nc->head_data_size) {
506 M_LOGW("cache head data %u ret %d\n",
507 nc->buffer_size, wr_ret);
508 }
509 nc->load_length += nc->head_data_size;
510 nc->head_data_size = 0;
511 }
512
513 load_size = MIN(nc->buffer_size,
514 nc->content_length - nc->load_length);
515
516 if (nc->load_length >= nc->content_length) {
517 nc->cache_cplt = 1;
518 goto __exit;
519 }
520
521 M_LOGD("start\n");
522
523 os_mutex_unlock(nc->lock);
524
525 while (1) {
526 rd_ret = nc->cache_load(nc->priv, nc->buffer + nc->offset,
527 load_size);
528 if (rd_ret < 0) {
529 M_LOGE("load failed !\n");
530 nc->cache_cplt = 1;
531 nc->load_length -= nc->offset;
532 break;
533 } else if (rd_ret == 0) {
534 M_LOGD("load end\n");
535 nc->cache_cplt = 1;
536 nc->load_length -= nc->offset;
537 break;
538 } else if (rd_ret != load_size) {
539 M_LOGW("load %d ret %u\n", load_size, rd_ret);
540 }
541
542 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
543
544 if (nc->cache_stop) {
545 nc->cache_stop = 0;
546 nc->cache_cplt = 1;
547 nc->load_length -= nc->offset;
548 M_LOGD("cache stop\n");
549 os_mutex_unlock(nc->lock);
550 goto __exit;
551 }
552
553 while (uvoice_ringbuff_freesize(&cache->rb) <
554 rd_ret + nc->offset) {
555 if (cache->rd_waiting) {
556 os_sem_signal(cache->rd_sem);
557 cache->rd_waiting = 0;
558 }
559
560 cache->wr_len = rd_ret + nc->offset;
561 cache->wr_waiting = 1;
562 os_mutex_unlock(nc->lock);
563
564 os_sem_wait(cache->wr_sem, OS_WAIT_FOREVER);
565
566 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
567 cache->wr_waiting = 0;
568
569 if (nc->cache_stop) {
570 nc->cache_stop = 0;
571 nc->cache_cplt = 1;
572 nc->load_length -= nc->offset;
573 M_LOGD("cache stop\n");
574 os_mutex_unlock(nc->lock);
575 goto __exit;
576 }
577 }
578
579 wr_ret = uvoice_ringbuff_fill(&cache->rb,
580 nc->buffer, rd_ret + nc->offset);
581 if (wr_ret < 0) {
582 M_LOGE("fill failed %d!\n", wr_ret);
583 nc->cache_cplt = 1;
584 nc->load_length -= nc->offset;
585 os_mutex_unlock(nc->lock);
586 break;
587 } else if (wr_ret != rd_ret + nc->offset) {
588 M_LOGW("fill %u ret %d\n", rd_ret + nc->offset, wr_ret);
589 }
590
591 nc->load_length += rd_ret;
592
593 if (nc->offset > 0)
594 nc->offset = 0;
595
596 if (cache->rd_waiting &&
597 uvoice_ringbuff_dirtysize(&cache->rb) >= cache->rd_len) {
598 cache->rd_waiting = 0;
599 os_sem_signal(cache->rd_sem);
600 }
601
602 if (nc->cache_stop) {
603 nc->cache_stop = 0;
604 nc->cache_cplt = 1;
605 M_LOGD("stop\n");
606 os_mutex_unlock(nc->lock);
607 break;
608 }
609
610 load_size = MIN(nc->buffer_size,
611 nc->content_length - nc->load_length);
612
613 if (load_size <= 0) {
614 if (!nc->sequence) {
615 M_LOGD("load end\n");
616 nc->cache_cplt = 1;
617 os_mutex_unlock(nc->lock);
618 break;
619 } else {
620 M_LOGD("request next segment\n");
621 os_mutex_unlock(nc->lock);
622 if (nc->event(nc->priv, CACHE_EV_CACHE_CPLT, NULL)) {
623 M_LOGD("request next segment failed !\n");
624 nc->cache_cplt = 1;
625 break;
626 }
627 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
628
629 load_size = MIN(nc->buffer_size,
630 nc->content_length - nc->load_length);
631 if (load_size <= 0) {
632 M_LOGD("load end\n");
633 nc->cache_cplt = 1;
634 os_mutex_unlock(nc->lock);
635 break;
636 }
637
638 if (nc->head_data_size > 0) {
639 nc->offset = nc->head_data_size;
640 load_size -= nc->offset;
641 nc->load_length += nc->offset;
642 M_LOGD("cache head data %u\n", nc->offset);
643 nc->head_data_size = 0;
644 }
645 }
646 }
647
648 os_mutex_unlock(nc->lock);
649 }
650
651 __exit:
652 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
653 M_LOGD("complete %d/%d\n",
654 nc->load_length, nc->content_length);
655 if (cache->rd_waiting) {
656 M_LOGD("wake rd wait\n");
657 cache->rd_waiting = 0;
658 os_sem_signal(cache->rd_sem);
659 }
660 if (nc->cplt_waiting) {
661 nc->cplt_waiting = 0;
662 os_sem_signal(nc->cplt_sem);
663 }
664
665 nc->cache_running = 0;
666 os_mutex_unlock(nc->lock);
667 return 0;
668 }
669
net_cache_mem_read(void * priv,unsigned char * buffer,int nbytes)670 static int net_cache_mem_read(void *priv, unsigned char *buffer,
671 int nbytes)
672 {
673 net_cache_t *nc = (net_cache_t *)priv;
674 struct cache_mem *cache;
675 int ret = 0;
676
677 if (!nc) {
678 M_LOGE("nc null !\n");
679 return -1;
680 }
681
682 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
683
684 if (nbytes <= 0)
685 goto __exit;
686
687 cache = nc->cache;
688 if (!cache) {
689 M_LOGE("cache null !\n");
690 ret = -1;
691 goto __exit;
692 }
693
694 if (!cache->rd_start) {
695 #ifdef UVOICE_IOTNLP_ENABLE
696 cache->rd_len = nbytes;
697 #else
698 if (nc->cache_cplt)
699 cache->rd_len = MIN(cache->pool_size,
700 MIN(nbytes, nc->content_length));
701 else
702 cache->rd_len = MIN(cache->pool_size,
703 MIN(nbytes * 4, nc->content_length - nc->load_length));
704 if (nbytes > cache->rd_len) {
705 nbytes = cache->rd_len;
706 M_LOGD("update read bytes %d\n", nbytes);
707 }
708 #endif
709 cache->rd_start = 1;
710 } else {
711 cache->rd_len = nbytes;
712 }
713
714 if (nc->cache_cplt) {
715 if (uvoice_ringbuff_dirtysize(&cache->rb) <= 0) {
716 M_LOGD("data end\n");
717 goto __exit;
718 } else if (uvoice_ringbuff_dirtysize(&cache->rb) < nbytes) {
719 nbytes = uvoice_ringbuff_dirtysize(&cache->rb);
720 cache->rd_len = nbytes;
721 M_LOGD("cache cplt, read %d\n", nbytes);
722 }
723 }
724
725 if (nc->seek_offset != 0) {
726 if (nc->seek_offset > 0) {
727 if (nc->seek_offset <= uvoice_ringbuff_dirtysize(&cache->rb)) {
728 uvoice_ringbuff_drop(&cache->rb, nc->seek_offset);
729 nc->event(nc->priv, CACHE_EV_SEEK_DONE,
730 (void *)nc->seek_offset);
731 }
732 } else {
733 if (abs(nc->seek_offset) <= uvoice_ringbuff_freesize(&cache->rb)) {
734 uvoice_ringbuff_back(&cache->rb, abs(nc->seek_offset));
735 nc->event(nc->priv, CACHE_EV_SEEK_DONE,
736 (void *)nc->seek_offset);
737 }
738 }
739 M_LOGD("seek %d bytes\n", nc->seek_offset);
740 nc->seek_offset = 0;
741 }
742
743 if (uvoice_ringbuff_dirtysize(&cache->rb) < cache->rd_len) {
744 cache->rd_waiting = 1;
745 if (cache->wr_waiting) {
746 os_sem_signal(cache->wr_sem);
747 cache->wr_waiting = 0;
748 }
749
750 if (cache->rd_len == nbytes && !nc->sequence)
751 cache->rd_len = MIN(cache->pool_size / 2,
752 nc->content_length - nc->load_length);
753
754 if (cache->rd_len <= 0) {
755 M_LOGD("content end\n");
756 cache->rd_waiting = 0;
757 goto __exit;
758 }
759 nbytes = MIN(nbytes, cache->rd_len);
760 nc->event(nc->priv, CACHE_EV_READ_BLOCK, (void *)1);
761
762 M_LOGD("wait cache, rd_len %u dirtysize %d freesize %d\n",
763 cache->rd_len,
764 uvoice_ringbuff_dirtysize(&cache->rb),
765 uvoice_ringbuff_freesize(&cache->rb));
766 os_mutex_unlock(nc->lock);
767
768 if (os_sem_wait(cache->rd_sem, 60000)) {
769 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
770 M_LOGE("wait timeout ! rd_len %u dirtysize %d freesize %d\n",
771 cache->rd_len,
772 uvoice_ringbuff_dirtysize(&cache->rb),
773 uvoice_ringbuff_freesize(&cache->rb));
774 cache->rd_waiting = 0;
775 goto __exit;
776 }
777 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
778 M_LOGD("wait exit, rd_len %u dirtysize %d freesize %d\n",
779 cache->rd_len,
780 uvoice_ringbuff_dirtysize(&cache->rb),
781 uvoice_ringbuff_freesize(&cache->rb));
782 nc->event(nc->priv, CACHE_EV_READ_BLOCK, 0);
783 cache->rd_waiting = 0;
784 }
785
786 if (nc->cache_cplt) {
787 if (uvoice_ringbuff_dirtysize(&cache->rb) <= 0) {
788 M_LOGD("read end\n");
789 goto __exit;
790 } else if (uvoice_ringbuff_dirtysize(&cache->rb) <
791 nbytes) {
792 nbytes = uvoice_ringbuff_dirtysize(&cache->rb);
793 cache->rd_len = nbytes;
794 M_LOGD("cache cplt, read %d\n", nbytes);
795 }
796 }
797
798 ret = uvoice_ringbuff_read(&cache->rb, buffer, nbytes);
799 if (ret < 0) {
800 M_LOGE("read %d failed %d!\n", nbytes, ret);
801 ret = -1;
802 goto __exit;
803 } else if (ret != nbytes) {
804 M_LOGW("read %d ret %d\n", nbytes, ret);
805 }
806
807 if (cache->wr_waiting &&
808 uvoice_ringbuff_freesize(&cache->rb) >= cache->wr_len) {
809 os_sem_signal(cache->wr_sem);
810 cache->wr_waiting = 0;
811 }
812
813 __exit:
814 os_mutex_unlock(nc->lock);
815 return ret;
816 }
817
net_cache_mem_reset(struct cache_mem * cache)818 static int net_cache_mem_reset(struct cache_mem *cache)
819 {
820 if (!cache) {
821 M_LOGE("cache null !\n");
822 return -1;
823 }
824
825 cache->rd_start = 0;
826 cache->wr_waiting = 0;
827 cache->rd_waiting = 0;
828 cache->rd_len = 0;
829 cache->wr_len = 0;
830 memset(cache->pool, 0, cache->pool_size);
831 uvoice_ringbuff_reset(&cache->rb);
832
833 M_LOGD("mem cache reset\n");
834 return 0;
835 }
836
net_cache_mem_init(net_cache_t * nc)837 static int net_cache_mem_init(net_cache_t *nc)
838 {
839 struct cache_mem *cache;
840
841 if (!nc) {
842 M_LOGE("nc null !\n");
843 return -1;
844 }
845
846 cache = snd_zalloc(sizeof(struct cache_mem), AFM_EXTN);
847 if (!cache) {
848 M_LOGE("alloc cache mem failed !\n");
849 return -1;
850 }
851
852 cache->pool_size = nc->cache_config.mem_size * 1024;
853 if (nc->sequence && nc->cache_config.mem_size > 40)
854 cache->pool_size = 40 * 1024;
855
856 cache->pool = snd_zalloc(cache->pool_size + 4, AFM_EXTN);
857 if (!cache->pool) {
858 M_LOGE("alloc cache pool failed !\n");
859 snd_free(cache);
860 return -1;
861 }
862
863 M_LOGD("alloc cache pool %u\n", cache->pool_size);
864
865 if (uvoice_ringbuff_init(&cache->rb,
866 cache->pool, cache->pool_size)) {
867 M_LOGE("init ring buffer failed !\n");
868 snd_free(cache->pool);
869 snd_free(cache);
870 return -1;
871 }
872
873 cache->wr_sem = os_sem_new(0);
874 cache->rd_sem = os_sem_new(0);
875 nc->cache_read = net_cache_mem_read;
876 nc->cache = cache;
877
878 return 0;
879 }
880
net_cache_mem_deinit(net_cache_t * nc)881 static int net_cache_mem_deinit(net_cache_t *nc)
882 {
883 struct cache_mem *cache;
884
885 if (!nc) {
886 M_LOGE("nc null !\n");
887 return -1;
888 }
889
890 cache = nc->cache;
891 if (!cache) {
892 M_LOGE("cache null !\n");
893 return -1;
894 }
895
896 os_sem_free(cache->wr_sem);
897 os_sem_free(cache->rd_sem);
898 snd_free(cache->pool);
899 snd_free(cache);
900 nc->cache_read = NULL;
901 nc->cache = NULL;
902
903 return 0;
904 }
905
net_cache_task(void * arg)906 static void net_cache_task(void *arg)
907 {
908 net_cache_t *nc = (net_cache_t *)arg;
909 if (!nc) {
910 M_LOGE("nc null !\n");
911 return;
912 }
913
914 if (nc->cache_config.place == CACHE_FILE)
915 net_cache_file(nc);
916 else if (nc->cache_config.place == CACHE_MEM)
917 net_cache_mem(nc);
918 }
919
920
net_get_cacheinfo(net_cache_t * nc,cache_info_t * info)921 int net_get_cacheinfo(net_cache_t *nc, cache_info_t *info)
922 {
923 if (!nc) {
924 M_LOGE("nc null !\n");
925 return -1;
926 }
927
928 if (!info) {
929 M_LOGE("info null !\n");
930 return -1;
931 }
932
933 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
934
935 if (nc->cache_config.place == CACHE_FILE) {
936 struct cache_file *cache = nc->cache;
937 info->dirty_cache_size = cache->rd_pos;
938 info->avail_cache_size = cache->wr_pos - cache->rd_pos;
939 } else if (nc->cache_config.place == CACHE_MEM) {
940 struct cache_mem *cache = nc->cache;
941 info->dirty_cache_size = 0;
942 info->avail_cache_size =
943 uvoice_ringbuff_dirtysize(&cache->rb);
944 }
945
946 os_mutex_unlock(nc->lock);
947 return 0;
948 }
949
net_get_mediainfo(net_cache_t * nc,media_info_t * info,media_format_t format)950 int net_get_mediainfo(net_cache_t *nc,
951 media_info_t *info, media_format_t format)
952 {
953 if (!nc) {
954 M_LOGE("nc null !\n");
955 return -1;
956 }
957
958 if (!info) {
959 M_LOGE("info null !\n");
960 return -1;
961 }
962
963 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
964
965 switch (nc->cache_config.place) {
966 case CACHE_FILE:
967 if (!nc->cache_cplt)
968 break;
969
970 if (net_cache_file_mediainfo(nc->cache,
971 info, format)) {
972 M_LOGE("get file mediainfo failed !\n");
973 os_mutex_unlock(nc->lock);
974 return -1;
975 }
976 break;
977 default:
978 break;
979 }
980
981 os_mutex_unlock(nc->lock);
982 return 0;
983 }
984
net_cache_reset(net_cache_t * nc)985 int net_cache_reset(net_cache_t *nc)
986 {
987 if (!nc) {
988 M_LOGE("nc null !\n");
989 return -1;
990 }
991
992 if (nc->cache_config.place == CACHE_NONE) {
993 M_LOGD("cache disabled\n");
994 goto __exit;
995 }
996
997 if (!nc->cache_cplt && nc->cache_running) {
998 M_LOGE("cache not cplt !\n");
999 return -1;
1000 }
1001
1002 nc->cache_running = 0;
1003 nc->load_length = 0;
1004 nc->cache_cplt = 0;
1005 nc->seek_offset = 0;
1006 nc->rebuild = 0;
1007
1008 switch (nc->cache_config.place) {
1009 case CACHE_FILE:
1010 if (net_cache_file_reset(nc->cache)) {
1011 M_LOGE("reset file cache failed !\n");
1012 return -1;
1013 }
1014 break;
1015 case CACHE_MEM:
1016 if (net_cache_mem_reset(nc->cache)) {
1017 M_LOGE("reset mem cache failed !\n");
1018 return -1;
1019 }
1020 break;
1021 default:
1022 break;
1023 }
1024
1025 __exit:
1026 return 0;
1027 }
1028
net_cache_seek(net_cache_t * nc,int offset)1029 int net_cache_seek(net_cache_t *nc, int offset)
1030 {
1031 if (!nc) {
1032 M_LOGE("nc null !\n");
1033 return -1;
1034 }
1035
1036 if (offset != 0) {
1037 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
1038 nc->seek_offset = offset;
1039 os_mutex_unlock(nc->lock);
1040 }
1041 return 0;
1042 }
1043
net_cache_start(net_cache_t * nc)1044 int net_cache_start(net_cache_t *nc)
1045 {
1046 if (!nc) {
1047 M_LOGE("nc null !\n");
1048 return -1;
1049 }
1050
1051 if (nc->load_length >= nc->content_length) {
1052 M_LOGD("load cplt, ignore\n");
1053 nc->cache_cplt = 1;
1054 goto __exit;
1055 }
1056
1057 if (nc->cache_config.place != CACHE_NONE) {
1058 nc->cache_cplt = 0;
1059 os_task_create(&nc->cache_task, "uvoice_cache_task",
1060 net_cache_task, nc,
1061 2048, NET_CACHE_TASK_PRIORITY);
1062 }
1063
1064 __exit:
1065 return 0;
1066 }
1067
net_cache_pause(net_cache_t * nc)1068 int net_cache_pause(net_cache_t *nc)
1069 {
1070 if (!nc) {
1071 M_LOGE("nc null !\n");
1072 return -1;
1073 }
1074
1075 if (nc->cache_config.place == CACHE_MEM ||
1076 nc->cache_config.place == CACHE_NONE) {
1077 M_LOGD("rebuild cache\n");
1078 nc->rebuild = NET_CACHE_REBUILD_ENABLE;
1079
1080 /* sequece stream rebuild forcibly */
1081 if (nc->sequence)
1082 nc->rebuild = 1;
1083 }
1084
1085 return 0;
1086 }
1087
net_cache_resume(net_cache_t * nc)1088 int net_cache_resume(net_cache_t *nc)
1089 {
1090 if (!nc) {
1091 M_LOGE("nc null !\n");
1092 return -1;
1093 }
1094
1095 return 0;
1096 }
1097
net_cache_stop(net_cache_t * nc)1098 int net_cache_stop(net_cache_t *nc)
1099 {
1100 if (!nc) {
1101 M_LOGE("nc null !\n");
1102 return -1;
1103 }
1104
1105 if (!nc->cache_running) {
1106 M_LOGD("cache not running, ignore\n");
1107 goto __exit;
1108 }
1109
1110 if (nc->cache_cplt) {
1111 M_LOGD("cache cplt already, ignore\n");
1112 goto __exit;
1113 }
1114
1115 if (nc->cache_config.place != CACHE_NONE) {
1116 os_mutex_lock(nc->lock, OS_WAIT_FOREVER);
1117 if (!nc->cache_cplt) {
1118 M_LOGD("wait cache cplt\n");
1119 if (nc->cache_config.place == CACHE_MEM) {
1120 struct cache_mem *cache = nc->cache;
1121 nc->cache_stop = 1;
1122 if (cache->wr_waiting) {
1123 M_LOGD("wake wr waiting\n");
1124 os_sem_signal(cache->wr_sem);
1125 cache->wr_waiting = 0;
1126 }
1127 cache->rd_start = 0;
1128 } else if (nc->cache_config.place == CACHE_FILE) {
1129 struct cache_file *cache = nc->cache;
1130 nc->cache_stop = 1;
1131 cache->rd_start = 0;
1132 }
1133 nc->cplt_waiting = 1;
1134 os_mutex_unlock(nc->lock);
1135 if (os_sem_wait(nc->cplt_sem, 15000)) {
1136 nc->cplt_waiting = 0;
1137 M_LOGW("wait cache cplt timeout !\n");
1138 }
1139 M_LOGD("cache cplt and stop\n");
1140 } else {
1141 nc->cache_cplt = 0;
1142 os_mutex_unlock(nc->lock);
1143 }
1144 }
1145
1146 __exit:
1147 return 0;
1148 }
1149
net_cache_create(int read_size,cache_config_t * config,bool sequence)1150 net_cache_t *net_cache_create(int read_size,
1151 cache_config_t *config, bool sequence)
1152 {
1153 net_cache_t *nc;
1154
1155 nc = snd_zalloc(sizeof(net_cache_t), AFM_EXTN);
1156 if (!nc) {
1157 M_LOGE("alloc net cache failed !\n");
1158 return NULL;
1159 }
1160
1161 memcpy(&nc->cache_config, config, sizeof(cache_config_t));
1162 nc->buffer_size = read_size;
1163 nc->buffer = snd_zalloc(nc->buffer_size, AFM_MAIN);
1164 if (!nc->buffer) {
1165 M_LOGE("alloc buffer failed !\n");
1166 snd_free(nc);
1167 return NULL;
1168 }
1169 nc->lock = os_mutex_new();
1170 nc->cplt_sem = os_sem_new(0);
1171 if (sequence)
1172 nc->sequence = 1;
1173
1174 if (nc->cache_config.place == CACHE_FILE) {
1175 if (net_cache_file_init(nc)) {
1176 M_LOGE("init file cache failed !\n");
1177 snd_free(nc->buffer);
1178 snd_free(nc);
1179 return NULL;
1180 }
1181 } else if (nc->cache_config.place == CACHE_MEM) {
1182 if (net_cache_mem_init(nc)) {
1183 M_LOGE("init mem cache failed !\n");
1184 snd_free(nc->buffer);
1185 snd_free(nc);
1186 return NULL;
1187 }
1188 }
1189
1190 M_LOGD("net cache create\n");
1191 return nc;
1192 }
1193
net_cache_release(net_cache_t * nc)1194 int net_cache_release(net_cache_t *nc)
1195 {
1196 int ret = 0;
1197
1198 if (!nc) {
1199 M_LOGE("nc null !\n");
1200 return -1;
1201 }
1202
1203 if (nc->cache_config.place == CACHE_FILE)
1204 ret = net_cache_file_deinit(nc);
1205 else if (nc->cache_config.place == CACHE_MEM)
1206 ret = net_cache_mem_deinit(nc);
1207 if (ret) {
1208 M_LOGE("cache deinit failed !\n");
1209 return -1;
1210 }
1211
1212 os_sem_free(nc->cplt_sem);
1213 os_mutex_free(nc->lock);
1214 snd_free(nc->buffer);
1215 snd_free(nc);
1216
1217 M_LOGD("net cache release\n");
1218 return 0;
1219 }
1220
1221