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 }