static int prepare_audio_decoding( lsmash_handler_t *h, audio_option_t *opt ) { avs_handler_t *hp = (avs_handler_t *)h->audio_private; h->audio_pcm_sample_count = hp->vi->num_audio_samples; /* Support of WAVEFORMATEXTENSIBLE is much restrictive on AviUtl, so we always use WAVEFORMATEX instead. */ WAVEFORMATEX *Format = &h->audio_format.Format; Format->nChannels = hp->vi->nchannels; Format->nSamplesPerSec = hp->vi->audio_samples_per_second; Format->wBitsPerSample = avs_bytes_per_channel_sample( hp->vi ) * 8; Format->nBlockAlign = avs_bytes_per_audio_sample( hp->vi ); Format->nAvgBytesPerSec = Format->nSamplesPerSec * Format->nBlockAlign; Format->wFormatTag = WAVE_FORMAT_PCM; Format->cbSize = 0; return 0; }
static int avisynth_read_packet_audio(AVFormatContext *s, AVPacket *pkt, int discard) { AviSynthContext *avs = s->priv_data; AVRational fps, samplerate; int samples; int64_t n; const char *error; if (avs->curr_sample >= avs->vi->num_audio_samples) return AVERROR_EOF; fps.num = avs->vi->fps_numerator; fps.den = avs->vi->fps_denominator; samplerate.num = avs->vi->audio_samples_per_second; samplerate.den = 1; if (avs_has_video(avs->vi)) { if (avs->curr_frame < avs->vi->num_frames) samples = av_rescale_q(avs->curr_frame, samplerate, fps) - avs->curr_sample; else samples = av_rescale_q(1, samplerate, fps); } else { samples = 1000; } /* After seeking, audio may catch up with video. */ if (samples <= 0) { pkt->size = 0; pkt->data = NULL; return 0; } if (avs->curr_sample + samples > avs->vi->num_audio_samples) samples = avs->vi->num_audio_samples - avs->curr_sample; /* This must happen even if the stream is discarded to prevent desync. */ n = avs->curr_sample; avs->curr_sample += samples; if (discard) return 0; pkt->size = avs_bytes_per_channel_sample(avs->vi) * samples * avs->vi->nchannels; if (!pkt->size) return AVERROR_UNKNOWN; if (av_new_packet(pkt, pkt->size) < 0) return AVERROR(ENOMEM); pkt->pts = n; pkt->dts = n; pkt->duration = samples; pkt->stream_index = avs->curr_stream; avs_library.avs_get_audio(avs->clip, pkt->data, n, samples); error = avs_library.avs_clip_get_error(avs->clip); if (error) { av_log(s, AV_LOG_ERROR, "%s\n", error); avs->error = 1; av_packet_unref(pkt); return AVERROR_UNKNOWN; } return 0; }