TSM_TIMESTAMP tsmGetFrmTs(void* pHandle,void* pfrmHandle)
{
	/*nfrmHandle==NULL: 
		(1) only need to pop one time stamp. (e.g. frame is not decoded at all by vpu for skipmode/corrupt/... cases); 
		(2) mosaic frame which is dropped by vpu for non-gop case
	*/
	TSM_TIMESTAMP ts=TS_INVALIDTS;
	TSM_TIMESTAMP tsOri=TS_INVALIDTS;
	TSM_TIMESTAMP ts2=TS_INVALIDTS;
	TSM_TIMESTAMP tsDiff;
	TSM_OBJ* pObj=(TSM_OBJ*)pHandle;
	if(pObj->pHandleOri){
		if(pObj->nInCurTsOri != TS_INVALIDTS) {
			tsOri = pObj->nInCurTsOri;
			pObj->nInCurTsOri = TS_INVALIDTS;
		}
		else{
			tsOri = TSManagerSend(pObj->pHandleOri);
			TS_API("ori: calling TSManagerSend: returned ts(ns): %lld, total: %d \n",tsOri, (int)pObj->nInTsCntOri);
			tsOri=(tsOri==TS_INVALIDTS)?tsOri:(tsOri/TS_SCALE);
			pObj->nInTsCntOri--;
		}
		ts=tsOri;
	}
	if(pObj->pHandle2){
		if(pObj->nIsActived2==0){
			TS_DEBUG("new strategy isn't detected, it will be disabled automatically\n");
			TS_API("new: calling destroyTSManager\n");
			destroyTSManager(pObj->pHandle2);
			pObj->pHandle2=NULL;
		}
		else{				
			if(pObj->nInCurTs2 != TS_INVALIDTS) {
				ts2 = pObj->nInCurTs2;
				pObj->nInCurTs2 = TS_INVALIDTS;
			}
			else{
				if(NULL==pfrmHandle){
					ts2=TSManagerSend2(pObj->pHandle2, NULL);
					TS_API("new: calling TSManagerSend2(NULL): returned ts(ns): %lld, total: %d \n",ts2, (int)pObj->nInTsCnt2);
				}
				else{
					ts2=TSManagerSend2(pObj->pHandle2, pfrmHandle);
					TS_API("new: calling TSManagerSend2: frm: 0x%X, returned ts(ns): %lld, total: %d \n",pfrmHandle,ts2, (int)pObj->nInTsCnt2);
				}
				ts2=(ts2==TS_INVALIDTS)?ts2:(ts2/TS_SCALE);
				pObj->nInTsCnt2--;
			}
			//TS_DEBUG("new: get one ts: %lld, total: %d\n", ts2, (int)pObj->nInTsCnt2);
			ts=ts2;
			pObj->nCurOutputTs=ts;
		}
	}

	//double check the ts for different schema
	if(pObj->pHandleOri && pObj->pHandle2){
		tsDiff=TS_ABS(tsOri,ts2);
		if(tsDiff>=TS_MAX_DIFF_US){
			TS_ERROR("LEVEL: 1 %s: the time stamp is conflict: ori ts(us): %lld, new ts(us): %lld, diff(us): %lld \n",__FUNCTION__,tsOri,ts2,tsDiff);
		}
	}

	if(ts==TS_INVALIDTS){
		TS_ERROR("%s: warning: can't get one valid ts \n",__FUNCTION__);
	}
#ifdef TS_DEBUG	
	if(pObj->nLastTs!=TS_INVALIDTS){
		pObj->nDeltaTs=ts-pObj->nLastTs;
	}		
	pObj->nLastTs=ts;
	TS_DEBUG("%s: current ts(us): %lld, delta(us): %lld \n",__FUNCTION__,pObj->nLastTs,pObj->nDeltaTs);
#endif	
	return ts;
}
Esempio n. 2
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;
}