?? cas_parser.c
字號:
/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the "License"). You may not use this file except
* in compliance with the License.
*
* You can obtain a copy of the license at
* http://www.opensource.org/licenses/cddl1.php
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* HEADER in each file and include the License file at
* http://www.opensource.org/licenses/cddl1.php. If
* applicable, add the following below this CDDL HEADER,
* with the fields enclosed by brackets "[]" replaced
* with your own identifying information:
* Portions Copyright [yyyy]
* [name of copyright owner]
*/
/*
* $(@)cas_parser.c $Revision: 1.1.1.1 $ $Date: 2006/04/17 22:47:29 $
*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
*/
/*
* Copyright (c) 2005 by Sun Microsystems, Inc.
* Functions to perform TS parsing
* Created: July 29, 2005
* Author: Yongfang Liang
*---------------------------------------------------------------*/
#include "cas_sys.h"
static void mpeg2GatherTS(Mpeg2Ts mpeg2Ts, Pipe pipe)
{
ca_sys_p p_sys = (ca_sys_p)mpeg2Ts->token;
ca_ts_pck_p p_ts_pkt = NULL;
p_ts_pkt = PIPE_PEEK(pipe, ca_ts_pck_t);
memcpy(&(p_sys->pkt_buf.data[0]), p_ts_pkt, sizeof(ca_ts_pck_t));
return;
}
static RetCode mpeg2PatInfoCallback (void *token, Mpeg2PatInfo *infop,
RetCode retCode)
{
ca_sys_p p_sys = (ca_sys_p)token;
unsigned pex;
Mpeg2PatSection *curPsp = &(infop->patSection);
for (pex = 0; pex < curPsp->nPatEntries; pex++)
{
Mpeg2PatEntry *pep = &curPsp->patEntries[pex];
unsigned pn = MPEG2_PAT_ENTRY_PROGRAM_NUMBER(pep);
unsigned pid = MPEG2_PAT_ENTRY_PROGRAM_MAP_PID(pep);
p_sys->pid[pid].b_seen = TRUE;
p_sys->pid[pid].pn = pn;
p_sys->pid[pid].b_pmt_pid = TRUE;
}
return RETCODE_SUCCESS;
}
static RetCode mpeg2GatherTSCallback (void *token, Mpeg2TsInfo *infop,
RetCode retCode)
{
ca_sys_p p_sys = (ca_sys_p)token;
unsigned pid;
Pipe pidPipe = NULL;
#define MPEG2_TS_GATHER_TS 7
if ((retCode & 0xffff) == MPEG2_TS_GATHER_TS)
{
mpeg2GatherTS((Mpeg2Ts)token, (Pipe)infop);
return RETCODE_SUCCESS;
}
pid = MPEG2_TS_TRANSPORT_PACKET_PID(&infop->transportPacket);
pidPipe = MMP_CONTEXT_PIDTOPIPE(p_sys->mpeg2TScop, pid);
if (p_sys->tsCallback)
{
(*p_sys->tsCallback)(p_sys->ts_token, infop->position);
}
if (pidPipe != PIPE_NULL && pidPipe != NULL)
{
if (pid == MPEG2_TS_NULL_PID || pid == MPEG2_TS_PAT_PID
|| pid == MPEG2_TS_CAT_PID)
{
/* break: output the packet as it is */
/* output the packet */
pipeSync(p_sys->outpipe);
pipePut(p_sys->outpipe,&(p_sys->pkt_buf.data[0]), MPEG2_TS_PKT_SIZE, FALSE, p_sys->putPosition);
p_sys->putPosition += MPEG2_TS_PKT_SIZE;
}
else /* pmt */
{
if (infop->transportPacket.adaptationFieldControl == MPEG2_TS_ADAPTATION_FIELD_CONTROL_ADAPTATION_ONLY
|| infop->transportPacket.adaptationFieldControl == MPEG2_TS_ADAPTATION_FIELD_CONTROL_ADAPTATION_PAYLOAD)
{
/* output a new ts packet contains only adaptation field, since we will generate a new pmt */
int i = 0;
/* adaptation field only */
p_sys->pkt_buf.data[3] |= 0x20; /* bit 4 */
p_sys->pkt_buf.data[3] &= 0xef; /* bit 3 */
/* change adaptation field length */
p_sys->pkt_buf.data[4] = MPEG2_TS_PKT_SIZE - 5;
for (i = infop->adaptationFieldLength + 5; i < MPEG2_TS_PKT_SIZE; i++)
{
p_sys->pkt_buf.data[i] = 0xff; /* stuffing bytes */
}
/* output this additional packet before new pmt is built */
pipeSync(p_sys->outpipe);
pipePut(p_sys->outpipe,&(p_sys->pkt_buf.data[0]), MPEG2_TS_PKT_SIZE, FALSE, p_sys->putPosition);
p_sys->putPosition += MPEG2_TS_PKT_SIZE;
msg_TRACE("old PMT contains adaptation field, output one adaptation_only TS packet.\n");
}
}
}
else
{
/* scramble the packet if required, only the payload! */
scrambleTsPacket(p_sys, pid, &(p_sys->pkt_buf.data[0]), &(p_sys->pkt_buf.data[0]) + MPEG2_TS_PKT_SIZE - infop->payloadLen,
infop->payloadLen, infop->position);
/* output the packet */
pipeSync(p_sys->outpipe);
pipePut(p_sys->outpipe,&(p_sys->pkt_buf.data[0]), MPEG2_TS_PKT_SIZE, FALSE, p_sys->putPosition);
p_sys->putPosition += MPEG2_TS_PKT_SIZE;
}
return RETCODE_SUCCESS;
}
/* callback functin for PMT */
static RetCode mpeg2InjectCA2Pmt (void *token, Mpeg2PmtInfo *infop,
RetCode retCode)
{
ca_sys_p p_sys = (ca_sys_p)token;
Mpeg2PmtTsProgramMapSection *pmsp = &infop->tsProgramMapSection;
unsigned pcr_pid;
Mpeg2PmtStream *streamList = pmsp->streamList;
Mpeg2PmtDescriptor *desc = NULL;
unsigned pn; /* program number */
encrypt_key_p p_keys = NULL;
ts_ca_descriptor_p p_ca_descriptor = NULL; /* CA descriptors to be inserted for this pmt */
int i = 0;
pn = MPEG2_PMT_PROGRAM_NUMBER(&pmsp->psiExtension);
/* record the pids (pcr_pid and elementary stream pid) that have been used */
pcr_pid = MPEG2_PMT_HEADER_PCR_PID(&(pmsp->pmtHeader));
p_sys->pid[pcr_pid].b_seen = TRUE;
p_sys->pid[pcr_pid].pn = pn;
/* note: we assume there are no CA descriptors for current program
and that is why we need to introduce them */
for (streamList = pmsp->streamList; streamList != NULL;
streamList = streamList->next)
{
unsigned ePid = MPEG2_PMT_STREAM_HEADER_ELEMENTARY_PID(&streamList->streamHeader);
p_sys->pid[ePid].b_seen = TRUE;
p_sys->pid[ePid].pn = pn;
}
/* look up the keys. do we need CA injection for this PMT ? */
for (p_keys = p_sys->p_keys; p_keys != NULL;
p_keys = p_keys->next)
{
int key_count = 0;
if (p_keys->pn == pn || p_keys->pn == FOR_ANY_PROGRAM)
{
/* create the CAs if an injection is needed */
short availabe_pid = 0;
int i = 0;
key_count ++;
if (p_keys->ecm_pid != 0)
{
/* we already got one */
availabe_pid = p_keys->ecm_pid;
}
else
{
/* find available pid */
for (i = 0x10; i < 0x01FFE; i++)
{
if (p_sys->pid[i].b_seen == FALSE)
{
availabe_pid = (short)i;
p_sys->pid[i].b_seen = TRUE;
p_sys->pid[i].pn = pn;
msg_TRACE("ECM pid allocated: %d,the %dth key.\n", availabe_pid, key_count);
break;
}
}
}
if (availabe_pid != 0)
{
p_sys->pid[availabe_pid].b_seen = TRUE;
p_sys->pid[availabe_pid].pn = pn;
/* assign pid to this key */
p_keys->ecm_pid = availabe_pid;
/* we can support multiple CA system, now just CA_SYS_ID */
/* we don't have privdate data for the descriptor */
ts_ca_descriptor_p d = ts_ca_descriptor_create(p_keys->e_type, p_sys->i_ca_system_id, availabe_pid, NULL, 0);
d->p_key = p_keys;
p_ca_descriptor = ts_ca_descriptor_append(p_ca_descriptor, d);
}
else
{
printf("all the pids are being used, key ignored, pn# %d\n", p_keys->pn);
}
}
}
if (p_ca_descriptor)
{
/* set up the encryption key for each ES */
for (streamList = pmsp->streamList; streamList != NULL;
streamList = streamList->next)
{
ts_ca_descriptor_p d = NULL;
short ePid = MPEG2_PMT_STREAM_HEADER_ELEMENTARY_PID(&streamList->streamHeader);
for (d = p_ca_descriptor; d != NULL; d = d->next)
{
/* what type of CA? for the whole program, video or audio? */
switch (d->en_type)
{
case ENCRYPT_ALL:
p_sys->pid[pcr_pid].p_key = d->p_key;
p_sys->pid[ePid].p_key = d->p_key;
/* now we have the specific stream type */
d->stream_type = ANY_STREAM_TYPE;
break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -