Set id and password correctly to Android RTSP module
[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     // TODO: Set sdpInfoSize properly without a hard-coded value.
39     private static final int sdpInfoSize = 35;
40     private static final int socketTimeout = 10000;
41     private String rtspUrl = null;
42     private int height;
43     private int width;
44     private final AtomicBoolean exitFlag;
45     private final ReceiveDataCallback streamCb;
46     private RtspClient mRtspClient;
47     private H264Decoder decoder;
48     private byte[] sps;
49     private byte[] pps;
50
51     /**
52      * Interface to implement DataCallback from RTSP module to RTSP stream
53      */
54     public interface ReceiveDataCallback {
55         void pushData(byte[] frame);
56     }
57
58     /**
59      * Interface to implement socket connection callback
60      */
61     public interface SocketConnectCallback {
62         void socketConnect(Boolean bool);
63     }
64
65     /**
66      * RTSPClient class constructor
67      *
68      * @param exitFlag AtomicBoolean flag to exit execution
69      * @param cb       callback object to send data to upper layer
70      */
71     public RTSPClient(AtomicBoolean exitFlag, ReceiveDataCallback cb) {
72         this.exitFlag = exitFlag;
73         streamCb = cb;
74     }
75
76     /**
77      * Method to create a client socket for RTSP connection with RTSP server
78      *
79      * @param socketCB socket connection callback to notify success/failure of socket creation
80      */
81     public void createClientSocket(SocketConnectCallback socketCB) {
82         if (rtspUrl == null || rtspUrl.isEmpty()) {
83             Log.e(TAG, "Failed create client socket: Invalid RTSP URL");
84             return;
85         }
86
87         Uri uri = Uri.parse(rtspUrl);
88         try {
89             Thread thread = new Thread(() -> {
90                 try {
91                     clientSocket = NetUtils.createSocketAndConnect(uri.getHost(), uri.getPort(), socketTimeout);
92                     if (clientSocket != null)
93                         socketCB.socketConnect(true);
94                 } catch (Exception e) {
95                     socketCB.socketConnect(false);
96                     Log.e(TAG, "Exception in RTSP client socket creation");
97                 }
98             });
99
100             thread.start();
101
102         } catch (Exception e) {
103             Log.e(TAG, "Exception in RTSP client socket creation");
104         }
105     }
106
107     /**
108      * Method to create RtspClient object to access RTSP lib from dependency
109      */
110     public void initRtspClient(String id, String password) {
111
112         RtspClient.RtspClientListener clientListener = new RtspClient.RtspClientListener() {
113             @Override
114             public void onRtspConnecting() {
115                 Log.d(TAG, "Connecting to RTSP server");
116             }
117
118             @Override
119             public void onRtspConnected(@NonNull @NotNull RtspClient.SdpInfo sdpInfo) {
120                 Log.d(TAG, "Connected to RTSP server");
121                 if (sdpInfo.videoTrack != null) {
122                     sps = sdpInfo.videoTrack.sps;
123                     pps = sdpInfo.videoTrack.pps;
124                 }
125             }
126
127             @Override
128             public void onRtspVideoNalUnitReceived(@NonNull @NotNull byte[] bytes, int i, int i1, long l) {
129                 Log.i(TAG, "RTSP video stream callback -- video NAL units received.  bytes.length = " + bytes.length + ",  sdpInfoSize = " + sdpInfoSize);
130                 if (bytes.length < sdpInfoSize)
131                     decoder.initH264Decoder(sps, pps);
132                 else
133                     decoder.setRawH264Data(bytes);
134             }
135
136             @Override
137             public void onRtspAudioSampleReceived(@NonNull @NotNull byte[] bytes, int i, int i1, long l) {
138                 //TODO : Decode the Audio Nal units (AAC encoded) received using audio decoder
139                 Log.d(TAG, "RTSP audio stream callback");
140             }
141
142             @Override
143             public void onRtspDisconnected() {
144                 decoder.stopDecoder();
145                 Log.d(TAG, "Disconnected from RTSP server");
146             }
147
148             @Override
149             public void onRtspFailedUnauthorized() {
150                 Log.d(TAG, "onRtspFailedUnauthorized");
151             }
152
153             @Override
154             public void onRtspFailed(@androidx.annotation.Nullable @Nullable String s) {
155                 Log.d(TAG, "onRtspFailed");
156             }
157         };
158
159         Uri uri = Uri.parse(rtspUrl);
160
161         decoder = new H264Decoder(streamCb, height, width);
162         if ("".equalsIgnoreCase(id)) {
163             mRtspClient = new RtspClient.Builder(clientSocket, uri.toString(), exitFlag, clientListener)
164                     .requestAudio(false)
165                     .requestVideo(true)
166                     .withDebug(true)
167                     .withUserAgent("RTSP sample Client")
168                     .build();
169         } else {
170             mRtspClient = new RtspClient.Builder(clientSocket, uri.toString(), exitFlag, clientListener)
171                     .requestAudio(false)
172                     .requestVideo(true)
173                     .withCredentials(id, password)
174                     .withDebug(true)
175                     .withUserAgent("RTSP sample Client")
176                     .build();
177         }
178     }
179
180     /**
181      * Method to start RTSP streaming
182      */
183     public void start() {
184         mRtspClient.execute();
185     }
186
187     /**
188      * Method to stop RTSP streaming
189      */
190     public void stop() {
191         try {
192             NetUtils.closeSocket(clientSocket);
193             decoder.stopDecoder();
194         } catch (Exception E) {
195             Log.e(TAG, "Error closing socket");
196         }
197     }
198
199     /**
200      * Method to set RTSP URL
201      *
202      * @param url String for RTSP URL
203      */
204     public void setRtspUrl(String url) {
205         rtspUrl = url;
206     }
207
208     /**
209      * Method to set RTSP frame resolution
210      *
211      * @param height Height of the RTSP stream
212      * @param width  Width of the RTSP stream
213      */
214     public void setResolution(int height, int width) {
215         this.height = height;
216         this.width = width;
217     }
218 }