RDK Documentation (Open Sourced RDK Components)
rmf_shim.cpp
Go to the documentation of this file.
1 /*
2  * If not stated otherwise in this file or this component's license file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2022 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 /**
21  * @file rmf_shim.cpp
22  * @brief shim for dispatching UVE RMF playback
23  */
24 
25 #include "AampUtils.h"
26 #include "rmf_shim.h"
27 #include "priv_aamp.h"
28 #include <stdlib.h>
29 #include <string.h>
30 #include <pthread.h>
31 #include <signal.h>
32 #include <assert.h>
33 
34 #ifdef USE_CPP_THUNDER_PLUGIN_ACCESS
35 #include <core/core.h>
36 #include <websocket/websocket.h>
37 
38 using namespace std;
39 using namespace WPEFramework;
40 
41 #define RMF_PLUGIN_CALLSIGN "org.rdk.MediaEngineRMF.1"
42 #define APP_ID "MainPlayer"
43 
44 #define RDKSHELL_CALLSIGN "org.rdk.RDKShell.1"
45 
46 RMFGlobalSettings gRMFSettings;
47 
48 void StreamAbstractionAAMP_RMF::onPlayerStatusHandler(const JsonObject& parameters) {
49  std::string message;
50  parameters.ToString(message);
51 
52  JsonObject playerData = parameters[APP_ID].Object();
53  AAMPLOG_WARN( "[RMF_SHIM]Received event : message : %s ", message.c_str());
54 
55 
56  std::string title = parameters["title"].String();
57 
58  if(0 == title.compare("report first video frame"))
59  {
60  if(!tuned){
61  aamp->SendTunedEvent(false);
62  tuned = true;
63  aamp->LogFirstFrame();
64  aamp->LogTuneComplete();
65  }
66  aamp->SetState(eSTATE_PLAYING);
67  }
68 }
69 
70 void StreamAbstractionAAMP_RMF::onPlayerErrorHandler(const JsonObject& parameters) {
71  std::string message;
72  parameters.ToString(message);
73 
74  AAMPLOG_WARN( "[RMF_SHIM]Received error : message : %s ", message.c_str());
75 
76  std::string error_message = parameters["source"].String() + ": " + parameters["title"].String() + "- " + parameters["message"].String();
77  aamp->SendAnomalyEvent(ANOMALY_WARNING, error_message.c_str());
78  aamp->SetState(eSTATE_ERROR);
79 }
80 
81 
82 /**
83  * @brief Initialize a newly created object.
84  */
85 AAMPStatusType StreamAbstractionAAMP_RMF::Init(TuneType tuneType)
86 {
87  AAMPLOG_INFO("[RMF_SHIM]Inside" );
89 
90  tuned = false;
91 
92  aamp->SetContentType("RMF");
93 
94  thunderAccessObj.ActivatePlugin();
95  JsonObject param;
96  JsonObject result;
97  param["source_type"] = "qam";
98  if(false == thunderAccessObj.InvokeJSONRPC("initialize", param, result)) //Note: do not deinitialize unless we're desperate for resources. deinit is sluggish.
99  {
100  AAMPLOG_ERR("Failed to initialize %s plugin.\n", RMF_PLUGIN_CALLSIGN);
101  retval = eAAMPSTATUS_GENERIC_ERROR;
102  }
103  return retval;
104 }
105 
106 /**
107  * @brief StreamAbstractionAAMP_RMF Constructor
108  */
109 StreamAbstractionAAMP_RMF::StreamAbstractionAAMP_RMF(AampLogManager *logObj, class PrivateInstanceAAMP *aamp,double seek_pos, float rate)
110  : StreamAbstractionAAMP(logObj, aamp)
111  , tuned(false),
112  thunderAccessObj(RMF_PLUGIN_CALLSIGN, logObj),
113  thunderRDKShellObj(RDKSHELL_CALLSIGN,logObj)
114 { // STUB
115 }
116 
117 /**
118  * @brief StreamAbstractionAAMP_RMF Distructor
119  */
120 StreamAbstractionAAMP_RMF::~StreamAbstractionAAMP_RMF()
121 {
122  AAMPLOG_INFO("[RMF_SHIM]StreamAbstractionAAMP_RMF Destructor called !! ");
123 }
124 
125 /**
126  * @brief Starts streaming.
127  */
128 void StreamAbstractionAAMP_RMF::Start(void)
129 {
130  std::string url = aamp->GetManifestUrl();
131 
132  AAMPLOG_INFO( "[RMF_SHIM] url : %s ", url.c_str());
133  JsonObject result;
134 
135  //SetPreferredAudioLanguages(); //TODO
136 
137  std::function<void(const WPEFramework::Core::JSON::VariantContainer&)> eventHandler = std::bind(&StreamAbstractionAAMP_RMF::onPlayerStatusHandler, this, std::placeholders::_1);
138  std::function<void(const WPEFramework::Core::JSON::VariantContainer&)> errorHandler = std::bind(&StreamAbstractionAAMP_RMF::onPlayerErrorHandler, this, std::placeholders::_1);
139 
140  if(true != thunderAccessObj.SubscribeEvent(_T("onStatusChanged"), eventHandler))
141  {
142  AAMPLOG_ERR("Failed to register for onStatusChanged notification from RMF plugin.\n");
143  }
144  if(true != thunderAccessObj.SubscribeEvent(_T("onError"), errorHandler))
145  {
146  AAMPLOG_ERR("Failed to register for onError notification from RMF plugin.\n");
147  }
148 
149  JsonObject playParam;
150  playParam["source_type"] = "qam";
151  playParam["identifier"] = url;
152  if(true != thunderAccessObj.InvokeJSONRPC("play", playParam, result))
153  {
154  AAMPLOG_ERR("Failed to play RMF URL %s.\n", url.c_str());
155  }
156 }
157 
158 /**
159  * @brief Stops streaming.
160  */
161 void StreamAbstractionAAMP_RMF::Stop(bool clearChannelData)
162 {
163  /*StreamAbstractionAAMP::Stop is being called twice
164  PrivateInstanceAAMP::Stop calls Stop with clearChannelData set to true
165  PrivateInstanceAAMP::TeardownStream calls Stop with clearChannelData set to false
166  Hence avoiding the Stop with clearChannelData set to false*/
167  if(!clearChannelData)
168  return;
169 
170  JsonObject param;
171  JsonObject result;;
172  if(true != thunderAccessObj.InvokeJSONRPC("stop", param, result))
173  {
174  AAMPLOG_ERR("Failed to stop RMF playback. URL: %s.\n", aamp->GetManifestUrl().c_str());
175  }
176  thunderAccessObj.UnSubscribeEvent(_T("onStatusChanged"));
177  thunderAccessObj.UnSubscribeEvent(_T("onError"));
178  aamp->SetState(eSTATE_STOPPED);
179 }
180 
181 bool StreamAbstractionAAMP_RMF::GetScreenResolution(int & screenWidth, int & screenHeight)
182 {
183  JsonObject param;
184  JsonObject result;
185  bool bRetVal = false;
186 
187  if( thunderRDKShellObj.InvokeJSONRPC("getScreenResolution", param, result) )
188  {
189  screenWidth = result["w"].Number();
190  screenHeight = result["h"].Number();
191  AAMPLOG_INFO( "StreamAbstractionAAMP_RMF: screenWidth:%d screenHeight:%d ",screenWidth, screenHeight);
192  bRetVal = true;
193  }
194  return bRetVal;
195 }
196 
197 /**
198  * @brief SetVideoRectangle sets the position coordinates (x,y) & size (w,h)
199  */
200 void StreamAbstractionAAMP_RMF::SetVideoRectangle(int x, int y, int w, int h)
201 {
202  JsonObject param;
203  JsonObject videoRect;
204  JsonObject result;
205  videoRect["x"] = x;
206  videoRect["y"] = y;
207  videoRect["width"] = w;
208  videoRect["height"] = h;
209 
210  param["video_rectangle"] = videoRect;
211 
212  if(true != thunderAccessObj.InvokeJSONRPC("setVideoRectangle", param, result))
213  {
214  AAMPLOG_ERR("Failed to set video rectangle for URL: %s.\n", aamp->GetManifestUrl().c_str());
215  }
216 }
217 
218 /**
219  * @brief Get the list of available audio tracks
220  */
221 std::vector<AudioTrackInfo> & StreamAbstractionAAMP_RMF::GetAvailableAudioTracks(bool allTrack)
222 {
223  if (mAudioTrackIndex.empty())
224  GetAudioTracks();
225 
226  return mAudioTracks;
227 }
228 
229 /**
230  * @brief Get current audio track
231  */
232 int StreamAbstractionAAMP_RMF::GetAudioTrack()
233 {
234  int index = -1;
235  if (mAudioTrackIndex.empty())
236  GetAudioTracks();
237 
238  if (!mAudioTrackIndex.empty())
239  {
240  for (auto it = mAudioTracks.begin(); it != mAudioTracks.end(); it++)
241  {
242  if (it->index == mAudioTrackIndex)
243  {
244  index = std::distance(mAudioTracks.begin(), it);
245  }
246  }
247  }
248  return index;
249 }
250 
251 /**
252  * @brief Get current audio track
253  */
254 bool StreamAbstractionAAMP_RMF::GetCurrentAudioTrack(AudioTrackInfo &audioTrack)
255 {
256  int index = -1;
257  bool bFound = false;
258  if (mAudioTrackIndex.empty())
259  GetAudioTracks();
260 
261  if (!mAudioTrackIndex.empty())
262  {
263  for (auto it = mAudioTracks.begin(); it != mAudioTracks.end(); it++)
264  {
265  if (it->index == mAudioTrackIndex)
266  {
267  audioTrack = *it;
268  bFound = true;
269  }
270  }
271  }
272  return bFound;
273 }
274 
275 /**
276  * @brief SetPreferredAudioLanguages set the preferred audio language list
277  */
278 void StreamAbstractionAAMP_RMF::SetPreferredAudioLanguages()
279 {
280  JsonObject properties;
281  bool modifiedLang = false;
282  bool modifiedRend = false;
283 
284  if((0 != aamp->preferredLanguagesString.length()) && (aamp->preferredLanguagesString != gRMFSettings.preferredLanguages)){
285  properties["preferredAudioLanguage"] = aamp->preferredLanguagesString.c_str();
286  modifiedLang = true;
287  }
288  if(modifiedLang || modifiedRend)
289  {
290  bool rpcResult = false;
291  JsonObject result;
292  JsonObject param;
293 
294  param["properties"] = properties;
295  //TODO: Pass preferred audio language to MediaEngineRMF. Not currently supported.
296 
297  }
298 }
299 
300 /**
301  * @brief SetAudioTrackByLanguage set the audio language
302  */
303 void StreamAbstractionAAMP_RMF::SetAudioTrackByLanguage(const char* lang)
304 {
305  JsonObject param;
306  JsonObject result;
307  JsonObject properties;
308  int index = -1;
309 
310  if(NULL != lang)
311  {
312  if(mAudioTrackIndex.empty())
313  GetAudioTracks();
314 
315  std::vector<AudioTrackInfo>::iterator itr;
316  for(itr = mAudioTracks.begin(); itr != mAudioTracks.end(); itr++)
317  {
318  if(0 == strcmp(lang, itr->language.c_str()))
319  {
320  index = std::distance(mAudioTracks.begin(), itr);
321  break;
322  }
323  }
324  }
325  if(-1 != index)
326  {
327  SetAudioTrack(index);
328  }
329  return;
330 }
331 
332 /**
333  * @brief GetAudioTracks get the available audio tracks for the selected service / media
334  */
335 void StreamAbstractionAAMP_RMF::GetAudioTracks()
336 {
337  //TODO: coming soon...
338  return;
339 }
340 
341 
342 /**
343  * @brief GetAudioTrackInternal get the primary key for the selected audio
344  */
345 int StreamAbstractionAAMP_RMF::GetAudioTrackInternal()
346 {
347  //TODO: audio track selection support will follow later.
348  return 0;
349 }
350 
351 /**
352  * @brief SetAudioTrack sets a specific audio track
353  */
354 void StreamAbstractionAAMP_RMF::SetAudioTrack(int trackId)
355 {
356  //TODO: audio track selection will follow later.
357 }
358 
359 /**
360  * @brief Get the list of available text tracks
361  */
362 std::vector<TextTrackInfo> & StreamAbstractionAAMP_RMF::GetAvailableTextTracks(bool all)
363 {
364  AAMPLOG_TRACE("[RMF_SHIM]");
365  return mTextTracks;
366 }
367 
368 /**
369  * @brief GetTextTracks get the available text tracks for the selected service / media
370  */
371 void StreamAbstractionAAMP_RMF::GetTextTracks()
372 {
373  //TODO: this is a placeholder. Actual CC support will follow later.
374  return;
375 }
376 
377 /**
378  * @brief Disable Restrictions (unlock) till seconds mentioned
379  */
380 void StreamAbstractionAAMP_RMF::DisableContentRestrictions(long grace, long time, bool eventChange)
381 {
382  //Not supported.
383 }
384 
385 /**
386  * @brief Enable Content Restriction (lock)
387  */
388 void StreamAbstractionAAMP_RMF::EnableContentRestrictions()
389 {
390  //Not supported.
391 }
392 
393 /**
394  * @brief Stub implementation
395  */
396 void StreamAbstractionAAMP_RMF::DumpProfiles(void)
397 { // STUB
398 }
399 
400 /**
401  * @brief Get output format of stream.
402  */
403 void StreamAbstractionAAMP_RMF::GetStreamFormat(StreamOutputFormat &primaryOutputFormat, StreamOutputFormat &audioOutputFormat, StreamOutputFormat &auxAudioOutputFormat, StreamOutputFormat &subtitleOutputFormat)
404 {
405  primaryOutputFormat = FORMAT_INVALID;
406  audioOutputFormat = FORMAT_INVALID;
407  auxAudioOutputFormat = FORMAT_INVALID;
408  subtitleOutputFormat = FORMAT_INVALID;
409 }
410 
411 /**
412  * @brief Return MediaTrack of requested type
413  */
414 MediaTrack* StreamAbstractionAAMP_RMF::GetMediaTrack(TrackType type)
415 { // STUB
416  return NULL;
417 }
418 
419 /**
420  * @brief Get current stream position.
421  */
422 double StreamAbstractionAAMP_RMF::GetStreamPosition()
423 { // STUB
424  return 0.0;
425 }
426 
427 /**
428  * @brief Get stream information of a profile from subclass.
429  */
430 StreamInfo* StreamAbstractionAAMP_RMF::GetStreamInfo(int idx)
431 { // STUB
432  return NULL;
433 }
434 
435 /**
436  * @brief Get PTS of first sample.
437  */
438 double StreamAbstractionAAMP_RMF::GetFirstPTS()
439 { // STUB
440  return 0.0;
441 }
442 
443 /**
444  * @brief Get Start time PTS of first sample.
445  */
446 double StreamAbstractionAAMP_RMF::GetStartTimeOfFirstPTS()
447 { // STUB
448  return 0.0;
449 }
450 
451 /**
452  * @brief Get the Buffered time
453  */
454 double StreamAbstractionAAMP_RMF::GetBufferedDuration()
455 { // STUB
456  return -1.0;
457 }
458 
459 /**
460  * @brief Check if initial Caching is supports
461  */
462 bool StreamAbstractionAAMP_RMF::IsInitialCachingSupported()
463 { // STUB
464  return false;
465 }
466 
467 /**
468  * @brief Get index of profile corresponds to bandwidth
469  */
470 int StreamAbstractionAAMP_RMF::GetBWIndex(long bitrate)
471 { // STUB
472  return 0;
473 }
474 
475 /**
476  * @brief To get the available video bitrates.
477  */
478 std::vector<long> StreamAbstractionAAMP_RMF::GetVideoBitrates(void)
479 { // STUB
480  return std::vector<long>();
481 }
482 
483 /**
484  * @brief Gets Max Bitrate avialable for current playback.
485  */
486 long StreamAbstractionAAMP_RMF::GetMaxBitrate()
487 { // STUB
488  return 0;
489 }
490 
491 /**
492  * @brief To get the available audio bitrates.
493  */
494 std::vector<long> StreamAbstractionAAMP_RMF::GetAudioBitrates(void)
495 { // STUB
496  return std::vector<long>();
497 }
498 
499 /**
500  * @brief To get the available video tracks.
501  */
502 std::vector<StreamInfo*> StreamAbstractionAAMP_RMF::GetAvailableVideoTracks(void)
503 { // STUB
504  return std::vector<StreamInfo*>();
505 }
506 
507 /**
508  * @brief To get the available thumbnail tracks.
509  */
510 std::vector<StreamInfo*> StreamAbstractionAAMP_RMF::GetAvailableThumbnailTracks(void)
511 { // STUB
512  return std::vector<StreamInfo*>();
513 }
514 
515 /**
516  * @brief Function to set thumbnail track for processing
517  */
518 bool StreamAbstractionAAMP_RMF::SetThumbnailTrack(int thumbnailIndex)
519 {
520  (void) thumbnailIndex; /* unused */
521  return false;
522 }
523 
524 /**
525  * @brief To get the available thumbnail tracks.
526  */
527 std::vector<ThumbnailData> StreamAbstractionAAMP_RMF::GetThumbnailRangeData(double start, double end, std::string *baseurl, int *raw_w, int *raw_h, int *width, int *height)
528 {
529  return std::vector<ThumbnailData>();
530 }
531 
532 /**
533  * @brief Stops injecting fragments to StreamSink.
534  */
535 void StreamAbstractionAAMP_RMF::StopInjection(void)
536 { // STUB - discontinuity related
537 }
538 
539 /**
540  * @brief Start injecting fragments to StreamSink.
541  */
542 void StreamAbstractionAAMP_RMF::StartInjection(void)
543 { // STUB - discontinuity related
544 }
545 
546 #endif //USE_CPP_THUNDER_PLUGIN_ACCESS
eSTATE_STOPPED
@ eSTATE_STOPPED
Definition: AampEvent.h:168
StreamOutputFormat
StreamOutputFormat
Media output format.
Definition: main_aamp.h:106
StreamInfo
Structure holding the information of a stream.
Definition: StreamAbstractionAAMP.h:69
AudioTrackInfo
Structure for audio track information Holds information about an audio track in playlist.
Definition: main_aamp.h:178
TuneType
TuneType
Tune Typea.
Definition: priv_aamp.h:190
FORMAT_INVALID
@ FORMAT_INVALID
Definition: main_aamp.h:108
eAAMPSTATUS_GENERIC_ERROR
@ eAAMPSTATUS_GENERIC_ERROR
Definition: priv_aamp.h:209
AampLogManager
AampLogManager Class.
Definition: AampLogManager.h:150
MediaTrack
Base Class for Media Track.
Definition: StreamAbstractionAAMP.h:159
StreamAbstractionAAMP
StreamAbstraction class of AAMP.
Definition: StreamAbstractionAAMP.h:577
eSTATE_ERROR
@ eSTATE_ERROR
Definition: AampEvent.h:170
TrackType
TrackType
Media Track Types.
Definition: StreamAbstractionAAMP.h:48
eAAMPSTATUS_OK
@ eAAMPSTATUS_OK
Definition: priv_aamp.h:207
priv_aamp.h
Private functions and types used internally by AAMP.
AAMPLOG_TRACE
#define AAMPLOG_TRACE(FORMAT,...)
AAMP logging defines, this can be enabled through setLogLevel() as per the need.
Definition: AampLogManager.h:83
PrivateInstanceAAMP
Class representing the AAMP player's private instance, which is not exposed to outside world.
Definition: priv_aamp.h:640
AAMPStatusType
AAMPStatusType
AAMP Function return values.
Definition: priv_aamp.h:205
videoRect
To store video rectangle properties.
Definition: priv_aamp.h:530
eSTATE_PLAYING
@ eSTATE_PLAYING
Definition: AampEvent.h:166
rmf_shim.h
shim for dispatching UVE RMF playback
ANOMALY_WARNING
@ ANOMALY_WARNING
Definition: main_aamp.h:72