blob: 2fd1e89bbef71e24aa384bb2ffc3e020de8aa8d5
1 | #define LOG_TAG "audio_hwsync" |
2 | |
3 | #include <stdint.h> |
4 | #include <inttypes.h> |
5 | #include <cutils/log.h> |
6 | #include <string.h> |
7 | |
8 | #include "audio_hw_utils.h" |
9 | #include "audio_hwsync.h" |
10 | |
11 | void aml_audio_hwsync_init(audio_hwsync_t *p_hwsync) |
12 | { |
13 | if (p_hwsync == NULL) |
14 | return; |
15 | |
16 | p_hwsync->first_apts_flag = false; |
17 | p_hwsync->hw_sync_state = HW_SYNC_STATE_HEADER; |
18 | p_hwsync->hw_sync_header_cnt = 0; |
19 | return; |
20 | } |
21 | //return bytes cost from input, |
22 | int aml_audio_hwsync_find_frame(audio_hwsync_t *p_hwsync, |
23 | const void *in_buffer, size_t in_bytes, uint64_t *cur_pts, int *outsize) |
24 | { |
25 | size_t remain = in_bytes; |
26 | uint8_t *p = (uint8_t *)in_buffer; |
27 | uint64_t time_diff = 0; |
28 | |
29 | if (p_hwsync == NULL || in_buffer == NULL) |
30 | return 0; |
31 | |
32 | //ALOGI(" --- out_write %d, cache cnt = %d, body = %d, hw_sync_state = %d", out_frames * frame_size, out->body_align_cnt, out->hw_sync_body_cnt, out->hw_sync_state); |
33 | while (remain > 0) { |
34 | //if (p_hwsync->hw_sync_state == HW_SYNC_STATE_RESYNC) { |
35 | //} |
36 | if (p_hwsync->hw_sync_state == HW_SYNC_STATE_HEADER) { |
37 | //ALOGI("Add to header buffer [%d], 0x%x", out->hw_sync_header_cnt, *p); |
38 | p_hwsync->hw_sync_header[p_hwsync->hw_sync_header_cnt++] = *p++; |
39 | remain--; |
40 | if (p_hwsync->hw_sync_header_cnt == 16) { |
41 | uint64_t pts; |
42 | if (!hwsync_header_valid(&p_hwsync->hw_sync_header[0])) { |
43 | //ALOGE("!!!!!!hwsync header out of sync! Resync.should not happen????"); |
44 | p_hwsync->hw_sync_state = HW_SYNC_STATE_HEADER; |
45 | memcpy(p_hwsync->hw_sync_header, p_hwsync->hw_sync_header + 1, 15); |
46 | p_hwsync->hw_sync_header_cnt--; |
47 | continue; |
48 | } |
49 | if ((in_bytes-remain) > 16) |
50 | ALOGI("got the frame sync header cost %zu",in_bytes-remain); |
51 | p_hwsync->hw_sync_state = HW_SYNC_STATE_BODY; |
52 | p_hwsync->hw_sync_body_cnt = hwsync_header_get_size(&p_hwsync->hw_sync_header[0]); |
53 | p_hwsync->hw_sync_frame_size = p_hwsync->hw_sync_body_cnt; |
54 | p_hwsync->body_align_cnt = 0; |
55 | pts = hwsync_header_get_pts(&p_hwsync->hw_sync_header[0]); |
56 | //memcpy(write_buf+write_pos,&p_hwsync->hw_sync_header[0],16); |
57 | //write_pos += 16; |
58 | pts = pts * 90 / 1000000; |
59 | time_diff = get_pts_gap(pts, p_hwsync->last_apts_from_header) / 90; |
60 | ALOGV("pts %"PRIx64",frame len %zu\n", pts, p_hwsync->hw_sync_body_cnt); |
61 | ALOGV("last pts %"PRIx64",diff %"PRIx64" ms\n", p_hwsync->last_apts_from_header, time_diff); |
62 | |
63 | if (time_diff > 32) { |
64 | ALOGI("pts time gap %"PRIx64" ms,last %"PRIx64",cur %"PRIx64"\n", time_diff, |
65 | p_hwsync->last_apts_from_header, pts); |
66 | } |
67 | p_hwsync->last_apts_from_header = pts; |
68 | *cur_pts = pts; |
69 | //ALOGI("get header body_cnt = %d, pts = %lld", out->hw_sync_body_cnt, pts); |
70 | } |
71 | continue; |
72 | } else if (p_hwsync->hw_sync_state == HW_SYNC_STATE_BODY) { |
73 | int m = (p_hwsync->hw_sync_body_cnt < remain) ? p_hwsync->hw_sync_body_cnt : remain; |
74 | //ALOGI("m = %d", m); |
75 | // process m bytes body with an empty fragment for alignment |
76 | if (m > 0) { |
77 | //ret = pcm_write(out->pcm, p, m - align); |
78 | memcpy(p_hwsync->hw_sync_body_buf + p_hwsync->hw_sync_frame_size - p_hwsync->hw_sync_body_cnt, p, m); |
79 | p += m; |
80 | remain -= m; |
81 | //ALOGI("pcm_write %d, remain %d", m - align, remain); |
82 | p_hwsync->hw_sync_body_cnt -= m; |
83 | if (p_hwsync->hw_sync_body_cnt == 0) { |
84 | p_hwsync->hw_sync_state = HW_SYNC_STATE_HEADER; |
85 | p_hwsync->hw_sync_header_cnt = 0; |
86 | *outsize = p_hwsync->hw_sync_frame_size; |
87 | ALOGV("we found the frame total body,yeah\n"); |
88 | break;//continue; |
89 | } |
90 | } |
91 | } |
92 | } |
93 | return in_bytes - remain; |
94 | } |
95 | |
96 | int aml_audio_hwsync_set_first_pts(audio_hwsync_t *p_hwsync, uint64_t pts) |
97 | { |
98 | uint32_t pts32; |
99 | char tempbuf[128]; |
100 | |
101 | if (p_hwsync == NULL) |
102 | return -1; |
103 | |
104 | if (pts > 0xffffffff) { |
105 | ALOGE("APTS exeed the 32bit range!"); |
106 | return -1; |
107 | } |
108 | |
109 | pts32 = (uint32_t)pts; |
110 | p_hwsync->first_apts_flag = true; |
111 | p_hwsync->first_apts = pts; |
112 | sprintf(tempbuf, "AUDIO_START:0x%x", pts32); |
113 | ALOGI("hwsync set tsync -> %s", tempbuf); |
114 | if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) { |
115 | ALOGE("set AUDIO_START failed \n"); |
116 | return -1; |
117 | } |
118 | |
119 | return 0; |
120 | } |
121 |