diff --git a/trunk/src/app/srs_app_rtc.cpp b/trunk/src/app/srs_app_rtc.cpp
index 80b28ddf5..ca525637e 100644
--- a/trunk/src/app/srs_app_rtc.cpp
+++ b/trunk/src/app/srs_app_rtc.cpp
@@ -208,7 +208,6 @@ srs_error_t SrsRtpH264Muxer::packet_single_nalu(SrsSharedPtrMessage* shared_fram
 {
     srs_error_t err = srs_success;
 
-    uint8_t header = sample->bytes[0];
     srs_verbose("rtp single nalu, size=%u, seq=%u, timestamp=%lu", sample->size, sequence, (shared_frame->timestamp * 90));
 
     SrsRtpSharedPacket* packet = new SrsRtpSharedPacket();
@@ -287,32 +286,47 @@ srs_error_t SrsRtpOpusMuxer::initialize()
     return err;
 }
 
+// An AAC packet may be transcoded to many OPUS packets.
+const int kMaxOpusPackets = 8;
+// The max size for each OPUS packet.
+const int kMaxOpusPacketSize = 4096;
+
 srs_error_t SrsRtpOpusMuxer::frame_to_packet(SrsSharedPtrMessage* shared_audio, SrsFormat* format, char* adts_audio, int nn_adts_audio)
 {
     srs_error_t err = srs_success;
 
-    vector<SrsRtpSharedPacket*> rtp_packets;
+    // Opus packet cache.
+    static char* opus_payloads[kMaxOpusPackets];
 
-    char* data_ptr[kArrayLength];
-    static char data_array[kArrayLength][kArrayBuffer];
-    int elen[kArrayLength], number = 0;
+    static bool initialized = false;
+    if (!initialized) {
+        initialized = true;
 
-    data_ptr[0] = &data_array[0][0];
-    for (int i = 1; i < kArrayLength; i++) {
-       data_ptr[i] = data_array[i];
+        static char opus_packets_cache[kMaxOpusPackets][kMaxOpusPacketSize];
+        opus_payloads[0] = &opus_packets_cache[0][0];
+        for (int i = 1; i < kMaxOpusPackets; i++) {
+           opus_payloads[i] = opus_packets_cache[i];
+        }
     }
 
-    SrsSample pkt;
-    pkt.bytes = adts_audio;
-    pkt.size = nn_adts_audio;
-    if ((err = transcode->recode(&pkt, data_ptr, elen, number)) != srs_success) {
+    // Transcode aac packet to opus packets.
+    SrsSample aac;
+    aac.bytes = adts_audio;
+    aac.size = nn_adts_audio;
+
+    int nn_opus_packets = 0;
+    int opus_sizes[kMaxOpusPackets];
+    if ((err = transcode->recode(&aac, opus_payloads, opus_sizes, nn_opus_packets)) != srs_success) {
         return srs_error_wrap(err, "recode error");
     }
 
-    for (int i = 0; i < number; i++) {
+    // Package opus packets to RTP packets.
+    vector<SrsRtpSharedPacket*> rtp_packets;
+
+    for (int i = 0; i < nn_opus_packets; i++) {
         SrsSample sample;
-        sample.size = elen[i];
-        sample.bytes = data_ptr[i];
+        sample.size = opus_sizes[i];
+        sample.bytes = opus_payloads[i];
         if ((err = packet_opus(shared_audio, &sample, rtp_packets)) != srs_success) {
             return srs_error_wrap(err, "packet as opus");
         }
diff --git a/trunk/src/app/srs_app_rtc.hpp b/trunk/src/app/srs_app_rtc.hpp
index 2ba18c43e..f409e2624 100644
--- a/trunk/src/app/srs_app_rtc.hpp
+++ b/trunk/src/app/srs_app_rtc.hpp
@@ -61,8 +61,6 @@ const uint8_t kEnd              = 0x40; // Fu-header end bit
 
 const int kChannel              = 2;
 const int kSamplerate           = 48000;
-const int kArrayLength          = 8;
-const int kArrayBuffer          = 4096;
 
 // SSRC will rewrite in srs_app_rtc_conn.cpp when send to client.
 const uint32_t kAudioSSRC       = 1;
diff --git a/trunk/src/kernel/srs_kernel_codec.hpp b/trunk/src/kernel/srs_kernel_codec.hpp
index b265ccb2d..14e486835 100644
--- a/trunk/src/kernel/srs_kernel_codec.hpp
+++ b/trunk/src/kernel/srs_kernel_codec.hpp
@@ -532,7 +532,7 @@ class SrsSample
 public:
     // The size of unit.
     int size;
-    // The ptr of unit, user must manage it.
+    // The ptr of unit, user must free it.
     char* bytes;
     // Whether is B frame.
     bool bframe;
diff --git a/trunk/src/kernel/srs_kernel_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp
index 411b42596..f74df7968 100644
--- a/trunk/src/kernel/srs_kernel_flv.cpp
+++ b/trunk/src/kernel/srs_kernel_flv.cpp
@@ -214,8 +214,8 @@ SrsSharedPtrMessage::SrsSharedPtrPayload::SrsSharedPtrPayload()
     samples = NULL;
     nb_samples = 0;
 
-    extra_payload = NULL;
-    extra_size = 0;
+    extra_payloads = NULL;
+    nn_extra_payloads = 0;
 }
 
 SrsSharedPtrMessage::SrsSharedPtrPayload::~SrsSharedPtrPayload()
@@ -225,7 +225,12 @@ SrsSharedPtrMessage::SrsSharedPtrPayload::~SrsSharedPtrPayload()
 #endif
     srs_freepa(payload);
     srs_freepa(samples);
-    srs_freepa(extra_payload);
+
+    for (int i = 0; i < nn_extra_payloads; i++) {
+        SrsSample* p = extra_payloads + i;
+        srs_freep(p->bytes);
+    }
+    srs_freep(extra_payloads);
 }
 
 SrsSharedPtrMessage::SrsSharedPtrMessage() : timestamp(0), stream_id(0), size(0), payload(NULL)
diff --git a/trunk/src/kernel/srs_kernel_flv.hpp b/trunk/src/kernel/srs_kernel_flv.hpp
index 397439b7c..b948d2596 100644
--- a/trunk/src/kernel/srs_kernel_flv.hpp
+++ b/trunk/src/kernel/srs_kernel_flv.hpp
@@ -311,9 +311,9 @@ private:
         SrsSample* samples;
         int nb_samples;
         // For RTC audio, we may need to transcode AAC to opus,
-        // so there must be an extra payload, which is transformed from payload.
-        char* extra_payload;
-        int extra_size;
+        // so there must be an extra payloads, which is transformed from payload.
+        SrsSample* extra_payloads;
+        int nn_extra_payloads;
     public:
         SrsSharedPtrPayload();
         virtual ~SrsSharedPtrPayload();