summaryrefslogtreecommitdiff
path: root/audio_hwsync.c (plain)
blob: a04fc70dfcc9caddedde919fe2fefc5e1fb7e9a2
1/*
2 * Copyright (C) 2010 Amlogic Corporation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18
19#define LOG_TAG "audio_hwsync"
20
21#include <stdint.h>
22#include <inttypes.h>
23#include <cutils/log.h>
24#include <string.h>
25
26#include "audio_hw_utils.h"
27#include "audio_hwsync.h"
28
29void aml_audio_hwsync_init(audio_hwsync_t *p_hwsync)
30{
31 if (p_hwsync == NULL)
32 return;
33
34 p_hwsync->first_apts_flag = false;
35 p_hwsync->hw_sync_state = HW_SYNC_STATE_HEADER;
36 p_hwsync->hw_sync_header_cnt = 0;
37 return;
38}
39//return bytes cost from input,
40int aml_audio_hwsync_find_frame(audio_hwsync_t *p_hwsync,
41 const void *in_buffer, size_t in_bytes, uint64_t *cur_pts, int *outsize)
42{
43 size_t remain = in_bytes;
44 uint8_t *p = (uint8_t *)in_buffer;
45 uint64_t time_diff = 0;
46
47 if (p_hwsync == NULL || in_buffer == NULL)
48 return 0;
49
50 //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);
51 while (remain > 0) {
52 //if (p_hwsync->hw_sync_state == HW_SYNC_STATE_RESYNC) {
53 //}
54 if (p_hwsync->hw_sync_state == HW_SYNC_STATE_HEADER) {
55 //ALOGI("Add to header buffer [%d], 0x%x", out->hw_sync_header_cnt, *p);
56 p_hwsync->hw_sync_header[p_hwsync->hw_sync_header_cnt++] = *p++;
57 remain--;
58 if (p_hwsync->hw_sync_header_cnt == 16) {
59 uint64_t pts;
60 if (!hwsync_header_valid(&p_hwsync->hw_sync_header[0])) {
61 //ALOGE("!!!!!!hwsync header out of sync! Resync.should not happen????");
62 p_hwsync->hw_sync_state = HW_SYNC_STATE_HEADER;
63 memcpy(p_hwsync->hw_sync_header, p_hwsync->hw_sync_header + 1, 15);
64 p_hwsync->hw_sync_header_cnt--;
65 continue;
66 }
67 if ((in_bytes-remain) > 16)
68 ALOGI("got the frame sync header cost %zu",in_bytes-remain);
69 p_hwsync->hw_sync_state = HW_SYNC_STATE_BODY;
70 p_hwsync->hw_sync_body_cnt = hwsync_header_get_size(&p_hwsync->hw_sync_header[0]);
71 p_hwsync->hw_sync_frame_size = p_hwsync->hw_sync_body_cnt;
72 p_hwsync->body_align_cnt = 0;
73 pts = hwsync_header_get_pts(&p_hwsync->hw_sync_header[0]);
74 //memcpy(write_buf+write_pos,&p_hwsync->hw_sync_header[0],16);
75 //write_pos += 16;
76 pts = pts * 90 / 1000000;
77 time_diff = get_pts_gap(pts, p_hwsync->last_apts_from_header) / 90;
78 ALOGV("pts %"PRIx64",frame len %zu\n", pts, p_hwsync->hw_sync_body_cnt);
79 ALOGV("last pts %"PRIx64",diff %"PRIx64" ms\n", p_hwsync->last_apts_from_header, time_diff);
80
81 if (time_diff > 32) {
82 ALOGI("pts time gap %"PRIx64" ms,last %"PRIx64",cur %"PRIx64"\n", time_diff,
83 p_hwsync->last_apts_from_header, pts);
84 }
85 p_hwsync->last_apts_from_header = pts;
86 *cur_pts = pts;
87 //ALOGI("get header body_cnt = %d, pts = %lld", out->hw_sync_body_cnt, pts);
88 }
89 continue;
90 } else if (p_hwsync->hw_sync_state == HW_SYNC_STATE_BODY) {
91 int m = (p_hwsync->hw_sync_body_cnt < remain) ? p_hwsync->hw_sync_body_cnt : remain;
92 //ALOGI("m = %d", m);
93 // process m bytes body with an empty fragment for alignment
94 if (m > 0) {
95 //ret = pcm_write(out->pcm, p, m - align);
96 memcpy(p_hwsync->hw_sync_body_buf + p_hwsync->hw_sync_frame_size - p_hwsync->hw_sync_body_cnt, p, m);
97 p += m;
98 remain -= m;
99 //ALOGI("pcm_write %d, remain %d", m - align, remain);
100 p_hwsync->hw_sync_body_cnt -= m;
101 if (p_hwsync->hw_sync_body_cnt == 0) {
102 p_hwsync->hw_sync_state = HW_SYNC_STATE_HEADER;
103 p_hwsync->hw_sync_header_cnt = 0;
104 *outsize = p_hwsync->hw_sync_frame_size;
105 ALOGV("we found the frame total body,yeah\n");
106 break;//continue;
107 }
108 }
109 }
110 }
111 return in_bytes - remain;
112}
113
114int aml_audio_hwsync_set_first_pts(audio_hwsync_t *p_hwsync, uint64_t pts)
115{
116 uint32_t pts32;
117 char tempbuf[128];
118
119 if (p_hwsync == NULL)
120 return -1;
121
122 if (pts > 0xffffffff) {
123 ALOGE("APTS exeed the 32bit range!");
124 return -1;
125 }
126
127 pts32 = (uint32_t)pts;
128 p_hwsync->first_apts_flag = true;
129 p_hwsync->first_apts = pts;
130 sprintf(tempbuf, "AUDIO_START:0x%x", pts32);
131 ALOGI("hwsync set tsync -> %s", tempbuf);
132 if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) {
133 ALOGE("set AUDIO_START failed \n");
134 return -1;
135 }
136
137 return 0;
138}
139