• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2022 The Android Open Source Project
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 
17 #include <VideoManager.h>
18 #include <ImsMediaTrace.h>
19 #include <ImsMediaNetworkUtil.h>
20 
21 using namespace android;
22 VideoManager* VideoManager::manager;
23 
VideoManager()24 VideoManager::VideoManager()
25 {
26     mRequestHandler.Init("VIDEO_REQUEST_EVENT");
27     mResponseHandler.Init("VIDEO_RESPONSE_EVENT");
28 }
29 
~VideoManager()30 VideoManager::~VideoManager()
31 {
32     mRequestHandler.Deinit();
33     mResponseHandler.Deinit();
34     manager = nullptr;
35 }
36 
getInstance()37 VideoManager* VideoManager::getInstance()
38 {
39     if (manager == nullptr)
40     {
41         manager = new VideoManager();
42     }
43 
44     return manager;
45 }
46 
getState(int sessionId)47 int VideoManager::getState(int sessionId)
48 {
49     auto session = mSessions.find(sessionId);
50 
51     if (session != mSessions.end())
52     {
53         return (session->second)->getState();
54     }
55     else
56     {
57         return kSessionStateClosed;
58     }
59 }
60 
openSession(const int sessionId,const int rtpFd,const int rtcpFd,VideoConfig * config)61 ImsMediaResult VideoManager::openSession(
62         const int sessionId, const int rtpFd, const int rtcpFd, VideoConfig* config)
63 {
64     IMLOGI1("[openSession] sessionId[%d]", sessionId);
65 
66     if (rtpFd == -1 || rtcpFd == -1)
67     {
68         return RESULT_INVALID_PARAM;
69     }
70 
71     if (!mSessions.count(sessionId))
72     {
73         std::unique_ptr<VideoSession> session(new VideoSession());
74         session->setSessionId(sessionId);
75         session->setLocalEndPoint(rtpFd, rtcpFd);
76 
77         if (session->startGraph(config) != RESULT_SUCCESS)
78         {
79             IMLOGI0("[openSession] startGraph failed");
80         }
81 
82         mSessions.insert(std::make_pair(sessionId, std::move(session)));
83     }
84     else
85     {
86         return RESULT_INVALID_PARAM;
87     }
88 
89     return RESULT_SUCCESS;
90 }
91 
closeSession(const int sessionId)92 ImsMediaResult VideoManager::closeSession(const int sessionId)
93 {
94     IMLOGI1("[closeSession] sessionId[%d]", sessionId);
95 
96     if (mSessions.count(sessionId))
97     {
98         mSessions.erase(sessionId);
99         return RESULT_SUCCESS;
100     }
101 
102     return RESULT_INVALID_PARAM;
103 }
104 
setPreviewSurfaceToSession(const int sessionId,ANativeWindow * surface)105 ImsMediaResult VideoManager::setPreviewSurfaceToSession(const int sessionId, ANativeWindow* surface)
106 {
107     auto session = mSessions.find(sessionId);
108     IMLOGI1("[setPreviewSurfaceToSession] sessionId[%d]", sessionId);
109 
110     if (session != mSessions.end())
111     {
112         return (session->second)->setPreviewSurface(surface);
113     }
114     else
115     {
116         IMLOGE1("[setPreviewSurfaceToSession] no session id[%d]", sessionId);
117         return RESULT_INVALID_PARAM;
118     }
119 }
120 
setDisplaySurfaceToSession(const int sessionId,ANativeWindow * surface)121 ImsMediaResult VideoManager::setDisplaySurfaceToSession(const int sessionId, ANativeWindow* surface)
122 {
123     auto session = mSessions.find(sessionId);
124     IMLOGI1("[setDisplaySurfaceToSession] sessionId[%d]", sessionId);
125 
126     if (session != mSessions.end())
127     {
128         return (session->second)->setDisplaySurface(surface);
129     }
130     else
131     {
132         IMLOGE1("[setDisplaySurfaceToSession] no session id[%d]", sessionId);
133         return RESULT_INVALID_PARAM;
134     }
135 }
136 
modifySession(const int sessionId,VideoConfig * config)137 ImsMediaResult VideoManager::modifySession(const int sessionId, VideoConfig* config)
138 {
139     auto session = mSessions.find(sessionId);
140     IMLOGI1("[modifySession] sessionId[%d]", sessionId);
141 
142     if (session != mSessions.end())
143     {
144         return (session->second)->startGraph(config);
145     }
146     else
147     {
148         IMLOGE1("[modifySession] no session id[%d]", sessionId);
149         return RESULT_INVALID_PARAM;
150     }
151 }
152 
setMediaQualityThreshold(const int sessionId,MediaQualityThreshold * threshold)153 void VideoManager::setMediaQualityThreshold(const int sessionId, MediaQualityThreshold* threshold)
154 {
155     auto session = mSessions.find(sessionId);
156     IMLOGI1("[setMediaQualityThreshold] sessionId[%d]", sessionId);
157 
158     if (session != mSessions.end())
159     {
160         (session->second)->setMediaQualityThreshold(*threshold);
161     }
162     else
163     {
164         IMLOGE1("[setMediaQualityThreshold] no session id[%d]", sessionId);
165     }
166 }
167 
sendMessage(const int sessionId,const android::Parcel & parcel)168 void VideoManager::sendMessage(const int sessionId, const android::Parcel& parcel)
169 {
170     int nMsg = parcel.readInt32();
171     status_t err = NO_ERROR;
172 
173     switch (nMsg)
174     {
175         case kVideoOpenSession:
176         {
177             int rtpFd = parcel.readInt32();
178             int rtcpFd = parcel.readInt32();
179             VideoConfig* config = new VideoConfig();
180             err = config->readFromParcel(&parcel);
181 
182             if (err != NO_ERROR)
183             {
184                 IMLOGE1("[sendMessage] error readFromParcel[%d]", err);
185                 delete config;
186                 config = nullptr;
187             }
188 
189             EventParamOpenSession* param = new EventParamOpenSession(rtpFd, rtcpFd, config);
190             ImsMediaEventHandler::SendEvent(
191                     "VIDEO_REQUEST_EVENT", nMsg, sessionId, reinterpret_cast<uint64_t>(param));
192         }
193         break;
194         case kVideoCloseSession:
195             ImsMediaEventHandler::SendEvent("VIDEO_REQUEST_EVENT", nMsg, sessionId);
196             break;
197         case kVideoModifySession:
198         {
199             VideoConfig* config = new VideoConfig();
200             err = config->readFromParcel(&parcel);
201 
202             if (err != NO_ERROR)
203             {
204                 IMLOGE1("[sendMessage] error readFromParcel[%d]", err);
205             }
206 
207             ImsMediaEventHandler::SendEvent(
208                     "VIDEO_REQUEST_EVENT", nMsg, sessionId, reinterpret_cast<uint64_t>(config));
209         }
210         break;
211         case kVideoSendRtpHeaderExtension:
212             // TO DO
213             break;
214         case kVideoSetMediaQualityThreshold:
215         {
216             MediaQualityThreshold* threshold = new MediaQualityThreshold();
217             threshold->readFromParcel(&parcel);
218             ImsMediaEventHandler::SendEvent(
219                     "VIDEO_REQUEST_EVENT", nMsg, sessionId, reinterpret_cast<uint64_t>(threshold));
220         }
221         break;
222         default:
223             break;
224     }
225 }
226 
setPreviewSurface(const int sessionId,ANativeWindow * surface)227 void VideoManager::setPreviewSurface(const int sessionId, ANativeWindow* surface)
228 {
229     IMLOGI1("[setPreviewSurface] sessionId[%d]", sessionId);
230     ImsMediaEventHandler::SendEvent("VIDEO_REQUEST_EVENT", kVideoSetPreviewSurface, sessionId,
231             reinterpret_cast<uint64_t>(surface));
232 }
233 
setDisplaySurface(const int sessionId,ANativeWindow * surface)234 void VideoManager::setDisplaySurface(const int sessionId, ANativeWindow* surface)
235 {
236     IMLOGI1("[setDisplaySurface] sessionId[%d]", sessionId);
237     ImsMediaEventHandler::SendEvent("VIDEO_REQUEST_EVENT", kVideoSetDisplaySurface, sessionId,
238             reinterpret_cast<uint64_t>(surface));
239 }
240 
SendInternalEvent(uint32_t event,uint64_t sessionId,uint64_t paramA,uint64_t paramB)241 void VideoManager::SendInternalEvent(
242         uint32_t event, uint64_t sessionId, uint64_t paramA, uint64_t paramB)
243 {
244     auto session = mSessions.find(sessionId);
245     IMLOGI1("[SendInternalEvent] sessionId[%d]", sessionId);
246 
247     if (session != mSessions.end())
248     {
249         (session->second)->SendInternalEvent(event, paramA, paramB);
250     }
251     else
252     {
253         IMLOGE1("[SendInternalEvent] no session id[%d]", sessionId);
254     }
255 }
256 
processEvent(uint32_t event,uint64_t sessionId,uint64_t paramA,uint64_t paramB)257 void VideoManager::RequestHandler::processEvent(
258         uint32_t event, uint64_t sessionId, uint64_t paramA, uint64_t paramB)
259 {
260     IMLOGI4("[processEvent] event[%d], sessionId[%d], paramA[%d], paramB[%d]", event, sessionId,
261             paramA, paramB);
262     ImsMediaResult result = RESULT_SUCCESS;
263 
264     switch (event)
265     {
266         case kVideoOpenSession:
267         {
268             EventParamOpenSession* param = reinterpret_cast<EventParamOpenSession*>(paramA);
269 
270             if (param != nullptr)
271             {
272                 VideoConfig* pConfig = reinterpret_cast<VideoConfig*>(param->mConfig);
273                 result = VideoManager::getInstance()->openSession(
274                         static_cast<int>(sessionId), param->rtpFd, param->rtcpFd, pConfig);
275 
276                 if (result == RESULT_SUCCESS)
277                 {
278                     ImsMediaEventHandler::SendEvent(
279                             "VIDEO_RESPONSE_EVENT", kVideoOpenSessionSuccess, sessionId);
280                 }
281                 else
282                 {
283                     ImsMediaEventHandler::SendEvent(
284                             "VIDEO_RESPONSE_EVENT", kVideoOpenSessionFailure, sessionId, result);
285                 }
286 
287                 delete param;
288 
289                 if (pConfig != nullptr)
290                 {
291                     delete pConfig;
292                 }
293             }
294             else
295             {
296                 ImsMediaEventHandler::SendEvent("VIDEO_RESPONSE_EVENT", kVideoOpenSessionFailure,
297                         sessionId, RESULT_INVALID_PARAM);
298             }
299         }
300         break;
301         case kVideoCloseSession:
302             if (VideoManager::getInstance()->closeSession(static_cast<int>(sessionId)) ==
303                     RESULT_SUCCESS)
304             {
305                 ImsMediaEventHandler::SendEvent(
306                         "VIDEO_RESPONSE_EVENT", kVideoSessionClosed, sessionId, 0, 0);
307             }
308             break;
309         case kVideoSetPreviewSurface:
310             VideoManager::getInstance()->setPreviewSurfaceToSession(
311                     static_cast<int>(sessionId), reinterpret_cast<ANativeWindow*>(paramA));
312             break;
313         case kVideoSetDisplaySurface:
314             VideoManager::getInstance()->setDisplaySurfaceToSession(
315                     static_cast<int>(sessionId), reinterpret_cast<ANativeWindow*>(paramA));
316             break;
317         case kVideoModifySession:
318         {
319             VideoConfig* config = reinterpret_cast<VideoConfig*>(paramA);
320             result =
321                     VideoManager::getInstance()->modifySession(static_cast<int>(sessionId), config);
322             ImsMediaEventHandler::SendEvent(
323                     "VIDEO_RESPONSE_EVENT", kVideoModifySessionResponse, sessionId, result, paramA);
324         }
325         break;
326         case kVideoSendRtpHeaderExtension:
327             /** TODO: add implementation */
328             break;
329         case kVideoSetMediaQualityThreshold:
330         {
331             MediaQualityThreshold* threshold = reinterpret_cast<MediaQualityThreshold*>(paramA);
332 
333             if (threshold != nullptr)
334             {
335                 VideoManager::getInstance()->setMediaQualityThreshold(
336                         static_cast<int>(sessionId), threshold);
337                 delete threshold;
338             }
339         }
340         break;
341         case kRequestVideoCvoUpdate:
342         case kRequestVideoBitrateChange:
343         case kRequestVideoIdrFrame:
344         case kRequestVideoSendNack:
345         case kRequestVideoSendPictureLost:
346         case kRequestVideoSendTmmbr:
347         case kRequestVideoSendTmmbn:
348         case kRequestRoundTripTimeDelayUpdate:
349             VideoManager::getInstance()->SendInternalEvent(event, sessionId, paramA, paramB);
350             break;
351         default:
352             break;
353     }
354 }
355 
processEvent(uint32_t event,uint64_t sessionId,uint64_t paramA,uint64_t paramB)356 void VideoManager::ResponseHandler::processEvent(
357         uint32_t event, uint64_t sessionId, uint64_t paramA, uint64_t paramB)
358 {
359     IMLOGI4("[processEvent] event[%d], sessionId[%d], paramA[%d], paramB[%d]", event, sessionId,
360             paramA, paramB);
361     android::Parcel parcel;
362     switch (event)
363     {
364         case kVideoOpenSessionSuccess:
365         case kVideoOpenSessionFailure:
366             parcel.writeInt32(event);
367             parcel.writeInt32(static_cast<int>(sessionId));
368 
369             if (event == kVideoOpenSessionFailure)
370             {
371                 // fail reason
372                 parcel.writeInt32(static_cast<int>(paramA));
373             }
374 
375             VideoManager::getInstance()->sendResponse(sessionId, parcel);
376             break;
377         case kVideoModifySessionResponse:  // fall through
378         {
379             parcel.writeInt32(event);
380             parcel.writeInt32(static_cast<int>(paramA));  // result
381             VideoConfig* config = reinterpret_cast<VideoConfig*>(paramB);
382 
383             if (config != nullptr)
384             {
385                 config->writeToParcel(&parcel);
386                 VideoManager::getInstance()->sendResponse(sessionId, parcel);
387                 delete config;
388             }
389         }
390         break;
391         case kVideoFirstMediaPacketInd:
392             parcel.writeInt32(event);
393             VideoManager::getInstance()->sendResponse(sessionId, parcel);
394             break;
395         case kVideoPeerDimensionChanged:
396             parcel.writeInt32(event);
397             parcel.writeInt32(static_cast<int>(paramA));
398             parcel.writeInt32(static_cast<int>(paramB));
399             VideoManager::getInstance()->sendResponse(sessionId, parcel);
400             break;
401         case kVideoRtpHeaderExtensionInd:
402             // TODO : add implementation
403             break;
404         case kVideoMediaInactivityInd:
405         case kVideoBitrateInd:
406             parcel.writeInt32(event);
407             parcel.writeInt32(static_cast<int>(paramA));
408             VideoManager::getInstance()->sendResponse(sessionId, parcel);
409             break;
410         case kVideoDataUsageInd:
411             parcel.writeInt32(event);
412             parcel.writeInt64(static_cast<int>(paramA));
413             VideoManager::getInstance()->sendResponse(sessionId, parcel);
414             break;
415         case kVideoSessionClosed:
416             parcel.writeInt32(event);
417             parcel.writeInt32(static_cast<int>(sessionId));
418             VideoManager::getInstance()->sendResponse(sessionId, parcel);
419             break;
420         default:
421             break;
422     }
423 }
424