Changeset 262

Show
Ignore:
Timestamp:
07/04/08 22:59:58 (4 years ago)
Author:
ath
Message:

Make seeking a lot more robust.

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

Legend:

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

    r246 r262  
    522522                track = input_gst->read_track; 
    523523                common->new_track = NULL; 
    524                 g_print ("NEW TRACK - skipped to track %d\n", track->id); 
     524                g_print ("NEW TRACK - skipped to track %d, _search\n", track->id); 
    525525                skip_to = _search_chunk (track, 0); 
    526526 
     
    538538                guint64 seek_at_sample = ns_to_samples (common, input_gst->seek_at_ns); 
    539539                 
    540                 if ((seek_at_sample > first_avail_sample) && (seek_at_sample < last_avail_sample)) { 
     540                if ((seek_at_sample >= first_avail_sample) && (seek_at_sample < last_avail_sample)) { 
    541541                        /* LOCAL seek - we have the data already ready in the ringbuffer */ 
    542542                        g_print ("seek at %ld, first %ld last %ld, LOCAL\n", seek_at_sample, first_avail_sample, last_avail_sample); 
     
    554554                        FM_BUFFER_DISCONT (buffer) = TRUE; 
    555555                } else { 
     556                        g_print ("non-LOCAL seek, _search\n"); 
    556557                        skip_to = _search_chunk (track, input_gst->seek_at_ns); 
    557558                        if (skip_to) { 
    558559                                /* CHUNK seek - the destination is in another ready chunk */ 
    559560                                g_print ("seek at %ld, first %ld last %ld, CHUNK %u\n", seek_at_sample, first_avail_sample, last_avail_sample, skip_to->id); 
     561 
     562                                /* If we're just requested a FAR seek for the same position and the new buffer has just arrived 
     563                                   don't wait for it any more. Prevents _search_chunk () loops */ 
     564                                if (track->seek_waiting_for_ns == input_gst->seek_at_ns) 
     565                                        track->seek_waiting_for_ns = -1; 
    560566                         
    561567                        } else { 
     
    576582        if ((!skip_to) && (track) && (track->seek_waiting_for_ns > -1)) { 
    577583//              g_print ("Waiting...\n"); 
     584                g_print ("Pending FAR seek for %llu, _search\n", (long long unsigned int) track->seek_waiting_for_ns); 
    578585                skip_to = _search_chunk (track, track->seek_waiting_for_ns); 
    579586                if (skip_to) 
     
    588595                        g_warning ("Skipping to a chunk not marked usable!"); 
    589596                 
     597//              input_gst->seek_at_ns = -1;     // prevent looping if we're both waiting for a local and a far seek 
    590598                track->read_chunk = skip_to; 
    591599                 
     
    798806                seek_target = 0; 
    799807 
     808/*      if ((seek_target == 0) && (input_gst->read_track->start_at > 0)) 
     809                seek_target =input_gst->read_track->start_at;*/ 
     810 
    800811        input_gst->seek_at_ns = seek_target; 
    801812} 
     
    813824        g_return_if_fail (track->read_chunk->duration_ns > 0); 
    814825 
    815         input_gst->seek_at_ns = track->read_chunk->duration_ns * pos; 
     826        gint64 seek_target = track->read_chunk->duration_ns * pos; 
     827 
     828/*      if ((seek_target == 0) && (input_gst->read_track->start_at > 0)) 
     829                seek_target =input_gst->read_track->start_at;*/ 
     830 
     831        input_gst->seek_at_ns = seek_target; 
    816832} 
    817833 
  • trunk/fm_server/src/fm_input_gst/fm_input_gst.h

    r242 r262  
    5252 
    5353        guint           tick_ns_count;  // for "tick" 
    54          
    55 //      gboolean        drop_chunks;    // invalidate all the currently unused chunks    
    5654 
    5755        guint           rt_signal; 
  • trunk/fm_server/src/fm_input_gst/fm_input_gst_common.c

    r242 r262  
    6363        track->gst_seek_to_ns = -1; 
    6464        track->seek_waiting_for_ns = -1; 
     65        track->start_at = -1; 
    6566        return track; 
    6667} 
  • trunk/fm_server/src/fm_input_gst/fm_input_gst_common.h

    r242 r262  
    8181        gint64          gst_seek_to_ns;         // only for a FAR seek, where GStreamer should seek 
    8282        gint64          seek_waiting_for_ns;    // only for a FAR seek, wait for a new chunk returned from GST which starts here 
     83 
     84        gint64          start_at; 
    8385}; 
    8486 
  • trunk/fm_server/src/fm_input_gst/gstfmsink.c

    r242 r262  
    250250                } 
    251251                case GST_EVENT_NEWSEGMENT: { 
    252 //                      g_print(">   new segment! creating a new chunk...\n"); 
     252                        g_print(">   new segment! creating a new chunk...\n"); 
    253253                        sink->create_new_chunk = TRUE; 
    254254                } 
     
    317317 
    318318        gboolean ret; 
    319         ret = gst_element_seek (common->pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, 
     319        g_print (">   asking GStreamer to seek to %lld ns\n", (long long int) sink->seek_target_timestamp); 
     320        if (sink->seek_target_timestamp != 0) 
     321                ret = gst_element_seek (common->pipeline, 1.0, GST_FORMAT_TIME, 
     322                                GST_SEEK_FLAG_ACCURATE, 
    320323                                GST_SEEK_TYPE_SET, sink->seek_target_timestamp, 
    321324                                GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); 
     325        else { 
     326                /* What the... it looks like gstreamer-0.10.18 is not able to seek reliably to "0" with 
     327                   a "normal" seek. But it used to work, I'm sure */ 
     328                ret = gst_element_seek (common->pipeline, 1.0, GST_FORMAT_TIME, 
     329                                GST_SEEK_FLAG_KEY_UNIT | GST_SEEK_FLAG_FLUSH, 
     330                                GST_SEEK_TYPE_SET, 0, 
     331                                GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); 
     332        } 
     333 
    322334         
    323335        if (ret) { 
    324336                sink->seek_completed = TRUE; 
    325                 g_print(">   trying to seek to %lld ns...\n", (long long int) sink->seek_target_timestamp); 
     337                g_print(">   ok, now waiting for %lld ns...\n", (long long int) sink->seek_target_timestamp); 
    326338        } else { 
    327339                sink->seek_in_progress = FALSE; 
     
    334346 
    335347 
    336  
    337348static GstFlowReturn 
    338349gst_fm_sink_render (GstBaseSink * bsink, GstBuffer * buf) 
     
    342353        FmInputGstTrack *track = sink->write_track; 
    343354 
     355        //g_print (">   sink_render, new buffer TIMESTAMP %lld\n", (long long int) GST_BUFFER_TIMESTAMP (buf)); 
     356 
    344357        if (common->stop_processing || (sink->seek_in_progress && !sink->seek_completed)) 
    345358                return GST_FLOW_OK; 
     
    352365            (sink->create_new_chunk && !sink->seek_in_progress) || 
    353366            (sink->create_new_chunk && sink->seek_in_progress && sink->seek_completed)) {  // ehm... 
    354                          
     367 
    355368                sink->create_new_chunk = FALSE; 
    356369                 
     
    361374 
    362375                chk = fm_chunk_new (SAMPLES_TO_BYTES (CHUNK_SAMPLES), track->chunk_count++); 
    363                 track->chunks = g_slist_append (track->chunks, chk); 
    364376                track->write_chunk = chk; 
    365  
     377                 
    366378                gint64 timestamp = GST_BUFFER_TIMESTAMP (buf); 
    367379                g_print (">   new chunk %d, TIMESTAMP %lld\n", chk->id, (long long int) timestamp); 
     
    369381                        g_warning ("This file probably starts at timestamp %llu, taking care of it", (long long int) timestamp); 
    370382                        chk->start_of_file = TRUE; 
     383                        track->start_at = timestamp; 
    371384                } 
    372385                if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) 
     
    466479//                      common->chunk_skip_to = chk; 
    467480                        g_print (">   preload complete... GO!\n"); 
    468                      
     481                        track->chunks = g_slist_append (track->chunks, chk); 
     482                                             
    469483                        // GStreamer has hopefully figured out the correct lenght 
    470484                        // of the stream now (useful with old MP3 VBR)