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

📄 siparser.cpp

📁 数字电视中间件小型库
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    /* By default open only the PID for PAT */    Table[PAT]->Request(0);    Table[SERVICES]->Request(0);    Table[MGT]->Request(0);    Table[STT]->Request(0);    Table[NETWORK]->Request(0);    for (int x = 0 ; x < NumHandlers ; x++)        Table[x]->SetSIStandard(_SIStandard);    SIStandard = _SIStandard;    pthread_mutex_unlock(&pmap_lock);    return true;}bool SIParser::AddPMT(uint16_t ServiceID){    pthread_mutex_lock(&pmap_lock);    SIPARSER(QString("Adding a PMT (%1) to the request list").arg(ServiceID));    Table[PMT]->RequestEmit(ServiceID);    pthread_mutex_unlock(&pmap_lock);    return true;}bool SIParser::FindTransports(){    Table[NETWORK]->RequestEmit(0);    return true;}bool SIParser::FindServices(){    Table[SERVICES]->RequestEmit(0);    return true;}/*------------------------------------------------------------------------ *   COMMON PARSER CODE *------------------------------------------------------------------------*/void SIParser::ParseTable(uint8_t* buffer, int size, uint16_t pid){    pthread_mutex_lock(&pmap_lock);#ifndef USING_DVB_EIT    (void) pid;#endif    if (!(buffer[1] & 0x80))    {        SIPARSER(QString("SECTION_SYNTAX_INDICATOR = 0 - Discarding Table (%1)")                 .arg(buffer[0],2,16));        pthread_mutex_unlock(&pmap_lock);        return;    }    tablehead_t head = ParseTableHead(buffer,size);    /* Parse Common Tables (PAT/CAT/PMT) regardless of SI Standard */    switch(head.table_id)    {        case 0x00:  ParsePAT(&head, &buffer[8], size-8);                    break;        case 0x01:  ParseCAT(&head, &buffer[8], size-8);                    break;        case 0x02:  ParsePMT(&head, &buffer[8], size-8);                    break;    }    /* In Detection mode determine what SIStandard you are using */    if (SIStandard == SI_STANDARD_AUTO)    {        switch(head.table_id)        {        case 0x46:        case 0x42:              SIStandard = SI_STANDARD_DVB;            SIPARSER("SI Standard Detected: DVB");            standardChange = true;        break;        case 0xC7:              SIStandard = SI_STANDARD_ATSC;            SIPARSER("SI Standard Detected: ATSC");            standardChange = true;        break;        }    }    /* Parse DVB Specific Tables Here */    if (SIStandard == SI_STANDARD_DVB)    {        switch(head.table_id)        {        case 0x40:            /* Network Information Table(s) */            ParseNIT(&head, &buffer[8], size-8);            break;        case 0x42: /* Service Table(s) */        case 0x46:              ParseSDT(&head, &buffer[8], size-8);            break;#ifdef USING_DVB_EIT        case 0x50 ... 0x6F:            /* Standard Future Event Information Table(s) */            ParseDVBEIT(&head, &buffer[8], size-8);            break;#endif        // --- BEGIN: changes by PJ ---        case 0x3b:            if(!CarouselTracker.ProcessDownloadControl(component_tags[pid], head.table_id_ext, &buffer[8])) {                SIPARSER("### ERROR: CarouselTracker::ProcessDownloadControl failed!");            }            while(CarouselTracker.StreamNeeded()) {                uint8_t tag = CarouselTracker.StreamTag();                Table[DSMCC]->Request(stream_pids[tag]);            }            break;        case 0x3c:            if(!CarouselTracker.ProcessDownloadData(component_tags[pid], head.table_id_ext, &buffer[8])) {                SIPARSER("### ERROR: CarouselTracker::ProcessDownloadData failed!");            }            break;        case 0x3d:            SIPARSER("****** TABLE: DSM-CC DSMCC_Descriptor_Lists (stream descriptors)");            break;        // --- END: changes by PJ ---        }    }    if (SIStandard == SI_STANDARD_ATSC)    {        switch(head.table_id)        {              case 0xC7:  ParseMGT(&head, &buffer[8], size-8);                          break;              case 0xC8:                case 0xC9:  ParseVCT(&head, &buffer[8], size-8);                          break;              case 0xCA:  ParseRRT(&head, &buffer[8], size-8);                          break;#ifdef USING_DVB_EIT              case 0xCB:  ParseATSCEIT(&head, &buffer[8], size-8, pid);                          break;              case 0xCC:  ParseETT(&head, &buffer[8], size-8, pid);                          break;#endif              case 0xCD:  ParseSTT(&head, &buffer[8], size-8);                          break;              case 0xD3:  ParseDCCT(&head, &buffer[8], size-8);                          break;              case 0xD4:  ParseDCCSCT(&head, &buffer[8], size-8);                          break;        }    }    pthread_mutex_unlock(&pmap_lock);    return;}tablehead_t SIParser::ParseTableHead(uint8_t* buffer, int size){// TODO: Maybe handle the size but should be OK if CRC passes    (void) size;    tablehead_t head;    head.table_id       = buffer[0];    head.section_length = ((buffer[1] & 0x0f)<<8) | buffer[2];    head.table_id_ext   = (buffer[3] << 8) | buffer[4];    head.current_next   = (buffer[5] & 0x1);    head.version        = ((buffer[5] >> 1) & 0x1f);    head.section_number = buffer[6];    head.section_last   = buffer[7];    return head;}void SIParser::ParsePAT(tablehead_t* head,uint8_t *buffer,int size){    // Check to see if you have already loaded all of the PAT sections    // ISO 13818-1 state that PAT can be segmented, although it rarely is    if(((PATHandler*) Table[PAT])->Tracker.AddSection(head))        return;    SIPARSER(QString("PAT Version = %1").arg(head->version));    PrivateTypes.CurrentTransportID = head->table_id_ext;    SIPARSER(QString("Tuned to TransportID: %1").arg(PrivateTypes.CurrentTransportID));    int pos = -1;    while (pos < (size - 4))    {        if (pos+4 >= (size-4))        {            break;        }        uint16_t program = (buffer[pos + 1] << 8) | buffer[pos + 2];        uint16_t pid = ((buffer[pos + 3] & 0x1f)<<8) | buffer[pos + 4];        if (program != 0)        {            ((PATHandler*) Table[PAT])->pids[program]=pid;            Table[PMT]->AddKey(pid,0);            ((PMTHandler*) Table[PMT])->pmt[program].PMTPID = pid;        }        else        {            // Program 0 in the PAT represents the location of the NIT in DVB            NITPID = pid;            SIPARSER(QString("NIT Present on this transport on PID %1").arg(NITPID));        }        pos += 4;    }    QString ProgramList = QString("Services on this Transport: ");    QMap_uint16_t::Iterator p;    for (p = ((PATHandler*) Table[PAT])->pids.begin(); p != ((PATHandler*) Table[PAT])->pids.end() ; ++p)        ProgramList += QString("%1 ").arg(p.key());    SIPARSER(ProgramList);}void SIParser::ParseCAT(tablehead_t* head, uint8_t* buffer, int size){    (void) head;    CAPMTObject c;    int pos = -1;    while (pos < (size - 4))    {        if (buffer[pos+1] == 0x09)        {            c = ParseDescriptorCA(&buffer[pos+1],buffer[pos+2]);            SIPARSER(QString("CA System 0x%1, EMM PID = %2")                     .arg(c.CASystemID,0,16)                     .arg(c.PID));        }        pos += buffer[pos+2] + 2;    }}void SIParser::ParsePMT(tablehead_t* head, uint8_t* buffer, int size){    // TODO: Catch serviceMove descriptor and send a signal when you get one    //       to retune to correct transport or send an error tuning the channel    if (Table[PMT]->AddSection(head,head->table_id_ext,0))        return;    SIPARSER(QString("PMT ServiceID: %1 Version = %2").arg(head->table_id_ext).arg(head->version));    // Create a PMTObject and populate it    PMTObject p;    uint8_t descriptors_length;    uint16_t pidescriptors_length = (((buffer[2] & 0x0F) << 8) | buffer[3]);    p.PCRPID = (buffer[0] & 0x1F) << 8 | buffer[1];    p.ServiceID = head->table_id_ext;    // Process Program Info Descriptors    uint16_t pos = 4;    uint16_t tempPos = pos + pidescriptors_length;    while (pos < tempPos)    {        switch (buffer[pos])        {            // Conditional Access Descriptor            case 0x09:                {                    CAPMTObject cad = ParseDescriptorCA(&buffer[pos], buffer[pos+1]);                    p.CA.insert(cad.CASystemID, cad);                    p.hasCA = true;                }                break;            default:                SIPARSER(QString("Unknown descriptor, tag = %1").arg(buffer[pos]));                p.Descriptors.append(Descriptor(&buffer[pos], buffer[pos + 1] + 2));                break;        }        pos += buffer[pos+1] + 2;    }    // Process streams    while ((pos + 4) < size)    {        ElementaryPIDObject e;        // Reset Elementary PID object        e.Reset();        // Grab PIDs, and set PID Type        e.PID = (buffer[pos+1] & 0x1F) << 8 | buffer[pos+2];        e.Orig_Type = buffer[pos];        SIPARSER(QString("PID: %1").arg(e.PID));        // The stream type can be detected in two ways:        // - by stream type field in PMT, if known        // - by a descriptor        switch (e.Orig_Type)        {            case 0x01:                e.Type = ES_TYPE_VIDEO_MPEG1;                break;            case 0x02:                e.Type = ES_TYPE_VIDEO_MPEG2;                break;            case 0x03:                e.Type = ES_TYPE_AUDIO_MPEG1;                break;            case 0x04:                e.Type = ES_TYPE_AUDIO_MPEG2;                break;            // --- BEGIN: changes by PJ ---            case 0x08:                SIPARSER("***** DSM-CC (per ISO/IEC 13818-1) stream");                e.Type = ES_TYPE_DSMCC;                break;            case 0x0A:                SIPARSER("***** DSM-CC multiprotocol encapsulation stream");                e.Type = ES_TYPE_DSMCC;                break;            case 0x0B:  // DSM-CC User-Network messages                e.Type = ES_TYPE_DSMCC;                break;            case 0x0C:                SIPARSER("***** DSM-CC (Stream Descriptors only) stream");                e.Type = ES_TYPE_DSMCC;                break;            case 0x0D:                SIPARSER("***** DSM-CC (any type) stream");                e.Type = ES_TYPE_DSMCC;                break;            // --- END: changes by PJ ---            case 0x0F:                e.Type = ES_TYPE_AUDIO_AAC;                break;            case 0x81:                e.Type = ES_TYPE_AUDIO_AC3;// Where ATSC Puts the AC3 Descriptor                break;            default:                break;        }        descriptors_length = (buffer[pos+3] & 0x0F) << 8 | buffer[pos+4];        pos += 5;        tempPos = pos + descriptors_length;        while (pos < tempPos)        {            uint8_t *descriptor = &buffer[pos];            int descriptor_tag = descriptor[0];            int descriptor_len = descriptor[1];            if (descriptor_tag == 0x09) // Conditional Access Descriptor            {                // Note: the saved streams have already been descrambled by the CAM                // so any CA descriptors should *not* be added to the descriptor list.                // We need a CAPMTObject to send to the CAM though.                CAPMTObject cad = ParseDescriptorCA(descriptor, descriptor_len);                e.CA.insert(cad.CASystemID, cad);                p.hasCA = true;            }            else            {                e.Descriptors.append(Descriptor(descriptor, descriptor_len + 2));                switch (descriptor_tag)                {                    case 0x05: // Registration Descriptor                        {                            QString format = QString::fromLatin1((const char*) descriptor + 2, 4);                            if (format == "DTS1")                                e.Type = ES_TYPE_AUDIO_DTS;                        }                        break;                    case 0x0A: // ISO 639 Language Descriptor                        e.Language = ParseDescriptorLanguage(descriptor, descriptor_len);                        break;                    // --- BEGIN: changes by PJ ---                    case 0x02:  // Video stream descriptor                        break;                                        case 0x03:  // Audio stream descriptor                        break;                    case 0x0e:  // Maximum bitrate descriptor                        break;                    case 0x13: // DSM-CC carousel identifier descriptor                        ParseDescriptorCarouselIdentifier(descriptor, descriptor_len, e.PID);                        break;                    case 0x14: // DSM-CC association tag descriptor                        SIPARSER("DSM-CC association tag descriptor");                        break;                    case 0x15: // DSM-CC deferred association tags descriptor                        SIPARSER("DSM-CC deferred association tags descriptor");                        break;                    case 0x16: // (reserved to DSM-CC)                        SIPARSER("(reserved to DSM-CC)");                        break;                    case 0x17: // DSM-CC normal play time (NPT) reference descriptor

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -