Changeset 240
- Timestamp:
- 02/27/08 21:41:33 (4 years ago)
- Location:
- trunk/fm_server/src/fm_input_gst
- Files:
-
- 6 modified
-
fm_input_gst.c (modified) (14 diffs)
-
fm_input_gst.h (modified) (1 diff)
-
fm_input_gst_common.c (modified) (1 diff)
-
fm_input_gst_common.h (modified) (3 diffs)
-
gstfmsink.c (modified) (13 diffs)
-
gstfmsink.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/fm_server/src/fm_input_gst/fm_input_gst.c
r222 r240 185 185 input_gst->seek_at_ns = -1; 186 186 187 if (input_gst-> common)188 input_gst-> common->gst_seek_to_ns = -1;187 if (input_gst->read_track) 188 input_gst->read_track->gst_seek_to_ns = -1; 189 189 } 190 190 … … 293 293 gst_element_set_state (input_gst->common->pipeline, GST_STATE_PLAYING); 294 294 295 common->seek_waiting_for_ns = 0;295 // common->seek_waiting_for_ns = 0; 296 296 } 297 297 … … 348 348 reset_status(input_gst); 349 349 350 FmInputGstCommon *common = g_new0 (FmInputGstCommon, 1);350 FmInputGstCommon *common = g_new0 (FmInputGstCommon, 1); 351 351 input_gst->common = common; 352 352 common->input_gst = input_gst; 353 353 common->sem = fm_sem_new (1); 354 common->gst_seek_to_ns = -1;354 // common->seek_waiting_for_ns = -1; 355 355 common->sample_rate = fm_pipeline_get_sample_rate (FM_PIPELINE (element->pipeline)); 356 356 … … 437 437 _send_position (FmInputGst *input_gst) 438 438 { 439 FmInputGstCommon *common = input_gst->common;440 FmChunk *chk = common->read_chunk;439 // FmInputGstCommon *common = input_gst->common; 440 FmChunk *chk = input_gst->read_track->read_chunk; 441 441 442 442 if (!chk) … … 451 451 452 452 static FmChunk * 453 _search_chunk (FmInputGst Common *common,453 _search_chunk (FmInputGstTrack *track, 454 454 GstClockTime time) 455 455 { 456 GList *chunk = common->chunks; 456 g_return_val_if_fail (track, NULL); 457 458 GList *chunk = track->chunks; 457 459 458 460 while (chunk) { … … 482 484 483 485 static void 484 _mark_unused_chunks_for_deletion (FmInputGstCommon *common) 485 { 486 GList *chunk_list = common->chunks; 486 _mark_unused_chunks_for_deletion (FmInputGstTrack *track) 487 { 488 g_return_if_fail (track); 489 490 GList *chunk_list = track->chunks; 487 491 488 492 while (chunk_list) { … … 490 494 g_assert (chunk); 491 495 492 if ((chunk != common->read_chunk) && (chunk->usable)) {496 if ((chunk != track->read_chunk) && (chunk->usable)) { 493 497 g_print ("Marking chunk %d for deletion", chunk->num); 494 498 chunk->usable = FALSE; … … 509 513 FmInputGst *input_gst = FM_INPUT_GST(element); 510 514 FmInputGstCommon *common = input_gst->common; 511 FmChunk *chk = common->read_chunk; 515 FmInputGstTrack *track = input_gst->read_track; 516 FmChunk *chk = NULL; 512 517 FmChunk *skip_to = NULL; 513 518 519 if (track) 520 chk = track->read_chunk; 514 521 515 522 fm_buffer_reset_flags (buffer); 523 524 /* Check if we have a new track ready */ 525 if (common->new_track) { 526 input_gst->read_track = common->new_track; 527 track = input_gst->read_track; 528 common->new_track = NULL; 529 g_print ("NEW TRACK - skipped to track %d\n", track->id); 530 skip_to = _search_chunk (track, 0); 531 } 516 532 517 533 /* Check if we should perform a seek */ … … 538 554 FM_BUFFER_DISCONT (buffer) = TRUE; 539 555 } else { 540 skip_to = _search_chunk ( common, input_gst->seek_at_ns);556 skip_to = _search_chunk (track, input_gst->seek_at_ns); 541 557 if (skip_to) { 542 558 /* CHUNK seek - the destination is in another ready chunk */ … … 547 563 g_print ("seek at %ld, first %ld last %ld, FAR\n", seek_at_sample, first_avail_sample, last_avail_sample); 548 564 549 common->gst_seek_to_ns = input_gst->seek_at_ns;565 track->gst_seek_to_ns = input_gst->seek_at_ns; 550 566 // g_print (" seek_at_nsec = %lld\n", (long long int) common->gst_seek_to_nsec); 551 common->seek_waiting_for_ns = input_gst->seek_at_ns;567 track->seek_waiting_for_ns = input_gst->seek_at_ns; 552 568 fm_sem_increase (common->sem); 553 569 } … … 558 574 559 575 /* Check if a FAR seek has been completed */ 560 if ((!skip_to) && ( common->seek_waiting_for_ns > -1)) {576 if ((!skip_to) && (track) && (track->seek_waiting_for_ns > -1)) { 561 577 // g_print ("Waiting...\n"); 562 skip_to = _search_chunk ( common, common->seek_waiting_for_ns);578 skip_to = _search_chunk (track, track->seek_waiting_for_ns); 563 579 if (skip_to) 564 common->seek_waiting_for_ns = -1;580 track->seek_waiting_for_ns = -1; 565 581 } 566 582 … … 572 588 g_warning ("Skipping to a chunk not marked usable!"); 573 589 574 common->read_chunk = skip_to;590 track->read_chunk = skip_to; 575 591 576 chk = common->read_chunk;592 chk = track->read_chunk; 577 593 chk->usable = FALSE; 578 594 … … 591 607 /* If we are requested to drop unused chunks (ie. song change), do it now */ 592 608 if (input_gst->drop_chunks) { 593 _mark_unused_chunks_for_deletion ( common);609 _mark_unused_chunks_for_deletion (track); 594 610 input_gst->drop_chunks = FALSE; 595 611 } … … 787 803 g_return_if_fail (pos < 1); 788 804 789 FmInputGst Common *common = input_gst->common;790 g_return_if_fail ( common->read_chunk);791 g_return_if_fail ( common->read_chunk->duration_ns > 0);792 793 input_gst->seek_at_ns = common->read_chunk->duration_ns * pos;805 FmInputGstTrack *track = input_gst->read_track; 806 g_return_if_fail (track->read_chunk); 807 g_return_if_fail (track->read_chunk->duration_ns > 0); 808 809 input_gst->seek_at_ns = track->read_chunk->duration_ns * pos; 794 810 } 795 811 -
trunk/fm_server/src/fm_input_gst/fm_input_gst.h
r222 r240 58 58 GValue *val1; 59 59 GValue *val2; 60 61 FmInputGstTrack *read_track; 60 62 }; 61 63 -
trunk/fm_server/src/fm_input_gst/fm_input_gst_common.c
r221 r240 44 44 { 45 45 jack_ringbuffer_free(chk->ring); 46 free(chk); 46 g_free(chk); 47 } 48 49 50 FmInputGstTrack * 51 fm_input_gst_track_new (guint id) 52 { 53 FmInputGstTrack *track = g_new0(FmInputGstTrack, 1); 54 track->id = id; 55 track->gst_seek_to_ns = -1; 56 track->seek_waiting_for_ns = -1; 57 return track; 58 } 59 60 61 void 62 fm_input_gst_track_destroy (FmInputGstTrack *track) 63 { 64 g_free (track); 47 65 } 48 66 -
trunk/fm_server/src/fm_input_gst/fm_input_gst_common.h
r222 r240 60 60 61 61 62 63 typedef struct _FmInputGstTrack FmInputGstTrack; 64 65 struct _FmInputGstTrack { 66 guint id; 67 68 gboolean writing; // GstFmSink can be writing to this track 69 gboolean loaded; 70 71 GList *chunks; 72 FmChunk *write_chunk; 73 FmChunk *read_chunk; 74 75 gint64 gst_seek_to_ns; // only for a FAR seek, where GStreamer should seek 76 gint64 seek_waiting_for_ns; // only for a FAR seek, wait for a new chunk returned from GST which starts here 77 }; 78 79 80 62 81 typedef struct _FmInputGstCommon FmInputGstCommon; 63 82 … … 77 96 GstPad *output_pad; 78 97 79 GList *chunks;80 FmChunk *write_chunk;81 FmChunk *read_chunk;82 83 98 FmSemaphore *sem; 84 99 85 100 gboolean stop_processing; // discard incoming buffers and delete chunks 86 101 87 gint64 seek_waiting_for_ns; // only for a FAR seek, wait for a new chunk returned from GST which starts here88 gint64 gst_seek_to_ns; // only for a FAR seek, where GStreamer should seek102 GList *tracks; 103 FmInputGstTrack *new_track; 89 104 90 105 gdouble ns_for_sample; … … 100 115 fm_chunk_destroy (FmChunk *chk); 101 116 117 FmInputGstTrack * 118 fm_input_gst_track_new (guint id); 119 120 void 121 fm_input_gst_track_destroy (FmInputGstTrack *track); 122 102 123 guint64 103 124 ns_to_samples (FmInputGstCommon *common, -
trunk/fm_server/src/fm_input_gst/gstfmsink.c
r222 r240 102 102 static GstCaps *gst_fm_sink_getcaps (GstBaseSink *bsink); 103 103 gboolean seek_helper (gpointer data); 104 static GstStateChangeReturn 105 gst_fm_sink_change_state (GstElement *element, GstStateChange transition); 104 106 105 107 static GstElementClass *parent_class = NULL; … … 167 169 168 170 gstbase_sink_class->get_caps = GST_DEBUG_FUNCPTR (gst_fm_sink_getcaps); 171 172 gstelement_class->change_state = gst_fm_sink_change_state; 169 173 } 170 174 … … 188 192 189 193 sink->chunk_count = 0; 194 195 sink->write_track = NULL; 196 sink->track_count = 0; 190 197 } 191 198 … … 230 237 231 238 GstFmSink *sink = GST_FM_SINK (bsink); 232 FmInputGstCommon *common = sink->common; 239 // FmInputGstCommon *common = sink->common; 240 FmInputGstTrack *track = sink->write_track; 233 241 234 242 switch (GST_EVENT_TYPE (event)) { 235 243 236 244 case GST_EVENT_EOS: { 237 g_return_val_if_fail ( common->write_chunk, TRUE);238 common->write_chunk->eof_samples = sink->position_samples;245 g_return_val_if_fail (track->write_chunk, TRUE); 246 track->write_chunk->eof_samples = sink->position_samples; 239 247 g_print("> got EOF at timestamp %lld\n", (long long int) sink->start_timestamp); 240 248 sink->seek_in_progress = FALSE; … … 256 264 257 265 static gboolean 258 do_cleanup(FmInputGst Common *common)259 { 260 GList *list = common->chunks;266 do_cleanup(FmInputGstTrack *track) 267 { 268 GList *list = track->chunks; 261 269 while (list) { 262 270 FmChunk *chk = (FmChunk *) list->data; 263 271 if (chk->can_destroy) { 264 common->chunks = g_list_remove_link(common->chunks, list);272 track->chunks = g_list_remove_link(track->chunks, list); 265 273 266 274 g_print("> Destroying chunk %u\n", chk->num); … … 307 315 GstFmSink *sink = GST_FM_SINK (bsink); 308 316 FmInputGstCommon *common = sink->common; 317 FmInputGstTrack *track = sink->write_track; 309 318 310 319 if (common->stop_processing || (sink->seek_in_progress && !sink->seek_completed)) … … 313 322 guint buffer_pos_bytes = 0; 314 323 315 FmChunk *chk = common->write_chunk;324 FmChunk *chk = track->write_chunk; 316 325 317 326 if ((!chk) || … … 328 337 chk = fm_chunk_new (SAMPLES_TO_BYTES (CHUNK_SAMPLES)); 329 338 chk->num = sink->chunk_count++; 330 common->chunks = g_list_append (common->chunks, chk);331 common->write_chunk = chk;339 track->chunks = g_list_append (track->chunks, chk); 340 track->write_chunk = chk; 332 341 333 342 gint64 timestamp = GST_BUFFER_TIMESTAMP (buf); … … 376 385 377 386 if (bytes_space == 0) { 378 if (do_cleanup( common))387 if (do_cleanup(track)) 379 388 /*g_print ("> cleanup complete\n")*/; 380 389 … … 386 395 return GST_FLOW_OK; 387 396 388 if ( common->gst_seek_to_ns > -1) {397 if (track->gst_seek_to_ns > -1) { 389 398 if (sink->seek_in_progress) { 390 399 g_print ("> seek already in progress, we'll try later\n"); … … 392 401 } 393 402 394 g_print("> requested seek to %lld\n", (long long int) common->gst_seek_to_ns);395 396 sink->seek_target_timestamp = common->gst_seek_to_ns;397 common->gst_seek_to_ns = -1;403 g_print("> requested seek to %lld\n", (long long int) track->gst_seek_to_ns); 404 405 sink->seek_target_timestamp = track->gst_seek_to_ns; 406 track->gst_seek_to_ns = -1; 398 407 sink->seek_in_progress = TRUE; 399 408 … … 440 449 common->loaded = TRUE; 441 450 } 451 452 if (!track->loaded) { 453 track->loaded = TRUE; 454 common->new_track = track; 455 } 442 456 } else 443 457 chk->bytes_preloaded += written_bytes; … … 493 507 } 494 508 509 510 static GstStateChangeReturn 511 gst_fm_sink_change_state (GstElement *element, 512 GstStateChange transition) 513 { 514 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; 515 GstFmSink *fm_sink = GST_FM_SINK (element); 516 517 switch (transition) { 518 case GST_STATE_CHANGE_READY_TO_PAUSED: { 519 g_warning ("GST_STATE_CHANGE_READY_TO_PAUSED - LOAD TRACK"); 520 521 FmInputGstTrack *track = fm_input_gst_track_new (fm_sink->track_count++); 522 fm_sink->write_track = track; 523 track->writing = TRUE; 524 525 break; 526 } 527 default: 528 break; 529 } 530 531 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); 532 if (ret == GST_STATE_CHANGE_FAILURE) 533 return ret; 534 535 switch (transition) { 536 case GST_STATE_CHANGE_PLAYING_TO_PAUSED: 537 g_warning ("GST_STATE_CHANGE_PLAYING_TO_PAUSED - UNLOAD TRACK"); 538 539 fm_sink->write_track->writing = FALSE; 540 541 break; 542 default: 543 break; 544 } 545 546 return ret; 547 } -
trunk/fm_server/src/fm_input_gst/gstfmsink.h
r221 r240 93 93 94 94 guint chunk_count; 95 guint track_count; 96 97 98 FmInputGstTrack *write_track; 95 99 }; 96 100
