VT: SFP: H264: CVO implementation for Rx side

CVO(Coordination of Video Orientation) implemented for H264.

Support Coordination of Video Orientation (CVO) feature that carried in RTP Header extension.
it parses a device degrees(orientation) in RTP extension that remote sent.
(6.2.3 of 3GPP Release 12 TS 26.114)

Once AAVCAssembler parsed a video degress from RTP(CVO) extension,
A native window will be rotated as per parsed video degress.

Bug: 121230209
Change-Id: I802a9e43d9ee54b7970d2541f18fb4af8022336a
Signed-off-by: Byeongjo Park <bjo.park@samsung.com>
Signed-off-by: Kim Sungyeon <sy85.kim@samsung.com>
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 3c4a96b..4d33b4e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2838,28 +2838,34 @@
 }
 
 void NuPlayer::sendIMSRxNotice(const sp<AMessage> &msg) {
-    int32_t notice, payloadType, feedbackType, id, bitrate;
+    int32_t payloadType;
 
-    CHECK(msg->findInt32("IMS-Rx-notice", &notice));
     CHECK(msg->findInt32("payload-type", &payloadType));
-    CHECK(msg->findInt32("feedback-type", &feedbackType));
-    CHECK(msg->findInt32("sender", &id));
 
     Parcel in;
     in.writeInt32(payloadType);
-    in.writeInt32(feedbackType);
-    in.writeInt32(id);
 
     switch (payloadType) {
-        case 205:   // TSFB
+        case NuPlayer::RTPSource::RTCP_TSFB:   // RTCP TSFB
+        case NuPlayer::RTPSource::RTCP_PSFB:   // RTCP PSFB
         {
-            CHECK(msg->findInt32("bit-rate", &bitrate));
-            in.writeInt32(bitrate);
+            int32_t feedbackType, id;
+            CHECK(msg->findInt32("feedback-type", &feedbackType));
+            CHECK(msg->findInt32("sender", &id));
+            in.writeInt32(feedbackType);
+            in.writeInt32(id);
+            if (payloadType == NuPlayer::RTPSource::RTCP_TSFB) {
+                int32_t bitrate;
+                CHECK(msg->findInt32("bit-rate", &bitrate));
+                in.writeInt32(bitrate);
+            }
             break;
         }
-        case 206:   // PSFB
+        case NuPlayer::RTPSource::RTP_CVO:
         {
-            // nothing to do yet
+            int32_t cvo;
+            CHECK(msg->findInt32("cvo", &cvo));
+            in.writeInt32(cvo);
             break;
         }
         default:
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index f734439..8628edc 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -1050,7 +1050,7 @@
         uint32_t flags = 0;
         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
 
-        int32_t eos, csd;
+        int32_t eos, csd, cvo;
         // we do not expect SYNCFRAME for decoder
         if (buffer->meta()->findInt32("eos", &eos) && eos) {
             flags |= MediaCodec::BUFFER_FLAG_EOS;
@@ -1058,6 +1058,24 @@
             flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
         }
 
+        if (buffer->meta()->findInt32("cvo", (int32_t*)&cvo)) {
+            ALOGV("[%s] cvo(%d) found at %lld us", mComponentName.c_str(), cvo, (long long)timeUs);
+            switch (cvo) {
+                case 0:
+                    codecBuffer->meta()->setInt32("cvo", MediaCodec::CVO_DEGREE_0);
+                    break;
+                case 1:
+                    codecBuffer->meta()->setInt32("cvo", MediaCodec::CVO_DEGREE_90);
+                    break;
+                case 2:
+                    codecBuffer->meta()->setInt32("cvo", MediaCodec::CVO_DEGREE_180);
+                    break;
+                case 3:
+                    codecBuffer->meta()->setInt32("cvo", MediaCodec::CVO_DEGREE_270);
+                    break;
+            }
+        }
+
         // Modular DRM
         MediaBufferBase *mediaBuf = NULL;
         NuPlayerDrm::CryptoInfo *cryptInfo = NULL;
diff --git a/media/libmediaplayerservice/nuplayer/RTPSource.cpp b/media/libmediaplayerservice/nuplayer/RTPSource.cpp
index 6f4933c..e9e7d06 100644
--- a/media/libmediaplayerservice/nuplayer/RTPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTPSource.cpp
@@ -44,7 +44,8 @@
       mInPreparationPhase(true),
       mRTPConn(new ARTPConnection),
       mEOSTimeoutAudio(0),
-      mEOSTimeoutVideo(0) {
+      mEOSTimeoutVideo(0),
+      mLastCVOUpdated(-1) {
       ALOGD("RTPSource initialized with rtpParams=%s", rtpParams.string());
 }
 
@@ -92,7 +93,7 @@
         AString sdp;
         ASessionDescription::SDPStringFactory(sdp, info->mLocalIp,
                 info->mIsAudio, info->mLocalPort, info->mPayloadType, info->mAS, info->mCodecName,
-                NULL, info->mWidth, info->mHeight);
+                NULL, info->mWidth, info->mHeight, info->mCVOExtMap);
         ALOGD("RTPSource SDP =>\n%s", sdp.c_str());
 
         sp<ASessionDescription> desc = new ASessionDescription;
@@ -273,7 +274,29 @@
 
     setEOSTimeout(audio, 0);
 
-    return source->dequeueAccessUnit(accessUnit);
+    finalResult = source->dequeueAccessUnit(accessUnit);
+    if (finalResult != OK) {
+        return finalResult;
+    }
+
+    int32_t cvo;
+    if ((*accessUnit) != NULL && (*accessUnit)->meta()->findInt32("cvo", &cvo)) {
+        if (cvo != mLastCVOUpdated) {
+            sp<AMessage> msg = new AMessage();
+            msg->setInt32("payload-type", NuPlayer::RTPSource::RTP_CVO);
+            msg->setInt32("cvo", cvo);
+
+            sp<AMessage> notify = dupNotify();
+            notify->setInt32("what", kWhatIMSRxNotice);
+            notify->setMessage("message", msg);
+            notify->post();
+
+            ALOGV("notify cvo updated (%d)->(%d) to upper layer", mLastCVOUpdated, cvo);
+            mLastCVOUpdated = cvo;
+        }
+    }
+
+    return finalResult;
 }
 
 sp<AnotherPacketSource> NuPlayer::RTPSource::getSource(bool audio) {
@@ -666,6 +689,8 @@
     } else if (key == "rtp-param-time-scale") {
     } else if (key == "rtp-param-self-id") {
         info->mSelfID = atoi(value);
+    } else if (key == "rtp-param-ext-cvo-extmap") {
+        info->mCVOExtMap = atoi(value);
     }
 
     return OK;
diff --git a/media/libmediaplayerservice/nuplayer/RTPSource.h b/media/libmediaplayerservice/nuplayer/RTPSource.h
index 5b26478..85e77c6 100644
--- a/media/libmediaplayerservice/nuplayer/RTPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTPSource.h
@@ -53,6 +53,12 @@
             const sp<AMessage> &notify,
             const String8& rtpParams);
 
+    enum {
+        RTCP_TSFB = 205,
+        RTCP_PSFB = 206,
+        RTP_CVO = 300,
+    };
+
     virtual status_t getBufferingSettings(
             BufferingSettings* buffering /* nonnull */) override;
     virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
@@ -116,6 +122,8 @@
 
         /* Unique ID indicates itself */
         uint32_t mSelfID;
+        /* extmap:<value> for CVO will be set to here */
+        int32_t mCVOExtMap;
 
         /* a copy of TrackInfo in RTSPSource */
         sp<AnotherPacketSource> mSource;
@@ -168,6 +176,7 @@
     int64_t mMediaAnchorUs;
     int64_t mLastMediaTimeUs;
     int64_t mNumAccessUnitsReceived;
+    int32_t mLastCVOUpdated;
     bool mReceivedFirstRTCPPacket;
     bool mReceivedFirstRTPPacket;
     bool mPausing;