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 + -
显示快捷键?