ffmpeg addon: only use swresample for planar audio.

Fixes #12547.
This commit is contained in:
Jessica Hamilton
2015-12-31 16:19:57 +01:00
committed by Adrien Destugues
parent ccb3f7e7a0
commit 8113bbfe40
2 changed files with 41 additions and 18 deletions
@@ -408,12 +408,14 @@ AVCodecDecoder::_NegotiateAudioOutputFormat(media_format* inOutFormat)
if (fRawDecodedAudio->opaque == NULL) if (fRawDecodedAudio->opaque == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
fResampleContext = swr_alloc_set_opts(NULL, if (AVSampleFormatIsPlanar(fContext->sample_fmt)) {
fContext->channel_layout, fContext->request_sample_fmt, fResampleContext = swr_alloc_set_opts(NULL,
fContext->sample_rate, fContext->channel_layout, fContext->request_sample_fmt,
fContext->channel_layout, fContext->sample_fmt, fContext->sample_rate, fContext->sample_rate,
0, NULL); fContext->channel_layout, fContext->sample_fmt, fContext->sample_rate,
swr_init(fResampleContext); 0, NULL);
swr_init(fResampleContext);
}
TRACE(" bit_rate = %d, sample_rate = %d, channels = %d, " TRACE(" bit_rate = %d, sample_rate = %d, channels = %d, "
"output frame size: %d, count: %ld, rate: %.2f\n", "output frame size: %d, count: %ld, rate: %.2f\n",
@@ -923,24 +925,29 @@ AVCodecDecoder::_MoveAudioFramesToRawDecodedAudioAndUpdateStartTimes()
// "planar" audio (each channel separated instead of interleaved samples). // "planar" audio (each channel separated instead of interleaved samples).
// In that case, we use swresample to convert the data (and it is // In that case, we use swresample to convert the data (and it is
// smart enough to do just a copy, when possible) // smart enough to do just a copy, when possible)
const uint8_t* ptr[8]; if (AVSampleFormatIsPlanar(fContext->sample_fmt)) {
for (int i = 0; i < 8; i++) { const uint8_t* ptr[8];
if (fDecodedDataBuffer->data[i] == NULL) for (int i = 0; i < 8; i++) {
ptr[i] = NULL; if (fDecodedDataBuffer->data[i] == NULL)
else ptr[i] = NULL;
ptr[i] = fDecodedDataBuffer->data[i] + fDecodedDataBufferOffset; else
} ptr[i] = fDecodedDataBuffer->data[i] + fDecodedDataBufferOffset;
}
int32 result = swr_convert(fResampleContext, fRawDecodedAudio->data, int32 result = swr_convert(fResampleContext, fRawDecodedAudio->data,
outFrames, ptr, inFrames); outFrames, ptr, inFrames);
if (result < 0)
debugger("resampling failed");
} else {
memcpy(fRawDecodedAudio->data[0], fDecodedDataBuffer->data[0]
+ fDecodedDataBufferOffset, frames * fOutputFrameSize);
}
size_t remainingSize = inFrames * fOutputFrameSize; size_t remainingSize = inFrames * fOutputFrameSize;
size_t decodedSize = outFrames * fOutputFrameSize; size_t decodedSize = outFrames * fOutputFrameSize;
fDecodedDataBufferSize -= inFrames; fDecodedDataBufferSize -= inFrames;
if (result < 0)
debugger("resampling failed");
bool firstAudioFramesCopiedToRawDecodedAudio bool firstAudioFramesCopiedToRawDecodedAudio
= fRawDecodedAudio->data[0] != fDecodedData; = fRawDecodedAudio->data[0] != fDecodedData;
if (!firstAudioFramesCopiedToRawDecodedAudio) { if (!firstAudioFramesCopiedToRawDecodedAudio) {
@@ -317,4 +317,20 @@ ConvertAVSampleFormatToRawAudioFormat(AVSampleFormat sampleFormatIn,
} }
inline bool
AVSampleFormatIsPlanar(AVSampleFormat sampleFormat)
{
switch (sampleFormat) {
case AV_SAMPLE_FMT_FLTP:
case AV_SAMPLE_FMT_DBLP:
case AV_SAMPLE_FMT_S32P:
case AV_SAMPLE_FMT_S16P:
case AV_SAMPLE_FMT_U8P:
return true;
default:
return false;
}
}
#endif // UTILITIES_H #endif // UTILITIES_H