37 #include "AampUtils.h"
46 #ifdef LOG_ENABLE_TRACE
47 #define TRACE1 AAMPLOG_TRACE("PC: TRACE1 %s:%d:"); AAMPLOG_TRACE
48 #define TRACE2 AAMPLOG_TRACE("PC: TRACE2 "); AAMPLOG_TRACE
49 #define TRACE3 AAMPLOG_TRACE("PC: TRACE3 "); AAMPLOG_TRACE
50 #define TRACE4 AAMPLOG_TRACE("PC: TRACE4 "); AAMPLOG_TRACE
52 #define TRACE1 print_nop
53 #define TRACE2 print_nop
54 #define TRACE3 print_nop
55 #define TRACE4 print_nop
59 #define DEBUG print_nop
60 #define INFO print_nop
62 #define INFO AAMPLOG_INFO("PC: INFO " ); AAMPLOG_INFO
63 #define DEBUG AAMPLOG_TRACE("PC: DEBUG " ); AAMPLOG_TRACE
66 #define LOG_WARNINGS_AND_ERRORS
69 #ifndef LOG_WARNINGS_AND_ERRORS
70 #define NOTICE print_nop
71 #define WARNING print_nop
72 #define ERROR print_nop
73 #define FATAL print_nop
76 #define NOTICE(FORMAT, ...) AAMPLOG(mLogObj, eLOGLEVEL_INFO, "INFO", FORMAT, ##__VA_ARGS__)
77 #define WARNING(FORMAT, ...) AAMPLOG(mLogObj, eLOGLEVEL_WARN, "WARN", FORMAT, ##__VA_ARGS__)
78 #define ERROR(FORMAT, ...) AAMPLOG(mLogObj, eLOGLEVEL_ERROR, "ERROR", FORMAT, ##__VA_ARGS__)
84 #define PACKET_SIZE (188)
85 #define MAX_PACKET_SIZE (208)
86 #define FIXED_FRAME_RATE (10)
87 #define FRAME_WIDTH_MAX (1920)
88 #define FRAME_HEIGHT_MAX (1080)
89 #define WAIT_FOR_DATA_MILLISEC 100
90 #define WAIT_FOR_DATA_MAX_RETRIES 1
91 #define MAX_PMT_SECTION_SIZE (1021)
92 #define PATPMT_MAX_SIZE (2*1024)
93 #define PAT_SPTS_SIZE (13)
94 #define PAT_TABLE_ENTRY_SIZE (4)
97 #define MAX_PTS (uint33_t::max_value().value)
100 #define MAX_DESCRIPTOR (4)
102 #define I_FRAME (0x1)
103 #define P_FRAME (0x2)
104 #define B_FRAME (0x4)
105 #define ALL_FRAMES (0x7)
106 #define SEQ_START (0x10)
107 #define IDX_BUFF_SIZE (128*1024)
110 #define DEFAULT_THROTTLE_MAX_DELAY_MS 500
111 #define DEFAULT_THROTTLE_MAX_DIFF_SEGMENTS_MS 400
112 #define DEFAULT_THROTTLE_DELAY_IGNORED_MS 200
113 #define DEFAULT_THROTTLE_DELAY_FOR_DISCONTINUITY_MS 2000
115 #define PES_STATE_WAITING_FOR_HEADER 0
116 #define PES_STATE_GETTING_HEADER 1
117 #define PES_STATE_GETTING_HEADER_EXTENSION 2
118 #define PES_STATE_GETTING_ES 3
120 #define PAYLOAD_UNIT_START(packetStart) ( packetStart[1] & 0x40)
121 #define CONTAINS_PAYLOAD(packetStart) ( packetStart[3] & 0x10)
122 #define IS_PES_PACKET_START(a) ( (a[0] == 0 )&& (a[1] == 0 ) &&(a[2] == 1 ))
123 #define PES_OPTIONAL_HEADER_PRESENT(pesStart) ( ( pesStart[6] & 0xC0) == 0x80 )
124 #define PES_HEADER_LENGTH 6
125 #define PES_OPTIONAL_HEADER_LENGTH(pesStart) (pesStart[PES_HEADER_LENGTH+2])
126 #define PES_MIN_DATA (PES_HEADER_LENGTH+3)
127 #define ADAPTATION_FIELD_PRESENT(mpegbuf) ((mpegbuf[3] & 0x20) == 0x20)
128 #define PES_PAYLOAD_LENGTH(pesStart) (pesStart[4]<<8|pesStart[5])
129 #define MAX_FIRST_PTS_OFFSET (uint33_t{45000})
131 #define DESCRIPTOR_TAG_SUBTITLE 0x59
132 #define DESCRIPTOR_TAG_AC3 0x6A
133 #define DESCRIPTOR_TAG_EAC3 0x7A
135 #ifdef DEBUG_DEMUX_TRACK
136 #define DEBUG_DEMUX(a...) { \
137 if (type == DEBUG_DEMUX_TRACK || DEBUG_DEMUX_TRACK == 0xff) \
139 AAMPLOG_WARN("PC: DEBUG_DEMUX Track %d : ", DEBUG_DEMUX_TRACK );\
148 #define DEBUG_DEMUX DEBUG
179 static unsigned long long mTimeAdjust;
180 static bool mbInduceRollover;
181 void tsdemuxer_InduceRollover(
bool enable )
184 mbInduceRollover = enable;
194 unsigned long long v;
195 v = (
unsigned long long) (ptr[0] & 0x0F) << 32
196 | (
unsigned long long) ptr[1] << 24 | (
unsigned long long) ptr[2] << 16
197 | (
unsigned long long) ptr[3] << 8 | (
unsigned long long) ptr[4];
198 unsigned long long timeStamp = 0;
199 timeStamp |= (v >> 3) & (0x0007ULL << 30);
200 timeStamp |= (v >> 2) & (0x7fff << 15);
201 timeStamp |= (v >> 1) & (0x7fff << 0);
203 if( mbInduceRollover )
205 mTimeAdjust = (
MAX_PTS-90000*10) - timeStamp;
206 mbInduceRollover =
false;
208 timeStamp += mTimeAdjust;
218 template<
class T,
class U = T>
221 T old_value = std::move(obj);
222 obj = std::forward<U>(new_value);
236 int pes_header_ext_len;
237 int pes_header_ext_read;
246 bool update_first_pts;
249 bool finalized_base_pts;
252 bool reached_steady_state;
260 if( !reached_steady_state )
262 if ((base_pts > current_pts)
263 || (current_dts && base_pts > current_dts))
265 WARNING(
"Discard ES Type %d position %f base_pts %llu current_pts %llu diff %f seconds length %d",
266 type, position, base_pts.value, current_pts.value, (
double)(base_pts - current_pts) / 90000, (
int)es.
len );
271 if (base_pts + uint33_t::half_max() > current_pts + uint33_t::half_max())
273 WARNING(
"Discard ES Type %d position %f base_pts %llu current_pts %llu base_pts+half_max %llu current_pts+half_max %llu",
274 type, position, base_pts.value, current_pts.value, (base_pts+uint33_t::half_max()).value, (current_pts+uint33_t::half_max()).value);
278 reached_steady_state =
true;
281 double pts = position;
285 pts += (double)(current_pts - base_pts) / 90000;
287 if (!trickmode && current_dts)
289 dts = position + (double)(current_dts - base_pts) / 90000;
295 DEBUG_DEMUX(
"Send : pts %f dts %f", pts, dts);
296 DEBUG_DEMUX(
"position %f base_pts %llu current_pts %llu diff %f seconds length %d", position, base_pts, current_pts, (
double)(current_pts - base_pts) / 90000, (
int)es.
len );
301 if(0 == (sentESCount % 150 ))
303 AAMPLOG_WARN(
"Demuxer:: type %d sent %d packets", (
int)type, sentESCount);
316 pes_header_ext_len(0), pes_header_ext_read(0), pes_header(),
317 es(), position(0), duration(0), base_pts{0}, current_pts{0},
318 current_dts{0}, type(type), trickmode(
false), finalized_base_pts(
false),
319 sentESCount(0), allowPtsRewind(
false), first_pts{0}, update_first_pts(
false), reached_steady_state(
false)
321 init(0, 0,
false,
true);
351 void init(
double position,
double duration,
bool trickmode,
bool resetBasePTS)
353 this->position = position;
354 this->duration = duration;
355 this->trickmode = trickmode;
363 update_first_pts =
false;
364 finalized_base_pts =
false;
368 pes_state = PES_STATE_WAITING_FOR_HEADER;
369 DEBUG_DEMUX(
"init : position %f, duration %f resetBasePTS %d", position, duration, resetBasePTS);
380 INFO(
"demux : sending remaining bytes. es.len %d", (
int)es.
len);
383 AAMPLOG_INFO(
"Demuxer::count %d in duration %f",sentESCount, duration);
410 NOTICE(
"Type[%d], basePTS %llu final %d\n", (
int)type, basePTS, (
int)isFinal);
413 finalized_base_pts = isFinal;
422 return base_pts.value;
432 void processPacket(
unsigned char * packetStart,
bool &basePtsUpdated,
bool &ptsError,
bool &isPacketIgnored,
bool applyOffset)
434 int adaptation_fieldlen = 0;
435 basePtsUpdated =
false;
436 if (CONTAINS_PAYLOAD(packetStart))
438 if (ADAPTATION_FIELD_PRESENT(packetStart))
440 adaptation_fieldlen = packetStart[4];
442 int pesOffset = 4 + adaptation_fieldlen;
443 if (ADAPTATION_FIELD_PRESENT(packetStart))
448 if (PAYLOAD_UNIT_START(packetStart))
454 unsigned char* pesStart = packetStart + pesOffset;
455 if (IS_PES_PACKET_START(pesStart))
457 if (PES_OPTIONAL_HEADER_PRESENT(pesStart))
459 if ((pesStart[7] & 0x80) && ((pesStart[9] & 0x20) == 0x20))
462 auto prev_pts =
exchange(current_pts, timeStamp);
463 if(prev_pts > current_pts && prev_pts - current_pts > uint33_t::half_max())
465 WARNING(
"PTS Rollover type:%d %llu -> %llu ", type, prev_pts.value, current_pts.value);
467 current_pts = timeStamp;
468 DEBUG(
"PTS updated %llu", current_pts.value);
469 if(!finalized_base_pts)
471 finalized_base_pts =
true;
480 base_pts = current_pts - MAX_FIRST_PTS_OFFSET;
481 WARNING(
"Type[%d] base_pts not initialized, updated to %llu", type, base_pts.value );
485 base_pts = current_pts;
490 if(current_pts < base_pts)
492 auto orig_base_pts = base_pts;
493 if (current_pts > MAX_FIRST_PTS_OFFSET)
497 base_pts = current_pts - MAX_FIRST_PTS_OFFSET;
501 base_pts = current_pts;
506 base_pts = current_pts;
508 WARNING(
"Type[%d] current_pts[%llu] < base_pts[%llu], base_pts[%llu]->[%llu]",
509 type, current_pts.value, base_pts.value, orig_base_pts.value, base_pts.value);
513 auto delta = current_pts - base_pts;
514 if (MAX_FIRST_PTS_OFFSET < delta)
517 auto orig_base_pts = base_pts;
520 base_pts = current_pts - MAX_FIRST_PTS_OFFSET;
524 base_pts = current_pts;
526 NOTICE(
"Type[%d] delta[%lld] > MAX_FIRST_PTS_OFFSET, current_pts[%llu] base_pts[%llu]->[%llu]",
527 type, delta.value, current_pts.value, orig_base_pts.value, base_pts.value);
531 NOTICE(
"Type[%d] PTS in range.delta[%lld] <= MAX_FIRST_PTS_OFFSET base_pts[%llu]",
532 type, delta.value, base_pts.value);
539 base_pts = timeStamp;
540 WARNING(
"base_pts not available, updated to pts %llu", timeStamp.value );
542 else if (base_pts > timeStamp)
544 WARNING(
"base_pts update from %llu to %llu", base_pts.value, timeStamp.value );
545 base_pts = timeStamp;
547 basePtsUpdated =
true;
552 WARNING(
"PTS NOT present pesStart[7] & 0x80 = 0x%x pesStart[9]&0xF0 = 0x%x",
553 pesStart[7] & 0x80, (pesStart[9] & 0x20));
556 if (((pesStart[7] & 0xC0) == 0xC0) && ((pesStart[14] & 0x1) == 0x01))
562 DEBUG(
"DTS NOT present pesStart[7] & 0x80 = 0x%x pesStart[9]&0xF0 = 0x%x",
563 pesStart[7] & 0x80, (pesStart[9] & 0x20));
568 WARNING(
"Optional pes header NOT present pesStart[6] & 0xC0 = 0x%x", pesStart[6] & 0xC0);
573 WARNING(
"Packet start prefix check failed 0x%x 0x%x 0x%x adaptation_fieldlen %d", pesStart[0],
574 pesStart[1], pesStart[2], adaptation_fieldlen);
590 if( current_pts == 0 )
592 WARNING(
"Avoiding PTS check when new audio or video TS packet is received without proper PES data");
593 isPacketIgnored =
true;
597 DEBUG(
" PES_PAYLOAD_LENGTH %d", PES_PAYLOAD_LENGTH(pesStart));
599 if ((first_pts == 0) && !update_first_pts)
601 first_pts = current_pts;
602 update_first_pts =
true;
613 unsigned char * data = packetStart + pesOffset;
614 int size = PACKET_SIZE - pesOffset;
616 if (PAYLOAD_UNIT_START(packetStart))
618 pes_state = PES_STATE_GETTING_HEADER;
620 DEBUG_DEMUX(
"Payload Unit Start");
627 case PES_STATE_WAITING_FOR_HEADER:
628 WARNING(
"PES_STATE_WAITING_FOR_HEADER , discard data. type =%d size = %d", (
int)type, size);
631 case PES_STATE_GETTING_HEADER:
632 bytes_to_read = PES_MIN_DATA - pes_header.
len;
633 if (size < bytes_to_read)
635 bytes_to_read = size;
637 DEBUG(
"PES_STATE_GETTING_HEADER. size = %d, bytes_to_read =%d", size, bytes_to_read);
639 data += bytes_to_read;
640 size -= bytes_to_read;
641 if (pes_header.
len == PES_MIN_DATA)
643 if (!IS_PES_PACKET_START(pes_header.
ptr))
645 WARNING(
"Packet start prefix check failed 0x%x 0x%x 0x%x", pes_header.
ptr[0],
646 pes_header.
ptr[1], pes_header.
ptr[2]);
647 pes_state = PES_STATE_WAITING_FOR_HEADER;
650 if (PES_OPTIONAL_HEADER_PRESENT(pes_header.
ptr))
652 pes_state = PES_STATE_GETTING_HEADER_EXTENSION;
653 pes_header_ext_len = PES_OPTIONAL_HEADER_LENGTH(pes_header.
ptr);
654 pes_header_ext_read = 0;
656 "Optional header preset len = %d. Switching to PES_STATE_GETTING_HEADER_EXTENSION",
662 "Optional header not preset pesStart[6] 0x%x bytes_to_read %d- switching to PES_STATE_WAITING_FOR_HEADER",
663 pes_header.
ptr[6], bytes_to_read);
664 pes_state = PES_STATE_WAITING_FOR_HEADER;
668 case PES_STATE_GETTING_HEADER_EXTENSION:
669 bytes_to_read = pes_header_ext_len - pes_header_ext_read;
670 if (bytes_to_read > size)
672 bytes_to_read = size;
674 data += bytes_to_read;
675 size -= bytes_to_read;
676 pes_header_ext_read += bytes_to_read;
677 if (pes_header_ext_read == pes_header_ext_len)
679 pes_state = PES_STATE_GETTING_ES;
680 DEBUG(
"Optional header read. switch to PES_STATE_GETTING_ES");
683 case PES_STATE_GETTING_ES:
685 TRACE1(
"PES_STATE_GETTING_ES bytes_to_read = %d", size);
690 pes_state = PES_STATE_WAITING_FOR_HEADER;
691 ERROR(
"Invalid pes_state. type =%d size = %d", (
int)type, size);
699 INFO(
"No payload in packet packetStart[3] 0x%x", packetStart[3]);
705 #define rmf_osal_memcpy(d, s, n, dc, sc) memcpy(d, s, n)
707 static unsigned long crc32_table[256];
708 static int crc32_initialized = 0;
716 if (crc32_initialized)
return;
717 unsigned int k, i, j;
718 for (i = 0; i < 256; i++)
721 for (j = (i << 24) | 0x800000; j != 0x80000000; j <<= 1)
723 k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0);
727 crc32_initialized = 1;
738 static uint32_t
get_crc32(
unsigned char *data,
int size, uint32_t initial = 0xffffffff)
741 uint32_t result = initial;
743 for (i = 0; i < size; i++)
745 result = (result << 8) ^ crc32_table[(result >> 24) ^ data[i]];
756 static void dumpPacket(
unsigned char *packet,
int packetSize)
765 buff[buffPos] = 0x00;
766 for (i = 0; i < packetSize; ++i)
768 buffPos += snprintf(&buff[buffPos], (
sizeof(buff) - buffPos),
"%02X\n", packet[i]);
777 buffPos += snprintf(&buff[buffPos], (
sizeof(buff) - buffPos),
"\n");
781 printf(
"%s\n", buff);
792 static void dumpPackets(
unsigned char *packets,
int len,
int packetSize)
798 packets += packetSize;
857 : m_needDiscontinuity(true),
858 m_PatPmtLen(0), m_PatPmt(0), m_PatPmtTrickLen(0), m_PatPmtTrick(0), m_PatPmtPcrLen(0), m_PatPmtPcr(0),
859 m_nullPFrame(0), m_nullPFrameLength(0), m_nullPFrameNextCount(0), m_nullPFrameOffset(0),
860 m_emulationPreventionCapacity(0), m_emulationPreventionOffset(0), m_emulationPrevention(0), aamp(aamp),
861 m_currStreamOffset(0), m_currPTS(-1), m_currTimeStamp(-1LL), m_currFrameNumber(-1),
862 m_currFrameLength(0), m_currFrameOffset(-1LL), m_trickExcludeAudio(true), m_patCounter(0),
864 m_playRateNext(1.0f), m_apparentFrameRate(FIXED_FRAME_RATE), m_packetSize(PACKET_SIZE), m_ttsSize(0),
865 m_pcrPid(-1), m_videoPid(-1), m_haveBaseTime(false), m_haveEmittedIFrame(false), m_haveUpdatedFirstPTS(true),
866 m_pcrPerPTSCount(0), m_baseTime(0), m_segmentBaseTime(0), m_basePCR(-1LL), m_prevRateAdjustedPCR(-1LL),
867 m_currRateAdjustedPCR(0), m_currRateAdjustedPTS(-1LL), m_nullPFrameWidth(-1), m_nullPFrameHeight(-1),
868 m_frameWidth(FRAME_WIDTH_MAX), m_frameHeight(FRAME_HEIGHT_MAX), m_scanForFrameSize(false), m_scanRemainderSize(0),
869 m_scanRemainderLimit(SCAN_REMAINDER_SIZE_MPEG2), m_isH264(false), m_isMCChannel(false), m_isInterlaced(false), m_isInterlacedKnown(false),
870 m_throttle(true), m_haveThrottleBase(false), m_lastThrottleContentTime(-1LL), m_lastThrottleRealTime(-1LL),
871 m_baseThrottleContentTime(-1LL), m_baseThrottleRealTime(-1LL), m_throttlePTS{uint33_t::max_value()}, m_insertPCR(
false),
872 m_scanSkipPacketsEnabled(
false), m_currSPSId(0), m_picOrderCount(0), m_updatePicOrderCount(
false),
873 m_havePAT(
false), m_versionPAT(0), m_program(0), m_pmtPid(0), m_havePMT(
false), m_versionPMT(-1), m_indexAudio(
false),
874 m_haveAspect(
false), m_haveFirstPTS(
false), m_currentPTS(uint33_t::max_value()), m_pmtCollectorNextContinuity(0),
875 m_pmtCollectorSectionLength(0), m_pmtCollectorOffset(0), m_pmtCollector(NULL),
876 m_scrambledWarningIssued(
false), m_checkContinuity(
false), videoComponentCount(0), audioComponentCount(0),
877 m_actualStartPTS{uint33_t::max_value()}, m_throttleMaxDelayMs(DEFAULT_THROTTLE_MAX_DELAY_MS),
878 m_throttleMaxDiffSegments(DEFAULT_THROTTLE_MAX_DIFF_SEGMENTS_MS),
879 m_throttleDelayIgnoredMs(DEFAULT_THROTTLE_DELAY_IGNORED_MS), m_throttleDelayForDiscontinuityMs(DEFAULT_THROTTLE_DELAY_FOR_DISCONTINUITY_MS),
880 m_throttleCond(), m_basePTSCond(), m_mutex(), m_enabled(
true), m_processing(
false), m_framesProcessedInSegment(0),
881 m_lastPTSOfSegment(-1), m_streamOperation(streamOperation), m_vidDemuxer(NULL), m_audDemuxer(NULL), m_dsmccDemuxer(NULL),
882 m_demux(
false), m_peerTSProcessor(peerTSProcessor), m_packetStartAfterFirstPTS(-1), m_queuedSegment(NULL),
883 m_queuedSegmentPos(0), m_queuedSegmentDuration(0), m_queuedSegmentLen(0), m_queuedSegmentDiscontinuous(
false), m_startPosition(-1.0),
884 m_track(track), m_last_frame_time(0), m_demuxInitialized(
false), m_basePTSFromPeer(-1), m_dsmccComponentFound(
false), m_dsmccComponent()
885 , m_AudioTrackIndexToPlay(0)
886 , m_auxTSProcessor(auxTSProcessor)
887 , m_auxiliaryAudio(
false)
892 INFO(
"constructor - %p",
this);
894 memset(m_SPS, 0, 32 *
sizeof(H264SPS));
895 memset(m_PPS, 0, 256 *
sizeof(H264PPS));
897 pthread_cond_init(&m_throttleCond, NULL);
898 pthread_cond_init(&m_basePTSCond, NULL);
899 pthread_mutex_init(&m_mutex, NULL);
917 m_auxiliaryAudio =
true;
932 memset(videoComponents, 0, compBufLen);
933 memset(audioComponents, 0, compBufLen);
941 INFO(
"destructor - %p",
this);
968 if (m_emulationPrevention)
970 free(m_emulationPrevention);
971 m_emulationPrevention = 0;
974 for (
int i = 0; i < audioComponentCount; ++i)
976 if (audioComponents[i].associatedLanguage)
978 free(audioComponents[i].associatedLanguage);
982 SAFE_DELETE(m_vidDemuxer);
983 SAFE_DELETE(m_audDemuxer);
984 SAFE_DELETE(m_dsmccDemuxer);
988 free(m_queuedSegment);
989 m_queuedSegment = NULL;
992 pthread_mutex_destroy(&m_mutex);
993 pthread_cond_destroy(&m_throttleCond);
994 pthread_cond_destroy(&m_basePTSCond);
998 #define BUFFER_POOL_SIZE (10)
999 #define PLAY_BUFFER_AUDIO_MAX_PACKETS (100)
1000 #define PLAY_BUFFER_MAX_PACKETS (512)
1001 #define PLAY_BUFFER_SIZE (PLAY_BUFFER_MAX_PACKETS*MAX_PACKET_SIZE)
1002 #define POOL_BUFFER_ALIGNMENT (16)
1003 #define PLAY_BUFFER_CTX_OFFSET (0)
1004 #define PLAY_BUFFER_SIGNATURE (('P')|(('L')<<8)|(('A')<<16)|(('Y')<<24))
1015 if (trick && m_trickExcludeAudio)
1017 len = m_PatPmtTrickLen;
1018 rmf_osal_memcpy(buffer, m_PatPmtTrick, len, bufferSize, m_PatPmtTrickLen);
1020 else if (trick && m_isMCChannel)
1022 len = m_PatPmtPcrLen;
1023 rmf_osal_memcpy(buffer, m_PatPmtPcr, len, bufferSize, m_PatPmtPcrLen);
1028 rmf_osal_memcpy(buffer, m_PatPmt, len, bufferSize, m_PatPmtLen);
1031 int index = 3 + m_ttsSize;
1032 buffer[index] = ((buffer[index] & 0xF0) | (m_patCounter++ & 0x0F));
1034 index += m_packetSize;
1037 buffer[index] = ((buffer[index] & 0xF0) | (m_pmtCounter++ & 0x0F));
1038 index += m_packetSize;
1056 memset(packet, 0, m_ttsSize);
1059 packet[i + 0] = 0x47;
1060 packet[i + 1] = (0x60 | (
unsigned char)((pid >> 8) & 0x1F));
1061 packet[i + 2] = (
unsigned char)(0xFF & pid);
1064 packet[i + 3] = (0x20 | (m_continuityCounters[pid] & 0x0F));
1065 packet[i + 4] = 0xB7;
1066 packet[i + 5] = 0x10;
1067 currPCR = ((m_currRateAdjustedPTS - 10000) & 0x1FFFFFFFFLL);
1068 TRACE1(
"TSProcessor::insertPCR: m_currRateAdjustedPTS= %llx currPCR= %llx", m_currRateAdjustedPTS, currPCR);
1069 writePCR(&packet[i + 6], currPCR,
true);
1070 for (
int i = 6 + 6 + m_ttsSize; i < m_packetSize; i++)
1082 unsigned char *programInfo, *programInfoEnd;
1083 unsigned int dataDescTags[MAX_PIDS];
1084 int streamType = 0, pid = 0, len = 0;
1089 int version = ((section[2] >> 1) & 0x1F);
1090 int pcrPid = (((section[5] & 0x1F) << 8) + section[6]);
1091 int infoLength = (((section[7] & 0x0F) << 8) + section[8]);
1095 for (
int i = 0; i < audioComponentCount; ++i)
1097 if (audioComponents[i].associatedLanguage)
1099 free(audioComponents[i].associatedLanguage);
1103 memset(videoComponents, 0,
sizeof(videoComponents));
1104 memset(audioComponents, 0,
sizeof(audioComponents));
1106 memset(dataDescTags, 0,
sizeof(dataDescTags));
1108 memset(work, 0,
sizeof(work));
1110 videoComponentCount = audioComponentCount = 0;
1115 programInfo = §ion[9 + infoLength];
1116 programInfoEnd = section + sectionLength - 4;
1117 while (programInfo < programInfoEnd)
1119 streamType = programInfo[0];
1120 pid = (((programInfo[1] & 0x1F) << 8) + programInfo[2]);
1121 len = (((programInfo[3] & 0x0F) << 8) + programInfo[4]);
1127 if (videoComponentCount < MAX_PIDS)
1129 videoComponents[videoComponentCount].
pid = pid;
1130 videoComponents[videoComponentCount].
elemStreamType = streamType;
1131 ++videoComponentCount;
1135 WARNING(
"Warning: RecordContext: pmt contains more than %d video PIDs", MAX_PIDS);
1139 if (videoComponentCount < MAX_PIDS)
1141 videoComponents[videoComponentCount].
pid = pid;
1142 videoComponents[videoComponentCount].
elemStreamType = streamType;
1143 ++videoComponentCount;
1145 m_scanRemainderLimit = SCAN_REMAINDER_SIZE_H264;
1149 WARNING(
"Warning: RecordContext: pmt contains more than %d video PIDs", MAX_PIDS);
1155 bool isAudio =
false;
1158 int descIdx, maxIdx;
1159 int descrTag, descrLen;
1162 maxIdx = descIdx + len;
1164 while (descIdx < maxIdx)
1166 descrTag = programInfo[descIdx];
1167 descrLen = programInfo[descIdx + 1];
1168 NOTICE(
"descrTag 0x%x descrLen %d", descrTag, descrLen);
1169 if (descrTag == DESCRIPTOR_TAG_AC3)
1171 NOTICE(
"descrTag 0x%x descrLen %d. marking as audio component", descrTag, descrLen);
1176 if (descrTag == DESCRIPTOR_TAG_EAC3)
1178 NOTICE(
"descrTag 0x%x descrLen %d. marking as audio component", descrTag, descrLen);
1183 descIdx += (2 + descrLen);
1205 if (audioComponentCount < MAX_PIDS)
1207 audioComponents[audioComponentCount].
pid = pid;
1208 audioComponents[audioComponentCount].
elemStreamType = streamType;
1212 int descIdx, maxIdx;
1213 int descrTag, descrLen;
1216 maxIdx = descIdx + len;
1218 while (descIdx < maxIdx)
1220 descrTag = programInfo[descIdx];
1221 descrLen = programInfo[descIdx + 1];
1227 rmf_osal_memcpy(work, &programInfo[descIdx + 2], descrLen, 32, programInfoEnd - &programInfo[descIdx + 2]);
1228 work[descrLen] =
'\0';
1233 descIdx += (2 + descrLen);
1236 ++audioComponentCount;
1240 WARNING(
"Warning: RecordContext: pmt contains more than %d audio PIDs", MAX_PIDS);
1254 DEBUG(
"RecordContext: pmt contains unused stream type 0x%x", streamType);
1257 programInfo += (5 + len);
1259 aamp->mAudioComponentCount = audioComponentCount;
1260 aamp->mVideoComponentCount = videoComponentCount;
1261 if (videoComponentCount > 0)
1263 m_videoPid = videoComponents[0].
pid;
1264 NOTICE(
"[%p] found %d video pids in program %d with pcr pid %d video pid %d",
1265 this, videoComponentCount,
m_program, pcrPid, m_videoPid);
1267 if (audioComponentCount > 0)
1269 std::vector<AudioTrackInfo> audioTracks;
1270 for(
int i=0; i< audioComponentCount; i++)
1272 std::string index =
"mux-" + std::to_string(i);
1273 std::string language;
1274 if(audioComponents[i].associatedLanguage)
1278 std::string group_id = m_audioGroupId;
1279 std::string name =
"pid-" + std::to_string(audioComponents[i].pid);
1280 std::string characteristics =
"muxed-audio";
1282 std::string codec = GetAudioFormatStringForCodec(streamtype);
1283 audioTracks.push_back(
AudioTrackInfo(index, language, group_id, name, codec, characteristics, 0));
1284 NOTICE(
"[%p] found audio#%d in program %d with pcr pid %d audio pid %d lan:%s codec:%s group:%s",
1285 this, i,
m_program, pcrPid, audioComponents[i].pid, language.c_str(), codec.c_str(), group_id.c_str());
1289 if(audioTracks.size() > 0)
1299 int trackIndex = SelectAudioIndexToPlay();
1300 if(trackIndex != -1 && trackIndex < audioComponentCount)
1302 AAMPLOG_INFO(
"Selected best track audio#%d with per preference", trackIndex);
1303 m_AudioTrackIndexToPlay = trackIndex;
1304 std::string index =
"mux-" + std::to_string(trackIndex);
1311 if (videoComponentCount > 0)
1320 if (!m_auxiliaryAudio)
1331 NOTICE(
"[%p] found dsmcc pid in program %d with pcr pid %d dsmcc pid %d",
1336 if (videoComponentCount == 0)
1338 for (
int audioIndex = 0; audioIndex < audioComponentCount; ++audioIndex)
1340 if (pcrPid == audioComponents[audioIndex].pid)
1342 INFO(
"RecordContext: indexing audio");
1368 free(m_PatPmtTrick);
1389 long long currPTS, currPCR,
insertPCR = -1LL;
1390 bool haveInsertPCR =
false;
1394 currPCR = ((currPTS - 10000) & 0x1FFFFFFFFLL);
1395 if (!m_haveBaseTime)
1399 haveInsertPCR =
true;
1402 m_haveUpdatedFirstPTS =
false;
1403 m_pcrPerPTSCount = 0;
1404 m_prevRateAdjustedPCR = -1LL;
1405 m_currRateAdjustedPCR = currPCR;
1406 m_currRateAdjustedPTS = currPTS;
1418 if (haveInsertPCR && (m_playRateNext != 1.0))
1420 m_haveBaseTime =
true;
1422 m_segmentBaseTime = m_baseTime;
1423 INFO(
"have baseTime %llx from pid %x on signal of PCR discontinuity", m_baseTime, m_pcrPid);
1431 if ((m_videoPid != -1) && (m_videoPid != m_pcrPid))
1435 for (
int discIndex = 0; discIndex < discCount; ++discIndex)
1437 int discPid = (discIndex == 0) ? m_pcrPid : m_videoPid;
1438 unsigned char discontinuityPacket[MAX_PACKET_SIZE];
1442 memset(discontinuityPacket, 0, m_ttsSize);
1445 discontinuityPacket[i + 0] = 0x47;
1446 discontinuityPacket[i + 1] = 0x60;
1447 discontinuityPacket[i + 1] |= (
unsigned char)((discPid >> 8) & 0x1F);
1448 discontinuityPacket[i + 2] = (
unsigned char)(0xFF & discPid);
1449 discontinuityPacket[i + 3] = 0x20;
1450 discontinuityPacket[i + 4] = 0xB7;
1451 discontinuityPacket[i + 5] = 0x80;
1452 for (
int i = 6 + m_ttsSize; i < m_packetSize; i++)
1454 discontinuityPacket[i] = 0xFF;
1456 m_continuityCounters[discPid] = 0x00;
1458 TRACE1(
"emit pcr discontinuity");
1468 memset(discontinuityPacket, 0, m_ttsSize);
1471 discontinuityPacket[i + 0] = 0x47;
1472 discontinuityPacket[i + 1] = 0x60;
1473 discontinuityPacket[i + 1] |= (
unsigned char)((discPid >> 8) & 0x1F);
1474 discontinuityPacket[i + 2] = (
unsigned char)(0xFF & discPid);
1475 discontinuityPacket[i + 3] = 0x21;
1476 discontinuityPacket[i + 4] = 0xB7;
1477 discontinuityPacket[i + 5] = 0x10;
1479 for (
int i = 6 + 6 + m_ttsSize; i < m_packetSize; i++)
1481 discontinuityPacket[i] = 0xFF;
1483 m_continuityCounters[discPid] = 0x01;
1485 TRACE1(
"supply new pcr value");
1493 m_needDiscontinuity =
false;
1503 long long currentTime;
1505 gettimeofday(&tv, 0);
1507 currentTime = (((
unsigned long long)tv.tv_sec) * 1000 + ((
unsigned long long)tv.tv_usec) / 1000);
1518 #define MICROSECONDS_PER_SECOND 1000000L
1521 bool aborted =
false;
1522 gettimeofday(&tv, NULL);
1523 long long utc_usec = tv.tv_sec*MICROSECONDS_PER_SECOND + (tv.tv_usec) + throttleDiff*1000;
1524 ts.tv_sec = (time_t)(utc_usec/MICROSECONDS_PER_SECOND);
1525 ts.tv_nsec = (long)(1000L*(utc_usec%MICROSECONDS_PER_SECOND));
1526 pthread_mutex_lock(&m_mutex);
1530 int ret = pthread_cond_timedwait(&m_throttleCond, &m_mutex, &ts);
1535 else if (ETIMEDOUT != ret)
1537 AAMPLOG_ERR(
"sleep - condition wait failed %s", strerror(ret));
1545 pthread_mutex_unlock(&m_mutex);
1555 bool aborted =
false;
1561 long long contentTime = ((m_playRate != 1.0) ? m_throttlePTS.value : m_actualStartPTS.value);
1562 if (contentTime != -1LL)
1564 long long now, contentTimeDiff, realTimeDiff;
1565 TRACE2(
"contentTime %lld (%lld ms) m_playRate %f", contentTime, contentTime / 90, m_playRate);
1568 contentTime = (contentTime / 90LL);
1571 if (m_haveThrottleBase)
1574 if (m_lastThrottleContentTime != -1LL)
1576 contentTimeDiff = contentTime - m_lastThrottleContentTime;
1577 realTimeDiff = now - m_lastThrottleRealTime;
1578 if (((contentTimeDiff > 0) && (contentTimeDiff < m_throttleMaxDiffSegments)) && ((realTimeDiff > 0) && (realTimeDiff < m_throttleMaxDiffSegments)))
1580 contentTimeDiff = contentTime - m_baseThrottleContentTime;
1581 realTimeDiff = now - m_baseThrottleRealTime;
1582 if ((realTimeDiff > 0) && (realTimeDiff < contentTimeDiff))
1584 long long throttleDiff = (contentTimeDiff - realTimeDiff - m_throttleDelayIgnoredMs);
1585 if (throttleDiff > 0)
1587 if (throttleDiff > m_throttleMaxDelayMs)
1590 TRACE2(
"TSProcessor::fillBuffer: throttle: cap %lld to %d ms", throttleDiff, m_throttleMaxDelayMs);
1591 throttleDiff = m_throttleMaxDelayMs;
1595 TRACE2(
"TSProcessor::fillBuffer: throttle: sleep %lld ms", throttleDiff);
1597 aborted =
msleep(throttleDiff);
1601 INFO(
"throttleDiff negative? %lld", throttleDiff);
1606 TRACE2(
"realTimeDiff %lld", realTimeDiff);
1609 else if ((contentTimeDiff < -m_throttleDelayForDiscontinuityMs) || (contentTimeDiff > m_throttleDelayForDiscontinuityMs))
1613 m_haveThrottleBase =
false;
1614 INFO(
" contentTimeDiff( %lld) greater than threshold (%d) - probable pts discontinuity", contentTimeDiff, m_throttleDelayForDiscontinuityMs);
1618 INFO(
" Out of throttle window - contentTimeDiff %lld realTimeDiff %lld", contentTimeDiff, realTimeDiff);
1623 TRACE2(
" m_lastThrottleContentTime %lld", m_lastThrottleContentTime);
1628 INFO(
"Do not have ThrottleBase");
1631 if (!m_haveThrottleBase)
1633 m_haveThrottleBase =
true;
1634 m_baseThrottleRealTime = now;
1635 m_baseThrottleContentTime = contentTime;
1637 m_lastThrottleRealTime = now;
1638 m_lastThrottleContentTime = contentTime;
1640 else if (m_demux && (1.0 != m_playRate))
1642 if (m_last_frame_time)
1645 long long nextFrameTime = m_last_frame_time + 1000 / m_apparentFrameRate;
1646 if (nextFrameTime > now)
1648 long long throttleDiff = nextFrameTime - now;
1649 INFO(
"Wait %llu ms ", throttleDiff);
1650 aborted =
msleep(throttleDiff);
1657 INFO(
"contentTime not updated yet");
1662 TRACE1(
"Throttle not enabled");
1675 unsigned char *packet, *bufferEnd;
1676 int pid, payloadStart, adaptation, payloadOffset;
1677 int continuity, scramblingControl;
1678 int packetCount = 0;
1680 bool removePatPmt =
false;
1681 m_packetStartAfterFirstPTS = -1;
1686 removePatPmt =
true;
1687 INFO(
"Replace PAT/PMT");
1691 removePatPmt =
true;
1692 INFO(
"Remove PAT/PMT");
1695 bool doThrottle = m_throttle;
1698 m_actualStartPTS = -1LL;
1700 packet = buffer + m_ttsSize;
1703 if (!((packet[0] == 0x47) && ((size%m_packetSize) == 0)))
1705 ERROR(
"Error: data buffer not TS packet aligned");
1706 AAMPLOG_WARN(
"packet=%p size=%d m_packetSize=%d", packet, size, m_packetSize);
1711 bufferEnd = packet + size - m_ttsSize;
1712 while (packet < bufferEnd)
1714 pid = (((packet[1] << 8) | packet[2]) & 0x1FFF);
1715 TRACE4(
"pid = %d, m_ttsSize %d", pid, m_ttsSize);
1717 if (m_checkContinuity)
1719 if ((pid != 0x1FFF) && (packet[3] & 0x10))
1721 continuity = (packet[3] & 0x0F);
1722 int expected = m_continuityCounters[pid];
1723 expected = ((expected + 1) & 0xF);
1724 if (expected != continuity)
1726 WARNING(
"input SPTS discontinuity on pid %X (%d instead of %d) offset %llx",
1727 pid, continuity, expected, (
long long)(packetCount*m_packetSize));
1730 m_continuityCounters[pid] = continuity;
1736 adaptation = ((packet[3] & 0x30) >> 4);
1737 if (adaptation & 0x01)
1741 if (adaptation & 0x02)
1743 payloadOffset += (1 + packet[4]);
1746 payloadStart = (packet[1] & 0x40);
1749 int tableid = packet[payloadOffset + 1];
1750 if (tableid == 0x00)
1752 int version = packet[payloadOffset + 6];
1753 int current = (version & 0x01);
1754 version = ((version >> 1) & 0x1F);
1756 TRACE4(
"PAT current version %d existing version %d", version,
m_versionPAT);
1761 int length = ((packet[payloadOffset + 2] & 0x0F) << 8) + (packet[payloadOffset + 3]);
1763 if (length >= PAT_SPTS_SIZE)
1765 int patTableIndex = payloadOffset + 9;
1766 int patTableEndIndex = payloadOffset + length -1;
1767 pthread_mutex_lock(&m_mutex);
1771 pthread_mutex_unlock(&m_mutex);
1774 m_program = ((packet[patTableIndex + 0] << 8) + packet[patTableIndex + 1]);
1775 m_pmtPid = (((packet[patTableIndex + 2] & 0x1F) << 8) + packet[patTableIndex + 3]);
1777 patTableIndex += PAT_TABLE_ENTRY_SIZE;
1779 }
while (
m_program == 0 && patTableIndex < patTableEndIndex);
1783 if (length > PAT_SPTS_SIZE)
1785 WARNING(
"RecordContext: PAT is MPTS, using program %d.",
m_program);
1789 INFO(
"RecordContext: pmt change detected in pat");
1794 DEBUG(
"RecordContext: acquired PAT version %d program %X pmt pid %X", version,
m_program,
m_pmtPid);
1798 WARNING(
"Warning: RecordContext: ignoring pid 0 TS packet with suspect program %x and pmtPid %x",
m_program,
m_pmtPid);
1806 WARNING(
"Warning: RecordContext: ignoring pid 0 TS packet with length of %d - not SPTS?", length);
1812 WARNING(
"Warning: RecordContext: ignoring pid 0 TS packet with tableid of %x", tableid);
1817 WARNING(
"Warning: RecordContext: ignoring pid 0 TS packet with adaptation of %x", adaptation);
1822 WARNING(
"Warning: RecordContext: ignoring pid 0 TS with no payload indicator");
1828 packet[1] = ((packet[1] & 0xE0) | 0x1F);
1834 TRACE4(
"Got PMT : m_pmtPid %d",
m_pmtPid);
1835 adaptation = ((packet[3] & 0x30) >> 4);
1836 if (adaptation & 0x01)
1840 if (adaptation & 0x02)
1842 payloadOffset += (1 + packet[4]);
1845 payloadStart = (packet[1] & 0x40);
1848 int tableid = packet[payloadOffset + 1];
1849 if (tableid == 0x02)
1851 int program = ((packet[payloadOffset + 4] << 8) + packet[payloadOffset + 5]);
1854 int version = packet[payloadOffset + 6];
1855 int current = (version & 0x01);
1856 version = ((version >> 1) & 0x1F);
1858 TRACE4(
"PMT current version %d existing version %d", version,
m_versionPMT);
1865 INFO(
"RecordContext: pmt change detected: version %d -> %d",
m_versionPMT, version);
1872 int sectionLength = (((packet[payloadOffset + 2] & 0x0F) << 8) + packet[payloadOffset + 3]);
1875 if (payloadOffset + 4 + sectionLength <= m_packetSize - m_ttsSize)
1879 else if (sectionLength <= MAX_PMT_SECTION_SIZE)
1886 ERROR(
"Error: unable to allocate pmt collector buffer - ignoring large pmt (section length %d)", sectionLength);
1889 INFO(
"RecordContext: allocating pmt collector buffer %p",
m_pmtCollector);
1892 int sectionOffset = payloadOffset + 4;
1893 int sectionAvail = m_packetSize - m_ttsSize - sectionOffset;
1894 unsigned char *sectionData = packet + sectionOffset;
1895 rmf_osal_memcpy(
m_pmtCollector, sectionData, sectionAvail, MAX_PMT_SECTION_SIZE, (bufferEnd - sectionData));
1899 INFO(
"RecordContext: starting to collect multi-packet pmt: section length %d", sectionLength);
1903 WARNING(
"Warning: RecordContext: ignoring oversized pmt (section length %d)", sectionLength);
1910 WARNING(
"Warning: RecordContext: ignoring pmt TS packet with mismatched program of %x (expecting %x)", program,
m_program);
1916 TRACE1(
"Warning: RecordContext: ignoring pmt TS packet with tableid of %x", tableid);
1924 int continuity = (packet[3] & 0xF);
1927 WARNING(
"Warning: RecordContext: next packet of multi-packet pmt has wrong continuity count %d (expecting %d)",
1935 int avail = m_packetSize - m_ttsSize - payloadOffset;
1937 int copylen = ((avail > sectionAvail) ? sectionAvail : avail);
1955 ERROR(
"Error: RecordContext: aborting multi-packet pmt due to discontinuity error: expected %d got %d",
1962 WARNING(
"Warning: RecordContext: ignoring unexpected pmt TS packet without payload start indicator");
1968 WARNING(
"Warning: RecordContext: ignoring unexpected pmt TS packet without payload indicator");
1974 packet[1] = ((packet[1] & 0xE0) | 0x1F);
1978 else if ((pid == m_videoPid) || (pid == m_pcrPid))
1981 if ((m_actualStartPTS == -1LL) && doThrottle)
1984 adaptation = ((packet[3] & 0x30) >> 4);
1985 payloadStart = (packet[1] & 0x40);
1987 scramblingControl = ((packet[3] & 0xC0) >> 6);
1988 if (scramblingControl)
1990 if (!m_scrambledWarningIssued)
1992 TRACE3(
"RecordingContext: video pid %x transport_scrambling_control bits are non-zero (%02x)- is data still scrambled?", pid, packet[3]);
1993 m_scrambledWarningIssued =
true;
1994 TRACE3(
"[found scrambled data, NOT writing idx,mpg files, returning(true)... ");
1997 m_scrambledWarningIssued =
false;
1999 if (adaptation & 0x02)
2001 payloadOffset += (1 + packet[4]);
2004 if (adaptation & 0x01)
2008 if ((packet[payloadOffset] == 0x00) && (packet[payloadOffset + 1] == 0x00) && (packet[payloadOffset + 2] == 0x01))
2010 int pesHeaderDataLen = packet[payloadOffset + 8];
2011 if (packet[payloadOffset + 7] & 0x80)
2018 validPTS =
readTimeStamp(&packet[payloadOffset + 9], result);
2025 m_packetStartAfterFirstPTS = (packet - buffer) + PACKET_SIZE;
2028 constexpr
auto tenSecAsPTS =
uint33_t{10ULL * 90000ULL};
2029 constexpr
auto twelveSecAsPTS =
uint33_t{12ULL * 90000ULL};
2031 if (m_actualStartPTS != uint33_t::max_value())
2038 if (diffPTS > tenSecAsPTS)
2040 if ((diffPTS < twelveSecAsPTS))
2047 INFO(
"RecordContext: pts discontinuity: %llx to %llx",
m_currentPTS.value, PTS.value);
2054 if (m_actualStartPTS == uint33_t::max_value())
2056 m_actualStartPTS = PTS;
2057 TRACE2(
"Updated m_actualStartPTS to %lld", m_actualStartPTS.value);
2064 payloadOffset = payloadOffset + 9 + pesHeaderDataLen;
2073 INFO(
"throttle aborted");
2074 m_haveThrottleBase =
false;
2075 m_lastThrottleContentTime = -1;
2081 if (1.0 != m_playRate && !m_demux)
2084 unsigned char* tmpPacket = packet;
2089 else if (m_playRate != 1.0)
2092 packet[1] = ((packet[1] & 0xE0) | 0x1F);
2097 packet += m_packetSize;
2109 int segmentDurationMs = abs(segmentDurationMsSigned);
2110 m_throttleMaxDelayMs = segmentDurationMs + DEFAULT_THROTTLE_DELAY_IGNORED_MS;
2111 m_throttleMaxDiffSegments = m_throttleMaxDelayMs;
2112 m_throttleDelayIgnoredMs = DEFAULT_THROTTLE_DELAY_IGNORED_MS;
2113 m_throttleDelayForDiscontinuityMs = segmentDurationMs * 10;
2114 TRACE1(
"segmentDurationMs %d", segmentDurationMs);
2123 int videoPid = -1, audioPid = -1, dsmccPid = -1;
2124 unsigned long long firstPcr = 0;
2125 bool isTrickMode = !( 1.0 == m_playRate);
2126 bool notifyPeerBasePTS =
false;
2128 bool basePtsUpdatedFromCurrentSegment =
false;
2132 if (videoComponentCount > 0)
2134 videoPid = videoComponents[0].
pid;
2140 if (discontinuous || !m_demuxInitialized )
2142 if (discontinuous && (1.0 == m_playRate))
2144 NOTICE(
"TSProcessor:%p discontinuous buffer- flushing video demux",
this);
2146 m_vidDemuxer->
flush();
2147 m_vidDemuxer->
init(position, duration, isTrickMode,
true);
2148 m_dsmccDemuxer->
flush();
2149 m_dsmccDemuxer->
init(position, duration, isTrickMode,
true);
2154 if (audioComponentCount > 0)
2156 audioPid = audioComponents[m_AudioTrackIndexToPlay].
pid;
2158 if (discontinuous || !m_demuxInitialized )
2163 NOTICE(
"TSProcessor:%p discontinuous buffer- flushing audio demux",
this);
2165 m_audDemuxer->
flush();
2173 m_demuxInitialized =
true;
2175 INFO(
"demuxAndSend : len %d videoPid %d audioPid %d m_pcrPid %d videoComponentCount %d m_demuxInitialized = %d", (
int)len, videoPid, audioPid, m_pcrPid, videoComponentCount, m_demuxInitialized);
2177 unsigned char * packetStart = (
unsigned char *)ptr;
2178 while (len >= PACKET_SIZE)
2181 int pid = (packetStart[1] & 0x1f) << 8 | packetStart[2];
2182 bool dsmccDemuxerUsed =
false;
2184 if (m_vidDemuxer && (pid == videoPid))
2186 demuxer = m_vidDemuxer;
2188 else if (m_audDemuxer && (pid == audioPid))
2190 demuxer = m_audDemuxer;
2192 else if(m_dsmccDemuxer && (pid == dsmccPid))
2194 demuxer = m_dsmccDemuxer;
2195 dsmccDemuxerUsed =
true;
2198 if ((discontinuous || !m_demuxInitialized ) && !firstPcr && (pid == m_pcrPid))
2200 int adaptation_fieldlen = 0;
2201 if ((packetStart[3] & 0x20) == 0x20)
2203 adaptation_fieldlen = packetStart[4];
2204 if (0 != adaptation_fieldlen && (packetStart[5] & 0x10))
2206 firstPcr = (
unsigned long long) packetStart[6] << 25 | (
unsigned long long) packetStart[7] << 17
2207 | (
unsigned long long) packetStart[8] << 9 | packetStart[9] << 1 | (packetStart[10] & (0x80)) >> 7;
2209 if (m_playRate == 1.0)
2211 NOTICE(
"firstPcr %llu", firstPcr);
2225 notifyPeerBasePTS =
true;
2226 m_demuxInitialized =
true;
2233 bool ptsError =
false;
2234 bool basePTSUpdated =
false;
2235 bool isPacketIgnored =
false;
2236 demuxer->
processPacket(packetStart, basePTSUpdated, ptsError, isPacketIgnored,m_applyOffset);
2245 if( ( demuxer == m_audDemuxer ) && isPacketIgnored )
2247 if( (audioComponentCount > 0) && (m_AudioTrackIndexToPlay < audioComponentCount-1) )
2249 m_AudioTrackIndexToPlay++;
2250 WARNING(
"Switched to next audio pid, since no PES data in current pid");
2255 if(!m_demuxInitialized && !dsmccDemuxerUsed)
2257 WARNING(
"PCR not available before ES packet, updating firstPCR");
2258 m_demuxInitialized =
true;
2259 notifyPeerBasePTS =
true;
2263 if( basePTSUpdated && notifyPeerBasePTS && !dsmccDemuxerUsed)
2267 INFO(
"Using first video pts as base pts");
2272 WARNING(
"Using first audio pts as base pts");
2281 if(m_peerTSProcessor)
2285 if(m_auxTSProcessor)
2289 notifyPeerBasePTS =
false;
2291 if (ptsError && !dsmccDemuxerUsed && !basePtsUpdatedFromCurrentSegment)
2293 WARNING(
"PTS error, discarding segment");
2299 basePtsUpdatedFromCurrentSegment =
true;
2304 INFO(
"demuxAndSend : discarded packet with pid %d", pid);
2307 packetStart += PACKET_SIZE;
2319 pthread_mutex_lock(&m_mutex);
2322 AAMPLOG_WARN(
"TSProcessor[%p] - reset video demux %p",
this, m_vidDemuxer);
2323 m_vidDemuxer->
reset();
2328 AAMPLOG_WARN(
"TSProcessor[%p] - reset audio demux %p",
this, m_audDemuxer);
2329 m_audDemuxer->
reset();
2332 m_demuxInitialized =
false;
2333 m_basePTSFromPeer = -1;
2336 m_AudioTrackIndexToPlay = 0;
2337 pthread_mutex_unlock(&m_mutex);
2347 pthread_mutex_lock(&m_mutex);
2350 AAMPLOG_WARN(
"TSProcessor[%p] flush video demux %p",
this, m_vidDemuxer);
2351 m_vidDemuxer->
flush();
2356 AAMPLOG_WARN(
"TSProcessor[%p] flush audio demux %p",
this, m_audDemuxer);
2357 m_audDemuxer->
flush();
2362 AAMPLOG_WARN(
"TSProcessor[%p] flush dsmcc demux %p",
this, m_dsmccDemuxer);
2363 m_dsmccDemuxer->
flush();
2365 pthread_mutex_unlock(&m_mutex);
2373 WARNING(
"PC %p basepts %lld",
this, basepts);
2374 pthread_mutex_lock(&m_mutex);
2375 if (m_queuedSegment)
2377 if (-1 != updatedStartPositon)
2379 DEBUG(
"Update position from %f to %f", m_queuedSegmentPos, updatedStartPositon);
2380 m_queuedSegmentPos = updatedStartPositon;
2385 m_queuedSegmentPos, m_queuedSegmentDuration);
2393 if(!
demuxAndSend(m_queuedSegment, m_queuedSegmentLen, m_queuedSegmentPos, m_queuedSegmentDuration, m_queuedSegmentDiscontinuous ))
2395 AAMPLOG_WARN(
"demuxAndSend");
2400 ERROR(
"sendQueuedSegment invoked in Invalid stream operation");
2402 free(m_queuedSegment);
2403 m_queuedSegment = NULL;
2407 WARNING(
"No pending buffer");
2409 pthread_mutex_unlock(&m_mutex);
2417 pthread_mutex_lock(&m_mutex);
2418 m_basePTSFromPeer = pts;
2419 m_startPosition = position;
2420 INFO(
"pts = %lld", pts);
2423 m_audDemuxer->
flush();
2424 m_audDemuxer->
init(position, 0,
false,
true);
2426 m_demuxInitialized =
true;
2428 pthread_cond_signal(&m_basePTSCond);
2429 pthread_mutex_unlock(&m_mutex);
2438 bool insPatPmt =
false;
2439 unsigned char * packetStart;
2443 pthread_mutex_lock(&m_mutex);
2446 INFO(
"Not Enabled, Returning");
2447 pthread_mutex_unlock(&m_mutex);
2450 m_processing =
true;
2451 if ((m_playModeNext != m_playMode) || (m_playRateNext != m_playRate))
2453 TRACE1(
"change play mode");
2454 m_playMode = m_playModeNext;
2456 m_playRate = m_playRateNext;
2457 m_absPlayRate = fabs(m_playRate);
2458 INFO(
"playback changed to rate %f mode %d", m_playRate, m_playMode);
2459 m_haveEmittedIFrame =
false;
2460 m_currFrameOffset = -1LL;
2461 m_nullPFrameNextCount = 0;
2462 m_needDiscontinuity =
true;
2464 pthread_mutex_unlock(&m_mutex);
2465 m_framesProcessedInSegment = 0;
2466 m_lastPTSOfSegment = -1;
2467 packetStart = (
unsigned char *)segment;
2468 if ((packetStart[0] != 0x47) || ((packetStart[1] & 0x80) != 0x00) || ((packetStart[3] & 0xC0) != 0x00))
2470 ERROR(
"Segment doesn't starts with valid TS packet, discarding. Dump first packet");
2471 for (
int i = 0; i < PACKET_SIZE; i++)
2473 printf(
"0x%2x ", packetStart[i]);
2476 pthread_mutex_lock(&m_mutex);
2477 m_processing =
false;
2478 pthread_cond_signal(&m_throttleCond);
2479 pthread_mutex_unlock(&m_mutex);
2482 if (len % m_packetSize)
2484 int discardAtEnd = len % m_packetSize;
2485 INFO(
"Discarding %d bytes at end", discardAtEnd);
2486 len = len - discardAtEnd;
2488 ret =
processBuffer((
unsigned char*)packetStart, len, insPatPmt);
2491 if (-1.0 == m_startPosition)
2493 INFO(
"Reset m_startPosition to %f", position);
2494 m_startPosition = position;
2496 double updatedPosition = m_startPosition + (position - m_startPosition) / m_playRate;
2497 INFO(
"updatedPosition = %f Position = %f m_startPosition = %f m_playRate = %f", updatedPosition, position, m_startPosition, m_playRate);
2498 position = updatedPosition;
2500 if (m_needDiscontinuity&& !m_demux)
2504 if (insPatPmt && !m_demux)
2506 unsigned char *sec = (
unsigned char *)malloc(PATPMT_MAX_SIZE);
2513 TRACE1(
"Send PAT/PMT");
2522 pthread_mutex_lock(&m_mutex);
2523 if (-1 == m_basePTSFromPeer)
2527 AAMPLOG_WARN(
"TSProcessor[%p] wait for base PTS. m_audDemuxer %p",
this, m_audDemuxer);
2528 pthread_cond_wait(&m_basePTSCond, &m_mutex);
2533 INFO(
"Not Enabled, Returning");
2534 m_processing =
false;
2535 pthread_cond_signal(&m_throttleCond);
2536 pthread_mutex_unlock(&m_mutex);
2539 AAMPLOG_WARN(
"TSProcessor[%p] got base PTS. m_audDemuxer %p",
this, m_audDemuxer);
2541 pthread_mutex_unlock(&m_mutex);
2543 ret =
demuxAndSend(packetStart, len, m_startPosition, duration, discontinuous);
2547 ret =
demuxAndSend(packetStart, len, position, duration, discontinuous);
2551 WARNING(
"Sending Audio First");
2559 if (m_packetStartAfterFirstPTS != -1)
2562 aamp->
SendStreamCopy((
MediaType)m_track, packetStart, m_packetStartAfterFirstPTS, position, position, duration);
2565 len - m_packetStartAfterFirstPTS, position, position, duration);
2569 ERROR(
"m_packetStartAfterFirstPTS Not updated");
2571 len - m_packetStartAfterFirstPTS, position, position, duration);
2576 pthread_mutex_lock(&m_mutex);
2577 if (m_queuedSegment)
2579 ERROR(
"Queued buffer not NULL");
2580 free(m_queuedSegment);
2582 m_queuedSegment = (
unsigned char *)malloc(len);
2583 if (!m_queuedSegment)
2585 ERROR(
"Failed to allocate memory");
2589 memcpy(m_queuedSegment, packetStart, len);
2590 m_queuedSegmentLen = len;
2591 m_queuedSegmentPos = position;
2592 m_queuedSegmentDuration = duration;
2593 m_queuedSegmentDiscontinuous = discontinuous;
2595 pthread_mutex_unlock(&m_mutex);
2604 int durationMs = (int)(duration * 1000);
2607 pthread_mutex_lock(&m_mutex);
2608 m_processing =
false;
2609 pthread_cond_signal(&m_throttleCond);
2610 pthread_mutex_unlock(&m_mutex);
2614 #define HEADER_SIZE 4
2615 #define INDEX(i) (base+i < m_packetSize-m_ttsSize-HEADER_SIZE) ? i : i+m_ttsSize+HEADER_SIZE
2628 int unitType = (buffer[INDEX(3)] & 0x1F);
2638 if (buffer[INDEX(4)] & 0x80)
2642 unsigned char *p = &buffer[INDEX(4)];
2645 m_currSPSId = m_PPS[pic_parameter_set_id].spsId;
2646 pSPS = &m_SPS[m_currSPSId];
2648 if (pSPS->picOrderCountType == 0)
2650 if (pSPS->separateColorPlaneFlag)
2657 getBits(p, mask, pSPS->log2MaxFrameNumMinus4 + 4);
2659 if (!pSPS->frameMBSOnlyFlag)
2661 int field_pic_flag =
getBits(p, mask, 1);
2678 putBits(p, mask, pSPS->log2MaxPicOrderCntLsbMinus4 + 4, m_picOrderCount);
2679 m_picOrderCount = m_picOrderCount + 1;
2680 if (m_picOrderCount == pSPS->maxPicOrderCount)
2682 m_picOrderCount = 0;
2684 m_updatePicOrderCount =
false;
2685 m_scanForFrameSize =
false;
2698 bool scanForAspect =
false;
2699 bool splitSPS =
false;
2701 if (!m_emulationPrevention || (m_emulationPreventionCapacity < (m_emulationPreventionOffset + length)))
2703 unsigned char *newBuff = 0;
2704 int newSize = m_emulationPreventionCapacity * 2 + length;
2705 newBuff = (
unsigned char *)calloc(newSize,
sizeof(
char));
2708 ERROR(
"Error: unable to allocate emulation prevention buffer");
2711 if (m_emulationPrevention)
2713 if (m_emulationPreventionOffset > 0)
2715 rmf_osal_memcpy(newBuff, m_emulationPrevention, m_emulationPreventionOffset, newSize, m_emulationPreventionCapacity);
2717 free(m_emulationPrevention);
2719 m_emulationPreventionCapacity = newSize;
2720 m_emulationPrevention = newBuff;
2722 if (m_emulationPreventionOffset > 0)
2726 for (
int i = 4; i < length - 3; ++i)
2728 if ((buffer[INDEX(i)] == 0x00) && (buffer[INDEX(i + 1)] == 0x00))
2730 if (buffer[INDEX(i + 2)] == 0x01)
2732 scanForAspect =
true;
2735 else if (buffer[INDEX(i + 2)] == 0x03)
2737 m_emulationPrevention[m_emulationPreventionOffset++] = 0x00;
2738 m_emulationPrevention[m_emulationPreventionOffset++] = 0x00;
2742 m_emulationPrevention[m_emulationPreventionOffset++] = buffer[INDEX(i)];
2747 if (updateSPS && !splitSPS)
2749 int ppb = -1, pb = -1, b;
2751 while (i < m_emulationPreventionOffset)
2753 b = m_emulationPrevention[i];
2754 if ((ppb == 0) && (pb == 0) && (b == 1))
2762 buffer[INDEX(j)] = b;
2768 m_emulationPreventionOffset = 0;
2774 m_scanForFrameSize =
false;
2775 keepScanning =
false;
2783 bool processPPS =
false;
2785 if (!m_emulationPrevention || (m_emulationPreventionCapacity < (m_emulationPreventionOffset + length)))
2787 unsigned char *newBuff = 0;
2788 int newSize = m_emulationPreventionCapacity * 2 + length;
2789 newBuff = (
unsigned char *)malloc(newSize*
sizeof(
char));
2792 AAMPLOG_ERR(
"Error: unable to allocate emulation prevention buffer");
2795 if (m_emulationPrevention)
2797 if (m_emulationPreventionOffset > 0)
2799 rmf_osal_memcpy(newBuff, m_emulationPrevention, m_emulationPreventionOffset, newSize, m_emulationPreventionCapacity);
2801 free(m_emulationPrevention);
2803 m_emulationPreventionCapacity = newSize;
2804 m_emulationPrevention = newBuff;
2806 for (
int i = 4; i < length - 3; ++i)
2808 if ((buffer[INDEX(i)] == 0x00) && (buffer[INDEX(i + 1)] == 0x00))
2810 if (buffer[INDEX(i + 2)] == 0x01)
2815 else if (buffer[INDEX(i + 2)] == 0x03)
2817 m_emulationPrevention[m_emulationPreventionOffset++] = 0x00;
2818 m_emulationPrevention[m_emulationPreventionOffset++] = 0x00;
2822 m_emulationPrevention[m_emulationPreventionOffset++] = buffer[INDEX(i)];
2828 m_emulationPreventionOffset = 0;
2862 switch (buffer[INDEX(3)])
2867 m_frameWidth = (((int)buffer[INDEX(4)]) << 4) | (((int)buffer[INDEX(5)]) >> 4);
2868 m_frameHeight = ((((int)buffer[INDEX(5)]) & 0x0F) << 8) | ((
int)buffer[INDEX(6)]);
2869 if ((m_nullPFrameWidth != m_frameWidth) || (m_nullPFrameHeight != m_frameHeight))
2871 INFO(
"TSProcessor: sequence frame size %dx%d", m_frameWidth, m_frameHeight);
2873 keepScanning =
false;
2877 if ((buffer[INDEX(3)] >= 0x01) && (buffer[INDEX(3)] <= 0xAF))
2881 keepScanning =
false;
2895 unsigned char* packetEnd = packet + length;
2896 for (
int i = 0; i < length; i += m_packetSize)
2898 packet += m_ttsSize;
2900 int pid = (((packet[1] & 0x1F) << 8) | (packet[2] & 0xFF));
2901 int payloadStart = (packet[1] & 0x40);
2902 int adaptation = ((packet[3] & 0x30) >> 4);
2906 if (pid == m_pcrPid)
2908 if (adaptation & 0x02)
2910 payload += (1 + packet[4]);
2913 if (adaptation & 0x01)
2918 if ((packet[payload] == 0x00) && (packet[payload + 1] == 0x00) && (packet[payload + 2] == 0x01))
2920 int streamid = packet[payload + 3];
2921 int pesHeaderDataLen = packet[payload + 8];
2922 int tsbase = payload + 9;
2924 if ((streamid >= 0xE0) && (streamid <= 0xEF))
2927 m_scanForFrameSize =
true;
2929 if (packet[payload + 7] & 0x80)
2933 if (packet[payload + 7] & 0x40)
2937 payload = payload + 9 + pesHeaderDataLen;
2941 if (m_scanForFrameSize && (m_videoPid != -1) && (pid == m_videoPid))
2945 if (m_scanRemainderSize)
2947 unsigned char *remainder = m_scanRemainder;
2951 srcCapacity = packetEnd - (packet + payload);
2952 if (srcCapacity > 0)
2954 copyLen = m_scanRemainderLimit + (m_scanRemainderLimit - m_scanRemainderSize);
2955 if (copyLen > packetEnd - (packet + payload))
2957 INFO(
"scan copyLen adjusted from %d to %d", copyLen, (
int)(packetEnd - (packet + payload)));
2958 copyLen = packetEnd - (packet + payload);
2960 rmf_osal_memcpy(remainder + m_scanRemainderSize, packet + payload, copyLen, m_scanRemainderLimit * 3 - m_scanRemainderSize, packetEnd - (packet + payload));
2961 m_scanRemainderSize += copyLen;
2962 if (m_scanRemainderSize >= m_scanRemainderLimit * 2)
2964 for (j = 0; j < m_scanRemainderLimit; ++j)
2966 if ((remainder[j] == 0x00) && (remainder[j + 1] == 0x00) && (remainder[j + 2] == 0x01))
2968 processStartCode(&remainder[j], m_scanForFrameSize, 2 * m_scanRemainderLimit - j, j);
2972 m_scanRemainderSize = 0;
2977 m_scanRemainderSize = 0;
2978 INFO(
"TSProcessor::checkIfInterlaced: scan skipped");
2980 if (m_scanSkipPacketsEnabled){
2981 FILE *pFile = fopen(
"/opt/trick-scan.dat\n",
"wb");
2984 fwrite(packet, 1, m_packetSize - m_ttsSize, pFile);
2986 INFO(
"scan skipped: packet writing to /opt/trick-scan.dat");
2993 if (m_scanForFrameSize)
2997 jmax = m_packetSize - m_scanRemainderLimit - m_ttsSize;
2999 for (j = payload; j < jmax; ++j)
3001 if ((packet[j] == 0x00) && (packet[j + 1] == 0x00) && (packet[j + 2] == 0x01))
3005 if (!m_scanForFrameSize || m_isInterlacedKnown)
3012 if (m_scanForFrameSize)
3014 unsigned char* packetScanPosition = packet + m_packetSize - m_scanRemainderLimit - m_ttsSize;
3015 m_scanRemainderSize = m_scanRemainderLimit < packetEnd - packetScanPosition ? m_scanRemainderLimit : packetEnd - packetScanPosition;
3016 rmf_osal_memcpy(m_scanRemainder, packetScanPosition, m_scanRemainderSize, m_scanRemainderLimit * 3, packetEnd - packetScanPosition);
3023 if (m_isInterlacedKnown)
3028 packet += (m_packetSize - m_ttsSize);
3031 m_scanRemainderSize = 0;
3040 unsigned char *pidFilter;
3041 unsigned char* packetEnd = packet + length;
3043 if (m_isH264 && !m_isInterlacedKnown)
3046 TRACE1(
"m_isH264 = %s m_isInterlacedKnown = %s m_isInterlaced %s", m_isH264 ?
"true" :
"false",
3047 m_isInterlacedKnown ?
"true" :
"false", m_isInterlaced ?
"true" :
"false");
3052 float rm = ((m_isH264 && !m_isInterlaced) ? 1.0 : 2.0);
3054 if (!m_haveBaseTime) m_basePCR = -1LL;
3056 TRACE4(
"reTimestamp: packet %p length %d", packet, length);
3057 for (
int i = 0; i < length; i += m_packetSize)
3059 packet += m_ttsSize;
3061 int pid = (((packet[1] & 0x1F) << 8) | (packet[2] & 0xFF));
3062 int payloadStart = (packet[1] & 0x40);
3063 int adaptation = ((packet[3] & 0x30) >> 4);
3068 pidFilter = (m_trickExcludeAudio ? m_pidFilterTrick : m_pidFilter);
3069 if (!pidFilter[pid])
3072 packet[1] = ((packet[1] & 0xE0) | 0x1F);
3077 unsigned char byte3 = packet[3];
3080 packet[3] = ((byte3 & 0xF0) | (m_continuityCounters[pid]++ & 0x0F));
3085 if (pid == m_pcrPid)
3087 if (payloadStart) m_basePCR = -1LL;
3089 if (adaptation & 0x02)
3091 int adaptationFlags = packet[5];
3092 if (adaptationFlags & 0x10)
3094 long long timeOffset, timeOffsetBase, rateAdjustedPCR;
3097 if (!m_haveBaseTime)
3099 m_haveBaseTime =
true;
3101 m_segmentBaseTime = m_baseTime;
3102 INFO(
"have baseTime %llx from pid %x PCR", m_baseTime, pid);
3104 if (m_basePCR < 0) m_basePCR = PCR;
3107 rateAdjustedPCR = ((m_currRateAdjustedPTS - 10000) & 0x1FFFFFFFFLL);
3111 timeOffset = PCR - m_baseTime;
3112 if (m_playRate < 0.0)
3114 timeOffset = -timeOffset;
3117 timeOffsetBase = m_baseTime - m_basePCR;
3118 if (timeOffset < timeOffsetBase)
3122 timeOffset = timeOffsetBase + (timeOffsetBase - timeOffset);
3126 rateAdjustedPCR = (((
long long)(timeOffset / m_absPlayRate + 0.5) + m_segmentBaseTime) & 0x1FFFFFFFFLL);
3128 m_currRateAdjustedPCR = rateAdjustedPCR;
3132 payload += (1 + packet[4]);
3136 if (adaptation & 0x01)
3143 if ((packet[payload] == 0x00) && (packet[payload + 1] == 0x00) && (packet[payload + 2] == 0x01))
3145 int streamid = packet[payload + 3];
3146 int pesHeaderDataLen = packet[payload + 8];
3147 int tsbase = payload + 9;
3149 if ((streamid >= 0xE0) && (streamid <= 0xEF))
3154 m_scanForFrameSize =
true;
3157 m_updatePicOrderCount =
true;
3161 else if (((streamid >= 0xC0) && (streamid <= 0xDF)) || (streamid == 0xBD))
3166 long long timeOffset;
3167 long long PTS = 0, DTS;
3168 long long rateAdjustedPTS = 0, rateAdjustedDTS;
3169 bool validPTS =
false;
3170 if (packet[payload + 7] & 0x80)
3175 if (pid == m_pcrPid)
3177 m_pcrPerPTSCount = 0;
3181 m_haveBaseTime =
true;
3182 m_baseTime = ((PTS - ((
long long)(90000 / (m_apparentFrameRate*rm)))) & 0x1FFFFFFFFLL);
3183 m_segmentBaseTime = m_baseTime;
3184 TRACE2(
"have baseTime %llx from pid %x PTS", m_baseTime, pid);
3186 timeOffset = PTS - m_baseTime;
3187 if (m_playRate < 0) timeOffset = -timeOffset;
3190 long long interFrameDelay = 90000 / (m_apparentFrameRate*rm);
3191 if (!m_haveUpdatedFirstPTS)
3193 if (m_currRateAdjustedPCR != 0)
3195 rateAdjustedPTS = ((m_currRateAdjustedPCR + 10000) & 0x1FFFFFFFFLL);
3196 TRACE2(
"Updated rateAdjustedPTS to %lld m_currRateAdjustedPCR %lld", rateAdjustedPTS, m_currRateAdjustedPCR);
3200 rateAdjustedPTS = PTS;
3201 TRACE2(
"Updated rateAdjustedPTS to %lld m_currRateAdjustedPCR %lld", rateAdjustedPTS, m_currRateAdjustedPCR);
3203 m_haveUpdatedFirstPTS =
true;
3207 rateAdjustedPTS = ((m_currRateAdjustedPTS + interFrameDelay) & 0x1FFFFFFFFLL);
3208 TRACE2(
"Updated rateAdjustedPTS to %lld m_currRateAdjustedPTS %lld interFrameDelay %lld", rateAdjustedPTS, m_currRateAdjustedPTS, interFrameDelay);
3210 if (m_framesProcessedInSegment > 0)
3212 TRACE4(
"Not incrementing pts with interFrameDelay as already done for the segment");
3213 if (m_playRate != 0)
3215 rateAdjustedPTS = m_currRateAdjustedPTS + ((PTS - m_lastPTSOfSegment) / m_playRate);
3219 rateAdjustedPTS = m_currRateAdjustedPTS + (PTS - m_lastPTSOfSegment);
3225 long long rateAdjustedPCR = ((rateAdjustedPTS - 10000) & 0x1FFFFFFFFLL);
3227 m_currRateAdjustedPCR = rateAdjustedPCR;
3230 m_currRateAdjustedPTS = rateAdjustedPTS;
3234 rateAdjustedPTS = (((
long long)(timeOffset / m_absPlayRate + 0.5) + m_segmentBaseTime) & 0x1FFFFFFFFLL);
3236 if (pid == m_pcrPid)
3238 m_throttlePTS = rateAdjustedPTS;
3239 TRACE2(
"Updated throttlePTS to %lld", m_throttlePTS.value);
3241 writeTimeStamp(&packet[tsbase], packet[tsbase] >> 4, rateAdjustedPTS);
3242 m_lastPTSOfSegment = PTS;
3243 m_framesProcessedInSegment++;
3245 TRACE2(
"rateAdjustedPTS %lld (%lld ms)", rateAdjustedPTS, rateAdjustedPTS / 90);
3249 if (packet[payload + 7] & 0x40)
3253 bool validDTS =
false;
3256 rateAdjustedDTS = rateAdjustedPTS - (2 * 750);
3264 timeOffset = DTS - m_baseTime;
3265 if (m_playRate < 0) timeOffset = -timeOffset;
3266 rateAdjustedDTS = (((
long long)(timeOffset / m_absPlayRate + 0.5) + m_segmentBaseTime) & 0x1FFFFFFFFLL);
3271 writeTimeStamp(&packet[tsbase], packet[tsbase] >> 4, rateAdjustedDTS);
3276 if (packet[payload + 7] & 0x02)
3279 WARNING(
"Warning: PES packet has CRC flag set");
3281 payload = payload + 9 + pesHeaderDataLen;
3285 if (m_scanForFrameSize && (m_videoPid != -1) && (pid == m_videoPid))
3289 if (m_scanRemainderSize)
3291 unsigned char *remainder = m_scanRemainder;
3295 srcCapacity = packetEnd - (packet + payload);
3296 if (srcCapacity > 0)
3298 copyLen = 2 * m_scanRemainderLimit + (m_scanRemainderLimit - m_scanRemainderSize);
3299 if (copyLen > packetEnd - (packet + payload))
3301 INFO(
"scan copyLen adjusted from %d to %d", copyLen, (
int)(packetEnd - (packet + payload)));
3302 copyLen = packetEnd - (packet + payload);
3304 rmf_osal_memcpy(remainder + m_scanRemainderSize, packet + payload, copyLen, m_scanRemainderLimit * 3 - m_scanRemainderSize, packetEnd - (packet + payload));
3305 m_scanRemainderSize += copyLen;
3307 if (m_scanRemainderSize >= m_scanRemainderLimit * 3)
3309 for (j = 0; j < m_scanRemainderLimit; ++j)
3311 if ((remainder[j] == 0x00) && (remainder[j + 1] == 0x00) && (remainder[j + 2] == 0x01))
3313 processStartCode(&remainder[j], m_scanForFrameSize, 3 * m_scanRemainderLimit - j, j);
3314 rmf_osal_memcpy(packet + payload, remainder + m_scanRemainderLimit, 2 * m_scanRemainderLimit, packetEnd - (packet + payload), m_scanRemainderLimit * 3 - m_scanRemainderLimit);
3318 m_scanRemainderSize = 0;
3323 m_scanRemainderSize = 0;
3324 INFO(
"TSProcessor::reTimestamp: scan skipped");
3326 if (m_scanSkipPacketsEnabled){
3327 FILE *pFile = fopen(
"/opt/trick-scan.dat",
"wb");
3330 fwrite(packet, 1, m_packetSize - m_ttsSize, pFile);
3332 INFO(
"scan skipped: packet writing to /opt/trick-scan.dat");
3339 if (m_scanForFrameSize)
3343 jmax = m_packetSize - m_scanRemainderLimit - m_ttsSize;
3345 for (j = payload; j < jmax; ++j)
3347 if ((packet[j] == 0x00) && (packet[j + 1] == 0x00) && (packet[j + 2] == 0x01))
3351 if (!m_scanForFrameSize)
3358 if (m_scanForFrameSize)
3360 unsigned char* packetScanPosition = packet + m_packetSize - m_scanRemainderLimit - m_ttsSize;
3361 if (packetScanPosition < packetEnd)
3363 m_scanRemainderSize = m_scanRemainderLimit < packetEnd - packetScanPosition ? m_scanRemainderLimit : packetEnd - packetScanPosition;
3367 INFO(
"Scan reached out of bound packet packetScanPosition=%p", packetScanPosition);
3368 m_scanRemainderSize = 0;
3369 packetScanPosition = packetEnd;
3371 rmf_osal_memcpy(m_scanRemainder, packetScanPosition, m_scanRemainderSize, m_scanRemainderLimit * 3, packetEnd - packetScanPosition);
3381 if (m_currRateAdjustedPCR <= m_prevRateAdjustedPCR)
3383 m_currRateAdjustedPCR = ((
long long)(m_currRateAdjustedPCR + (90000 / (m_apparentFrameRate*rm) + m_pcrPerPTSCount * 8)) & 0x1FFFFFFFFLL);
3385 TRACE2(
"m_currRateAdjustedPCR %lld(%lld ms) diff %lld ms", m_currRateAdjustedPCR, m_currRateAdjustedPCR / 90, (m_currRateAdjustedPCR - m_prevRateAdjustedPCR) / 90);
3386 m_prevRateAdjustedPCR = m_currRateAdjustedPCR;
3387 writePCR(&packet[6], m_currRateAdjustedPCR, ((m_absPlayRate >= 4.0) ?
true :
false));
3389 packet += (m_packetSize - m_ttsSize);
3400 INFO(
"setting playback mode to %s", (mode ==
PlayMode_normal) ?
"PlayMode_normal" :
3404 "PlayMode_reverse_GOP");
3405 m_playModeNext = mode;
3415 pthread_cond_signal(&m_basePTSCond);
3416 while (m_processing)
3418 pthread_cond_signal(&m_throttleCond);
3419 INFO(
"Waiting for processing to end");
3420 pthread_cond_wait(&m_throttleCond, &m_mutex);
3429 pthread_mutex_lock(&m_mutex);
3431 pthread_mutex_unlock(&m_mutex);
3441 pthread_mutex_lock(&m_mutex);
3445 m_playRateNext = rate;
3446 INFO(
"set playback rate to %f", m_playRateNext);
3449 m_startPosition = -1.0;
3450 m_last_frame_time = 0;
3451 pthread_mutex_unlock(&m_mutex);
3459 INFO(
"TSProcessor::setThrottleEnable enable=%d", enable);
3460 m_throttle = enable;
3468 bool result =
false;
3470 int prognum, pmtVersion, pmtPid, pcrPid;
3471 int pmtSectionLen = 0;
3473 int audioComponentCount;
3479 INFO(
"Got audioComponents from audio track. audioComponentCount %d", audioComponentCount);
3483 audioComponentCount = this->audioComponentCount;
3484 audioComponents = this->audioComponents;
3493 if (videoComponentCount == 0)
3495 DEBUG(
"no video, so keep audio in trick mode PMT");
3498 if ((videoComponentCount == 0) && (audioComponentCount == 0))
3500 ERROR(
"generatePATandPMT: insufficient stream information - no PAT/PMT?");
3503 if (videoComponentCount > 0)
3506 m_scanRemainderLimit = (m_isH264 ? SCAN_REMAINDER_SIZE_H264 : SCAN_REMAINDER_SIZE_MPEG2);
3509 if (pmtVersion == -1)
3515 pcrPidFound =
false;
3519 for (pmtPid = 0x10; pmtPid < 0x1fff; ++pmtPid)
3521 if (pmtPid == pcrPid)
3525 for (i = 0; i < videoComponentCount; ++i)
3527 if (pcrPid == videoComponents[i].pid) pcrPidFound =
true;
3528 if (pmtPid == videoComponents[i].pid)
break;
3530 if (i < videoComponentCount)
continue;
3534 for (i = 0; i < audioComponentCount; ++i)
3536 if (pcrPid == audioComponents[i].pid) pcrPidFound =
true;
3537 if (pmtPid == audioComponents[i].pid)
break;
3541 INFO(
"It is possibly MC Channel..");
3542 m_isMCChannel =
true;
3544 if (i < audioComponentCount)
continue;
3552 for (i = 0; i < videoComponentCount; ++i)
3554 if (pcrPid == videoComponents[i].pid) pcrPidFound =
true;
3557 if ((!trick) && (!pcrPidFound))
3559 for (i = 0; i < audioComponentCount; ++i)
3561 if (pcrPid == audioComponents[i].pid) pcrPidFound =
true;
3565 INFO(
"It is possibly MC Channel..");
3566 m_isMCChannel =
true;
3571 if (bHandleMCTrick && (!trick))
3573 DEBUG(
"For MC channel where in audio is the PCR PID, ensure that VID PID is used as PCR PID during trick mode and change the PMT Version.");
3574 pcrPidFound =
false;
3583 INFO(
"If it is MC channel where in audio is the PCR PID && trick is true (ie no audio during trick), then the VID PID will become new PCR PID; So update the PMT Version by 1");
3590 if (videoComponentCount)
3592 pcrPid = videoComponents[0].
pid;
3594 else if (!trick && audioComponentCount)
3596 pcrPid = audioComponents[0].
pid;
3604 if ((pmtPid < 0x1fff) && (pcrPid < 0x1fff))
3606 DEBUG(
"using pmt pid %04x pcr pid %04X", pmtPid, pcrPid);
3610 int pmtSize = 17 + m_ttsSize;
3611 pmtSize += videoComponentCount * 5;
3614 for (i = 0; i < audioComponentCount; ++i)
3617 int nameLen = audioComponents[i].
associatedLanguage ? strlen(audioComponents[i].associatedLanguage) : 0;
3620 pmtSize += (3 + nameLen);
3627 DEBUG(
"pmt payload size %d bytes", pmtSize);
3628 int pmtPacketCount = 1;
3629 i = pmtSize - (m_packetSize - 17 - m_ttsSize);
3633 i -= (m_packetSize - m_ttsSize - 4 - 4);
3635 if (pmtPacketCount > 1)
3637 WARNING(
"================= pmt requires %d packets =====================", pmtPacketCount);
3640 int patpmtLen = (pmtPacketCount + 1)*m_packetSize*
sizeof(
unsigned char);
3641 unsigned char *patpmt = (
unsigned char*)malloc(patpmtLen);
3642 TRACE1(
"patpmtLen %d, patpmt %p", patpmtLen, patpmt);
3648 unsigned char *patPacket = &patpmt[0];
3660 memset(patPacket, 0, m_ttsSize);
3663 patPacket[i + 0] = 0x47;
3664 patPacket[i + 1] = 0x60;
3665 patPacket[i + 2] = 0x00;
3666 patPacket[i + 3] = 0x10;
3668 patPacket[i + 4] = 0x00;
3669 patPacket[i + 5] = 0x00;
3670 patPacket[i + 6] = 0xB0;
3671 patPacket[i + 7] = 0x0D;
3673 patPacket[i + 8] = 0x00;
3674 patPacket[i + 9] = 0x01;
3676 temp = version << 1;
3678 patPacket[i + 10] = 0xC1 | temp;
3680 patPacket[i + 11] = 0x00;
3681 patPacket[i + 12] = 0x00;
3684 patPacket[i + 13] = (prognum >> 8) & 0xFF;
3685 patPacket[i + 14] = prognum & 0xFF;
3689 patPacket[i + 15] = 0xE0;
3691 patPacket[i + 15] |= (
unsigned char)((pmtPid >> 8) & 0x1F);
3693 patPacket[i + 16] = (
unsigned char)(0xFF & pmtPid);
3697 patPacket[i + 17] = (crc >> 24) & 0xFF;
3698 patPacket[i + 18] = (crc >> 16) & 0xFF;
3699 patPacket[i + 19] = (crc >> 8) & 0xFF;
3700 patPacket[i + 20] = crc & 0xFF;
3703 for (i = 21 + m_ttsSize; i < m_packetSize; i++)
3705 patPacket[i] = 0xFF;
3709 unsigned char *pmtPacket = &patpmt[m_packetSize];
3714 memset(pmtPacket, 0, m_ttsSize);
3717 pmtPacket[i + 0] = 0x47;
3718 pmtPacket[i + 1] = 0x60;
3719 pmtPacket[i + 1] |= (
unsigned char)((pmtPid >> 8) & 0x1F);
3720 pmtPacket[i + 2] = (
unsigned char)(0xFF & pmtPid);
3721 pmtPacket[i + 3] = 0x10;
3723 pmtSectionLen = pmtSize - m_ttsSize - 8;
3724 pmtPacket[i + 4] = 0x00;
3725 pmtPacket[i + 5] = 0x02;
3726 pmtPacket[i + 6] = (0xB0 | ((pmtSectionLen >> 8) & 0xF));
3727 pmtPacket[i + 7] = (pmtSectionLen & 0xFF);
3730 pmtPacket[i + 8] = (prognum >> 8) & 0xFF;
3731 pmtPacket[i + 9] = prognum & 0xFF;
3733 temp = pmtVersion << 1;
3735 pmtPacket[i + 10] = 0xC1 | temp;
3737 pmtPacket[i + 11] = 0x00;
3738 pmtPacket[i + 12] = 0x00;
3740 pmtPacket[i + 13] = 0xE0;
3741 pmtPacket[i + 13] |= (
unsigned char)((pcrPid >> 8) & 0x1F);
3742 pmtPacket[i + 14] = (
unsigned char)(0xFF & pcrPid);
3743 pmtPacket[i + 15] = 0xF0;
3744 pmtPacket[i + 16] = 0x00;
3748 for (j = 0; j < videoComponentCount; ++j)
3750 int videoPid = videoComponents[j].
pid;
3751 m_videoPid = videoPid;
3752 putPmtByte(pmtPacket, pi, videoComponents[j].elemStreamType, pmtPid);
3753 byte = (0xE0 | (
unsigned char)((videoPid >> 8) & 0x1F));
3755 byte = (
unsigned char)(0xFF & videoPid);
3762 for (j = 0; j < audioComponentCount; ++j)
3764 int audioPid = audioComponents[j].
pid;
3765 int nameLen = audioComponents[j].
associatedLanguage ? strlen(audioComponents[j].associatedLanguage) : 0;
3766 putPmtByte(pmtPacket, pi, audioComponents[j].elemStreamType, pmtPid);
3767 byte = (0xE0 | (
unsigned char)((audioPid >> 8) & 0x1F));
3769 byte = (
unsigned char)(0xFF & audioPid);
3774 putPmtByte(pmtPacket, pi, (3 + nameLen), pmtPid);
3776 putPmtByte(pmtPacket, pi, (1 + nameLen), pmtPid);
3777 for (
int k = 0; k < nameLen; ++k)
3779 putPmtByte(pmtPacket, pi, audioComponents[j].associatedLanguage[k], pmtPid);
3786 unsigned char *crcData = &patpmt[m_packetSize + m_ttsSize + 5];
3787 int crcLenTotal = pmtSize - m_ttsSize - 5 - 4;
3788 int crcLen = ((crcLenTotal > (m_packetSize - m_ttsSize - 5)) ? (m_packetSize - m_ttsSize - 5) : crcLenTotal);
3794 crcLenTotal -= crcLen;
3795 if (crcLenTotal < crcLen)
3797 crcLen = crcLenTotal;
3800 putPmtByte(pmtPacket, pi, ((crc >> 24) & 0xFF), pmtPid);
3801 putPmtByte(pmtPacket, pi, ((crc >> 16) & 0xFF), pmtPid);
3802 putPmtByte(pmtPacket, pi, ((crc >> 8) & 0xFF), pmtPid);
3803 putPmtByte(pmtPacket, pi, (crc & 0xFF), pmtPid);
3806 for (i = pi; i < m_packetSize; i++)
3808 pmtPacket[i] = 0xFF;
3811 TRACE1(
"generated PAT and PMT:");
3814 *buflen = patpmtLen;
3821 memset(m_pidFilterTrick, 0,
sizeof(m_pidFilterTrick));
3822 TRACE1(
"pass pat %04x, pmt %04x pcr %04x", 0, pmtPid, pcrPid);
3823 m_pidFilterTrick[pcrPid] = 1;
3824 for (i = 0; i < videoComponentCount; ++i)
3826 int videoPid = videoComponents[i].
pid;
3827 TRACE1(
"video %04x", videoPid);
3828 m_pidFilterTrick[videoPid] = 1;
3836 memset(m_pidFilter, 0,
sizeof(m_pidFilter));
3837 TRACE1(
"pass pat %04x, pcr %04x", 0, pcrPid);
3838 m_pidFilter[pcrPid] = 1;
3839 for (i = 0; i < videoComponentCount; ++i)
3841 int videoPid = videoComponents[i].
pid;
3842 TRACE1(
"video %04x", videoPid);
3843 m_pidFilter[videoPid] = 1;
3845 for (i = 0; i < audioComponentCount; ++i)
3847 int audioPid = audioComponents[i].
pid;
3848 TRACE1(
"audio %04x", audioPid);
3849 m_pidFilter[audioPid] = 1;
3858 m_patCounter = m_pmtCounter = 0;
3860 INFO(
"TSProcessor::generatePATandPMT: trick %d prognum %d pmtpid: %X pcrpid: %X pmt section len %d video %d audio %d",
3861 trick, prognum, pmtPid, pcrPid, pmtSectionLen,
3862 videoComponentCount, audioComponentCount);
3873 pmt[index++] = byte;
3874 if (index > m_packetSize - 1)
3876 pmt += m_packetSize;
3880 memset(pmt, 0, m_ttsSize);
3884 pmt[i + 1] = (
unsigned char)((pmtPid >> 8) & 0x1F);
3885 pmt[i + 2] = (
unsigned char)(0xFF & pmtPid);
3909 if ((p[4] & 0x01) != 1)
3912 WARNING(
"TS:============ TS p[4] bit 0 not 1");
3914 if ((p[2] & 0x01) != 1)
3917 WARNING(
"TS:============ TS p[2] bit 0 not 1");
3919 if ((p[0] & 0x01) != 1)
3922 WARNING(
"TS:============ TS p[0] bit 0 not 1");
3924 switch ((p[0] & 0xF0) >> 4)
3932 WARNING(
"TS:============ TS p[0] YYYY bits have value %X", p[0]);
3936 TS = ((((
long long)(p[0] & 0x0E)) << 30) >> 1) |
3937 (((
long long)(p[1] & 0xFF)) << 22) |
3938 ((((
long long)(p[2] & 0xFE)) << 15) >> 1) |
3939 (((
long long)(p[3] & 0xFF)) << 7) |
3940 (((
long long)(p[4] & 0xFE)) >> 1);
3950 p[0] = (((prefix & 0xF) << 4) | (((TS >> 30) & 0x7) << 1) | 0x01);
3951 p[1] = ((TS >> 22) & 0xFF);
3952 p[2] = ((((TS >> 15) & 0x7F) << 1) | 0x01);
3953 p[3] = ((TS >> 7) & 0xFF);
3954 p[4] = ((((TS)& 0x7F) << 1) | 0x01);
3962 long long PCR = (((
long long)(p[0] & 0xFF)) << (33 - 8)) |
3963 (((
long long)(p[1] & 0xFF)) << (33 - 8 - 8)) |
3964 (((
long long)(p[2] & 0xFF)) << (33 - 8 - 8 - 8)) |
3965 (((
long long)(p[3] & 0xFF)) << (33 - 8 - 8 - 8 - 8)) |
3966 (((
long long)(p[4] & 0xFF)) >> 7);
3975 p[0] = ((PCR >> (33 - 8)) & 0xFF);
3976 p[1] = ((PCR >> (33 - 8 - 8)) & 0xFF);
3977 p[2] = ((PCR >> (33 - 8 - 8 - 8)) & 0xFF);
3978 p[3] = ((PCR >> (33 - 8 - 8 - 8 - 8)) & 0xFF);
3979 if (!clearExtension)
3981 p[4] = ((PCR & 0x01) << 7) | (p[4] & 0x7F);
3985 p[4] = ((PCR & 0x01) << 7) | (0x7E);
3995 AAMPLOG_INFO(
"m_applyOffset=%s",enable?
"TRUE":
"FALSE");
3996 m_applyOffset = enable;
4046 static unsigned char nullPFrameHeader[] =
4048 0x47, 0x40, 0x00, 0x10, 0x00, 0x00, 0x01, 0xE0,
4049 0x00, 0x00, 0x84, 0xC0, 0x0A, 0x31, 0x00, 0x01,
4050 0x00, 0x01, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00,
4051 0x00, 0x01, 0x00, 0x01, 0xD7, 0xFF, 0xFB, 0x80,
4052 0x00, 0x00, 0x01, 0xB5, 0x83, 0x3F, 0xF3, 0x5D,
4056 #define FLUSH_SLICE_BITS() \
4057 while ( bitcount > 8 ) \
4059 slice[i]= (((accum<<(32-bitcount))>>24)&0xFF); \
4063 #define FLUSH_ALL_SLICE_BITS() \
4064 while ( bitcount > 0 ) \
4066 slice[i]= (((accum<<(32-bitcount))>>24)&0xFF); \
4077 unsigned char *nullPFrame = 0;
4078 int requiredLen = 0;
4079 int blockWidth, skipWidth, escapeCount;
4080 int skipCode, skipCodeNumBits;
4081 int sliceBitLen, sliceLen, sliceCount;
4083 unsigned char slice[16];
4084 int i, j, accum, bitcount;
4087 requiredLen =
sizeof(nullPFrameHeader) - 4;
4089 blockWidth = (width + 15) / 16;
4090 skipWidth = blockWidth - 1;
4092 while (skipWidth > 33)
4097 skipCodeNumBits = macroblockAddressIncrementCodes[skipWidth - 1].numBits;
4098 skipCode = macroblockAddressIncrementCodes[skipWidth - 1].code;
4107 sliceBitLen += (escapeCount * 11 + skipCodeNumBits);
4113 if ((sliceBitLen % 8) == 0) ++sliceBitLen;
4116 sliceLen = (sliceBitLen + 7) / 8;
4119 sliceCount = (height + 15) / 16;
4122 requiredLen += sliceCount*sliceLen;
4126 while (requiredLen > 0)
4129 requiredLen += (4 + m_ttsSize);
4130 requiredLen -= m_packetSize;
4145 for (j = 0; j < escapeCount; ++j)
4152 accum <<= skipCodeNumBits;
4154 bitcount += skipCodeNumBits;
4168 FLUSH_ALL_SLICE_BITS();
4169 assert(i == sliceLen);
4172 nullPFrame = (
unsigned char *)malloc(numTSPackets*m_packetSize);
4177 memset(&nullPFrame[i], 0, m_ttsSize);
4180 rmf_osal_memcpy(&nullPFrame[i], nullPFrameHeader,
sizeof(nullPFrameHeader), numTSPackets*m_packetSize - i,
sizeof(nullPFrameHeader));
4181 nullPFrame[i + 1] = ((nullPFrame[i + 1] & 0xE0) | ((m_videoPid >> 8) & 0x1F));
4182 nullPFrame[i + 2] = (m_videoPid & 0xFF);
4183 i +=
sizeof(nullPFrameHeader);
4184 for (j = 1; j <= sliceCount; ++j)
4186 slice[3] = (j & 0xFF);
4187 rmf_osal_memcpy(&nullPFrame[i], slice, sliceLen, numTSPackets*m_packetSize - i, 16);
4189 if ((i%m_packetSize) < sliceLen)
4191 int excess = (i%m_packetSize);
4192 memmove(&nullPFrame[i - excess + m_ttsSize + 4], &nullPFrame[i - excess], excess);
4195 memset(&nullPFrame[i - excess], 0, m_ttsSize);
4198 nullPFrame[i - excess + 0] = 0x47;
4199 nullPFrame[i - excess + 1] = ((m_videoPid >> 8) & 0xFF);
4200 nullPFrame[i - excess + 2] = (m_videoPid & 0xFF);
4201 nullPFrame[i - excess + 3] = 0x10;
4205 memset(&nullPFrame[i], 0xFF, m_packetSize - (i%m_packetSize));
4208 for (i = 0; i < numTSPackets; ++i)
4210 dumpPacket(&nullPFrame[i*m_packetSize], m_packetSize);
4214 *nullPFrameLen = (numTSPackets*m_packetSize);
4228 bool result =
false;
4230 int seq_parameter_set_id;
4248 m_SPS[seq_parameter_set_id].separateColorPlaneFlag = 0;
4249 switch (profile_idc)
4251 case 44:
case 83:
case 86:
4252 case 100:
case 110:
case 118:
4253 case 122:
case 128:
case 244:
4256 if (chroma_format_idx == 3)
4259 m_SPS[seq_parameter_set_id].separateColorPlaneFlag =
getBits(p, mask, 1);
4268 int seq_scaling_matrix_present_flag =
getBits(p, mask, 1);
4269 if (seq_scaling_matrix_present_flag)
4271 int imax = ((chroma_format_idx != 3) ? 8 : 12);
4272 for (
int i = 0; i < imax; ++i)
4274 int seq_scaling_list_present_flag =
getBits(p, mask, 1);
4275 if (seq_scaling_list_present_flag)
4294 m_SPS[seq_parameter_set_id].log2MaxFrameNumMinus4 = log2_max_frame_num_minus4;
4297 m_SPS[seq_parameter_set_id].picOrderCountType = pic_order_cnt_type;
4298 if (pic_order_cnt_type == 0)
4301 int log2_max_pic_order_cnt_lsb_minus4 =
getUExpGolomb(p, mask);
4302 m_SPS[seq_parameter_set_id].log2MaxPicOrderCntLsbMinus4 = log2_max_pic_order_cnt_lsb_minus4;
4303 m_SPS[seq_parameter_set_id].maxPicOrderCount = (2 << (log2_max_pic_order_cnt_lsb_minus4 + 4));
4305 else if (pic_order_cnt_type == 1)
4314 int num_ref_frames_in_pic_order_cnt_cycle =
getUExpGolomb(p, mask);
4315 for (
int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i)
4330 int pic_height_in_map_units_minus1 =
getUExpGolomb(p, mask);
4332 int frame_mbs_only_flag =
getBits(p, mask, 1);
4333 m_SPS[seq_parameter_set_id].frameMBSOnlyFlag = frame_mbs_only_flag;
4335 m_frameWidth = (pic_width_in_mbs_minus1 + 1) * 16;
4337 m_frameHeight = (pic_height_in_map_units_minus1 + 1) * 16;
4339 m_isInterlaced = (frame_mbs_only_flag == 0);
4340 m_isInterlacedKnown =
true;
4346 if (!frame_mbs_only_flag)
4357 int frame_cropping_flag =
getBits(p, mask, 1);
4358 if (frame_cropping_flag)
4370 int vui_parameters_present_flag =
getBits(p, mask, 1);
4371 if (vui_parameters_present_flag)
4373 int aspect_ratio_info_present_flag =
getBits(p, mask, 1);
4374 if (aspect_ratio_info_present_flag)
4376 int aspect_ratio_idc =
getBits(p, mask, 8);
4379 int overscan_info_present_flag =
getBits(p, mask, 1);
4380 if (overscan_info_present_flag)
4386 int video_signal_type_present_flag =
getBits(p, mask, 1);
4387 if (video_signal_type_present_flag)
4393 int color_description_present_flag =
getBits(p, mask, 1);
4394 if (color_description_present_flag)
4405 int chroma_info_present_flag =
getBits(p, mask, 1);
4406 if (chroma_info_present_flag)
4414 int timing_info_present_flag =
getBits(p, mask, 1);
4415 if (timing_info_present_flag)
4417 unsigned char *timeScaleP;
4423 timeScaleMask = mask;
4428 unsigned int trick_time_scale = m_apparentFrameRate * 2 * 1000;
4429 DEBUG(
"put trick_time_scale=%d at %p mask %X", trick_time_scale, timeScaleP, timeScaleMask);
4430 putBits(timeScaleP, timeScaleMask, 32, trick_time_scale);
4438 TRACE2(
"TSProcessor: H.264 sequence frame size %dx%d interlaced=%d update SPS %d", m_frameWidth, m_frameHeight, m_isInterlaced, result);
4449 int pic_parameter_set_id;
4450 int seq_parameter_set_id;
4456 pPPS = &m_PPS[pic_parameter_set_id];
4457 pPPS->spsId = seq_parameter_set_id;
4467 for (
int j = 0; j < size; ++j)
4472 nextScale = (lastScale + deltaScale + 256) % 256;
4474 lastScale = (nextScale == 0) ? lastScale : nextScale;
4508 unsigned int putmask;
4510 putmask = (1 << (bitCount - 1));
4515 if (value & putmask)
4535 int leadingZeros = 0;
4540 bitClear = !(*p & mask);
4550 codeNum += (factor >> 1);
4556 codeNum +=
getBits(p, mask, leadingZeros);
4567 int n = (u + 1) >> 1;
4580 count = audioComponentCount;
4581 *audioComponentsPtr = audioComponents;
4588 void TSProcessor::ChangeMuxedAudioTrack(
unsigned char index)
4590 pthread_mutex_lock(&m_mutex);
4591 AAMPLOG_WARN(
"Track changed from %d to %d", m_AudioTrackIndexToPlay, index);
4592 m_AudioTrackIndexToPlay = index;
4593 pthread_mutex_unlock(&m_mutex);
4600 int TSProcessor::SelectAudioIndexToPlay()
4604 for(
int i=0; i<audioComponentCount ; i++)
4607 std::string trackLanguage;
4608 if(audioComponents[i].associatedLanguage)
4637 score += audioFormat;
4641 AAMPLOG_TRACE(
"TSProcessor > track#%d score = %d lang : %s", i+1, score, trackLanguage.c_str());
4642 if(score > bestScore)
4659 bool ignoreProfile =
false;
4661 bool bDisableAC3 = bDisableEC3;
4666 switch (audioFormat)
4671 ignoreProfile =
true;
4678 ignoreProfile =
true;
4685 ignoreProfile =
true;
4693 return ignoreProfile;
4713 m_audioGroupId = id;