Merge "Fugu Audio HAL: allow EAC3 at low sample rates" into mnc-dev
diff --git a/libaudio/AudioStreamOut.cpp b/libaudio/AudioStreamOut.cpp
index bb70bbd..0ae8e3b 100644
--- a/libaudio/AudioStreamOut.cpp
+++ b/libaudio/AudioStreamOut.cpp
@@ -113,7 +113,8 @@
     } else {
         // Else check to see if our HDMI sink supports this format before proceeding.
         if (!mOwnerHAL.getHDMIAudioCaps().supportsFormat(
-                lFormat, lRate, audio_channel_count_from_out_mask(lChannels))) {
+                lFormat, lRate, audio_channel_count_from_out_mask(lChannels),
+                mIsIec958NonAudio)) {
             ALOGW("set: parameters incompatible with hdmi capabilities");
             return BAD_VALUE;
         }
diff --git a/libaudio/HDMIAudioOutput.cpp b/libaudio/HDMIAudioOutput.cpp
index d79cb5e..8d1dc67 100644
--- a/libaudio/HDMIAudioOutput.cpp
+++ b/libaudio/HDMIAudioOutput.cpp
@@ -51,7 +51,8 @@
     if (!gAudioHardwareOutput.getHDMIAudioCaps().supportsFormat(
             stream.format(),
             stream.sampleRate(),
-            mChannelCnt)) {
+            mChannelCnt,
+            stream.isIec958NonAudio())) {
         ALOGE("HDMI Sink does not support format = 0x%0X, srate = %d, #channels = 0%d",
                 stream.format(), mFramesPerSec, mChannelCnt);
         return BAD_VALUE;
diff --git a/libaudio/alsa_utils.cpp b/libaudio/alsa_utils.cpp
index f90c6de..81e7355 100644
--- a/libaudio/alsa_utils.cpp
+++ b/libaudio/alsa_utils.cpp
@@ -356,9 +356,12 @@
 
 bool HDMIAudioCaps::supportsFormat(audio_format_t format,
                                       uint32_t sampleRate,
-                                      uint32_t channelCount) {
+                                      uint32_t channelCount,
+                                      bool isIec958NonAudio) {
     Mutex::Autolock _l(mLock);
 
+    ALOGV("supportsFormat() format = 0x%08X, sampleRate = %u, channels = 0x%08X, iec958 = %d",
+                format, sampleRate, channelCount, isIec958NonAudio ? 1 : 0);
     // If the sink does not support basic audio, then it supports no audio.
     if (!mBasicAudioSupported)
         return false;
@@ -373,6 +376,19 @@
         default: return false;
     }
 
+    // EAC3 uses a PCM sample rate of 4X the base rate.
+    // We try to detect that situation and allow 4X rate even if the
+    // EDID does not report that it is supported.
+    // This rate was chosen because it is between the region of typical PCM rates
+    // and the extreme rates used for IEC61973.
+    // It is > 96000 and < 4*32000.
+    const uint32_t maxReasonableRate = 100000; // FIXME review for N
+    if (isIec958NonAudio && (alsaFormat == kFmtLPCM) && (sampleRate > maxReasonableRate)) {
+        ALOGI("supportsFormat() dividing sample %u by 4 to test support for EAC3 over HDMI",
+                sampleRate);
+        sampleRate = sampleRate / 4;
+    }
+
     SRMask srMask;
     switch (sampleRate) {
         case 32000:  srMask = kSR_32000;  break;
diff --git a/libaudio/alsa_utils.h b/libaudio/alsa_utils.h
index b770468..f0f1b21 100644
--- a/libaudio/alsa_utils.h
+++ b/libaudio/alsa_utils.h
@@ -108,7 +108,8 @@
     void getChannelMasksForAF(String8& masks);
     bool supportsFormat(audio_format_t format,
                                       uint32_t sampleRate,
-                                      uint32_t channelCount);
+                                      uint32_t channelCount,
+                                      bool isIec958NonAudio);
 
     bool basicAudioSupport() const { return mBasicAudioSupported; }
     uint16_t speakerAllocation() const { return mSpeakerAlloc; }