misc small fixes in the ffmpeg audio provider, preparation for support of other sample formats than just 16-bit int

Originally committed to SVN as r2296.
This commit is contained in:
Karl Blomster 2008-08-04 07:13:41 +00:00
parent 9826d5bd58
commit 217c228738
1 changed files with 21 additions and 10 deletions

View File

@ -112,16 +112,25 @@ LAVCAudioProvider::LAVCAudioProvider(Aegisub::String _filename)
throw _T("ffmpeg audio provider: Failed to open audio decoder"); throw _T("ffmpeg audio provider: Failed to open audio decoder");
sample_rate = Options.AsInt(_T("Audio Sample Rate")); sample_rate = Options.AsInt(_T("Audio Sample Rate"));
if (!sample_rate) if (!sample_rate) {
sample_rate = codecContext->sample_rate; /* aegisub wants audio with sample rate higher than 32khz */
if (codecContext->sample_rate < 32000)
sample_rate = 48000;
else
sample_rate = codecContext->sample_rate;
}
/* rely on the downmixing audio provider to do downmixing for us later */ /* we rely on the intermediate audio provider to do downmixing for us later if necessary */
channels = codecContext->channels; channels = codecContext->channels;
/* FIXME: this entire provider always assumes 16-bit audio. Currently that isn't a problem since
ffmpeg always converts everything to 16-bit, but in the future it might become one. */
bytes_per_sample = 2;
/* aegisub currently supports mono only, so always resample unless it's mono with the desired samplerate */ /* FIXME: we need support for more audio types than just 16-bit int */
switch (codecContext->sample_fmt) {
case SAMPLE_FMT_S16: bytes_per_sample = 2; break;
default:
throw _T("ffmpeg audio provider: Only 16-bit audio is supported");
}
/* initiate resampling if necessary */
if (sample_rate != codecContext->sample_rate) { if (sample_rate != codecContext->sample_rate) {
rsct = audio_resample_init(channels, channels, sample_rate, codecContext->sample_rate); rsct = audio_resample_init(channels, channels, sample_rate, codecContext->sample_rate);
if (!rsct) if (!rsct)
@ -137,7 +146,7 @@ LAVCAudioProvider::LAVCAudioProvider(Aegisub::String _filename)
length = (double)lavcfile->fctx->duration / AV_TIME_BASE; length = (double)lavcfile->fctx->duration / AV_TIME_BASE;
else else
length = (double)stream->duration * av_q2d(stream->time_base); length = (double)stream->duration * av_q2d(stream->time_base);
num_samples = (int64_t)(length * sample_rate); // number of samples per channel num_samples = (int64_t)(length * sample_rate); /* number of samples per channel */
buffer = (int16_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); buffer = (int16_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
if (!buffer) if (!buffer)
@ -200,12 +209,13 @@ void LAVCAudioProvider::GetAudio(void *buf, int64_t start, int64_t count)
/* we're not dealing with video packets in this here provider */ /* we're not dealing with video packets in this here provider */
if (packet.stream_index == audStream) { if (packet.stream_index == audStream) {
int size = packet.size; int size = packet.size;
uint8_t *data = packet.data;
while (size > 0) { while (size > 0) {
int temp_output_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; /* see constructor, it malloc()'s buffer to this */ int temp_output_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; /* see constructor, it malloc()'s buffer to this */
int retval, decoded_bytes, decoded_samples; int retval, decoded_bytes, decoded_samples;
retval = avcodec_decode_audio2(codecContext, buffer, &temp_output_buffer_size, packet.data, size); retval = avcodec_decode_audio2(codecContext, buffer, &temp_output_buffer_size, data, size);
if (retval <= 0) if (retval <= 0)
throw _T("ffmpeg audio provider: failed to decode audio"); throw _T("ffmpeg audio provider: failed to decode audio");
/* decoding succeeded but the output buffer is empty, go to next packet */ /* decoding succeeded but the output buffer is empty, go to next packet */
@ -215,8 +225,9 @@ void LAVCAudioProvider::GetAudio(void *buf, int64_t start, int64_t count)
} }
decoded_bytes = temp_output_buffer_size; decoded_bytes = temp_output_buffer_size;
decoded_samples = decoded_bytes / 2; /* 2 bytes per sample */ decoded_samples = decoded_bytes / 2; /* FIXME: stop assuming everything is 16-bit! */
size -= retval; size -= retval;
data += retval;
/* do we need to resample? */ /* do we need to resample? */
if (rsct) { if (rsct) {