Changeset 221 for trunk

Show
Ignore:
Timestamp:
02/04/08 22:26:37 (4 years ago)
Author:
ath
Message:

First rough cleanup for FmInputGst. EOF detection should work now.

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

    r198 r221  
    181181{ 
    182182        g_print ("RESET STATUS!\n"); 
    183 //      input_gst->current_pos_samples = 0; 
    184         input_gst->current_pos_nsec = 0; 
    185         input_gst->seek_at_nsec = -1; 
     183        input_gst->current_pos_samples = 0; 
     184        //input_gst->current_pos_nsec = 0; 
     185        input_gst->seek_at_ns = -1; 
    186186 
    187187        if (input_gst->common) 
    188                 input_gst->common->gst_seek_to_nsec = -1; 
     188                input_gst->common->gst_seek_to_ns = -1; 
    189189} 
    190190 
     
    293293        gst_element_set_state (input_gst->common->pipeline, GST_STATE_PLAYING); 
    294294 
    295         common->seek_waiting_for_nsec = 0; 
     295        common->seek_waiting_for_ns = 0; 
    296296} 
    297297 
     
    352352        common->input_gst = input_gst; 
    353353        common->sem = fm_sem_new (1); 
    354         common->gst_seek_to_nsec = -1; 
     354        common->gst_seek_to_ns = -1; 
    355355        common->sample_rate = fm_pipeline_get_sample_rate (FM_PIPELINE (element->pipeline)); 
    356356 
     
    404404 
    405405 
    406         input_gst->interleaved_buffer = g_new0(gfloat, SAMPLES_TO_BYTES(STD_CHUNK_N_SAMPLES)); 
     406        input_gst->interleaved_buffer = g_new0(gfloat, SAMPLES_TO_BYTES(CHUNK_SAMPLES)); 
    407407 
    408408        if (input_gst->filename) { 
     
    443443                return; 
    444444 
    445         g_value_set_int64 (input_gst->val1, input_gst->current_pos_nsec); 
    446         g_value_set_int64 (input_gst->val2, chk->duration_nsec); 
     445        guint64 pos_ns = samples_to_ns (input_gst->common, input_gst->current_pos_samples); 
     446        g_value_set_int64 (input_gst->val1, pos_ns); 
     447        g_value_set_int64 (input_gst->val2, chk->duration_ns); 
    447448        rgc_signal_rt_emit (input_gst, input_gst->rt_signal, input_gst->val1, input_gst->val2, NULL);    
    448449} 
     
    458459                FmChunk *c = chunk->data; 
    459460 
    460                 g_print ("chunk n. %d - start %llu duration %llu", c->num, (long long unsigned int) c->start_timestamp, (long long unsigned int) c->duration_nsec); 
     461                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); 
    461462                if (c->usable) 
    462463                        g_print (" USABLE"); 
     
    467468                if (((c->usable) &&  
    468469                     (time >= c->start_timestamp) && 
    469                      (time < (c->start_timestamp + c->duration_nsec))) ||  
     470                     (time < (c->start_timestamp + c->duration_ns))) ||  
    470471                    ((time == 0) && (c->start_of_file))) {      // see gstfmsink.c:333 
    471472                        g_print ("Found target %llu at chunk %u\n", (long long unsigned int) time, c->num); 
     
    514515        fm_buffer_reset_flags (buffer); 
    515516 
    516         guint64 current_pos_samples = ns_to_samples (common, input_gst->current_pos_nsec); 
     517        //guint64 current_pos_samples = ns_to_samples (common, input_gst->current_pos_nsec); 
    517518 
    518519        /* Check if we should perform a seek */ 
    519         if ((input_gst->seek_at_nsec > -1) && chk){ 
    520                 /* We need to convert everything here down to samples and then to bytes */ 
    521                 glong first_avail_sample = current_pos_samples - BYTES_TO_SAMPLES(chk->bytes_behind_us); 
    522                 glong last_avail_sample = current_pos_samples + BYTES_TO_SAMPLES(jack_ringbuffer_read_space(chk->ring));  // we'll need an offset 
     520        if ((input_gst->seek_at_ns > -1) && chk){ 
     521                glong first_avail_sample = input_gst->current_pos_samples - chk->samples_behind_us; 
     522                glong last_avail_sample = input_gst->current_pos_samples + BYTES_TO_SAMPLES(jack_ringbuffer_read_space(chk->ring)); 
    523523             
    524                 guint64 seek_at_sample = ns_to_samples (common, input_gst->seek_at_nsec); 
     524                guint64 seek_at_sample = ns_to_samples (common, input_gst->seek_at_ns); 
    525525                 
    526526                if ((seek_at_sample > first_avail_sample) && (seek_at_sample < last_avail_sample)) { 
     
    528528                        g_print ("seek at %ld, first %ld last %ld, LOCAL\n", seek_at_sample, first_avail_sample, last_avail_sample); 
    529529 
    530                         gint bytes_to_seek =  SAMPLES_TO_BYTES(seek_at_sample - current_pos_samples); 
    531                         input_gst->current_pos_nsec = input_gst->seek_at_nsec; 
     530                        gint samples_to_seek = seek_at_sample - input_gst->current_pos_samples; 
     531                        gint bytes_to_seek = SAMPLES_TO_BYTES (samples_to_seek); 
     532                        input_gst->current_pos_samples = seek_at_sample; 
    532533                         
    533534                        if (bytes_to_seek > 0) { 
    534535                                jack_ringbuffer_read_advance(chk->ring, bytes_to_seek);          
    535536                        } else { 
    536                                 chk->bytes_behind_us += bytes_to_seek;  // yes, the "+" is correct 
     537                                chk->samples_behind_us += samples_to_seek;      // yes, the "+" is correct 
    537538                        } 
    538539                        FM_BUFFER_DISCONT (buffer) = TRUE; 
    539540                } else { 
    540                         skip_to = _search_chunk (common, input_gst->seek_at_nsec); 
     541                        skip_to = _search_chunk (common, input_gst->seek_at_ns); 
    541542                        if (skip_to) { 
    542543                                /* CHUNK seek - the destination is in another ready chunk */ 
     
    547548                                g_print ("seek at %ld, first %ld last %ld, FAR\n", seek_at_sample, first_avail_sample, last_avail_sample); 
    548549 
    549                                 common->gst_seek_to_nsec = input_gst->seek_at_nsec; 
     550                                common->gst_seek_to_ns = input_gst->seek_at_ns; 
    550551//                              g_print ("              seek_at_nsec = %lld\n", (long long int) common->gst_seek_to_nsec); 
    551                                 common->seek_waiting_for_nsec = input_gst->seek_at_nsec; 
     552                                common->seek_waiting_for_ns = input_gst->seek_at_ns; 
    552553                                fm_sem_increase (common->sem); 
    553554                        } 
    554555                } 
    555                 input_gst->seek_at_nsec = -1; 
     556                input_gst->seek_at_ns = -1; 
    556557        } 
    557558 
    558559 
    559560        /* Check if a FAR seek has been completed */ 
    560         if ((!skip_to) && (common->seek_waiting_for_nsec > -1)) { 
     561        if ((!skip_to) && (common->seek_waiting_for_ns > -1))   { 
    561562//              g_print ("Waiting...\n"); 
    562                 skip_to = _search_chunk (common, common->seek_waiting_for_nsec); 
     563                skip_to = _search_chunk (common, common->seek_waiting_for_ns); 
    563564                if (skip_to) 
    564                         common->seek_waiting_for_nsec = -1; 
     565                        common->seek_waiting_for_ns = -1; 
    565566        } 
    566567 
     
    577578                chk->usable = FALSE; 
    578579                 
    579                 //input_gst->current_pos_samples = ns_to_samples (common, chk->start_timestamp); 
    580                 input_gst->current_pos_nsec = chk->start_timestamp; 
     580                input_gst->current_pos_samples = ns_to_samples (common, chk->start_timestamp); 
     581                //input_gst->current_pos_ns = chk->start_timestamp; 
    581582                g_print("skipping... new position = %llu\n", (long long unsigned int) chk->start_timestamp); 
    582583 
     
    608609 
    609610        // bytes da scartare 
    610         guint bytes_from_ring = chk->bytes_behind_us + SAMPLES_TO_BYTES(FM_BUFFER_REQUESTED(buffer)); 
    611         gint64 eof_samples = ns_to_samples (common, chk->eof_timestamp); 
     611        guint samples_from_ring = chk->samples_behind_us + FM_BUFFER_REQUESTED(buffer); 
     612        guint bytes_from_ring = SAMPLES_TO_BYTES(samples_from_ring); 
     613/*      guint64 eof_samples = ns_to_samples (common, chk->eof_timestamp);*/ 
    612614     
    613         if ((eof_samples > 0) && 
    614             ((current_pos_samples + FM_BUFFER_REQUESTED (buffer)) > eof_samples)) 
    615                 bytes_from_ring = SAMPLES_TO_BYTES (eof_samples - current_pos_samples); 
     615/*      if (eof_samples > 0) {*/ 
     616        if (chk->eof_samples > 0) { 
     617//              g_print ("Get ready for EOF at chunk pos %lld\n", (long long int) chk->eof_samples); 
     618 
     619                if (chk->samples_read + FM_BUFFER_REQUESTED (buffer) > chk->eof_samples) 
     620                        bytes_from_ring = SAMPLES_TO_BYTES (chk->eof_samples - chk->samples_read); 
     621 
     622/*          if ((input_gst->current_pos_samples + FM_BUFFER_REQUESTED (buffer)) > eof_samples) 
     623                bytes_from_ring = SAMPLES_TO_BYTES (eof_samples - input_gst->current_pos_samples);*/ 
     624        } 
    616625 
    617626        size_t read_bytes = jack_ringbuffer_peek(chk->ring, (gchar *) input_gst->interleaved_buffer, bytes_from_ring); 
    618627//      write (temp_fd, input_gst->interleaved_buffer, SAMPLES_TO_BYTES(FM_BUFFER_REQUESTED(buffer))); 
    619628 
    620         gint useful_read_bytes = read_bytes - chk->bytes_behind_us; 
     629        guint useful_read_bytes = read_bytes - SAMPLES_TO_BYTES (chk->samples_behind_us); 
     630        guint useful_read_samples = BYTES_TO_SAMPLES (useful_read_bytes); 
     631        guint useful_read_ns = samples_to_ns (common, useful_read_samples); 
    621632//      g_print("got %d bytes, drop %d, keep %d\n", read_bytes, read_bytes - useful_read_bytes, useful_read_bytes); 
    622633 
     
    626637 
    627638        /* Timekeeping */ 
    628         guint64 current_pos_nsec_old = input_gst->current_pos_nsec; 
    629         guint useful_read_samples = BYTES_TO_SAMPLES (useful_read_bytes); 
    630         current_pos_samples += useful_read_samples;  // se abbiamo un underrun durante bytes_behind_us si sputtana tutto? 
    631         input_gst->current_pos_nsec += samples_to_ns (common, useful_read_samples); 
    632  
    633         buffer->timestamp = current_pos_nsec_old; 
     639        guint64 current_pos_samples_old = input_gst->current_pos_samples; 
     640        input_gst->current_pos_samples += useful_read_samples; 
     641        chk->samples_read += useful_read_samples; 
     642 
     643        buffer->timestamp = samples_to_ns (common, current_pos_samples_old); 
    634644        buffer->used_samples = buffer->requested_samples; 
    635         buffer->duration = input_gst->current_pos_nsec - current_pos_nsec_old; 
     645        buffer->duration = samples_to_ns (common, useful_read_samples); 
    636646        buffer->silence = FALSE; 
    637647//      g_print ("DURATION %lld\n", (long long int) FM_BUFFER_DURATION (buffer)); 
     
    640650 
    641651        /* Check for EOF */ 
    642         if ((eof_samples) && (current_pos_samples >= eof_samples)) { 
    643                 g_print ("We're at %lld samples - end of file!\n", (long long int) current_pos_samples); 
     652/*      if ((eof_samples) && (input_gst->current_pos_samples >= eof_samples)) {*/ 
     653        if ((chk->eof_samples > 0) && (chk->samples_read >= chk->eof_samples)) { 
     654                g_print ("We're at %lld samples - end of file!\n", (long long int) input_gst->current_pos_samples); 
    644655                chk->eof = TRUE; 
    645656        } 
     
    647658 
    648659        /* int-to-float conversion */ 
    649         gfloat *start_point = (gfloat *) (((gchar *) input_gst->interleaved_buffer) + chk->bytes_behind_us); 
     660        gfloat *start_point = (gfloat *) (((gchar *) input_gst->interleaved_buffer) + SAMPLES_TO_BYTES (chk->samples_behind_us)); 
    650661        fm_buffer_store_interleaved_data(buffer, start_point, FM_BUFFER_REQUESTED(buffer)); 
    651662 
    652663 
    653664        /* Advance ring pointer */ 
    654         if (chk->bytes_behind_us >= BYTES_TO_LEAVE_BEHIND) { 
     665        if (chk->samples_behind_us >= CHUNK_LEAVE_BEHIND_SAMPLES) { 
    655666                jack_ringbuffer_read_advance(chk->ring, useful_read_bytes); 
    656667                fm_sem_increase (common->sem); 
    657668        } else { 
    658                 chk->bytes_behind_us += useful_read_bytes; 
     669                chk->samples_behind_us += useful_read_samples; 
    659670        } 
    660671//      g_print("behind us %d bytes\n", input_gst->bytes_behind_us); 
     
    662673 
    663674        /* Send the updated position signal */ 
    664         input_gst->sample_count += buffer->requested_samples; 
    665         if (input_gst->sample_count > TICK_EVERY_N_SAMPLES) { 
    666                 input_gst->sample_count = 0; 
     675        input_gst->tick_ns_count += useful_read_ns; 
     676        if (input_gst->tick_ns_count > TICK_EVERY_NS) { 
     677                input_gst->tick_ns_count = 0; 
    667678                _send_position (input_gst); 
    668679        } 
     
    771782        g_return_if_fail (nsec != 0); 
    772783 
    773         gint64 seek_target = input_gst->current_pos_nsec + nsec; 
     784        /* FIXME: we should do the calculation in the PIPELINE thread to avoid races */ 
     785        gint64 seek_target = samples_to_ns (input_gst->common, input_gst->current_pos_samples) + nsec; 
    774786 
    775787        if (seek_target < 0) 
    776788                seek_target = 0; 
    777789 
    778         input_gst->seek_at_nsec = seek_target; 
     790        input_gst->seek_at_ns = seek_target; 
    779791} 
    780792 
     
    789801        FmInputGstCommon *common = input_gst->common; 
    790802        g_return_if_fail (common->read_chunk); 
    791         g_return_if_fail (common->read_chunk->duration_nsec > 0); 
    792  
    793         input_gst->seek_at_nsec = common->read_chunk->duration_nsec * pos; 
     803        g_return_if_fail (common->read_chunk->duration_ns > 0); 
     804 
     805        input_gst->seek_at_ns = common->read_chunk->duration_ns * pos; 
    794806} 
    795807 
  • trunk/fm_server/src/fm_input_gst/fm_input_gst.h

    r198 r221  
    2121 
    2222 
    23 #define TICK_EVERY_N_SAMPLES 4000 
     23#define TICK_EVERY_NS 40000000 
    2424 
    2525 
     
    4343        gchar           *filename; 
    4444 
    45 //      gint64          current_pos_samples; 
    46         gint64          current_pos_nsec; 
     45        gint64          current_pos_samples; 
     46//      gint64          current_pos_nsec; 
    4747 
    4848        gboolean        play_when_ready; 
     
    5050        gfloat          *interleaved_buffer; 
    5151 
    52         gint64          seek_at_nsec;   // where to seek (it's set by the non-RT threads) 
     52        gint64          seek_at_ns;     // where to seek (it's set by the non-RT threads) 
    5353 
    54         guint           sample_count;   // for "tick" 
     54        guint           tick_ns_count;  // for "tick" 
    5555         
    5656        gboolean        drop_chunks;    // invalidate all the currently unused chunks    
  • trunk/fm_server/src/fm_input_gst/fm_input_gst_common.c

    r198 r221  
    5252                                         guint64        nsec) 
    5353{ 
    54         return (guint64) (nsec / common->nsec_for_sample); 
     54        return (guint64) (nsec / common->ns_for_sample); 
    5555} 
    5656 
     
    6060                                         guint64        samples) 
    6161{ 
    62         return (guint64) (samples * common->nsec_for_sample); 
     62        return (guint64) (samples * common->ns_for_sample); 
    6363} 
  • trunk/fm_server/src/fm_input_gst/fm_input_gst_common.h

    r198 r221  
    2222  
    2323 
    24 #define STD_CHUNK_N_SAMPLES (16384 * 2) 
    25 #define CHUNK_PRELOAD_N_SAMPLES (4096 * 2) 
    26 #define BYTES_TO_LEAVE_BEHIND (8192 * 2) 
     24#define CHUNK_SAMPLES (16384 * 2) 
     25#define CHUNK_PRELOAD_SAMPLES (4096 * 2) 
     26#define CHUNK_LEAVE_BEHIND_SAMPLES (8192 * 2) 
    2727 
    2828 
     
    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         gint64          duration_nsec; 
     45        gint64          duration_ns; 
    4646 
    4747        gint            bytes_preloaded;                // -1 means ready to read 
    48         guint           bytes_behind_us; 
     48        guint           samples_behind_us; 
    4949         
    5050        /* FIXME: "eof" should be moved to FmInputGst */ 
    5151        gboolean        eof;                            // the file ends somewhere in this chunk 
    5252        GstClockTime    eof_timestamp;                  // where the file ends (stream timestamp) 
     53        guint64         eof_samples;                    // where the file ends (RELATIVE TO CHUNK START!!!!) 
    5354        gboolean        start_of_file;                  // 1° buffer of the file 
    5455 
    5556        gboolean        can_destroy;                    // set after skipping to a new chunk. 
    5657                                                        // if TRUE, the buffer will be freed by the GST thread in _do_cleanup() 
     58 
     59        guint64         samples_read; 
    5760}; 
    5861 
     
    8386        gboolean        stop_processing;        // discard incoming buffers and delete chunks 
    8487 
    85         gint64          seek_waiting_for_nsec;  // only for a FAR seek, wait for a new chunk returned from GST which starts here 
    86         gint64          gst_seek_to_nsec;       // only for a FAR seek, where GStreamer should seek 
     88        gint64          seek_waiting_for_ns;    // only for a FAR seek, wait for a new chunk returned from GST which starts here 
     89        gint64          gst_seek_to_ns;         // only for a FAR seek, where GStreamer should seek 
    8790 
    88         gdouble         nsec_for_sample; 
     91        gdouble         ns_for_sample; 
    8992 
    9093        gboolean        loaded; 
  • trunk/fm_server/src/fm_input_gst/gstfmsink.c

    r198 r221  
    237237                        g_return_val_if_fail (common->write_chunk, TRUE); 
    238238                        common->write_chunk->eof_timestamp = sink->start_timestamp; 
     239                        common->write_chunk->eof_samples = sink->position_samples; 
    239240                        g_print(">   got EOF at timestamp %lld\n", (long long int) common->write_chunk->eof_timestamp); 
    240241                        sink->seek_in_progress = FALSE; 
     
    326327                } 
    327328 
    328                 chk = fm_chunk_new (SAMPLES_TO_BYTES (STD_CHUNK_N_SAMPLES)); 
     329                chk = fm_chunk_new (SAMPLES_TO_BYTES (CHUNK_SAMPLES)); 
    329330                chk->num = sink->chunk_count++; 
    330331                common->chunks = g_list_append (common->chunks, chk); 
     
    342343                chk->start_timestamp = timestamp; 
    343344                sink->start_timestamp = timestamp; 
     345                sink->position_samples = 0; 
    344346 
    345347                if (sink->seek_target_timestamp != -1) { 
     
    355357                         
    356358                                        chk->start_timestamp_offset += nsec_to_skip; 
    357                                         chk->bytes_behind_us = SAMPLES_TO_BYTES (ns_to_samples(common, nsec_to_skip)); 
     359                                        chk->samples_behind_us = ns_to_samples(common, nsec_to_skip); 
    358360                                } else 
    359361                                        g_warning ("too much to skip, seek failed!"); 
     
    362364                } 
    363365                GstFormat fmt = GST_FORMAT_TIME; 
    364                 gst_element_query_duration (common->sink, &fmt, &chk->duration_nsec); 
     366                gst_element_query_duration (common->sink, &fmt, &chk->duration_ns); 
    365367//              g_print(">   gst_element_query_duration %lld\n", chk->duration_samples); 
    366368        } 
     
    385387                                return GST_FLOW_OK; 
    386388     
    387                         if (common->gst_seek_to_nsec > -1) { 
     389                        if (common->gst_seek_to_ns > -1) { 
    388390                                if (sink->seek_in_progress) { 
    389391                                        g_print (">   seek already in progress, we'll try later\n"); 
     
    391393                                } 
    392394                                 
    393                                 g_print(">   requested seek to %lld\n", (long long int) common->gst_seek_to_nsec); 
    394  
    395                                 sink->seek_target_timestamp = common->gst_seek_to_nsec; 
    396                                 common->gst_seek_to_nsec = -1; 
     395                                g_print(">   requested seek to %lld\n", (long long int) common->gst_seek_to_ns); 
     396 
     397                                sink->seek_target_timestamp = common->gst_seek_to_ns; 
     398                                common->gst_seek_to_ns = -1; 
    397399                                sink->seek_in_progress = TRUE; 
    398400 
     
    414416                 
    415417                buffer_pos_bytes += written_bytes; 
     418                sink->position_samples += BYTES_TO_SAMPLES (written_bytes); 
    416419 
    417420                if (written_bytes < bytes_to_write) { 
     
    420423 
    421424                if (chk->bytes_preloaded == -1) {} 
    422                 else if (chk->bytes_preloaded > CHUNK_PRELOAD_N_SAMPLES) { 
     425                else if (chk->bytes_preloaded > CHUNK_PRELOAD_SAMPLES) { 
    423426                        chk->usable = TRUE; 
    424427//                      common->chunk_skip_to = chk; 
     
    428431                        // of the stream now (useful with old MP3 VBR) 
    429432                        GstFormat fmt = GST_FORMAT_TIME; 
    430                         gst_element_query_duration (common->sink, &fmt, &chk->duration_nsec); 
     433                        gst_element_query_duration (common->sink, &fmt, &chk->duration_ns); 
    431434//                      g_print(">   gst_element_query_duration %lld\n", chk->duration_samples); 
    432435 
     
    444447 
    445448        sink->start_timestamp = GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf); 
    446 //      g_print(">   sink->offset_samples %lld\n", sink->offset_samples); 
     449//      g_print(">   sink->position_samples %lld\n", sink->position_samples); 
    447450 
    448451        return GST_FLOW_OK; 
     
    459462        fm_sink->common = (FmInputGstCommon *) ptr; 
    460463 
    461         fm_sink->common->nsec_for_sample = (gdouble) GST_SECOND / SAMPLES_FOR_SEC; 
     464        fm_sink->common->ns_for_sample = (gdouble) GST_SECOND / SAMPLES_FOR_SEC; 
    462465} 
    463466 
  • trunk/fm_server/src/fm_input_gst/gstfmsink.h

    r198 r221  
    8888        GstClockTime    seek_target_timestamp;  // ns 
    8989 
     90        guint64         position_samples;       // from start of chunk 
     91 
    9092        guint           bytes_behind_us; 
    9193