43 #include <semaphore.h>
48 #include <openssl/sha.h>
58 #ifdef AAMP_VANILLA_AES_SUPPORT
62 #include "SubtecFactory.hpp"
65 #include "AampUtils.h"
73 #ifdef AAMP_CC_ENABLED
84 unsigned char * metadataPtr;
90 int deferredInterval ;
91 long long drmKeyReqTime;
94 #define DRM_SHA1_HASH_LEN 40
96 static const int DEFAULT_STREAM_WIDTH = 720;
97 static const int DEFAULT_STREAM_HEIGHT = 576;
98 static const double DEFAULT_STREAM_FRAMERATE = 25.0;
101 #define IS_FOR_IFRAME(rate, type) ((type == eTRACK_VIDEO) && (rate != AAMP_NORMAL_PLAY_RATE))
109 #define UseProgramDateTimeIfAvailable() (ISCONFIGSET(eAAMPConfig_HLSAVTrackSyncUsingStartTime) || aamp->mIsVSS)
118 static size_t FindLineLength(
const char* ptr);
128 static bool startswith(
const char **pstring,
const char *prefix)
130 const char *
string = *pstring;
154 static bool startswith(
char **pstring,
const char *prefix)
156 char *
string = *pstring;
182 static bool AttributeNameMatch(
const char *attrNamePtr,
const char *targetAttrNameCString)
184 while (*targetAttrNameCString)
186 if (*targetAttrNameCString++ != *attrNamePtr++)
191 return *attrNamePtr ==
'=';
203 static bool SubStringMatch(
const char *srcStart,
const char *srcFin,
const char *cstring)
205 while (srcStart <= srcFin)
229 static const char * GetAttributeValueString(
char *valuePtr,
char *fin)
231 const char *rc = NULL;
232 if (*valuePtr ==
'\"')
239 AAMPLOG_WARN(
"quoted-string missing end-quote:%s",valuePtr );
246 if( memcmp(valuePtr,
"NONE",4) !=0 )
248 AAMPLOG_WARN(
"GetAttributeValueString input neither quoted string nor NONE");
264 static void ParseKeyAttributeCallback(
char *attrName,
char *delimEqual,
char *fin,
void* arg)
267 char *valuePtr = delimEqual + 1;
268 if (AttributeNameMatch(attrName,
"METHOD"))
270 if (SubStringMatch(valuePtr, fin,
"NONE"))
276 AAMPLOG_WARN(
"Track %s encrypted to clear ", ts->
name);
283 else if (SubStringMatch(valuePtr, fin,
"AES-128"))
289 AAMPLOG_WARN(
"Track %s clear to encrypted ", ts->
name);
300 else if (SubStringMatch(valuePtr, fin,
"SAMPLE-AES-CTR"))
307 AAMPLOG_WARN(
"Track %s clear to encrypted", ts->
name);
313 else if (SubStringMatch(valuePtr, fin,
"SAMPLE-AES"))
316 AAMPLOG_ERR(
"SAMPLE-AES unsupported");
321 AAMPLOG_ERR(
"unsupported METHOD");
324 else if (AttributeNameMatch(attrName,
"KEYFORMAT"))
326 const char *keyFormat = GetAttributeValueString(valuePtr, fin);
329 if (startswith(&keyFormat,
"urn:uuid:"))
334 else if (AttributeNameMatch(attrName,
"URI"))
336 const char *uri = GetAttributeValueString(valuePtr, fin);
339 else if (AttributeNameMatch(attrName,
"IV"))
341 const char *srcPtr = valuePtr;
342 assert(srcPtr[0] ==
'0');
343 assert((srcPtr[1] ==
'x') || (srcPtr[1] ==
'X'));
348 else if (AttributeNameMatch(attrName,
"CMSha1Hash"))
350 assert(valuePtr[0] ==
'0');
351 assert((valuePtr[1] ==
'x') || (valuePtr[1] ==
'X'));
366 static void ParseTileInfCallback(
char *attrName,
char *delimEqual,
char *fin,
void* arg)
370 const char *valuePtr = delimEqual + 1;
371 if (AttributeNameMatch(attrName,
"LAYOUT"))
376 else if (AttributeNameMatch(attrName,
"DURATION"))
393 static void ParseXStartAttributeCallback(
char *attrName,
char *delimEqual,
char *fin,
void* arg)
396 char *valuePtr = delimEqual + 1;
397 if (AttributeNameMatch(attrName,
"TIME-OFFSET"))
399 var->
offset = atof(valuePtr);
401 else if (AttributeNameMatch(attrName,
"PRECISE"))
418 static void ParseStreamInfCallback(
char *attrName,
char *delimEqual,
char *fin,
void* arg)
421 char *valuePtr = delimEqual + 1;
422 HlsStreamInfo *streamInfo = &context->streamInfo[context->GetTotalProfileCount()];
423 if (AttributeNameMatch(attrName,
"URI"))
425 streamInfo->
uri = GetAttributeValueString(valuePtr, fin);
427 else if (AttributeNameMatch(attrName,
"BANDWIDTH"))
431 else if (AttributeNameMatch(attrName,
"PROGRAM-ID"))
435 else if (AttributeNameMatch(attrName,
"AUDIO"))
437 streamInfo->
audio = GetAttributeValueString(valuePtr, fin);
439 else if (AttributeNameMatch(attrName,
"CODECS"))
441 streamInfo->
codecs = GetAttributeValueString(valuePtr, fin);
443 else if (AttributeNameMatch(attrName,
"RESOLUTION"))
448 else if (AttributeNameMatch(attrName,
"AVERAGE-BANDWIDTH"))
452 else if (AttributeNameMatch(attrName,
"FRAME-RATE"))
456 else if (AttributeNameMatch(attrName,
"CLOSED-CAPTIONS"))
458 streamInfo->
closedCaptions = GetAttributeValueString(valuePtr, fin);
460 else if (AttributeNameMatch(attrName,
"SUBTITLES"))
462 streamInfo->
subtitles = GetAttributeValueString(valuePtr, fin);
466 AAMPLOG_INFO(
"unknown stream inf attribute %s", attrName);
480 static void ParseMediaAttributeCallback(
char *attrName,
char *delimEqual,
char *fin,
void *arg)
483 char *valuePtr = delimEqual + 1;
484 struct MediaInfo *mediaInfo = &context->mediaInfo[context->GetMediaCount()];
489 if (AttributeNameMatch(attrName,
"TYPE"))
491 if (SubStringMatch(valuePtr, fin,
"AUDIO"))
495 else if (SubStringMatch(valuePtr, fin,
"VIDEO"))
499 else if (SubStringMatch(valuePtr, fin,
"SUBTITLES"))
503 else if (SubStringMatch(valuePtr, fin,
"CLOSED-CAPTIONS"))
506 mediaInfo->
isCC =
true;
509 else if (AttributeNameMatch(attrName,
"GROUP-ID"))
511 mediaInfo->
group_id = GetAttributeValueString(valuePtr, fin);
513 else if (AttributeNameMatch(attrName,
"NAME"))
515 mediaInfo->
name = GetAttributeValueString(valuePtr, fin);
517 else if (AttributeNameMatch(attrName,
"LANGUAGE"))
519 mediaInfo->
language = GetAttributeValueString(valuePtr, fin);
521 else if (AttributeNameMatch(attrName,
"AUTOSELECT"))
523 if (SubStringMatch(valuePtr, fin,
"YES"))
528 else if (AttributeNameMatch(attrName,
"DEFAULT"))
530 if (SubStringMatch(valuePtr, fin,
"YES"))
535 else if (AttributeNameMatch(attrName,
"URI"))
537 mediaInfo->
uri = GetAttributeValueString(valuePtr, fin);
540 else if (AttributeNameMatch(attrName,
"CHANNELS"))
542 mediaInfo->
channels = atoi(valuePtr);
544 else if (AttributeNameMatch(attrName,
"INSTREAM-ID"))
546 mediaInfo->
instreamID = GetAttributeValueString(valuePtr, fin);
548 else if (AttributeNameMatch(attrName,
"FORCED"))
550 if (SubStringMatch(valuePtr, fin,
"YES"))
555 else if (AttributeNameMatch(attrName,
"CHARACTERISTICS"))
561 AAMPLOG_WARN(
"unk MEDIA attr %s", attrName);
572 static char *mystrpbrk(
char *ptr)
578 fin = strchr(ptr, CHAR_LF);
585 while(fin > ptr && fin[-1] == CHAR_CR)
606 static void ParseAttrList(
char *attrName,
void(*cb)(
char *attrName,
char *delim,
char *fin,
void *context),
void *context)
608 char *origParseStr = attrName;
611 while (*attrName ==
' ')
615 char *delimEqual = attrName;
616 if(*delimEqual ==
'\r')
620 while (*delimEqual !=
'=')
622 char c = *delimEqual++;
626 AAMPLOG_WARN(
"Missing equal delimiter %s",origParseStr);
630 char *fin = delimEqual;
631 bool inQuote =
false;
652 else if (c ==
',' && !inQuote)
658 cb(attrName, delimEqual, fin, context);
675 static double ParseXStartTimeOffset(
const char* ptr)
677 double retOffSet = 0.0;
681 size_t len = FindLineLength(ptr);
682 char* xstartStr =(
char*) malloc (len+1);
685 memcpy(xstartStr,ptr,len);
689 ParseAttrList(xstartStr, ParseXStartAttributeCallback, &xstart);
691 retOffSet = xstart.
offset;
703 static void * TrackPLDownloader(
void *arg)
706 if(aamp_pthread_setname(pthread_self(),
"aampHLSAudPLDL"))
708 AAMPLOG_WARN(
"aamp_pthread_setname failed");
725 if (aamp->fragmentCdmEncrypted &&
ISCONFIGSET(eAAMPConfig_Fragmp4PrefetchLicense)){
726 pthread_mutex_lock(&aamp->drmParserMutex);
728 for (
int i=0; i < aamp->aesCtrAttrDataList.size(); i++ ){
729 if (!aamp->aesCtrAttrDataList.at(i).isProcessed){
730 aamp->aesCtrAttrDataList.at(i).isProcessed =
true;
731 DrmSessionDataInfo* drmData = ProcessContentProtection(aamp, aamp->aesCtrAttrDataList.at(i).attrName);
732 if (NULL != drmData){
734 if (NULL != drmDataToUse) {
737 drmDataToUse = drmData;
741 if (drmDataToUse !=
nullptr)
745 pthread_mutex_unlock(&aamp->drmParserMutex);
746 if (NULL != drmDataToUse) {
753 void static setupStreamInfo(
struct HlsStreamInfo * streamInfo,
int streamNo)
766 int vProfileCount, iFrameCount , lineNum;
771 vProfileCount = iFrameCount = lineNum = 0;
776 char *next = mystrpbrk(ptr);
779 if (startswith(&ptr,
"#EXT"))
781 if (startswith(&ptr,
"-X-I-FRAME-STREAM-INF:"))
789 next = mystrpbrk(next);
803 else if (startswith(&ptr,
"-X-IMAGE-STREAM-INF:"))
811 next = mystrpbrk(next);
823 else if (startswith(&ptr,
"-X-STREAM-INF:"))
831 next = mystrpbrk(next);
850 else if (startswith(&ptr,
"-X-MEDIA:"))
864 else if (startswith(&ptr,
"-X-VERSION:"))
868 else if (startswith(&ptr,
"-X-INDEPENDENT-SEGMENTS"))
872 else if (startswith(&ptr,
"-X-FAXS-CM"))
876 else if (startswith(&ptr,
"M3U"))
881 AAMPLOG_WARN(
"M3U tag not the first line[%d] of Manifest",lineNum);
886 else if (startswith(&ptr,
"-X-CONTENT-IDENTIFIER:"))
889 else if (startswith(&ptr,
"-X-FOG"))
892 else if (startswith(&ptr,
"-X-XCAL-CONTENTMETADATA"))
895 else if (startswith(&ptr,
"-NOM-I-FRAME-DISTANCE"))
898 else if (startswith(&ptr,
"-X-ADVERTISING"))
901 else if (startswith(&ptr,
"-UPLYNK-LIVE"))
904 else if (startswith(&ptr,
"-X-START:"))
909 double offsetval = ParseXStartTimeOffset(ptr);
921 AAMPLOG_WARN(
"WARNING:found EXT-X-START in MainManifest Offset:%f liveOffset:%f",offsetval,
aamp->mLiveOffset);
925 else if (startswith(&ptr,
"INF:"))
933 else if (startswith(&ptr,
"-X-SESSION-KEY:"))
935 if (
ISCONFIGSET(eAAMPConfig_Fragmp4PrefetchLicense))
938 len = FindLineLength(ptr);
939 std::string KeyTagStr(ptr,len);
941 pthread_mutex_lock(&
aamp->drmParserMutex);
942 attrNameData* aesCtrAttrData =
new attrNameData(KeyTagStr);
943 if (std::find(
aamp->aesCtrAttrDataList.begin(),
aamp->aesCtrAttrDataList.end(),
944 *aesCtrAttrData) ==
aamp->aesCtrAttrDataList.end()) {
945 AAMPLOG_INFO(
"Adding License data from Main Manifest %s",KeyTagStr.c_str());
946 aamp->aesCtrAttrDataList.push_back(*aesCtrAttrData);
948 SAFE_DELETE(aesCtrAttrData);
949 pthread_mutex_unlock(&
aamp->drmParserMutex);
950 aamp->fragmentCdmEncrypted =
true;
951 InitiateDrmProcess(this->aamp);
957 std::string unknowTag= ptr;
958 AAMPLOG_INFO(
"***unknown tag:%s", unknowTag.substr(0,24).c_str());
969 if(vProfileCount == 0)
971 AAMPLOG_WARN(
"ERROR No video profiles available in manifest for playback");
979 AAMPLOG_WARN(
"WARNING !!! No media definitions in manifest for playback");
984 AAMPLOG_WARN(
"WARNING !!! No iframe definitions .Trickplay not supported");
1033 AAMPLOG_WARN(
"rate - %f playTarget(%f) > seekWindowEnd(%f), forcing EOS",
1046 if (node->completionTimeSecondsFromStart >=
playTarget)
1049 AAMPLOG_WARN(
"Found node - rate %f completionTimeSecondsFromStart %f playTarget %f",
1066 if (node->completionTimeSecondsFromStart <=
playTarget)
1069 AAMPLOG_WARN(
"Found node - rate %f completionTimeSecondsFromStart %f playTarget %f",
1080 if ( idxNode->initFragmentPtr
1083 AAMPLOG_TRACE(
"init fragment injection required (%s)", idxNode->initFragmentPtr );
1092 const char *fragmentInfo = idxNode->pFragmentInfo;
1102 bSegmentRepeated =
true;
1106 bSegmentRepeated =
false;
1110 while (fragmentInfo[0] ==
'#')
1112 if (!memcmp(fragmentInfo,
"#EXT-X-BYTERANGE:", 17))
1115 const char * end = fragmentInfo;
1116 while (end[0] != CHAR_LF)
1120 int len = end - fragmentInfo;
1122 strncpy(temp, fragmentInfo + 17, len);
1124 char * offsetDelim = strchr(temp,
'@');
1127 *offsetDelim++ = 0x00;
1133 while (fragmentInfo[0] != CHAR_LF)
1139 const char *urlEnd = strchr(fragmentInfo, CHAR_LF);
1142 if (*(urlEnd - 1) == CHAR_CR)
1146 int urlLen = urlEnd - fragmentInfo;
1162 AAMPLOG_WARN(
"unable to find end");
1164 if (-1 == idxNode->drmMetadataIdx)
1173 int keyIndexPosn = idxNode->drmMetadataIdx;
1176 AAMPLOG_WARN(
"[%d] KeyTable Size [%zu] keyIndexPosn[%d] lastKeyIdx[%d]",
type, mKeyHashTable.size(), keyIndexPosn,
mLastKeyTagIdx);
1177 if(keyIndexPosn < mKeyHashTable.size() && mKeyHashTable[keyIndexPosn].mKeyTagStr.size())
1181 char* key =(
char*) malloc (mKeyHashTable[keyIndexPosn].mKeyTagStr.size());
1182 memcpy(key,mKeyHashTable[keyIndexPosn].mKeyTagStr.c_str(),mKeyHashTable[keyIndexPosn].mKeyTagStr.size());
1185 ParseAttrList((
char *)key, ParseKeyAttributeCallback,
this);
1196 AAMPLOG_WARN(
"Couldn't find node - rate %f playTarget %f",
1212 const char* programDateTime = NULL;
1218 AAMPLOG_WARN(
"[!!!!! WARNING !!!!] Invalid playTarget %f, so set playTarget to 0",
playTarget);
1235 AAMPLOG_WARN(
"playlistPosition[%f] > playTarget[%f] more than last fragmentDurationSeconds[%f]",
1246 char *next = mystrpbrk(ptr);
1250 if (startswith(&ptr,
"#EXT"))
1252 if (startswith(&ptr,
"M3U"))
1255 else if (startswith(&ptr,
"INF:"))
1267 AAMPLOG_WARN(
"Next - EXTINF - playlistPosition updated to %f",
playlistPosition);
1271 else if (startswith(&ptr,
"-X-BYTERANGE:"))
1274 strncpy(temp, ptr, 1023);
1276 char * offsetDelim = strchr(temp,
'@');
1279 *offsetDelim++ = 0x00;
1289 AAMPLOG_TRACE(
"byteRangeOffset:%zu Last played fragment Offset:%zu byteRangeLength:%zu Last fragment Length:%zu", byteRangeOffset, this->byteRangeOffset,
byteRangeLength, this->byteRangeLength);
1291 else if (startswith(&ptr,
"-X-TARGETDURATION:"))
1295 else if (startswith(&ptr,
"-X-MEDIA-SEQUENCE:"))
1299 else if (startswith(&ptr,
"-X-KEY:"))
1303 else if(startswith(&ptr,
"-X-MAP:"))
1313 else if (startswith(&ptr,
"-X-PROGRAM-DATE-TIME:"))
1319 programDateTime = ptr;
1329 else if (startswith(&ptr,
"-X-ALLOW-CACHE:"))
1331 if (startswith(&ptr,
"YES"))
1335 else if (startswith(&ptr,
"NO"))
1341 AAMPLOG_ERR(
"unknown ALLOW-CACHE setting");
1344 else if (startswith(&ptr,
"-X-PLAYLIST-TYPE:"))
1348 else if (startswith(&ptr,
"-X-ENDLIST"))
1350 AAMPLOG_WARN(
"#EXT-X-ENDLIST");
1353 else if (startswith(&ptr,
"-X-DISCONTINUITY-SEQUENCE"))
1357 else if (startswith(&ptr,
"-X-DISCONTINUITY"))
1361 else if (startswith(&ptr,
"-X-I-FRAMES-ONLY"))
1363 AAMPLOG_WARN(
"#EXT-X-I-FRAMES-ONLY");
1365 else if (startswith(&ptr,
"-X-VERSION:"))
1369 else if (startswith(&ptr,
"-X-FAXS-CM:"))
1373 else if (startswith(&ptr,
"-X-FAXS-PACKAGINGCERT"))
1376 else if (startswith(&ptr,
"-X-FAXS-SIGNATURE"))
1379 else if (startswith(&ptr,
"-X-CUE"))
1382 else if (startswith(&ptr,
"-X-CM-SEQUENCE"))
1385 else if (startswith(&ptr,
"-X-MARKER"))
1388 else if (startswith(&ptr,
"-X-MAP"))
1391 else if (startswith(&ptr,
"-X-MEDIA-TIME"))
1394 else if (startswith(&ptr,
"-X-END-TOP-TAGS"))
1397 else if (startswith(&ptr,
"-X-CONTENT-IDENTIFIER"))
1400 else if (startswith(&ptr,
"-X-TRICKMODE-RESTRICTION"))
1403 else if (startswith(&ptr,
"-X-INDEPENDENT-SEGMENTS"))
1406 else if (startswith(&ptr,
"-X-BITRATE"))
1409 else if (startswith(&ptr,
"-X-FOG"))
1412 else if (startswith(&ptr,
"-UPLYNK-LIVE"))
1415 else if (startswith(&ptr,
"-X-START:"))
1418 else if (startswith(&ptr,
"-X-XCAL-CONTENTMETADATA"))
1421 else if (startswith(&ptr,
"-NOM-I-FRAME-DISTANCE"))
1424 else if (startswith(&ptr,
"-X-ADVERTISING"))
1427 else if (startswith(&ptr,
"-X-SOURCE-STREAM"))
1430 else if (startswith(&ptr,
"-X-X1-LIN-CK"))
1433 else if (startswith(&ptr,
"-X-SCTE35"))
1436 else if (startswith(&ptr,
"-X-ASSET") || startswith(&ptr,
"-X-CUE-OUT") || startswith(&ptr,
"-X-CUE-IN") ||
1437 startswith(&ptr,
"-X-DATERANGE") || startswith(&ptr,
"-X-SPLICEPOINT-SCTE35"))
1442 std::string unknowTag= ptr;
1443 AAMPLOG_INFO(
"***unknown tag:%s", unknowTag.substr(0,24).c_str());
1446 else if (*ptr ==
'#')
1449 else if (*ptr ==
'\0')
1463 if (!ignoreDiscontinuity)
1471 AAMPLOG_WARN(
"Reusing last seen #EXT-X-MAP for this discontinuity, data: %s",
mInitFragmentInfo);
1481 if (!programDateTime)
1483 position = playPosition;
1488 AAMPLOG_WARN(
"[%s] Discontinuity - position from program-date-time %f",
name, position);
1490 if(mDiscontinuityCheckingOn)
1497 AAMPLOG_WARN(
"%s Checking HasDiscontinuity for position :%f, playposition :%f playtarget:%f mDiscontinuityCheckingOn:%d",
name,position,playPosition,
playTarget,mDiscontinuityCheckingOn);
1498 if (!mDiscontinuityCheckingOn)
1500 bool isDiffChkReq=
true;
1503 AAMPLOG_WARN(
"[%s] Ignoring discontinuity as %s track does not have discontinuity",
name, other->
name);
1506 else if ( programDateTime && isDiffChkReq )
1508 AAMPLOG_WARN(
"[WARN] [%s] diff %f with other track discontinuity position!!",
name, diff);
1514 AAMPLOG_WARN(
"[WARN!! Can be a Stream Issue!!] [%s] Other track's discontinuity time greater by %f. updating playTarget %f to %f",
1519 programDateTime = NULL;
1554 programDateTime = NULL;
1565 std::string url(rc);
1569 size_t found = url.rfind(std::to_string(seqNo));
1570 if (found != std::string::npos)
1573 std::string sequenceNumberNew = std::to_string(seqNo);
1574 url.replace(found,sequenceNumberNew.length(),sequenceNumberNew);
1576 AAMPLOG_INFO(
"Next fragment url %s",url.c_str());
1581 AAMPLOG_WARN(
"GetNextFragmentUriFromPlaylist %s: pos %f returning %s",
name,
playlistPosition, rc);
1596 char *initFragment = NULL;
1601 char *next = mystrpbrk(ptr);
1604 if (startswith(&ptr,
"#EXTINF:"))
1608 else if (startswith(&ptr,
"#EXT-X-MEDIA-SEQUENCE:"))
1612 else if (startswith(&ptr,
"#EXT-X-KEY:"))
1616 else if (startswith(&ptr,
"#EXT-X-MAP:"))
1620 else if (ptr[0] !=
'#')
1622 if (seq >= mediaSequenceNumber)
1637 if (seq != mediaSequenceNumber)
1639 AAMPLOG_WARN(
"seq gap %lld!=%lld", seq, mediaSequenceNumber);
1659 AAMPLOG_WARN(
"FetchFragmentHelper Enter: pos %f start %f frag-duration %f fragmentURI %s",
1664 bool bSegmentRepeated =
false;
1677 AAMPLOG_WARN(
"aamp rew to beginning");
1693 AAMPLOG_WARN(
"aamp ffw to end");
1730 std::string fragmentUrl;
1737 char rangeStr[MAX_RANGE_STRING_CHARS];
1741 snprintf(rangeStr,
sizeof(rangeStr),
"%zu-%zu",
byteRangeOffset, next - 1);
1742 AAMPLOG_WARN(
"FetchFragmentHelper rangeStr %s ", rangeStr);
1751 AAMPLOG_WARN(
"FetchFragmentHelper: fetching %s", fragmentUrl.c_str());
1755 std::string tempEffectiveUrl;
1758 tempEffectiveUrl, &http_error, &downloadTime, range,
type,
false, (
MediaType)(
type), NULL, NULL,
fragmentDurationSeconds,
pCMCDMetrics);
1783 if (AAMP_IS_LOG_WORTHY_ERROR(http_error))
1785 AAMPLOG_WARN(
"FetchFragmentHelper aamp_GetFile failed");
1789 int FragmentDownloadFailThreshold;
1793 AAMPLOG_ERR(
"Not able to download fragments; reached failure threshold sending tune failed event");
1808 std::size_t pos = fragmentUrl.find(FOG_FRAG_BW_IDENTIFIER);
1809 if (pos != std::string::npos)
1811 std::string bwStr = fragmentUrl.substr(pos + FOG_FRAG_BW_IDENTIFIER_LEN);
1814 pos = bwStr.find(FOG_FRAG_BW_DELIMITER);
1815 if (pos != std::string::npos)
1817 bwStr = bwStr.substr(0, pos);
1854 AAMPLOG_WARN (
"FetchFragmentHelper : Create Init Vector failed");
1868 decryption_error =
true;
1869 AAMPLOG_WARN(
"FetchFragmentHelper : drm_Decrypt failed due to license acquisition timeout");
1879 decryption_error =
true;
1880 AAMPLOG_ERR(
"FetchFragmentHelper : drm_Decrypt failed for fragments, reached failure threshold (%d) sending failure event",
aamp->
mDrmDecryptFailCount);
1892 AAMPLOG_WARN(
"aamp: hls - eMETHOD_AES_128 not set for %s",
fragmentURI);
1905 AAMPLOG_WARN(
"fragment. len zero for %s",
fragmentURI);
1913 AAMPLOG_INFO(
"FetchFragmentHelper : Found init fragment playTarget(%f), playlistPosition(%f)",
playTarget,
playlistPosition);
1934 long http_error = 0;
1935 double downloadTime = 0;
1936 bool decryption_error =
false;
1951 bool bKeyChanged =
false;
1952 int iFogErrorCode = -1;
1956 if (
false ==
FetchFragmentHelper(http_error, decryption_error,bKeyChanged,&iFogErrorCode, downloadTime))
1983 AAMPLOG_WARN(
"Error while fetching fragment:%s, failedCount:%d. decrementing profile",
name,
segDLFailCount);
1987 AAMPLOG_WARN(
"%s Already at the lowest profile, skipping segment",
name);
1992 else if (decryption_error)
1994 AAMPLOG_WARN(
"%s Error while decrypting fragments. failedCount:%d",
name,
segDLFailCount);
1996 else if (AAMP_IS_LOG_WORTHY_ERROR(http_error))
2070 AAMPLOG_WARN(
"%s cachedFragment->fragment.ptr is NULL",
name);
2072 #ifdef AAMP_DEBUG_INJECT
2073 if ((1 <<
type) & AAMP_DEBUG_INJECT)
2090 #ifndef FOG_HAMMER_TEST // support aamp stress-tests of fog without video decoding/presentation
2093 double position = 0;
2103 fragmentDiscarded =
false;
2118 static double GetCompletionTimeForFragment(
const TrackState *trackState,
long long mediaSequenceNumber)
2127 if (idx >= indexCount)
2129 idx = indexCount - 1;
2132 rc = node->completionTimeSecondsFromStart;
2136 AAMPLOG_WARN(
"bad index! mediaSequenceNumber=%lld, indexFirstMediaSequenceNumber=%lld", mediaSequenceNumber, trackState->
indexFirstMediaSequenceNumber);
2150 static void DumpIndex(
TrackState *trackState)
2152 AAMPLOG_WARN(
"index (%d fragments)", trackState->
indexCount);
2154 for (
int idx = 0; idx < trackState->
indexCount; idx++)
2157 AAMPLOG_WARN(
"%lld: %f %d", mediaSequenceNumber, node->completionTimeSecondsFromStart, node->drmMetadataIdx);
2158 mediaSequenceNumber++;
2170 mProgramDateTime = 0.0;
2178 mKeyHashTable.clear();
2187 assert(NULL != drmMetadataNode);
2190 AAMPLOG_TRACE(
"TrackState::drmMetadataNode[%d].metaData.metadataPtr %p",i,
2191 drmMetadataNode[i].metaData.metadataPtr);
2193 if ((NULL == drmMetadataNode[i].metaData.metadataPtr || NULL == drmMetadataNode[i].sha1Hash) &&
mDrmMetaDataIndexCount)
2195 AAMPLOG_WARN (
"TrackState: **** metadataPtr/sha1Hash is NULL, give attention and analyze it... mDrmMetaDataIndexCount[%d]",
mDrmMetaDataIndexCount);
2198 if (drmMetadataNode[i].metaData.metadataPtr)
2200 free(drmMetadataNode[i].metaData.metadataPtr);
2201 drmMetadataNode[i].metaData.metadataPtr = NULL;
2204 if (drmMetadataNode[i].sha1Hash)
2206 free(drmMetadataNode[i].sha1Hash);
2207 drmMetadataNode[i].sha1Hash = NULL;
2235 AAMPLOG_INFO(
"Drm support available");
2239 AAMPLOG_WARN(
"Failed to create Drm Session");
2246 #ifdef AAMP_VANILLA_AES_SUPPORT
2247 AAMPLOG_INFO(
"StreamAbstractionAAMP_HLS::Get AesDec");
2252 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: AAMP_VANILLA_AES_SUPPORT not defined");
2268 static char* GetNextLineStart(
char* ptr)
2270 ptr = strchr(ptr, CHAR_LF);
2284 static size_t FindLineLength(
const char* ptr)
2291 const char * delim = strchr(ptr, CHAR_LF);
2295 if (delim > ptr && delim[-1] == CHAR_CR)
2313 double totalDuration = 0.0;
2315 double prevProgramDateTime = mProgramDateTime;
2317 double prevSecondsBeforePlayPoint;
2318 const char *initFragmentPtr = NULL;
2320 if(IsRefresh && !UseProgramDateTimeIfAvailable())
2322 prevSecondsBeforePlayPoint = GetCompletionTimeForFragment(
this, commonPlayPosition);
2335 temp[tempDataLen] = 0x00;
2336 AAMPLOG_ERR(
"ERROR: Invalid Playlist URL:%s ",
mPlaylistUrl.c_str());
2337 AAMPLOG_ERR(
"ERROR: Invalid Playlist DATA:%s ", temp);
2339 mDuration = totalDuration;
2346 node.completionTimeSecondsFromStart = 0.0;
2347 node.pFragmentInfo = NULL;
2348 int drmMetadataIdx = -1;
2350 bool mediaSequence =
false;
2351 const char* programDateTimeIdxOfFragment = NULL;
2353 bool pdtAtTopAvailable=
false;
2359 double fragDuration = 0;
2363 if(startswith(&ptr,
"#EXT"))
2365 if (startswith(&ptr,
"INF:"))
2371 discontinuityIndexNode.
position = totalDuration;
2373 if (programDateTimeIdxOfFragment)
2382 programDateTimeIdxOfFragment = NULL;
2383 node.pFragmentInfo = ptr-8;
2384 fragDuration = atof(ptr);
2389 std::string urlname;
2390 char *urlstrstart=GetNextLineStart(ptr);
2391 char *urlstrend=GetNextLineStart(urlstrstart);
2392 urlname.assign(urlstrstart,(urlstrend-urlstrstart));
2393 AAMPLOG_WARN(
"%s [%d]:[%f]:[%f]:%s",
name,
indexCount,fragDuration,totalDuration,urlname.c_str());
2396 totalDuration += fragDuration;
2397 node.completionTimeSecondsFromStart = totalDuration;
2398 node.drmMetadataIdx = drmMetadataIdx;
2399 node.initFragmentPtr = initFragmentPtr;
2402 else if(startswith(&ptr,
"-X-MEDIA-SEQUENCE:"))
2405 mediaSequence =
true;
2411 else if(startswith(&ptr,
"-X-TARGETDURATION:"))
2416 else if(startswith(&ptr,
"-X-X1-LIN-CK:"))
2422 else if(startswith(&ptr,
"-X-PLAYLIST-TYPE:"))
2425 if (startswith(&ptr,
"VOD"))
2427 AAMPLOG_WARN(
"aamp: EXT-X-PLAYLIST-TYPE - VOD");
2430 else if (startswith(&ptr,
"EVENT"))
2432 AAMPLOG_WARN(
"aamp: EXT-X-PLAYLIST-TYPE = EVENT");
2437 AAMPLOG_ERR(
"unknown PLAYLIST-TYPE");
2440 else if(startswith(&ptr,
"-X-FAXS-CM:"))
2444 else if(startswith(&ptr,
"-X-DISCONTINUITY-SEQUENCE"))
2448 else if(startswith(&ptr,
"-X-DISCONTINUITY"))
2453 AAMPLOG_WARN(
"%s [%d] Discontinuity Posn : %f ",
name,
indexCount,totalDuration);
2456 else if (startswith(&ptr,
"-X-PROGRAM-DATE-TIME:"))
2458 programDateTimeIdxOfFragment = ptr;
2461 AAMPLOG_INFO(
"%s EXT-X-PROGRAM-DATE-TIME: %.*s ",
name, 30, programDateTimeIdxOfFragment);
2463 if(!pdtAtTopAvailable)
2470 mProgramDateTime = tmppdt - totalDuration;
2471 AAMPLOG_WARN(
"%s mProgramDateTime From Extrapolation : %f ",
name, mProgramDateTime);
2476 AAMPLOG_INFO(
"%s mProgramDateTime From Start : %f ",
name, mProgramDateTime);
2478 pdtAtTopAvailable =
true;
2488 else if (startswith(&ptr,
"-X-KEY:"))
2492 len = FindLineLength(ptr);
2493 char* key =(
char*) malloc (len+1);
2494 memcpy(key,ptr,len);
2505 memcpy((
char*)keyinfo.
mKeyTagStr.data(),key,len);
2515 if (
ISCONFIGSET(eAAMPConfig_Fragmp4PrefetchLicense)){
2516 pthread_mutex_lock(&
aamp->drmParserMutex);
2517 attrNameData* aesCtrAttrData =
new attrNameData(keyinfo.
mKeyTagStr);
2518 if (std::find(
aamp->aesCtrAttrDataList.begin(),
aamp->aesCtrAttrDataList.end(),
2519 *aesCtrAttrData) ==
aamp->aesCtrAttrDataList.end()) {
2521 aamp->aesCtrAttrDataList.push_back(*aesCtrAttrData);
2524 SAFE_DELETE(aesCtrAttrData);
2525 pthread_mutex_unlock(&
aamp->drmParserMutex);
2527 aamp->fragmentCdmEncrypted =
true;
2528 InitiateDrmProcess(this->aamp);
2536 drmMetadataIdx = -1;
2543 keyinfo.
mShaID.resize(DRM_SHA1_HASH_LEN);
2546 mKeyHashTable.push_back(keyinfo);
2552 else if(startswith(&ptr,
"-X-MAP:"))
2554 initFragmentPtr = ptr;
2567 else if (startswith(&ptr,
"-X-START:"))
2572 double offsetval = ParseXStartTimeOffset(ptr);
2583 aamp->mLiveOffset = offsetval;
2592 SetXStartTimeOffset(
aamp->mLiveOffset);
2595 else if (startswith(&ptr,
"-X-ENDLIST"))
2602 AAMPLOG_WARN(
"aamp: Changing playlist type from[%d] to ePLAYLISTTYPE_VOD as ENDLIST tag present.",
mPlaylistType);
2607 ptr=GetNextLineStart(ptr);
2610 if(mediaSequence==
false)
2612 AAMPLOG_INFO(
"warning: no EXT-X-MEDIA-SEQUENCE tag");
2653 mDuration = totalDuration;
2657 if(!UseProgramDateTimeIfAvailable())
2659 double newSecondsBeforePlayPoint = GetCompletionTimeForFragment(
this, commonPlayPosition);
2660 culledSec = prevSecondsBeforePlayPoint - newSecondsBeforePlayPoint;
2672 AAMPLOG_INFO(
"(%s) Prev:%f Now:%f culled with sequence:(%f -> %f) TrackCulled:%f",
2673 name, prevSecondsBeforePlayPoint, newSecondsBeforePlayPoint,
aamp->culledSeconds,(
aamp->culledSeconds+culledSec),
mCulledSeconds);
2675 else if (prevProgramDateTime > 0)
2677 if(mProgramDateTime > 0)
2679 culledSec = mProgramDateTime - prevProgramDateTime;
2682 AAMPLOG_INFO(
"(%s) Prev:%f Now:%f culled with ProgramDateTime:(%f -> %f) TrackCulled:%f",
2687 AAMPLOG_INFO(
"(%s) Failed to read ProgramDateTime:(%f) Retained last PDT (%f) TrackCulled:%f",
2689 mProgramDateTime = prevProgramDateTime;
2707 if(pcontext != NULL)
2711 pthread_mutex_lock(&
mutex);
2722 AAMPLOG_WARN(
" GetPlaylistURI is null");
2724 pthread_mutex_unlock(&
mutex);
2734 long http_error = 0;
2750 memset(&tempBuff, 0,
sizeof(tempBuff));
2754 bool bCacheRead =
false;
2771 if(IS_FOR_IFRAME(iCurrentRate,
type))
2788 double downloadTime;
2799 ManifestData manifestData(downloadTime * 1000,
playlist.
len);
2816 printf(
"***New Playlist:**************\n\n%s\n*************\n",
playlist.
ptr);
2831 AAMPLOG_INFO(
"Updating PDT (%f) and culled (%f)",mProgramDateTime,culled);
2832 aamp->mProgramDateTime = mProgramDateTime;
2840 if( mDuration > 0.0f )
2872 if (CURLE_OPERATION_TIMEDOUT == http_error || CURLE_COULDNT_CONNECT == http_error)
2875 AAMPLOG_WARN(
" Ignore curl timeout");
2894 bool ignoreProfile =
false;
2896 bool bDisableAC3 = bDisableEC3;
2906 ignoreProfile =
true;
2913 ignoreProfile =
true;
2920 ignoreProfile =
true;
2928 return ignoreProfile;
2973 if( this->mediaInfo[i].isDefault || this->mediaInfo[i].autoselect )
2979 AAMPLOG_INFO(
"track#%d score = %d", i, score );
2980 if( score > bestScore )
2995 const char *playlistURI = NULL;
3036 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: Couldn't find subtitle URI for preferred language: %s",
aamp->mSubLanguage.c_str());
3049 AAMPLOG_WARN(
"GetPlaylistURI : Auxiliary Track: Audio selected name is %s",
GetLanguageCode(index).c_str());
3072 std::istringstream playlistStream(trackState->
playlist.
ptr);
3073 for (std::string line; std::getline(playlistStream, line); )
3081 if( line.rfind(
"#EXT-X-MAP",0) == 0)
3089 while(isspace(line.back()))
3102 size_t end = line.find(
"?");
3103 if (end != std::string::npos)
3105 line = line.substr(0, end);
3107 size_t extenstionStart = line.find_last_of(
'.');
3108 if (extenstionStart != std::string::npos)
3110 std::string extension = line.substr(extenstionStart);
3112 if ( extension ==
".ts" )
3116 else if ( extension ==
".aac" )
3120 else if ( extension ==
".ac3" )
3124 else if ( extension ==
".ec3" )
3128 else if ( extension ==
".vtt" || extension ==
".webvtt" )
3134 AAMPLOG_WARN(
"Not TS or MP4 extension, probably ES. fragment extension %s len %zu", extension.c_str(), strlen(extension.c_str()));
3139 AAMPLOG_WARN(
"Could not find extension from line %s", line.c_str());
3158 bool retValIsLive =
false;
3164 retValIsLive |= track->IsLive();
3167 return retValIsLive;
3185 if (videoDiscontinuityIndex[i].position < audioDiscontinuityIndex[i].position)
3187 AAMPLOG_WARN(
"video->playTarget %f -> %f audio->playTarget %f -> %f",
3188 video->
playTarget, videoDiscontinuityIndex[i].
position,
audio->playTarget, audioDiscontinuityIndex[i].position);
3190 audio->playTarget = audioDiscontinuityIndex[i].position;
3194 AAMPLOG_WARN(
"video->playTarget %f -> %d audio->playTarget %f -> %d",
3195 video->
playTarget, (
int)audioDiscontinuityIndex[i].position,
audio->playTarget, (
int)audioDiscontinuityIndex[i].position);
3196 video->
playTarget =
audio->playTarget = (int)audioDiscontinuityIndex[i].position;
3213 if (!
audio->enabled)
3215 AAMPLOG_WARN(
"Attempting to sync between muxed track and auxiliary audio track");
3224 double roundedPlayTarget = std::round(video->
playTarget);
3226 double offsetVideoToAdd = roundedPlayTarget;
3227 double offsetAudioToAdd = roundedPlayTarget;
3229 double audioPeriodStartCurrentPeriod = 0.0;
3230 double videoPeriodStartCurrentPeriod = 0.0;
3231 double audioPeriodStartPrevPeriod = 0.0;
3232 double videoPeriodStartPrevPeriod = 0.0;
3238 AAMPLOG_WARN(
"WARNING audio's number of period %d video number of period: %d",
audio->GetNumberOfPeriods(), video->
GetNumberOfPeriods());
3250 double roundedIndexPosition = std::round(videoDiscontinuityIndex[i].position);
3251 double roundedFragDurtion = std::round(videoDiscontinuityIndex[i].fragmentDuration);
3253 double diff = (roundedIndexPosition - roundedPlayTarget);
3255 videoPeriodStartCurrentPeriod = videoDiscontinuityIndex[i].
position;
3256 audioPeriodStartCurrentPeriod = audioDiscontinuityIndex[i].position;
3260 if(fabs(diff) <= roundedFragDurtion || diff == 0)
3263 offsetVideoToAdd = offsetAudioToAdd = 0;
3264 AAMPLOG_WARN (
"PlayTarget around the discontinuity window,rounding position to discontinuity index");
3271 offsetVideoToAdd = (roundedPlayTarget - roundedIndexPosition);
3272 offsetAudioToAdd = (roundedPlayTarget - std::round(audioDiscontinuityIndex[i].position));
3279 audioPeriodStartCurrentPeriod = audioPeriodStartPrevPeriod;
3280 videoPeriodStartCurrentPeriod = videoPeriodStartPrevPeriod;
3282 offsetVideoToAdd = (roundedPlayTarget - std::round(videoPeriodStartPrevPeriod));
3283 offsetAudioToAdd = (roundedPlayTarget - std::round(audioPeriodStartPrevPeriod));
3287 videoPeriodStartPrevPeriod = videoPeriodStartCurrentPeriod;
3288 audioPeriodStartPrevPeriod = audioPeriodStartCurrentPeriod;
3292 audio->playTarget = audioPeriodStartCurrentPeriod + offsetAudioToAdd;
3293 video->
playTarget = videoPeriodStartCurrentPeriod + offsetVideoToAdd;
3297 double offsetFromPeriod;
3298 double audioOffsetFromPeriod;
3304 double audioPeriodStart =
audio->GetPeriodStartPosition(periodIdx);
3306 int audioFragmentIdx;
3308 audio->GetNextFragmentPeriodInfo (periodIdx, audioOffsetFromPeriod, audioFragmentIdx);
3310 AAMPLOG_WARN(
"video periodIdx: %d, video-offsetFromPeriod: %f, videoPeriodStart: %f, audio-offsetFromPeriod: %f, audioPeriodStart: %f",
3311 periodIdx, offsetFromPeriod, videoPeriodStart, audioOffsetFromPeriod, audioPeriodStart);
3313 if (0 != audioPeriodStart)
3315 if ((fragmentIdx != -1) && (audioFragmentIdx != -1) && (fragmentIdx != audioFragmentIdx) && ((
int)audioPeriodStart == (
int)videoPeriodStart))
3317 if (audioPeriodStart > videoPeriodStart)
3319 audio->playTarget = audioPeriodStart + audioOffsetFromPeriod;
3320 video->
playTarget = videoPeriodStart + audioOffsetFromPeriod;
3321 AAMPLOG_WARN(
"(audio > video) - vid start: %f, audio start: %f", video->
playTarget,
audio->playTarget );
3325 audio->playTarget = audioPeriodStart + offsetFromPeriod;
3326 video->
playTarget = videoPeriodStart + offsetFromPeriod;
3327 AAMPLOG_WARN(
"(video > audio) - vid start: %f, audio start: %f", video->
playTarget,
audio->playTarget );
3332 audio->playTarget = audioPeriodStart + audioOffsetFromPeriod;
3333 video->
playTarget = videoPeriodStart + offsetFromPeriod;
3334 AAMPLOG_WARN(
"(audio != video) - vid start: %f, audio start: %f", video->
playTarget,
audio->playTarget );
3339 AAMPLOG_WARN(
"VP: %f, AP: %f, seek_pos_seconds changed to %f based on video playTarget", video->
playTarget,
audio->playTarget,
seekPosition);
3345 AAMPLOG_WARN(
"audioDiscontinuityOffset: 0");
3350 AAMPLOG_WARN(
"WARNING audio's number of period %d subtitle number of period %d",
audio->GetNumberOfPeriods(), subtitle->
GetNumberOfPeriods());
3368 double offsetFromPeriod;
3369 int audioFragmentIdx;
3370 audio->GetNextFragmentPeriodInfo(periodIdx, offsetFromPeriod, audioFragmentIdx);
3371 if (-1 != periodIdx)
3373 AAMPLOG_WARN(
"audio periodIdx: %d, offsetFromPeriod: %f", periodIdx, offsetFromPeriod);
3375 if (0 != trackPeriodStart)
3377 track->
playTarget = trackPeriodStart + offsetFromPeriod;
3381 AAMPLOG_WARN(
"subtitleDiscontinuityOffset: 0");
3387 AAMPLOG_WARN(
"WARNING audio's number of period %d, %s number of period: %d",
3395 AAMPLOG_WARN(
"Exit : aux track start %f, muxed track start %f sub track start %f",
3400 AAMPLOG_WARN(
"Exit : audio track start %f, vid track start %f sub track start %f aux track start %f",
3413 bool useProgramDateTimeIfAvailable = UseProgramDateTimeIfAvailable();
3415 bool startTimeAvailable =
true;
3416 bool syncedUsingSeqNum =
false;
3422 double diffBetweenStartTimes = 0.0;
3435 AAMPLOG_WARN(
"startTime not available for track %d", i);
3436 startTimeAvailable =
false;
3452 if (startTimeAvailable)
3456 AAMPLOG_WARN(
"Difference in PDT between A/V: %f Audio:%f Video:%f ", diffBetweenStartTimes,
audio->startTimeForPlaylistSync,
3458 if (!useProgramDateTimeIfAvailable)
3462 AAMPLOG_WARN(
"WARNING seqno based track synchronization when video->targetDurationSeconds[%f] != audio->targetDurationSeconds[%f]",
3471 AAMPLOG_WARN(
"WARNING - inconsistency between startTime and seqno startTime diff %f diffBasedOnSeqNumber %f",
3472 diffBetweenStartTimes, diffBasedOnSeqNumber);
3477 if((diffBetweenStartTimes < -10 || diffBetweenStartTimes > 10))
3479 AAMPLOG_WARN(
"syncTracks diff debug : Audio start time : %f Video start time : %f ",
3485 if (!startTimeAvailable || !useProgramDateTimeIfAvailable)
3489 AAMPLOG_WARN(
"sync using sequence number. A %lld V %lld a-f-uri %s v-f-uri %s", mediaSequenceNumber[
eMEDIATYPE_AUDIO], mediaSequenceNumber[
eMEDIATYPE_VIDEO],
3499 AAMPLOG_WARN(
"video track lag in seqno. diff %lld", diff);
3506 AAMPLOG_WARN(
"audio track lag in seqno. diff %lld", diff);
3512 AAMPLOG_WARN(
"falling back to synchronization based on start time as diff = %lld", diff);
3516 AAMPLOG_WARN(
"sync using sequence number. diff [%lld] A [%lld] V [%lld] a-f-uri [%s] v-f-uri [%s]",
3529 AAMPLOG_WARN(
"laggingTS->fragmentURI NULL, seek might be out of window");
3533 syncedUsingSeqNum =
true;
3537 AAMPLOG_WARN(
"Lag in '%s' seq no, diff[%lld] > maxValue[%d]",
3543 AAMPLOG_WARN(
"No lag in seq no b/w AV");
3544 syncedUsingSeqNum =
true;
3558 long long diff = mediaSequenceNumber[
eMEDIATYPE_AUDIO] - mediaSequenceNumber[index];
3562 AAMPLOG_WARN(
"sync %s using sequence number. diff [%lld] A [%lld] T [%lld] a-f-uri [%s] t-f-uri [%s]",
3576 AAMPLOG_WARN(
"%s fragmentURI NULL, seek might be out of window", track->
name);
3584 AAMPLOG_WARN(
"sync using sequence number failed, %s will be starting late. diff [%lld] A [%lld] T [%lld] a-f-uri [%s] t-f-uri [%s]",
3590 AAMPLOG_WARN(
"No lag in seq no b/w audio and %s", track->
name);
3596 if (!syncedUsingSeqNum)
3598 if (startTimeAvailable)
3600 if (diffBetweenStartTimes > 0)
3605 if (video->mDuration > (ts->
playTarget + diffBetweenStartTimes))
3609 AAMPLOG_WARN(
"Audio track in front, catchup videotrack video playTarget:%f playTargetOffset:%f",ts->
playTarget ,ts->
playTargetOffset);
3613 AAMPLOG_WARN(
"invalid diff %f ts->playTarget %f trackDuration %f",
3614 diffBetweenStartTimes, ts->
playTarget, video->mDuration);
3620 AAMPLOG_WARN(
"syncTracks : Skip playTarget updation diff %f, vid track start %f fragmentDurationSeconds %f",
3624 else if (diffBetweenStartTimes < 0)
3633 AAMPLOG_WARN(
"Video track in front, catchup audiotrack audio playTarget:%f playTargetOffset:%f",ts->
playTarget ,ts->
playTargetOffset);
3637 AAMPLOG_ERR(
"invalid diff %f ts->playTarget %f trackDuration %f",
3644 AAMPLOG_WARN(
"syncTracks : Skip playTarget updation diff %f, aud track start %f fragmentDurationSeconds %f",
3667 if (track->mDuration > (track->
playTarget + diff))
3671 AAMPLOG_WARN(
"Audio track in front, catchup %s playTarget:%f playTargetOffset:%f",
3677 AAMPLOG_WARN(
"invalid diff(%f) greater than duration, ts->playTarget %f trackDuration %f, %s may start early",
3683 AAMPLOG_WARN(
"syncTracks : Skip %s playTarget updation diff %f, track start %f fragmentDurationSeconds %f",
3690 AAMPLOG_WARN(
"syncTracks : Skip %s sync to audio for subtitle startTime %f, audio startTime %f. Subtitle will be starting late",
3698 AAMPLOG_ERR(
"Could not sync using seq num and start time not available., cannot play this content.!!");
3703 video->playTargetBufferCalc = video->
playTarget;
3706 AAMPLOG_WARN(
"Exit : aux track start %f, muxed track start %f sub track start %f",
3711 AAMPLOG_WARN(
"Exit : audio track start %f, vid track start %f sub track start %f aux track start %f",
3724 std::string lang = this->mediaInfo[iMedia].
language;
3735 bool needMetadata =
true;
3743 long http_error = 0;
3753 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: Main manifest retrieved from cache");
3756 bool updateVideoEndMetrics =
false;
3757 double mainManifestdownloadTime = 0;
3758 int parseTimeMs = 0;
3762 AAMPLOG_TRACE(
"StreamAbstractionAAMP_HLS::downloading manifest");
3765 double downloadTime;
3767 (void)
aamp->
GetFile(
aamp->
GetManifestUrl(), &this->
mainManifest, aamp->
GetManifestUrl(), &http_error, &mainManifestdownloadTime, NULL,
eCURLINSTANCE_MANIFEST_PLAYLIST,
true,
eMEDIATYPE_MANIFEST,NULL,NULL,0,
pCMCDMetrics);
3768 updateVideoEndMetrics =
true;
3773 AAMPLOG_TRACE(
"StreamAbstractionAAMP_HLS::downloaded manifest");
3779 AAMPLOG_ERR(
"Manifest download failed : http response : %d", (
int) http_error);
3794 printf(
"***Main Manifest***:\n\n%s\n************\n", this->
mainManifest.
ptr);
3806 long long tStartTime = NOW_STEADY_TS_MS;
3808 parseTimeMs = NOW_STEADY_TS_MS - tStartTime;
3821 AAMPLOG_INFO(
"StreamAbstractionAAMP_HLS::Playlist only playback.");
3826 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Invalid manifest format.");
3837 temp[tempDataLen] = 0x00;
3839 printf(
"ERROR: Invalid Main Manifest : %s \n", temp);
3840 return mainManifestResult;
3852 if (persistedBandwidth > 0 && (persistedBandwidth < defaultBitRate || aamp->IsBitRatePersistedOverSeek()))
3867 AAMPLOG_WARN(
"PersistBitrate used as defaultBitrate. PersistBandwidth : %ld TimeGap : %ld",persistbandwidth,TimeGap);
3871 else if(
ISCONFIGSET(eAAMPConfig_PersistHighNetworkBandwidth) && TimeGap < 10000 && persistbandwidth > 0)
3873 AAMPLOG_WARN(
"PersistBitrate used as defaultBitrate. PersistBandwidth : %ld TimeGap : %ld",persistbandwidth,TimeGap);
3879 AAMPLOG_WARN(
"Using defaultBitrate %ld . PersistBandwidth : %ld TimeGap : %ld",
aamp->
GetDefaultBitrate(),persistbandwidth,TimeGap);
3886 if(
rate == AAMP_NORMAL_PLAY_RATE)
3895 if(
rate == AAMP_NORMAL_PLAY_RATE)
3917 const char* trackName =
"subs";
3922 trackName =
"video";
3924 else if (
rate != AAMP_NORMAL_PLAY_RATE)
3926 trackName =
"iframe";
3930 trackName =
"muxed";
3935 trackName =
"audio";
3939 trackName =
"aux-audio";
3948 AAMPLOG_INFO(
"StreamAbstractionAAMP_HLS::subtitles disabled by application");
3957 AAMPLOG_INFO(
"StreamAbstractionAAMP_HLS::auxiliary audio disabled");
3964 AAMPLOG_INFO(
"StreamAbstractionAAMP_HLS::auxiliary audio same as primary audio, set forward audio flag");
4020 pthread_t trackPLDownloadThreadID;
4021 bool trackPLDownloadThreadStarted =
false;
4026 AAMPLOG_INFO(
"StreamAbstractionAAMP_HLS::audio playlist retrieved from cache");
4028 if(!
audio->playlist.len)
4032 int ret = pthread_create(&trackPLDownloadThreadID, NULL, TrackPLDownloader,
audio);
4035 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: pthread_create failed for TrackPLDownloader with errno = %d, %s", errno, strerror(errno));
4039 trackPLDownloadThreadStarted =
true;
4044 audio->FetchPlaylist();
4052 AAMPLOG_INFO(
"StreamAbstractionAAMP_HLS::video playlist retrieved from cache");
4058 int numberOfLimit = 0;
4064 if ((!video->
playlist.
len) && (limitCount <= numberOfLimit) ){
4065 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Video playlist download failed, rettrying with rampdown logic : %d ( %d )",
4066 limitCount, numberOfLimit );
4083 AAMPLOG_ERR(
"StreamAbstractionAAMP_HLS::Failed to get URL after %d rampdown attempts",
4095 AAMPLOG_INFO(
"Selected BitRate: %ld, Max BitRate: %ld",
4100 }
while(limitCount <= numberOfLimit);
4102 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Video playlist download failed still after %d rampdown attempts",
4112 AAMPLOG_INFO(
"StreamAbstractionAAMP_HLS::subtitle playlist retrieved from cache");
4121 AAMPLOG_ERR(
"StreamAbstractionAAMP_HLS::Subtitle playlist download failed");
4129 AAMPLOG_INFO(
"StreamAbstractionAAMP_HLS::auxiliary audio playlist retrieved from cache");
4138 AAMPLOG_ERR(
"StreamAbstractionAAMP_HLS::Auxiliary audio playlist download failed");
4144 if (trackPLDownloadThreadStarted)
4146 pthread_join(trackPLDownloadThreadID, NULL);
4150 AAMPLOG_ERR(
"StreamAbstractionAAMP_HLS::Video Playlist download failed");
4153 else if (
audio->enabled && !
audio->playlist.len)
4155 AAMPLOG_ERR(
"StreamAbstractionAAMP_HLS::Audio Playlist download failed");
4159 if (
rate != AAMP_NORMAL_PLAY_RATE)
4176 double programStartTime = -1;
4179 bool audioFormatMPEGTS =
true;
4187 bool playContextConfigured =
false;
4191 printf(
"***Initial Playlist:******\n\n%s\n*****************\n", ts->
playlist.
ptr);
4198 programStartTime = ts->mProgramDateTime;
4202 AAMPLOG_INFO(
"Updating PDT (%f) and culled (%f) Updated seek_pos_seconds:%f ",ts->mProgramDateTime,culled,(
seekPosition - culled));
4203 aamp->mProgramDateTime = ts->mProgramDateTime;
4210 AAMPLOG_ERR(
"TrackState: Sending Error event DRM unsupported");
4213 if (ts->mDuration == 0.0f)
4221 AAMPLOG_ERR(
"StreamAbstractionAAMP_HLS::%s playlist duration is zero!!",
4234 if(bMetadata && newTune)
4258 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Unsupported subtitle format from fragment extension:%d", format);
4266 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Auxiliary audio not supported for FORMAT_ISO_BMFF, disabling!");
4273 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Init : Track[%s] - FORMAT_ISO_BMFF", ts->
name);
4291 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Init : Track[%s] - FORMAT_AUDIO_ES_AAC", ts->
name);
4294 audioFormatMPEGTS =
false;
4301 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Init : Track[%s] - FORMAT_AUDIO_ES_AC3", ts->
name);
4304 audioFormatMPEGTS =
false;
4311 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Init : Track[%s] - FORMAT_AUDIO_ES_EC3", ts->
name);
4314 audioFormatMPEGTS =
false;
4320 bool subtitleDisabled =
false;
4321 if (this->
rate != AAMP_NORMAL_PLAY_RATE)
4323 subtitleDisabled =
true;
4327 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Unsupported subtitle format from fragment extension:%d", format);
4328 subtitleDisabled =
true;
4332 if (!subtitleDisabled)
4338 AAMPLOG_WARN(
"Legacy subtec");
4343 AAMPLOG_WARN(
"GST subtec");
4351 AAMPLOG_WARN(
"No subtec, no sub parser");
4369 if (this->
rate == AAMP_NORMAL_PLAY_RATE)
4373 AAMPLOG_WARN(
"Configure auxiliary audio TS track demuxing");
4379 playContextConfigured =
true;
4388 AAMPLOG_WARN(
"Configure auxiliary audio format based on extension");
4393 AAMPLOG_WARN(
"Keeping auxiliary audio format from playlist");
4398 AAMPLOG_WARN(
"Disable auxiliary audio format - trick play");
4406 if (this->
rate == AAMP_NORMAL_PLAY_RATE)
4413 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: Configure audio TS track demuxing");
4426 AAMPLOG_WARN(
"Configure audio TS track to queue");
4436 playContextConfigured =
true;
4445 AAMPLOG_WARN(
"Configure audio format based on extension");
4450 AAMPLOG_WARN(
"Keeping audio format from playlist");
4455 AAMPLOG_WARN(
"Disable audio format - trick play");
4504 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Init : Configure video TS track demuxing demuxOp %d", demuxOp);
4508 if(!audioFormatMPEGTS)
4527 if (this->
rate == AAMP_NORMAL_PLAY_RATE)
4536 playContextConfigured =
true;
4540 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Init : VideoTrack -couldn't determine format from streamInfo->codec %s",
4548 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Init : Configure video TS track eStreamOp_SEND_VIDEO_AND_QUEUED_AUDIO");
4552 playContextConfigured =
true;
4556 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Init : Configure video TS track %p : No streamops", ts);
4561 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Init : track %p context configuring for eStreamOp_NONE", ts);
4564 if (this->
rate == AAMP_NORMAL_PLAY_RATE)
4599 if ((video->
enabled && video->mDuration == 0.0f) || (
audio->enabled &&
audio->mDuration == 0.0f))
4601 AAMPLOG_ERR(
"StreamAbstractionAAMP_HLS: Track Duration is 0. Cannot play this content");
4605 if (newTune && needMetadata)
4607 needMetadata =
false;
4639 AAMPLOG_WARN(
"aamp: hls - sent tune event after indexing playlist");
4655 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: eTUNETYPE_SEEKTOLIVE, reset playTarget and enable liveAdjust");
4658 audio->playTarget = 0;
4666 double seekWindowEnd = video->mDuration;
4669 seekWindowEnd -=
aamp->mLiveOffset ;
4672 if (round(video->
playTarget) >= round(seekWindowEnd))
4676 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: playTarget > seekWindowEnd , playTarget:%f and seekWindowEnd:%f",
4680 audio->playTarget = 0;
4693 audio->eosReached =
true;
4694 audio->fragmentURI = NULL;
4699 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: seek target out of range, mark EOS. playTarget:%f End:%f. ",
4738 double xStartOffset = video->GetXStartTimeOffset();
4739 double offsetFromLive =
aamp->mLiveOffset ;
4745 if(xStartOffset < 0)
4747 offsetFromLive = abs(xStartOffset);
4748 AAMPLOG_WARN(
"liveOffset modified with X-Start to :%f",offsetFromLive);
4759 double offsetToLiveVideo,offsetToLiveAudio,offsetToLive;
4760 offsetToLiveVideo = offsetToLiveAudio = video->mDuration - offsetFromLive - video->
playTargetOffset;
4764 offsetToLiveAudio = 0;
4766 if(
audio->mDuration > (offsetFromLive +
audio->playTargetOffset))
4767 offsetToLiveAudio =
audio->mDuration - offsetFromLive -
audio->playTargetOffset;
4769 AAMPLOG_WARN(
"aamp: live adjust not possible ATotal[%f]< (AoffsetFromLive[%f] + AplayTargetOffset[%f]) A-target[%f]",
audio->mDuration,offsetFromLive,
audio->playTargetOffset,
audio->playTarget);
4772 offsetToLive = (std::min)(offsetToLiveVideo,offsetToLiveAudio);
4774 video->playTargetBufferCalc = video->
playTarget;
4775 if (
audio->enabled )
4777 audio->playTarget += offsetToLive;
4778 audio->playTargetBufferCalc =
audio->playTarget;
4783 subtitle->playTargetBufferCalc = subtitle->
playTarget;
4793 AAMPLOG_WARN(
"aamp: after live adjust - V-target %f A-target %f S-target %f Aux-target %f offsetFromLive %f offsetToLive %f offsetVideo[%f] offsetAudio[%f] AtLivePoint[%d]",
4798 AAMPLOG_WARN(
"aamp: live adjust not possible VTotal[%f] < (VoffsetFromLive[%f] + VplayTargetOffset[%f]) V-target[%f]",
4810 if (discontinuityIndexCount > 0)
4818 float videoPrevDiscontinuity = 0;
4819 float audioPrevDiscontinuity = 0;
4820 float videoNextDiscontinuity;
4821 float audioNextDiscontinuity;
4824 for (
int i = 0; i <= discontinuityIndexCount; i++)
4826 if (i < discontinuityIndexCount)
4828 videoNextDiscontinuity = videoDiscontinuityIndex[i].
position;
4829 audioNextDiscontinuity = audioDiscontinuityIndex[i].position;
4834 audioNextDiscontinuity = videoNextDiscontinuity;
4836 if ((videoNextDiscontinuity > (video->
playTarget + 5))
4837 && (audioNextDiscontinuity > (otherTrack->
playTarget + 5)))
4840 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: video->playTarget %f videoPrevDiscontinuity %f videoNextDiscontinuity %f",
4841 video->
playTarget, videoPrevDiscontinuity, videoNextDiscontinuity);
4842 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: %s->playTarget %f audioPrevDiscontinuity %f audioNextDiscontinuity %f",
4843 otherTrack->
name, otherTrack->
playTarget, audioPrevDiscontinuity, audioNextDiscontinuity);
4844 if (video->
playTarget < videoPrevDiscontinuity)
4846 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: [video] playTarget(%f) advance to discontinuity(%f)",
4849 video->playTargetBufferCalc = video->
playTarget;
4851 if (otherTrack->
playTarget < audioPrevDiscontinuity)
4853 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: [%s] playTarget(%f) advance to discontinuity(%f)",
4854 otherTrack->
name, otherTrack->
playTarget, audioPrevDiscontinuity);
4855 otherTrack->
playTarget = audioPrevDiscontinuity;
4856 otherTrack->playTargetBufferCalc = otherTrack->
playTarget;
4860 videoPrevDiscontinuity = videoNextDiscontinuity;
4861 audioPrevDiscontinuity = audioNextDiscontinuity;
4866 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: videoPeriodPositionIndex.size %d audioPeriodPositionIndex.size %d",
4872 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: videoPeriodPositionIndex.size 0");
4887 if (!
audio->enabled)
4891 video->playTargetBufferCalc = video->
playTarget;
4894 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: Setting setProgressEventOffset value of %.3f ms", offset);
4898 if (
rate == AAMP_NORMAL_PLAY_RATE)
4953 SETCONFIGVALUE(AAMP_STREAM_SETTING,eAAMPConfig_InitialBuffer,0);
4973 if (
aamp->culledSeconds > 0)
4983 if (0 <= iframeStreamIdx)
4985 std::string defaultIframePlaylistUrl;
4986 std::string defaultIframePlaylistEffectiveUrl;
4988 long http_error = 0;
4992 AAMPLOG_TRACE(
"StreamAbstractionAAMP_HLS:: Downloading iframe playlist");
4993 bool bFiledownloaded =
false;
4995 double downloadTime;
4998 ManifestData manifestData(downloadTime * 1000, defaultIframePlaylist.
len);
5001 if (defaultIframePlaylist.
len && bFiledownloaded)
5004 AAMPLOG_TRACE(
"StreamAbstractionAAMP_HLS:: Cached iframe playlist");
5008 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: Error Download iframe playlist. http_error %d",
5029 if(updateVideoEndMetrics)
5032 ManifestData manifestData(mainManifestdownloadTime * 1000, this->
mainManifest.
len, parseTimeMs);
5045 static void * CachePlaylistThreadFunction(
void * This)
5064 PreCacheUrlList dnldList ;
5071 dnldList.push_back(newelem);
5083 dnldList.push_back(newelem);
5089 int ret = pthread_create(&
aamp->mPreCachePlaylistThreadId, NULL, CachePlaylistThreadFunction,(
void *)
aamp );
5092 AAMPLOG_ERR(
"pthread_create failed for PreCachePlaylist with errno = %d, %s", errno, strerror(errno));
5096 aamp->mPreCachePlaylistThreadFlag =
true;
5135 double retval = -1.0;
5161 pthread_mutex_lock(&
mutex);
5163 AAMPLOG_INFO(
"Preparing to flush fragments and switch playlist");
5175 pthread_mutex_unlock(&
mutex);
5185 bool skipFetchFragment =
false;
5186 bool abortedDownload =
false;
5192 skipFetchFragment =
false;
5206 skipFetchFragment =
true;
5210 skipFetchFragment =
false;
5219 if (!skipFetchFragment)
5252 AAMPLOG_INFO(
"Refreshing '%s' playlist as maximum refresh delay exceeded",
name);
5259 AAMPLOG_WARN(
"Not refreshing timeSinceLastPlaylistDownload = %d", timeSinceLastPlaylistDownload);
5274 pthread_mutex_lock(&
mutex);
5281 pthread_mutex_unlock(&
mutex);
5289 abortedDownload =
true;
5294 if(!abortedDownload){
5305 int minDelayBetweenPlaylistUpdates = MAX_DELAY_BETWEEN_PLAYLIST_UPDATE_MS;
5307 long long endPositionAvailable = (
aamp->culledSeconds +
aamp->durationSeconds)*1000;
5310 long bufferAvailable = (endPositionAvailable - currentPlayPosition);
5323 else if(bufferAvailable > (2*MAX_DELAY_BETWEEN_PLAYLIST_UPDATE_MS))
5325 minDelayBetweenPlaylistUpdates = MAX_DELAY_BETWEEN_PLAYLIST_UPDATE_MS;
5334 minDelayBetweenPlaylistUpdates = (int)(bufferAvailable / 3) ;
5338 minDelayBetweenPlaylistUpdates = MIN_DELAY_BETWEEN_PLAYLIST_UPDATE_MS;
5342 static int bufferlowCnt;
5343 if((bufferlowCnt++ & 5) == 0)
5345 AAMPLOG_WARN(
"Buffer is running low(%ld).Type(%d) Refreshing playlist(%d).Target(%f) PlayPosition(%lld) End(%lld)",
5346 bufferAvailable,
type,minDelayBetweenPlaylistUpdates,
playTarget,currentPlayPosition,endPositionAvailable);
5351 minDelayBetweenPlaylistUpdates -= timeSinceLastPlaylistDownload;
5353 if (minDelayBetweenPlaylistUpdates > MAX_DELAY_BETWEEN_PLAYLIST_UPDATE_MS)
5355 minDelayBetweenPlaylistUpdates = MAX_DELAY_BETWEEN_PLAYLIST_UPDATE_MS;
5357 else if(minDelayBetweenPlaylistUpdates < MIN_DELAY_BETWEEN_PLAYLIST_UPDATE_MS)
5360 minDelayBetweenPlaylistUpdates = MIN_DELAY_BETWEEN_PLAYLIST_UPDATE_MS;
5362 AAMPLOG_INFO(
"aamp playlist end refresh type(%d) bufferMs(%ld) playtarget(%f) delay(%d) End(%lld) PlayPosition(%lld)",
5363 type,bufferAvailable,
playTarget,minDelayBetweenPlaylistUpdates,endPositionAvailable,currentPlayPosition);
5369 AAMPLOG_FAILOVER(
"fragmentURI [%s] timeElapsedSinceLastFragment [%f]",
5376 AAMPLOG_FAILOVER(
"fragmentURI is NULL, playback may stall in few seconds..");
5380 AAMPLOG_WARN(
"fragment collector done. track %s",
name);
5394 if(aamp_pthread_setname(pthread_self(),
"aampHLSFetcher"))
5396 AAMPLOG_WARN(
"aamp_pthread_setname failed");
5407 enableThrottle(false), firstFragmentDecrypted(false), mStartTimestampZero(false), mNumberOfTracks(0), midSeekPtsOffset(0),
5408 lastSelectedProfileIndex(0), segDLFailCount(0), segDrmDecryptFailCount(0), mMediaCount(0),mProfileCount(0),
5409 mLangList(),mIframeAvailable(false), thumbnailManifest(), indexedTileInfo(),pCMCDMetrics(NULL),
5414 AAMPLOG_WARN(
"hls fragment collector seekpos = %f", seekpos);
5415 if (
rate == AAMP_NORMAL_PLAY_RATE)
5441 indexCount(0), currentIdx(0), indexFirstMediaSequenceNumber(0), fragmentURI(NULL), lastPlaylistDownloadTimeMS(0),
5442 byteRangeLength(0), byteRangeOffset(0), nextMediaSequenceNumber(0), playlistPosition(0), playTarget(0),playTargetBufferCalc(0),lastDownloadedIFrameTarget(-1),
5444 playTargetOffset(0),
5445 discontinuity(false),
5446 refreshPlaylist(false), fragmentCollectorThreadID(0),
5447 fragmentCollectorThreadStarted(false),
5448 manifestDLFailCount(0),
5449 mCMSha1Hash(NULL), mDrmTimeStamp(0), mDrmMetaDataIndexCount(0),firstIndexDone(false), mDrm(NULL), mDrmLicenseRequestPending(false),
5450 mInjectInitFragment(false), mInitFragmentInfo(NULL), mDrmKeyTagCount(0), mIndexingInProgress(false), mForceProcessDrmMetadata(false),
5451 mDuration(0), mLastMatchedDiscontPosition(-1), mCulledSeconds(0),mCulledSecondsOld(0),
5452 mEffectiveUrl(
""), mPlaylistUrl(
""), mFragmentURIFromIndex(
""),
5453 mDiscontinuityIndexCount(0), mSyncAfterDiscontinuityInProgress(false), playlist(),
5454 index(), targetDurationSeconds(1), mDeferredDrmKeyMaxTime(0), startTimeForPlaylistSync(),
5455 context(parent), fragmentEncrypted(false), mKeyTagChanged(false), mLastKeyTagIdx(0), mDrmInfo(),
5456 mDrmMetaDataIndexPosition(0), mDrmMetaDataIndex(), mDiscontinuityIndex(), mKeyHashTable(), mPlaylistMutex(),
5457 mPlaylistIndexed(), mDiscoCheckMutex(), mDiscoCheckComplete(), mTrackDrmMutex(), mPlaylistType(
ePLAYLISTTYPE_UNDEFINED), mReachedEndListTag(false),
5458 mByteOffsetCalculation(false),mSkipAbr(false),
5459 mCheckForInitialFragEnc(false), mFirstEncInitFragmentInfo(NULL), mDrmMethod(
eDRM_KEY_METHOD_NONE)
5460 ,mXStartTimeOFfset(0), mCulledSecondsAtStart(0.0)
5461 ,mProgramDateTime(0.0),pCMCDMetrics(NULL)
5462 ,mDiscontinuityCheckingOn(false)
5463 ,mSkipSegmentOnError(true)
5476 mProgramDateTime =
aamp->mProgramDateTime;
5477 AAMPLOG_INFO(
"Restore PDT (%f) ",mProgramDateTime);
5496 int maxCachedFragmentsPerTrack;
5498 for (
int j=0; j< maxCachedFragmentsPerTrack; j++)
5538 void *value_ptr = NULL;
5542 AAMPLOG_WARN(
"***pthread_join fragmentCollectorThread returned %d(%s)", rc, strerror(rc));
5547 AAMPLOG_WARN(
"joined fragmentCollectorThread");
5566 if(
mDrm && clearDRM)
5610 AAMPLOG_WARN(
"Failed to create FragmentCollector thread");
5666 if(otherTrack && otherTrack->
Enabled())
5674 track->
Stop(clearChannelData);
5675 if (!clearChannelData)
5683 if (clearChannelData)
5690 if(
aamp->fragmentCdmEncrypted)
5697 aamp->mDRMSessionManager->notifyCleanup();
5703 if(!clearChannelData)
5718 for (
int i = 0; i < profileCount; i++)
5721 AAMPLOG_WARN(
"stream[%d]:", i);
5737 AAMPLOG_WARN(
"media[%d]:", i);
5742 AAMPLOG_WARN(
"type:AUDIO");
5745 AAMPLOG_WARN(
"type:VIDEO");
5755 AAMPLOG_WARN(
"\tAUTOSELECT");
5759 AAMPLOG_WARN(
"\tDEFAULT");
5781 std::vector<long> bitrates;
5804 return std::vector<long>();
5813 static bool isThumbnailStream(
const struct HlsStreamInfo *streamInfo )
5818 ret = SubStringMatch(streamInfo->
codecs, streamInfo->
codecs+4,
"jpeg");
5829 std::vector<StreamInfo*> thumbnailTracks;
5836 thumbnailTracks.push_back(sptr);
5840 return thumbnailTracks;
5850 static std::vector<TileInfo> IndexThumbnails(
char *ptr )
5852 std::vector<TileInfo> rc;
5854 double startTime = 0;
5856 memset( &tileInfo,0,
sizeof(tileInfo) );
5860 char *next = mystrpbrk(ptr);
5863 if (startswith(&ptr,
"#EXT"))
5865 if (startswith(&ptr,
"INF:"))
5869 else if (startswith(&ptr,
"-X-TILES:"))
5877 tileInfo.startTime = startTime;
5879 rc.push_back( tileInfo );
5909 aamp->mthumbIndexValue = iProfile;
5913 long http_error = 0;
5914 double downloadTime = 0;
5915 std::string tempEffectiveUrl;
5918 AAMPLOG_WARN(
"In StreamAbstractionAAMP_HLS: Configured Thumbnail");
5926 AAMPLOG_WARN(
"In StreamAbstractionAAMP_HLS: Unable to fetch the Thumbnail Manifest");
5941 std::vector<ThumbnailData> data;
5952 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS: Failed to retrieve the thumbnail playlist from cache.");
5957 double totalSetDuration = 0;
5960 tmpdata.
t = tileInfo.startTime;
5961 if( tmpdata.
t > tEnd )
5967 if( tileSetEndTime < tStart )
5971 tmpdata.
url = tileInfo.url;
5976 for(
int row=0; row<tileInfo.
numRows && !done; row++ )
5978 for(
int col=0; col<tileInfo.
numCols && !done; col++ )
5981 if( tNext >= tileSetEndTime )
5983 tmpdata.
d = tileSetEndTime - tmpdata.
t;
5986 if( tEnd >= tmpdata.
t && tStart < tNext )
5990 data.push_back(tmpdata);
5998 *baseurl = url.substr(0,url.find_last_of(
"/\\")+1);
6011 mFirstPTS = ((double)pts / (
double)timeScale);
6023 AAMPLOG_INFO(
"sending init %.3f",
mFirstPTS * 1000.0);
6037 AAMPLOG_INFO(
"setting subtitles pause state = %d", pause);
6084 unsigned char *pui8IV=NULL;
6094 pui8IV = (
unsigned char*)malloc(DRM_IV_LEN);
6095 if ( NULL == pui8IV )
6097 AAMPLOG_WARN(
"IV MemAlloc error, Size:%d",DRM_IV_LEN);
6103 memset(pui8IV, 0x00, DRM_IV_LEN);
6112 for(i32loop=12; i32loop< 16; ++i32loop)
6114 pui8IV[i32loop]=((ui32Seqno)>> (8*(15-i32loop)))&0xff;
6141 bool drmDataChanged =
false;
6152 if (0 != memcmp(ptr, (
char*)
mCMSha1Hash, DRM_SHA1_HASH_LEN))
6156 AAMPLOG_WARN(
"[%s] Different DRM metadata hash. old - ",
name);
6157 for (
int i = 0; i< DRM_SHA1_HASH_LEN; i++)
6162 for (
int i = 0; i< DRM_SHA1_HASH_LEN; i++)
6164 printf(
"%c", ptr[i]);
6168 drmDataChanged =
true;
6173 AAMPLOG_INFO(
"Same DRM Metadata");
6180 AAMPLOG_WARN(
"[%s] New DRM metadata hash - ",
name);
6181 for (
int i = 0; i < DRM_SHA1_HASH_LEN; i++)
6183 printf(
"%c", ptr[i]);
6190 AAMPLOG_WARN(
"mCMSha1Hash is null");
6195 drmDataChanged =
true;
6204 if(drmMetadataNode[i].sha1Hash)
6206 if (0 == memcmp(
mCMSha1Hash, drmMetadataNode[i].sha1Hash, DRM_SHA1_HASH_LEN))
6219 AAMPLOG_WARN(
"[%s] Couldn't find matching hash mDrmMetaDataIndexCount %d ",
6223 if (drmMetadataNode[j].sha1Hash)
6225 AAMPLOG_WARN(
"drmMetadataNode[%d].sha1Hash -- \n", j);
6226 for (
int i = 0; i < DRM_SHA1_HASH_LEN; i++)
6228 printf(
"%c", drmMetadataNode[j].sha1Hash[i]);
6234 AAMPLOG_WARN(
"drmMetadataNode[%d].sha1Hash NULL", j);
6258 unsigned char *iv =
base16_Decode(ptr, (DRM_IV_LEN*2), &len);
6259 assert(len == DRM_IV_LEN);
6266 for (
int i = 0; i< DRM_IV_LEN*2; i++)
6268 printf(
"%c", ptr[i]);
6290 long http_error = 0;
6291 double downloadTime;
6292 long main_error = 0;
6322 ManifestData manifestData(downloadTime * 1000,
playlist.
len);
6331 AAMPLOG_WARN(
"Playlist download failed : %s http response : %d",
mPlaylistUrl.c_str(), (
int)http_error);
6369 offsetFromPeriodStart = 0;
6371 double prevCompletionTimeSecondsFromStart = 0;
6376 if (node->completionTimeSecondsFromStart >
playTarget)
6378 AAMPLOG_WARN(
"(%s) Found node - rate %f completionTimeSecondsFromStart %f playTarget %f",
name,
6383 prevCompletionTimeSecondsFromStart = node->completionTimeSecondsFromStart;
6389 offsetFromPeriodStart = prevCompletionTimeSecondsFromStart;
6390 double periodStartPosition = 0;
6394 AAMPLOG_TRACE(
"TrackState:: [%s] Loop periodItr %d idx %d first %d second %f",
name, i, idx,
6395 discontinuityIndex[i].fragmentIdx, discontinuityIndex[i].position);
6396 if (discontinuityIndex[i].fragmentIdx > idx)
6398 AAMPLOG_WARN(
"TrackState: [%s] Found periodItr %d idx %d first %d offsetFromPeriodStart %f",
6399 name, i, idx, discontinuityIndex[i].fragmentIdx, periodStartPosition);
6405 periodStartPosition = discontinuityIndex[i].
position;
6407 offsetFromPeriodStart -= periodStartPosition;
6409 AAMPLOG_WARN(
"TrackState: [%s] periodIdx %d offsetFromPeriodStart %f",
name, periodIdx,
6410 offsetFromPeriodStart);
6414 AAMPLOG_WARN(
"TrackState: [%s] idxNode NULL",
name);
6425 AAMPLOG_WARN(
"TrackState: [%s] periodIdx %d periodCount %d",
name, periodIdx,
6433 if (count == periodIdx)
6435 offset = discontinuityIndex[i].
position;
6436 AAMPLOG_WARN(
"TrackState: [%s] offset %f periodCount %d",
name, offset,
6448 AAMPLOG_WARN(
"TrackState: [%s] WARNING periodIdx %d periodCount %d",
name, periodIdx,
6469 bool discontinuityFound =
false;
6470 bool useProgramDateTimeIfAvailable = UseProgramDateTimeIfAvailable();
6472 double low = position - discDiscardTolreanceInSec;
6473 double high = position + discDiscardTolreanceInSec;
6474 int playlistRefreshCount = 0;
6475 diffBetweenDiscontinuities = DBL_MAX;
6476 bool newDiscHandling =
true;
6478 mDiscontinuityCheckingOn =
true;
6486 bool foundmatchingdisc =
false;
6494 AAMPLOG_WARN(
"[%s] Host loop %d mDiscontinuityIndexCount %d discontinuity-pos %f mCulledSeconds %f playlistRefreshTime:%f discdatetime=%f",
name, i,
6497 AAMPLOG_WARN(
"Visitor loop %d Input track position:%f useDateTime:%d CulledSeconds :%f playlistRefreshTime :%f DeltaCulledSec:%f", i,
6498 position ,useDiscontinuityDateTime, inputCulledSec , inputProgramDateTime , deltaCulledSec);
6501 if(useDiscontinuityDateTime && discdatetime)
6504 AAMPLOG_WARN(
"Comparing two disc date&time input pdt:%f pdt:%f diff:%f",position, discdatetime, fabs(discdatetime - position));
6507 foundmatchingdisc =
true;
6508 diffBetweenDiscontinuities = discdatetime - position;
6509 AAMPLOG_WARN(
"[%s] Found the matching discontinuity with pdt at position:%f",
name,position);
6518 int limit1 = (int)(discontinuityIndex[i].position - abs(deltaCulledSec) -
targetDurationSeconds - 1.0);
6519 int limit2 = (int)(discontinuityIndex[i].position + abs(deltaCulledSec) +
targetDurationSeconds + 1.0);
6534 roundedPosn = std::round(position);
6538 roundedPosn = std::round(playPosition);
6539 isDiffChkReq =
false;
6542 AAMPLOG_WARN(
"Comparing position input posn:%d index[%d] position:%d deltaCulled:%f limit1:%d limit2:%d ",roundedPosn,i,(
int)(discontinuityIndex[i].position),deltaCulledSec,
6544 if(roundedPosn >= limit1 && roundedPosn <= limit2 )
6546 foundmatchingdisc =
true;
6547 AAMPLOG_WARN(
"[%s] Found the matching discontinuity at position:%f for position:%f",
name,discontinuityIndex[i].position,position);
6554 if(!foundmatchingdisc)
6556 AAMPLOG_WARN(
"##[%s] Discontinuity not found mDuration %f playPosition %f playlistType %d useStartTime %d ",
6557 name, mDuration, playPosition, (
int)
mPlaylistType, (
int)useDiscontinuityDateTime);
6560 int maxPlaylistRefreshCount;
6575 if(useProgramDateTimeIfAvailable)
6579 if (mProgramDateTime >= inputProgramDateTime+
targetDurationSeconds || playlistRefreshCount > maxPlaylistRefreshCount)
6581 AAMPLOG_WARN(
"%s Discontinuity not found mProgramDateTime:%f > inputProgramDateTime:%f playlistRefreshCount:%d maxPlaylistRefreshCount:%d",
name,
6582 mProgramDateTime,inputProgramDateTime,playlistRefreshCount,maxPlaylistRefreshCount);
6588 if(!((playlistRefreshCount < maxPlaylistRefreshCount) && (liveNoTSB || (mDuration < (playPosition + discDiscardTolreanceInSec)))))
6590 AAMPLOG_WARN(
"%s Discontinuity not found After playlistRefreshCount:%d",
name,playlistRefreshCount);
6594 AAMPLOG_WARN(
"Wait for [%s] playlist update over for playlistRefreshCount %d",
name, playlistRefreshCount);
6596 playlistRefreshCount++;
6605 discontinuityFound =
true;
6609 mDiscontinuityCheckingOn =
false;
6612 return discontinuityFound;
6638 long http_code = -1;
6643 AAMPLOG_WARN(
"TrackState::[%s] first encrypted init-fragment is NULL! fragmentEncrypted-%d",
name,
fragmentEncrypted);
6644 forcePushEncryptedHeader =
false;
6662 if (!forcePushEncryptedHeader)
6680 AAMPLOG_WARN(
"Reset mFirstEncInitFragmentInfo since rampdown for another profile");
6684 AAMPLOG_INFO(
"Init fragment fetch failed, Successfully ramped down to lower profile");
6692 AAMPLOG_ERR(
"TrackState::Init fragment fetch failed");
6698 AAMPLOG_WARN(
"Error while fetching init fragment:%s, failedCount:%d. decrementing profile",
name,
segDLFailCount);
6703 AAMPLOG_ERR(
"TrackState::Init fragment fetch failed");
6710 AAMPLOG_ERR(
"TrackState::Need to push init fragment but fragment info is missing! mInjectInitFragment(%d)",
mInjectInitFragment);
6723 std::istringstream initFragmentUrlStream;
6728 if (forcePushEncryptedHeader)
6731 AAMPLOG_WARN(
"TrackState::[%s] first init-fragment is unencrypted.! Pushing encrypted init-header",
name);
6739 std::getline(initFragmentUrlStream, line);
6742 const char *range = NULL;
6743 char rangeStr[MAX_RANGE_STRING_CHARS];
6746 size_t uriTagStart = line.find(
"URI=");
6747 if (uriTagStart != std::string::npos)
6749 std::string uriStart = line.substr(uriTagStart + 5);
6751 size_t uriTagEnd = uriStart.find(
"\"");
6752 if (uriTagEnd != std::string::npos)
6755 uri = uriStart.substr(0, uriTagEnd);
6760 AAMPLOG_ERR(
"URI parse error. Tag end not found");
6765 AAMPLOG_ERR(
"URI parse error. URI= not found");
6767 size_t byteRangeTagStart = line.find(
"BYTERANGE=");
6768 if (byteRangeTagStart != std::string::npos)
6770 std::string byteRangeStart = line.substr(byteRangeTagStart + 11);
6771 size_t byteRangeTagEnd = byteRangeStart.find(
"\"");
6772 if (byteRangeTagEnd != std::string::npos)
6774 std::string byteRange = byteRangeStart.substr(0, byteRangeTagEnd);
6776 if (!byteRange.empty())
6778 size_t offsetIdx = byteRange.find(
"@");
6779 if (offsetIdx != std::string::npos)
6781 int offsetVal = stoi(byteRange.substr(offsetIdx + 1));
6782 int rangeVal = stoi(byteRange.substr(0, offsetIdx));
6783 int next = offsetVal + rangeVal;
6784 snprintf(rangeStr,
sizeof(rangeStr),
"%d-%d", offsetVal, next - 1);
6785 AAMPLOG_INFO(
"TrackState::rangeStr %s", rangeStr);
6792 AAMPLOG_ERR(
"TrackState::byteRange parse error. Tag end not found byteRangeStart %s",
6793 byteRangeStart.c_str());
6798 std::string fragmentUrl;
6800 std::string tempEffectiveUrl;
6802 AAMPLOG_WARN(
"TrackState::[%s] init-fragment = %s",
name, fragmentUrl.c_str());
6806 if(IS_FOR_IFRAME(iCurrentRate,
type))
6823 #ifdef CHECK_PERFORMANCE
6824 long long ts_start, ts_end;
6829 #ifdef CHECK_PERFORMANCE
6832 AAMPLOG_TRACE(
"---------------CacheRead Time diff:%llu---------------" , ts_end-ts_start);
6837 double downloadTime;
6839 type,
false, actualType);
6841 #ifdef CHECK_PERFORMANCE
6843 AAMPLOG_TRACE(
"---------------CurlReq Time diff:%llu---------------" , downloadTime);
6854 AAMPLOG_ERR(
"TrackState::aamp_GetFile failed");
6864 AAMPLOG_ERR(
"TrackState::Could not parse init fragment URI. line %s", line.c_str());
6869 AAMPLOG_ERR(
"TrackState::Init fragment URI parse error");
6943 AAMPLOG_WARN(
"track [%s]",
name);
6954 AAMPLOG_WARN(
"track [%s]",
name);
6969 mDrm->CancelKeyWait();
6989 mDrm->RestoreKeyState();
6998 double totalDuration = 0.0;
7007 if(startswith(&ptr,
"#EXT"))
7009 if (startswith(&ptr,
"INF:"))
7011 totalDuration += atof(ptr);
7013 for (
int i = 0; i <
aamp->subscribedTags.size(); i++)
7015 const char* data =
aamp->subscribedTags.at(i).data();
7016 if(startswith(&ptr, (data + 4)))
7019 int nb = (int)FindLineLength(ptr);
7035 ptr=GetNextLineStart(ptr);
7071 bool Stream4k =
false;
7074 if (stream.resolution.height > AAMP_FHD_HEIGHT)
7076 height = stream.resolution.height ;
7077 bandwidth = stream.bandwidthBitsPerSecond;
7079 AAMPLOG_INFO(
"4K profile found resolution : %d*%d bandwidth %ld", stream.resolution.height, stream.resolution.width, stream.bandwidthBitsPerSecond);
7091 std::string audiogroupId ;
7094 bool iProfileCapped =
false;
7098 resolutionCheckEnabled =
false;
7104 int iFrameSelectedCount = 0;
7105 int iFrameAvailableCount = 0;
7110 for (
int i = 0; i <
aamp->bitrateList.size(); i++)
7113 long curValue, diff;
7120 if ((0 == pidx) || (diff < curValue))
7133 bool loopAgain =
false;
7140 iFrameAvailableCount++;
7144 iProfileCapped =
true;
7173 iFrameSelectedCount++;
7179 if (iFrameAvailableCount > 0 && 0 == iFrameSelectedCount && resolutionCheckEnabled)
7181 resolutionCheckEnabled = iProfileCapped =
false;
7184 if (
false == loopAgain)
7193 if(iFrameSelectedCount == 0 && iFrameAvailableCount !=0)
7196 AAMPLOG_WARN(
"No Iframe available matching bitrate criteria Low[%ld] High[%ld]. Total Iframe available:%d",minBitrate,maxBitrate,iFrameAvailableCount);
7198 else if(iFrameSelectedCount)
7204 else if(
rate == AAMP_NORMAL_PLAY_RATE ||
rate == AAMP_RATE_PAUSE)
7213 bool bDisableAC3 = bDisableEC3;
7216 bool bDisableAAC =
false;
7223 AAMPLOG_WARN(
"Audio groupId selected:%s", audiogroupId.c_str());
7229 for (
int i = 0; i <
aamp->bitrateList.size(); i++)
7239 if ((0 == pidx) || (diff < tval))
7250 int vProfileCountSelected = 0;
7252 int aacProfiles = 0, ac3Profiles = 0, ec3Profiles = 0, atmosProfiles = 0;
7253 vProfileCountSelected = 0;
7254 int vProfileCountAvailable = 0;
7255 int audioProfileMatchedCount = 0;
7256 int bitrateMatchedCount = 0;
7257 int resolutionMatchedCount = 0;
7258 bool ignoreBitRateRangeCheck =
false;
7259 int availableCountATMOS = 0, availableCountEC3 = 0, availableCountAC3 = 0;
7261 bool bVideoResolutionCheckEnabled =
false;
7262 bool bVideoThumbnailResolutionCheckEnabled =
false;
7268 bool ignoreProfile =
false;
7269 bool clearProfiles =
false;
7272 vProfileCountAvailable++;
7281 audioProfileMatchedCount++;
7284 iProfileCapped =
true;
7289 AAMPLOG_INFO(
"Video Profile ignored for disabled 4k content");
7293 resolutionMatchedCount++;
7297 iProfileCapped =
true;
7301 iProfileCapped =
true;
7306 bitrateMatchedCount++;
7314 ignoreProfile =
true;
7323 availableCountAC3++;
7327 ignoreProfile =
true;
7338 clearProfiles =
true;
7344 availableCountEC3++;
7348 ignoreProfile =
true;
7355 if(aacProfiles || ac3Profiles)
7358 aacProfiles = ac3Profiles = 0;
7359 clearProfiles =
true;
7365 availableCountATMOS++;
7369 ignoreProfile =
true;
7377 if(aacProfiles || ac3Profiles || ec3Profiles)
7380 aacProfiles = ac3Profiles = ec3Profiles = 0;
7381 clearProfiles =
true;
7387 AAMPLOG_WARN(
"unknown codec string to categorize :%s ",
streamInfo->
codecs);
7394 vProfileCountAvailable = 0;
7395 audioProfileMatchedCount = 0;
7396 bitrateMatchedCount = 0;
7397 vProfileCountSelected = 0;
7398 availableCountEC3 = 0;
7399 availableCountAC3 = 0;
7400 availableCountATMOS = 0;
7408 vProfileCountSelected ++;
7417 vProfileCountSelected ++;
7423 AAMPLOG_WARN(
"AudioType Changed %d -> %d",
7430 if(vProfileCountSelected)
7478 if(vProfileCountAvailable && audioProfileMatchedCount==0)
7482 AAMPLOG_WARN(
"ERROR No Video Profile found for matching audio group [%s]", audiogroupId.c_str());
7483 audiogroupId.clear();
7486 else if(vProfileCountAvailable && audioProfileMatchedCount && resolutionMatchedCount==0)
7491 resolutionCheckEnabled =
false;
7492 iProfileCapped =
false;
7495 else if(vProfileCountAvailable && audioProfileMatchedCount && bitrateMatchedCount==0)
7499 AAMPLOG_WARN(
"ERROR No video profiles available in manifest for playback, minBitrate:%ld maxBitrate:%ld", minBitrate, maxBitrate);
7500 ignoreBitRateRangeCheck =
true;
7503 else if(vProfileCountAvailable && bitrateMatchedCount)
7506 if(bDisableATMOS && availableCountATMOS)
7508 AAMPLOG_WARN(
"Resetting DisableATMOS flag as no Video Profile could be selected. ATMOS Count[%d]", availableCountATMOS);
7509 bDisableATMOS =
false;
7512 else if(bDisableEC3 && availableCountEC3)
7514 AAMPLOG_WARN(
"Resetting DisableEC3 flag as no Video Profile could be selected. EC3 Count[%d]", availableCountEC3);
7515 bDisableEC3 =
false;
7518 else if(bDisableAC3 && availableCountAC3)
7520 AAMPLOG_WARN(
"Resetting DisableAC3 flag as no Video Profile could be selected. AC3 Count[%d]", availableCountAC3);
7521 bDisableAC3 =
false;
7526 AAMPLOG_WARN(
"Unable to select any video profiles due to unknown codec selection , mProfileCount : %d vProfileCountAvailable:%d",
mProfileCount,vProfileCountAvailable);
7533 AAMPLOG_WARN(
"Unable to select any video profiles , mProfileCount : %d vProfileCountAvailable:%d",
mProfileCount,vProfileCountAvailable);
7537 }
while(vProfileCountSelected == 0);
7548 if (!track.index.empty())
7554 if (!
aamp->mSubLanguage.empty())
7570 bool tracksChanged =
false;
7576 std::string index = std::to_string(i);
7579 std::string
name = (media->
name != NULL) ? std::string(media->
name) : std::string();
7581 std::string codec = GetAudioFormatStringForCodec(media->
audioFormat) ;
7582 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS:: Audio Track - lang:%s, group_id:%s, name:%s, codec:%s, characteristics:%s, channels:%d",
7588 std::string index = std::to_string(i);
7591 std::string
name = (media->
name != NULL) ? std::string(media->
name) : std::string();
7594 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS:: Text Track - lang:%s, isCC:%d, group_id:%s, name:%s, instreamID:%s, characteristics:%s",
7602 tracksChanged =
true;
7610 tracksChanged =
false;
7613 tracksChanged =
true;
7620 #ifdef AAMP_CC_ENABLED
7621 std::vector<TextTrackInfo> textTracksCopy;
7629 #ifdef AAMP_CC_ENABLED
7632 AAMPLOG_ERR(
"StreamAbstractionAAMP_HLS:: Fail to get available audio/text tracks, mMediaCount=%d and profileCount=%d!",
mMediaCount,
mProfileCount);
7651 const char* group = NULL;
7654 if(streamInfo !=
nullptr)
7667 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS:: track [%d] group [%s], language [%s]",
type, group, lang.c_str());
7670 if (this->mediaInfo[i].
group_id && !strcmp(group, this->mediaInfo[i].
group_id))
7673 if (lang == mediaLang)
7708 format = map->format;
7709 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::Track[%d] format is %d [%s]",
type, map->format, map->codec);
7713 AAMPLOG_WARN(
"StreamAbstractionAAMP_HLS::assuming stereo");
7723 std::vector<StreamInfo*> StreamAbstractionAAMP_HLS::GetAvailableVideoTracks(
void)
7725 std::vector<StreamInfo*> videoTracks;
7731 videoTracks.push_back(sptr);
7766 std::string muxPrefix =
"mux-";
7767 std::string trackIndex = index.substr(muxPrefix.size());
7768 unsigned char indexNum = (
unsigned char) stoi(trackIndex);