Exemplo n.º 1
0
BOOL
parse_TS(BYTE *ts_stream)
{
	uint8_t tsph.sync = TS_SYNC_BYTE(ts_stream);
	if(tsph.sync != 0x47){
		debuglog("sync bytes missed!");
		return FALSE;
	}
	tsph.transport_error_indicator = TS_ERROR(ts_stream);
	tsph.payload_uint_start_indicator = TS_PAYLOAD_START(ts_stream);
	tsph.transport_priority = TS_PRIORITY(ts_stream);
	tsph.PID = TS_PID(ts_stream);
	tsph.transport_scrambling = TS_SCRAMBLING(ts_stream);
	tsph.adaptation_field_control = TS_ADAPT_CTL(ts_stream);
	tsph.continuity_counter = TS_CONT_COUNT(ts_stream);

	debuglog("ts:transport_error_indicator:%d\n
			payload_uint_start_indicator:%d\n
			transport_priority:%d\n
			PID:%d\n
			transport_scrambling:%d\n
			continuity_counter:%d\n",
			tsph.transport_error_indicator,
			tsph.payload_uint_start_indicator,
			tsph.transport_priority,
			tsph.PID,
			tsph.transport_scrambling,
			tsph.continuity_counter);

	if(!tsph.transport_error_indicator)
	{
		int len = 0;
		len += 4;

		if(is_psi(tsph.PID))
		{
			if(tsph.payload_uint_start_indicator == 1)
			{
				tsph.pointer_field = TS_POINTER_FIELD(ts_stream + len);
				len = len + tsph.pointer_field + 1;
			}
			else
			{
				/*TS包的净荷不带有PSI/SI包数据的第一个字节,没有pointer_field
				 *psi/si信息跨越两个ts包,不解析
				 */
				debuglog("此ts包是另一个psi/si表未完部分,暂为解析");
				return FALSE;
			}

			switch(tsph.adaptation_field_control)
			{
				case 0x03:
					/* 有adaptation,也有净荷 */
					tsph.adaptation_fields = (tsadaptation_filed *)malloc(sizeof(tsadaptation_filed));
					if(!tsph.adaptation_fields)
					{
						debuglog("malloc tsph.adaptation_field failed");
						return FALSE;
					}
					tsph.adaptation_fields->adapt_field_len = TS_ADAPT_LEN(ts_stream);
					len = len + tsph.adaptation_fields->adapt_field_len + 1; /* adapt_field_len表示在它后面的数据的长度 */
					break;
				case 0x01:/* 只有净荷数据 */
				case 0x02:/* 只有adaptation */
				case 0x00:/* 保留 */
				default:
					break;
			}

			BYTE* sec_start = ts_stream + len;	/* psi/si表起始位置 */

			switch(tsph.PID)
			{
				/* todo:对不同的错误可以给一个错误号 */
				case 0x0000:
					if(!parse_PAT(sec_start))
					{
						debuglog("parse pat failed!check log...");
						return FALSE;
					}
					break;
				case 0x0001:
					if(!parse_CAT(sec_start))
					{
						debuglog("parse cat failed!check log...");
						return FALSE;
					}
					break;
				case 0x0010:
					if(!parse_NIT(sec_start))
					{
						debuglog("parse nit failed!check log...");
						return FALSE;
					}
					break;
				case 0x0011:
					if(!parse_SDT(sec_start))
					{
						debuglog("parse sdt failed!check log...");
						return FALSE;
					}
					break;
				case 0x0012:
					if(!parse_EIT(sec_start))
					{
						debuglog("parse eit failed!check log...");
						return FALSE;
					}
					break;
				case 0x0014:
	//				parse_TDT();
	//				parse_TOD();
					break;
				default:
					if(is_pmt_pid(tsph.PID))
					{
						parse_PMT(sec_start);
					}
					break;
			}
		}
		else
		{
			if(is_es_pid(tsph.PID))
			{
				/*parse_ES()*/
			}
			else
			{
				/*parse_Others() */
			}
		}
		
	}
	else
	{
		debuglog("transport error!");
		return FALSE;
	}

	free(tsph.adaptation_fields);
	tsph.adaptation_fields = NULL;

	return TRUE;
}
Exemplo n.º 2
0
//	input parser: Parse a TS packet Documentation at iso13818-1.pdf
SSIZE_T TSDemuxer::parse( Buffer *buf, SSIZE_T parsed ) {
	BYTE *ptr	= (BYTE *)buf->buffer();
	SIZE_T size = buf->length();

	//printf( "[TSDemuxer] Begin parse: offset=%ld, bufLen=%ld, local=%d\n", parsed, size, (_local == buf) );			
	
	while (parsed < size) {
		{	//	Find TS SYNC byte
			SSIZE_T begin=parsed;
			while (ptr[parsed] != TS_SYNC && parsed < size) {
				parsed++;
			}
			if (parsed - begin) {
				Buffer show( buf->buffer()+begin, parsed+10, false );
				printf( "[TSDemuxer] Warning: Sync lost offset=%ld, size=%ld, count=%ld, isLocal=%d, data=%s\n",
					begin, size, parsed-begin, (_local == buf), show.asHexa().c_str() );
			}
		}

		//	is the begin of TS packet!
		if (parsed < size) {
			int len	 = size - parsed;
			BYTE *ts = ptr + parsed;

			//	is ths TS complete?
			if (len >= TS_PACKET_SIZE) {
				ID pid = TS_PID(ts);

				//	Check for Transport Error Indicator (TES), payload exist, and null packets!!
				if (!TS_HAS_ERROR(ts) && TS_HAS_PAYLOAD(ts) && pid != TS_PID_NULL) {
					int payloadOffset = TS_HEAD_SIZE;
					
					//	Adaptation field exists?
					if (TS_HAS_ADAPTATION(ts)) {
						//	Only calculate payload offset if adaptation field exist
						payloadOffset += TSA_LEN(ts);
					}

					//	Check payload offset
					if (payloadOffset < TS_PACKET_SIZE) {
						bool startFlag = TS_START(ts);
						
						//	Find filter (and check continuity bit)
						_mutex.lock();
						PSIFilter *filter = checkContinuity( pid, startFlag, TS_CONTINUITY(ts) );
						if (filter) {
							BYTE *tsPayload	 = ts+payloadOffset;
							int tsPayloadLen = TS_PACKET_SIZE-payloadOffset;

							//	Begin of a section?
							if (startFlag) {
								//	Get pointer field, skip them in payload and len
								BYTE pointerField = tsPayload[0];
								tsPayload++;
								tsPayloadLen--;
								
								//	Check pointer field
								if (!pointerField || pointerField < tsPayloadLen) {
									if (pointerField) {
										//	Append last block of a section
										filter->pushData( tsPayload, pointerField );

										//	Skip data marked via pointer field
										tsPayload	 += pointerField;
										tsPayloadLen -= pointerField;
									}
									//	TODO: Can start more than one section/pes packet

									//	Start a new section
									filter->startData( tsPayload, tsPayloadLen );
								}
								else {
									printf( "[TSDemuxer] Warning: Pointer field invalid pointer=%d, tsPayloadLen=%d\n", pointerField, tsPayloadLen );
								}
							}
							else {
								//	Add payload to current section
								filter->pushData( tsPayload, tsPayloadLen );
							}

							if (TS_PRIORITY(ts)) {	//	TODO: Priority not processed
								printf( "[TSDemuxer] Warning: Priority not processed\n" );
							}
						}
						_mutex.unlock();
					}
					else {
						printf( "[TSDemuxer] Warning: Transport stream payload not valid\n" );
					}
				}

				parsed += TS_PACKET_SIZE;				
			}
			else {
				//	break loop
				break;
			}
		}
	}

	//printf( "[TSDemuxer] End parse: parsed=%ld\n", parsed );
	
	return parsed;
}