Changeset 242 for trunk

Show
Ignore:
Timestamp:
03/01/08 22:49:03 (4 years ago)
Author:
ath
Message:

Major cleanups and seek retry implementation for FmInputGst.

Location:
trunk/fm_server/src/fm_input_gst
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/fm_server/src/fm_input_gst/fm_input_gst.c

    r240 r242  
    259259                                         const gchar    *filename) 
    260260{ 
    261         g_print("ohhhh- filename %s\n", filename); 
     261//      g_print("ohhhh- filename %s\n", filename); 
    262262 
    263263        g_return_if_fail(filename); 
    264264        FmElement *element = FM_ELEMENT(input_gst); 
    265         FmInput *input = FM_INPUT(input_gst); 
     265//      FmInput *input = FM_INPUT(input_gst); 
    266266        FmInputGstCommon *common = input_gst->common; 
    267267 
     
    272272                return; 
    273273 
    274         FmInputState prev_state = input->state; 
    275  
    276         g_print("Stopping the pipeline...\n"); 
    277 /*      if (prev_state == FM_INPUT_PAUSE) { 
    278                 g_print("unlocking mutex\n"); 
    279                 common->stop_processing = TRUE; 
    280                 fm_sem_increase (common->sem); 
    281         }*/ 
    282          
    283         input_gst->drop_chunks = TRUE;  // let fm_input_gst_get_buffer() drop all the currently unused chunks 
     274//      FmInputState prev_state = input->state; 
     275 
     276//      g_print("Stopping the pipeline...\n"); 
     277//      input_gst->drop_chunks = TRUE;  // let fm_input_gst_get_buffer() drop all the currently unused chunks 
    284278        common->stop_processing = TRUE; 
    285279        fm_sem_increase (common->sem); 
    286         gst_element_set_state (input_gst->common->pipeline, GST_STATE_READY); 
     280        gst_element_set_state (input_gst->common->pipeline, GST_STATE_NULL); 
    287281        g_object_set (G_OBJECT (common->source), "location", input_gst->filename, NULL); 
    288282        common->stop_processing = FALSE; 
    289         g_print("Old state was %d\n", prev_state); 
     283//      g_print("Old state was %d\n", prev_state); 
    290284        reset_status(input_gst); 
    291285 
     
    456450        g_return_val_if_fail (track, NULL); 
    457451 
    458         GList *chunk = track->chunks; 
     452        GSList *chunk = track->chunks; 
    459453 
    460454        while (chunk) { 
    461455                FmChunk *c = chunk->data; 
    462456 
    463                 g_print ("chunk n. %d - start %llu duration %llu", c->num, (long long unsigned int) c->start_timestamp, (long long unsigned int) c->duration_ns); 
     457                g_print ("chunk n. %d - start %llu duration %llu", c->id, (long long unsigned int) c->start_timestamp, (long long unsigned int) c->duration_ns); 
    464458                if (c->usable) 
    465459                        g_print (" USABLE"); 
     
    472466                     (time < (c->start_timestamp + c->duration_ns))) ||  
    473467                    ((time == 0) && (c->start_of_file))) {      // see gstfmsink.c:333 
    474                         g_print ("Found target %llu at chunk %u\n", (long long unsigned int) time, c->num); 
     468                        g_print ("Found target %llu at chunk %u\n", (long long unsigned int) time, c->id); 
    475469                        return c; 
    476470                } 
     
    488482        g_return_if_fail (track); 
    489483 
    490         GList *chunk_list = track->chunks; 
     484        GSList *chunk_list = track->chunks; 
    491485 
    492486        while (chunk_list) { 
     
    495489                 
    496490                if ((chunk != track->read_chunk) && (chunk->usable)) { 
    497                         g_print ("Marking chunk %d for deletion", chunk->num); 
     491                        g_print ("Marking chunk %d for deletion", chunk->id); 
    498492                        chunk->usable = FALSE; 
    499493                        chunk->can_destroy = TRUE; 
     
    524518        /* Check if we have a new track ready */ 
    525519        if (common->new_track) { 
     520                FmInputGstTrack *old_track = track; 
    526521                input_gst->read_track = common->new_track; 
    527522                track = input_gst->read_track; 
     
    529524                g_print ("NEW TRACK - skipped to track %d\n", track->id); 
    530525                skip_to = _search_chunk (track, 0); 
     526 
     527                if (old_track) { 
     528                        _mark_unused_chunks_for_deletion (old_track); 
     529                        old_track->can_destroy = TRUE; 
     530                } 
    531531        } 
    532532 
     
    557557                        if (skip_to) { 
    558558                                /* CHUNK seek - the destination is in another ready chunk */ 
    559                                 g_print ("seek at %ld, first %ld last %ld, CHUNK %u\n", seek_at_sample, first_avail_sample, last_avail_sample, skip_to->num); 
     559                                g_print ("seek at %ld, first %ld last %ld, CHUNK %u\n", seek_at_sample, first_avail_sample, last_avail_sample, skip_to->id); 
    560560                         
    561561                        } else { 
     
    606606         
    607607        /* If we are requested to drop unused chunks (ie. song change), do it now */ 
    608         if (input_gst->drop_chunks) { 
     608        /*if (input_gst->drop_chunks) { 
    609609                _mark_unused_chunks_for_deletion (track); 
    610610                input_gst->drop_chunks = FALSE; 
    611         } 
     611        }*/ 
    612612 
    613613 
     
    902902 
    903903                default: 
    904                         g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message)); 
     904//                      g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message)); 
    905905                        /* unhandled message */ 
    906906                break; 
  • trunk/fm_server/src/fm_input_gst/fm_input_gst.h

    r240 r242  
    5353        guint           tick_ns_count;  // for "tick" 
    5454         
    55         gboolean        drop_chunks;    // invalidate all the currently unused chunks    
     55//      gboolean        drop_chunks;    // invalidate all the currently unused chunks    
    5656 
    5757        guint           rt_signal; 
  • trunk/fm_server/src/fm_input_gst/fm_input_gst_common.c

    r240 r242  
    3030 
    3131FmChunk * 
    32 fm_chunk_new                            (guint          samples) 
     32fm_chunk_new                            (guint          samples, 
     33                                         guint          id) 
    3334{ 
    3435        FmChunk *chk = g_new0(FmChunk, 1); 
    3536         
     37        chk->id = id; 
    3638        chk->ring = jack_ringbuffer_create(samples * 2 * sizeof(gfloat)); 
    3739 
     
    5355        FmInputGstTrack *track = g_new0(FmInputGstTrack, 1); 
    5456        track->id = id; 
     57        track->writing = TRUE; 
     58        track->loaded = FALSE; 
     59        track->chunks = NULL; 
     60        track->chunk_count = 0; 
     61        track->write_chunk = NULL; 
     62        track->read_chunk = NULL; 
    5563        track->gst_seek_to_ns = -1; 
    5664        track->seek_waiting_for_ns = -1; 
  • trunk/fm_server/src/fm_input_gst/fm_input_gst_common.h

    r240 r242  
    3535struct _FmChunk 
    3636{ 
    37         guint           num; 
     37        guint           id; 
    3838        jack_ringbuffer_t *ring; 
    3939     
     
    4343        GstClockTime    start_timestamp_offset;         // where to find the REAL start of the segment requested in the seek 
    4444                                                        // (as an offset from the start of the chunk) 
     45        GstClockTime    asked_timestamp; 
     46 
    4547        gint64          duration_ns; 
    4648 
     
    6668        guint           id; 
    6769 
    68         gboolean        writing;                // GstFmSink can be writing to this track 
    69         gboolean        loaded; 
     70        gboolean        writing;                // GstFmSink has write access to this track 
     71                                                // it will be set to FALSE only when it has abandoned this track 
     72        gboolean        loaded;  
     73        gboolean        can_destroy;            // FmInputGst has stopped reading this track and moved to the next, 
     74                                                // so it can be freed 
    7075 
    71         GList           *chunks; 
     76        GSList          *chunks; 
     77        guint           chunk_count; 
    7278        FmChunk         *write_chunk; 
    7379        FmChunk         *read_chunk; 
     
    100106        gboolean        stop_processing;        // discard incoming buffers and delete chunks 
    101107 
    102         GList           *tracks; 
     108        GSList          *tracks; 
    103109        FmInputGstTrack *new_track; 
    104110 
     
    110116 
    111117FmChunk * 
    112 fm_chunk_new                            (guint          samples); 
     118fm_chunk_new                            (guint          samples, 
     119                                         guint          id); 
    113120 
    114121void 
  • trunk/fm_server/src/fm_input_gst/gstfmsink.c

    r240 r242  
    191191        sink->seek_target_timestamp = -1; 
    192192 
    193         sink->chunk_count = 0; 
    194  
    195193        sink->write_track = NULL; 
    196194        sink->track_count = 0; 
     
    234232gst_fm_sink_event  (GstBaseSink *bsink, GstEvent *event) 
    235233{ 
    236         g_print(">   event %p (%s)\n", event, GST_EVENT_TYPE_NAME (event)); 
     234//      g_print(">   event %p (%s)\n", event, GST_EVENT_TYPE_NAME (event)); 
    237235 
    238236        GstFmSink *sink = GST_FM_SINK (bsink); 
     
    252250                } 
    253251                case GST_EVENT_NEWSEGMENT: { 
    254                         g_print(">   new segment! creating a new chunk...\n"); 
     252//                      g_print(">   new segment! creating a new chunk...\n"); 
    255253                        sink->create_new_chunk = TRUE; 
    256254                } 
     
    266264do_cleanup(FmInputGstTrack *track) 
    267265{ 
    268         GList *list = track->chunks; 
     266        GSList *list = track->chunks; 
    269267        while (list) { 
    270268                FmChunk *chk = (FmChunk *) list->data; 
    271269                if (chk->can_destroy) { 
    272                         track->chunks = g_list_remove_link(track->chunks, list); 
     270                        track->chunks = g_slist_remove_link(track->chunks, list); 
    273271                         
    274                         g_print(">   Destroying chunk %u\n", chk->num); 
     272                        g_print(">   Destroying chunk %u of track %u\n", chk->id, track->id); 
    275273                        fm_chunk_destroy(chk); 
    276                         g_list_free(list); 
     274                        g_slist_free(list); 
    277275 
    278276                        return TRUE; 
    279277                } 
    280                 list = g_list_next(list); 
     278                list = g_slist_next(list); 
     279        } 
     280 
     281        return FALSE; 
     282} 
     283 
     284 
     285static gboolean 
     286do_cleanup_tracks(FmInputGstCommon *common) 
     287{ 
     288        GSList *list = common->tracks; 
     289        while (list) { 
     290                FmInputGstTrack *track = (FmInputGstTrack *) list->data; 
     291                if (track->can_destroy) { 
     292                        common->tracks = g_slist_remove_link(common->tracks, list); 
     293                         
     294                        g_print(">   Destroying track %u\n", track->id); 
     295                        while (do_cleanup(track));      // destroy the remaining unused chunks 
     296 
     297                        if (g_slist_length(track->chunks) > 0) 
     298                                g_warning ("track not empty!"); 
     299 
     300                        fm_input_gst_track_destroy(track); 
     301                        g_slist_free(list); 
     302 
     303                        return TRUE; 
     304                } 
     305                list = g_slist_next(list); 
    281306        } 
    282307 
     
    302327                sink->seek_in_progress = FALSE; 
    303328                sink->seek_target_timestamp = -1; 
    304                 g_print(">   seek to %lld ns failed!\n", (long long int) sink->seek_target_timestamp); 
     329                g_warning(">   seek to %lld ns failed!", (long long int) sink->seek_target_timestamp); 
    305330        } 
    306331 
     
    335360                } 
    336361 
    337                 chk = fm_chunk_new (SAMPLES_TO_BYTES (CHUNK_SAMPLES)); 
    338                 chk->num = sink->chunk_count++; 
    339                 track->chunks = g_list_append (track->chunks, chk); 
     362                chk = fm_chunk_new (SAMPLES_TO_BYTES (CHUNK_SAMPLES), track->chunk_count++); 
     363                track->chunks = g_slist_append (track->chunks, chk); 
    340364                track->write_chunk = chk; 
    341365 
    342366                gint64 timestamp = GST_BUFFER_TIMESTAMP (buf); 
    343                 g_print (">   new chunk %d, TIMESTAMP %lld\n", chk->num, (long long int) timestamp); 
     367                g_print (">   new chunk %d, TIMESTAMP %lld\n", chk->id, (long long int) timestamp); 
    344368                if ((timestamp > 0) && (timestamp < 50000000)) { 
    345369                        g_warning ("This file probably starts at timestamp %llu, taking care of it", (long long int) timestamp); 
     
    356380                        gint64 nsec_to_skip = sink->seek_target_timestamp - timestamp; 
    357381                        if (nsec_to_skip < 0) { 
    358                                 g_print(">   hell, we targeted for %lld, after seeking we're at %lld!\n", 
     382                                g_warning(">   hell, we targeted for %lld, after seeking we're at %lld!", 
    359383                                (long long int) sink->seek_target_timestamp, (long long int) timestamp); 
     384 
     385                                g_warning ("RRRREEEEETTTRRRRRRYYYY!!!!!!!!!!!!!!!!!!!!!!!!!!!! ********************************************************************************"); 
     386                                chk->can_destroy = TRUE; 
     387                                track->gst_seek_to_ns = sink->seek_target_timestamp; 
     388 
     389                                //g_assert_not_reached (); 
    360390                        } else { 
    361                                 g_print(">   target for seek %lld, after seeking we're at %lld, skipping %lld\n",  
     391                                if (nsec_to_skip > 0) 
     392                                g_warning(">   target for seek %lld, after seeking we're at %lld, need to skip %lld\n",  
    362393                                        (long long int) sink->seek_target_timestamp, (long long int) timestamp, (long long int) nsec_to_skip); 
    363394 
     
    397428                        if (track->gst_seek_to_ns > -1) { 
    398429                                if (sink->seek_in_progress) { 
    399                                         g_print (">   seek already in progress, we'll try later\n"); 
     430                                        g_warning ("   seek already in progress, we'll try later"); 
    400431                                        continue; 
    401432                                } 
     
    514545        GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; 
    515546        GstFmSink *fm_sink = GST_FM_SINK (element); 
     547        FmInputGstCommon *common = fm_sink->common; 
    516548 
    517549        switch (transition) { 
    518                 case GST_STATE_CHANGE_READY_TO_PAUSED: { 
    519                         g_warning ("GST_STATE_CHANGE_READY_TO_PAUSED - LOAD TRACK"); 
     550                case GST_STATE_CHANGE_NULL_TO_READY: { 
     551                        g_print ("GST_STATE_CHANGE_NULL_TO_READY - LOAD TRACK\n"); 
     552 
     553                        do_cleanup_tracks (common); 
    520554 
    521555                        FmInputGstTrack *track = fm_input_gst_track_new (fm_sink->track_count++); 
     556                        common->tracks = g_slist_append (common->tracks, track); 
    522557                        fm_sink->write_track = track; 
    523558                        track->writing = TRUE; 
     
    534569 
    535570        switch (transition) { 
    536                 case GST_STATE_CHANGE_PLAYING_TO_PAUSED: 
    537                         g_warning ("GST_STATE_CHANGE_PLAYING_TO_PAUSED - UNLOAD TRACK"); 
     571                case GST_STATE_CHANGE_READY_TO_NULL: 
     572                        g_print ("GST_STATE_CHANGE_READY_TO_NULL - UNLOAD TRACK\n"); 
    538573 
    539574                        fm_sink->write_track->writing = FALSE; 
  • trunk/fm_server/src/fm_input_gst/gstfmsink.h

    r240 r242  
    9292        guint           bytes_behind_us; 
    9393 
    94         guint           chunk_count; 
    9594        guint           track_count; 
    9695