Merge "Apparently the generic mpeg4 file header does not describe the actual samplerate and channel count of the content in the case of mpeg4 audio, instead the 'ESDS' atom must be consulted."
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index 71344e6..26fcc95 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -47,7 +47,7 @@
     // Return time in us.
     virtual int64_t getRealTimeUs();
 
-    void start();
+    status_t start();
 
     void pause();
     void resume();
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 14842c0..efe7ebb 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -58,12 +58,15 @@
     mSource = source;
 }
 
-void AudioPlayer::start() {
+status_t AudioPlayer::start() {
     CHECK(!mStarted);
     CHECK(mSource != NULL);
 
     status_t err = mSource->start();
-    CHECK_EQ(err, OK);
+
+    if (err != OK) {
+        return err;
+    }
 
     sp<MetaData> format = mSource->getFormat();
     const char *mime;
@@ -83,7 +86,11 @@
                 mSampleRate, numChannels, AudioSystem::PCM_16_BIT,
                 DEFAULT_AUDIOSINK_BUFFERCOUNT,
                 &AudioPlayer::AudioSinkCallback, this);
-        CHECK_EQ(err, OK);
+        if (err != OK) {
+            mSource->stop();
+
+            return err;
+        }
 
         mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
         mFrameSize = mAudioSink->frameSize();
@@ -97,7 +104,14 @@
                     : AudioSystem::CHANNEL_OUT_MONO,
                 8192, 0, &AudioCallback, this, 0);
 
-        CHECK_EQ(mAudioTrack->initCheck(), OK);
+        if (mAudioTrack->initCheck() != OK) {
+            delete mAudioTrack;
+            mAudioTrack = NULL;
+
+            mSource->stop();
+
+            return mAudioTrack->initCheck();
+        }
 
         mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
         mFrameSize = mAudioTrack->frameSize();
@@ -106,6 +120,8 @@
     }
 
     mStarted = true;
+
+    return OK;
 }
 
 void AudioPlayer::pause() {
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 85019aa..4e7738e 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -378,7 +378,16 @@
                         &AwesomePlayer::AudioNotify, this);
 
                 mAudioPlayer->setSource(mAudioSource);
-                mAudioPlayer->start();
+                status_t err = mAudioPlayer->start();
+
+                if (err != OK) {
+                    delete mAudioPlayer;
+                    mAudioPlayer = NULL;
+
+                    mFlags &= ~(PLAYING | FIRST_FRAME);
+
+                    return err;
+                }
 
                 delete mTimeSource;
                 mTimeSource = mAudioPlayer;
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index da8fe79..7365dfa 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -178,7 +178,8 @@
 
             mBitsPerSample = U16_LE_AT(&formatSpec[14]);
 
-            if (mBitsPerSample != 8 && mBitsPerSample != 16) {
+            if (mBitsPerSample != 8 && mBitsPerSample != 16
+                && mBitsPerSample != 24) {
                 return ERROR_UNSUPPORTED;
             }
 
@@ -329,6 +330,24 @@
 
         buffer->release();
         buffer = tmp;
+    } else if (mBitsPerSample == 24) {
+        // Convert 24-bit signed samples to 16-bit signed.
+
+        const uint8_t *src =
+            (const uint8_t *)buffer->data() + buffer->range_offset();
+        int16_t *dst = (int16_t *)src;
+
+        size_t numSamples = buffer->range_length() / 3;
+        for (size_t i = 0; i < numSamples; ++i) {
+            int32_t x = (int32_t)(src[0] | src[1] << 8 | src[2] << 16);
+            x = (x << 8) >> 8;  // sign extension
+
+            x = x >> 8;
+            *dst++ = (int16_t)x;
+            src += 3;
+        }
+
+        buffer->set_range(buffer->range_offset(), 2 * numSamples);
     }
 
     size_t bytesPerSample = mBitsPerSample >> 3;
diff --git a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp b/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
index 36272ea..aa2a3d1 100644
--- a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
+++ b/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
@@ -322,8 +322,10 @@
                 crop_top = crop_left = 0;
             }
 
-            mFormat->setInt32(kKeyWidth, crop_right - crop_left + 1);
-            mFormat->setInt32(kKeyHeight, crop_bottom - crop_top + 1);
+            int32_t aligned_width = (crop_right - crop_left + 1 + 15) & ~15;
+            int32_t aligned_height = (crop_bottom - crop_top + 1 + 15) & ~15;
+            mFormat->setInt32(kKeyWidth, aligned_width);
+            mFormat->setInt32(kKeyHeight, aligned_height);
 
             mInputBuffer->release();
             mInputBuffer = NULL;