cas_parser.c
来自「Sun公司Dream项目」· C语言 代码 · 共 486 行 · 第 1/2 页
C
486 行
case ENCRYPT_VIDEO_ONLY:
/* see ISO/IEC 13818-1, Table 2-29 */
if (getStreamType(streamList->streamHeader.streamType) == ENCRYPT_VIDEO_ONLY)
{
p_sys->pid[ePid].p_key = d->p_key;
/* now we have the specific stream type */
d->stream_type = streamList->streamHeader.streamType;
}
break;
case ENCRYPT_AUDIO_ONLY:
if (getStreamType(streamList->streamHeader.streamType) == ENCRYPT_AUDIO_ONLY)
{
p_sys->pid[ePid].p_key = d->p_key;
/* now we have the specific stream type */
d->stream_type = streamList->streamHeader.streamType;
}
break;
default:
break;
}
}
}
}
/* do the actual CA injection */
for( i = 0x10; i < 8192; i++ )
{
if (p_sys->pid[i].b_seen && p_sys->pid[i].b_pmt_pid
&& p_sys->pid[i].pn == pn)
{
injectCA2PMT(p_sys, infop, i, p_ca_descriptor);
/* output ECMs for this program */
if (p_sys->b_outputECMafterPMT)
{
ouputECMs(p_sys, pn);
}
break;
}
}
if (p_ca_descriptor)
{
ts_ca_descriptor_delete(p_ca_descriptor);
}
return RETCODE_SUCCESS;
}
/*
----------------------------------------------------------------------
setupNewParser: setup a MPEG2 TS parser for the CAS structure
ARGUMENTS:
p_sys: pointer to the structure
RETURN:
the parser pointer
----------------------------------------------------------------------
*/
parser_p setupNewParser(ca_sys_p p_sys)
{
parser_p parser = (parser_p)calloc(1, sizeof(parser_t));
MmpParserObject *psi2TableIdToPop[MPEG2_PSI_TABLE_ID_STUFF];
MmpParserObject *mmpPops[1] ;
/* we only parse the bitstream until PMT,we don't need PES parser */
parser->mmp = mmpNew() ;
parser->mpeg2Ts = mpeg2TsNew() ;
parser->mpeg2Psi = mpeg2PsiNew() ;
parser->mpeg2Pat = mpeg2PatNew();
parser->mpeg2Pmt = mpeg2PmtNew();
mpeg2PatSetCallBack(parser->mpeg2Pat, mpeg2PatInfoCallback, p_sys);
mpeg2PmtSetCallBack(parser->mpeg2Pmt, mpeg2InjectCA2Pmt, p_sys);
mpeg2TsSetCallBack (parser->mpeg2Ts , mpeg2GatherTSCallback, p_sys);
/* Set Psi Parser with the Ts Parser */
mpeg2TsSetPsiParser(parser->mpeg2Ts, mpeg2PsiParserObject(parser->mpeg2Psi));
/* Set Pat, Pmt Parser with the Psi Parser */
memset(psi2TableIdToPop, 0, sizeof(psi2TableIdToPop));
psi2TableIdToPop[MPEG2_PMT_TABLE_ID] = mpeg2PmtParserObject(parser->mpeg2Pmt);
psi2TableIdToPop[MPEG2_PAT_TABLE_ID] = mpeg2PatParserObject(parser->mpeg2Pat);
mpeg2PsiSetTableParsers(parser->mpeg2Psi, psi2TableIdToPop);
mpeg2PatSetPsiParsers(parser->mpeg2Pat, NULL, mpeg2PsiParserObject(parser->mpeg2Psi));
mmpPops[0] = mpeg2TsParserObject(parser->mpeg2Ts) ;
mmpSetParsers(parser->mmp, mmpPops);
p_sys->mpeg2TScop = parser->mpeg2Ts->cop; /* important !, let the cas have the context of the TS parser */
return parser;
}
/* Free the parser */
void freeParser(parser_p parser)
{
if (parser)
{
/* Propagate free on each of the individual parsers */
mpeg2TsFree (parser->mpeg2Ts );
mpeg2PsiFree(parser->mpeg2Psi);
mpeg2PatFree(parser->mpeg2Pat);
mpeg2PmtFree(parser->mpeg2Pmt);
free(parser);
}
return;
}
#if 0
static RetCodeId retCodeId;
/* ARGSUSED changed from mpeg2TsParse()*/
static RetCode
mpeg2TsParseForCAS(void *instp, MmpContextObject *cop, Pipe pipe)
{
RetCode retCode;
Mpeg2Ts mpeg2Ts = (Mpeg2Ts) instp;
Mpeg2TsInfo info;
Mpeg2TsInfo *infop = &info;
unsigned lastPid = MPEG2_TS_NULL_PID;
mpeg2Ts->isDirty = TRUE;
MMP_CONTEXT_ADDPIPE(mpeg2Ts->cop, MPEG2_TS_PAT_PID,
MMP_PARSER_NEWPIPE(mpeg2Ts->psip, mpeg2Ts->cop));
MMP_CONTEXT_ADDPIPE(mpeg2Ts->cop, MPEG2_TS_CAT_PID,
MMP_PARSER_NEWPIPE(mpeg2Ts->psip, mpeg2Ts->cop));
while (pipeIsAvail(pipe, 1)) {
PipePosition tpEnd;
unsigned pid;
Pipe pidPipe;
(void) memset(infop, 0, sizeof(*infop));
infop->position = pipePosition(pipe);
tpEnd = infop->position + MPEG2_TS_PKT_SIZE;
/* added for CA injecton */
if (mpeg2Ts->callBack != NULL)
{
mpeg2GatherTS(mpeg2Ts, pipe);
}
/* ---> */
infop->transportPacket = *PIPE_GET(pipe, Mpeg2TsTransportPacket);
if (infop->transportPacket.syncByte != MPEG2_TS_SYNC_BYTE) {
retCode = RETCODE_CONS(retCodeId, MPEG2_TS_ERROR_SYNC);
goto error;
}
pid = MPEG2_TS_TRANSPORT_PACKET_PID(&infop->transportPacket);
if (pid == MPEG2_TS_NULL_PID) {
infop->payloadLen = tpEnd - pipePosition(pipe);
goto skip;
}
if (infop->transportPacket.transportErrorIndicator) {
retCode = RETCODE_CONS(retCodeId, MPEG2_TS_ERROR_TEI);
goto error;
}
switch (infop->transportPacket.adaptationFieldControl) {
case MPEG2_TS_ADAPTATION_FIELD_CONTROL_RESERVED:
retCode = RETCODE_CONS(retCodeId, MPEG2_TS_ERROR_AFC);
goto error;
case MPEG2_TS_ADAPTATION_FIELD_CONTROL_ADAPTATION_ONLY:
case MPEG2_TS_ADAPTATION_FIELD_CONTROL_ADAPTATION_PAYLOAD:
infop->adaptationFieldLength = *PIPE_PEEK(pipe, u8);
if (infop->adaptationFieldLength == 0) {
PIPE_SKIP(pipe, u8);
} else if ((retCode = mpeg2TsAdaptationField(mpeg2Ts, pipe, infop))
!= RETCODE_SUCCESS) {
goto error;
}
break;
}
infop->payloadLen = tpEnd - pipePosition(pipe);
if (infop->payloadLen < 0
|| (infop->payloadLen > 0
&& infop->transportPacket.adaptationFieldControl
== MPEG2_TS_ADAPTATION_FIELD_CONTROL_ADAPTATION_ONLY)) {
retCode = RETCODE_CONS(retCodeId, MPEG2_TS_ERROR_LEN);
goto error;
}
skip:
if (pid != lastPid && pid != MPEG2_TS_NULL_PID) {
/*
* Switching pid. Force child pipe to parse accumulated
* TS payloads because that might be a PSI table that
* will create a new pipe (the one for this new payload).
*/
retCode = pipeSync(pipe);
if (retCode != RETCODE_SUCCESS) {
goto done;
}
lastPid = pid;
}
if (mpeg2Ts->callBack != NULL) {
/* added for CA injecton by Yongfang Liang */
mpeg2TSPsi(mpeg2Ts, MMP_CONTEXT_PIDTOPIPE(mpeg2Ts->cop, pid));
/* ----> */
retCode = (*mpeg2Ts->callBack) (mpeg2Ts->token, infop,
RETCODE_SUCCESS);
if (retCode != RETCODE_SUCCESS) {
return retCode;
}
}
if (pid == MPEG2_TS_NULL_PID) {
infop->transportPacket.adaptationFieldControl
= MPEG2_TS_ADAPTATION_FIELD_CONTROL_PAYLOAD_ONLY;
}
switch (infop->transportPacket.adaptationFieldControl) {
case MPEG2_TS_ADAPTATION_FIELD_CONTROL_ADAPTATION_PAYLOAD:
case MPEG2_TS_ADAPTATION_FIELD_CONTROL_PAYLOAD_ONLY:
pidPipe = MMP_CONTEXT_PIDTOPIPE(mpeg2Ts->cop, pid);
if (pidPipe == NULL) {
pidPipe = PIPE_NULL;
}
retCode = pipeTransfer(pidPipe, pipe, infop->payloadLen,
infop->transportPacket.payloadUnitStartIndicator,
mpeg2Ts->doFlush);
if (retCode != RETCODE_SUCCESS) {
goto done;
}
break;
}
}
retCode = RETCODE_SUCCESS;
goto done;
error:
if (mpeg2Ts->callBack != NULL) {
(void) (*mpeg2Ts->callBack) (mpeg2Ts->token, infop, retCode);
}
done:
/*
* PAT and CAT pipes (along with any other created pipes)
* are deleted when mpeg2TsRecover is called from pipeThreadWrapper.
*/
return retCode;
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?