Revert r8577 "Collapse AudioEncoderDecoderIsacRed into ..."

Some of the build bots seems to have reacted to this change.

TBR=kwiberg@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/42169004

Cr-Commit-Position: refs/heads/master@{#8578}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8578 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
index 38d5903..4b56b91 100644
--- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
+++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h
@@ -41,7 +41,6 @@
     int bit_rate;  // Limit on the short-term average bit rate, in bits/second.
     int max_bit_rate;
     int max_payload_size_bytes;
-    bool use_red;
   };
 
   // For constructing an encoder in channel-adaptive mode. Allowed combinations
@@ -61,7 +60,6 @@
     int max_bit_rate;
     bool enforce_frame_size;  // Prevent adaptive changes to the frame size?
     int max_payload_size_bytes;
-    bool use_red;
   };
 
   explicit AudioEncoderDecoderIsacT(const Config& config);
@@ -110,7 +108,6 @@
 
   const int payload_type_;
   const int red_payload_type_;
-  const bool use_red_;
 
   // iSAC encoder/decoder state, guarded by a mutex to ensure that encode calls
   // from one thread won't clash with decode calls from another thread.
@@ -134,7 +131,11 @@
   uint32_t last_encoded_timestamp_ GUARDED_BY(lock_);
 
   // Redundant encoding from last time.
-  const rtc::scoped_ptr<uint8_t[]> redundant_payload_ GUARDED_BY(lock_);
+  // Note: If has_redundant_encoder is false, we set the array length to 1,
+  // since zero-length arrays are not supported by all compilers.
+  uint8_t redundant_payload_[T::has_redundant_encoder
+                                 ? kSufficientEncodeBufferSizeBytes
+                                 : 1] GUARDED_BY(lock_);
   size_t redundant_length_bytes_ GUARDED_BY(lock_);
 
   DISALLOW_COPY_AND_ASSIGN(AudioEncoderDecoderIsacT);
diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
index 024efa1..7ac51b6 100644
--- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
+++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h
@@ -33,8 +33,7 @@
       frame_size_ms(30),
       bit_rate(kDefaultBitRate),
       max_bit_rate(-1),
