1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
/* -*- C -*- */
_TYPE_ *data_in, *data_out, *filter_data;
filter_data = (_TYPE_ *) filter->buffer;
num_filter = filter->buffer_bytes / sizeof(_TYPE_);
do {
if (in == NULL && ! filter->eos) in = gst_pad_pull(filter->sinkpad);
/****************************************************************************/
/* see if we've got any events coming through ... */
while (! filter->eos && GST_IS_EVENT(in)) {
if (GST_EVENT_TYPE(in) == GST_EVENT_EOS) {
gst_event_unref(in);
gst_buffer_free(in);
filter->eos = TRUE;
} else if ((GST_EVENT_TYPE(in) == GST_EVENT_SEEK) ||
(GST_EVENT_TYPE(in) == GST_EVENT_FLUSH)) {
gst_event_unref(in);
gst_buffer_free(in);
filter->eos = FALSE;
filter->write = 0;
} else {
gst_pad_push(filter->srcpad, in);
}
in = gst_pad_pull(filter->sinkpad);
}
/****************************************************************************/
/* handle data from the input buffer. */
if (! filter->eos) {
register guint j, w = filter->write;
data_in = (_TYPE_ *) GST_BUFFER_DATA(in);
num_in = GST_BUFFER_SIZE(in) / sizeof(_TYPE_);
for (j = 0; (j < num_in) && (w+j < num_filter); j++)
filter_data[w+j] = data_in[j];
filter->write += j;
if (filter->write >= num_filter) filter->eos = TRUE;
out = in;
} else {
out = gst_buffer_new_from_pool(filter->bufpool, 0, 0);
}
in = NULL;
/****************************************************************************/
/* check to see if we have to add new play pointers. */
if (filter->clock) {
register gint t, tick_offset;
guint total_ticks = filter->total_ticks;
guint current_tick = \
((guint) (gst_clock_get_time(filter->clock) * filter->tick_rate /
GST_SECOND)) % total_ticks;
/* for some reason modulo arithmetic isn't working for me here, i suspect
some unsigned/signed voodoo. but it's probably safe to do this with an if
statement since it doesn't happen all that often ... */
tick_offset = current_tick - last_tick;
if (tick_offset < 0) tick_offset += total_ticks;
for (tick_offset -= 1, t = current_tick - tick_offset;
tick_offset >= 0;
tick_offset--, t--) {
if (t < 0) t += total_ticks;
if (filter->ticks[t / 32] & (1 << t % 32))
play_on_demand_add_play_pointer(
filter, filter->rate * tick_offset / filter->tick_rate);
}
last_tick = current_tick;
}
/****************************************************************************/
/* handle output data. */
{
register guint k, p;
data_out = (_TYPE_ *) GST_BUFFER_DATA(out);
num_out = GST_BUFFER_SIZE(out) / sizeof(_TYPE_);
for (k = 0; k < num_out; k++) data_out[k] = zero;
for (p = 0; p < filter->max_plays; p++) {
guint offset = filter->plays[p];
if (offset != G_MAXUINT) {
/* only copy audio data if the element's not muted. */
if (! filter->mute)
for (k = 0; (k < num_out) && (offset+k < num_filter); k++)
data_out[k] = CLAMP(data_out[k] + filter_data[offset+k], min, max);
/* update the play pointer. k > 0 even if the filter is muted. */
filter->plays[p] = (offset+k >= num_filter) ? G_MAXUINT : offset + k;
}
}
}
/****************************************************************************/
/* push out the buffer. */
gst_pad_push(filter->srcpad, out);
if (gst_element_interrupt (GST_ELEMENT (filter))) break;
} while (TRUE);
|