46 #define THROTTLE_BYTES (3 * 1024 * 1024 - 262144) 49 #define INVALID_TIMESTAMP 0xffffffff 50 #define SYNC_BYTE 0x47 51 #define SYNC_COUNT_ACCEPT 20 52 #define SYNC_BUFFER_SIZE (STMR_TS_PACKET_SIZE * SYNC_COUNT_ACCEPT) 53 #define SYNC_COUNT_MIN_ACCEPT (SYNC_COUNT_ACCEPT / 2) 58 #define GOOD_MAGIC 0xdeadbeef 59 #define BAD_MAGIC 0xfefefefe 60 #define SET_MAGIC(r) do { r->magic = GOOD_MAGIC; } while (0) 61 #define VERIFY_MAGIC(r) assert(r->magic == GOOD_MAGIC) 62 #define CLEAR_MAGIC(r) do { r->magic = BAD_MAGIC; } while (0) 65 #define VERIFY_MAGIC(r) 66 #define CLEAR_MAGIC(r) 70 #define PDBG(x) TRACE(TICS, x) 232 if (memcmp(url,
"https://", 8) == 0)
264 request->throttled =
FALSE;
265 request->targetBitrate = 0;
281 request->
next = downloadRequestList;
282 downloadRequestList = request;
285 strcat(rangeBuffer,
"-");
288 ULL_Itoa(rangeTo, &rangeBuffer[strlen(rangeBuffer)]);
292 (
U8BIT *)rangeBuffer,
297 if (request->
handle != NULL)
321 request = FindRequestById(downloadId);
326 assert(request->
handle != NULL);
340 U8BIT *redirectUrl = NULL;
342 request = FindRequestById(downloadId);
347 PDBG((
"id=%d",downloadId));
363 request = FindRequestById(downloadId);
370 result = IsPositionPartial(request);
398 request = FindRequestById(downloadId);
420 request = FindRequestById(downloadId);
450 request = FindRequestById(downloadId);
465 if (keyLocation->
len > 0)
474 *keys = request->
keys;
506 request = FindRequestById(downloadId);
531 request = downloadRequestList;
538 DBG((
"Download: Resuming connection"));
553 request = downloadRequestList;
558 DBG((
"Download: Clearing throttling"));
562 request->throttled =
FALSE;
563 request->targetBitrate = 0;
588 request = FindRequestById(downloadId);
593 if (request->
handle != NULL)
613 request = FindRequestById(downloadId);
631 pRequest = &downloadRequestList;
632 while (*pRequest != NULL)
639 *pRequest = request->
next;
641 if (request->
handle != NULL)
657 pRequest = &request->
next;
671 request = FindRequestById(downloadId);
676 if (request->
handle != NULL)
702 request = FindRequestById(downloadId);
706 assert(request->
handle == NULL);
719 strcat(rangeBuffer,
"-");
725 HeaderCallback, ContentCallback, downloadId, request);
743 request = downloadRequestList;
744 while (request != NULL && request->
downloadId != downloadId)
746 request = request->
next;
772 DBG((
"Calling NotifyHeadersDone"));
777 HandleHeaderData(request, response->
data, response->
data_len);
869 if (request->
code == 200 || request->
code == 206)
873 handled = HandleStreamData(request, response->
data,
875 if (handled && request->
stopped)
902 PDBG((
"response->status = %s",
911 if (response->
code == 206 &&
913 IsPositionPartial(request) )
941 if (request->throttled)
949 bytes = request->throttledBytes;
963 if (bitrate <= request->targetBitrate)
977 DBG((
"Download: Pausing connection"));
983 handled = HandleData(request,
data, len);
993 DBG((
"Download: Pausing connection"));
1019 if (count > maxCount)
1028 DBG((
"[sync] Found possible offset %d with count %d\n",
1029 bestOffset, maxCount));
1030 offset = bestOffset;
1037 DBG((
"[sync] Could not find sync offset"));
1053 DBG((
"[sync] Found offset %d", offset));
1080 DBG((
"[sync] request->syncState == SYNC_ACCUM"));
1089 DBG((
"[sync] Updated request->syncBufferPos from %d to %d",
1100 DBG((
"[sync] request->SyncState == SYNC_ACCUM and enough data"));
1101 if (!FindSyncOffset( request->
syncBuffer, &offset ))
1111 DBG((
"[sync] offset = %d", offset));
1116 if (offset == origOffset)
1120 else if (offset > origOffset)
1123 len -= offset - origOffset;
1124 data += offset - origOffset;
1129 if (!StoreItem(request, request->
syncBuffer + offset, origOffset - offset, &item))
1136 (void)ProcessItem(item, &request->
psiInfo);
1143 if (!StoreItem(request,
data, len, &item))
1150 if (!ProcessItem(item, &request->
psiInfo))
1155 if (origOffset != 0)
1186 U32BIT totalLen, storeLen, partialLen, remainingLen;
1206 DBG((
"FAIL Q alloc for %d",storeLen));
1221 item->
len += partialLen;
1224 remainingLen =
len - partialLen;
1225 if (remainingLen > 0)
1233 PDBG((
"Download: Inserting item(%d, %u + %u + %u)",
1256 if (!request->throttled)
1258 CheckThrottling(request);
1290 if (!request->throttled)
1292 if (
ULL_Get32(request->throttledBytes) >= THROTTLE_BYTES &&
1295 request->throttled =
TRUE;
1301 request->targetBitrate =
ULL_Get32(bitrate);
1327 while (remaining != 0)
1331 PDBG((
"Need to find sync byte again"))
1335 if (ProcessPacket(packet, psiInfo, ×tamp))
1337 DBG((
"item=%p position=%s timestamp=%lu remaining=%d",item,
ULL_ToString(item->
position),timestamp,remaining));
1365 remaining = item->
len;
1367 packet = item->
data + remaining;
1373 while (remaining != 0)
1377 pid = (packet[1] << 8 | packet[2]) & 0x1fff;
1378 if (pid == psiInfo->
pcr_pid &&
1379 HandlePcrPacket(packet,×tamp))
1381 DBG((
"item=%p position=%s timestamp=%lu remaining=%d",item,
ULL_ToString(item->
position),timestamp,remaining));
1407 pid = (packet[1] << 8 | packet[2]) & 0x1fff;
1409 switch (psiInfo->
state)
1414 built = BuildSection(packet, psiInfo->
section, &psiInfo->
offset);
1417 if (psiInfo->
section[0] == 0x00)
1419 HandlePatSection(psiInfo);
1428 built = BuildSection(packet, psiInfo->
section, &psiInfo->
offset);
1431 if (psiInfo->
section[0] == 0x02)
1433 HandlePmtSection(psiInfo);
1442 found = HandlePcrPacket(packet, timestamp);
1459 U32BIT payload_start_indicator;
1460 U32BIT adaptation_field_control;
1468 payload_start_indicator = (packet[1] >> 6) & 0x1;
1469 adaptation_field_control = (packet[3] >> 4) & 0x3;
1470 if (adaptation_field_control >= 2)
1472 payload = packet + 5 + packet[4];
1473 payload_length = 188 - 5 - packet[4];
1477 payload = packet + 4;
1478 payload_length = 188 - 4;
1481 if (payload_start_indicator)
1483 pointer = payload[0];
1484 if (payload_length > 0)
1486 memcpy(
section, payload + 1 + pointer, payload_length - 1);
1487 *offset = payload_length - 1;
1494 else if (*offset > 0)
1496 if (payload_length > 0)
1500 memcpy(
section + *offset, payload, payload_length);
1501 *offset += payload_length;
1516 if (*offset >= section_length + 3)
1518 complete = IsValidSection(
section);
1535 static void HandlePatSection(
PsiInfo *psiInfo)
1543 section_length = (section[1] << 8 | section[2]) & 0xfff;
1545 while (offset + 4 < section_length + 3)
1547 program_number = section[
offset] << 8 | section[offset + 1];
1548 pmt_pid = (section[offset + 2] << 8 | section[offset + 3]) & 0x1fff;
1549 if (program_number != 0x0000)
1551 PDBG((
"program_number = %d, program_map_PID = %d",
1552 program_number, pmt_pid));
1567 static void HandlePmtSection(
PsiInfo *psiInfo)
1572 psiInfo->
pcr_pid = (section[8] << 8 | section[9]) & 0x1fff;
1587 S32BIT adaptation_field_control;
1588 S32BIT adaptation_field_length;
1599 adaptation_field_control = (packet[3] >> 4) & 0x3;
1600 if (adaptation_field_control >= 2)
1602 adaptation_field_length = packet[4];
1603 if (adaptation_field_length > 0)
1605 PCR_flag = (packet[5] >> 4) & 0x1;
1615 pcr_base_x = (packet[6] << 24 |
1619 pcr_base_y = packet[10] >> 7;
1631 *timestamp = (pcr_base_x / 45 +
1632 (2 * (pcr_base_x % 45) + pcr_base_y) / 90);
1655 event.data.streamer.code =
code;
1661 PDBG((
"NotifyHeaders: Cannot generate event %d", cqu_err));
1678 event.data.streamer.status =
status;
1679 event.data.streamer.code =
code;
1685 PDBG((
"Download: Cannot send MHEG5_STREAMER_EVENT_HTTP_DOWNLOAD_DONE %d", cqu_err));
1689 static U32BIT crc_table[] = {
1690 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
1691 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
1692 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
1693 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
1694 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
1695 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1696 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
1697 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
1698 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
1699 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
1700 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
1701 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
1702 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
1703 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
1704 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
1705 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1706 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
1707 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
1708 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
1709 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
1710 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
1711 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
1712 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
1713 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
1714 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
1715 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1716 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
1717 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
1718 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
1719 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
1720 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
1721 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
1722 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
1723 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
1724 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
1725 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1726 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
1727 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
1728 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
1729 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
1730 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
1731 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
1732 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1749 section_length = (section[1] << 8 | section[2]) & 0xfff;
1751 crc_accum = 0xffffffffL;
1752 limit = section + section_length + 3;
1753 while (section < limit)
1755 idx = ((crc_accum >> 24) ^ (*section++)) & 0xff;
1756 crc_accum = ((crc_accum << 8) ^ crc_table[idx]) & 0xffffffffL;
1759 if (crc_accum == 0x00000000)
U32BIT STB_OSGetClockMilliseconds(void)
Get Current Computer Clock Time.
U64BIT MHEG5GetDownloadContentLength(U32BIT downloadId, U64BIT contentLength)
Return content length (in bytes) for download request. The content length may be: ...
E_MhegErr VQ_PutMsg(S_MhegMessage *pMsg, E_PRIORITY priority)
Post event or section message on queue. Copies data into queue.
#define ULL_IsValid(variable)
F_MSG_PROCESS proc_msg_func
#define INVALID_TIMESTAMP
U32BIT MHEG5GetUniqueId(void)
Return a unique ID. The ID is a non-zero 32-bit value. It is guaranteed to be unique for the first 0x...
U8BIT syncBuffer[SYNC_BUFFER_SIZE]
void httpStartRequest(HttpRequest_t request)
Start an HTTP request. Everything related to the request is passed through the callback that was regi...
Manages the interface between MHEG5 Engine and the HTTP component.
#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...
BOOLEAN MHEG5GetDownloadPmt(U32BIT downloadId, U8BIT *pmt)
Return program map table (PMT) for download (if available). The table is provided as a complete secti...
#define ULL_IsEqual(variable, value)
#define ULL_Sub32(variable, value)
void MHEG5ClearDownloadThrottling(void)
Clear information about throttling, causing the download to proceed at full speed (until throttling k...
void MHEG5stringDestruct(MHEG5String *item)
Destruct a MHEG5String.
void(* F_MSG_PROCESS)(void *data)
Function to Process voyager message.
BOOLEAN MHEG5DownloadPositionPartial(U32BIT downloadId, U64BIT *position)
Return what is current position of download request.
U8BIT section[STMR_MAX_PSI_SECTION]
#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...
char * ULL_ToString(U64BIT val)
Convert 64 bit value to string (for debug purposes).
#define SYNC_COUNT_MIN_ACCEPT
struct sDownloadRequest * next
IC Streamer queue manager.
U8BIT * httpGetRequestRedirect(HttpRequest_t request)
Return the URL that the request is redirected to (valid only for response codes of 3xx)...
void MHEG5StopDownloadRequest(U32BIT downloadId)
Stop HTTP download request.
#define ULL_Mul32(variable, value)
#define ULL_SetInvalid(variable)
U32BIT MHEG5CreateDownloadRequest(U32BIT requestId, char *url, U64BIT rangeFrom, U64BIT rangeTo, BOOLEAN lastRequest)
Create HTTP download request.
void MHEG5StartDownloadRequest(U32BIT downloadId)
Start HTTP download request.
void httpStopRequest(HttpRequest_t request)
Stop an HTTP request. This function does not destroy the request; this is done using httpDestroyReque...
void MHEG5QueueInsertItem(MHEG5QueueItem *item)
Insert a queue item into the queue.
#define ULL_Add(variable, value)
void httpResumeRequest(HttpRequest_t request)
Resume an HTTP request. A request can be paused by returning FALSE from the content callback to tell ...
MHEG5QueueItem * MHEG5QueueAllocItem(U32BIT requestId, U32BIT len)
Allocate a new queue item and initialise with request ID and block length.
#define ULL_Compare(first, second)
void MHEG5CopyDownloadBitrate(U32BIT downloadId, U32BIT *bytesPerSecond)
Copy download bitrate that was obtained from the headers. If the X-BytesPerSecond header were not rec...
void httpDestroyRequest(HttpRequest_t request)
Destroy an HTTP request.
void MHEG5StreamerHandle(MHEG5StreamerEventParams_t *params)
Process an MHEG5StreamerEvent message The event is passed onto the streamer module for processing...
#define SYNC_COUNT_ACCEPT
#define ULL_Set32(variable, value)
#define STMR_TS_PACKET_SIZE
#define ULL_Div32(variable, value)
#define STMR_MAX_PSI_SECTION
void MHEG5ResumeDownload(void)
Resume download of the active request. Download may or may not have been paused due to the buffer bei...
void MHEG5DestroyDownloadRequest(U32BIT downloadId)
Destroy HTTP download request.
HttpRequest_t httpCreateStreamRequest(U8BIT *url, U8BIT *range, HttpCallback_t header_callback, HttpCallback_t callback, U32BIT request_id, void *userdata)
Create an HTTP request for stream media.
#define MHEG5_MAX_RANGE_BUFFER
struct HttpRequest_tag * HttpRequest_t
#define ULL_Get32(variable)
struct sDownloadRequest DownloadRequest
U8BIT partialData[STMR_TS_PACKET_SIZE]
IC Streamer download manager.
#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.