-      max_payload_size_bytes(-1),
-      use_red(false) {
+      max_payload_size_bytes(-1) {
 }
 
 template <typename T>
@@ -43,8 +42,6 @@
     return false;
   if (max_payload_size_bytes < 120 && max_payload_size_bytes != -1)
     return false;
-  if (use_red && red_payload_type == kInvalidPayloadType)
-    return false;
   switch (sample_rate_hz) {
     case 16000:
       if (max_bit_rate > 53400)
@@ -76,8 +73,7 @@
       initial_bit_rate(kDefaultBitRate),
       max_bit_rate(-1),
       enforce_frame_size(false),
-      max_payload_size_bytes(-1),
-      use_red(false) {
+      max_payload_size_bytes(-1) {
 }
 
 template <typename T>
@@ -86,8 +82,6 @@
     return false;
   if (max_payload_size_bytes < 120 && max_payload_size_bytes != -1)
     return false;
-  if (use_red && red_payload_type == kInvalidPayloadType)
-    return false;
   switch (sample_rate_hz) {
     case 16000:
       if (max_bit_rate > 53400)
@@ -114,13 +108,10 @@
 AudioEncoderDecoderIsacT<T>::AudioEncoderDecoderIsacT(const Config& config)
     : payload_type_(config.payload_type),
       red_payload_type_(config.red_payload_type),
-      use_red_(config.use_red),
       state_lock_(CriticalSectionWrapper::CreateCriticalSection()),
       decoder_sample_rate_hz_(0),
       lock_(CriticalSectionWrapper::CreateCriticalSection()),
       packet_in_progress_(false),
-      redundant_payload_(
-          use_red_ ? new uint8_t[kSufficientEncodeBufferSizeBytes] : nullptr),
       redundant_length_bytes_(0) {
   CHECK(config.IsOk());
   CHECK_EQ(0, T::Create(&isac_state_));
@@ -145,13 +136,10 @@
     const ConfigAdaptive& config)
     : payload_type_(config.payload_type),
       red_payload_type_(config.red_payload_type),
-      use_red_(config.use_red),
       state_lock_(CriticalSectionWrapper::CreateCriticalSection()),
       decoder_sample_rate_hz_(0),
       lock_(CriticalSectionWrapper::CreateCriticalSection()),
       packet_in_progress_(false),
-      redundant_payload_(
-          use_red_ ? new uint8_t[kSufficientEncodeBufferSizeBytes] : nullptr),
       redundant_length_bytes_(0) {
   CHECK(config.IsOk());
   CHECK_EQ(0, T::Create(&isac_state_));
@@ -230,7 +218,7 @@
   info->encoded_timestamp = packet_timestamp_;
   info->payload_type = payload_type_;
 
-  if (!use_red_)
+  if (!T::has_redundant_encoder)
     return;
 
   if (redundant_length_bytes_ == 0) {
@@ -241,7 +229,7 @@
     // resulting payload consists of the primary encoding followed by the
     // redundant encoding from last time.
     const size_t primary_length = info->encoded_bytes;
-    memcpy(&encoded[primary_length], redundant_payload_.get(),
+    memcpy(&encoded[primary_length], redundant_payload_,
            redundant_length_bytes_);
     // The EncodedInfo struct |info| will have one root node and two leaves.
     // |info| will be implicitly cast to an EncodedInfoLeaf struct, effectively
@@ -263,9 +251,9 @@
   {
     CriticalSectionScoped cs(state_lock_.get());
     // Call the encoder's method to get redundant encoding.
-    redundant_length_bytes_ =
-        T::GetRedPayload(isac_state_, redundant_payload_.get());
+    redundant_length_bytes_ = T::GetRedPayload(isac_state_, redundant_payload_);
   }
+  DCHECK_LE(redundant_length_bytes_, sizeof(redundant_payload_));
   DCHECK_GE(redundant_length_bytes_, 0u);
   last_encoded_timestamp_ = packet_timestamp_;
 }
diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h b/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h
index 979c7fe..2727611 100644
--- a/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h
+++ b/webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_isacfix.h
@@ -20,6 +20,7 @@
 struct IsacFix {
   typedef ISACFIX_MainStruct instance_type;
   static const bool has_swb = false;
+  static const bool has_redundant_encoder = false;
   static const uint16_t kFixSampleRate = 16000;
   static inline int16_t Control(instance_type* inst,
                                 int32_t rate,
diff --git a/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h b/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h
index 5218230..4ab88b6 100644
--- a/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h
+++ b/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h
@@ -20,6 +20,7 @@
 struct IsacFloat {
   typedef ISACStruct instance_type;
   static const bool has_swb = true;
+  static const bool has_redundant_encoder = false;
   static inline int16_t Control(instance_type* inst,
                                 int32_t rate,
                                 int16_t framesize) {
@@ -99,7 +100,8 @@
                                        rtp_seq_number, send_ts, arr_ts);
   }
   static inline int16_t GetRedPayload(instance_type* inst, uint8_t* encoded) {
-    return WebRtcIsac_GetRedPayload(inst, encoded);
+    FATAL() << "Should never be called.";
+    return -1;
   }
   static inline int16_t SetMaxPayloadSize(instance_type* inst,
                                           int16_t max_payload_size_bytes) {
@@ -112,5 +114,15 @@
 
 typedef AudioEncoderDecoderIsacT<IsacFloat> AudioEncoderDecoderIsac;
 
+struct IsacRed : public IsacFloat {
+  static const bool has_redundant_encoder = true;
+
+  static inline int16_t GetRedPayload(instance_type* inst, uint8_t* encoded) {
+    return WebRtcIsac_GetRedPayload(inst, encoded);
+  }
+};
+
+typedef AudioEncoderDecoderIsacT<IsacRed> AudioEncoderDecoderIsacRed;
+
 }  // namespace webrtc
 #endif  // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_AUDIO_ENCODER_ISAC_H_
diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc b/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc
index ba08603..5e554ba 100644
--- a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc
+++ b/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc
@@ -18,4 +18,8 @@
 // AudioEncoderDecoderIsac.
 template class AudioEncoderDecoderIsacT<IsacFloat>;
 
+// Explicit instantiation of AudioEncoderDecoderIsacT<IsacRed>, a.k.a.
+// AudioEncoderDecoderIsacRed.
+template class AudioEncoderDecoderIsacT<IsacRed>;
+
 }  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac_red_unittest.cc b/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac_red_unittest.cc
index 4bc6166..0372523 100644
--- a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac_red_unittest.cc
+++ b/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac_red_unittest.cc
@@ -36,13 +36,12 @@
   AudioEncoderDecoderIsac::Config config;
   config.sample_rate_hz = kSampleRateHz;
   AudioEncoderDecoderIsac isac_encoder(config);
-  AudioEncoderDecoderIsac::Config red_config;
+  AudioEncoderDecoderIsacRed::Config red_config;
   red_config.sample_rate_hz = kSampleRateHz;
   red_config.red_payload_type = kRedPayloadType;
-  red_config.use_red = true;
   ASSERT_NE(red_config.red_payload_type, red_config.payload_type)
       << "iSAC and RED payload types must be different.";
-  AudioEncoderDecoderIsac isac_red_encoder(red_config);
+  AudioEncoderDecoderIsacRed isac_red_encoder(red_config);
   AudioEncoder::EncodedInfo info, red_info;
 
   // Note that we are not expecting any output from the redundant encoder until
diff --git a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc
index 30960ac..071244b 100644
--- a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc
+++ b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc
@@ -372,40 +372,62 @@
 #ifdef WEBRTC_CODEC_ISAC
   } else if (!STR_CASE_CMP(codec_inst.plname, "ISAC")) {
     is_isac_ = true;
-    using_codec_internal_red = copy_red_enabled_;
-    AudioEncoderDecoderIsac* enc_dec;
-    if (codec_inst.rate == -1) {
-      // Adaptive mode.
-      AudioEncoderDecoderIsac::ConfigAdaptive config;
-      config.sample_rate_hz = codec_inst.plfreq;
-      config.initial_frame_size_ms = rtc::CheckedDivExact(
-          1000 * codec_inst.pacsize, config.sample_rate_hz);
-      config.max_payload_size_bytes = max_payload_size_bytes_;
-      config.max_bit_rate = max_rate_bps_;
-      config.payload_type = codec_inst.pltype;
-      if (copy_red_enabled_) {
+    if (copy_red_enabled_) {
+      using_codec_internal_red = true;
+      AudioEncoderDecoderIsacRed* enc_dec;
+      if (codec_inst.rate == -1) {
+        // Adaptive mode.
+        AudioEncoderDecoderIsacRed::ConfigAdaptive config;
+        config.sample_rate_hz = codec_inst.plfreq;
+        config.initial_frame_size_ms = rtc::CheckedDivExact(
+            1000 * codec_inst.pacsize, config.sample_rate_hz);
+        config.max_payload_size_bytes = max_payload_size_bytes_;
+        config.max_bit_rate = max_rate_bps_;
+        config.payload_type = codec_inst.pltype;
         config.red_payload_type = red_payload_type_;
-        config.use_red = true;
+        enc_dec = new AudioEncoderDecoderIsacRed(config);
+      } else {
+        // Channel independent mode.
+        AudioEncoderDecoderIsacRed::Config config;
+        config.sample_rate_hz = codec_inst.plfreq;
+        config.bit_rate = codec_inst.rate;
+        config.frame_size_ms = rtc::CheckedDivExact(1000 * codec_inst.pacsize,
+                                                    config.sample_rate_hz);
+        config.max_payload_size_bytes = max_payload_size_bytes_;
+        config.max_bit_rate = max_rate_bps_;
+        config.payload_type = codec_inst.pltype;
+        config.red_payload_type = red_payload_type_;
+        enc_dec = new AudioEncoderDecoderIsacRed(config);
       }
-      enc_dec = new AudioEncoderDecoderIsac(config);
+      audio_encoder_.reset(enc_dec);
+      decoder_proxy_.SetDecoder(enc_dec);
     } else {
-      // Channel independent mode.
-      AudioEncoderDecoderIsac::Config config;
-      config.sample_rate_hz = codec_inst.plfreq;
-      config.bit_rate = codec_inst.rate;
-      config.frame_size_ms = rtc::CheckedDivExact(1000 * codec_inst.pacsize,
-                                                  config.sample_rate_hz);
-      config.max_payload_size_bytes = max_payload_size_bytes_;
-      config.max_bit_rate = max_rate_bps_;
-      config.payload_type = codec_inst.pltype;
-      if (copy_red_enabled_) {
-        config.red_payload_type = red_payload_type_;
-        config.use_red = true;
+      AudioEncoderDecoderIsac* enc_dec;
+      if (codec_inst.rate == -1) {
+        // Adaptive mode.
+        AudioEncoderDecoderIsac::ConfigAdaptive config;
+        config.sample_rate_hz = codec_inst.plfreq;
+        config.initial_frame_size_ms = rtc::CheckedDivExact(
+            1000 * codec_inst.pacsize, config.sample_rate_hz);
+        config.max_payload_size_bytes = max_payload_size_bytes_;
+        config.max_bit_rate = max_rate_bps_;
+        config.payload_type = codec_inst.pltype;
+        enc_dec = new AudioEncoderDecoderIsac(config);
+      } else {
+        // Channel independent mode.
+        AudioEncoderDecoderIsac::Config config;
+        config.sample_rate_hz = codec_inst.plfreq;
+        config.bit_rate = codec_inst.rate;
+        config.frame_size_ms = rtc::CheckedDivExact(1000 * codec_inst.pacsize,
+                                                    config.sample_rate_hz);
+        config.max_payload_size_bytes = max_payload_size_bytes_;
+        config.max_bit_rate = max_rate_bps_;
+        config.payload_type = codec_inst.pltype;
+        enc_dec = new AudioEncoderDecoderIsac(config);
       }
-      enc_dec = new AudioEncoderDecoderIsac(config);
+      audio_encoder_.reset(enc_dec);
+      decoder_proxy_.SetDecoder(enc_dec);
     }
-    audio_encoder_.reset(enc_dec);
-    decoder_proxy_.SetDecoder(enc_dec);
 #endif
   } else {
     FATAL();