VT: DSCP implementation.

[Problem] dscp value needs to be updated based on operator's
  requirement. but there is no interface to update the dscp value.

[Solution] Implement interface to set dscp value into socket by
  setsockopt(). dscp value will be taking care by upper layer.

Bug: 142345921

Merged-in: I1468a08f64b71db0f12d96b393263b520109be6d
Change-Id: I1468a08f64b71db0f12d96b393263b520109be6d
Signed-off-by: JainishKumar Anghan <jai.anghan@samsung.com>
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 1f2a5bf..1238f6b 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -119,6 +119,7 @@
       mVideoSource(VIDEO_SOURCE_LIST_END),
       mRTPCVOExtMap(-1),
       mRTPCVODegrees(0),
+      mRTPSockDscp(0),
       mRTPSockNetwork(0),
       mLastSeqNo(0),
       mStarted(false),
@@ -878,6 +879,13 @@
     return OK;
 }
 
+status_t StagefrightRecorder::setParamRtpDscp(int32_t dscp) {
+    ALOGV("setParamRtpDscp: %d", dscp);
+
+    mRTPSockDscp = dscp;
+    return OK;
+}
+
 status_t StagefrightRecorder::setSocketNetwork(int64_t networkHandle) {
     ALOGV("setSocketNetwork: %llu", (unsigned long long) networkHandle);
 
@@ -1056,6 +1064,11 @@
         }
     } else if (key == "video-param-request-i-frame") {
         return requestIDRFrame();
+    } else if (key == "rtp-param-set-socket-dscp") {
+        int32_t dscp;
+        if (safe_strtoi32(value.string(), &dscp)) {
+            return setParamRtpDscp(dscp);
+        }
     } else if (key == "rtp-param-set-socket-network") {
         int64_t networkHandle;
         if (safe_strtoi64(value.string(), &networkHandle)) {
@@ -1234,6 +1247,10 @@
                 meta->setInt32(kKeyRtpExtMap, mRTPCVOExtMap);
                 meta->setInt32(kKeyRtpCvoDegrees, mRTPCVODegrees);
             }
+            if (mRTPSockDscp > 0) {
+                meta->setInt32(kKeyRtpDscp, mRTPSockDscp);
+            }
+
             status = mWriter->start(meta.get());
             break;
         }
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index d68f7de..0362edd 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -148,6 +148,7 @@
     int32_t mPayloadType;
     int32_t mRTPCVOExtMap;
     int32_t mRTPCVODegrees;
+    int32_t mRTPSockDscp;
     int64_t mRTPSockNetwork;
     uint32_t mLastSeqNo;
 
@@ -241,6 +242,7 @@
     status_t setParamPayloadType(int32_t payloadType);
     status_t setRTPCVOExtMap(int32_t extmap);
     status_t setRTPCVODegrees(int32_t cvoDegrees);
+    status_t setParamRtpDscp(int32_t dscp);
     status_t setSocketNetwork(int64_t networkHandle);
     status_t requestIDRFrame();
     void clipVideoBitRate();
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
index 9a83a08..6c505ac 100644
--- a/media/libstagefright/include/media/stagefright/MetaDataBase.h
+++ b/media/libstagefright/include/media/stagefright/MetaDataBase.h
@@ -253,6 +253,7 @@
     kKeyPayloadType      = 'pTyp', // int32_t, SDP negotiated payload type.
     kKeyRtpExtMap        = 'extm', // int32_t, rtp extension ID for cvo on RTP protocol.
     kKeyRtpCvoDegrees    = 'cvod', // int32_t, rtp cvo degrees as per 3GPP 26.114.
+    kKeyRtpDscp          = 'dscp', // int32_t, DSCP(Differentiated services codepoint) of RFC 2474.
     kKeySocketNetwork    = 'sNet', // int64_t, socket will be bound to network handle.
 };
 
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index 415220d..309e5cf 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -227,6 +227,10 @@
     if(params->findInt32(kKeyRtpCvoDegrees, &rtpCVODegrees))
         mRTPCVODegrees = rtpCVODegrees;
 
+    int32_t dscp = 0;
+    if(params->findInt32(kKeyRtpDscp, &dscp))
+        updateSocketDscp(dscp);
+
     int64_t sockNetwork = 0;
     if(params->findInt64(kKeySocketNetwork, &sockNetwork))
         updateSocketNetwork(sockNetwork);
@@ -1182,6 +1186,21 @@
     mPayloadType = payloadType;
 }
 
+void ARTPWriter::updateSocketDscp(int32_t dscp) {
+    mRtpLayer3Dscp = dscp << 2;
+
+    /* mRtpLayer3Dscp will be mapped to WMM(Wifi) as per operator's requirement */
+    if (setsockopt(mRTPSocket, IPPROTO_IP, IP_TOS,
+                (int *)&mRtpLayer3Dscp, sizeof(mRtpLayer3Dscp)) < 0) {
+        ALOGE("failed to set dscp on rtpsock. err=%s", strerror(errno));
+    } else {
+        ALOGD("success to set dscp on rtpsock. opt=%d", mRtpLayer3Dscp);
+        setsockopt(mRTCPSocket, IPPROTO_IP, IP_TOS,
+                (int *)&mRtpLayer3Dscp, sizeof(mRtpLayer3Dscp));
+        ALOGD("success to set dscp on rtcpsock. opt=%d", mRtpLayer3Dscp);
+    }
+}
+
 void ARTPWriter::updateSocketNetwork(int64_t socketNetwork) {
     mRTPSockNetwork = (net_handle_t)socketNetwork;
     ALOGI("trying to bind rtp socket(%d) to network(%llu).",
diff --git a/media/libstagefright/rtsp/ARTPWriter.h b/media/libstagefright/rtsp/ARTPWriter.h
index 6045561..f7e2204 100644
--- a/media/libstagefright/rtsp/ARTPWriter.h
+++ b/media/libstagefright/rtsp/ARTPWriter.h
@@ -49,6 +49,7 @@
     virtual status_t pause();
     void updateCVODegrees(int32_t cvoDegrees);
     void updatePayloadType(int32_t payloadType);
+    void updateSocketDscp(int32_t dscp);
     void updateSocketNetwork(int64_t socketNetwork);
     uint32_t getSequenceNum();
 
@@ -94,6 +95,7 @@
     struct sockaddr_in6 mLocalAddr6;
     struct sockaddr_in6 mRTPAddr6;
     struct sockaddr_in6 mRTCPAddr6;
+    int32_t mRtpLayer3Dscp;
     net_handle_t mRTPSockNetwork;
 
     AString mProfileLevel;