Mercurial > mplayer.hg
annotate libaf/af_pan.c @ 25509:1cfa39a320cc
Fix update_subtitles() checking subtitle type for the wrong track.
update_subtitles() uses 'type' field from d_dvdsub even when some other track
is active. For this reason, external vobsub is not displayed when there is at
least one text track from demuxer (type is always 't' or 'a' in this case).
The solution is to check vobsub_id and dvdsub_id instead.
author | eugeni |
---|---|
date | Fri, 28 Dec 2007 20:57:38 +0000 |
parents | b2402b4f0afa |
children | 72d0b1444141 |
rev | line source |
---|---|
8607 | 1 /*============================================================================= |
2 // | |
13602
14090f7300a8
The full name of the GPL is GNU General Public License.
diego
parents:
12008
diff
changeset
|
3 // This software has been released under the terms of the GNU General Public |
8607 | 4 // license. See http://www.gnu.org/copyleft/gpl.html for details. |
5 // | |
6 // Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au | |
7 // | |
8 //============================================================================= | |
9 */ | |
10 | |
11 /* */ | |
12 | |
13 #include <stdio.h> | |
14 #include <stdlib.h> | |
15 | |
16 #include <inttypes.h> | |
17 #include <math.h> | |
18 #include <limits.h> | |
19 | |
20 #include "af.h" | |
21 | |
22 // Data for specific instances of this filter | |
23 typedef struct af_pan_s | |
24 { | |
23532
a1eb547cf52e
Avoid zero output for pan filter; zero output now means same # of channels
zuxy
parents:
23531
diff
changeset
|
25 int nch; // Number of output channels; zero means same as input |
8607 | 26 float level[AF_NCH][AF_NCH]; // Gain level for each channel |
27 }af_pan_t; | |
28 | |
29 // Initialization and runtime control | |
30 static int control(struct af_instance_s* af, int cmd, void* arg) | |
31 { | |
32 af_pan_t* s = af->setup; | |
33 | |
34 switch(cmd){ | |
35 case AF_CONTROL_REINIT: | |
36 // Sanity check | |
37 if(!arg) return AF_ERROR; | |
38 | |
39 af->data->rate = ((af_data_t*)arg)->rate; | |
14245 | 40 af->data->format = AF_FORMAT_FLOAT_NE; |
8607 | 41 af->data->bps = 4; |
23532
a1eb547cf52e
Avoid zero output for pan filter; zero output now means same # of channels
zuxy
parents:
23531
diff
changeset
|
42 af->data->nch = s->nch ? s->nch: ((af_data_t*)arg)->nch; |
24888 | 43 af->mul = (double)af->data->nch / ((af_data_t*)arg)->nch; |
8607 | 44 |
45 if((af->data->format != ((af_data_t*)arg)->format) || | |
46 (af->data->bps != ((af_data_t*)arg)->bps)){ | |
47 ((af_data_t*)arg)->format = af->data->format; | |
48 ((af_data_t*)arg)->bps = af->data->bps; | |
49 return AF_FALSE; | |
50 } | |
23532
a1eb547cf52e
Avoid zero output for pan filter; zero output now means same # of channels
zuxy
parents:
23531
diff
changeset
|
51 return AF_OK; |
8607 | 52 case AF_CONTROL_COMMAND_LINE:{ |
53 int nch = 0; | |
54 int n = 0; | |
55 char* cp = NULL; | |
56 int j,k; | |
57 // Read number of outputs | |
58 sscanf((char*)arg,"%i%n", &nch,&n); | |
59 if(AF_OK != control(af,AF_CONTROL_PAN_NOUT | AF_CONTROL_SET, &nch)) | |
60 return AF_ERROR; | |
61 | |
62 // Read pan values | |
63 cp = &((char*)arg)[n]; | |
64 j = 0; k = 0; | |
65 while((*cp == ':') && (k < AF_NCH)){ | |
16493
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
66 sscanf(cp, ":%f%n" , &s->level[j][k], &n); |
8607 | 67 af_msg(AF_MSG_VERBOSE,"[pan] Pan level from channel %i to" |
16493
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
68 " channel %i = %f\n",k,j,s->level[j][k]); |
8607 | 69 cp =&cp[n]; |
70 j++; | |
71 if(j>=nch){ | |
72 j = 0; | |
73 k++; | |
74 } | |
75 } | |
76 return AF_OK; | |
77 } | |
78 case AF_CONTROL_PAN_LEVEL | AF_CONTROL_SET:{ | |
79 int i; | |
80 int ch = ((af_control_ext_t*)arg)->ch; | |
81 float* level = ((af_control_ext_t*)arg)->arg; | |
16493
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
82 if (ch >= AF_NCH) |
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
83 return AF_FALSE; |
8607 | 84 for(i=0;i<AF_NCH;i++) |
16493
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
85 s->level[ch][i] = level[i]; |
8607 | 86 return AF_OK; |
87 } | |
88 case AF_CONTROL_PAN_LEVEL | AF_CONTROL_GET:{ | |
89 int i; | |
90 int ch = ((af_control_ext_t*)arg)->ch; | |
91 float* level = ((af_control_ext_t*)arg)->arg; | |
16493
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
92 if (ch >= AF_NCH) |
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
93 return AF_FALSE; |
8607 | 94 for(i=0;i<AF_NCH;i++) |
95 level[i] = s->level[ch][i]; | |
96 return AF_OK; | |
97 } | |
98 case AF_CONTROL_PAN_NOUT | AF_CONTROL_SET: | |
99 // Reinit must be called after this function has been called | |
100 | |
101 // Sanity check | |
12008 | 102 if(((int*)arg)[0] <= 0 || ((int*)arg)[0] > AF_NCH){ |
8607 | 103 af_msg(AF_MSG_ERROR,"[pan] The number of output channels must be" |
104 " between 1 and %i. Current value is %i\n",AF_NCH,((int*)arg)[0]); | |
105 return AF_ERROR; | |
106 } | |
23532
a1eb547cf52e
Avoid zero output for pan filter; zero output now means same # of channels
zuxy
parents:
23531
diff
changeset
|
107 s->nch=((int*)arg)[0]; |
8607 | 108 return AF_OK; |
109 case AF_CONTROL_PAN_NOUT | AF_CONTROL_GET: | |
110 *(int*)arg = af->data->nch; | |
111 return AF_OK; | |
23551 | 112 case AF_CONTROL_PAN_BALANCE | AF_CONTROL_SET:{ |
113 float val = *(float*)arg; | |
114 if (s->nch) | |
115 return AF_ERROR; | |
116 if (af->data->nch >= 2) { | |
117 s->level[0][0] = min(1.f, 1.f - val); | |
118 s->level[0][1] = max(0.f, val); | |
119 s->level[1][0] = max(0.f, -val); | |
120 s->level[1][1] = min(1.f, 1.f + val); | |
121 } | |
122 return AF_OK; | |
123 } | |
124 case AF_CONTROL_PAN_BALANCE | AF_CONTROL_GET: | |
125 if (s->nch) | |
126 return AF_ERROR; | |
127 *(float*)arg = s->level[0][1] - s->level[1][0]; | |
128 return AF_OK; | |
8607 | 129 } |
130 return AF_UNKNOWN; | |
131 } | |
132 | |
133 // Deallocate memory | |
134 static void uninit(struct af_instance_s* af) | |
135 { | |
22175
105f32787336
Fix nonsense tests ("if (af->data->audio)" before "if (af->data)").
uau
parents:
16493
diff
changeset
|
136 if(af->data) |
8674
93212da0032e
10l memory leak + bug fixes in ms to sample time conversion
anders
parents:
8607
diff
changeset
|
137 free(af->data->audio); |
22175
105f32787336
Fix nonsense tests ("if (af->data->audio)" before "if (af->data)").
uau
parents:
16493
diff
changeset
|
138 free(af->data); |
8607 | 139 if(af->setup) |
140 free(af->setup); | |
141 } | |
142 | |
143 // Filter data through filter | |
144 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
145 { | |
146 af_data_t* c = data; // Current working data | |
147 af_data_t* l = af->data; // Local data | |
148 af_pan_t* s = af->setup; // Setup for this instance | |
149 float* in = c->audio; // Input audio data | |
150 float* out = NULL; // Output audio data | |
151 float* end = in+c->len/4; // End of loop | |
152 int nchi = c->nch; // Number of input channels | |
153 int ncho = l->nch; // Number of output channels | |
154 register int j,k; | |
155 | |
156 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
157 return NULL; | |
158 | |
159 out = l->audio; | |
160 // Execute panning | |
161 // FIXME: Too slow | |
162 while(in < end){ | |
163 for(j=0;j<ncho;j++){ | |
164 register float x = 0.0; | |
165 register float* tin = in; | |
166 for(k=0;k<nchi;k++) | |
167 x += tin[k] * s->level[j][k]; | |
168 out[j] = x; | |
169 } | |
170 out+= ncho; | |
171 in+= nchi; | |
172 } | |
173 | |
174 // Set output data | |
175 c->audio = l->audio; | |
24888 | 176 c->len = c->len / c->nch * l->nch; |
8607 | 177 c->nch = l->nch; |
178 | |
179 return c; | |
180 } | |
181 | |
182 // Allocate memory and set function pointers | |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22175
diff
changeset
|
183 static int af_open(af_instance_t* af){ |
8607 | 184 af->control=control; |
185 af->uninit=uninit; | |
186 af->play=play; | |
24888 | 187 af->mul=1; |
8607 | 188 af->data=calloc(1,sizeof(af_data_t)); |
189 af->setup=calloc(1,sizeof(af_pan_t)); | |
190 if(af->data == NULL || af->setup == NULL) | |
191 return AF_ERROR; | |
192 return AF_OK; | |
193 } | |
194 | |
195 // Description of this filter | |
196 af_info_t af_info_pan = { | |
197 "Panning audio filter", | |
198 "pan", | |
199 "Anders", | |
200 "", | |
23531
bd9e74cd4d3d
Make pan reentrant. Multiple pans in chain work fine.
zuxy
parents:
22748
diff
changeset
|
201 AF_FLAGS_REENTRANT, |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22175
diff
changeset
|
202 af_open |
8607 | 203 }; |