64 #define STREAMER_STACK_SIZE (4096) 65 #define MIN_BUFFERED_BYTES (524288) 67 #define INVALID_MEASUREMENT (-1) 68 #define MAX_HISTORY_SIZE (262144) 69 #define MAX_REDIRECTS (5) 71 #define DEBUG_DETAIL(x) 73 #define PDBG(x) TRACE(TICS, x) 78 #define REQUEST_STREAM_STATE_STR(r) \ 79 ((r)->streamState == STATE_STREAM_STOPPED ? "STATE_STREAM_STOPPED" : \ 80 (r)->streamState == STATE_STREAM_PREPARED ? "STATE_STREAM_PREPARED" : \ 81 (r)->streamState == STATE_STREAM_RUNNING ? "STATE_STREAM_RUNNING" : \ 84 #define REQUEST_DOWNLOAD_STATE_STR(r) \ 85 ((r)->downloadState == STATE_DOWNLOAD_STOPPED ? "STATE_DOWNLOAD_STOPPED" : \ 86 (r)->downloadState == STATE_DOWNLOAD_QUEUED ? "STATE_DOWNLOAD_QUEUED" : \ 87 (r)->downloadState == STATE_DOWNLOAD_CHECK_ACCESS ? "STATE_DOWNLOAD_CHECK_ACCESS" : \ 88 (r)->downloadState == STATE_DOWNLOAD_WAIT_ACCESS ? "STATE_DOWNLOAD_WAIT_ACCESS" : \ 89 (r)->downloadState == STATE_DOWNLOAD_HAS_ACCESS ? "STATE_DOWNLOAD_HAS_ACCESS" : \ 90 (r)->downloadState == STATE_DOWNLOAD_WAIT_CERT ? "STATE_DOWNLOAD_WAIT_CERT" : \ 91 (r)->downloadState == STATE_DOWNLOAD_HAS_CERT ? "STATE_DOWNLOAD_HAS_CERT" : \ 92 (r)->downloadState == STATE_DOWNLOAD_STARTED ? "STATE_DOWNLOAD_STARTED" : \ 93 (r)->downloadState == STATE_DOWNLOAD_RUNNING ? "STATE_DOWNLOAD_RUNNING" : \ 94 (r)->downloadState == STATE_DOWNLOAD_DONE ? "STATE_DOWNLOAD_DONE" : \ 95 (r)->downloadState == STATE_DOWNLOAD_FAILED ? "STATE_DOWNLOAD_FAILED" : \ 98 #define REQUEST_OUTPUT_STATE_STR(r) \ 99 ((r)->outputState == STATE_OUTPUT_STOPPED ? "STATE_OUTPUT_STOPPED" : \ 100 (r)->outputState == STATE_OUTPUT_PENDING ? "STATE_OUTPUT_PENDING" : \ 101 (r)->outputState == STATE_OUTPUT_SETUP ? "STATE_OUTPUT_SETUP" : \ 102 (r)->outputState == STATE_OUTPUT_READY ? "STATE_OUTPUT_READY" : \ 103 (r)->outputState == STATE_OUTPUT_RUNNING ? "STATE_OUTPUT_RUNNING" : \ 104 (r)->outputState == STATE_OUTPUT_STARVED ? "STATE_OUTPUT_STARVED" : \ 105 (r)->outputState == STATE_OUTPUT_DONE ? "STATE_OUTPUT_DONE" : \ 108 #define REQUEST_FLOW_STATE_STR(r) \ 109 ((r)->flowState == STATE_FLOW_STOPPED ? "STATE_FLOW_STOPPED" : \ 110 (r)->flowState == STATE_FLOW_STARTED ? "STATE_FLOW_STARTED" : \ 111 (r)->flowState == STATE_FLOW_RUNNING ? "STATE_FLOW_RUNNING" : \ 112 (r)->flowState == STATE_FLOW_UNDERFLOW ? "STATE_FLOW_UNDERFLOW" : \ 115 #define REQUEST_KEY_STATE_STR(r) \ 116 ((r)->keyState == STATE_KEY_UNKNOWN ? "STATE_KEY_UNKNOWN" : \ 117 (r)->keyState == STATE_KEY_VALID ? "STATE_KEY_VALID" : \ 118 (r)->keyState == STATE_KEY_PENDING ? "STATE_KEY_PENDING" : \ 119 (r)->keyState == STATE_KEY_ERROR ? "STATE_KEY_ERROR" : \ 131 ST_DOLBY_BRAY = 0x84,
132 ST_DOLBY_ATSC = 0x87,
136 ISO_LANG_DTAG = 0x0a,
137 STREAMID_DTAG = 0x52,
138 SUBTITLE_DTAG = 0x59,
143 STATE_STREAM_STOPPED,
144 STATE_STREAM_PREPARED,
150 STATE_DOWNLOAD_QUEUED,
151 STATE_DOWNLOAD_STOPPED,
152 STATE_DOWNLOAD_CHECK_ACCESS,
153 STATE_DOWNLOAD_WAIT_ACCESS,
154 STATE_DOWNLOAD_HAS_ACCESS,
155 STATE_DOWNLOAD_WAIT_CERT,
156 STATE_DOWNLOAD_HAS_CERT,
157 STATE_DOWNLOAD_STARTED,
158 STATE_DOWNLOAD_RUNNING,
160 STATE_DOWNLOAD_FAILED
165 STATE_OUTPUT_STOPPED,
166 STATE_OUTPUT_PENDING,
169 STATE_OUTPUT_RUNNING,
170 STATE_OUTPUT_STARVED,
195 S32BIT audio_component_tag;
196 S32BIT video_component_tag;
200 typedef struct sCounterTrigger
204 struct sCounterTrigger *next;
207 typedef struct sStreamerRequest
215 BOOLEAN contentAvailableNotified;
216 BOOLEAN contentAvailableGenerated;
217 BOOLEAN streamPlayingGenerated;
225 S32BIT counterEndPosition;
226 S32BIT counterMaxPosition;
232 U64BIT currentBytePosition;
237 StreamState streamState;
238 DownloadState downloadState;
239 OutputState outputState;
259 CounterTrigger *triggers;
261 struct sStreamerRequest *next;
268 static StreamerRequest* CreateRequest(
BOOLEAN isMeasure);
269 static void PrepareStreamingRequest(StreamerRequest *request,
271 static void SetCounterPosition(StreamerRequest *request,
MHEG5Stream *stream);
272 static void AddRequestToList(StreamerRequest *request);
273 static void RemoveRequestFromList(StreamerRequest *request);
274 static void DestroyRequest(StreamerRequest *request);
275 static void CreateDownloadRequest(StreamerRequest *request);
276 static void ProgressDownloadRequest(StreamerRequest *request);
277 static void CheckTlsCertificates(StreamerRequest *request);
278 static void DestroyDownloadRequest(StreamerRequest *request);
279 static void DestroyMeasurementRequest(StreamerRequest *request);
280 static StreamerRequest* FindRequestById(
U32BIT requestId);
281 static StreamerRequest* FindRequestByObj(
MHEG5Root *root);
282 static StreamerRequest* FindRequestByDownloadId(
U32BIT downloadId);
283 static void ProcessHttpHeaders(
U32BIT downloadId,
S32BIT code);
284 static void CalculateExpectedBytes(StreamerRequest *request);
285 static void HandleStreamKeys(StreamerRequest *request);
287 static void HandleDownloadRedirection(StreamerRequest *request,
289 static void HandleDownloadSuccess(StreamerRequest *request);
290 static void HandleDownloadPartial(StreamerRequest *request,
U32BIT downloadId);
291 static void HandleMeasurementFinished(
U32BIT downloadId);
292 static void HandleMeasurementRedirection(StreamerRequest *request);
293 static void HandleStreamPlaying(
U32BIT requestId);
294 static void HandleStreamStopped(
U32BIT requestId);
295 static void HandleCounterTrigger(
U32BIT requestId,
S32BIT triggerId);
296 static void HandleContentAvailable(
U32BIT requestId);
297 static void GenerateStreamRefError(StreamerRequest *request);
298 #ifdef INCLUDE_FREESAT 299 static void GenerateIPStreamAccessError(StreamerRequest *request);
301 static void GenerateStreamUnderflow(
void);
302 static void GenerateStreamUnderflowResume(
void);
303 static void GenerateContentAvailable(StreamerRequest *request);
304 static void GenerateStreamPlaying(StreamerRequest *request);
305 static void GenerateStreamStopped(StreamerRequest *request);
306 static void GenerateCounterTrigger(StreamerRequest *request,
S32BIT triggerId);
307 static void GenerateKeyFileError(
void);
308 static void NotifyContentAvailable(
U32BIT requestId);
309 static void NotifyStreamPlaying(
U32BIT requestId);
310 static void NotifyStreamStopped(
U32BIT requestId);
311 static void ItemInsertCallback(
U32BIT downloadId,
U64BIT base,
313 static void ItemReleaseCallback(
U32BIT requestId,
U64BIT base,
315 static void CheckCounterTriggers(StreamerRequest *request,
U64BIT base,
317 static void CheckRunCondition(StreamerRequest *request);
318 static BOOLEAN IsEnoughDataBuffered(StreamerRequest *request);
319 static U32BIT ConvertToUnits(StreamerRequest *request,
U64BIT bytes);
320 static U64BIT ConvertToBytes(StreamerRequest *request,
U32BIT units);
321 static BOOLEAN IsStreamRunning(
void);
322 static void CheckDownloadCondition(
void);
323 static void StopContentOutput(StreamerRequest *request,
BOOLEAN flush);
324 static void ResumePlayback(StreamerRequest *request);
326 static void UnderflowCallback(
U32BIT requestId,
U32BIT playoutTime);
327 static void StreamKeyLoadedCallback(
void *userData,
S_CONTENT *content);
328 static void StreamKeyLoadFailCallback(
void *userData);
329 static void ServerAccessCallback(
void);
330 static void TlsCertCallback(
void);
331 static BOOLEAN MHEG5StreamerProcess(
void);
335 static StreamerRequest *requestList = NULL;
338 static U32BIT globalRequestId = 1;
341 static U32BIT globalPrepareNumber = 1;
343 static void *streamerBuffer = NULL;
344 static U32BIT streamerBufferSize = 0;
346 static void *requestMutex = NULL;
360 streamerBuffer = NULL;
361 streamerBufferSize = 0;
365 #ifdef ERROR_ON_SMALL_ICS_BUFFER 366 TRACE(TERROR, (
"Streaming buffer must not be NULL"));
369 DPL2((
"Streaming buffer NULL - Streaming disabled"));
375 #ifdef ERROR_ON_SMALL_ICS_BUFFER 379 DPL2((
"Streaming buffer too small - Streaming disabled"));
385 streamerBuffer = buffer;
386 streamerBufferSize = size;
399 ASSERT(requestMutex == NULL)
402 if (requestMutex == NULL)
404 TRACE(TERROR, (
"Streaming requerst mutex failure"));
425 StreamerRequest *request;
426 StreamerRequest *list;
427 if (streamerBuffer != NULL)
440 list = request->next;
441 DestroyRequest(request);
453 StreamerRequest *request;
460 request = CreateRequest(
FALSE);
464 AddRequestToList(request);
471 request->counterMaxPosition = -1;
481 if (request->streamState != STATE_STREAM_RUNNING)
483 request->contentAvailableNotified =
FALSE;
484 request->contentAvailableGenerated =
FALSE;
490 request->prepareNumber = globalPrepareNumber;
491 globalPrepareNumber = (globalPrepareNumber % 1073741824) + 1;
493 PrepareStreamingRequest(request, stream);
504 StreamerRequest *request;
513 counterPosition = ConvertToUnits(request, request->currentBytePosition);
519 TRACE(TERROR, (
"Cannot find request"));
523 return counterPosition;
534 StreamerRequest *request;
543 if (((request->counterMaxPosition == -1) ||
545 ((request->counterEndPosition == -1) ||
548 SetCounterPosition(request, stream);
552 if (request->streamState == STATE_STREAM_RUNNING)
558 DestroyDownloadRequest(request);
561 if (request->outputState != STATE_OUTPUT_DONE)
563 GenerateStreamStopped(request);
567 StopContentOutput(request,
TRUE);
581 request->bytePosition = ConvertToBytes(request, endPosition);
582 request->currentBytePosition = request->bytePosition;
583 request->currentLoop = 0;
584 request->restart =
TRUE;
586 if (request->streamState == STATE_STREAM_RUNNING && isIcsSetup)
604 StreamerRequest *request;
616 CalculateExpectedBytes(request);
627 StreamerRequest *request;
628 S32BIT counterMaxPosition;
634 counterMaxPosition = request->counterMaxPosition;
640 TRACE(TERROR, (
"Cannot find request"));
644 return counterMaxPosition;
660 StreamerRequest *request;
661 CounterTrigger **pTrigger, *trigger;
670 pTrigger = &request->triggers;
671 while (*pTrigger != NULL)
674 if (trigger->id == triggerId)
679 trigger->position = newValue;
684 *pTrigger = trigger->next;
690 pTrigger = &trigger->next;
693 if (!found && newValue >= 0)
699 trigger->id = triggerId;
700 trigger->position = newValue;
701 trigger->next = NULL;
710 TRACE(TERROR, (
"Cannot find request"));
721 StreamerRequest *request;
726 if (request->streamState == STATE_STREAM_RUNNING)
729 TRACE(TICS,(
"already running"));
733 if (IsStreamRunning())
736 TRACE(TICS,(
"another running"));
743 if (request->restart)
746 request->currentLoop = 0;
748 ULL_Set32(request->currentBytePosition, 0);
758 if (request->downloadState == STATE_DOWNLOAD_STOPPED)
761 CreateDownloadRequest(request);
770 request->streamPlayingGenerated =
FALSE;
771 request->streamState = STATE_STREAM_RUNNING;
773 CheckDownloadCondition();
775 assert(request->outputState == STATE_OUTPUT_STOPPED);
776 CheckRunCondition(request);
783 TRACE(TERROR, (
"Cannot find request"));
794 StreamerRequest *request;
799 if (request->streamState == STATE_STREAM_STOPPED)
810 if (request->streamState == STATE_STREAM_RUNNING)
818 DestroyDownloadRequest(request);
821 if (request->outputState != STATE_OUTPUT_DONE)
823 GenerateStreamStopped(request);
827 StopContentOutput(request,
TRUE);
830 stream->
counterPosition = ConvertToUnits(request, request->currentBytePosition);
831 request->bytePosition = request->currentBytePosition;
832 request->pauseRequestCount = 0;
835 request->redirectCount = 0;
837 if (request->streamState == STATE_STREAM_RUNNING && isIcsSetup)
843 request->streamState = STATE_STREAM_STOPPED;
848 TRACE(TERROR, (
"Cannot find request"));
859 StreamerRequest *request;
864 if ((request->streamState == STATE_STREAM_RUNNING) &&
867 switch (request->outputState)
869 case STATE_OUTPUT_READY:
870 case STATE_OUTPUT_RUNNING:
871 case STATE_OUTPUT_STARVED:
872 ++request->pauseRequestCount;
873 if (request->pauseRequestCount == 1)
886 stream->
counterPosition = ConvertToUnits(request, request->currentBytePosition);
888 request->paused =
TRUE;
893 TRACE(TERROR, (
"Cannot find request"));
904 StreamerRequest *request;
909 if ((request->streamState == STATE_STREAM_RUNNING) &&
912 switch (request->outputState)
914 case STATE_OUTPUT_READY:
915 case STATE_OUTPUT_RUNNING:
916 case STATE_OUTPUT_STARVED:
917 case STATE_OUTPUT_STOPPED:
918 ResumePlayback(request);
924 request->paused =
FALSE;
929 TRACE(TERROR, (
"Cannot find request"));
951 StreamerRequest *request;
956 if (request->streamState == STATE_STREAM_RUNNING)
964 DestroyDownloadRequest(request);
967 StopContentOutput(request,
TRUE);
970 RemoveRequestFromList(request);
973 DestroyRequest(request);
985 switch (params->eventType)
988 PDBG((
"MHEG5_STREAMER_EVENT_MSP_DOWNLOAD_DONE"));
989 HandleMeasurementFinished(params->requestId);
992 PDBG((
"MHEG5_STREAMER_HTTP_HEADERS_DONE"));
993 ProcessHttpHeaders(params->requestId,params->code);
996 PDBG((
"MHEG5_STREAMER_EVENT_HTTP_DOWNLOAD_DONE"));
997 HandleDownloadFinished(params->requestId,params->status,params->code);
1000 PDBG((
"MHEG5_STREAMER_EVENT_TASK_STREAM_PLAYING"));
1001 HandleStreamPlaying(params->requestId);
1004 PDBG((
"MHEG5_STREAMER_EVENT_TASK_STREAM_STOPPED"));
1005 HandleStreamStopped(params->requestId);
1008 PDBG((
"MHEG5_STREAMER_EVENT_COUNTER_TRIGGER"));
1009 HandleCounterTrigger(params->requestId, params->triggerId);
1012 DBG((
"MHEG5_STREAMER_EVENT_CONTENT_AVAILABLE"));
1013 HandleContentAvailable(params->requestId);
1016 PDBG((
"Unhandled event %d!", params->eventType));
1030 StreamerRequest *request;
1034 if (request != NULL)
1036 switch (request->flowState)
1038 case STATE_FLOW_STARTED:
1039 request->flowState = STATE_FLOW_RUNNING;
1040 GenerateStreamPlaying(request);
1042 case STATE_FLOW_UNDERFLOW:
1043 request->flowState = STATE_FLOW_RUNNING;
1044 GenerateStreamUnderflowResume();
1046 case STATE_FLOW_RUNNING:
1048 DBG((
"Ignoring StreamStarted in STATE_FLOW_RUNNING"));
1050 case STATE_FLOW_STOPPED:
1051 PDBG((
"%d ~ WARNING: Stream started when flow is stopped",
1052 request->requestId));
1055 TRACE(TERROR, (
"Unhandled flow state"));
1070 StreamerRequest *request;
1074 if (request != NULL)
1076 PDBG((
"%d ~ request->flowState = %s", request->requestId,
1077 REQUEST_FLOW_STATE_STR(request)));
1078 switch (request->flowState)
1080 case STATE_FLOW_RUNNING:
1081 PDBG((
"%d ~ request->downloadState = %s", request->requestId,
1082 REQUEST_DOWNLOAD_STATE_STR(request)));
1083 if (request->downloadState == STATE_DOWNLOAD_RUNNING)
1085 request->flowState = STATE_FLOW_UNDERFLOW;
1086 GenerateStreamUnderflow();
1088 else if (request->downloadState == STATE_DOWNLOAD_DONE)
1090 request->flowState = STATE_FLOW_STOPPED;
1091 GenerateStreamStopped(request);
1095 TRACE(TERROR, (
"Unhandled download state"));
1099 case STATE_FLOW_STOPPED:
1101 DBG((
"Expected underflow in %s", REQUEST_FLOW_STATE_STR(request)));
1103 case STATE_FLOW_UNDERFLOW:
1106 case STATE_FLOW_STARTED:
1114 TRACE(TERROR, (
"Unhandled flow state"));
1124 static BOOLEAN MHEG5StreamerProcess(
void)
1126 StreamerRequest *request;
1128 if (processRequests)
1133 processRequests =
FALSE;
1135 request = requestList;
1136 while (request != NULL)
1138 switch (request->downloadState)
1140 case STATE_DOWNLOAD_CHECK_ACCESS:
1141 ProgressDownloadRequest(request);
1148 request = request->next;
1151 return processRequests;
1165 StreamerRequest *request;
1167 request = CreateRequest(
TRUE);
1168 if (request != NULL)
1173 if (IsValidUrl(&request->url))
1175 DBG((
"Measurement URL: %s", request->url.data));
1178 request->maxBytes = maxBytes;
1181 AddRequestToList(request);
1184 request->downloadState = STATE_DOWNLOAD_QUEUED;
1185 ProgressDownloadRequest(request);
1190 DBG((
"MHEG5StreamerMeasurePerformance: Invalid URL"));
1191 request->downloadState = STATE_DOWNLOAD_FAILED;
1203 StreamerRequest *request;
1207 if (request != NULL)
1214 TRACE(TERROR, (
"Cannot find request"));
1226 StreamerRequest *request;
1229 request = requestList;
1230 while (request != NULL)
1232 if (request->streamState == STATE_STREAM_RUNNING)
1236 request = request->next;
1240 if (request != NULL)
1242 if (activeState && isIcsSetup)
1244 PDBG((
"rid=%d",request->requestId));
1246 if (request->isPartial)
1248 request->downloadState = STATE_DOWNLOAD_QUEUED;
1249 ProgressDownloadRequest(request);
1265 if (streamerBuffer != NULL)
1273 if (requestMutex != NULL)
1276 requestMutex = NULL;
1290 StreamerRequest *request;
1291 if (streamerBuffer != NULL)
1294 request = requestList;
1295 while (request != NULL)
1297 if (request->streamState == STATE_STREAM_RUNNING)
1300 request->flowState = STATE_FLOW_STOPPED;
1301 request->outputState = STATE_OUTPUT_STOPPED;
1302 CheckRunCondition(request);
1304 request = request->next;
1322 StreamerRequest *request;
1324 request = FindRequestById(requestId);
1325 if (request != NULL)
1332 MHEG5notifyStreamPerformanceMeasurement(request->root, speed);
1336 RemoveRequestFromList(request);
1339 DestroyRequest(request);
1352 static StreamerRequest* CreateRequest(
BOOLEAN isMeasure)
1354 StreamerRequest *request;
1356 #ifndef ERROR_ON_SMALL_ICS_BUFFER 1357 if (streamerBuffer == NULL)
1359 TRACE(TERROR, (
"Streaming buffer must not be NULL"));
1366 if (request != NULL)
1369 request->requestId = globalRequestId;
1370 globalRequestId = (globalRequestId % 1073741824) + 1;
1373 request->downloadId = 0;
1376 request->isMeasureType = isMeasure;
1379 request->paused =
TRUE;
1380 request->isPartial =
FALSE;
1381 request->pauseRequestCount = 0;
1382 request->contentAvailableNotified =
FALSE;
1383 request->contentAvailableGenerated =
FALSE;
1384 request->streamPlayingGenerated =
FALSE;
1385 request->counterEndPosition = -1;
1386 request->counterMaxPosition = -1;
1387 request->certCount = 0;
1388 request->streamState = STATE_STREAM_STOPPED;
1389 request->downloadState = STATE_DOWNLOAD_STOPPED;
1390 request->outputState = STATE_OUTPUT_STOPPED;
1391 request->flowState = STATE_FLOW_STOPPED;
1395 ULL_Set32(request->currentBytePosition, 0);
1400 request->url.len = 0;
1401 request->url.data = NULL;
1403 request->redirectUrl.len = 0;
1404 request->redirectUrl.data = NULL;
1405 request->redirectCount = 0;
1408 request->bitrate = 0;
1410 request->keys.num_pids = 0;
1411 request->keys.pid_info = NULL;
1412 request->keyLocation.len = 0;
1413 request->keyLocation.data = NULL;
1414 request->keyState = STATE_KEY_UNKNOWN;
1415 request->keyDownloadId = 0;
1417 request->pmtRetrieved =
FALSE;
1418 request->triggers = NULL;
1419 request->prepareNumber = globalPrepareNumber;
1420 globalPrepareNumber = (globalPrepareNumber % 1073741824) + 1;
1432 static void PrepareStreamingRequest(StreamerRequest *request,
1449 request->url = newUrl;
1453 request->redirectCount = 0;
1455 len = request->url.len;
1458 PDBG((
"%d ~ Cannot convert GID", request->requestId));
1459 request->downloadState = STATE_DOWNLOAD_FAILED;
1463 if (IsValidUrl(&request->url))
1467 if (request->streamState == STATE_STREAM_RUNNING)
1473 DestroyDownloadRequest(request);
1476 StopContentOutput(request,
TRUE);
1479 request->bytePosition = ConvertToBytes(request, stream->
counterPosition);
1480 request->currentBytePosition = request->bytePosition;
1483 request->looping = stream->
looping;
1484 request->currentLoop = 0;
1485 request->restart =
FALSE;
1487 if (stream->
speed[0] == 0)
1489 request->paused =
TRUE;
1493 request->paused =
FALSE;
1496 switch (request->streamState)
1498 case STATE_STREAM_RUNNING:
1499 request->flowState = STATE_FLOW_STOPPED;
1500 request->outputState = STATE_OUTPUT_STOPPED;
1502 case STATE_STREAM_STOPPED:
1503 request->streamState = STATE_STREAM_PREPARED;
1505 case STATE_STREAM_PREPARED:
1506 request->contentAvailableNotified =
FALSE;
1507 request->contentAvailableGenerated =
FALSE;
1516 request->contentAvailableNotified =
FALSE;
1517 request->contentAvailableGenerated =
FALSE;
1519 request->pmtRetrieved =
FALSE;
1520 if (request->keys.num_pids > 0)
1523 request->keys.num_pids = 0;
1524 request->keys.pid_info = NULL;
1527 request->keyState = STATE_KEY_UNKNOWN;
1528 request->keyDownloadId = 0;
1531 CheckDownloadCondition();
1536 DBG((
"InitStreamRequest: Invalid source"));
1537 request->downloadState = STATE_DOWNLOAD_FAILED;
1547 static void SetCounterPosition(StreamerRequest *request,
MHEG5Stream *stream)
1553 oldpos = request->currentBytePosition;
1554 downpos = request->bytePosition;
1555 ULL_Add(downpos,request->downloadedBytes);
1559 TRACE(TICS,(
"requestId=%d newBytePos=%d oldBytePos=%d",request->requestId,
1566 TRACE(TICS,(
"flushing data that is no longer required"));
1567 if (request->streamState == STATE_STREAM_RUNNING)
1570 request->flowState = STATE_FLOW_STOPPED;
1571 request->outputState = STATE_OUTPUT_STOPPED;
1574 request->currentBytePosition = newpos;
1577 CheckRunCondition(request);
1582 TRACE(TICS,(
"SCP outside of buffered data, restarting download SCOut"));
1584 if (request->streamState == STATE_STREAM_RUNNING)
1592 DestroyDownloadRequest(request);
1595 request->bytePosition = newpos;
1596 request->currentBytePosition = newpos;
1598 request->currentLoop = 0;
1599 request->restart =
FALSE;
1601 PDBG((
"streamState %u", request->streamState));
1602 switch (request->streamState)
1604 case STATE_STREAM_RUNNING:
1605 request->flowState = STATE_FLOW_STOPPED;
1606 request->outputState = STATE_OUTPUT_STOPPED;
1609 case STATE_STREAM_STOPPED:
1610 request->streamState = STATE_STREAM_PREPARED;
1612 case STATE_STREAM_PREPARED:
1613 request->contentAvailableNotified =
FALSE;
1614 request->contentAvailableGenerated =
FALSE;
1618 CheckDownloadCondition();
1627 static void AddRequestToList(StreamerRequest *request)
1629 StreamerRequest **ppRequest;
1632 ppRequest = &requestList;
1633 while (*ppRequest != NULL)
1635 ppRequest = &(*ppRequest)->next;
1638 *ppRequest = request;
1639 request->next = NULL;
1647 static void RemoveRequestFromList(StreamerRequest *request)
1649 StreamerRequest **ppRequest;
1651 ppRequest = &requestList;
1652 while (*ppRequest != NULL && *ppRequest != request)
1654 ppRequest = &(*ppRequest)->next;
1657 if (*ppRequest != NULL)
1660 *ppRequest = (*ppRequest)->next;
1669 static void CreateDownloadRequest(StreamerRequest *request)
1671 assert(request->downloadId == 0);
1672 assert(request->downloadState != STATE_DOWNLOAD_STARTED &&
1673 request->downloadState != STATE_DOWNLOAD_RUNNING);
1675 request->downloadState = STATE_DOWNLOAD_QUEUED;
1676 ProgressDownloadRequest(request);
1690 static void ProgressDownloadRequest(StreamerRequest *request)
1695 U64BIT rangeFrom, rangeTo;
1697 if (request->downloadState == STATE_DOWNLOAD_QUEUED)
1700 PDBG((
"%d ~ Progress: STATE_DOWNLOAD_QUEUED", request->requestId));
1703 request->downloadState = STATE_DOWNLOAD_CHECK_ACCESS;
1706 if (request->downloadState == STATE_DOWNLOAD_CHECK_ACCESS)
1709 PDBG((
"%d ~ Progress: STATE_DOWNLOAD_CHECK_ACCESS", request->requestId));
1710 if (request->redirectCount == 0)
1715 request->downloadState = STATE_DOWNLOAD_FAILED;
1716 GenerateStreamRefError(request);
1717 PDBG((
"%d ~ Progress: STATE_DOWNLOAD_FAILED", request->requestId));
1721 request->downloadState = STATE_DOWNLOAD_WAIT_ACCESS;
1722 PDBG((
"%d ~ Progress: STATE_DOWNLOAD_WAIT_ACCESS", request->requestId));
1726 request->downloadState = STATE_DOWNLOAD_HAS_ACCESS;
1732 request->downloadState = STATE_DOWNLOAD_HAS_ACCESS;
1736 if (request->downloadState == STATE_DOWNLOAD_HAS_ACCESS)
1739 PDBG((
"%d ~ Progress: STATE_DOWNLOAD_HAS_ACCESS", request->requestId));
1740 CheckTlsCertificates(request);
1743 if (request->downloadState == STATE_DOWNLOAD_HAS_CERT)
1746 PDBG((
"%d ~ Progress: STATE_DOWNLOAD_HAS_CERT", request->requestId));
1747 if (request->redirectCount > 0)
1749 url = (
char *)request->redirectUrl.data;
1753 url = (
char *)request->url.data;
1756 if (request->isPartial)
1758 assert(request->downloadId != 0);
1760 request->isPartial =
FALSE;
1765 if (request->currentLoop == request->looping - 1)
1771 lastRequest =
FALSE;
1774 rangeFrom = request->bytePosition;
1776 if (!request->isMeasureType)
1779 request->requestId, url, rangeFrom, rangeTo, lastRequest);
1784 request->requestId, url, request->maxBytes);
1788 if (request->downloadId != 0)
1790 request->downloadState = STATE_DOWNLOAD_STARTED;
1791 if (!request->isMeasureType)
1802 request->downloadState = STATE_DOWNLOAD_FAILED;
1817 static void CheckTlsCertificates(StreamerRequest *request)
1823 if (request->redirectCount == 0)
1825 url = request->url.data;
1829 url = request->redirectUrl.data;
1835 request->downloadState = STATE_DOWNLOAD_WAIT_CERT;
1838 if (certCount == 0 || request->certCount == certCount)
1848 request->downloadState = STATE_DOWNLOAD_HAS_CERT;
1852 request->downloadState = STATE_DOWNLOAD_FAILED;
1853 GenerateStreamRefError(request);
1856 else if (request->certCount < certCount)
1859 request->certCount = certCount;
1860 request->downloadState = STATE_DOWNLOAD_HAS_CERT;
1866 request->downloadState = STATE_DOWNLOAD_HAS_CERT;
1875 static void DestroyDownloadRequest(StreamerRequest *request)
1880 request->downloadState = STATE_DOWNLOAD_STOPPED;
1881 request->downloadId = 0;
1882 request->certCount = 0;
1890 static void DestroyMeasurementRequest(StreamerRequest *request)
1895 request->downloadState = STATE_DOWNLOAD_STOPPED;
1896 request->downloadId = 0;
1897 request->certCount = 0;
1905 static void DestroyRequest(StreamerRequest *request)
1907 CounterTrigger *trigger, *next;
1909 DestroyDownloadRequest(request);
1913 trigger = request->triggers;
1914 while (trigger != NULL)
1916 next = trigger->next;
1920 request->triggers = NULL;
1922 if (request->keys.pid_info != NULL)
1938 static StreamerRequest* FindRequestById(
U32BIT requestId)
1940 StreamerRequest *request;
1942 request = requestList;
1944 while (request != NULL && request->requestId != requestId)
1946 request = request->next;
1957 static StreamerRequest* FindRequestByObj(
MHEG5Root *root)
1959 StreamerRequest *request;
1961 request = requestList;
1962 while ((request != NULL) && (request->root != root))
1964 request = request->next;
1975 static StreamerRequest* FindRequestByDownloadId(
U32BIT downloadId)
1977 StreamerRequest *request;
1979 request = requestList;
1981 while (request != NULL && request->downloadId != downloadId)
1983 request = request->next;
2003 static void ProcessHttpHeaders(
U32BIT downloadId,
S32BIT code)
2005 StreamerRequest *request;
2010 request = FindRequestByDownloadId(downloadId);
2011 if (request != NULL)
2013 PDBG((
"%d ~ response code: %d", request->requestId, code));
2015 if (code == 200 || code == 206)
2022 ULL_Set32(request->currentBytePosition, 0);
2025 DBG((
"request %d download state %s", request->requestId,
2026 REQUEST_DOWNLOAD_STATE_STR(request)));
2029 if (request->downloadState != STATE_DOWNLOAD_STARTED)
2031 PDBG((
"%d ~ WARNING: Incorrect download state, overridden",
2032 request->requestId));
2034 request->downloadState = STATE_DOWNLOAD_RUNNING;
2040 request->contentLength =
2042 request->contentLength);
2043 PDBG((
"%d ~ contentLength:", request->requestId));
2048 units = ConvertToUnits(request, request->contentLength);
2049 request->counterMaxPosition = units;
2050 PDBG((
"%d ~ counterMaxPosition = units = %d",
2051 request->requestId, units));
2052 CalculateExpectedBytes(request);
2057 &request->keyLocation);
2058 HandleStreamKeys(request);
2063 CheckRunCondition(request);
2080 static void CalculateExpectedBytes(StreamerRequest *request)
2082 U64BIT endPosition, counterEndPosition;
2091 PDBG((
"%d ~ contentLength is valid", request->requestId));
2092 endPosition = request->contentLength;
2093 if (request->counterEndPosition > 0)
2095 PDBG((
"%d ~ counterEndPosition > 0", request->requestId));
2096 counterEndPosition = ConvertToBytes(request, request->counterEndPosition);
2097 if (
ULL_Compare(counterEndPosition, endPosition) < 0)
2100 PDBG((
"%d ~ counterEndPosition < counterMaxPosition",
2101 request->requestId));
2102 endPosition = counterEndPosition;
2107 PDBG((
"%d ~ endPosition is valid: %s\n", request->requestId,
2112 request->expectedBytes = endPosition;
2113 ULL_Sub(request->expectedBytes, request->bytePosition);
2114 PDBG((
"%d ~ request->expectedBytes = ", request->requestId));
2124 static void HandleStreamKeys(StreamerRequest *request)
2129 if ((request->keyState == STATE_KEY_UNKNOWN) &&
2130 (request->keys.num_pids == 0) &&
2131 (request->keyLocation.len > 0))
2133 request->keyState = STATE_KEY_PENDING;
2139 request->keyDownloadId = request->downloadId;
2142 (
void *)request->root,
2143 StreamKeyLoadedCallback,
2144 StreamKeyLoadFailCallback);
2148 request->keyState = STATE_KEY_VALID;
2159 StreamerRequest *request;
2161 request = FindRequestByDownloadId(downloadId);
2162 if (request == NULL)
2164 PDBG((
"Cannot find request from download id %d - already gone",downloadId));
2173 HandleDownloadRedirection(request,
TRUE);
2175 else if ((code > 301) && (code <= 307) && (code != 306))
2178 HandleDownloadRedirection(request,
FALSE);
2180 else if ((code == 200) || (code == 206))
2183 HandleDownloadSuccess(request);
2187 PDBG((
"%d ~ HTTP_STATUS_OK code=%d", request->requestId,code));
2188 #ifdef INCLUDE_FREESAT 2189 if ((code == 401) || (code == 403) || (code == 407))
2191 GenerateIPStreamAccessError(request);
2195 GenerateStreamRefError(request);
2198 GenerateStreamRefError(request);
2204 PDBG((
"%d ~ HTTP_STATUS_PARTIAL", request->requestId));
2205 HandleDownloadPartial(request,downloadId);
2209 PDBG((
"%d ~ HTTP_STATUS_SSL_ERROR", request->requestId));
2210 request->downloadState = STATE_DOWNLOAD_QUEUED;
2211 ProgressDownloadRequest(request);
2215 PDBG((
"%d ~ Network error, timeout or other", request->requestId));
2218 request->downloadState = STATE_DOWNLOAD_FAILED;
2219 GenerateStreamRefError(request);
2223 CheckDownloadCondition();
2232 static void HandleDownloadRedirection(StreamerRequest *request,
2240 if (redirectUrl.
data != NULL)
2244 &request->keyLocation);
2247 redirectUrl.
len = strlen((
char *)redirectUrl.
data);
2255 ++request->redirectCount;
2257 DestroyDownloadRequest(request);
2259 request->downloadState = STATE_DOWNLOAD_HAS_ACCESS;
2260 ProgressDownloadRequest(request);
2264 PDBG((
"%d ~ Cannot find redirection URL", request->requestId));
2265 request->downloadState = STATE_DOWNLOAD_FAILED;
2266 GenerateStreamRefError(request);
2271 PDBG((
"%d ~ Too many redirections!", request->requestId));
2272 request->downloadState = STATE_DOWNLOAD_FAILED;
2273 GenerateStreamRefError(request);
2282 static void HandleDownloadSuccess(StreamerRequest *request)
2284 DestroyDownloadRequest(request);
2286 if (request->looping == 0 || request->currentLoop < request->looping - 1)
2288 PDBG((
"%d ~ Looping: current loop %d out of %d",
2289 request->requestId, request->currentLoop, request->looping));
2290 ++request->currentLoop;
2291 assert(request->downloadState == STATE_DOWNLOAD_STOPPED);
2292 CreateDownloadRequest(request);
2296 request->downloadState = STATE_DOWNLOAD_DONE;
2303 CheckRunCondition(request);
2313 static void HandleDownloadPartial(StreamerRequest *request,
U32BIT downloadId)
2320 PDBG((
"%d ~ restart download",request->requestId));
2323 request->bytePosition = position;
2324 request->isPartial =
TRUE;
2325 request->certCount = 0;
2328 request->downloadState = STATE_DOWNLOAD_QUEUED;
2329 ProgressDownloadRequest(request);
2334 DestroyDownloadRequest(request);
2335 request->downloadState = STATE_DOWNLOAD_DONE;
2338 CheckRunCondition(request);
2347 static void HandleMeasurementFinished(
U32BIT downloadId)
2349 StreamerRequest *request;
2353 request = FindRequestByDownloadId(downloadId);
2354 if (request != NULL)
2360 if ((code >= 301) && (code <= 307) && (code != 306))
2363 HandleMeasurementRedirection(request);
2373 PDBG((
"%d ~ HTTP_STATUS_SSL_ERROR", request->requestId));
2374 request->downloadState = STATE_DOWNLOAD_QUEUED;
2375 ProgressDownloadRequest(request);
2379 PDBG((
"%d ~ Network error, timeout or other", request->requestId));
2381 request->downloadState = STATE_DOWNLOAD_FAILED;
2396 static void HandleMeasurementRedirection(StreamerRequest *request)
2403 if (redirectUrl.
data != NULL)
2406 redirectUrl.
len = strlen((
char *)redirectUrl.
data);
2408 ++request->redirectCount;
2410 DestroyMeasurementRequest(request);
2412 request->downloadState = STATE_DOWNLOAD_HAS_ACCESS;
2413 ProgressDownloadRequest(request);
2417 PDBG((
"%d ~ Cannot find redirection URL", request->requestId));
2418 request->downloadState = STATE_DOWNLOAD_FAILED;
2424 PDBG((
"%d ~ Too many redirections!", request->requestId));
2425 request->downloadState = STATE_DOWNLOAD_FAILED;
2437 StreamerRequest *request;
2441 request = requestList;
2442 while (request != NULL)
2444 if (request->outputState == STATE_OUTPUT_PENDING)
2452 request->outputState = STATE_OUTPUT_SETUP;
2453 CheckRunCondition(request);
2457 request = request->next;
2468 static void HandleStreamPlaying(
U32BIT requestId)
2470 StreamerRequest *request;
2472 request = FindRequestById(requestId);
2473 if (request != NULL)
2475 switch (request->flowState)
2477 case STATE_FLOW_STARTED:
2478 request->flowState = STATE_FLOW_RUNNING;
2479 GenerateStreamPlaying(request);
2481 case STATE_FLOW_UNDERFLOW:
2482 request->flowState = STATE_FLOW_RUNNING;
2483 GenerateStreamUnderflowResume();
2485 case STATE_FLOW_RUNNING:
2487 DBG((
"Ignoring StreamStarted in STATE_FLOW_RUNNING"));
2489 case STATE_FLOW_STOPPED:
2490 PDBG((
"%d ~ WARNING: Stream started when flow is stopped",
2491 request->requestId));
2494 TRACE(TERROR, (
"Unhandled flow state"));
2506 static void HandleStreamStopped(
U32BIT requestId)
2508 StreamerRequest *request;
2510 request = FindRequestById(requestId);
2511 if (request != NULL)
2513 PDBG((
"%d ~ request->flowState = %s", request->requestId,
2514 REQUEST_FLOW_STATE_STR(request)));
2515 switch (request->flowState)
2517 case STATE_FLOW_RUNNING:
2518 PDBG((
"%d ~ request->downloadState = %s", request->requestId,
2519 REQUEST_DOWNLOAD_STATE_STR(request)));
2520 if (request->downloadState == STATE_DOWNLOAD_RUNNING)
2522 request->flowState = STATE_FLOW_UNDERFLOW;
2523 GenerateStreamUnderflow();
2525 else if (request->downloadState == STATE_DOWNLOAD_DONE)
2527 request->flowState = STATE_FLOW_STOPPED;
2528 GenerateStreamStopped(request);
2530 else if (request->downloadState == STATE_DOWNLOAD_STARTED)
2536 TRACE(TERROR, (
"Unhandled download state"));
2540 case STATE_FLOW_STOPPED:
2542 DBG((
"Expected underflow in %s", REQUEST_FLOW_STATE_STR(request)));
2544 case STATE_FLOW_UNDERFLOW:
2547 case STATE_FLOW_STARTED:
2555 TRACE(TERROR, (
"Unhandled flow state"));
2567 static void HandleCounterTrigger(
U32BIT requestId,
S32BIT triggerId)
2569 StreamerRequest *request;
2571 request = FindRequestById(requestId);
2572 if (request != NULL)
2574 GenerateCounterTrigger(request, triggerId);
2583 static void HandleContentAvailable(
U32BIT requestId)
2585 StreamerRequest *request;
2587 request = FindRequestById(requestId);
2588 if (request != NULL)
2590 GenerateContentAvailable(request);
2599 static void GenerateStreamRefError(StreamerRequest *request)
2603 if (request->root->runningStatus)
2608 PDBG((
"%d ~ Generating StreamRefError EngineEvent",
2609 request->requestId));
2615 #ifdef INCLUDE_FREESAT 2621 static void GenerateIPStreamAccessError(StreamerRequest *request)
2625 if (request->root->runningStatus)
2630 PDBG((
"%d ~ Generating IPStreamAccessError EngineEvent",
2631 request->requestId));
2644 static void GenerateStreamUnderflow(
void)
2651 PDBG((
"Generating StreamUnderflow EngineEvent"));
2660 static void GenerateStreamUnderflowResume(
void)
2667 PDBG((
"Generating StreamUnderflowResume EngineEvent"));
2676 static void GenerateContentAvailable(StreamerRequest *request)
2678 if (!request->contentAvailableGenerated)
2681 PDBG((
"%d ~ Generating ContentAvailable for (%.*s %ld) [%d]",
2683 (
int)request->root->grp->groupName.len,
2684 request->root->grp->groupName.data, request->root->id,
2685 request->requestId));
2686 request->contentAvailableGenerated =
TRUE;
2695 static void GenerateStreamPlaying(StreamerRequest *request)
2697 if (!request->streamPlayingGenerated)
2700 PDBG((
"%d ~ Generating StreamPlaying for (%.*s %ld)",
2702 (
int)request->root->grp->groupName.len,
2703 request->root->grp->groupName.data, request->root->id));
2704 request->streamPlayingGenerated =
TRUE;
2714 static void GenerateStreamStopped(StreamerRequest *request)
2716 if (request->streamPlayingGenerated)
2719 PDBG((
"%d ~ Generating StreamStopped for (%.*s %ld)",
2720 request->requestId, (
int)request->root->grp->groupName.len,
2721 request->root->grp->groupName.data, request->root->id));
2722 if (request->terminateStreamSetup && isIcsSetup)
2727 request->streamPlayingGenerated =
FALSE;
2738 static void GenerateCounterTrigger(StreamerRequest *request,
S32BIT triggerId)
2741 PDBG((
"%d ~ Generating CounterTrigger for (%.*s %ld), triggerId = %d",
2742 request->requestId, (
int)request->root->grp->groupName.len,
2743 request->root->grp->groupName.data, request->root->id, triggerId));
2751 static void GenerateKeyFileError(
void)
2758 PDBG((
"Generating KeyFileError EngineEvent"));
2771 static void NotifyContentAvailable(
U32BIT requestId)
2778 event.data.streamer.requestId = requestId;
2781 PDBG((
"%d ~ Sending MHEG5_STREAMER_EVENT_CONTENT_AVAILABLE", requestId));
2785 TRACE(TERROR, (
"Cannot generate event %d", cqu_err));
2795 static void NotifyStreamPlaying(
U32BIT requestId)
2802 event.data.streamer.requestId = requestId;
2805 PDBG((
"%d ~ Sending MHEG5_STREAMER_EVENT_TASK_STREAM_PLAYING", requestId));
2809 TRACE(TERROR, (
"Cannot generate event %d", cqu_err));
2819 static void NotifyStreamStopped(
U32BIT requestId)
2826 event.data.streamer.requestId = requestId;
2829 PDBG((
"%d ~ Sending MHEG5_STREAMER_EVENT_TASK_STREAM_STOPPED", requestId));
2833 TRACE(TERROR, (
"Cannot generate event %d", cqu_err));
2846 static void ItemInsertCallback(
U32BIT downloadId,
U64BIT base,
2849 StreamerRequest *request;
2853 request = FindRequestByDownloadId(downloadId);
2854 if (request != NULL)
2858 request->downloadedBytes = position;
2859 ULL_Add32(request->downloadedBytes, len);
2861 if (!request->contentAvailableNotified)
2864 request->contentAvailableNotified =
TRUE;
2865 NotifyContentAvailable(request->requestId);
2869 if (!request->pmtRetrieved)
2878 request->expectedBytes) >= 0))
2886 CheckRunCondition(request);
2901 static void ItemReleaseCallback(
U32BIT requestId,
U64BIT base,
2904 StreamerRequest *request;
2908 request = FindRequestById(requestId);
2909 if (request != NULL)
2911 DBG((
"%d ~ request->outputState = %s", request->requestId,
2912 REQUEST_OUTPUT_STATE_STR(request)));
2913 if (request->outputState == STATE_OUTPUT_READY)
2916 request->outputState = STATE_OUTPUT_RUNNING;
2917 NotifyStreamPlaying(request->requestId);
2919 else if (request->outputState == STATE_OUTPUT_STARVED)
2922 request->outputState = STATE_OUTPUT_RUNNING;
2923 NotifyStreamPlaying(request->requestId);
2925 if (request->outputState == STATE_OUTPUT_RUNNING)
2927 request->currentBytePosition = base;
2928 ULL_Add(request->currentBytePosition, position);
2929 ULL_Add32(request->currentBytePosition, len);
2931 request->presentedBytes = position;
2932 ULL_Add32(request->presentedBytes, len);
2935 CheckCounterTriggers(request, base, position, len);
2949 static void CheckCounterTriggers(StreamerRequest *request,
U64BIT base,
2952 CounterTrigger *trigger;
2959 itemPosition = base;
2960 ULL_Add(itemPosition, position);
2962 itemLimit = itemPosition;
2965 trigger = request->triggers;
2966 while (trigger != NULL)
2968 triggerPosition = ConvertToBytes(request, trigger->position);
2969 if ((
ULL_Compare(triggerPosition, itemPosition) >= 0) &&
2976 event.data.streamer.requestId = request->requestId;
2978 event.data.streamer.triggerId = trigger->id;
2980 PDBG((
"%d ~ Sending MHEG5_STREAMER_EVENT_COUNTER_TRIGGER",
2981 request->requestId));
2985 TRACE(TERROR, (
"Cannot generate event %d", cqu_err));
2988 trigger = trigger->next;
2998 static void SetupComponents(StreamerRequest *request,S_ICSComponents *components)
3006 components->audio_active =
FALSE;
3007 components->audio_component_tag = -1;
3008 components->video_active =
FALSE;
3009 components->video_component_tag = -1;
3013 for (index = 0; index !=
MAX_MLTPLX; index++)
3028 components->audio_active =
TRUE;
3030 DBGTRACE(TSTRM|TICS,
"Found active audio component: tag = %d",
3031 components->audio_component_tag);
3037 components->video_active =
TRUE;
3043 DBGTRACE(TSTRM|TICS,
"Found active video component: tag = %d, freeze = %s",
3044 components->video_component_tag,
3056 while ( dptr < dend )
3060 DBGTRACE(TSTRM,
"dtag=%d dlen=%d",dtag,dlen)
3066 DBGTRACE(TSTRM,
"lang=%c%c%c atyp=%x",dptr[0],dptr[1],dptr[2],dptr[3])
3067 info_ptr->lang_code = dptr[0] << 16 | dptr[1] << 8 | dptr[2] | 0x202020;
3068 info_ptr->a_type = dptr[3];
3075 DBGTRACE(TERROR,"lang=%c%c%c styp=%x",dptr[0],dptr[1],dptr[2],dptr[3])
3087 while ( dptr < dend )
3091 DBGTRACE(TSTRM,
"dtag=%d dlen=%d",dtag,dlen)
3097 DBGTRACE(TERROR,
"lang=%c%c%c atyp=%x",dptr[0],dptr[1],dptr[2],dptr[3])
3103 DBGTRACE(TSTRM,"lang=%c%c%c styp=%x",dptr[0],dptr[1],dptr[2],dptr[3])
3104 info_ptr->lang_code = dptr[0] << 16 | dptr[1] << 8 | dptr[2] | 0x202020;
3105 info_ptr->s_type = dptr[3];
3106 info_ptr->u.page.composition = (dptr[4] << 8) | dptr[5];
3107 info_ptr->u.page.ancillary = (dptr[6] << 8) | dptr[7];
3125 while ( dptr < dend )
3129 if (dtag == STREAMID_DTAG && *dptr ==
id)
3143 for (i = 0; i != num_pids; i++)
3146 if (pid_info[i].PID == pid)
3150 memcpy(pkeys->
even + 16, pid_info[i].
iv, 16);
3151 memcpy(pkeys->
odd + 16, pid_info[i].
iv, 16);
3155 return (i != num_pids)? pkeys : NULL;
3163 static void StartStreaming(StreamerRequest *request)
3174 S_ICSComponents components;
3180 SetupComponents(request,&components);
3183 DBGTRACE((TICS|TSTRM),
"PREF lang=%x",pref_lang)
3189 dlen = (data[1] << 8 | data[2]) & 0xfff;
3190 eptr = data + dlen - 4;
3191 pids.
pcr_pid = (data[8] << 8 | data[9]) & 0x1fff;
3192 dlen = (data[10] << 8 | data[11]) & 0xfff;
3198 dlen = ((sptr[3] & 0x0f) << 8) | sptr[4];
3204 if (components.video_active)
3213 if (components.audio_active)
3237 pid = ((data[1] & 0x1f) << 8) | data[2];
3238 dlen = ((data[3] & 0x0f) << 8) | data[4];
3243 DBGTRACE(TERROR,
"Unsupported stream type=0x%x",type)
3246 DBGTRACE(TSTRM,"PES type pid=%d len=%d",pid,dlen)
3247 if (components.video_active && info_ptr)
3249 if (ParseSubts(data,data+dlen,info_ptr))
3251 info_ptr->pid = pid;
3252 if (pids.
subtitle_pid == 0 || info_ptr->lang_code == subt_lang)
3265 DBGTRACE(TERROR,
"cactive=%u iptr=%p",components.video_active,info_ptr)
3269 DBGTRACE(TSTRM,
"H264 type pid=%d len=%d",pid,dlen)
3270 if (components.video_active)
3272 if (components.video_component_tag == -1)
3277 else if (HasStreamId(data,data+dlen,(
U8BIT)components.video_component_tag))
3285 DBGTRACE(TERROR,
"cactive=%u iptr=%p",components.video_active,info_ptr)
3292 DBGTRACE(TSTRM,
"type=%d pid=%d len=%d",type,pid,dlen)
3293 if (components.audio_active && info_ptr)
3295 info_ptr->pid = pid;
3309 if (components.audio_component_tag == -1)
3311 if ((ParseAudio(data,data+dlen,info_ptr) && info_ptr->lang_code == pref_lang) || pids.
audio_pid == 0)
3313 DBGTRACE((TICS|TSTRM),
"INFO lang=%x Aud-PID=%x",info_ptr->lang_code,pids.
audio_pid)
3314 audcodec = info_ptr->u.codec;
3315 pids.audio_pid = pid;
3318 else if (HasStreamId(data,data+dlen,(
U8BIT)components.audio_component_tag))
3320 audcodec = info_ptr->u.codec;
3327 DBGTRACE(TERROR,
"cactive=%u iptr=%p",components.audio_active,info_ptr)
3335 SetupKeys(request->keys.pid_info, request->keys.num_pids, pids.
audio_pid, &audio_keys),
3336 SetupKeys(request->keys.pid_info, request->keys.num_pids, pids.
video_pid, &video_keys),
3337 components.video_termination, audcodec, vidcodec );
3346 static void CheckRunCondition(StreamerRequest *request)
3348 DBG((
"%d ~ CheckRunCondition: streamState = %s", request->requestId,
3349 REQUEST_STREAM_STATE_STR(request)));
3350 if (request->streamState == STATE_STREAM_RUNNING)
3352 DBG((
"%d ~ request->outputState = %s", request->requestId,
3353 REQUEST_OUTPUT_STATE_STR(request)));
3354 DBG((
"%d ~ request->downloadState = %s", request->requestId,
3355 REQUEST_DOWNLOAD_STATE_STR(request)));
3356 DBG((
"%d ~ request->keyState = %s", request->requestId,
3357 REQUEST_KEY_STATE_STR(request)));
3358 DBG((
"%d ~ request->pmtRetrieved = %s", request->requestId,
3359 request->pmtRetrieved ?
"TRUE" :
"FALSE"));
3362 if ((request->outputState == STATE_OUTPUT_STOPPED) &&
3363 (request->downloadState != STATE_DOWNLOAD_STARTED) &&
3364 (request->keyState == STATE_KEY_VALID) &&
3365 (request->pmtRetrieved))
3367 PDBG((
"%d ~ Output stopped, ICS ready", request->requestId));
3373 StartStreaming(request);
3374 request->outputState = STATE_OUTPUT_SETUP;
3377 if (request->outputState == STATE_OUTPUT_SETUP)
3380 PDBG((
"%d ~ Output is setup, check buffer / download",
3381 request->requestId));
3382 if ((IsEnoughDataBuffered(request)) ||
3383 (request->downloadState == STATE_DOWNLOAD_DONE))
3385 PDBG((
"%d ~ Start streaming", request->requestId));
3386 request->outputState = STATE_OUTPUT_READY;
3387 request->flowState = STATE_FLOW_STARTED;
3389 if (!request->paused)
3393 if (request->isPartial)
3395 request->downloadState = STATE_DOWNLOAD_QUEUED;
3396 ProgressDownloadRequest(request);
3401 else if (request->outputState == STATE_OUTPUT_STARVED)
3404 PDBG((
"%d ~ Output is starved, check buffer / download",
3405 request->requestId));
3406 if ((IsEnoughDataBuffered(request)) ||
3407 (request->downloadState == STATE_DOWNLOAD_DONE))
3410 PDBG((
"%d ~ Starved output resumed", request->requestId));
3411 ResumePlayback(request);
3423 static BOOLEAN IsEnoughDataBuffered(StreamerRequest *request)
3436 ULL_Itoa(request->expectedBytes, buffer);
3437 PDBG((
"%d ~ request->expectedBytes = %s", request->requestId, buffer));
3438 expectedBytes = request->expectedBytes;
3439 ULL_Sub(expectedBytes, request->downloadedBytes);
3441 PDBG((
"%d ~ expectedBytes = %s", request->requestId, buffer));
3446 PDBG((
"%d ~ Unknown expected: allow"));
3450 PDBG((
"%d ~ bufferedBytes = %d, expectedBytes %s bufferedBytes",
3451 request->requestId, bufferedBytes,
3452 bufferedBytes >= MIN_BUFFERED_BYTES ?
"?" :
3453 ULL_Compare32(expectedBytes, bufferedBytes) <= 0 ?
"<=" :
">"));
3454 if ((bufferedBytes >= MIN_BUFFERED_BYTES) ||
3460 if (bufferedBytes >= MIN_BUFFERED_BYTES)
3476 static U32BIT ConvertToUnits(StreamerRequest *request,
U64BIT bytes)
3481 if (request->bitrate > 0)
3509 static U64BIT ConvertToBytes(StreamerRequest *request,
U32BIT units)
3514 if (request->bitrate > 0)
3545 static BOOLEAN IsStreamRunning(
void)
3547 StreamerRequest *request;
3551 request = requestList;
3552 while (request != NULL)
3554 if (request->streamState == STATE_STREAM_RUNNING)
3560 request = request->next;
3571 static void CheckDownloadCondition(
void)
3573 StreamerRequest *request;
3574 StreamerRequest *primaryRequest = NULL;
3576 U32BIT minPrepareNumber = 0;
3577 StreamerRequest *nextPrepare = NULL;
3580 request = requestList;
3581 while (request != NULL)
3583 if (request->streamState == STATE_STREAM_RUNNING)
3586 primaryRequest = request;
3590 if ((request->downloadState != STATE_DOWNLOAD_STOPPED) &&
3591 (request->downloadState != STATE_DOWNLOAD_DONE))
3596 secondaryDownloading =
TRUE;
3599 if ((minPrepareNumber == 0) ||
3600 (request->prepareNumber < minPrepareNumber))
3602 if ((request->streamState == STATE_STREAM_PREPARED) &&
3603 (request->downloadState == STATE_DOWNLOAD_STOPPED))
3605 minPrepareNumber = request->prepareNumber;
3606 nextPrepare = request;
3610 request = request->next;
3613 PDBG((
"primaryRequest = %p, nextPrepare = %p", primaryRequest,
3616 if ((primaryRequest != NULL) &&
3617 (primaryRequest->downloadState == STATE_DOWNLOAD_STOPPED))
3622 PDBG((
"Downloading primary, stopping any secondary"));
3623 request = requestList;
3624 while (request != NULL)
3626 if (request != primaryRequest)
3628 PDBG((
"Destroying download request for %d (secondary)",
3629 request->requestId));
3630 DestroyDownloadRequest(request);
3633 request = request->next;
3636 PDBG((
"Creating download request for %d (primary)",
3637 primaryRequest->requestId));
3639 primaryRequest->currentLoop = 0;
3640 CreateDownloadRequest(primaryRequest);
3642 else if ((primaryRequest == NULL) ||
3643 (primaryRequest->downloadState == STATE_DOWNLOAD_DONE) ||
3644 (primaryRequest->downloadState == STATE_DOWNLOAD_FAILED))
3650 if (nextPrepare != NULL && !secondaryDownloading)
3652 PDBG((
"Creating download request for %d (secondary)",
3653 nextPrepare->requestId));
3654 nextPrepare->currentLoop = 0;
3655 CreateDownloadRequest(nextPrepare);
3667 static void StopContentOutput(StreamerRequest *request,
BOOLEAN flush)
3675 if (request->streamState == STATE_STREAM_RUNNING)
3677 request->flowState = STATE_FLOW_STOPPED;
3678 request->outputState = STATE_OUTPUT_STOPPED;
3689 static void ResumePlayback(StreamerRequest *request)
3694 if (request->pauseRequestCount > 0)
3696 --request->pauseRequestCount;
3697 if (request->pauseRequestCount == 0)
3706 if (request->isPartial)
3708 request->downloadState = STATE_DOWNLOAD_QUEUED;
3709 ProgressDownloadRequest(request);
3729 static void TimerCallback(
BOOLEAN triggered,
void *callerRef,
H_Timer timerHandle)
3732 request.
ptr = callerRef;
3734 NotifyStreamStopped(request.
u32);
3744 static void UnderflowCallback(
U32BIT requestId,
U32BIT playoutTime)
3746 StreamerRequest *request;
3750 request = FindRequestById(requestId);
3751 if (request != NULL)
3753 PDBG((
"UnderflowCallback: request->outputState = %s",
3754 REQUEST_OUTPUT_STATE_STR(request)));
3755 if (request->outputState == STATE_OUTPUT_RUNNING)
3757 if ((request->downloadState == STATE_DOWNLOAD_DONE) &&
3759 (
ULL_Compare(request->presentedBytes,request->expectedBytes) >= 0) &&
3760 (request->currentLoop == request->looping - 1))
3763 rqstId.
u32 = requestId;
3764 PDBG((
"%d ~ STATE_OUTPUT_DONE", request->requestId));
3765 request->outputState = STATE_OUTPUT_DONE;
3766 request->restart =
TRUE;
3768 if (playoutTime == 0 ||
3771 NotifyStreamStopped(requestId);
3776 request->outputState = STATE_OUTPUT_STARVED;
3777 if (request->flowState != STATE_FLOW_UNDERFLOW)
3779 request->pauseRequestCount++;
3780 if (request->pauseRequestCount == 1)
3787 NotifyStreamStopped(request->requestId);
3794 PDBG((
"%d ~ UnderflowCallback: output state = %s",
3795 request->requestId, REQUEST_OUTPUT_STATE_STR(request)));
3807 static void StreamKeyLoadedCallback(
void *userData,
S_CONTENT *content)
3809 StreamerRequest *request;
3816 request = FindRequestByObj(userData);
3817 if ((request != NULL) &&
3818 ((request->downloadId == request->keyDownloadId) ||
3819 (request->downloadState == STATE_DOWNLOAD_DONE)))
3821 assert(request->keys.pid_info == NULL);
3826 data = content->
data;
3827 size = content->
size;
3828 if (content->
size > 8 && memcmp(content->
data,
"X-Keys: ", 8) == 0)
3830 data = content->
data + 8;
3835 if (request->keys.num_pids == 0)
3837 GenerateKeyFileError();
3838 request->keyState = STATE_KEY_ERROR;
3842 request->keyState = STATE_KEY_VALID;
3843 CheckRunCondition(request);
3854 static void StreamKeyLoadFailCallback(
void *userData)
3856 StreamerRequest *request;
3860 request = FindRequestByObj(userData);
3861 if ((request != NULL) &&
3862 ((request->downloadId == request->keyDownloadId) ||
3863 (request->downloadState == STATE_DOWNLOAD_DONE)))
3865 GenerateKeyFileError();
3866 request->keyState = STATE_KEY_ERROR;
3874 static void ServerAccessCallback(
void)
3876 StreamerRequest *request;
3880 request = requestList;
3881 while (request != NULL)
3883 if (request->downloadState == STATE_DOWNLOAD_WAIT_ACCESS)
3885 request->downloadState = STATE_DOWNLOAD_CHECK_ACCESS;
3886 processRequests =
TRUE;
3889 request = request->next;
3898 static void TlsCertCallback(
void)
3900 StreamerRequest *request;
3904 request = requestList;
3905 while (request != NULL)
3907 if (request->downloadState == STATE_DOWNLOAD_WAIT_CERT)
3909 request->downloadState = STATE_DOWNLOAD_QUEUED;
3910 processRequests =
TRUE;
3913 request = request->next;
U8BIT DVB_MhegPrefSubtitleLangs(U32BIT *langs, U8BIT max)
Get list of preferred subtitle languages. If there is no preference then zero is returned. This only writes into array up to 'max' items This MUST be a non-blocking function, returning results immediately.
U32BIT STB_OSGetClockMilliseconds(void)
Get Current Computer Clock Time.
Task functions for IC Streamer.
U64BIT MHEG5GetDownloadContentLength(U32BIT downloadId, U64BIT contentLength)
Return content length (in bytes) for download request. The content length may be: ...
Implement MHEG5 engine control functions (i.e. start/stop etc)
void MHEG5StreamerResume(MHEG5Stream *stream)
Resume IP content streaming after it was paused by MHEG5StreamerPause.
E_MhegErr VQ_PutMsg(S_MhegMessage *pMsg, E_PRIORITY priority)
Post event or section message on queue. Copies data into queue.
void MHEG5AddTlsCertificateCallback(void(*loadCallback)(void))
Add a callback function to be called when pending requests are resolved.
void MHEG5StopMeasureRequest(U32BIT downloadId)
Stop HTTP streaming performance measurement request.
#define ULL_IsValid(variable)
#define ULL_Mod32(variable, value)
MHEG5Int counterMaxPosition
F_MSG_PROCESS proc_msg_func
void MHEG5StreamerSetCounterPosition(MHEG5Stream *stream)
Set the counter position of a stream in the streamer. This function uses the counter position as set ...
E_MhegErr DVB_MhegICStreamSetup(S_StreamPids pids, S_ICSPidKeys *audio_keys, S_ICSPidKeys *video_keys, E_VideoTermination video_termination, E_ICSAudioCodec audio_codec, E_ICSVideoCodec video_codec)
This function tells the external application that an IC delivered stream is to be played using DVB_Mh...
E_MhegErr DVB_MhegICStreamRelease(void)
This function tells the external application that the IC delivered stream is stopped. Presentation of all stream components (audio, video and/or subtitles) should cease. This function may be called while DVB_MhegHandleStreamData is in progress. In this case DVB_MhegHandleStreamData should return indicating that the entire block has been processed.
void MHEG5StreamerNotifyStreamStopped(MHEG5Stream *stream)
Notify that a stream has stopped. This notification comes from the audio/video deocder.
MHEG5TlsCertRequestStatus
MHEG5Ingredient ingredient
E_MhegErr VT_TimerCreate(U32BIT millisecs, F_TimerCallback callback, void *callerRef, H_Timer *pTimerHandle)
Set a timer for a certain number of millseconds. When the timer expires a specified callback will be ...
void MHEG5StreamerPrepare(MHEG5Stream *stream)
Prepare for retrieval of a stream from the IP connection.
MHEG5Bool MHEG5stringEqual(MHEG5String *s1, MHEG5String *s2)
Compare two Strings (case sensitive!)
#define ULL_Sub(variable, value)
void MHEG5ClearDownloadRequest(U32BIT downloadId)
Clear HTTP download request.
Common header internal to IC streamer.
void MHEG5CopyDownloadStreamKeyInfo(U32BIT downloadId, S_ICSKeys *keys, MHEG5String *keyLocation)
Copy any keys or key location that were obtained from the headers. If such keys or location exist...
void MHEG5StreamerSetCounterEndPosition(MHEG5Stream *stream)
Set the counter end position of a stream in the streamer. This function uses the counter end position...
void ULL_Print(U64BIT size)
Print a stream size value (for debug purposes).
E_MhegErr MHEG5StreamerStartTask(U32BIT stack, U8BIT priority)
Start streamer task. The task passes stream data to the external application and generates stream and...
BOOLEAN MHEG5GetDownloadPmt(U32BIT downloadId, U8BIT *pmt)
Return program map table (PMT) for download (if available). The table is provided as a complete secti...
Implementation of the Video class Description Defines the attributes and behaviour of an elementary v...
#define ULL_IsEqual(variable, value)
void STB_OSDeleteMutex(void *mutex)
Delete a mutex.
#define ULL_Sub32(variable, value)
void MHEG5StreamerAbortMeasurement(MHEG5Program *program)
Abort streaming performance measurement.
void MHEG5ClearDownloadThrottling(void)
Clear information about throttling, causing the download to proceed at full speed (until throttling k...
S32BIT MHEG5GetMeasureStatus(U32BIT downloadId)
Return HTTP status of performance measurement request.
void * MHEG5FileOrmGet(MHEG5String name, U16BIT priority, void *userData, F_CB_Good cbGood, F_CB_Fail cbFail)
Get a file. The file will be loaded and one of the callback functions called when request is resolved...
MHEG5Int counterEndPosition
E_MhegErr DVB_MhegICStreamResume(void)
Resume presentation of audio and/or video components of the currently playing IC delivered stream...
MHEG5Ingredient ingredient
void MHEG5QueueRegisterReleaseCallback(void(*callback)(U32BIT requestId, U64BIT base, U64BIT position, U32BIT len, BOOLEAN last))
Register notification callback for item release events. If a callback is already registered for the e...
#define FRP_CACHE_DEFAULT
MHEG5TlsCertRequestStatus MHEG5GetNextTlsCertificate(void)
Issues a request to load the next TLS certificate from the DSM-CC object carousel.
void MHEG5StartMeasureRequest(U32BIT downloadId)
Start HTTP streaming performance measurement request.
void MHEG5StreamerSetActiveState(BOOLEAN activeState)
Set the active state of the streamer. When it is not active, it is allowed to buffer data but not to ...
void MHEG5stringDestruct(MHEG5String *item)
Destruct a MHEG5String.
MHEG5 engine interface error codes.
U32BIT MHEG5QueueGetBufferedBytes(void)
Return number of buffered bytes in the queue (regardless of request)
void(* F_MSG_PROCESS)(void *data)
Function to Process voyager message.
S32BIT MHEG5StreamerGetCounterPosition(MHEG5Stream *stream)
Return the current counter position (in units of 188 bytes).
U8BIT * MHEG5GetMeasureRedirect(U32BIT downloadId)
Return the redirection URL for a request that was redirected (HTTP status 3xx).
void MHEG5StreamerRegisterUnderflowCallback(void(*callback)(U32BIT requestId, U32BIT playoutTime))
Register notification callback for underflow events. If a callback is already registered for the even...
BOOLEAN MHEG5DownloadPositionPartial(U32BIT downloadId, U64BIT *position)
Return what is current position of download request.
void MHEG5StreamerMeasurePerformance(MHEG5String *url, MHEG5Int maxBytes, MHEG5Program *program)
Measure streaming performance (bytes per second). The result is returned to the resident program...
void(* F_TimerCallback)(BOOLEAN triggered, void *callerRef, H_Timer timerHandle)
DVB Video functions are required by MHEG5 engine. All required functions should be non-blocking...
string parsing utility functions for MHEG5
#define ICS_MINIMUM_BUFFER_SIZE
void MHEG5QueueTerm(void)
Terminate queue manager.
#define ULL_Itoa(variable, str)
void MHEG5RenewDownloadRequest(U32BIT downloadId, char *url)
Renew HTTP download request.
void MHEG5StopDownloadRequestAsync(U32BIT downloadId)
Stop HTTP download request asynchronously. This function should be used when the caller wants to stop...
void STB_OSMutexUnlock(void *mutex)
Unlock a mutex (a.k.a. 'leave', 'signal' or 'release')
void * STB_MemAlloc(U32BIT memSize)
Allocates the specified number of bytes.
IC Streamer queue manager.
This file defines the profile for the MHEG engine.
void MHEG5StopDownloadRequest(U32BIT downloadId)
Stop HTTP download request.
void MHEG5AddServerAccessCallback(void(*LoadNotifyCallback)(void))
Add callback function to be called when the server access permission file is loaded.
Implementation of the resident programs which are defined by the current profile. ...
Implement Functions to support Service Gateways. Functions for standarizing several GroupIDs like +DS...
void MHEG5StreamerStop(MHEG5Stream *stream)
Stop streaming IP content.
#define ULL_Mul32(variable, value)
void MHEG5streamerNotifyStreamingReady(void)
Handle notification that the external application is ready to handle IP stream data.
S32BIT MHEG5GetMeasureResponseCode(U32BIT downloadId)
Return response code for performance measurement request.
void * STB_OSCreateMutex(void)
Create a mutex.
#define ULL_SetInvalid(variable)
void MHEG5DestroyMeasureRequest(U32BIT downloadId)
Destroy HTTP streaming performance measurement request.
void MHEG5QueueReleaseItems(U32BIT requestId, U64BIT marker)
Release queue items that are related to a given request up to a marker.
U32BIT MHEG5CreateDownloadRequest(U32BIT requestId, char *url, U64BIT rangeFrom, U64BIT rangeTo, BOOLEAN lastRequest)
Create HTTP download request.
MHEG5ServerAccess_t MHEG5CheckServerPermitted(U8BIT *url)
void MHEG5StreamerSendSignalToTask(void)
Send signal to streamer task to wake it up (if it's asleep)
Event handling. Implementation of a combined queue for events and actions. This is the eventsystem wh...
S32BIT MHEG5StreamerGetCounterMaxPosition(MHEG5Stream *stream)
Return the counter maximum position (content length in units of 188 bytes).
Functions relating to HTTPS Server Access.
void MHEG5StartDownloadRequest(U32BIT downloadId)
Start HTTP download request.
BOOLEAN MHEG5StreamerIsRunable(MHEG5Stream *stream)
Check that stream is runable (i.e. MHEG5StreamerPrepare has been called for it)
#define UND_LANGUAGE_CODE
void MHEG5StreamerNotifyStreamStarted(MHEG5Stream *stream)
Notify that a stream has started. This notification comes from the audio/video deocder.
#define MHEG5strncmp(a, b, n)
Implement functions to retrieve MHEG5objects by GroupID and ID.
MHEG5Ingredient * multiplex[MAX_MLTPLX]
Implementation of the MHEG5 Application Class Defines a set of Ingredient objects, which are shared within an application scope. Base class: Group Subclasses: None Status: Concrete class.
#define ULL_Add(variable, value)
U32BIT MHEG5CreateMeasureRequest(U32BIT requestId, char *url, S32BIT maxBytes)
Create HTTP streaming performance measurement request.
void MHEG5QueueEnableStreaming(U32BIT requestId)
Allow streaming data from the queue.
E_MhegErr DVB_MhegICStreamPause(void)
Pause presentation of audio and/or video components of the currently playing IC delivered stream...
File interface functions to DSMCC component.
void MHEG5StreamerRefresh(void)
Refresh any running IC streams - called when user preferences have changed.
U8BIT DVB_MhegPrefAudioLangs(U32BIT *langs, U8BIT max)
Get list of preferred audio languages. If there is no preference then zero is returned. This only writes into array up to 'max' items This MUST be a non-blocking function, returning results immediately.
DVB Audio functions are required by MHEG5 engine. All required functions should be non-blocking...
void MHEG5StreamerClose(void)
Close the IC streaming module.
U32BIT MHEG5GetTlsCertStoreCount(void)
Return number of TLS certificates in the TLS certificate store.
void MHEG5QueueRegisterInsertCallback(void(*callback)(U32BIT downloadId, U64BIT base, U64BIT position, U32BIT len, BOOLEAN last))
Register notification callback for item insertion event. If a callback is already registered for the ...
BOOLEAN MHEG5QueueIsStreamingEnabled(void)
Tell whether streaming is enabled.
void MHEG5sendEvent(MHEG5Root *source, MHEG5EventType event, MHEG5Int data)
Store an event in the asynchronous event queue.
#define ULL_Compare(first, second)
void STB_OSMutexLock(void *mutex)
Lock a mutex (a.k.a. 'enter', 'wait' or 'get').
Functions relating to TLS certificate store.
The timer module allows the use of timers within the MHEG5 component. These timers can be set by othe...
void MHEG5CopyDownloadBitrate(U32BIT downloadId, U32BIT *bytesPerSecond)
Copy download bitrate that was obtained from the headers. If the X-BytesPerSecond header were not rec...
#define ULL_Compare32(first, second)
E_MhegErr MHEG5QueueInit(U8BIT *buffer, U32BIT bufferSize)
Initialise queue manager.
IC Streamer performance measurement.
void MHEG5QueueReleaseRequestItems(U32BIT requestId)
Release all queue items that are related to a given request.
union sMHEG5ContentBody::@2 ref
void MHEG5StreamerHandle(MHEG5StreamerEventParams_t *params)
Process an MHEG5StreamerEvent message The event is passed onto the streamer module for processing...
void MHEG5StreamerNotifyStreamingPerformance(U32BIT requestId, U32BIT speed)
Notify measured streaming performance (speed).
#define ULL_Set32(variable, value)
void MHEG5StreamerRemove(MHEG5Stream *stream)
Remove streaming IP request.
#define STMR_TS_PACKET_SIZE
Interaction Channel Streaming functions required by MHEG5 engine References: [1] UK1 Profile - Digita...
void MHEG5StreamerRun(MHEG5Stream *stream)
Start streaming IP content for a prepared request.
#define ULL_Div32(variable, value)
#define STMR_MAX_PSI_SECTION
MHEG5String MHEG5convertGID(MHEG5String *inRef)
Convert a group ID from a relative reference to an absolute reference. See UK1.05 section 8...
void MHEG5QueueReleaseAllItems(void)
Release all queue items - clear the queue completely.
void MHEG5DestroyDownloadRequest(U32BIT downloadId)
Destroy HTTP download request.
void MHEG5StreamerSetCounterTrigger(MHEG5Stream *stream, S32BIT triggerId, S32BIT newValue)
Add, remove or update a counter trigger for the stream. If the trigger does not exist, it will be added. If it already exists it will be updated if the new value is non-negative, otherwise it will be removed.
Implement the MHEG5 Audio Class Audio Class Defines the attributes and behaviour of an elementary aud...
void MHEG5StreamerPause(MHEG5Stream *stream)
Pause IP content streaming.
MHEG5Bool terminationFreeze
void MHEG5StreamerStopTask(void)
Stop streamer task. This function blocks until the task is stopped.
void MHEG5QueueDisableStreaming(void)
Do not allow streaming data from the queue.
void MHEG5StreamerReset(void)
Reset the IC streaming module.
#define ULL_Get32(variable)
void MHEG5ProcessMeasureRequest(U32BIT downloadId)
Process HTTP streaming performance measurement request.
void MH5GlueAddPostProcessFunc(F_PostProcess func)
IC Streamer download manager.
MHEG5Application * MHEG5getCurrentApplication(void)
<Function description>="">
E_MhegErr MHEG5StreamerOpen(void *buffer, U32BIT size, U32BIT taskPriority)
Open the IC streaming module.
#define ULL_Add32(variable, value)
U8BIT * MHEG5GetDownloadRedirect(U32BIT downloadId)
Return the redirection URL for a request that was redirected (HTTP status 3xx).
Header file - Function prototypes for operating system.