Merge "Disable 10secs forward/backward seeking for rtsp as seek is a very expensive operation there. Decouple the 10sec forward/backward button functionality from seekbar functionality." into gingerbread
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 3662983..0521709 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -76,6 +76,7 @@
         virtual uint32_t    latency() const = 0;
         virtual float       msecsPerFrame() const = 0;
         virtual status_t    getPosition(uint32_t *position) = 0;
+        virtual int         getSessionId() = 0;
 
         // If no callback is specified, use the "write" API below to submit
         // audio data.
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index c6b2efb..cc41e66 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -56,6 +56,7 @@
     mVideoWidth = mVideoHeight = 0;
     mLockThreadId = 0;
     mAudioSessionId = AudioSystem::newAudioSessionId();
+    mSendLevel = 0;
 }
 
 MediaPlayer::~MediaPlayer()
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index d975cb9..c43e9bb 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1546,6 +1546,11 @@
 
 }
 
+int MediaPlayerService::AudioOutput::getSessionId()
+{
+    return mSessionId;
+}
+
 #undef LOG_TAG
 #define LOG_TAG "AudioCache"
 MediaPlayerService::AudioCache::AudioCache(const char* name) :
@@ -1733,4 +1738,9 @@
     p->mSignal.signal();
 }
 
+int MediaPlayerService::AudioCache::getSessionId()
+{
+    return 0;
+}
+
 } // namespace android
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index a967ee2..4492e20 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -77,6 +77,7 @@
         virtual uint32_t        latency() const;
         virtual float           msecsPerFrame() const;
         virtual status_t        getPosition(uint32_t *position);
