19 #include "rdkmediaplayer.h"
25 #include "rmfplayer.h"
26 #include "aampplayer.h"
27 #include "rmf_osal_init.h"
41 #define CALL_ON_MAIN_THREAD(body) \
47 [](gpointer data) -> gboolean \
49 RDKMediaPlayer &self = *static_cast<RDKMediaPlayer*>(data); \
50 ReleaseOnScopeEnd releaseOnScopeEnd(self); \
52 return G_SOURCE_REMOVE; \
58 void stringToBool(rtString
const& s,
bool& b)
60 if(s.compare(
"true") == 0)
62 else if(s.compare(
"false") == 0)
68 void boolToString(
bool b, rtString& s)
70 s = b ? rtString(
"true") : rtString(
"false");
94 rtDefineProperty (
RDKMediaPlayer, availableClosedCaptionsLanguages);
112 RDKMediaPlayer::RDKMediaPlayer() :
115 m_vidDecoderHandle(0),
117 m_closedCaptionsEnabled(false),
121 m_closedCaptionsOptions[
"textSize"] =
"";
122 m_closedCaptionsOptions[
"fontStyle"] =
"";
123 m_closedCaptionsOptions[
"textForegroundColor"] =
"";
124 m_closedCaptionsOptions[
"textForegroundOpacity"] =
"";
125 m_closedCaptionsOptions[
"textBackgroundColor"] =
"";
126 m_closedCaptionsOptions[
"textBackgroundOpacity"] =
"";
127 m_closedCaptionsOptions[
"textItalicized"] =
"";
128 m_closedCaptionsOptions[
"textUnderline"] =
"";
129 m_closedCaptionsOptions[
"windowFillColor"] =
"";
130 m_closedCaptionsOptions[
"windowFillOpacity"] =
"";
131 m_closedCaptionsOptions[
"windowBorderEdgeColor"] =
"";
132 m_closedCaptionsOptions[
"windowBorderEdgeStyle"] =
"";
133 m_closedCaptionsOptions[
"textEdgeColor"] =
"";
134 m_closedCaptionsOptions[
"textEdgeStyle"] =
"";
135 m_closedCaptionsOptions[
"fontSize"] =
"";
136 m_audioLanguage =
"en";
137 m_loadStartTime = g_get_monotonic_time();
141 m_videoBufferLength = 0.0f;
143 m_networkBufferSize = 0;
147 m_tsbEnabled =
false;
148 m_isInProgressRecording =
false;
149 m_eissFilterStatus =
false;
150 rmf_osal_init(
"/etc/rmfconfig.ini",
"/etc/debug.ini" );
153 RDKMediaPlayer::~RDKMediaPlayer()
155 LOG_WARNING(
"Destroying RDKMediaPlayer (should almost NEVER happen!)");
158 void RDKMediaPlayer::onInit()
160 LOG_INFO(
"%s\n", __PRETTY_FUNCTION__);
166 s = m_currentURL.c_str();
170 rtError RDKMediaPlayer::startQueuedTune()
172 LOG_INFO(
"enter %s\n", m_currentURL.c_str());
176 if(m_currentURL.size() == 0)
179 if(!m_pImpl || !m_pImpl->doCanPlayURL(m_currentURL))
184 for(std::vector<RDKMediaPlayerImpl*>::iterator it = m_playerCache.begin(); it != m_playerCache.end(); ++it)
186 if( !((*it)->isManagementSession()) && (*it)->doCanPlayURL(m_currentURL) )
194 if(AAMPPlayer::canPlayURL(m_currentURL))
200 if(RMFPlayer::canPlayURL(m_currentURL))
207 LOG_WARNING(
"Unsupported media type!");
212 m_playerCache.push_back(m_pImpl);
216 CALL_ON_MAIN_THREAD (
217 LOG_INFO(
"Tuning player to %s\n",
self.m_currentURL.c_str());
218 self.m_pImpl->setTuneState(TuneStart);
219 self.m_pImpl->doLoad(
self.m_currentURL);
222 self.m_pImpl->doSetVideoRectangle(
self.m_videoRect);
231 m_setURLTime = g_get_monotonic_time();
232 m_currentURL = s.cString();
233 LOG_INFO(
"enter %s\n", m_currentURL.c_str());
236 m_vidDecoderHandle = 0;
240 if(m_pImpl->getTuneState() == TuneStart)
246 else if(m_pImpl->getTuneState() == TuneStop)
248 LOG_INFO(
"waiting on player to stop\n");
252 LOG_INFO(
"calling startQueuedTune");
253 return startQueuedTune();
258 s = m_audioLanguage.c_str();
264 m_audioLanguage = s.cString();
265 LOG_INFO(
"%s %s\n", __PRETTY_FUNCTION__, m_audioLanguage.c_str());
268 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetAudioLanguage(
self.m_audioLanguage););
275 s = m_secondaryAudioLanguage.c_str();
280 m_secondaryAudioLanguage = s.cString();
281 LOG_INFO(
"%s %s\n", __PRETTY_FUNCTION__, m_secondaryAudioLanguage.c_str());
290 m_pImpl->getProgressData(&pd);
300 LOG_INFO(
"%s %f\n", __PRETTY_FUNCTION__, t);
304 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetPosition(
self.m_seekTime););
313 m_pImpl->getProgressData(&pd);
323 LOG_INFO(
"%s %f\n", __PRETTY_FUNCTION__, t);
327 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetSpeed(
self.m_speed););
328 updateClosedCaptionsState();
339 LOG_INFO(
"%s %f\n", __PRETTY_FUNCTION__, t);
343 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetVolume(
self.m_volume););
349 boolToString(m_isBlocked, t);
355 stringToBool(t, m_isBlocked);
356 LOG_INFO(
"%s %d\n", __PRETTY_FUNCTION__, (
int)m_isBlocked);
359 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetBlocked(
self.m_isBlocked););
365 boolToString(m_isInProgressRecording, t);
370 stringToBool(t, m_isInProgressRecording);
371 LOG_INFO(
"%s %d\n", __PRETTY_FUNCTION__, (
int)m_isInProgressRecording);
374 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetIsInProgressRecording(
self.m_isInProgressRecording););
380 t = m_zoom ? rtString(
"NONE") : rtString(
"FULL");
386 if(t.compare(
"FULL")==0)
390 LOG_INFO(
"%s %s=%d\n", __PRETTY_FUNCTION__, t.cString(), m_zoom);
393 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetZoom(
self.m_zoom););
399 t = m_networkBufferSize;
405 LOG_INFO(
"%s %d\n", __PRETTY_FUNCTION__, t);
406 m_networkBufferSize = t;
409 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetNetworkBufferSize(
self.m_networkBufferSize););
415 t = m_videoBufferLength;
420 LOG_INFO(
"%s %f\n", __PRETTY_FUNCTION__, t);
421 m_videoBufferLength = t;
424 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetVideoBufferLength(
self.m_videoBufferLength););
430 boolToString(m_eissFilterStatus, t);
436 stringToBool(t, m_eissFilterStatus);
437 LOG_INFO(
"%s %d\n", __PRETTY_FUNCTION__, (
int)m_eissFilterStatus);
440 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetEISSFilterStatus(
self.m_eissFilterStatus););
452 LOG_INFO(
"%s %lld\n", __PRETTY_FUNCTION__, t);
459 boolToString(m_closedCaptionsEnabled, t);
465 stringToBool(t, m_closedCaptionsEnabled);
466 LOG_INFO(
"%s %d\n", __PRETTY_FUNCTION__, (
int)m_closedCaptionsEnabled);
467 updateClosedCaptionsState();
473 for(std::map<std::string, std::string>::const_iterator it = m_closedCaptionsOptions.begin();
474 it != m_closedCaptionsOptions.end();
477 t.set(it->first.c_str(), rtValue(it->second.c_str()));
484 for(std::map<std::string, std::string>::iterator it = m_closedCaptionsOptions.begin();
485 it != m_closedCaptionsOptions.end();
489 if(t.get(it->first.c_str(), v) == RT_OK)
490 it->second = v.convert<rtString>().cString();
493 for(std::map<std::string, std::string>::iterator it = m_closedCaptionsOptions.begin();
494 it != m_closedCaptionsOptions.end();
497 LOG_INFO(
"%s %s:%s\n", __PRETTY_FUNCTION__, it->first.c_str(), it->second.c_str());
504 t = m_closedCaptionsTrack.c_str();
510 m_closedCaptionsTrack = t.cString();
511 LOG_INFO(
"%s %s\n", __PRETTY_FUNCTION__, m_closedCaptionsTrack.c_str());
517 t = m_contentOptions;
523 m_contentOptions = t;
529 boolToString(m_autoPlay, t);
535 LOG_INFO(
"%s %s\n", __PRETTY_FUNCTION__, t.cString());
536 stringToBool(t, m_autoPlay);
548 t = m_availableAudioLanguages.c_str();
554 t = m_availableClosedCaptionsLanguages.c_str();
560 t = m_availableSpeeds.c_str();
566 boolToString(m_tsbEnabled, t);
572 LOG_INFO(
"%s %s\n", __PRETTY_FUNCTION__, t.cString());
573 stringToBool(t, m_tsbEnabled);
581 LOG_INFO(
"%s %d %d %d %d\n", __PRETTY_FUNCTION__, x, y, w, h);
582 m_videoRect =
IntRect(x,y,w,h);
585 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetVideoRectangle(
self.m_videoRect););
591 LOG_INFO(
"%s\n", __PRETTY_FUNCTION__);
592 m_playStartTime = g_get_monotonic_time();
597 CALL_ON_MAIN_THREAD(
self.m_pImpl->doPlay(););
598 updateClosedCaptionsState();
604 LOG_INFO(
"%s\n", __PRETTY_FUNCTION__);
609 CALL_ON_MAIN_THREAD(
self.m_pImpl->doPause(););
615 LOG_INFO(
"%s\n", __PRETTY_FUNCTION__);
619 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSeekToLive(););
626 LOG_INFO(
"%s\n", __PRETTY_FUNCTION__);
629 if(m_pImpl->getTuneState() == TuneStop)
631 m_pImpl->setTuneState(TuneStop);
635 self.m_vidDecoderHandle = 0;
636 self.updateClosedCaptionsState();
637 self.m_pImpl->doStop();
639 self.m_pImpl->setTuneState(TuneNone);
643 LOG_INFO(
"calling startQueuedTune");
644 self.startQueuedTune();
652 LOG_INFO(
"%s %f %d\n", __PRETTY_FUNCTION__,
speed, overshootTime);
654 m_overshootTime = overshootTime;
657 CALL_ON_MAIN_THREAD(
self.m_pImpl->doChangeSpeed(
self.m_speed,
self.m_overshootTime););
666 m_pImpl->getProgressData(&pd);
667 m_seekTime = pd.position + seconds/1000.0;
670 m_seekTime = 0 + seconds/1000.0;
675 CALL_ON_MAIN_THREAD(
self.m_pImpl->doSetPosition(
self.m_seekTime););
681 LOG_INFO(
"%s\n", __PRETTY_FUNCTION__);
689 LOG_INFO(
"%s\n", __PRETTY_FUNCTION__);
695 return m_eventEmitter.setListener(eventName, f);
700 return m_eventEmitter.delListener(eventName, f);
705 LOG_INFO(
"%s\n", __PRETTY_FUNCTION__);
711 LOG_INFO(
"%s, openData = %s\n", __PRETTY_FUNCTION__, openData.cString());
714 json_t *root = json_loads(openData.cString(), 0, &error);
717 LOG_INFO(
"json error on line %d: %s\n", error.line, error.text);
721 std::string url = json_string_value(json_object_get(root,
"mediaurl"));
722 std::string mode = json_string_value(json_object_get(root,
"mode"));
723 std::string manage = json_string_value(json_object_get(root,
"manage"));
725 if((mode ==
"MODE_NONE") &&
726 (manage ==
"MANAGE_FULL" || manage ==
"MANAGE_NO_PSI" || manage ==
"MANAGE_NO_TUNER"))
728 std::string casocdmid = json_string_value(json_object_get(root,
"casocdmid"));
730 if(casocdmid.empty() || (manage ==
"MANAGE_FULL" && url.empty())) {
731 LOG_INFO(
"ocdmcasid is mandatory for CAS management session or url is empty");
736 for(std::vector<RDKMediaPlayerImpl*>::iterator it = m_playerCache.begin(); it != m_playerCache.end(); ++it)
738 if( (*it)->isManagementSession() )
750 m_playerCache.push_back(m_pImpl);
751 if(manage ==
"MANAGE_FULL") {
754 std::string data = openData.cString();
755 #ifdef USE_EXTERNAL_CAS
757 ((
RMFPlayer *)m_pImpl)->registerCASData();
762 LOG_INFO(
"CAS Managment session is already avialable");
764 resp = (std::to_string((uintptr_t)m_pImpl)).c_str();
765 LOG_INFO(
"resp = %x", resp.cString());
768 else if ((mode ==
"MODE_LIVE" || mode ==
"MODE_PLAYBACK") && manage ==
"MANAGE_NONE") {
771 LOG_INFO(
"MediaUrl is mandatory when ModeType is LIVE, PLAYBACK");
776 std::string data = openData.cString();
777 #ifdef USE_EXTERNAL_CAS
780 for(std::vector<RDKMediaPlayerImpl*>::iterator it = m_playerCache.begin(); it != m_playerCache.end(); ++it)
782 if( !((*it)->isManagementSession()) && (*it)->doCanPlayURL(m_currentURL) )
785 resp = (std::to_string((uintptr_t)*it)).c_str();
786 LOG_INFO(
"resp = %x", resp.cString());
791 LOG_INFO(
"Invalid Option to Open media or cas management session ...");
803 LOG_INFO(
"%s\n", __PRETTY_FUNCTION__);
806 std::string strData = data.cString();
807 #ifdef USE_EXTERNAL_CAS
808 ((
RMFPlayer *)m_pImpl)->sendCASData(strData);
826 return m_loadStartTime;
831 return m_playStartTime;
836 return m_eventEmitter;
841 LOG_INFO(
"%s %u\n", __PRETTY_FUNCTION__, handle);
842 m_vidDecoderHandle = handle;
843 updateClosedCaptionsState();
848 m_availableAudioLanguages = languages;
849 m_availableSpeeds = speeds;
851 #ifndef DISABLE_CLOSEDCAPTIONS
852 m_availableClosedCaptionsLanguages = m_closedCaptions.getAvailableTracks();
854 std::string mediaType;
858 void RDKMediaPlayer::updateClosedCaptionsState()
860 #ifndef DISABLE_CLOSEDCAPTIONS
861 LOG_INFO(
"%s m_vidDecoderHandle=%u m_closedCaptionsEnabled=%d m_speed=%f\n", __PRETTY_FUNCTION__, (uint32_t)m_vidDecoderHandle, (
int)m_closedCaptionsEnabled, m_speed);
863 if(m_vidDecoderHandle && m_closedCaptionsEnabled && m_speed >= 0 && m_speed <= 1 )
865 if(!m_closedCaptions.isEnabled())
867 LOG_INFO(
"updateClosedCaptionsState cc start\n");
868 if(!m_closedCaptions.setEnabled(
true))
872 m_closedCaptions.start((
void*)m_vidDecoderHandle);
873 m_closedCaptions.setVisible(
true);
878 if(m_closedCaptions.isEnabled())
880 LOG_INFO(
"updateClosedCaptionsState cc stop\n");
881 m_closedCaptions.stop();
882 if(!m_closedCaptions.setEnabled(
false))