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; }
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; }