+        virtual int             getSessionId();
 
         virtual status_t        open(
                 uint32_t sampleRate, int channelCount,
@@ -133,6 +134,7 @@
         virtual uint32_t        latency() const;
         virtual float           msecsPerFrame() const;
         virtual status_t        getPosition(uint32_t *position);
+        virtual int             getSessionId();
 
         virtual status_t        open(
                 uint32_t sampleRate, int channelCount, int format,
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index 71d48b3..c0b1abe 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -15,7 +15,6 @@
  */
 
 #include <media/stagefright/AMRWriter.h>
-
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaDebug.h>
 #include <media/stagefright/MediaDefs.h>
@@ -23,6 +22,8 @@
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/MetaData.h>
 #include <media/mediarecorder.h>
+#include <sys/prctl.h>
+#include <sys/resource.h>
 
 namespace android {
 
@@ -194,6 +195,7 @@
     int64_t maxTimestampUs = 0;
     status_t err = OK;
 
+    prctl(PR_SET_NAME, (unsigned long)"AMRWriter", 0, 0, 0);
     while (!mDone) {
         MediaBuffer *buffer;
         err = mSource->read(&buffer);
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 6d00d7c..e53b0a0 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -20,8 +20,9 @@
 
 #include <arpa/inet.h>
 
-#include <ctype.h>
 #include <pthread.h>
+#include <sys/prctl.h>
+#include <sys/resource.h>
 
 #include <media/stagefright/MPEG4Writer.h>
 #include <media/stagefright/MediaBuffer.h>
@@ -1104,6 +1105,7 @@
 void MPEG4Writer::threadFunc() {
     LOGV("threadFunc");
 
+    prctl(PR_SET_NAME, (unsigned long)"MPEG4Writer", 0, 0, 0);
     while (!mDone) {
         {
             Mutex::Autolock autolock(mLock);
@@ -1632,6 +1634,11 @@
     int64_t previousPausedDurationUs = 0;
     int64_t timestampUs;
 
+    if (mIsAudio) {
+        prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0);
+    } else {
+        prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0);
+    }
     sp<MetaData> meta_data;
 
     mNumSamples = 0;
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index a8f1104..8762d29 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -41,10 +41,12 @@
     br.skipBits(16);
     parseUE(&br);  // seq_parameter_set_id
 
+    unsigned chroma_format_idc = 1;  // 4:2:0 chroma format
+
     if (profile_idc == 100 || profile_idc == 110
             || profile_idc == 122 || profile_idc == 244
             || profile_idc == 44 || profile_idc == 83 || profile_idc == 86) {
-        unsigned chroma_format_idc = parseUE(&br);
+        chroma_format_idc = parseUE(&br);
         if (chroma_format_idc == 3) {
             br.skipBits(1);  // residual_colour_transform_flag
         }
@@ -85,6 +87,41 @@
 
     *height = (2 - frame_mbs_only_flag)
         * (pic_height_in_map_units_minus1 * 16 + 16);
+
+    if (!frame_mbs_only_flag) {
+        br.getBits(1);  // mb_adaptive_frame_field_flag
+    }
+
+    br.getBits(1);  // direct_8x8_inference_flag
+
+    if (br.getBits(1)) {  // frame_cropping_flag
+        unsigned frame_crop_left_offset = parseUE(&br);
+        unsigned frame_crop_right_offset = parseUE(&br);
+        unsigned frame_crop_top_offset = parseUE(&br);
+        unsigned frame_crop_bottom_offset = parseUE(&br);
+
+        unsigned cropUnitX, cropUnitY;
+        if (chroma_format_idc == 0  /* monochrome */) {
+            cropUnitX = 1;
+            cropUnitY = 2 - frame_mbs_only_flag;
+        } else {
+            unsigned subWidthC = (chroma_format_idc == 3) ? 1 : 2;
+            unsigned subHeightC = (chroma_format_idc == 1) ? 2 : 1;
+
+            cropUnitX = subWidthC;
+            cropUnitY = subHeightC * (2 - frame_mbs_only_flag);
+        }
+
+        LOGV("frame_crop = (%u, %u, %u, %u), cropUnitX = %u, cropUnitY = %u",
+             frame_crop_left_offset, frame_crop_right_offset,
+             frame_crop_top_offset, frame_crop_bottom_offset,
+             cropUnitX, cropUnitY);
+
+        *width -=
+            (frame_crop_left_offset + frame_crop_right_offset) * cropUnitX;
+        *height -=
+            (frame_crop_top_offset + frame_crop_bottom_offset) * cropUnitY;
+    }
 }
 
 }  // namespace android
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index a31b2b2..2c9cfd3 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -86,6 +86,7 @@
           mFirstAccessUnitNTP(0),
           mNumAccessUnitsReceived(0),
           mCheckPending(false),
+          mCheckGeneration(0),
           mTryTCPInterleaving(false),
           mReceivedFirstRTCPPacket(false) {
         mNetLooper->setName("rtsp net");
@@ -434,6 +435,13 @@
 
             case 'chek':
             {
+                int32_t generation;
+                CHECK(msg->findInt32("generation", &generation));
+                if (generation != mCheckGeneration) {
+                    // This is an outdated message. Ignore.
+                    break;
+                }
+
                 if (mNumAccessUnitsReceived == 0) {
                     LOGI("stream ended? aborting.");
                     (new AMessage('abor', id()))->post();
@@ -454,12 +462,7 @@
                 }
 
                 ++mNumAccessUnitsReceived;
-
-                if (!mCheckPending) {
-                    mCheckPending = true;
-                    sp<AMessage> check = new AMessage('chek', id());
-                    check->post(kAccessUnitTimeoutUs);
-                }
+                postAccessUnitTimeoutCheck();
 
                 size_t trackIndex;
                 CHECK(msg->findSize("track-index", &trackIndex));
@@ -557,6 +560,11 @@
 
                 mSeekPending = true;
 
+                // Disable the access unit timeout until we resumed
+                // playback again.
+                mCheckPending = true;
+                ++mCheckGeneration;
+
                 AString request = "PAUSE ";
                 request.append(mSessionURL);
                 request.append(" RTSP/1.0\r\n");
@@ -612,6 +620,9 @@
                 LOGI("PLAY completed with result %d (%s)",
                      result, strerror(-result));
 
+                mCheckPending = false;
+                postAccessUnitTimeoutCheck();
+
                 if (result == OK) {
                     sp<RefBase> obj;
                     CHECK(msg->findObject("response", &obj));
@@ -674,6 +685,17 @@
         }
     }
 
+    void postAccessUnitTimeoutCheck() {
+        if (mCheckPending) {
+            return;
+        }
+
+        mCheckPending = true;
+        sp<AMessage> check = new AMessage('chek', id());
+        check->setInt32("generation", mCheckGeneration);
+        check->post(kAccessUnitTimeoutUs);
+    }
+
     static void SplitString(
             const AString &s, const char *separator, List<AString> *items) {
         items->clear();
@@ -783,6 +805,7 @@
     uint64_t mFirstAccessUnitNTP;
     int64_t mNumAccessUnitsReceived;
     bool mCheckPending;
+    int32_t mCheckGeneration;
     bool mTryTCPInterleaving;
     bool mReceivedFirstRTCPPacket;