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

📄 schedule.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, USAschedule.cPlugin to collect EPG schedule information.*/#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <string.h>#include <stdint.h>#include <time.h>#include "plugin.h"#include "epgdbase.h"#include "dvbpsi/datetime.h"#include "dvbpsi/eit.h"#include "dvbpsi/dr_4d.h"#include "dvbpsi/dr_55.h"#include "dvbpsi/dr_76.h"#include "list.h"#include "logging.h"#include "subtableprocessor.h"#include "dvbtext.h"#include "deferredproc.h"/******************************************************************************** Defines                                                                      ********************************************************************************/#define EIT_PID 0x12#define MAX_STRING_LEN 256#define SHORT_EVENT_DR      0x4d#define PARENTAL_RATINGS_DR 0x55#define CRID_DR             0x76#define UK_FREEVIEW_CONTENT 49#define UK_FREEVIEW_SERIES  50/******************************************************************************** Prototypes                                                                   ********************************************************************************/static void Init0x12Filter(PIDFilter_t *filter);static void Deinit0x12Filter(PIDFilter_t *filter);static void SubTableHandler(void * arg, dvbpsi_handle demuxHandle, uint8_t tableId, uint16_t extension);static void ProcessEIT(void *arg, dvbpsi_eit_t *newEIT);static void DeferredProcessEIT(void *arg);static void ProcessEvent(EPGServiceRef_t *serviceRef, dvbpsi_eit_event_t *event);static void ConvertToTM(dvbpsi_date_time_t *datetime, dvbpsi_eit_event_duration_t *duration,    struct tm *startTime, struct tm *endTime);static char *ResolveCRID(EPGServiceRef_t *serviceRef, char *relativeCRID);/******************************************************************************** Global variables                                                             ********************************************************************************/static PluginFilter_t filter = {NULL, Init0x12Filter, Deinit0x12Filter};static const char DVBSCHEDULE[] = "DVBSchedule";static const char ISO639NoLinguisticContent[] = "zxx";static char *RatingsTable[] = {    "Undefined",    "4",    "5",        "6",    "7",    "8",    "9",    "10",    "11",    "12",    "13",    "14",    "15",    "16",    "17",    "18"};/******************************************************************************** Plugin Setup                                                                 ********************************************************************************/#ifdef __CYGWIN__#define PluginInterface DVBSchedulePluginInterface#endifPLUGIN_FEATURES(    PLUGIN_FEATURE_FILTER(filter)    );PLUGIN_INTERFACE_F(    PLUGIN_FOR_DVB,    "DVBSchedule", "0.2",     "Plugin to capture DVB EPG schedule information.",     "charrea6@users.sourceforge.net"    );/******************************************************************************** Filter Functions                                                             ********************************************************************************/static void Init0x12Filter(PIDFilter_t *filter){    filter->name = "DVB Schedule";    filter->enabled = TRUE;    SubTableProcessorInit(filter, 0x12, SubTableHandler, NULL, NULL, NULL);    if (filter->tsFilter->adapter->hardwareRestricted)    {        DVBDemuxAllocateFilter(filter->tsFilter->adapter, EIT_PID, TRUE);    }      }static void Deinit0x12Filter(PIDFilter_t *filter){    filter->enabled = FALSE;    if (filter->tsFilter->adapter->hardwareRestricted)    {        DVBDemuxReleaseFilter(filter->tsFilter->adapter, EIT_PID);    }                    SubTableProcessorDeinit(filter);}static void SubTableHandler(void * arg, dvbpsi_handle demuxHandle, uint8_t tableId, uint16_t extension){    if ((tableId >= 0x50) && (tableId <= 0x6f))    {        LogModule(LOG_DEBUG, DVBSCHEDULE, "Request for Sub-Table handler for %#02x (%#04x)\n", tableId, extension);        dvbpsi_AttachEIT(demuxHandle, tableId, extension, ProcessEIT, NULL);    }}static void ProcessEIT(void *arg, dvbpsi_eit_t *newEIT){    LogModule(LOG_DEBUG, DVBSCHEDULE, "EIT received (version %d) net id %x ts id %x service id %x\n",        newEIT->i_version, newEIT->i_network_id, newEIT->i_ts_id, newEIT->i_service_id);    DeferredProcessingAddJob(DeferredProcessEIT, newEIT );    ObjectRefDec(newEIT);}static void DeferredProcessEIT(void *arg){    dvbpsi_eit_t *eit = (dvbpsi_eit_t *)arg;    EPGServiceRef_t serviceRef;    dvbpsi_eit_event_t *event;    LogModule(LOG_DEBUG, DVBSCHEDULE, "Processing EIT (version %d) net id %x ts id %x service id %x\n",    eit->i_version, eit->i_network_id, eit->i_ts_id, eit->i_service_id);        EPGDBaseTransactionStart();    serviceRef.netId = eit->i_network_id;    serviceRef.tsId = eit->i_ts_id;    serviceRef.serviceId = eit->i_service_id;    for (event = eit->p_first_event; event; event = event->p_next)    {        ProcessEvent(&serviceRef, event);    }    ObjectRefDec(eit);    EPGDBaseTransactionCommit();}/******************************************************************************** Helper Functions                                                             ********************************************************************************/static void ProcessEvent(EPGServiceRef_t *serviceRef, dvbpsi_eit_event_t *eitevent){    EPGEvent_t epgevent;    dvbpsi_descriptor_t *descriptor;    char startTimeStr[25];    char endTimeStr[25];    epgevent.serviceRef = *serviceRef;    epgevent.eventId = eitevent->i_event_id;    ConvertToTM(&eitevent->t_start_time, &eitevent->t_duration, &epgevent.startTime, &epgevent.endTime);    epgevent.ca = eitevent->b_free_ca;    strftime(startTimeStr, sizeof(startTimeStr), "%Y-%m-%d %T", &epgevent.startTime);    strftime(endTimeStr, sizeof(startTimeStr), "%Y-%m-%d %T", &epgevent.endTime);    LogModule(LOG_DEBUG, DVBSCHEDULE, "(%x:%x:%x) Event %x Start Time %s End Time %s\n",        serviceRef->netId, serviceRef->tsId, serviceRef->serviceId, epgevent.eventId,        startTimeStr, endTimeStr);        if (EPGDBaseEventAdd(&epgevent) != 0)    {        return;    }            for (descriptor = eitevent->p_first_descriptor; descriptor; descriptor = descriptor->p_next)    {        switch(descriptor->i_tag)        {            case SHORT_EVENT_DR:                {                    char lang[4];                    char *temp;                    dvbpsi_short_event_dr_t * sed = dvbpsi_DecodeShortEventDr(descriptor);                    lang[0] = sed->i_iso_639_code[0];                    lang[1] = sed->i_iso_639_code[1];                    lang[2] = sed->i_iso_639_code[2];                    lang[3] = 0;                    temp = DVBTextToUTF8((char *)sed->i_event_name, sed->i_event_name_length);                    if (temp)                    {                        EPGDBaseDetailAdd(serviceRef, epgevent.eventId, lang, EPG_EVENT_DETAIL_TITLE, temp);                        free(temp);                    }                    temp = DVBTextToUTF8((char *)sed->i_text, sed->i_text_length);                    if (temp)                    {                        EPGDBaseDetailAdd(serviceRef, epgevent.eventId, lang, EPG_EVENT_DETAIL_DESCRIPTION, temp);                        free(temp);                    }                }                break;            case PARENTAL_RATINGS_DR:                {                    dvbpsi_parental_rating_dr_t * prd = dvbpsi_DecodeParentalRatingDr(descriptor);                    char cc[4];                    int i;                    cc[3] = 0;                                        for (i=0; i < prd->i_ratings_number; i ++)                    {                        cc[0] = prd->p_parental_rating[i].i_country_code >> 16;                        cc[1] = prd->p_parental_rating[i].i_country_code >> 8;                        cc[2] = prd->p_parental_rating[i].i_country_code >> 0;                        if (prd->p_parental_rating[i].i_rating < 0x0f)                        {                            char *rating =  RatingsTable[prd->p_parental_rating[i].i_rating];                            EPGDBaseRatingAdd(serviceRef, epgevent.eventId, cc,rating);                        }                    }                }                break;            case CRID_DR:                {                    dvbpsi_content_id_dr_t * cridd = dvbpsi_DecodeContentIdDr(descriptor);                    int i;                    char *type = NULL;                    LogModule(LOG_DEBUG, DVBSCHEDULE, "CRID Descriptor with %d entries\n", cridd->i_number_of_entries);                    for (i = 0;i < cridd->i_number_of_entries; i ++)                    {                        LogModule(LOG_DEBUG, DVBSCHEDULE, "%d) Type    : %d\n", i, cridd->p_entries[i].i_type);                        switch (cridd->p_entries[i].i_type)                        {                            case UK_FREEVIEW_CONTENT:                            case CRID_TYPE_CONTENT:                                type = "content";                                break;                            case UK_FREEVIEW_SERIES:                            case CRID_TYPE_SERIES:                                type = "series";                                break;                                                            default:                                type = NULL;                                break;                        }                        LogModule(LOG_DEBUG, DVBSCHEDULE, "%d) Location: %d\n", i, cridd->p_entries[i].i_location);                                                if (cridd->p_entries[i].i_location == CRID_LOCATION_DESCRIPTOR)                        {                            LogModule(LOG_DEBUG, DVBSCHEDULE, "%d) Path    : %s\n", i, cridd->p_entries[i].value.path);                            if (type)                            {                                if (cridd->p_entries[i].value.path[0] == '/')                                {                                    char *crid = ResolveCRID(serviceRef, (char*)cridd->p_entries[i].value.path);                                    if (crid)                                    {                                        EPGDBaseDetailAdd(serviceRef, epgevent.eventId, (char*)ISO639NoLinguisticContent,                                         type, crid);                                        free(crid);                                    }                                                                    }                                else                                {                                    EPGDBaseDetailAdd(serviceRef, epgevent.eventId, (char*)ISO639NoLinguisticContent,                                         type, (char *)cridd->p_entries[i].value.path);                                }                            }                        }                        else                        {                            LogModule(LOG_DEBUG, DVBSCHEDULE, "%d) Ref     : %d\n", i, cridd->p_entries[i].value.ref);                        }                    }                                    }                break;        }                }}static void ConvertToTM(dvbpsi_date_time_t *datetime, dvbpsi_eit_event_duration_t *duration,    struct tm *startTime, struct tm *endTime){    struct tm *temp_time;    time_t secs;    startTime->tm_year = datetime->i_year - 1900;    startTime->tm_mon  = datetime->i_month - 1;    startTime->tm_mday = datetime->i_day;    startTime->tm_hour = datetime->i_hour;    startTime->tm_min  = datetime->i_minute;    startTime->tm_sec  = datetime->i_second;    secs = mktime(startTime);        secs += (duration->i_hours * 60 * 60) + (duration->i_minutes* 60) + duration->i_seconds;    temp_time = gmtime(&secs);    *endTime = *temp_time;}static char *ResolveCRID(EPGServiceRef_t *serviceRef, char *relativeCRID){    char *result = NULL;    Service_t *service;    service = ServiceFindFQID(serviceRef->netId, serviceRef->tsId, serviceRef->serviceId);    if (service)    {        if (service->defaultAuthority)        {            asprintf(&result, "%s%s", service->defaultAuthority,relativeCRID);        }        ServiceRefDec(service);    }    return result;}

⌨️ 快捷键说明

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