📄 psi_task.c
字号:
dummyVar.programNum = -1;
psiGetProgramNo( &dummyVar.programNum );
if (dummyVar.programNum <= 0 )
{
goto _return;
}
if ( !bChangePids )
{
if ( prevProgramNum != dummyVar.programNum && prevProgramNum != 0 )
{
bSearchForProgram = False;
}
prevProgramNum = dummyVar.programNum;
}
/* If the user is trying to change to the same channel again, don't process
anything */
if ( dummyVar.programNum == gPMTInfo.program_number )
{
psiPidsAlreadySet();
goto _return;
}
// Only the program numbers are parsed every time.
for ( i = 8; i < (length - 7); i += 2 )
{
gPATInfo.programInfo = tmDefault_Calloc( sizeof( *(gPATInfo.programInfo) ) );
EQ_ERRCHK( gPATInfo.programInfo, Null )
gPATInfo.programInfo->program_number = (section[i] << 8) | (section[i+1]);
i += 2;
gPATInfo.programInfo->program_map_PID = ((section[i] & 0x1F) << 8) | (section[i+1]);
if ( (gPMTInfo.program_number == gPATInfo.programInfo->program_number) &&
(gPMTInfo.PMTPid != gPATInfo.programInfo->program_map_PID) )
{
/* TODO: Send status to IIC that the pids for the program number
in use have changed */
DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1,
"psiParsePat: PIDs for the program number in use "
"have changed") )
}
TAILQ_INSERT_TAIL( &programList, gPATInfo.programInfo, PATentries );
}
TAILQ_FOREACH( gPATInfo.programInfo, &programList, PATentries )
{
if ( dummyVar.programNum == gPATInfo.programInfo->program_number )
{
bProgramFound = True;
bChangePids = True;
DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1,
"psiParsePat: bChangePids = True") )
break;
}
j++;
}
if ( !bProgramFound )
{
if ( !bSearchForProgram )
{
psiPidsAlreadySet();
}
psiSetProgramNo( dummyVar.programNum );
bSearchForProgram = True;
bChangePids = False;
goto _return;
}
if ( gPMTInfo.PMTPid != 0 )
{
ERRCHK( tmolDemuxMpegTsRemoveRedirectedPid( taskArgs->instance,
gPMTInfo.PMTPid ) )
}
gDoNotPrint[j] = False;
// Request PMT PID
ERRCHK( tmolDemuxMpegTsAddRedirectedPid(
taskArgs->instance,
gPATInfo.programInfo->program_map_PID,
DEMUXMPEGTS_PSI_OUTPUT,
demuxMpegTSSectionCRC,
0, // Not interested in PCR
(Pointer)&gDoNotPrint[j++],
psiParsePmt ) )
while ( gPATInfo.programInfo == TAILQ_FIRST( &programList ) )
{
TAILQ_REMOVE( &programList, gPATInfo.programInfo, PATentries );
tmDefault_Free( gPATInfo.programInfo );
}
_return:
DBG_ISR_PRINT( (dbgTsDemux, DBG_INTERNAL_LEAVE, "psiParsePat") )
return( TM_OK );
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
static Bool
psiParsePmt(
UInt32 pid,
UInt8 *section,
UInt32 sectionLength,
void *userData,
UInt32 *userOutData )
{
Int i = 0;
Int numAudioPids = 0;
Int numVideoPids = 0;
pids_t pids;
#define ASTR(s) \
( \
(s) == MPEG_1_AUDIO? "MPEG_1_AUDIO": \
(s) == MPEG_2_AUDIO? "MPEG_2_AUDIO": \
(s) == AC3_AUDIO? "AC3_AUDIO": \
"unknown" \
) \
TAILQ_INIT( &pidList );
pids.videoPid = DEMUXMPEGTS_NO_PID;
pids.mainAudioPid = DEMUXMPEGTS_NO_PID;
pids.secondaryAudioPid = DEMUXMPEGTS_NO_PID;
pids.pcrPid = DEMUXMPEGTS_NO_PID;
DBG_ISR_PRINT( (dbgTsDemux, DBG_INTERNAL_ENTER, "psiParsePmt") )
if ( !*(Bool*)userData )
{
DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_2,
"psiParsePmt: parsing PMT PID=0x%x", pid) )
gPMTInfo.PMTPid = pid;
gPMTInfo.numOfPids = 0;
gPMTInfo.table_ID = section[0];
gPMTInfo.section_syntax_indicator = (section[1] >> 7) & 0x01;
gPMTInfo.section_length = (section[1] & 0x0F) << 4 | section[2];
gPMTInfo.program_number = (section[3]) << 8 | section[4];
gPATInfo.version_number = (section[5] >> 1) & 0x3F;
gPATInfo.current_next_indicator = section[5] & 0x01;
gPATInfo.section_number = section[6];
gPATInfo.last_section_number = section[7];
gPMTInfo.PCR_PID = ((section[8] & 0x1F) << 8) | section[9];
gPMTInfo.program_info_length = ((section[10] & 0x0F) << 8) | section[11];
i = gPMTInfo.program_info_length + 12;
while( i < (sectionLength - 7) )
{
UInt8 audioStreamType = 0;
gPMTInfo.PMTpids = tmDefault_Calloc( sizeof( *(gPMTInfo.PMTpids) ) );
EQ_ERRCHK( gPMTInfo.PMTpids, Null )
gPMTInfo.PMTpids->stream_type = section[i++];
gPMTInfo.PMTpids->elementary_PID = ((section[i] & 0x1F) << 8) | (section[i+1]);
i += 2;
gPMTInfo.PMTpids->ES_info_length = ((section[i] & 0x0F) << 8) | (section[i+1]);
i += 2;
i += gPMTInfo.PMTpids->ES_info_length;
switch ( gPMTInfo.PMTpids->stream_type )
{
case MPEG_2_VIDEO:
numVideoPids++;
// Set video pid
if ( numVideoPids == 1 )
{
pids.videoPid = (numVideoPids > 1) ? 0x00 :
gPMTInfo.PMTpids->elementary_PID;
printf ("psiParsePmt: videoPid %d (MPEG_2_VIDEO)\n", pids.videoPid);
}
break;
case MPEG_1_AUDIO:
case MPEG_2_AUDIO:
case AC3_AUDIO:
numAudioPids++;
if ( numAudioPids == 1 )
{
// Set main audio PID, store stream type associated with it
audioStreamType = gPMTInfo.PMTpids->stream_type;
pids.mainAudioPid = gPMTInfo.PMTpids->elementary_PID;
printf ("psiParsePmt: mainAudioPid %d (%s)\n", pids.mainAudioPid, ASTR (gPMTInfo.PMTpids->stream_type));
}
else if ( numAudioPids == 2 )
{
/* If the stream type of the secondary audio PID is not the
same as the main audio PID */
if ( audioStreamType != gPMTInfo.PMTpids->stream_type )
{
// Do not store the secondary audio PID
numAudioPids--;
DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_5,
"psiParsePmt : Error: Main audio PID and "
"secondary audio PID do not have the same "
"audio stream type. Ignoring SAP") )
break;
}
else
{
// Set secondary audio pid
pids.secondaryAudioPid = gPMTInfo.PMTpids->elementary_PID;
printf ("psiParsePmt: secondaryAudioPid %d\n", pids.secondaryAudioPid);
}
}
break;
default:
// Do Nothing
break;
} // end switch
gPMTInfo.numOfPids++;
TAILQ_INSERT_TAIL( &pidList, gPMTInfo.PMTpids, PMTentries );
} // end while
gPMTInfo.CRC_32 = (UInt8)(section[i] << 24) +
(UInt8)(section[i + 1] << 16) +
(UInt8)(section[i + 2] << 8) +
(UInt8)(section[i + 3] );
if ( (numAudioPids == 0) && (numVideoPids == 0) )
{
if ( gPMTInfo.section_number != gPMTInfo.last_section_number )
{
goto _return;
}
else
{
// :TODO: Add status here that Pids were not found
DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1,
"psiParsePmt: PIDs not found") )
}
}
pids.pcrPid = gPMTInfo.PCR_PID;
printf ("psiParsePmt: pcrPid %d\n", pids.pcrPid);
psiSetPids( pids );
while ( gPMTInfo.PMTpids == TAILQ_FIRST( &pidList ) )
{
TAILQ_REMOVE( &pidList, gPMTInfo.PMTpids, PMTentries );
tmDefault_Free( gPMTInfo.PMTpids );
}
}
*(Bool *)userData = True;
*userOutData = ++gPmtCounter;
if ( bSearchForProgram && bChangePids )
{
DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1, "psiParsePmt: changing Pids") )
ERRCHK( tmolDemuxMpegTsChangeToNewPids(
gDemuxInst,
pids.pcrPid, // PCR PID
pids.videoPid, // Video PID
pids.mainAudioPid, // Main audio PID
pids.secondaryAudioPid, // Secondary audio PID
0 ) ) // Relative index
bSearchForProgram = False;
bChangePids = False;
}
_return:
DBG_ISR_PRINT( (dbgTsDemux, DBG_INTERNAL_LEAVE, "psiParsePmt") )
return( True ); // Pass section along
#undef ASTR
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
tmErrorCode_t
psiPidsAlreadySet(
void )
{
DBG_ISR_PRINT( (dbgTsDemux, DBG_INTERNAL_ENTER, "psiPidsAlreadySet") )
// Release semaphore to indicate that PIDs have been set
ERRCHK( tmosalSemRelease( gPsiSemaphore ) )
DBG_ISR_PRINT( (dbgTsDemux, DBG_INTERNAL_LEAVE, "psiPidsAlreadySet") )
return( TM_OK );
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
tmErrorCode_t
psiSetPids(
pids_t pid )
{
DBG_ISR_PRINT( (dbgTsDemux, DBG_INTERNAL_ENTER, "psiSetPids") )
gPids.pcrPid = pid.pcrPid;
gPids.videoPid = pid.videoPid;
gPids.mainAudioPid = pid.mainAudioPid;
gPids.secondaryAudioPid = pid.secondaryAudioPid;
// Release semaphore to indicate that PIDs have been set
ERRCHK( tmosalSemRelease( gPsiSemaphore ) )
DBG_ISR_PRINT( (dbgTsDemux, DBG_INTERNAL_LEAVE, "psiSetPids") )
return( TM_OK );
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
tmErrorCode_t
psiSetProgramNo(
Int num )
{
DBG_ISR_PRINT( (dbgTsDemux, DBG_INTERNAL_ENTER, "psiSetProgramNo") )
// Set the value of the Program Number
gPids.programNum = num;
DBG_ISR_PRINT( (dbgTsDemux, DBG_INTERNAL_LEAVE, "psiSetProgramNo") )
return( TM_OK );
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -