Mercurial > audlegacy-plugins
comparison src/demac/plugin.c @ 3028:b20622733f08
Fix seeking when paused for .ape plugin (Debian bug #517692)
author | John Lindgren <john.lindgren@tds.net> |
---|---|
date | Fri, 10 Apr 2009 00:28:00 -0400 |
parents | 3134a0987162 |
children |
comparison
equal
deleted
inserted
replaced
3027:3b200cf6d1b7 | 3028:b20622733f08 |
---|---|
59 static gpointer demac_decode_loop(InputPlayback *pb); | 59 static gpointer demac_decode_loop(InputPlayback *pb); |
60 static Tuple *demac_get_tuple(char *filename); | 60 static Tuple *demac_get_tuple(char *filename); |
61 static Tuple *demac_probe_for_tuple (gchar *uri, VFSFile *vfd); | 61 static Tuple *demac_probe_for_tuple (gchar *uri, VFSFile *vfd); |
62 | 62 |
63 static GMutex *demac_mutex; | 63 static GMutex *demac_mutex; |
64 static unsigned long seek_to_msec=(unsigned long)-1; /* -1 == not needed */ | 64 static volatile int seek_to_msec = -1; |
65 static volatile char pause_flag = 0; | |
65 | 66 |
66 static InputPlugin demac_ip; | 67 static InputPlugin demac_ip; |
67 static GtkWidget *about_window = NULL; | 68 static GtkWidget *about_window = NULL; |
68 | 69 |
69 #ifdef AUD_DEBUG | 70 #ifdef AUD_DEBUG |
91 pb->playing = 1; | 92 pb->playing = 1; |
92 pb->eof = 0; | 93 pb->eof = 0; |
93 pb->error = FALSE; | 94 pb->error = FALSE; |
94 pb_thread = g_thread_self(); | 95 pb_thread = g_thread_self(); |
95 pb->set_pb_ready(pb); | 96 pb->set_pb_ready(pb); |
96 | 97 |
97 demac_decode_loop(pb); | 98 demac_decode_loop(pb); |
98 } | 99 } |
99 | 100 |
100 static void demac_do_mseek(APEContext *ctx, unsigned long msec) { | 101 static void demac_do_mseek (APEContext * ctx, InputPlayback * playback) { |
101 if(ctx->seektable) { | 102 if(ctx->seektable) { |
102 unsigned int framecount = msec * ((unsigned long long)ctx->totalframes - 1L) / ctx->duration; | 103 ctx->currentframe = (ctx->totalframes - 1) * (long long) seek_to_msec |
103 ctx->currentframe = framecount; | 104 / ctx->duration; |
105 playback->output->flush (ctx->duration * (long long) ctx->currentframe | |
106 / (ctx->totalframes - 1)); | |
107 seek_to_msec = -1; | |
104 } | 108 } |
105 } | 109 } |
106 | 110 |
107 gpointer demac_decode_loop(InputPlayback *pb) { | 111 gpointer demac_decode_loop(InputPlayback *pb) { |
108 VFSFile *vfd; | 112 VFSFile *vfd; |
110 guint8 *wav = NULL; | 114 guint8 *wav = NULL; |
111 int wav_buffer_size; | 115 int wav_buffer_size; |
112 gchar *title = NULL; | 116 gchar *title = NULL; |
113 int audio_opened = 0; | 117 int audio_opened = 0; |
114 int playing; | 118 int playing; |
115 unsigned long local_seek_to; | 119 char paused = 0; |
116 APEContext *ctx = NULL; | 120 APEContext *ctx = NULL; |
117 APEDecoderContext *dec = NULL; | 121 APEDecoderContext *dec = NULL; |
118 int decoded_bytes; | 122 int decoded_bytes; |
119 int pkt_size, bytes_used; | 123 int pkt_size, bytes_used; |
120 #ifdef AUD_DEBUG | 124 #ifdef AUD_DEBUG |
168 | 172 |
169 while (playing && (ctx->currentframe < ctx->totalframes)) | 173 while (playing && (ctx->currentframe < ctx->totalframes)) |
170 { | 174 { |
171 g_mutex_lock(demac_mutex); | 175 g_mutex_lock(demac_mutex); |
172 playing = pb->playing; | 176 playing = pb->playing; |
173 local_seek_to = seek_to_msec; | |
174 g_mutex_unlock(demac_mutex); | 177 g_mutex_unlock(demac_mutex); |
175 | 178 if (seek_to_msec != -1) { |
176 /* do seeking */ | 179 demac_do_mseek (ctx, pb); |
177 if (local_seek_to != -1) { | |
178 demac_do_mseek(ctx, local_seek_to); | |
179 pb->output->flush(local_seek_to); | |
180 | |
181 local_seek_to = -1; | |
182 g_mutex_lock(demac_mutex); | |
183 seek_to_msec = -1; | |
184 g_mutex_unlock(demac_mutex); | |
185 | |
186 /* reset decoder */ | 180 /* reset decoder */ |
187 dec->samples = 0; | 181 dec->samples = 0; |
188 } | 182 } |
189 | 183 |
190 ape_read_packet(ctx, vfd, frame_buf, &pkt_size); | 184 ape_read_packet(ctx, vfd, frame_buf, &pkt_size); |
193 frame_crc = ape_initcrc(); | 187 frame_crc = ape_initcrc(); |
194 #endif | 188 #endif |
195 bytes_used = 0; | 189 bytes_used = 0; |
196 | 190 |
197 /* Decode the frame a chunk at a time */ | 191 /* Decode the frame a chunk at a time */ |
198 while (playing && (bytes_used != pkt_size) && (local_seek_to == -1)) | 192 while (playing && (bytes_used != pkt_size)) { |
199 { | 193 if (pause_flag) { |
194 if (! paused) { | |
195 pb->output->pause (1); | |
196 paused = 1; | |
197 } | |
198 while (pause_flag && seek_to_msec == -1) | |
199 g_usleep (50000); | |
200 } | |
201 if (paused && ! pause_flag) { | |
202 pb->output->pause (0); | |
203 paused = 0; | |
204 } | |
205 if (seek_to_msec != -1) | |
206 break; | |
200 g_mutex_lock(demac_mutex); | 207 g_mutex_lock(demac_mutex); |
201 playing = pb->playing; | 208 playing = pb->playing; |
202 local_seek_to = seek_to_msec; | |
203 g_mutex_unlock(demac_mutex); | 209 g_mutex_unlock(demac_mutex); |
204 | 210 |
205 decoded_bytes = wav_buffer_size; | 211 decoded_bytes = wav_buffer_size; |
206 bytes_used = ape_decode_frame(dec, wav, &decoded_bytes, frame_buf, pkt_size); | 212 bytes_used = ape_decode_frame(dec, wav, &decoded_bytes, frame_buf, pkt_size); |
207 if(bytes_used < 0) { | 213 if(bytes_used < 0) { |
208 /* skip frame */ | 214 /* skip frame */ |
209 dec->samples = 0; | 215 dec->samples = 0; |
210 break; | 216 break; |
211 } | 217 } |
212 | |
213 if(local_seek_to != -1) break; | |
214 | |
215 /* Write audio data */ | 218 /* Write audio data */ |
216 pb->pass_audio(pb, FMT_S16_LE, ctx->channels, decoded_bytes, wav, &playing); | 219 pb->pass_audio(pb, FMT_S16_LE, ctx->channels, decoded_bytes, wav, &playing); |
217 #ifdef AUD_DEBUG | 220 #ifdef AUD_DEBUG |
218 frame_crc = ape_updatecrc(wav, decoded_bytes, frame_crc); | 221 frame_crc = ape_updatecrc(wav, decoded_bytes, frame_crc); |
219 #endif | 222 #endif |
263 AUDDBG("** demac: plugin.c: thread finished\n"); | 266 AUDDBG("** demac: plugin.c: thread finished\n"); |
264 } | 267 } |
265 } | 268 } |
266 | 269 |
267 static void demac_pause(InputPlayback *pb, short paused) { | 270 static void demac_pause(InputPlayback *pb, short paused) { |
268 pb->output->pause(paused); | 271 pause_flag = paused; |
269 } | 272 } |
270 | 273 |
271 static void destroy_cb(mowgli_dictionary_elem_t *delem, void *privdata) { | 274 static void destroy_cb(mowgli_dictionary_elem_t *delem, void *privdata) { |
272 g_free(delem->data); | 275 g_free(delem->data); |
273 } | 276 } |
329 aud_vfs_fclose(vfd); | 332 aud_vfs_fclose(vfd); |
330 return tpl; | 333 return tpl; |
331 } | 334 } |
332 | 335 |
333 static void demac_mseek (InputPlayback *pb, gulong millisecond) { | 336 static void demac_mseek (InputPlayback *pb, gulong millisecond) { |
334 g_mutex_lock(demac_mutex); | |
335 seek_to_msec = millisecond; | 337 seek_to_msec = millisecond; |
336 g_mutex_unlock(demac_mutex); | 338 while (seek_to_msec != -1) |
337 AUDDBG("** demac: plugin.c: seeking to %u msec\n", millisecond); | 339 g_usleep (50000); |
338 } | 340 } |
339 | 341 |
340 static void demac_seek (InputPlayback *pb, gint time) { | 342 static void demac_seek (InputPlayback *pb, gint time) { |
341 demac_mseek(pb, (unsigned long)time*1000); | 343 demac_mseek(pb, (unsigned long)time*1000); |
342 } | 344 } |