static uint32_t get_preroll_samples ( libavsmash_audio_decode_handler_t *adhp, uint64_t skip_decoded_samples, uint32_t *frame_number ) { /* Some audio CODEC requires pre-roll for correct composition. */ lsmash_sample_property_t prop; if( lsmash_get_sample_property_from_media_timeline( adhp->root, adhp->track_ID, *frame_number, &prop ) ) return 0; if( prop.pre_roll.distance == 0 ) { if( skip_decoded_samples == 0 || !adhp->implicit_preroll ) return 0; /* Estimate pre-roll distance. */ for( uint32_t i = 1; i <= adhp->frame_count || skip_decoded_samples; i++ ) { libavsmash_summary_t *dummy = NULL; uint32_t frame_length; if( get_frame_length( adhp, i, &frame_length, &dummy ) ) break; if( skip_decoded_samples < frame_length ) skip_decoded_samples = 0; else skip_decoded_samples -= frame_length; ++ prop.pre_roll.distance; } } uint32_t preroll_samples = 0; for( uint32_t i = 0; i < prop.pre_roll.distance; i++ ) { if( *frame_number > 1 ) --(*frame_number); else break; libavsmash_summary_t *dummy = NULL; uint32_t frame_length; if( get_frame_length( adhp, *frame_number, &frame_length, &dummy ) ) break; preroll_samples += frame_length; } return preroll_samples; }
static int find_start_audio_frame ( libavsmash_audio_decode_handler_t *adhp, int output_sample_rate, uint64_t skip_decoded_samples, uint64_t start_frame_pos, uint64_t *start_offset ) { uint32_t frame_number = 1; uint64_t current_frame_pos = 0; uint64_t next_frame_pos = 0; int current_sample_rate = 0; uint32_t current_frame_length = 0; uint64_t pcm_sample_count = 0; /* the number of accumulated PCM samples before resampling per sequence */ uint64_t resampled_sample_count = 0; /* the number of accumulated PCM samples after resampling per sequence */ uint64_t prior_sequences_resampled_count = 0; /* the number of accumulated PCM samples of all prior sequences */ do { current_frame_pos = next_frame_pos; libavsmash_summary_t *s = NULL; uint32_t frame_length; if( get_frame_length( adhp, frame_number, &frame_length, &s ) ) { ++frame_number; continue; } if( (current_sample_rate != s->extended.sample_rate && s->extended.sample_rate > 0) || current_frame_length != frame_length ) { /* Encountered a new sequence. */ prior_sequences_resampled_count += resampled_sample_count; pcm_sample_count = 0; current_sample_rate = s->extended.sample_rate > 0 ? s->extended.sample_rate : adhp->config.ctx->sample_rate; current_frame_length = frame_length; } pcm_sample_count += frame_length; resampled_sample_count = output_sample_rate == current_sample_rate || pcm_sample_count == 0 ? pcm_sample_count : RESAMPLE_PCM_COUNT( pcm_sample_count ); next_frame_pos = prior_sequences_resampled_count + resampled_sample_count; if( start_frame_pos < next_frame_pos ) break; ++frame_number; } while( frame_number <= adhp->frame_count ); *start_offset = start_frame_pos - current_frame_pos; if( *start_offset && current_sample_rate != output_sample_rate ) /* start_offset is applied at the decoder sampling rate. */ *start_offset = (*start_offset * current_sample_rate - 1) / output_sample_rate + 1; *start_offset += get_preroll_samples( adhp, skip_decoded_samples, &frame_number ); return frame_number; }
static int bu92747_get_frame_length(struct bu92747_port *s) { struct rev_frame_length *f = &(s->rev_frames); unsigned long len = 0; #if 0 wait_event_interruptible_timeout(s->data_ready_wq, atomic_read(&(s->data_ready) ), msecs_to_jiffies(1000) ); if ( 0 == atomic_read(&(s->data_ready)) ) { printk("waiting 'data_ready_wq' timed out."); return -1; } #endif spin_lock(&s->data_lock); if (get_frame_length(f, &len) != 0) { printk("line %d: FIR data not ready......\n", __LINE__); //atomic_set(&(s->data_ready), 0); } spin_unlock(&s->data_lock); return len; }