int bg_nle_audio_compositor_read(void * priv, gavl_audio_frame_t* ret, int stream, int num_samples) { bg_nle_audio_compositor_t * c = priv; stream_t * s; int i = c->num_streams; gavl_audio_frame_mute(ret, &c->format); while(--i) { s = &c->streams[i]; } return 0; }
static gavl_source_status_t decode_frame_mad(bgav_stream_t * s) { mad_priv_t * priv; int i, j; gavl_source_status_t st; int got_frame; int flush = 0; priv = s->decoder_priv; if(priv->eof) return GAVL_SOURCE_EOF; while(1) { st = get_data(s); switch(st) { case GAVL_SOURCE_AGAIN: return st; break; case GAVL_SOURCE_EOF: flush = 1; break; case GAVL_SOURCE_OK: break; } got_frame = 1; mad_stream_buffer(&priv->stream, priv->buf.buffer, priv->buf.size + flush * MAD_BUFFER_GUARD); if(priv->do_init) { get_format(s); priv->do_init = 0; } if(mad_frame_decode(&priv->frame, &priv->stream) == -1) { got_frame = 0; if(priv->stream.error != MAD_ERROR_BUFLEN) { /* This is often a spurious error, which ALWAYS occurs for ripped radio stations */ if(priv->stream.error != MAD_ERROR_BADDATAPTR) bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Decode failed %s\n", mad_stream_errorstr(&priv->stream)); break; } } else break; if(!got_frame && flush) return GAVL_SOURCE_EOF; } if(got_frame) { // fprintf(stderr, "Decodes %ld bytes\n", priv->stream.next_frame - priv->stream.buffer); mad_synth_frame(&priv->synth, &priv->frame); for(i = 0; i < s->data.audio.format.num_channels; i++) { for(j = 0; j < s->data.audio.format.samples_per_frame; j++) { if (priv->synth.pcm.samples[i][j] >= MAD_F_ONE) priv->synth.pcm.samples[i][j] = MAD_F_ONE - 1; else if (priv->synth.pcm.samples[i][j] < -MAD_F_ONE) priv->synth.pcm.samples[i][j] = -MAD_F_ONE; priv->audio_frame->channels.f[i][j] = (float)(priv->synth.pcm.samples[i][j]) / (float)MAD_F_ONE; } } priv->audio_frame->valid_samples = s->data.audio.format.samples_per_frame; } else gavl_audio_frame_mute(priv->audio_frame, &s->data.audio.format); if(flush && priv->last_duration && (priv->last_duration < priv->audio_frame->valid_samples)) priv->audio_frame->valid_samples = priv->last_duration; gavl_audio_frame_copy_ptrs(&s->data.audio.format, s->data.audio.frame, priv->audio_frame); #if 0 fprintf(stderr, "Done decode %ld %ld\n", priv->stream.this_frame - priv->stream.buffer, priv->stream.next_frame - priv->stream.this_frame); #endif s->flags |= STREAM_HAVE_FRAME; bgav_bytebuffer_remove(&priv->buf, priv->stream.next_frame - priv->stream.buffer); if(flush) priv->eof = 1; return GAVL_SOURCE_OK; }
bool ReadMedia::initFormat() { const gavl_audio_format_t * open_audio_format; const gavl_video_format_t * open_video_format; // we use the m_vfifosize to see if the user app wants video or not // then, we set m_video_stream_count to 0 if he doesn't want video if (m_video_stream_count > 0 && m_vfifosize > 0) { open_video_format = bgav_get_video_format(m_file, 0); if (open_video_format->pixelformat == GAVL_PIXELFORMAT_NONE) { printf("!!!sorry, pixelformat is not recognized.\n"); return false; } // let's check to see if the formats are the same, if they are the same // there is no reason to recreate the fifo or frames if ( gavl_video_formats_equal( &m_video_format, open_video_format) == 0 ) { // the formats are different gavl_video_format_copy (&m_video_format, open_video_format); if (m_video_frame != NULL) gavl_video_frame_destroy(m_video_frame); m_video_frame = gavl_video_frame_create(&m_video_format); gavl_video_frame_clear( m_video_frame, &m_video_format); if (m_fifovideo != NULL) delete m_fifovideo; m_fifovideo= new FifoVideoFrames( m_vfifosize , &m_video_format); } } else { m_video_stream_count = 0; m_veof = true; } // we use the m_afifosize to see if the user app wants audio or not // then, we set m_audio_stream_count to 0 if he doesn't want audio if (m_audio_stream_count > 0 && m_afifosize > 0) { open_audio_format = bgav_get_audio_format(m_file, 0); // we can get audio formats that are unkown if ( open_audio_format->sample_format == GAVL_SAMPLE_NONE) { printf("sorry, this file has unsupported audio.\n"); return false; } if ( gavl_audio_formats_equal(&m_audio_format, open_audio_format) == 0 ) { // audio formats are different // save the old spf int spf = m_audio_format.samples_per_frame; gavl_audio_format_copy(&m_audio_format, open_audio_format); if (m_audio_frame != NULL) { gavl_audio_frame_destroy(m_audio_frame); } // set it back to original m_audio_format.samples_per_frame = spf ; m_audio_frame = gavl_audio_frame_create(&m_audio_format); gavl_audio_frame_mute( m_audio_frame, &m_audio_format); if( m_fifoaudio != NULL ) delete m_fifoaudio; m_fifoaudio = new FifoAudioFrames( m_afifosize , &m_audio_format); } } else { // user doesn't want audio m_audio_stream_count = 0; m_aeof=true; } m_length_in_gavltime = bgav_get_duration ( m_file, 0);; m_length_in_seconds = gavl_time_to_seconds( m_length_in_gavltime ); m_num_samples = 0; m_num_frames = 0; if (m_audio_stream_count) { if ( bgav_can_seek_sample(m_file) == 1 ) { m_num_samples= bgav_audio_duration ( m_file, 0) ; } else { m_num_samples= gavl_time_to_samples( m_audio_format.samplerate , bgav_get_duration ( m_file, 0) ); } } // set frames WE NEED TO take care here for non-constant frame-rates if(m_video_stream_count) { if ( bgav_can_seek_sample(m_file) == 1 && m_video_format.framerate_mode == GAVL_FRAMERATE_CONSTANT) { m_num_frames = bgav_video_duration ( m_file, 0)/ m_video_format.frame_duration; } else if ( bgav_can_seek_sample(m_file) == 1 && m_video_format.framerate_mode == GAVL_FRAMERATE_VARIABLE ) { // FIXME what to do with non constant frame rates? m_num_frames=0; } else { m_num_frames = gavl_time_to_frames( m_video_format.timescale, m_video_format.frame_duration , bgav_get_duration ( m_file, 0) ); } } // printf("m_num_frames =%lld, duration = %lld , vid_duration=%lld\n", // m_num_frames, bgav_get_duration ( m_file, 0), bgav_video_duration ( m_file, 0) ); // set seconds if ( bgav_can_seek_sample(m_file) == 1) { gavl_time_t atime=0,vtime=0; if ( m_audio_stream_count ) atime = gavl_samples_to_time( m_audio_format.samplerate, m_num_samples ); if (m_video_stream_count && m_video_format.frame_duration > 0) { vtime = gavl_frames_to_time( m_video_format.timescale, m_video_format.frame_duration, m_num_frames ); } else if ( m_video_stream_count ) { // non constant framerate vtime = bgav_video_duration( m_file, 0); } // else rely on audio time m_length_in_gavltime = atime > vtime ? atime :vtime; m_length_in_seconds = gavl_time_to_seconds( m_length_in_gavltime ); //printf("atime=%ld, vtime=%ld, l_in_sec=%f\n", atime, vtime, m_length_in_seconds); } m_pcm_seek = SEEK_NOTHING; m_frame_seek = SEEK_NOTHING; return true; }