7bf67a08f0386dc9b17cc475fe10a1ea5f7decd0
[platform/core/ml/aitt.git] / android / modules / rtsp / src / main / java / com / samsung / android / modules / rtsp / RTSPClient.java
1 /*
2  * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.samsung.android.modules.rtsp;
17
18 import android.net.Uri;
19 import android.util.Log;
20
21 import androidx.annotation.NonNull;
22
23 import com.alexvas.rtsp.RtspClient;
24 import com.alexvas.utils.NetUtils;
25
26 import org.jetbrains.annotations.NotNull;
27 import org.jetbrains.annotations.Nullable;
28
29 import java.net.Socket;
30 import java.util.concurrent.atomic.AtomicBoolean;
31
32 /**
33  * RTSPClient class to implement RTSP client side functionalities
34  */
35 public class RTSPClient {
36     private static final String TAG = "RTSPClient";
37     private static volatile Socket clientSocket;
38     private static final int sdpInfoSize = 30;
39     private static final int socketTimeout = 10000;
40     private String rtspUrl = null;
41     private int height;
42     private int width;
43     private final AtomicBoolean exitFlag;
44     private final ReceiveDataCallback streamCb;
45     private RtspClient mRtspClient;
46     private H264Decoder decoder;
47     private byte[] sps;
48     private byte[] pps;
49
50     /**
51      * Interface to implement DataCallback from RTSP module to RTSP stream
52      */
53     public interface ReceiveDataCallback {
54         void pushData(byte[] frame);
55     }
56
57     /**
58      * Interface to implement socket connection callback
59      */
60     public interface SocketConnectCallback {
61         void socketConnect(Boolean bool);
62     }
63
64     /**
65      * RTSPClient class constructor
66      * @param exitFlag AtomicBoolean flag to exit execution
67      * @param cb callback object to send data to upper layer
68      */
69     public RTSPClient(AtomicBoolean exitFlag, ReceiveDataCallback cb) {
70         this.exitFlag = exitFlag;
71         streamCb = cb;
72     }
73
74     /**
75      * Method to create a client socket for RTSP connection with RTSP server
76      * @param socketCB socket connection callback to notify success/failure of socket creation
77      */
78     public void createClientSocket(SocketConnectCallback socketCB){
79         if (rtspUrl == null || rtspUrl.isEmpty()) {
80             Log.e(TAG, "Failed create client socket: Invalid RTSP URL");
81             return;
82         }
83
84         Uri uri = Uri.parse(rtspUrl);
85         try {
86             Thread thread = new Thread(() -> {
87                 try  {
88                     clientSocket = NetUtils.createSocketAndConnect(uri.getHost(), uri.getPort(), socketTimeout);
89                     if(clientSocket != null)
90                         socketCB.socketConnect(true);
91                 } catch (Exception e) {
92                     socketCB.socketConnect(false);
93                     Log.d(TAG, "Exception in RTSP client socket creation");
94                 }
95             });
96
97             thread.start();
98
99         } catch (Exception e) {
100             Log.e(TAG, "Exception in RTSP client socket creation");
101         }
102     }
103
104     /**
105      * Method to create RtspClient object to access RTSP lib from dependency
106      */
107     public void initRtspClient() {
108
109         RtspClient.RtspClientListener clientListener = new RtspClient.RtspClientListener() {
110             @Override
111             public void onRtspConnecting() {
112                 Log.d(TAG, "Connecting to RTSP server");
113             }
114
115             @Override
116             public void onRtspConnected(@NonNull @NotNull RtspClient.SdpInfo sdpInfo) {
117                 Log.d(TAG, "Connected to RTSP server");
118                 if(sdpInfo.videoTrack != null) {
119                     sps = sdpInfo.videoTrack.sps;
120                     pps = sdpInfo.videoTrack.pps;
121                 }
122             }
123
124             @Override
125             public void onRtspVideoNalUnitReceived(@NonNull @NotNull byte[] bytes, int i, int i1, long l) {
126                 Log.d(TAG, "RTSP video stream callback -- video NAL units received");
127                 if (bytes.length < sdpInfoSize)
128                     decoder.initH264Decoder(sps, pps);
129                 else
130                     decoder.setRawH264Data(bytes);
131             }
132
133             @Override
134             public void onRtspAudioSampleReceived(@NonNull @NotNull byte[] bytes, int i, int i1, long l) {
135                 //TODO : Decode the Audio Nal units (AAC encoded) received using audio decoder
136                 Log.d(TAG, "RTSP audio stream callback");
137             }
138
139             @Override
140             public void onRtspDisconnected() {
141                 decoder.stopDecoder();
142                 Log.d(TAG, "Disconnected from RTSP server");
143             }
144
145             @Override
146             public void onRtspFailedUnauthorized() {
147                 Log.d(TAG, "onRtspFailedUnauthorized");
148             }
149
150             @Override
151             public void onRtspFailed(@androidx.annotation.Nullable @Nullable String s) {
152                 Log.d(TAG, "onRtspFailed");
153             }
154         };
155
156         Uri uri = Uri.parse(rtspUrl);
157
158         decoder = new H264Decoder(streamCb, height, width);
159         mRtspClient = new RtspClient.Builder(clientSocket, uri.toString(), exitFlag, clientListener)
160                 .requestAudio(false)
161                 .requestVideo(true)
162                 .withDebug(true)
163                 .withUserAgent("RTSP sample Client")
164                 .build();
165     }
166
167     /**
168      * Method to start RTSP streaming
169      */
170     public void start() {
171         mRtspClient.execute();
172     }
173
174     /**
175      * Method to stop RTSP streaming
176      */
177     public void stop() {
178         try{
179             NetUtils.closeSocket(clientSocket);
180             decoder.stopDecoder();
181         } catch (Exception E) {
182             Log.e(TAG, "Error closing socket");
183         }
184     }
185
186     /**
187      * Method to set RTSP URL
188      * @param url String for RTSP URL
189      */
190     public void setRtspUrl(String url) {
191         rtspUrl = url;
192     }
193
194     /**
195      * Method to set RTSP frame resolution
196      * @param height Height of the RTSP stream
197      * @param width Width of the RTSP stream
198      */
199     public void setResolution(int height, int width) {
200         this.height = height;
201         this.width = width;
202     }
203 }