Bug 1270016: P2. Make the FFVPX PDM work with FLAC. r?kentuckyfriedtakahe
MozReview-Commit-ID: BmwtZF3NSEI
--- a/dom/media/AudioSampleFormat.h
+++ b/dom/media/AudioSampleFormat.h
@@ -75,16 +75,21 @@ AudioSampleToFloat(float aValue)
{
return aValue;
}
inline float
AudioSampleToFloat(int16_t aValue)
{
return aValue/32768.0f;
}
+inline float
+AudioSampleToFloat(int32_t aValue)
+{
+ return aValue/(float)(1U<<31);
+}
template <typename T> T FloatToAudioSample(float aValue);
template <> inline float
FloatToAudioSample<float>(float aValue)
{
return aValue;
}
--- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
@@ -86,16 +86,35 @@ CopyAndPackAudio(AVFrame* aFrame, uint32
// and pack it into something we can understand.
AudioDataValue* tmp = audio.get();
int16_t** data = reinterpret_cast<int16_t**>(aFrame->data);
for (uint32_t frame = 0; frame < aNumAFrames; frame++) {
for (uint32_t channel = 0; channel < aNumChannels; channel++) {
*tmp++ = AudioSampleToFloat(data[channel][frame]);
}
}
+ } else if (aFrame->format == AV_SAMPLE_FMT_S32) {
+ // Audio data already packed. Need to convert from S16 to 32 bits Float
+ AudioDataValue* tmp = audio.get();
+ int32_t* data = reinterpret_cast<int32_t**>(aFrame->data)[0];
+ for (uint32_t frame = 0; frame < aNumAFrames; frame++) {
+ for (uint32_t channel = 0; channel < aNumChannels; channel++) {
+ *tmp++ = AudioSampleToFloat(*data++);
+ }
+ }
+ } else if (aFrame->format == AV_SAMPLE_FMT_S32P) {
+ // Planar audio data. Convert it from S32 to 32 bits float
+ // and pack it into something we can understand.
+ AudioDataValue* tmp = audio.get();
+ int32_t** data = reinterpret_cast<int32_t**>(aFrame->data);
+ for (uint32_t frame = 0; frame < aNumAFrames; frame++) {
+ for (uint32_t channel = 0; channel < aNumChannels; channel++) {
+ *tmp++ = AudioSampleToFloat(data[channel][frame]);
+ }
+ }
}
return audio;
}
FFmpegAudioDecoder<LIBAV_VER>::DecodeResult
FFmpegAudioDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample)
{
@@ -171,19 +190,19 @@ FFmpegAudioDecoder<LIBAV_VER>::ProcessDr
mCallback->DrainComplete();
}
AVCodecID
FFmpegAudioDecoder<LIBAV_VER>::GetCodecId(const nsACString& aMimeType)
{
if (aMimeType.EqualsLiteral("audio/mpeg")) {
return AV_CODEC_ID_MP3;
- }
-
- if (aMimeType.EqualsLiteral("audio/mp4a-latm")) {
+ } else if (aMimeType.EqualsLiteral("audio/flac")) {
+ return AV_CODEC_ID_FLAC;
+ } else if (aMimeType.EqualsLiteral("audio/mp4a-latm")) {
return AV_CODEC_ID_AAC;
}
return AV_CODEC_ID_NONE;
}
FFmpegAudioDecoder<LIBAV_VER>::~FFmpegAudioDecoder()
{
--- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
@@ -85,17 +85,19 @@ FFmpegDataDecoder<LIBAV_VER>::InitDecode
mLib->av_freep(&mCodecContext);
return NS_ERROR_FAILURE;
}
if (mCodecContext->codec_type == AVMEDIA_TYPE_AUDIO &&
mCodecContext->sample_fmt != AV_SAMPLE_FMT_FLT &&
mCodecContext->sample_fmt != AV_SAMPLE_FMT_FLTP &&
mCodecContext->sample_fmt != AV_SAMPLE_FMT_S16 &&
- mCodecContext->sample_fmt != AV_SAMPLE_FMT_S16P) {
+ mCodecContext->sample_fmt != AV_SAMPLE_FMT_S16P &&
+ mCodecContext->sample_fmt != AV_SAMPLE_FMT_S32 &&
+ mCodecContext->sample_fmt != AV_SAMPLE_FMT_S32P) {
NS_WARNING("FFmpeg audio decoder outputs unsupported audio format.");
return NS_ERROR_FAILURE;
}
FFMPEG_LOG("FFmpeg init successful.");
return NS_OK;
}
--- a/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
+++ b/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
@@ -40,45 +40,34 @@ public:
aParams.VideoConfig(),
aParams.mImageContainer);
return decoder.forget();
}
already_AddRefed<MediaDataDecoder>
CreateAudioDecoder(const CreateDecoderParams& aParams) override
{
-#ifdef USING_MOZFFVPX
- return nullptr;
-#else
RefPtr<MediaDataDecoder> decoder =
new FFmpegAudioDecoder<V>(mLib,
aParams.mTaskQueue,
aParams.mCallback,
aParams.AudioConfig());
return decoder.forget();
-#endif
}
bool SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const override
{
AVCodecID videoCodec = FFmpegVideoDecoder<V>::GetCodecId(aMimeType);
-#ifdef USING_MOZFFVPX
- if (videoCodec == AV_CODEC_ID_NONE) {
- return false;
- }
- return !!FFmpegDataDecoder<V>::FindAVCodec(mLib, videoCodec);
-#else
AVCodecID audioCodec = FFmpegAudioDecoder<V>::GetCodecId(aMimeType);
if (audioCodec == AV_CODEC_ID_NONE && videoCodec == AV_CODEC_ID_NONE) {
return false;
}
AVCodecID codec = audioCodec != AV_CODEC_ID_NONE ? audioCodec : videoCodec;
return !!FFmpegDataDecoder<V>::FindAVCodec(mLib, codec);
-#endif
}
ConversionRequired
DecoderNeedsConversion(const TrackInfo& aConfig) const override
{
if (aConfig.IsVideo() &&
(aConfig.mMimeType.EqualsLiteral("video/avc") ||
aConfig.mMimeType.EqualsLiteral("video/mp4"))) {
--- a/dom/media/platforms/ffmpeg/FFmpegLibs.h
+++ b/dom/media/platforms/ffmpeg/FFmpegLibs.h
@@ -21,16 +21,17 @@ extern "C" {
#if LIBAVCODEC_VERSION_MAJOR < 55
#define AV_CODEC_ID_VP6F CODEC_ID_VP6F
#define AV_CODEC_ID_H264 CODEC_ID_H264
#define AV_CODEC_ID_AAC CODEC_ID_AAC
#define AV_CODEC_ID_MP3 CODEC_ID_MP3
#define AV_CODEC_ID_VP8 CODEC_ID_VP8
#define AV_CODEC_ID_NONE CODEC_ID_NONE
+#define AV_CODEC_ID_FLAC CODEC_ID_FLAC
typedef CodecID AVCodecID;
#endif
#ifdef FFVPX_VERSION
enum { LIBAV_VER = FFVPX_VERSION };
#else
enum { LIBAV_VER = LIBAVCODEC_VERSION_MAJOR };
#endif
--- a/dom/media/platforms/ffmpeg/ffvpx/moz.build
+++ b/dom/media/platforms/ffmpeg/ffvpx/moz.build
@@ -5,16 +5,17 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
LOCAL_INCLUDES += ['/xpcom/build']
EXPORTS += [
'FFVPXRuntimeLinker.h',
]
UNIFIED_SOURCES += [
+ '../FFmpegAudioDecoder.cpp',
'../FFmpegDataDecoder.cpp',
'../FFmpegDecoderModule.cpp',
'../FFmpegVideoDecoder.cpp',
]
SOURCES += [
'FFVPXRuntimeLinker.cpp',
]
LOCAL_INCLUDES += [