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

📄 cmd_scanning.c

📁 Dvbstreamer 用在解析MPTS的部分内容
💻 C
字号:
/*Copyright (C) 2006  Adam CharrettThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USAscanning.cCommand functions related to scanning multiplex and frequency bands.*/#define _GNU_SOURCE#include <limits.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <pthread.h>#include <getopt.h>#include <ctype.h>#include <time.h>#include <errno.h>#include <readline/readline.h>#include <readline/history.h>#include "commands.h"#include "multiplexes.h"#include "services.h"#include "dvb.h"#include "ts.h"#include "logging.h"#include "cache.h"#include "main.h"#include "deliverymethod.h"#include "plugin.h"#include "servicefilter.h"#include "tuning.h"#include "patprocessor.h"#include "pmtprocessor.h"#include "sdtprocessor.h"#include "psipprocessor.h"/******************************************************************************** Typedefs                                                                     ********************************************************************************/struct PMTReceived_t{    uint16_t id;    uint16_t pid;    bool received;};/******************************************************************************** Prototypes                                                                   ********************************************************************************/static void CommandScan(int argc, char **argv);static void ScanMultiplex(Multiplex_t *multiplex);static void PATCallback(dvbpsi_pat_t* newpat);static void PMTCallback(dvbpsi_pmt_t* newpmt);static void SDTCallback(dvbpsi_sdt_t* newsdt);static void VCTCallback(dvbpsi_atsc_vct_t* newvct);/******************************************************************************** Global variables                                                             ********************************************************************************/Command_t CommandDetailsScanning[] = {    {        "scan",        TRUE, 1,1,        "Scan the specified multiplex for services.",        "scan <multiplex>\n"        "Tunes to the specified multiplex and wait 5 seconds for PAT/PMT/SDT."        " If multiplex is 'all' then all multiplexes will be scanned.",        CommandScan    },    {NULL, FALSE, 0, 0, NULL,NULL}};static bool scanning = FALSE;static bool PATReceived = FALSE;static bool AllPMTReceived = FALSE;static bool SDTReceived = FALSE;static int PMTCount = 0;static struct PMTReceived_t *PMTsReceived = NULL;static pthread_mutex_t scanningmutex = PTHREAD_MUTEX_INITIALIZER;static pthread_cond_t scanningcond = PTHREAD_COND_INITIALIZER;/******************************************************************************** Global functions                                                             ********************************************************************************/void CommandInstallScanning(void){    if (MainIsDVB())    {        SDTProcessorRegisterSDTCallback(SDTCallback);    }    else    {        PSIPProcessorRegisterVCTCallback(VCTCallback);    }    PATProcessorRegisterPATCallback(PATCallback);    PMTProcessorRegisterPMTCallback(PMTCallback);        CommandRegisterCommands(CommandDetailsScanning);}void CommandUnInstallScanning(void){    CommandUnRegisterCommands(CommandDetailsScanning);    scanning = FALSE;    PATProcessorUnRegisterPATCallback(PATCallback);    PMTProcessorUnRegisterPMTCallback(PMTCallback);    if (MainIsDVB())    {        SDTProcessorUnRegisterSDTCallback(SDTCallback);    }    else    {        PSIPProcessorUnRegisterVCTCallback(VCTCallback);    }}/******************************************************************************** Local Functions                                                              ********************************************************************************/static void CommandScan(int argc, char **argv){    Service_t *currentService;        Multiplex_t *multiplex;    CommandCheckAuthenticated();    currentService = TuningCurrentServiceGet();    if (strcmp(argv[0], "all") == 0)    {        int count = MultiplexCount();                Multiplex_t **multiplexes = ObjectAlloc(count * sizeof(Multiplex_t *));        if (multiplexes)        {            int i =0;            MultiplexEnumerator_t enumerator = MultiplexEnumeratorGet();            do            {                multiplex = MultiplexGetNext(enumerator);                if (multiplex)                {                    multiplexes[i] = multiplex;                    i ++;                }            }while(multiplex && ! ExitProgram);            MultiplexEnumeratorDestroy(enumerator);            for (i = 0; (i < count) && ! ExitProgram; i ++)            {                ScanMultiplex(multiplexes[i]);                MultiplexRefDec(multiplexes[i]);            }            ObjectFree(multiplexes);        }    }    else    {        multiplex = MultiplexFind(argv[0]);        if (multiplex)        {            ScanMultiplex(multiplex);            MultiplexRefDec(multiplex);        }    }    if (currentService)    {        TuningCurrentServiceSet(currentService);        ServiceRefDec(currentService);    }}/************************** Scan Callback Functions **************************/static void ScanMultiplex(Multiplex_t *multiplex){    struct timespec timeout;    bool seenPATReceived = FALSE;    bool seenAllPMTReceived = FALSE;    bool seenSDTRecieved = FALSE;    int ret = 0;        CommandPrintf("Scanning %d\n", multiplex->uid);    TuningCurrentMultiplexSet(multiplex);    PATReceived = FALSE;    SDTReceived = FALSE;    AllPMTReceived = FALSE;    PMTCount = 0;    PMTsReceived = NULL;    clock_gettime( CLOCK_REALTIME, &timeout);    timeout.tv_sec += 5;    scanning = TRUE;    while ( !(seenPATReceived && seenAllPMTReceived && seenSDTRecieved) && (ret != ETIMEDOUT))    {        pthread_mutex_lock(&scanningmutex);        ret = pthread_cond_timedwait(&scanningcond, &scanningmutex, &timeout);        pthread_mutex_unlock(&scanningmutex);        if (!seenPATReceived && PATReceived)        {            CommandPrintf(" PAT received? Yes\n");            seenPATReceived = TRUE;        }        if (!seenAllPMTReceived && AllPMTReceived)        {            CommandPrintf(" PMT received? Yes\n");            seenAllPMTReceived = TRUE;        }        if (!seenSDTRecieved && SDTReceived)        {            CommandPrintf(" %s received? Yes\n", MainIsDVB() ?"SDT":"VCT");            seenSDTRecieved = TRUE;        }    }    if (!seenPATReceived)    {        CommandPrintf(" PAT received? No\n");            }    if (!seenAllPMTReceived)    {        CommandPrintf(" PMT received? No\n");    }    if (!seenSDTRecieved)    {        CommandPrintf(" %s received? No\n", MainIsDVB() ?"SDT":"VCT");    }    scanning = FALSE;    if (PMTsReceived)    {        ObjectFree(PMTsReceived);    }}static void PATCallback(dvbpsi_pat_t* newpat){    if (scanning && !PATReceived)    {        int i;        dvbpsi_pat_program_t *patentry = newpat->p_first_program;        TSFilter_t *tsFilter = MainTSFilterGet();        PMTCount = 0;        while(patentry)        {            if (patentry->i_number != 0x0000)            {                PMTCount ++;            }            patentry = patentry->p_next;        }        PMTsReceived = ObjectAlloc(sizeof(struct PMTReceived_t) * PMTCount);        patentry = newpat->p_first_program;        i = 0;        while(patentry)        {            if (patentry->i_number != 0x0000)            {                PMTsReceived[i].id = patentry->i_number;                PMTsReceived[i].pid = patentry->i_pid;                i ++;            }            patentry = patentry->p_next;        }        PATReceived = TRUE;        tsFilter->tsStructureChanged = TRUE; /* Force all PMTs to be received again incase we are scanning a mux we have pids for */        if (tsFilter->adapter->hardwareRestricted)        {            DVBDemuxAllocateFilter(tsFilter->adapter, PMTsReceived[0].pid,FALSE);        }        pthread_mutex_lock(&scanningmutex);        pthread_cond_signal(&scanningcond);        pthread_mutex_unlock(&scanningmutex);    }}static void PMTCallback(dvbpsi_pmt_t* newpmt){    if (scanning && !AllPMTReceived)    {        bool all = TRUE;        int i;        DVBAdapter_t *adapter = MainDVBAdapterGet();        for (i = 0; i < PMTCount; i ++)        {            if (PMTsReceived[i].id == newpmt->i_program_number)            {                PMTsReceived[i].received = TRUE;                if (adapter->hardwareRestricted)                {                    DVBDemuxReleaseFilter(adapter,PMTsReceived[i].pid);                    if (i + 1 < PMTCount)                    {                        DVBDemuxAllocateFilter(adapter, PMTsReceived[i + 1].pid,FALSE);                    }                }            }        }        for (i = 0; i < PMTCount; i ++)        {            if (!PMTsReceived[i].received)            {                all = FALSE;            }        }        AllPMTReceived = all;        if (all)        {            pthread_mutex_lock(&scanningmutex);            pthread_cond_signal(&scanningcond);            pthread_mutex_unlock(&scanningmutex);        }    }}static void SDTCallback(dvbpsi_sdt_t* newsdt){    if (scanning && !SDTReceived)    {        SDTReceived = TRUE;        if (SDTReceived)        {            pthread_mutex_lock(&scanningmutex);            pthread_cond_signal(&scanningcond);            pthread_mutex_unlock(&scanningmutex);        }    }}static void VCTCallback(dvbpsi_atsc_vct_t* newvct){    if (scanning && !SDTReceived)    {        SDTReceived = TRUE;        if (SDTReceived)        {            pthread_mutex_lock(&scanningmutex);            pthread_cond_signal(&scanningcond);            pthread_mutex_unlock(&scanningmutex);        }    }}

⌨️ 快捷键说明

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