⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psi_task.c

📁 pnx1500 mpeg2 ts stream demo
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -