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 } |
