19 #include "mediaplayerdlna.h"
30 #include <gst/audio/streamvolume.h>
31 #include <gst/video/video.h>
32 #include <curl/curl.h>
35 #include <mediaplayersink.h>
36 #include <dumpfilesink.h>
38 #ifdef ENABLE_DIRECT_QAM
39 #include <rmfqamsrc.h>
41 #include <rmfvodsource.h>
43 #ifdef IPPV_CLIENT_ENABLED
47 #include <rmfqamsrcpriv.h>
48 #include "rmfprivate.h"
52 #define HEADER_NAME_SEEK_RANGE "availableSeekRange.dlna.org"
53 #define HEADER_NAME_PLAYSPEED "PlaySpeed.dlna.org"
54 #define HEADER_NAME_VODADINSERTION_STATUS "vodAdInsertionStatus.cmst.com"
55 #define RMF_VOD_BEGIN_PLAYBACK 7
56 #define RMF_VOD_BAD_START_POSITION_VAL 0x7FFFFFFFu
58 #define CURL_EASY_SETOPT(curl, CURLoption ,option) \
59 if (curl_easy_setopt(curl, CURLoption ,option) != 0) {\
60 LOG_ERROR("Failed at curl_easy_setopt %d \n", curl); \
61 } //CID:127965 - checked return
62 typedef std::vector<std::string> headers_t;
78 bool starts_with(
const std::string &s,
const std::string &starting) {
79 if (starting.size() > s.size())
81 return std::equal(starting.begin(), starting.end(), s.begin());
84 bool ends_with(
const std::string &s,
const std::string &ending) {
85 if (ending.size() > s.size())
87 return std::equal(ending.rbegin(), ending.rend(), s.rbegin());
90 bool has_substring(
const std::string &s,
const std::string &substring) {
91 return s.find(substring) != std::string::npos;
94 std::vector<std::string>& split_string(
95 const std::string &s,
char delim, std::vector<std::string> &elems) {
96 std::stringstream ss(s);
98 while (std::getline(ss, item, delim)) {
99 elems.push_back(item);
104 std::string <rim_string(std::string &s) {
110 std::not1(std::ptr_fun<int, int>(std::isspace))));
114 std::string &rtrim_string(std::string &s) {
119 std::not1(std::ptr_fun<int, int>(std::isspace))).base(),
124 std::string &trim_string(std::string &s) {
125 return ltrim_string(rtrim_string(s));
128 std::string& find_header(
const headers_t &headers,
const std::string &header_name, std::string &header_value) {
129 header_value = std::string();
130 for (headers_t::const_iterator cit = headers.begin();
131 cit != headers.end(); ++cit) {
132 const std::string& raw_header = *cit;
133 if (starts_with(raw_header, header_name)) {
134 const size_t column_pos = raw_header.find_first_of(
':');
135 header_value = raw_header.substr(column_pos + 1);
136 header_value = trim_string(header_value);
143 const int kCurlTimeoutInSeconds = 30;
145 #if LIBCURL_VERSION_NUM >= 0x071306
146 #define _CURLINFO_RESPONSE_CODE CURLINFO_RESPONSE_CODE
148 #define _CURLINFO_RESPONSE_CODE CURLINFO_HTTP_CODE
151 size_t write_callback(
void *contents,
size_t size,
size_t nmemb,
void *userp) {
152 size_t realsize = size * nmemb;
153 std::string *mem =
reinterpret_cast<std::string*
>(userp);
154 *mem += std::string(
reinterpret_cast<char*
>(contents), realsize);
158 class MediaEvents :
public IRMFMediaEvents {
161 void playing() { m_player->onPlay(); }
162 void paused() { m_player->onPause(); }
163 void stopped() { m_player->onStop(); }
165 LOG_INFO(
"DLNA player: End of Stream");
168 void error(RMFResult err,
const char* msg) {
169 LOG_ERROR(
"DLNA player: Error %s (%d)", msg, (
int)err);
170 m_player->notifyError(err, msg);
172 void status(
const RMFStreamingStatus& status) {
173 LOG_ERROR(
"DLNA player: Status %d", status.m_status);
174 m_player->notifyStatus(status);
176 void section(
const void* data_ptr,
unsigned int data_size){
177 LOG_ERROR(
"DLNA player: Section Data Received");
188 static void mediaPlayerPrivateHaveVideoCallback(
void* player) {
190 ASSERT(player == g_playerInstance);
194 static void mediaPlayerPrivateHaveAudioCallback(
void* player) {
198 static void mediaPlayerPrivateEISSDataCallback(
void* player)
201 ASSERT(player == g_playerInstance);
204 static void mediaPlayerPrivateAudioNotifyFirstFrameCallback(
void* player) {
205 ASSERT(player == g_playerInstance);
206 static_cast<MediaPlayerDLNA*
>(player)->notifyPlayerOfFirstAudioFrame();
209 static void mediaPlayerPrivateNotifyMediaWarningCallback(
void* player) {
210 ASSERT(player == g_playerInstance);
214 static void mediaPlayerPrivateVideoNotifyFirstFrameCallback(
void* player) {
215 ASSERT(player == g_playerInstance);
216 static_cast<MediaPlayerDLNA*
>(player)->notifyPlayerOfFirstVideoFrame();
219 static void mediaPlayerPrivateNotifyPmtUpdateCallback(
void* player) {
221 ASSERT(player == g_playerInstance);
225 static void mediaPlayerLanguageChangeCallback(
void* player) {
227 ASSERT(player == g_playerInstance);
231 bool MediaPlayerDLNA::isVOD()
const {
232 return has_substring(m_url,
"vod://");
235 bool MediaPlayerDLNA::isOCAP()
const {
236 return has_substring(m_url,
"ocap://");
239 bool MediaPlayerDLNA::isMpegTS()
const {
240 return ends_with(m_url,
".ts") || has_substring(m_url,
"/vldms/") ||
241 has_substring(m_url,
"profile=MPEG_TS");
245 : m_playerClient(client)
250 , m_events(new ::MediaEvents(this))
251 , m_events_sink(new ::MediaEvents(this))
252 , m_changingRate(false)
253 , m_endTime(std::numeric_limits<float>::infinity())
255 , m_videoState(
MediaPlayer::RMF_VIDEO_BUFFER_HAVENOTHING)
256 , m_isStreaming(false)
258 , m_pausedInternal(true)
261 , m_errorOccured(false)
263 , m_delayingLoad(false)
264 , m_mediaDurationKnown(false)
265 , m_volumeTimerHandler(0)
266 , m_muteTimerHandler(0)
269 , m_currentPosition(0)
270 , m_isVOnlyOnce(true)
271 , m_isAOnlyOnce(true)
272 , m_isEndReached(false)
273 , m_isInProgressRecording(false)
276 , m_baseSeekTime(0.0)
277 , m_currentProgressTime(0.0)
278 , m_rmfMediaWarnDesc(
"")
279 , m_rmfAudioTracks(
"")
280 , m_rmfCaptionDescriptor(
"")
281 , m_rmfEISSDataBuffer(
"")
282 , m_rmfMediaWarnData(0)
283 , m_networkBufferSize(0)
284 , m_restartPlaybackCount(0)
285 , m_allowPositionQueries(false)
286 , m_EOSPending(false)
287 , m_fetchTrickModeHeaders(false)
288 , m_isVODPauseRequested(false)
289 , m_isVODRateChangeRequested(false)
290 , m_isVODSeekRequested(false)
291 , m_isVODAsset(false)
292 , m_isMusicOnlyAsset(true)
293 #ifdef ENABLE_DIRECT_QAM
294 , m_isLiveAsset(false)
295 , m_isPPVAsset(false)
296 , m_isDVRAsset (false)
298 , m_VODKeepPipelinePlaying(true)
299 , m_eissFilterStatus(false)
300 , m_onFirstVideoFrameHandler(0)
301 , m_onFirstAudioFrameHandler(0)
302 , m_onEISSDUpdateHandler(0)
305 , m_audioMuteStatus(false)
306 , m_onMediaWarningReceivedHandler(0) {
307 LOG_INFO(
"DLNA video player created");
308 g_playerInstance =
this;
310 char *pVODKeepPipelinePlaying = NULL;
311 pVODKeepPipelinePlaying = getenv(
"RMF_VOD_KEEP_PIPELINE");
312 errno_t safec_rc = -1;
315 if (pVODKeepPipelinePlaying ) {
316 safec_rc = strcasecmp_s(
"FALSE", strlen(
"FALSE"), pVODKeepPipelinePlaying, &ind);
318 if((safec_rc == EOK) && (ind == 0)) {
319 m_VODKeepPipelinePlaying =
false;
322 m_maxTimeLoaded = 0.0f;
323 m_videoTimerHandler = 0;
324 m_audioTimerHandler = 0;
325 m_startedBuffering =
false;
326 m_isVOD5XHackEnabled =
true;
329 MediaPlayerDLNA::~MediaPlayerDLNA() {
330 LOG_INFO(
"DLNA video player destroying");
332 if (
this == g_playerInstance)
333 g_playerInstance = NULL;
335 if (m_progressTimer.isActive())
336 m_progressTimer.stop();
340 m_playerClient = NULL;
345 delete m_events_sink;
346 m_events_sink = NULL;
348 if (m_muteTimerHandler)
349 g_source_remove(m_muteTimerHandler);
351 if (m_volumeTimerHandler)
352 g_source_remove(m_volumeTimerHandler);
354 if (m_onFirstVideoFrameHandler)
355 g_source_remove(m_onFirstVideoFrameHandler);
357 if (m_onFirstAudioFrameHandler)
358 g_source_remove(m_onFirstAudioFrameHandler);
360 if (m_onMediaWarningReceivedHandler)
361 g_source_remove(m_onMediaWarningReceivedHandler);
363 if (m_onEISSDUpdateHandler)
364 g_source_remove(m_onEISSDUpdateHandler);
370 LOG_INFO(
"DLNA video player destroyed");
373 void MediaPlayerDLNA::notifyError(RMFResult err,
const char *pMsg) {
374 std::string tmp =
"130:ErrorCode:Unknown Error";
376 tmp = std::string(pMsg);
379 #ifdef ENABLE_DIRECT_QAM
380 getErrorMapping(err, pMsg);
382 setMediaErrorMessage(tmp);
384 loadingFailed(MediaPlayer::RMF_PLAYER_DECODEERROR);
387 void MediaPlayerDLNA::notifyStatus(
const RMFStreamingStatus& status) {
388 LOG_INFO(
"notifyStatus - Status %d", status.m_status);
389 bool psiEvent =
false;
390 switch (status.m_status)
392 case RMF_QAMSRC_EVENT_PAT_ACQUIRED:
393 LOG_INFO(
"notifyStatus - Status - RMF_QAMSRC_EVENT_PAT_ACQUIRED");
394 m_psiStatus |= PAT_ACQUIRE;
397 case RMF_QAMSRC_EVENT_PMT_ACQUIRED:
398 LOG_INFO(
"notifyStatus - Status - RMF_QAMSRC_EVENT_PMT_ACQUIRED");
399 m_psiStatus |= PMT_ACQUIRE;
402 case RMF_QAMSRC_EVENT_CAT_ACQUIRED:
403 LOG_INFO(
"notifyStatus - Status - RMF_QAMSRC_EVENT_CAT_ACQUIRED");
404 m_playerClient->psiUpdateReceived(CAT_ACQUIRE);
405 m_psiStatus |= CAT_ACQUIRE;
408 case RMF_QAMSRC_EVENT_PAT_UPDATE:
409 LOG_INFO(
"notifyStatus - Status - RMF_QAMSRC_EVENT_PAT_UPDATE");
410 m_playerClient->psiUpdateReceived(PAT_UPDATE);
412 case RMF_QAMSRC_EVENT_CAT_UPDATE:
413 LOG_INFO(
"notifyStatus - Status - RMF_QAMSRC_EVENT_CAT_UPDATE");
414 m_playerClient->psiUpdateReceived(CAT_UPDATE);
416 case RMF_QAMSRC_EVENT_PMT_UPDATE:
417 LOG_INFO(
"notifyStatus - Status - RMF_QAMSRC_EVENT_PMT_UPDATE");
418 m_playerClient->psiUpdateReceived(PMT_UPDATE);
420 onPMTUpdateAudioMute();
423 if(status.m_status == RMF_QAMSRC_EVENT_SECTION_ACQUIRED) {
424 LOG_INFO(
"Section Data is avialable to read");
425 m_playerClient->sectionDataReceived();
427 else if(psiEvent && (m_psiStatus == PSI_READY)){
428 LOG_INFO(
"PSI Data (PAT, PMT and CAT) is ready");
433 uint32_t MediaPlayerDLNA::getPATBuffer(std::vector<uint8_t>& buf) {
436 ((RMFQAMSrcImpl *)(m_source->getPrivateSourceImpl()))->getPATBuffer(buf, &length);
440 uint32_t MediaPlayerDLNA::getPMTBuffer(std::vector<uint8_t>& buf) {
442 m_source->getPrivateSourceImpl()->getPMTBuffer(buf, &length);
446 uint32_t MediaPlayerDLNA::getCATBuffer(std::vector<uint8_t>& buf) {
448 m_source->getPrivateSourceImpl()->getCATBuffer(buf, &length);
452 bool MediaPlayerDLNA::getAudioPidFromPMT(uint32_t *pid,
const std::string& audioLang) {
453 return m_source->getPrivateSourceImpl()->getAudioPidFromPMT(pid, audioLang);
456 void MediaPlayerDLNA::onPMTUpdateAudioMute()
461 (!getAudioPidFromPMT(&pid, m_sink->getAudioTrackSelected())) &&
462 (!getAudioPidFromPMT(&pid, m_sink->getPreferredAudioLanguage())) &&
463 (!getAudioPidFromPMT(&pid,
""))
465 LOG_ERROR(
"Failed to get AudioPid from PMT");
468 LOG_INFO(
"onPMTUpdateAudioMute updated audioPid - %p\n", pid);
469 if(pid != m_playerClient->getCurrentAudioPid())
472 rmf_setAudioMute(
true);
475 bool MediaPlayerDLNA::getAudioMute()
const
477 return m_audioMuteStatus;
481 uint32_t MediaPlayerDLNA::getSectionData(uint32_t *filterId, std::vector<uint8_t>& sectionData)
484 m_source->getPrivateSourceImpl()->getSectionData(filterId, sectionData, &length);
488 void MediaPlayerDLNA::setFilter(uint16_t pid,
char* filterParam, uint32_t *pFilterId)
490 LOG_INFO(
"MediaPlayerDLNA::setFilter");
491 m_source->getPrivateSourceImpl()->setFilter(pid, filterParam, pFilterId);
494 void MediaPlayerDLNA::releaseFilter(uint32_t filterId)
496 LOG_INFO(
"MediaPlayerDLNA::releaseFilter");
497 m_source->getPrivateSourceImpl()->releaseFilter(filterId);
500 void MediaPlayerDLNA::resumeFilter(uint32_t filterId)
502 LOG_INFO(
"MediaPlayerDLNA::resumeFilter");
503 m_source->getPrivateSourceImpl()->resumeFilter(filterId);
506 void MediaPlayerDLNA::pauseFilter(uint32_t filterId)
508 LOG_INFO(
"MediaPlayerDLNA::pauseFilter");
509 m_source->getPrivateSourceImpl()->pauseFilter(filterId);
512 #ifdef ENABLE_DIRECT_QAM
513 void MediaPlayerDLNA::getErrorMapping(RMFResult err,
const char *pMsg)
515 std::string errorMsg =
"Unknown Error";
516 std::string inputErr =
"Unknown Error";
518 inputErr = std::string(pMsg);
521 errorMsg =
"130:Error:" + inputErr;
522 else if (m_isLiveAsset | m_isPPVAsset)
524 std::string errorCode =
"0";
527 case RMF_QAMSRC_EVENT_CANNOT_DESCRAMBLE_ENTITLEMENT:
528 case RMF_QAMSRC_EVENT_CANNOT_DESCRAMBLE_RESOURCES:
529 case RMF_QAMSRC_EVENT_MMI_PURCHASE_DIALOG:
530 case RMF_QAMSRC_EVENT_MMI_TECHNICAL_DIALOG:
531 case RMF_QAMSRC_EVENT_POD_REMOVED:
532 case RMF_QAMSRC_EVENT_POD_RESOURCE_LOST:
536 case RMF_QAMSRC_ERROR_PAT_NOT_AVAILABLE:
537 case RMF_QAMSRC_ERROR_PMT_NOT_AVAILABLE:
538 case RMF_QAMSRC_ERROR_PROGRAM_NUMBER_INVALID:
539 case RMF_QAMSRC_ERROR_PROGRAM_NUMBER_INVALID_ON_PAT_UPDATE:
543 case RMF_QAMSRC_ERROR_UNRECOVERABLE_ERROR:
547 case RMF_QAMSRC_ERROR_TUNER_NOT_LOCKED:
548 case RMF_QAMSRC_ERROR_TUNE_FAILED:
552 inputErr =
"Service Unavailable";
556 errorMsg = errorCode +
":Error:" + inputErr;
558 else if (m_isDVRAsset)
564 LOG_INFO (
"The Error String set is %s", errorMsg.c_str());
565 setMediaErrorMessage(errorMsg);
569 void MediaPlayerDLNA::fetchHeaders() {
571 m_progressTimer.startOneShot(1.0);
576 request.headers.push_back(
"getAvailableSeekRange.dlna.org: 1");
577 fetchOnWorkerThread(request);
581 void MediaPlayerDLNA::fetchOnWorkerThread(
const RequestInfo& request) {
584 fetchWithCurl(request, response);
585 onReplyFinished(response);
588 void MediaPlayerDLNA::fetchWithCurl(
590 LOG_VERBOSE(
"curl request for url: %s", request.url.c_str());
591 LOG_VERBOSE(
"headers:");
592 for (headers_t::const_iterator cit = request.headers.begin();
593 cit != request.headers.end(); ++cit) {
594 const std::string& header = *cit;
595 LOG_VERBOSE(
"\t%s", header.c_str());
598 CURLcode res = CURLE_OK;
599 CURL *curl_handle = NULL;
601 std::string headers_buf;
602 std::string payload_buf;
604 curl_handle = curl_easy_init();
605 CURL_EASY_SETOPT(curl_handle, CURLOPT_URL, request.url.c_str());
606 CURL_EASY_SETOPT(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
607 CURL_EASY_SETOPT(curl_handle, CURLOPT_TIMEOUT, kCurlTimeoutInSeconds);
608 CURL_EASY_SETOPT(curl_handle, CURLOPT_HEADERFUNCTION,
write_callback);
609 CURL_EASY_SETOPT(curl_handle, CURLOPT_HEADERDATA,
610 reinterpret_cast<void *
>(&headers_buf));
615 CURL_EASY_SETOPT(curl_handle, CURLOPT_NOBODY, 1);
616 CURL_EASY_SETOPT(curl_handle, CURLOPT_HEADER, 1);
617 CURL_EASY_SETOPT(curl_handle, CURLOPT_NOPROGRESS, 1);
618 CURL_EASY_SETOPT(curl_handle, CURLOPT_NOSIGNAL, 1);
621 if (!request.headers.empty()) {
622 struct curl_slist *headers = NULL;
623 for (headers_t::const_iterator cit = request.headers.begin();
624 cit != request.headers.end(); ++cit) {
625 const std::string& header = *cit;
626 headers = curl_slist_append(headers, header.c_str());
628 CURL_EASY_SETOPT(curl_handle, CURLOPT_HTTPHEADER, headers);
631 res = curl_easy_perform(curl_handle);
633 if (res != CURLE_OK) {
634 LOG_ERROR(
"curl failed with result: %d", res);
635 response.http_code = -1;
636 curl_easy_cleanup(curl_handle);
641 if (CURLE_OK == curl_easy_getinfo(curl_handle, _CURLINFO_RESPONSE_CODE, &httpCode))
642 response.http_code = httpCode;
644 response.http_code = -1;
646 response.url = request.url;
647 response.payload = payload_buf;
648 response.headers = split_string(headers_buf,
'\n', response.headers);
650 LOG_VERBOSE(
"curl got response for url: %s", response.url.c_str());
651 LOG_VERBOSE(
"headers:");
652 for (headers_t::const_iterator cit = response.headers.begin();
653 cit != response.headers.end(); ++cit) {
654 const std::string& header = *cit;
655 LOG_VERBOSE(
"\t%s", header.c_str());
658 curl_easy_cleanup(curl_handle);
661 void MediaPlayerDLNA::time_to_hms(
662 float time,
unsigned& h,
unsigned& m,
float& s) {
667 m = (time - h * 3600) / 60;
668 s = time - h * 3600 - m * 60;
671 void MediaPlayerDLNA::fetchHeadersForTrickMode(
float speed,
double pos) {
677 m_fetchTrickModeHeaders =
true;
682 LOG_INFO(
"MediaPlayerDLNA: fetchHeadersForTrickMode speed change request. So reset the paused flag if any..");
683 m_isVODPauseRequested =
false;
689 errno_t safec_rc =sprintf_s(speed_str,
sizeof(speed_str),
"speed=%f", speed);
693 LOG_INFO(
"MediaPlayerDLNA: fetchHeadersForTrickMode speed: [%s]", speed_str);
695 unsigned h = 0, m = 0;
697 time_to_hms(pos, h, m, s);
699 safec_rc =sprintf_s(time_str,
sizeof(time_str),
"npt=%02u:%02u:%.2f-", h, m, s);
703 LOG_INFO(
"MediaPlayerDLNA: fetchHeadersForTrickMode position: [%s] (%f)", time_str, pos);
707 request.headers.push_back(std::string(
"getAvailableSeekRange.dlna.org: 1"));
708 request.headers.push_back(std::string(
"PlaySpeed.dlna.org: ") + speed_str);
709 request.headers.push_back(std::string(
"TimeSeekRange.dlna.org: ") + time_str);
711 fetchOnWorkerThread(request);
715 void MediaPlayerDLNA::onReplyError() {
716 setMediaErrorMessage(
"VOD:: MediaStreamer is not reachable");
717 loadingFailed(MediaPlayer::RMF_PLAYER_NETWORKERROR);
718 m_progressTimer.startOneShot(0);
721 void MediaPlayerDLNA::onReplyFinished(
const ResponseInfo& response) {
722 const headers_t& headers = response.headers;
723 LOG_TRACE(
"Load finished with http_code: %d", response.http_code);
724 if (response.http_code < 0) {
729 if (m_progressTimer.isActive())
730 m_progressTimer.stop();
732 std::string seek_header;
733 std::string speed_header;
734 std::string adHeader;
735 find_header(headers, HEADER_NAME_VODADINSERTION_STATUS, adHeader);
736 if (!adHeader.empty()) {
737 LOG_INFO (
"Ad_header: %s", adHeader.c_str());
739 if (std::string::npos != adHeader.find(
"started"))
741 LOG_INFO (
"Ad is being played; could not honor the trick request");
742 if (1.0 != m_playbackRate)
744 LOG_INFO (
"Ad Started during trick it seems; switch to 1.0f");
745 m_playbackRate = 1.0f;
746 m_playerClient->rateChanged();
748 m_rmfMediaWarnDesc = std::string(
"TRICK_MODE_NOT_ALLOWED");
749 m_rmfMediaWarnData = 1;
750 m_playerClient->mediaWarningReceived();
752 if ((m_paused) && (m_source))
756 g_print (
"Current state is paused; So update the hnsource for the timeouts..\n");
757 m_isVODPauseRequested =
true;
758 m_source->play (speed, time);
762 LOG_TRACE (
"No Opp as og now for this ad insertion %s", adHeader.c_str());
764 bool postTimeChanged =
true;
765 unsigned int seekTime = 0;
767 find_header(headers, HEADER_NAME_SEEK_RANGE, seek_header);
768 if (!seek_header.empty() && (!m_EOSPending)) {
770 LOG_INFO(
"seek_header: %s", seek_header.c_str());
772 std::vector<std::string> first_split;
773 split_string(seek_header,
'=', first_split);
775 std::string npt_str = first_split.at(1);
776 LOG_INFO(
"npt_str: %s", npt_str.c_str());
778 std::vector<std::string> second_split;
779 split_string(npt_str,
':', second_split);
781 if (3 == second_split.size()) {
783 int hour = atoi(second_split.at(0).c_str());
784 int minute = atoi(second_split.at(1).c_str());
785 int second = atoi(second_split.at(2).c_str());
786 LOG_TRACE(
"hour: %d, min: %d, second: %d", hour, minute, second);
787 seekTime = (hour * 3600) + (minute * 60) + second;
788 LOG_INFO (
"MediaPlayerDLNA:: Received lastStartNPT is %u", seekTime);
790 if (m_VODKeepPipelinePlaying) {
791 if (m_isVODAsset && (seekTime == (RMF_VOD_BAD_START_POSITION_VAL/1000u)))
793 LOG_INFO(
"MediaPlayerDLNA:: VOD EOS Pending");
800 find_header(headers, HEADER_NAME_PLAYSPEED, speed_header);
801 if (!speed_header.empty() && (!m_EOSPending))
803 LOG_TRACE(
"speed_header: %s", speed_header.c_str());
804 std::vector<std::string> speed_vec;
805 split_string(speed_header,
'=', speed_vec);
806 std::string new_param = speed_vec.at(1);
807 LOG_INFO (
"MediaPlayerDLNA:: Header Response:: Speed Header is = %s\n", new_param.c_str());
810 m_currentProgressTime = 0;
811 float speed = atof(new_param.c_str());
814 if (!m_isVOD5XHackEnabled)
824 if (m_playbackRate != speed)
826 m_playbackRate = speed;
827 m_playerClient->rateChanged();
830 LOG_INFO (
"MediaPlayerDLNA:: Header Response:: Asset [VOD] speed: [%f]\n", m_playbackRate);
834 if ((m_isVODPauseRequested) && (0 == speed))
838 if (speed != m_playbackRate)
840 m_playbackRate = speed;
841 m_playerClient->rateChanged();
844 else if ((m_isVODPauseRequested) && (0 != speed))
848 if (speed != m_playbackRate)
850 m_playbackRate = speed;
851 m_playerClient->rateChanged();
853 postTimeChanged =
false;
854 LOG_WARNING(
"MediaPlayerPrivateDLNA:: Header Response:: Ignore this [%s] response as it is invalid at this point in time", new_param.c_str());
861 LOG_WARNING(
"MediaPlayerPrivateDLNA:: Header Response received for the Pause request after we sent other trick mode command.");
863 postTimeChanged =
false;
865 else if ((m_isVODSeekRequested) && (speed != 1.0))
867 LOG_WARNING(
"MediaPlayerPrivateDLNA:: Header Response received for the trick modes after the seek command sent.");
869 postTimeChanged =
false;
873 m_isVODSeekRequested =
false;
874 if (speed != m_playbackRate)
876 m_playbackRate = speed;
877 m_playerClient->rateChanged();
879 LOG_WARNING(
"MediaPlayerPrivateDLNA:: Header Response:: Asset [VOD] speed: [%f]\n", m_playbackRate);
889 m_baseSeekTime = seekTime;
890 m_playerClient->timeChanged();
895 m_progressTimer.startOneShot(1.0);
899 void MediaPlayerDLNA::onProgressTimerTimeout() {
900 m_currentProgressTime += m_playbackRate;
907 if ((m_playbackRate == 4.0) || (m_playbackRate == -4.0))
908 m_currentProgressTime += m_playbackRate;
911 m_progressTimer.startOneShot(1.0);
913 if ((m_playbackRate < 0) && (playbackPosition() == 0)) {
914 m_restartPlaybackCount++;
915 if (m_restartPlaybackCount > RMF_VOD_BEGIN_PLAYBACK) {
916 m_restartPlaybackCount = 0;
922 bool MediaPlayerDLNA::rmf_load(
const std::string& httpUrl) {
923 LOG_INFO(
"LOAD IS CALLED (%s)", httpUrl.c_str());
925 char *pVOD5XHack = NULL;
926 pVOD5XHack = getenv(
"RMF_VOD_5X_MITIGATION");
927 errno_t safec_rc = -1;
931 safec_rc = strcasecmp_s(
"TRUE", strlen(
"TRUE"), pVOD5XHack, &ind);
933 if((safec_rc == EOK) && (ind == 0)) {
934 LOG_WARNING(
"RMF_VOD_5X_MITIGATION is set to TRUE..\n");
935 m_isVOD5XHackEnabled =
true;
939 if (httpUrl.empty()) {
940 LOG_ERROR(
"Empty URL, skipping RMF pipeline construction");
945 LOG_ERROR(
"It seems like, It is loaded was already but not stopped yet. "
946 "This is under worst case.. Just return or call stop internally");
953 m_isMusicOnlyAsset =
true;
956 #ifdef ENABLE_DIRECT_QAM
960 if (m_url.find(
"ocap://") != std::string::npos) {
961 safec_rc = strcpy_s(url,
sizeof(url), m_url.c_str());
962 if(safec_rc != EOK) {
966 p= strstr(url,
"ocap://0x");
967 len= strlen(
"ocap://0x");
969 while(((c >=
'0') && (c <=
'9')) ||
970 ((c >=
'a') && (c <=
'f')) ||
971 ((c >=
'A') && (c <=
'F')))
974 if (len >= (
sizeof(ocapUrl) - 1))
977 safec_rc = strncpy_s(ocapUrl,
sizeof(ocapUrl), p, len);
978 if(safec_rc != EOK) {
983 LOG_INFO(
"QAM service: %s", ocapUrl);
986 if (
true == RMFQAMSrc::useFactoryMethods()) {
987 m_source = RMFQAMSrc::getQAMSourceInstance(ocapUrl);
989 m_source =
new RMFQAMSrc();
992 else if (m_url.find(
"tune://") != std::string::npos) {
993 strcpy(url, m_url.c_str());
995 if (
true == RMFQAMSrc::useFactoryMethods()) {
996 m_source = RMFQAMSrc::getQAMSourceInstance(m_url.c_str());
998 m_source =
new RMFQAMSrc();
1000 RMFQAMSrc::init_platform();
1002 #ifdef IPPV_CLIENT_ENABLED
1003 else if (m_url.find(
"ippv://") != std::string::npos) {
1004 safec_rc = strcpy_s(url,
sizeof(url), m_url.c_str());
1005 if(safec_rc != EOK) {
1009 p= strstr(url,
"ippv://0x");
1010 len= strlen(
"ippv://0x");
1012 while(((c >=
'0') && (c <=
'9')) ||
1013 ((c >=
'a') && (c <=
'f')) ||
1014 ((c >=
'A') && (c <=
'F'))) {
1016 if (len >= (
sizeof(ocapUrl) - 1))
1019 safec_rc = strncpy_s(ocapUrl,
sizeof(ocapUrl), p, len);
1020 if(safec_rc != EOK) {
1025 LOG_INFO(
"IPPV service: %s", ocapUrl);
1026 safec_rc = strcpy_s(url,
sizeof(url), ocapUrl);
1027 if(safec_rc != EOK) {
1032 m_source =
new RMFiPPVSrc();
1036 else if (m_url.find(
"vod://") != std::string::npos) {
1037 safec_rc = strcpy_s(url,
sizeof(url), m_url.c_str());
1038 if(safec_rc != EOK) {
1042 p= strstr(url,
"vod://");
1043 char *tempstr = strchr(p,
'&');
1045 if(tempstr != NULL) {
1046 safec_rc = strncpy_s(ocapUrl,
sizeof(ocapUrl), p, tempstr-p);
1047 if(safec_rc != EOK) {
1051 ocapUrl[tempstr-p]=
'\0';
1053 safec_rc = strcpy_s(ocapUrl,
sizeof(ocapUrl), p);
1054 if(safec_rc != EOK) {
1059 LOG_INFO(
"vod service: %s", ocapUrl);
1060 safec_rc = strcpy_s(url,
sizeof(url), ocapUrl);
1061 if(safec_rc != EOK) {
1066 m_source =
new RMFVODSrc();
1067 m_VODKeepPipelinePlaying =
false;
1073 safec_rc = strcpy_s(url,
sizeof(url), m_url.c_str());
1074 if(safec_rc != EOK) {
1078 m_source =
new HNSource();
1079 m_hnsource =
dynamic_cast<HNSource *
>(m_source);
1081 #ifdef ENABLE_DIRECT_QAM
1085 if(NULL == m_source) {
1086 LOG_ERROR(
"Source create failed");
1087 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVENOTHING;
1088 notifyError(0,
"Service unavailable");
1092 if (m_url.find(
"vod://") != std::string::npos) {
1093 m_isVODAsset =
true;
1095 #ifdef ENABLE_DIRECT_QAM
1096 else if ((m_url.find(
"tune://") != std::string::npos) || (m_url.find(
"ocap://") != std::string::npos)) {
1097 m_isLiveAsset =
true;
1099 else if (m_url.find(
"ippv://") != std::string::npos) {
1100 m_isPPVAsset =
true;
1103 m_isDVRAsset =
true;
1106 if (m_source->init() != RMF_RESULT_SUCCESS) {
1107 m_errorMsg =
"Failed to initialize source";
1108 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVENOTHING;
1109 LOG_ERROR(
"%s", m_errorMsg.c_str());
1110 loadingFailed(MediaPlayer::RMF_PLAYER_DECODEERROR);
1114 m_source->setEvents(m_events);
1116 if(m_source->open(url, NULL) != RMF_RESULT_SUCCESS) {
1117 m_errorMsg =
"Failed to open source";
1118 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVENOTHING;
1119 LOG_ERROR(
"%s", m_errorMsg.c_str());
1120 loadingFailed(MediaPlayer::RMF_PLAYER_DECODEERROR);
1124 m_sink =
new MediaPlayerSink();
1126 if(NULL == m_sink) {
1127 m_errorMsg =
"Sink create failed";
1128 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVENOTHING;
1129 LOG_ERROR(
"%s", m_errorMsg.c_str());
1130 loadingFailed(MediaPlayer::RMF_PLAYER_DECODEERROR);
1134 if (m_sink->init() != RMF_RESULT_SUCCESS) {
1135 m_errorMsg =
"Failed to initialize video sink";
1136 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVENOTHING;
1137 LOG_ERROR(
"%s", m_errorMsg.c_str());
1138 loadingFailed(MediaPlayer::RMF_PLAYER_DECODEERROR);
1141 m_sink->setEvents(m_events_sink);
1143 if (getenv(
"USE_SINK_DUMP")) {
1144 LOG_INFO(
"######################### Adding dump file sink ##########################");
1145 m_dfsink =
new DumpFileSink();
1152 safec_rc = strcpy_s(url,
sizeof(url), m_url.c_str());
1153 if(safec_rc != EOK) {
1157 safec_rc = strcpy_s(ipaddr,
sizeof(ipaddr),
"127.0.0.1");
1158 if(safec_rc != EOK) {
1162 char* ip_start_pos = strstr(url,
"http://") + strlen(
"http://");
1163 if (NULL != ip_start_pos) {
1164 char* ip_end_pos = strstr(ip_start_pos,
":");
1165 if (NULL != ip_end_pos) {
1166 safec_rc = strncpy_s(ipaddr,
sizeof(ipaddr), ip_start_pos, ip_end_pos - ip_start_pos);
1167 if(safec_rc != EOK) {
1171 ipaddr[ip_end_pos - ip_start_pos] = 0;
1174 safec_rc = sprintf_s(location,
sizeof(location),
"/opt/SNK_IN_%s.ts", ipaddr);
1175 if(safec_rc < EOK) {
1179 if (m_dfsink->init() != RMF_RESULT_SUCCESS) {
1180 LOG_ERROR(
"Failed to initialize fd sink");
1183 m_dfsink->setLocation(location);
1184 m_dfsink->setSource(m_source);
1187 m_sink->setSource(m_source);
1188 m_sink->setHaveVideoCallback(mediaPlayerPrivateHaveVideoCallback,
this);
1189 m_sink->setHaveAudioCallback(mediaPlayerPrivateHaveAudioCallback,
this);
1190 m_sink->setEISSDataCallback(mediaPlayerPrivateEISSDataCallback,
this);
1191 m_sink->setVideoPlayingCallback(mediaPlayerPrivateVideoNotifyFirstFrameCallback,
this);
1192 m_sink->setAudioPlayingCallback(mediaPlayerPrivateAudioNotifyFirstFrameCallback,
this);
1193 m_sink->setMediaWarningCallback(mediaPlayerPrivateNotifyMediaWarningCallback,
this);
1194 m_sink->setPmtUpdateCallback(mediaPlayerPrivateNotifyPmtUpdateCallback,
this);
1195 m_sink->setLanguageChangeCallback(mediaPlayerLanguageChangeCallback,
this);
1199 m_source->setSpeed(1.0f);
1200 m_source->setMediaTime(0.0);
1204 if (!m_delayingLoad)
1213 void MediaPlayerDLNA::commitLoad() {
1214 ASSERT(!m_delayingLoad);
1219 float MediaPlayerDLNA::playbackPosition()
const {
1221 float pos = m_baseSeekTime + m_currentProgressTime;
1227 double pos = m_currentPosition;
1228 #ifdef ENABLE_DIRECT_QAM
1229 if (!m_isDVRAsset) {
1230 if ((m_sink) && (m_sink->getMediaTime(pos) != RMF_RESULT_SUCCESS)) {
1231 LOG_ERROR(
"Failed to get playback position, return previous: %f", m_currentPosition);
1232 return m_currentPosition;
1236 if (m_allowPositionQueries && (!m_source || m_source->getMediaTime(pos) != RMF_RESULT_SUCCESS)) {
1237 LOG_ERROR(
"Failed to get playback position, return previous: %f", m_currentPosition);
1238 return m_currentPosition;
1240 #ifdef ENABLE_DIRECT_QAM
1243 return static_cast<float>(pos);
1247 void MediaPlayerDLNA::prepareToPlay() {
1248 if (m_delayingLoad) {
1249 m_delayingLoad =
false;
1254 void MediaPlayerDLNA::rmf_play() {
1258 LOG_WARNING(
"No source, skip play.");
1262 m_isEndReached =
false;
1265 if ((m_networkBufferSize) && (m_isVOnlyOnce)) {
1266 m_sink->setNetWorkBufferSize(m_networkBufferSize);
1269 if (m_VODKeepPipelinePlaying) {
1272 LOG_WARNING(
"Play cannot be done now as the VOD Server posted that it is sending EOS shortly");
1275 if (!m_isAOnlyOnce && m_allowPositionQueries)
1276 fetchHeadersForTrickMode(rmf_getRate(), m_baseSeekTime);
1280 if (m_source->play() == RMF_RESULT_SUCCESS) {
1284 m_currentPosition = rmf_getCurrentTime();
1285 m_pausedInternal =
false;
1287 LOG_ERROR(
"Play failed for some unknown reason..");
1288 loadingFailed(MediaPlayer::RMF_PLAYER_EMPTY);
1291 #ifdef IPPV_CLIENT_ENABLED
1293 unsigned int eIdValue = 0x00;
1299 errno_t safec_rc = strcpy_s(url,
sizeof(url), m_url.c_str());
1300 if(safec_rc != EOK) {
1304 p= strstr(url,
"token=");
1308 while ((c >=
'0') && (c <=
'9')) {
1310 if (len >= (
sizeof(eid) - 1))
1313 safec_rc = strncpy_s(eid,
sizeof(eid), p+6, len-6);
1314 if(safec_rc != EOK) {
1320 eIdValue = atoi(eid);
1321 LOG_INFO(
"play:: ippv asset: EID='%s',%d", eid, eIdValue);
1324 if (0x00 != eIdValue) {
1325 int rc = ((RMFiPPVSrc*)m_source)->purchasePPVEvent( eIdValue );
1327 LOG_ERROR(
"PPV event purchase failed");
1330 LOG_INFO(
"PPV event purchase succeeded");
1333 LOG_INFO(
"Already purchased PPV event");
1336 #endif //IPPV_CLIENT_ENABLED
1339 void MediaPlayerDLNA::rmf_pause() {
1346 #ifdef ENABLE_DIRECT_QAM
1348 if (!(m_isDVRAsset | m_isVODAsset))
1352 if (!m_pausedInternal) {
1356 if (m_VODKeepPipelinePlaying) {
1359 LOG_WARNING(
"Pause cannot be done now as the VOD Server posted that it is sending EOS shortly");
1365 m_isVODPauseRequested =
true;
1366 fetchHeadersForTrickMode(speed, time);
1373 m_source->setSpeed (speed);
1374 m_source->setMediaTime (time);
1378 if (m_source->play(speed, time) == RMF_RESULT_SUCCESS)
1381 if (m_progressTimer.isActive())
1382 m_progressTimer.stop();
1391 m_source->getMediaTime(npt);
1392 m_baseSeekTime = (
long long) npt/1000;
1394 m_baseSeekTime = playbackPosition();
1396 m_currentProgressTime = 0;
1401 LOG_INFO(
"Pause Ignored. We are still in the process of trick mode...");
1405 void MediaPlayerDLNA::rmf_stop() {
1407 if (!m_sink || !m_source)
1410 m_progressTimer.stop();
1411 m_allowPositionQueries =
false;
1412 m_source->setEvents(NULL);
1413 m_sink->setEvents(NULL);
1414 m_source->removeEventHandler(m_events);
1420 #ifdef ENABLE_DIRECT_QAM
1421 if (m_isLiveAsset) {
1422 RMFQAMSrc *qamSrc=
dynamic_cast<RMFQAMSrc *
>(m_source);
1423 if ( qamSrc && (
true == RMFQAMSrc::useFactoryMethods())) {
1425 RMFQAMSrc::freeQAMSourceInstance( qamSrc );
1454 float MediaPlayerDLNA::rmf_getDuration()
const {
1462 if (!m_mediaDurationKnown)
1463 return std::numeric_limits<float>::infinity();
1465 return m_mediaDuration;
1468 float MediaPlayerDLNA::rmf_getCurrentTime()
const {
1472 return playbackPosition();
1478 unsigned long MediaPlayerDLNA::rmf_getCCDecoderHandle()
const {
1480 return m_sink->getVideoDecoderHandle();
1485 std::string MediaPlayerDLNA::rmf_getAudioLanguages()
const
1489 return m_sink->getAudioLanguages();
1492 void MediaPlayerDLNA::rmf_setAudioLanguage(
const std::string& audioLang) {
1494 m_sink->setAudioLanguage(audioLang.c_str());
1499 void MediaPlayerDLNA::rmf_setAudioMute(
bool isMuted) {
1500 if (m_audioMuteStatus != isMuted)
1504 m_sink->setAudioMute(isMuted);
1506 m_audioMuteStatus = isMuted;
1510 void MediaPlayerDLNA::rmf_setEissFilterStatus (
bool eissStatus)
1512 m_eissFilterStatus = eissStatus;
1514 m_sink->setEissFilterStatus (eissStatus);
1519 void MediaPlayerDLNA::rmf_setVideoZoom(
unsigned short zoomVal) {
1521 m_sink->setVideoZoom(zoomVal);
1526 void MediaPlayerDLNA::rmf_setVideoBufferLength(
float bufferLength) {
1527 m_mediaDuration = bufferLength;
1529 m_hnsource->setVideoLength(m_mediaDuration);
1532 void MediaPlayerDLNA::rmf_setInProgressRecording(
bool isInProgress) {
1533 m_isInProgressRecording = isInProgress;
1536 void MediaPlayerDLNA::setMediaErrorMessage(
const std::string& errorMsg) {
1537 m_errorMsg = errorMsg;
1539 if (m_VODKeepPipelinePlaying) {
1540 if (m_isVODAsset && (m_errorMsg ==
"VOD-Pause-10Min-Timeout")) {
1541 LOG_INFO(
"MediaPlayerDLNA::VOD EOS Pending\n");
1542 m_EOSPending =
true;
1550 void MediaPlayerDLNA::rmf_seekToLivePosition(
void) {
1552 LOG_INFO(
"No source, skip seekToLivePosition.");
1555 #ifdef ENABLE_DIRECT_QAM
1557 if (!(m_isDVRAsset | m_isVODAsset))
1561 m_playbackRate = 1.0f;
1562 m_pausedInternal =
false;
1564 m_currentPosition = m_mediaDuration - 3.0;
1565 m_allowPositionQueries =
false;
1567 m_hnsource->playAtLivePosition(m_mediaDuration);
1569 m_hnsource->setMediaTime(m_currentPosition);
1576 void MediaPlayerDLNA::rmf_seekToStartPosition(
void) {
1578 LOG_INFO(
"No source, skip seekToStartPosition.");
1582 m_playbackRate = 1.0f;
1583 m_currentPosition = 0.0;
1586 m_currentProgressTime = 0;
1587 m_baseSeekTime = 0.0;
1589 if (m_VODKeepPipelinePlaying) {
1590 m_fetchTrickModeHeaders =
false;
1593 if (m_progressTimer.isActive())
1594 m_progressTimer.stop();
1597 m_allowPositionQueries =
false;
1598 m_pausedInternal =
false;
1600 m_source->setSpeed (m_playbackRate);
1601 m_source->setMediaTime(m_currentPosition);
1603 m_progressTimer.startOneShot(1.0);
1606 m_hnsource->playAtLivePosition(m_currentPosition);
1610 m_source->setMediaTime(m_currentPosition);
1616 std::string MediaPlayerDLNA::rmf_getMediaErrorMessage()
const {
1620 std::string MediaPlayerDLNA::rmf_getMediaWarnDescription()
const
1622 return m_rmfMediaWarnDesc;
1625 std::string MediaPlayerDLNA::rmf_getAvailableAudioTracks()
const
1627 if (m_rmfAudioTracks.empty())
1628 m_rmfAudioTracks = m_sink->getAudioLanguages();
1631 return m_rmfAudioTracks;
1634 std::string MediaPlayerDLNA::rmf_getCaptionDescriptor()
const
1636 if (m_rmfCaptionDescriptor.empty() && m_sink !=
nullptr)
1637 m_rmfCaptionDescriptor = m_sink->getCCDescriptor();
1640 return m_rmfCaptionDescriptor;
1643 std::string MediaPlayerDLNA::rmf_getEISSDataBuffer()
const
1645 m_rmfEISSDataBuffer = m_sink->getEISSData();
1647 return m_rmfEISSDataBuffer;
1649 int MediaPlayerDLNA::rmf_getMediaWarnData()
const
1651 return m_rmfMediaWarnData;
1654 void MediaPlayerDLNA::rmf_setNetworkBufferSize(
int bufferSize) {
1655 m_networkBufferSize = bufferSize;
1659 int MediaPlayerDLNA::rmf_getVideoPid() {
1662 video_pid = m_sink->getVideoPid();
1667 int MediaPlayerDLNA::rmf_getAudioPid() {
1670 audio_pid = m_sink->getAudioPid();
1675 void MediaPlayerDLNA::rmf_setVideoKeySlot(
const char* str) {
1677 m_sink->setVideoKeySlot(str);
1681 void MediaPlayerDLNA::rmf_setAudioKeySlot(
const char* str) {
1683 m_sink->setAudioKeySlot(str);
1687 void MediaPlayerDLNA::rmf_deleteVideoKeySlot() {
1689 m_sink->deleteVideoKeySlot();
1693 void MediaPlayerDLNA::rmf_deleteAudioKeySlot() {
1695 m_sink->deleteAudioKeySlot();
1699 void MediaPlayerDLNA::rmf_seek(
float time)
1703 if (m_isEndReached) {
1704 LOG_INFO(
"Ignore the seek() as it is being called after receiving EOS.. Duration = %f", rmf_getDuration());
1708 #ifdef ENABLE_DIRECT_QAM
1710 if (!(m_isDVRAsset | m_isVODAsset))
1715 if (time == playbackPosition())
1718 if (m_VODKeepPipelinePlaying) {
1719 if (m_isVODAsset && (m_paused ==
true)) {
1720 m_pausedInternal =
true;
1727 LOG_INFO(
"No source, not seeking");
1731 if (m_errorOccured) {
1732 LOG_INFO(
"Error occurred, not seeking");
1736 if (m_VODKeepPipelinePlaying) {
1739 LOG_INFO(
"Seek cannot be done now as the VOD Server posted that it is sending EOS shortly");
1743 if (!m_isAOnlyOnce) {
1745 if (!m_isVOD5XHackEnabled)
1747 if (1.0f != m_playbackRate)
1749 m_playbackRate = 1.0f;
1750 m_playerClient->rateChanged();
1752 fetchHeadersForTrickMode(m_playbackRate, time);
1756 if (m_isVODPauseRequested && m_isVODRateChangeRequested)
1757 m_isVODSeekRequested =
true;
1759 m_isVODSeekRequested =
false;
1760 fetchHeadersForTrickMode(1.0f, time);
1764 m_allowPositionQueries =
false;
1767 m_allowPositionQueries =
false;
1771 double fTime = time;
1773 fTime = time * 1000;
1774 if (m_source->setMediaTime(fTime) == RMF_RESULT_SUCCESS)
1776 if (m_source->setMediaTime(time) == RMF_RESULT_SUCCESS)
1779 if (1.0f != m_playbackRate) {
1780 m_playbackRate = 1.0f;
1781 m_playerClient->rateChanged();
1784 if (m_VODKeepPipelinePlaying) {
1788 m_baseSeekTime = time;
1789 m_currentProgressTime = 0;
1791 m_currentPosition = time;
1792 LOG_INFO(
"m_seeking - no change - fake seek");
1794 m_playerClient->timeChanged();
1795 m_pausedInternal =
false;
1797 m_currentPosition = time;
1800 m_pausedInternal =
false;
1801 m_currentProgressTime = 0;
1802 m_baseSeekTime = time;
1803 if (m_progressTimer.isActive())
1804 m_progressTimer.stop();
1807 m_currentPosition = time;
1810 m_currentProgressTime = 0;
1811 m_baseSeekTime = time;
1812 m_pausedInternal =
false;
1815 m_source->getMediaTime(npt);
1816 m_baseSeekTime = (
long long) npt/1000;
1817 LOG_INFO(
"BaseTime that we received is = %f", m_baseSeekTime);
1819 m_playerClient->timeChanged();
1821 if (m_progressTimer.isActive())
1822 m_progressTimer.stop();
1826 LOG_ERROR(
"Seek failed");
1831 bool MediaPlayerDLNA::rmf_isPaused()
const {
1838 bool MediaPlayerDLNA::rmf_isSeeking()
const {
1842 void MediaPlayerDLNA::notifyPresenceOfVideo()
1845 m_isMusicOnlyAsset =
false;
1848 void MediaPlayerDLNA::notifyPlayerOfEISSData()
1850 if (m_onEISSDUpdateHandler)
1851 g_source_remove(m_onEISSDUpdateHandler);
1853 m_onEISSDUpdateHandler = g_timeout_add(0, [](gpointer data) -> gboolean {
1855 self.m_onEISSDUpdateHandler = 0;
1856 self.onEISSDUpdate();
1857 return G_SOURCE_REMOVE;
1861 void MediaPlayerDLNA::notifyPlayerOfFirstVideoFrame() {
1863 LOG_INFO(
"Received First Video Frame for the playback of the URL=%s with "
1864 "play speed = %f time position = %f",
1869 LOG_INFO(
"Received First Video Frame for the trickmode in the URL=%s with "
1870 "play speed = %f time position = %f",
1875 m_allowPositionQueries =
true;
1876 if (m_onFirstVideoFrameHandler)
1877 g_source_remove(m_onFirstVideoFrameHandler);
1878 m_onFirstVideoFrameHandler = g_timeout_add(0, [](gpointer data) -> gboolean {
1880 self.m_onFirstVideoFrameHandler = 0;
1881 self.onFirstVideoFrame();
1882 return G_SOURCE_REMOVE;
1886 void MediaPlayerDLNA::notifyPMTUpdate() {
1889 LOG_INFO(
"MediaPlayerDLNA::notifyPMTUpdate - Send pmtUpdate");
1890 m_playerClient->pmtUpdate();
1891 m_pmtUpdate =
false;
1895 LOG_INFO(
"MediaPlayerDLNA::notifyPMTUpdate - Send PSIReady");
1896 m_playerClient->psiReady();
1900 void MediaPlayerDLNA::notifyLanguageChange() {
1901 LOG_INFO(
"MediaPlayerDLNA::notifyLanguageChange - Send languageChange");
1902 m_playerClient->languageChange();
1905 void MediaPlayerDLNA::onFirstVideoFrame() {
1907 if (m_isVOnlyOnce) {
1910 m_isVOnlyOnce =
false;
1913 if (m_VODKeepPipelinePlaying) {
1914 if (m_isVODAsset && !m_EOSPending && !m_fetchTrickModeHeaders) {
1926 void MediaPlayerDLNA::onEISSDUpdate()
1928 m_playerClient->eissDataReceived();
1931 void MediaPlayerDLNA::notifyPlayerOfFirstAudioFrame() {
1933 LOG_INFO(
"Received First Audio Sample for the playback of URL=%s with play "
1934 "speed = %f time position = %f",
1939 LOG_INFO(
"Received First Audio Sample for the trickmode in URL=%s with play "
1940 "speed = %f time position = %f",
1946 if (m_isMusicOnlyAsset)
1947 m_allowPositionQueries =
true;
1949 if (m_onFirstAudioFrameHandler)
1950 g_source_remove(m_onFirstAudioFrameHandler);
1951 m_onFirstAudioFrameHandler = g_timeout_add(0, [](gpointer data) -> gboolean {
1953 self.m_onFirstAudioFrameHandler = 0;
1954 self.onFirstAudioFrame();
1955 return G_SOURCE_REMOVE;
1959 void MediaPlayerDLNA::onFirstAudioFrame() {
1960 if (m_isAOnlyOnce) {
1962 m_isAOnlyOnce =
false;
1966 void MediaPlayerDLNA::onFrameReceived() {
1968 if (m_isVOnlyOnce && m_isAOnlyOnce)
1971 m_playerClient->videoDecoderHandleReceived();
1972 m_playerClient->mediaFrameReceived();
1976 void MediaPlayerDLNA::notifyPlayerOfMediaWarning() {
1977 if (m_onMediaWarningReceivedHandler)
1978 g_source_remove(m_onMediaWarningReceivedHandler);
1979 m_onMediaWarningReceivedHandler = g_timeout_add(0, [](gpointer data) -> gboolean {
1981 self.m_onMediaWarningReceivedHandler = 0;
1982 self.onMediaWarningReceived();
1983 return G_SOURCE_REMOVE;
1987 void MediaPlayerDLNA::onMediaWarningReceived() {
1989 m_rmfMediaWarnDesc = m_sink->getMediaWarningString();
1990 m_rmfMediaWarnData = m_sink->getMediaBufferSize();
1991 m_playerClient->mediaWarningReceived();
1995 void MediaPlayerDLNA::onPlay() {
1997 m_isEndReached =
false;
2002 m_sink->setVideoRectangle(m_lastKnownRect.x(),
2003 m_lastKnownRect.y(),
2004 m_lastKnownRect.width(),
2005 m_lastKnownRect.height(),
2010 m_sink->setMuted(
true);
2013 m_currentPosition = rmf_getCurrentTime();
2018 void MediaPlayerDLNA::onPause() {
2023 void MediaPlayerDLNA::onStop() {
2028 void MediaPlayerDLNA::rmf_setVolume(
float volume) {
2032 m_sink->setVolume(volume);
2035 float MediaPlayerDLNA::rmf_getVolume()
const {
2039 return m_sink->getVolume();
2042 void MediaPlayerDLNA::rmf_setRate(
float rate) {
2044 "setRate called new speed=%f previous speed=%f pos=%f",
2047 playbackPosition());
2048 rmf_changeSpeed(rate, 0.0f);
2051 void MediaPlayerDLNA::rmf_changeSpeed(
float rate,
short overShootTime) {
2052 LOG_INFO(
"changeSpeed called new speed=%f previous speed=%f pos=%f, overShootTime=%d", rate,
2053 rmf_getRate(), playbackPosition(), overShootTime);
2055 LOG_INFO(
"No source, skip changeSpeed.");
2058 #ifdef ENABLE_DIRECT_QAM
2060 if (!(m_isDVRAsset | m_isVODAsset))
2063 if (m_playbackRate == rate)
2066 m_pausedInternal =
true;
2069 m_currentPosition = rmf_getCurrentTime();
2070 m_currentPosition += overShootTime;
2072 if (m_currentPosition < 0)
2073 m_currentPosition = 0;
2075 double position = m_currentPosition;
2078 if (!m_VODKeepPipelinePlaying) {
2079 m_allowPositionQueries =
false;
2082 if (m_VODKeepPipelinePlaying) {
2084 LOG_INFO(
"Rate Change is not accepted as VOD Server posted that it is sending EOS shortly");
2087 if (!m_isAOnlyOnce) {
2088 fetchHeadersForTrickMode(rate, position);
2089 m_pausedInternal =
false;
2091 m_isVODRateChangeRequested =
true;
2093 m_isVODRateChangeRequested =
false;
2097 m_playbackRate = rate;
2098 m_currentProgressTime = 0;
2099 m_baseSeekTime = m_currentPosition;
2101 if (m_progressTimer.isActive())
2102 m_progressTimer.stop();
2106 m_source->setSpeed (rate);
2107 m_source->setMediaTime((m_baseSeekTime * 1000));
2110 m_source->getMediaTime(npt);
2111 m_baseSeekTime = (
long long) npt/1000;
2112 m_pausedInternal =
false;
2114 if (m_source->play (rate, position) == RMF_RESULT_SUCCESS)
2115 m_playerClient->rateChanged();
2119 m_playbackRate = rate;
2120 m_allowPositionQueries =
false;
2121 if (m_source->play (rate, position) == RMF_RESULT_SUCCESS)
2122 m_playerClient->rateChanged();
2124 LOG_ERROR(
"Requested rate change(%f) is failed...", m_playbackRate);
2125 m_playerClient->timeChanged();
2130 MediaPlayer::RMFPlayerState MediaPlayerDLNA::rmf_playerState ()
const {
2131 return m_playerState;
2134 MediaPlayer::RMFVideoBufferState MediaPlayerDLNA::rmf_videoState()
const {
2135 return m_videoState;
2138 float MediaPlayerDLNA::maxTimeLoaded()
const {
2142 return rmf_getDuration();
2145 void MediaPlayerDLNA::cancelLoad() {
2146 if (m_playerState < MediaPlayer::RMF_PLAYER_LOADING ||
2147 m_playerState == MediaPlayer::RMF_PLAYER_LOADED)
2153 void MediaPlayerDLNA::updateStates() {
2157 if (m_errorOccured) {
2162 MediaPlayer::RMFPlayerState oldNetworkState = m_playerState;
2163 MediaPlayer::RMFVideoBufferState oldReadyState = m_videoState;
2167 RMFStateChangeReturn ret = m_source->getState(&state, &pending);
2168 LOG_VERBOSE(
"updateStates(): state: %s, pending: %s, ret = %s",
2169 gst_element_state_get_name((GstState) state),
2170 gst_element_state_get_name((GstState) pending),
2171 gst_element_state_change_return_get_name((GstStateChangeReturn) ret));
2173 bool shouldUpdateAfterSeek =
false;
2175 case RMF_STATE_CHANGE_SUCCESS:
2176 LOG_VERBOSE(
"State: %s, pending: %s",
2177 gst_element_state_get_name((GstState) state),
2178 gst_element_state_get_name((GstState) pending));
2181 if (state == RMF_STATE_READY) {
2182 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVEMETADATA;
2183 m_playerState = MediaPlayer::RMF_PLAYER_EMPTY;
2188 #ifdef ENABLE_DIRECT_QAM
2195 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVEENOUGHDATA;
2197 }
else if (maxTimeLoaded() == rmf_getDuration()) {
2198 m_playerState = MediaPlayer::RMF_PLAYER_LOADED;
2199 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVEENOUGHDATA;
2201 m_videoState = rmf_getCurrentTime() < maxTimeLoaded() ? MediaPlayer::RMF_VIDEO_BUFFER_HAVEFUTUREDATA : MediaPlayer::RMF_VIDEO_BUFFER_HAVECURRENTDATA;
2202 m_playerState = MediaPlayer::RMF_PLAYER_LOADING;
2207 if (state == RMF_STATE_PAUSED) {
2208 if (rmf_getCurrentTime() < rmf_getDuration()) {
2209 m_pausedInternal =
true;
2210 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVECURRENTDATA;
2211 m_playerState = MediaPlayer::RMF_PLAYER_LOADING;
2212 m_playerClient->timeChanged();
2214 }
else if (state == RMF_STATE_PLAYING) {
2215 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVEENOUGHDATA;
2216 m_playerState = MediaPlayer::RMF_PLAYER_LOADED;
2217 m_pausedInternal =
false;
2220 m_playerClient->timeChanged();
2222 m_pausedInternal =
true;
2225 if (rmf_isSeeking()) {
2226 shouldUpdateAfterSeek =
true;
2231 case RMF_STATE_CHANGE_ASYNC:
2232 LOG_VERBOSE(
"Async: State: %s, pending: %s",
2233 gst_element_state_get_name((GstState)state),
2234 gst_element_state_get_name((GstState)pending));
2240 if (rmf_isSeeking()) {
2241 shouldUpdateAfterSeek =
true;
2245 case RMF_STATE_CHANGE_FAILURE:
2246 LOG_VERBOSE(
"Failure: State: %s, pending: %s",
2247 gst_element_state_get_name((GstState)state),
2248 gst_element_state_get_name((GstState)pending));
2251 case RMF_STATE_CHANGE_NO_PREROLL:
2252 LOG_VERBOSE(
"No preroll: State: %s, pending: %s",
2253 gst_element_state_get_name((GstState)state),
2254 gst_element_state_get_name((GstState)pending));
2256 if (state == RMF_STATE_READY) {
2257 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVENOTHING;
2258 }
else if (state == RMF_STATE_PAUSED) {
2259 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVEENOUGHDATA;
2260 m_pausedInternal =
true;
2262 m_isStreaming =
true;
2263 }
else if (state == RMF_STATE_PLAYING) {
2264 m_pausedInternal =
false;
2267 if (rmf_isSeeking()) {
2268 shouldUpdateAfterSeek =
true;
2270 if (!m_pausedInternal)
2272 }
else if (!m_pausedInternal) {
2276 m_playerState = MediaPlayer::RMF_PLAYER_LOADING;
2279 LOG_VERBOSE(
"Else : %d", ret);
2283 if (rmf_isSeeking())
2284 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVENOTHING;
2286 if (shouldUpdateAfterSeek)
2287 m_playerClient->timeChanged();
2289 if (m_playerState != oldNetworkState) {
2290 LOG_INFO(
"Network State Changed from %u to %u",
2291 oldNetworkState, m_playerState);
2292 m_playerClient->playerStateChanged();
2294 if (m_videoState != oldReadyState) {
2295 LOG_INFO(
"Ready State Changed from %u to %u",
2296 oldReadyState, m_videoState);
2297 m_playerClient->videoStateChanged();
2300 if (!m_progressTimer.isActive() && !rmf_isSeeking() && !m_paused)
2301 m_progressTimer.startOneShot(0);
2304 void MediaPlayerDLNA::timeChanged() {
2306 m_playerClient->timeChanged();
2309 void MediaPlayerDLNA::ended() {
2310 if (m_progressTimer.isActive())
2311 m_progressTimer.stop();
2313 m_isEndReached =
true;
2315 if (m_playbackRate < 0)
2317 LOG_INFO(
"MediaPlayerDLNA: We have hit starting point when rewinding; Start from beginning\n");
2318 m_playbackRate = 1.0f;
2319 m_playerClient->rateChanged();
2320 rmf_seekToStartPosition();
2323 else if (m_isInProgressRecording && (m_playbackRate >= 1))
2325 LOG_INFO(
"MediaPlayerDLNA: We have got EOS for the asset and lets switch to Live/LivePoint\n");
2326 m_playbackRate = 1.0f;
2327 m_playerClient->rateChanged();
2328 rmf_seekToLivePosition();
2335 float now = rmf_getCurrentTime();
2337 m_mediaDuration = now;
2338 m_mediaDurationKnown =
true;
2339 m_playerClient->durationChanged();
2341 m_playerClient->timeChanged();
2342 m_playerClient->mediaPlaybackCompleted();
2345 void MediaPlayerDLNA::cacheDuration() {
2346 if (0 == m_mediaDuration)
2347 m_mediaDuration = rmf_getCurrentTime();
2349 m_mediaDurationKnown = !std::isinf(m_mediaDuration);
2352 void MediaPlayerDLNA::durationChanged() {
2353 float previousDuration = m_mediaDuration;
2359 if (previousDuration && m_mediaDuration != previousDuration)
2360 m_playerClient->durationChanged();
2363 void MediaPlayerDLNA::rmf_setMute(
bool muted) {
2366 m_sink->setMuted(muted);
2369 void MediaPlayerDLNA::loadingFailed(MediaPlayer::RMFPlayerState error) {
2370 LOG_ERROR(
"error=%s", StateString(error));
2371 m_errorOccured =
true;
2372 if (m_playerState != error) {
2373 m_playerState = error;
2374 m_playerClient->playerStateChanged();
2376 if (m_videoState != MediaPlayer::RMF_VIDEO_BUFFER_HAVENOTHING) {
2377 m_videoState = MediaPlayer::RMF_VIDEO_BUFFER_HAVENOTHING;
2378 m_playerClient->videoStateChanged();
2382 void MediaPlayerDLNA::rmf_setVideoRectangle(
2383 unsigned x,
unsigned y,
unsigned w,
unsigned h) {
2385 if (m_lastKnownRect != temp) {
2386 m_lastKnownRect = temp;
2388 LOG_VERBOSE(
"setVideoRectangle: %d,%d %dx%d", x, y, w, h);
2389 m_sink->setVideoRectangle(x, y, w, h,
true);
2395 bool MediaPlayerDLNA::supportsUrl(
const std::string& urlStr)
2398 has_substring(urlStr,
"/hnStreamStart") ||
2399 has_substring(urlStr,
"/vldms/") ||
2400 has_substring(urlStr,
"ocap://") ||
2401 has_substring(urlStr,
"tune://") ||
2402 has_substring(urlStr,
"vod://") ||
2403 has_substring(urlStr,
"ippv://") ||
2404 has_substring(urlStr,
"profile=MPEG_TS") ||
2405 has_substring(urlStr,
".ts") ||
2406 has_substring(urlStr,
".m2ts");