25 #include "AampUtils.h"
34 #ifdef USE_CPP_THUNDER_PLUGIN_ACCESS
36 #include <core/core.h>
37 #include <websocket/websocket.h>
40 using namespace WPEFramework;
43 #ifdef USE_CPP_THUNDER_PLUGIN_ACCESS
45 #define MEDIAPLAYER_CALLSIGN "org.rdk.MediaPlayer.1"
46 #define MEDIASETTINGS_CALLSIGN "org.rdk.MediaSettings.1"
47 #define APP_ID "MainPlayer"
49 #define RDKSHELL_CALLSIGN "org.rdk.RDKShell.1"
53 void StreamAbstractionAAMP_OTA::onPlayerStatusHandler(
const JsonObject& parameters) {
55 parameters.ToString(message);
57 JsonObject playerData = parameters[APP_ID].Object();
58 AAMPLOG_TRACE(
"[OTA_SHIM]Received event : message : %s ", message.c_str());
62 std::string currState = playerData[
"playerStatus"].String();
63 bool blockedReasonChanged =
false;
64 std::string reason(
"");
65 if(0 == currState.compare(
"BLOCKED"))
67 reason = playerData[
"blockedReason"].String();
68 if(0 != reason.compare(prevBlockedReason))
70 blockedReasonChanged =
true;
74 if(0 != prevState.compare(currState) || blockedReasonChanged)
77 prevBlockedReason.clear();
78 AAMPLOG_WARN(
"[OTA_SHIM] State changed from %s to %s ", prevState.c_str(), currState.c_str());
79 prevState = currState;
80 if(0 == currState.compare(
"PENDING"))
83 }
else if((0 == currState.compare(
"BLOCKED")) && (0 != reason.compare(
"NOT_BLOCKED")))
85 std::string ratingString;
86 JsonObject ratingObj = playerData[
"rating"].Object();
87 ratingObj.ToString(ratingString);
88 AAMPLOG_WARN(
"[OTA_SHIM] Received BLOCKED event from player with REASON: %s Current Ratings: %s", reason.c_str(), ratingString.c_str());
90 aamp->SendAnomalyEvent(
ANOMALY_WARNING,
"BLOCKED REASON:%s", reason.c_str());
91 aamp->SendBlockedEvent(reason);
93 prevBlockedReason = reason;
94 }
else if(0 == currState.compare(
"PLAYING"))
97 aamp->SendTunedEvent(
false);
102 aamp->LogFirstFrame();
103 aamp->LogTuneComplete();
105 std::string ratingString;
106 JsonObject ratingObj = playerData[
"rating"].Object();
107 ratingObj.ToString(ratingString);
108 AAMPLOG_WARN(
"[OTA_SHIM] PLAYING STATE Current Ratings : %s", ratingString.c_str());
110 }
else if(0 == currState.compare(
"DONE"))
118 if(0 == currState.compare(
"IDLE"))
123 AAMPLOG_INFO(
"[OTA_SHIM] Unsupported state change!");
128 aamp->SetState(state);
131 if((0 == currState.compare(
"PLAYING")) || (0 == currState.compare(
"BLOCKED")) && 0 == reason.compare(
"SERVICE_PIN_LOCKED"))
133 if(PopulateMetaData(playerData))
135 SendMediaMetadataEvent();
139 if( (miPrevmiVideoWidth != miVideoWidth) || (miPrevmiVideoHeight != miVideoHeight) )
141 miPrevmiVideoWidth = miVideoWidth;
142 miPrevmiVideoHeight = miVideoHeight;
143 aamp->NotifyBitRateChangeEvent(mVideoBitrate, eAAMP_BITRATE_CHANGE_BY_OTA, miVideoWidth, miVideoHeight, mFrameRate, 0,
false, mVideoScanType, mAspectRatioWidth, mAspectRatioHeight);
153 bool StreamAbstractionAAMP_OTA::PopulateMetaData(
const JsonObject& playerData)
155 bool isDataChanged =
false;
156 std::string ratingString;
157 JsonObject ratingObj = playerData[
"rating"].Object();
158 ratingObj.ToString(ratingString);
160 if( mPCRating != ratingString )
162 AAMPLOG_INFO(
"[OTA_SHIM]ratings changed : old:%s new:%s ", mPCRating.c_str(), ratingString.c_str());
163 mPCRating = ratingString;
164 isDataChanged =
true;
167 int tempSSI = playerData[
"ssi"].Number();
171 AAMPLOG_INFO(
"[OTA_SHIM]SSI changed : old:%d new:%d ", mSsi, tempSSI);
173 isDataChanged =
true;
177 JsonObject videoInfoObj = playerData[
"videoInfo"].Object();
180 if(mVideoScanType != tempScanType)
182 AAMPLOG_INFO(
"[OTA_SHIM]Scan type changed : old:%d new:%d ", mVideoScanType, tempScanType);
183 isDataChanged =
true;
184 mVideoScanType = tempScanType;
187 float tempframeRate = 0.0;
188 float frameRateN =
static_cast<float> (videoInfoObj[
"frameRateN"].Number());
189 float frameRateD =
static_cast<float> (videoInfoObj[
"frameRateD"].Number());
190 if((0 != frameRateN) && (0 != frameRateD))
192 tempframeRate = frameRateN / frameRateD;
194 if( mFrameRate != tempframeRate)
196 AAMPLOG_INFO(
"[OTA_SHIM] mFrameRate changed : old:%f new:%f ", mFrameRate, tempframeRate);
197 isDataChanged =
true;
198 mFrameRate = tempframeRate;
202 int tempAspectRatioWidth = videoInfoObj[
"aspectRatioWidth"].Number();
203 if( tempAspectRatioWidth != mAspectRatioWidth)
205 isDataChanged =
true;
206 AAMPLOG_INFO(
"[OTA_SHIM] mAspectRatioWidth changed : old:%d new:%d ", mAspectRatioWidth, tempAspectRatioWidth);
207 mAspectRatioWidth = tempAspectRatioWidth;
210 int tempAspectRatioHeight = videoInfoObj[
"aspectRatioHeight"].Number();
211 if( mAspectRatioHeight != tempAspectRatioHeight)
213 AAMPLOG_INFO(
"[OTA_SHIM] tempAspectRatioHeight : old:%d new:%d ", mAspectRatioHeight, tempAspectRatioHeight);
214 isDataChanged =
true;
215 mAspectRatioHeight = tempAspectRatioHeight;
218 int tempVideoWidth = videoInfoObj[
"width"].Number();
219 if( miVideoWidth != tempVideoWidth)
221 AAMPLOG_INFO(
"[OTA_SHIM] miVideoWidth : old:%d new:%d ", miVideoWidth, tempVideoWidth);
222 miVideoWidth = tempVideoWidth;
223 isDataChanged =
true;
226 int tempVideoHeight = videoInfoObj[
"height"].Number();
227 if( miVideoHeight != tempVideoHeight)
229 AAMPLOG_INFO(
"[OTA_SHIM] miVideoHeight : old:%d new:%d ", miVideoHeight, tempVideoHeight);
230 miVideoHeight = tempVideoHeight;
231 isDataChanged =
true;
234 std::string tempVideoCodec = videoInfoObj[
"codec"].String();
235 if(0 != mVideoCodec.compare(tempVideoCodec))
237 AAMPLOG_INFO(
"[OTA_SHIM] mVideoCodec : old:%s new:%s ", mVideoCodec.c_str(), tempVideoCodec.c_str());
238 mVideoCodec = tempVideoCodec;
239 isDataChanged =
true;
242 mHdrType = videoInfoObj[
"hdrType"].String();
245 JsonObject audioInfoObj = playerData[
"audioInfo"].Object();
247 std::string tempAudioCodec = audioInfoObj[
"codec"].String();
248 if(0 != mAudioCodec.compare(tempAudioCodec))
250 AAMPLOG_INFO(
"[OTA_SHIM] tempAudioCodec : old:%s new:%s ", mAudioCodec.c_str(), mAudioCodec.c_str());
251 mAudioCodec = tempAudioCodec;
252 isDataChanged =
true;
255 std::string tempAudioMixType = audioInfoObj[
"mixType"].String();
256 if(0 != mAudioMixType.compare(tempAudioMixType))
258 AAMPLOG_INFO(
"[OTA_SHIM] tempAudioMixType : old:%s new:%s ", mAudioMixType.c_str(), tempAudioMixType.c_str());
259 mAudioMixType = tempAudioMixType;
260 isDataChanged =
true;
263 bool tempIsAtmos = audioInfoObj[
"isAtmos"].Boolean();
265 if( mIsAtmos != tempIsAtmos)
267 AAMPLOG_INFO(
"[OTA_SHIM] -- mIsAtmos : old:%d new:%d ", mIsAtmos, tempIsAtmos);
268 mIsAtmos = tempIsAtmos;
269 isDataChanged =
true;
274 mVideoBitrate = videoInfoObj[
"bitrate"].Number();
275 mAudioBitrate = audioInfoObj[
"bitrate"].Number();
278 return isDataChanged;
282 void StreamAbstractionAAMP_OTA::SendMediaMetadataEvent()
286 MediaMetadataEventPtr
event = std::make_shared<MediaMetadataEvent>(-1, miVideoWidth, miVideoHeight,
false,
true,
"", -1);
289 event->addBitrate(mVideoBitrate);
290 event->addSupportedSpeed(1);
291 event->SetVideoMetaData(mFrameRate,mVideoScanType,mAspectRatioWidth,mAspectRatioHeight, mVideoCodec, mHdrType, mPCRating,mSsi);
292 event->SetAudioMetaData(mAudioCodec,mAudioMixType,mIsAtmos);
293 event->addAudioBitrate(mAudioBitrate);
305 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
306 AAMPLOG_WARN(
"[OTA_SHIM]Inside CURL ACCESS" );
309 AAMPLOG_INFO(
"[OTA_SHIM]Inside" );
315 miPrevmiVideoWidth = 0;
316 miPrevmiVideoHeight = 0;
318 prevBlockedReason =
"";
321 aamp->SetContentType(
"OTA");
323 thunderAccessObj.ActivatePlugin();
324 mediaSettingsObj.ActivatePlugin();
325 std::function<void(
const WPEFramework::Core::JSON::VariantContainer&)> actualMethod = std::bind(&StreamAbstractionAAMP_OTA::onPlayerStatusHandler,
this, std::placeholders::_1);
328 mEventSubscribed = thunderAccessObj.SubscribeEvent(_T(
"onPlayerStatus"), actualMethod);
344 #ifdef USE_CPP_THUNDER_PLUGIN_ACCESS
345 , tuned(false),mEventSubscribed(false),
346 thunderAccessObj(MEDIAPLAYER_CALLSIGN, logObj),
347 mediaSettingsObj(MEDIASETTINGS_CALLSIGN, logObj),
348 thunderRDKShellObj(RDKSHELL_CALLSIGN,logObj),
349 mPCRating(),mSsi(-1),mFrameRate(0),mVideoScanType(
eVIDEOSCAN_UNKNOWN),mAspectRatioWidth(0),mAspectRatioHeight(0),
350 mVideoCodec(),mHdrType(),mAudioBitrate(0),mAudioCodec(),mAudioMixType(),mIsAtmos(false),
351 miVideoWidth(0),miVideoHeight(0),miPrevmiVideoWidth(0),miPrevmiVideoHeight(0)
361 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
366 std::string
id =
"3";
367 std:: string response =
aamp_PostJsonRPC(
id,
"org.rdk.MediaPlayer.1.release",
"{\"id\":\"MainPlayer\",\"tag\" : \"MyApp\"}");
368 AAMPLOG_WARN(
"StreamAbstractionAAMP_OTA: response '%s'", response.c_str());
372 param[
"id"] = APP_ID;
373 param[
"tag"] =
"MyApp";
374 thunderAccessObj.InvokeJSONRPC(
"release", param, result);
377 if (mEventSubscribed)
379 thunderAccessObj.UnSubscribeEvent(_T(
"onPlayerStatus"));
380 mEventSubscribed =
false;
384 AAMPLOG_WARN(
"[OTA_SHIM]OTA Destructor finds Player Status Event not Subscribed !! ");
387 AAMPLOG_INFO(
"[OTA_SHIM]StreamAbstractionAAMP_OTA Destructor called !! ");
396 std::string
id =
"3";
397 std::string response;
398 const char *display = getenv(
"WAYLAND_DISPLAY");
399 std::string waylandDisplay;
402 waylandDisplay = display;
403 AAMPLOG_WARN(
"WAYLAND_DISPLAY: '%s'", display );
407 AAMPLOG_WARN(
"WAYLAND_DISPLAY: NULL!" );
410 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
411 AAMPLOG_WARN(
"[OTA_SHIM]Inside CURL ACCESS");
416 response =
aamp_PostJsonRPC(
id,
"Controller.1.activate",
"{\"callsign\":\"org.rdk.MediaPlayer\"}" );
417 AAMPLOG_WARN(
"StreamAbstractionAAMP_OTA: response '%s'", response.c_str());
423 response =
aamp_PostJsonRPC(
id,
"org.rdk.MediaPlayer.1.create",
"{\"id\":\"MainPlayer\",\"tag\":\"MyApp\"}");
424 AAMPLOG_WARN(
"StreamAbstractionAAMP_OTA: response '%s'", response.c_str());
431 response =
aamp_PostJsonRPC(
id,
"org.rdk.MediaPlayer.1.setWaylandDisplay",
"{\"id\":\"MainPlayer\",\"display\":\"" + waylandDisplay +
"\"}" );
432 AAMPLOG_WARN(
"StreamAbstractionAAMP_OTA: response '%s'", response.c_str());
438 response =
aamp_PostJsonRPC(
id,
"org.rdk.MediaPlayer.1.load",
"{\"id\":\"MainPlayer\",\"url\":\""+url+
"\",\"autoplay\":true}" );
439 AAMPLOG_WARN(
"StreamAbstractionAAMP_OTA: response '%s'", response.c_str());
451 AAMPLOG_INFO(
"[OTA_SHIM] url : %s ", url.c_str());
456 JsonObject createParam;
457 createParam[
"id"] = APP_ID;
458 createParam[
"tag"] =
"MyApp";
459 thunderAccessObj.InvokeJSONRPC(
"create", createParam, result);
461 JsonObject displayParam;
462 displayParam[
"id"] = APP_ID;
463 displayParam[
"display"] = waylandDisplay;
464 thunderAccessObj.InvokeJSONRPC(
"setWaylandDisplay", displayParam, result);
466 JsonObject loadParam;
467 loadParam[
"id"] = APP_ID;
468 loadParam[
"url"] = url;
469 loadParam[
"autoplay"] =
true;
470 thunderAccessObj.InvokeJSONRPC(
"load", loadParam, result);
488 if(!clearChannelData)
491 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
496 std::string
id =
"3";
497 std::string response =
aamp_PostJsonRPC(
id,
"org.rdk.MediaPlayer.1.stop",
"{\"id\":\"MainPlayer\"}");
498 AAMPLOG_WARN(
"StreamAbstractionAAMP_OTA: response '%s'", response.c_str());
502 param[
"id"] = APP_ID;
503 thunderAccessObj.InvokeJSONRPC(
"stop", param, result);
507 #ifdef USE_CPP_THUNDER_PLUGIN_ACCESS
509 bool StreamAbstractionAAMP_OTA::GetScreenResolution(
int & screenWidth,
int & screenHeight)
513 bool bRetVal =
false;
515 if( thunderRDKShellObj.InvokeJSONRPC(
"getScreenResolution", param, result) )
517 screenWidth = result[
"w"].Number();
518 screenHeight = result[
"h"].Number();
519 AAMPLOG_INFO(
"StreamAbstractionAAMP_OTA: screenWidth:%d screenHeight:%d ",screenWidth, screenHeight);
531 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
536 std::string
id =
"3";
537 std::string response =
aamp_PostJsonRPC(
id,
"org.rdk.MediaPlayer.1.setVideoRectangle",
"{\"id\":\"MainPlayer\", \"x\":" + to_string(x) +
", \"y\":" + to_string(y) +
", \"w\":" + to_string(w) +
", \"h\":" + std::to_string(h) +
"}");
538 AAMPLOG_WARN(
"StreamAbstractionAAMP_OTA: response '%s'", response.c_str());
542 param[
"id"] = APP_ID;
548 int screenHeight = 0;
549 if(GetScreenResolution(screenWidth,screenHeight))
552 meta[
"resWidth"] = screenWidth;
553 meta[
"resHeight"] = screenHeight;
554 param[
"meta"] = meta;
557 thunderAccessObj.InvokeJSONRPC(
"setVideoRectangle", param, result);
636 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
638 JsonObject properties;
639 bool modifiedLang =
false;
640 bool modifiedRend =
false;
650 properties[
"visuallyImpaired"] =
true;
653 properties[
"visuallyImpaired"] =
false;
659 if(modifiedLang || modifiedRend)
661 bool rpcResult =
false;
665 param[
"properties"] = properties;
666 rpcResult = mediaSettingsObj.InvokeJSONRPC(
"setProperties", param, result);
668 if (!result[
"success"].Boolean()){
669 std::string responseStr;
670 result.ToString(responseStr);
671 AAMPLOG_WARN(
"[OTA_SHIM] setProperties API failed result:%s", responseStr.c_str());
673 std::string paramStr;
674 param.ToString(paramStr);
675 AAMPLOG_WARN(
"[OTA_SHIM] setProperties success with param:%s", paramStr.c_str());
694 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
698 JsonObject properties;
706 std::vector<AudioTrackInfo>::iterator itr;
709 if(0 == strcmp(lang, itr->language.c_str()))
729 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
733 JsonArray attributesArray;
734 std::vector<AudioTrackInfo> aTracks;
735 std::string aTrackIdx =
"";
738 JsonArray outputArray;
739 JsonObject audioData;
740 int i = 0,arrayCount = 0;
742 int currentTrackPk = 0;
746 attributesArray.Add(
"pk");
747 attributesArray.Add(
"name");
748 attributesArray.Add(
"type");
749 attributesArray.Add(
"description");
750 attributesArray.Add(
"language");
751 attributesArray.Add(
"contentType");
752 attributesArray.Add(
"mixType");
753 attributesArray.Add(
"isSelected");
755 param[
"id"] = APP_ID;
756 param[
"attributes"] = attributesArray;
758 thunderAccessObj.InvokeJSONRPC(
"getAudioTracks", param, result);
760 result.ToString(output);
761 AAMPLOG_TRACE(
"[OTA_SHIM]:audio track output : %s ", output.c_str());
762 outputArray = result[
"table"].Array();
763 arrayCount = outputArray.Length();
765 for(i = 0; i < arrayCount; i++)
767 index = to_string(i);
768 audioData = outputArray[i].Object();
770 if(currentTrackPk == audioData[
"pk"].Number()){
771 aTrackIdx = to_string(i);
774 std::string languageCode;
776 aTracks.push_back(
AudioTrackInfo(index, languageCode, audioData[
"contentType"].String(), audioData[
"name"].String(), audioData[
"type"].String(), (
int)audioData[
"pk"].Number(), audioData[
"contentType"].String(), audioData[
"mixType"].String() ));
791 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
799 param[
"id"] = APP_ID;
800 thunderAccessObj.InvokeJSONRPC(
"getAudioTrack", param, result);
801 pk = result[
"pk"].Number();
811 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
816 param[
"id"] = APP_ID;
820 thunderAccessObj.InvokeJSONRPC(
"setAudioTrack", param, result);
821 if (result[
"success"].Boolean()) {
846 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
850 JsonArray attributesArray;
851 std::vector<TextTrackInfo> txtTracks;
853 JsonArray outputArray;
857 attributesArray.Add(
"pk");
858 attributesArray.Add(
"name");
859 attributesArray.Add(
"type");
860 attributesArray.Add(
"description");
861 attributesArray.Add(
"language");
862 attributesArray.Add(
"contentType");
863 attributesArray.Add(
"ccServiceNumber");
864 attributesArray.Add(
"isSelected");
865 attributesArray.Add(
"ccTypeIs708");
866 attributesArray.Add(
"ccType");
868 param[
"id"] = APP_ID;
869 param[
"attributes"] = attributesArray;
871 thunderAccessObj.InvokeJSONRPC(
"getSubtitleTracks", param, result);
873 result.ToString(output);
874 AAMPLOG_TRACE(
"[OTA_SHIM]:text track output : %s ", output.c_str());
875 outputArray = result[
"table"].Array();
876 arrayCount = outputArray.Length();
878 std::string txtTrackIdx =
"";
879 std::string instreamId;
882 for(
int i = 0; i < arrayCount; i++)
884 std::string trackType;
885 textData = outputArray[i].Object();
886 trackType = textData[
"type"].String();
887 if(0 == trackType.compare(
"CC"))
891 std::string index = std::to_string(ccIndex++);
892 std::string serviceNo;
893 int ccServiceNumber = -1;
896 ccServiceNumber = textData[
"ccServiceNumber"].Number();
898 if(textData[
"ccType"].String() == std::string{
"CC708"})
900 if((ccServiceNumber >= 1) && (ccServiceNumber <= 63))
903 serviceNo =
"SERVICE";
904 serviceNo.append(std::to_string(ccServiceNumber));
908 AAMPLOG_WARN(
"[OTA_SHIM]:unexpected text track for 708 CC");
911 else if(textData[
"ccType"].String() == std::string{
"CC608"})
913 if((ccServiceNumber >= 1) && (ccServiceNumber <= 4))
917 serviceNo.append(std::to_string(ccServiceNumber));
921 AAMPLOG_WARN(
"[OTA_SHIM]:unexpected text track for 608 CC");
924 else if(textData[
"ccType"].String() == std::string{
"TEXT"})
926 if((ccServiceNumber >= 1) && (ccServiceNumber <= 4))
930 serviceNo.append(std::to_string(ccServiceNumber));
934 AAMPLOG_WARN(
"[OTA_SHIM]:unexpected text track for TEXT CC");
939 AAMPLOG_WARN(
"[OTA_SHIM]:unexpected ccType: '%s'", textData[
"ccType"].String().c_str());
942 txtTracks.push_back(
TextTrackInfo(index, languageCode,
true, empty, textData[
"name"].String(), serviceNo, empty, (
int)textData[
"pk"].Number()));
944 AAMPLOG_WARN(
"[OTA_SHIM]:: Text Track - index:%s lang:%s, isCC:true, rendition:empty, name:%s, instreamID:%s, characteristics:empty, primarykey:%d", index.c_str(), languageCode.c_str(), textData[
"name"].String().c_str(), serviceNo.c_str(), (
int)textData[
"pk"].Number());
948 if (txtTracks.empty())
954 txtTracks.push_back(
TextTrackInfo(
"0",
"und",
true, empty,
"Undetermined",
"CC1", empty, 0 ));
967 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
971 param[
"id"] = APP_ID;
976 param[
"eventChange"] =
false;
977 AAMPLOG_WARN(
"[OTA_SHIM] unlocked till next reboot or explicit enable" );
980 param[
"time"] = time;
981 param[
"eventChange"] = eventChange;
984 AAMPLOG_WARN(
"[OTA_SHIM] unlocked for %ld sec ", time);
987 AAMPLOG_WARN(
"[OTA_SHIM] unlocked till next program ");
989 thunderAccessObj.InvokeJSONRPC(
"disableContentRestrictionsUntil", param, result);
999 #ifndef USE_CPP_THUNDER_PLUGIN_ACCESS
1001 AAMPLOG_WARN(
"[OTA_SHIM] locked ");
1004 param[
"id"] = APP_ID;
1005 thunderAccessObj.InvokeJSONRPC(
"enableContentRestrictions", param, result);
1097 return std::vector<long>();
1113 return std::vector<long>();
1121 return std::vector<StreamInfo*>();
1129 return std::vector<StreamInfo*>();
1137 (void) thumbnailIndex;
1146 return std::vector<ThumbnailData>();