| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- /**********************************************************************************************/
- /* The MIT License */
- /* */
- /* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */
- /* */
- /* Permission is hereby granted, free of charge, to any person obtaining a copy */
- /* of this software and associated documentation files (the "Software"), to deal */
- /* in the Software without restriction, including without limitation the rights */
- /* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
- /* copies of the Software, and to permit persons to whom the Software is */
- /* furnished to do so, subject to the following conditions: */
- /* */
- /* The above copyright notice and this permission notice shall be included in */
- /* all copies or substantial portions of the Software. */
- /* */
- /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
- /* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
- /* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
- /* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
- /* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
- /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN */
- /* THE SOFTWARE. */
- /**********************************************************************************************/
- #include "ts.h"
- #include <string.h>
- void ts_init (ts_t* ts)
- {
- memset (ts,0,sizeof (ts_t));
- }
- static int64_t ts_parse_pts (const uint8_t* data)
- {
- // 0000 1110 1111 1111 1111 1110 1111 1111 1111 1110
- uint64_t pts = 0;
- pts |= (uint64_t) (data[0] & 0x0E) << 29;
- pts |= (uint64_t) (data[1] & 0xFF) << 22;
- pts |= (uint64_t) (data[2] & 0xFE) << 14;
- pts |= (uint64_t) (data[3] & 0xFF) << 7;
- pts |= (uint64_t) (data[4] & 0xFE) >> 1;
- return pts;
- }
- int ts_parse_packet (ts_t* ts, const uint8_t* data)
- {
- size_t i = 0;
- int pusi = !! (data[i + 1] & 0x40); // Payload Unit Start Indicator
- int16_t pid = ( (data[i + 1] & 0x1F) << 8) | data[i + 2]; // PID
- int adaption_present = !! (data[i + 3] & 0x20); // Adaptation field exist
- int payload_present = !! (data[i + 3] & 0x10); // Contains payload
- i += 4;
- ts->data = 0;
- ts->size = 0;
- if (adaption_present) {
- uint8_t adaption_length = data[i + 0]; // adaption field length
- i += 1 + adaption_length;
- }
- if (pid == 0) {
- if (payload_present) {
- // Skip the payload.
- i += data[i] + 1;
- }
- ts->pmtpid = ( (data[i + 10] & 0x1F) << 8) | data[i + 11];
- } else if (pid == ts->pmtpid) {
- // PMT
- if (payload_present) {
- // Skip the payload.
- i += data[i] + 1;
- }
- uint16_t section_length = ( (data[i + 1] & 0x0F) << 8) | data[i + 2];
- int current = data[i + 5] & 0x01;
- int16_t program_info_length = ( (data[i + 10] & 0x0F) << 8) | data[i + 11];
- int16_t descriptor_loop_length = section_length - (9 + program_info_length + 4); // 4 for the crc
- i += 12 + program_info_length;
- if (current) {
- while (descriptor_loop_length >= 5) {
- uint8_t stream_type = data[i];
- int16_t elementary_pid = ( (data[i + 1] & 0x1F) << 8) | data[i + 2];
- int16_t esinfo_length = ( (data[i + 3] & 0x0F) << 8) | data[i + 4];
- if (0x1B == stream_type) {
- ts->avcpid = elementary_pid;
- }
- i += 5 + esinfo_length;
- descriptor_loop_length -= 5 + esinfo_length;
- }
- }
- } else if (payload_present && pid == ts->avcpid) {
- if (pusi) {
- // int data_alignment = !! (data[i + 6] & 0x04);
- int has_pts = !! (data[i + 7] & 0x80);
- int has_dts = !! (data[i + 7] & 0x40);
- uint8_t header_length = data[i + 8];
- if (has_pts) {
- ts->pts = ts_parse_pts (&data[i + 9]);
- ts->dts = has_dts ? ts_parse_pts (&data[i + 14]) : ts->pts;
- }
- i += 9 + header_length;
- }
- ts->data = &data[i];
- ts->size = TS_PACKET_SIZE-i;
- return LIBCAPTION_READY;
- }
- return LIBCAPTION_OK;
- }
|