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

📄 patprocessor.c

📁 linux下的dvb收看解析软件代码; 带参考程序
💻 C
字号:
/*
Copyright (C) 2006  Adam Charrett

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of 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 of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

patprocessor.c

Process Program Association Tables and update the services information.

*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>
#include <dvbpsi/dvbpsi.h>
#include <dvbpsi/descriptor.h>
#include <dvbpsi/psi.h>
#include <dvbpsi/pat.h>

#include "multiplexes.h"
#include "services.h"
#include "dvb.h"
#include "ts.h"
#include "patprocessor.h"
#include "cache.h"
#include "logging.h"
#include "main.h"

typedef struct PATProcessor_t
{
    TSFilter_t *tsfilter;
    PIDFilterSimpleFilter_t simplefilter;
    Multiplex_t *multiplex;
    dvbpsi_handle pathandle;
}
PATProcessor_t;

static TSPacket_t *PATProcessorProcessPacket(PIDFilter_t *pidfilter, void *arg, TSPacket_t *packet);
static void PATHandler(void* arg, dvbpsi_pat_t* newpat);

PIDFilter_t *PATProcessorCreate(TSFilter_t *tsfilter)
{
    PIDFilter_t *result = NULL;
    PATProcessor_t *state = calloc(1, sizeof(PATProcessor_t));
    if (state)
    {
        state->simplefilter.pidcount = 1;
        state->simplefilter.pids[0] = 0;
        state->tsfilter = tsfilter;
        result =  PIDFilterSetup(tsfilter,
                    PIDFilterSimpleFilter, &state->simplefilter,
                    PATProcessorProcessPacket, state,
                    NULL,NULL);
        if (result == NULL)
        {
            free(state);
        }
    }
    return result;
}

void PATProcessorDestroy(PIDFilter_t *filter)
{
    PATProcessor_t *state= (PATProcessor_t*)filter->pparg;
    assert(filter->processpacket == PATProcessorProcessPacket);
    PIDFilterFree(filter);
    if (state->multiplex)
    {
        dvbpsi_DetachPAT(state->pathandle);
    }
    free(state);
}

static TSPacket_t *PATProcessorProcessPacket(PIDFilter_t *pidfilter, void *arg, TSPacket_t *packet)
{
    TSPacket_t *result = NULL;
    PATProcessor_t *state= (PATProcessor_t*)arg;

    if (state->multiplex != CurrentMultiplex)
    {
        if (state->multiplex)
        {
            dvbpsi_DetachPAT(state->pathandle);
        }
        state->multiplex = (Multiplex_t*)CurrentMultiplex;
        if (CurrentMultiplex)
        {
            state->pathandle = dvbpsi_AttachPAT(PATHandler, (void*)state);
        }
    }

    if (state->multiplex)
    {
        dvbpsi_PushPacket(state->pathandle, (uint8_t*)packet);
    }

    return result;
}

static void PATHandler(void* arg, dvbpsi_pat_t* newpat)

{
    PATProcessor_t *state = (PATProcessor_t*)arg;
    Multiplex_t *multiplex = state->multiplex;
    printlog(LOG_DEBUG,"PAT recieved, version %d (old version %d)\n", newpat->i_version, multiplex->patversion);
    if (multiplex->patversion != newpat->i_version)
    {
        int count,i;
        Service_t **services;

        /* Version has changed update the services */
        dvbpsi_pat_program_t *patentry = newpat->p_first_program;
        while(patentry)
        {
            if (patentry->i_number != 0x0000)
            {
            Service_t *service = CacheServiceFindId(patentry->i_number);
                if (!service)
            {
                printlog(LOG_DEBUG, "Service not found in cache while processing PAT, adding 0x%04x\n", patentry->i_number);
                service = CacheServiceAdd(patentry->i_number);
                /* Cause a TS Structure change call back*/
                state->tsfilter->tsstructurechanged = TRUE;
            }

            if (service && (service->pmtpid != patentry->i_pid))
            {
                CacheUpdateService(service, patentry->i_pid);
            }
            }
            patentry = patentry->p_next;
        }

        /* Delete any services that no longer exist */
        services = CacheServicesGet(&count);
        for (i = 0; i < count; i ++)
        {
            int found = 0;

            for (patentry = newpat->p_first_program; patentry; patentry = patentry->p_next)
            {
                if (services[i]->id == patentry->i_number)
                {
                    found = 1;
                    break;
                }
            }
            if (!found)
            {
                printlog(LOG_DEBUG, "Service not found in PAT while checking cache, deleting 0x%04x (%s)\n",
                    services[i]->id, services[i]->name);
                CacheServiceDelete(services[i]);
                services = CacheServicesGet(&count);
                /* Cause a TS Structure change call back*/
                state->tsfilter->tsstructurechanged = TRUE;
            }
        }

        CacheUpdateMultiplex(multiplex, newpat->i_version, newpat->i_ts_id);
    }
    dvbpsi_DeletePAT(newpat);
}

⌨️ 快捷键说明

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