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

📄 atsctoepg.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, USAatsctoepg.cPlugin to collect EPG schedule information from ATSC/PSIP.*/#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/atsc/ett.h"#include "dvbpsi/atsc/eit.h"#include "list.h"#include "logging.h"#include "subtableprocessor.h"#include "atsctext.h"#include "tuning.h"#include "deferredproc.h"/******************************************************************************** Defines                                                                      ********************************************************************************/#define MAX_EITS 128 /* Maximum number of EIT tables (PIDs) */#define MAX_ETTS 128 /* Maximum number of ETT tables (PIDs) *//******************************************************************************** Typedefs                                                                     ********************************************************************************/typedef struct TableInfo_s{    uint16_t pid;    dvbpsi_handle decoder;}TableInfo_t;/******************************************************************************** Prototypes                                                                   ********************************************************************************/static void InitEITFilter(PIDFilter_t *filter);static void DeinitEITFilter(PIDFilter_t *filter);static void NewMGT(dvbpsi_atsc_mgt_t *newMGT);static void NewSTT(dvbpsi_atsc_stt_t *newSTT);static int ATSCtoEPGFilterPacket(PIDFilter_t *pidfilter, void *arg, uint16_t pid, TSPacket_t *packet);static TSPacket_t * ATSCtoEPGProcessPacket(PIDFilter_t *pidfilter, void *arg, TSPacket_t *packet);static void ATSCtoEPGMultiplexChanged(PIDFilter_t *pidfilter, void *arg, Multiplex_t *newmultiplex);static void ClearTableInfo(void);static void SubTableHandler(void * arg, dvbpsi_handle demuxHandle, uint8_t tableId, uint16_t extension);static void ProcessETT(void *arg, dvbpsi_atsc_ett_t *newETT);static void ProcessEIT(void *arg, dvbpsi_atsc_eit_t *newEIT);static void DeferredProcessEIT(void *arg);static void DeferredProcessETT(void *arg);static void ProcessEvent(EPGServiceRef_t *serviceRef, dvbpsi_atsc_eit_event_t *event);static void DumpDescriptor(char *prefix, dvbpsi_descriptor_t *descriptor);static void ConvertToTM(uint32_t startSeconds, uint32_t duration,    struct tm *startTime, struct tm *endTime);/******************************************************************************** Global variables                                                             ********************************************************************************/static PluginFilter_t filter = {NULL, InitEITFilter, DeinitEITFilter};static const char ATSCTOEPG[] = "ATSCtoEPG";static uint8_t GPStoUTCSecondsOffset = 14; /* From the test streams 24th May 2007 */static int EventInfoTableCount = 0;static TableInfo_t EventInfoTableInfo[MAX_EITS];static int ExtendedTextTableCount = 0;static TableInfo_t ExtendedTextTableInfo[MAX_ETTS];static time_t UnixEpochOffset = 315964800;/******************************************************************************** Plugin Setup                                                                 ********************************************************************************/#ifdef __CYGWIN__#define PluginInterface ATSCtoEPGPluginInterface#endifPLUGIN_FEATURES(    PLUGIN_FEATURE_FILTER(filter),    PLUGIN_FEATURE_MGTPROCESSOR(NewMGT),    PLUGIN_FEATURE_STTPROCESSOR(NewSTT)    );PLUGIN_INTERFACE_F(    PLUGIN_FOR_ATSC,    "ATSCtoEPG", "0.1",     "Plugin to capture ATSC EPG schedule information.",     "charrea6@users.sourceforge.net"    );/******************************************************************************** Filter Functions                                                             ********************************************************************************/static void InitEITFilter(PIDFilter_t *filter){    filter->name = "ATSC to EPG";    filter->enabled = TRUE;    PIDFilterFilterPacketSet(filter, ATSCtoEPGFilterPacket, NULL);    PIDFilterMultiplexChangeSet(filter, ATSCtoEPGMultiplexChanged, NULL);    PIDFilterProcessPacketSet(filter, ATSCtoEPGProcessPacket, NULL);   }static void DeinitEITFilter(PIDFilter_t *filter){    filter->enabled = FALSE;    ClearTableInfo();}static void ClearTableInfo(void){    int i;    for (i = 0; i < EventInfoTableCount; i ++)    {        dvbpsi_DetachDemux(EventInfoTableInfo[i].decoder);    }    EventInfoTableCount = 0;    for (i = 0; i < ExtendedTextTableCount; i ++)    {        dvbpsi_atsc_DetachETT(ExtendedTextTableInfo[i].decoder);    }    ExtendedTextTableCount = 0;}static void NewMGT(dvbpsi_atsc_mgt_t *newMGT){    dvbpsi_atsc_mgt_table_t * table;    ClearTableInfo();    for (table = newMGT->p_first_table; table; table = table->p_next)    {        if ((table->i_type >= 0x100) && (table->i_type <= 0x17f))        {            EventInfoTableInfo[EventInfoTableCount].pid = table->i_pid;            EventInfoTableInfo[EventInfoTableCount].decoder = dvbpsi_AttachDemux(SubTableHandler, NULL);            EventInfoTableCount ++;        }        if ((table->i_type >= 0x200) && (table->i_type <= 0x27f))        {            ExtendedTextTableInfo[ExtendedTextTableCount].pid = table->i_pid;            ExtendedTextTableInfo[ExtendedTextTableCount].decoder = dvbpsi_atsc_AttachETT(ProcessETT, NULL);            ExtendedTextTableCount ++;        }            }}static void NewSTT(dvbpsi_atsc_stt_t *newSTT){    GPStoUTCSecondsOffset = newSTT->i_gps_utc_offset;}static int ATSCtoEPGFilterPacket(PIDFilter_t *pidfilter, void *arg, uint16_t pid, TSPacket_t *packet){    int i;    for (i = 0; i < EventInfoTableCount; i ++)    {        if (EventInfoTableInfo[i].pid == pid)        {            return TRUE;        }    }    for (i = 0; i < ExtendedTextTableCount; i ++)    {        if (ExtendedTextTableInfo[i].pid == pid)        {            return TRUE;        }    }        return FALSE;}static void ATSCtoEPGMultiplexChanged(PIDFilter_t *pidfilter, void *arg, Multiplex_t *newmultiplex){    ClearTableInfo();}static TSPacket_t * ATSCtoEPGProcessPacket(PIDFilter_t *pidfilter, void *arg, TSPacket_t *packet){    int i;    uint16_t pid = TSPACKET_GETPID(*packet);    for (i = 0; i < EventInfoTableCount; i ++)    {        if (EventInfoTableInfo[i].pid == pid)        {            dvbpsi_PushPacket(EventInfoTableInfo[i].decoder, (uint8_t*)packet);        }    }    for (i = 0; i < ExtendedTextTableCount; i ++)    {        if (ExtendedTextTableInfo[i].pid == pid)        {            dvbpsi_PushPacket(ExtendedTextTableInfo[i].decoder, (uint8_t*)packet);                    }    }    return NULL;}static void SubTableHandler(void * arg, dvbpsi_handle demuxHandle, uint8_t tableId, uint16_t extension){    dvbpsi_atsc_AttachEIT(demuxHandle, tableId, extension, ProcessEIT, NULL);}static void ProcessETT(void *arg, dvbpsi_atsc_ett_t *newETT){    DeferredProcessingAddJob(DeferredProcessETT, newETT);    ObjectRefDec(newETT);    }static void ProcessEIT(void *arg, dvbpsi_atsc_eit_t *newEIT){    DeferredProcessingAddJob(DeferredProcessEIT, newEIT);    ObjectRefDec(newEIT);}static void DeferredProcessEIT(void *arg){    dvbpsi_atsc_eit_t *eit = (dvbpsi_atsc_eit_t *)arg;    Multiplex_t *multiplex = TuningCurrentMultiplexGet();    EPGServiceRef_t serviceRef;    dvbpsi_atsc_eit_event_t *event;    LogModule(LOG_DEBUG, ATSCTOEPG, "Processing EIT (version %d) source id %x\n",    eit->i_version, eit->i_source_id);        EPGDBaseTransactionStart();    serviceRef.netId = multiplex->networkId;    serviceRef.tsId = multiplex->tsId;    serviceRef.serviceId = eit->i_source_id;    for (event = eit->p_first_event; event; event = event->p_next)    {        ProcessEvent(&serviceRef, event);    }    ObjectRefDec(eit);    EPGDBaseTransactionCommit();    MultiplexRefDec(multiplex);}static void DeferredProcessETT(void *arg){    ATSCMultipleStrings_t *description;    dvbpsi_atsc_ett_t *ett = (dvbpsi_atsc_ett_t*) arg;    Multiplex_t *multiplex = TuningCurrentMultiplexGet();    EPGServiceRef_t serviceRef;    unsigned int eventId;     char lang[4];    int i;        serviceRef.netId = multiplex->networkId;    serviceRef.tsId = multiplex->tsId;    serviceRef.serviceId = (ett->i_etm_id >> 16) & 0xffff;    eventId = (ett->i_etm_id & 0xffff) >> 2;    lang[3] = 0;    EPGDBaseTransactionStart();        description = ATSCMultipleStringsConvert(ett->p_etm, ett->i_etm_length);    LogModule(LOG_DEBUG, ATSCTOEPG,"Processing ETT for %04x.%04x.%04x.%04x (%08x): Number of strings %d\n",        serviceRef.netId, serviceRef.tsId, serviceRef.serviceId, eventId,ett->i_etm_id, description->number_of_strings);    for (i = 0; i < description->number_of_strings; i ++)    {                LogModule(LOG_DEBUG, ATSCTOEPG, "%d : (%c%c%c) %s\n",            i + 1, description->strings[i].lang[0],description->strings[i].lang[1],description->strings[i].lang[2],            description->strings[i].text);        lang[0] = description->strings[i].lang[0];        lang[1] = description->strings[i].lang[1];        lang[2] = description->strings[i].lang[2];        EPGDBaseDetailAdd(&serviceRef,eventId, lang, EPG_EVENT_DETAIL_DESCRIPTION,description->strings[i].text);    }    EPGDBaseTransactionCommit();    ObjectRefDec(description);    MultiplexRefDec(multiplex);        ObjectRefDec(ett);}/******************************************************************************** Helper Functions                                                             ********************************************************************************/static void ProcessEvent(EPGServiceRef_t *serviceRef, dvbpsi_atsc_eit_event_t *eitevent){    EPGEvent_t epgevent;    dvbpsi_descriptor_t *descriptor;    char startTimeStr[25];    char endTimeStr[25];    ATSCMultipleStrings_t *title;    int i;    char lang[4];        epgevent.serviceRef = *serviceRef;    epgevent.eventId = eitevent->i_event_id;    ConvertToTM(eitevent->i_start_time, eitevent->i_length_seconds, &epgevent.startTime, &epgevent.endTime);    epgevent.ca = FALSE;    strftime(startTimeStr, sizeof(startTimeStr), "%Y-%m-%d %T", &epgevent.startTime);    strftime(endTimeStr, sizeof(startTimeStr), "%Y-%m-%d %T", &epgevent.endTime);    LogModule(LOG_DEBUG, ATSCTOEPG, "Processing EIT for %04x.%04x.%04x.%04x Start Time %s (%d) End Time %s (duration %d) Title Length %d ETM location=%d\n",        serviceRef->netId, serviceRef->tsId, serviceRef->serviceId, epgevent.eventId,        startTimeStr,eitevent->i_start_time, endTimeStr,eitevent->i_length_seconds, eitevent->i_title_length, eitevent->i_etm_location);        if (EPGDBaseEventAdd(&epgevent) != 0)    {        return;    }    lang[3] = 0;    title = ATSCMultipleStringsConvert(eitevent->i_title, eitevent->i_title_length);    for (i = 0; i < title->number_of_strings; i ++)    {                LogModule(LOG_DEBUG, ATSCTOEPG, "%d : (%c%c%c) %s\n",            i + 1, title->strings[i].lang[0],title->strings[i].lang[1],title->strings[i].lang[2],            title->strings[i].text);        lang[0] = title->strings[i].lang[0];        lang[1] = title->strings[i].lang[1];        lang[2] = title->strings[i].lang[2];        EPGDBaseDetailAdd(serviceRef,epgevent.eventId, lang, EPG_EVENT_DETAIL_TITLE,title->strings[i].text);    }    ObjectRefDec(title);        LogModule(LOG_DEBUGV, ATSCTOEPG, "Start of Descriptors\n");    for (descriptor = eitevent->p_first_descriptor; descriptor; descriptor = descriptor->p_next)    {        DumpDescriptor("\t", descriptor);    }    LogModule(LOG_DEBUGV, ATSCTOEPG, "End of Descriptors:\n");    }static void ConvertToTM(uint32_t startSeconds, uint32_t duration,    struct tm *startTime, struct tm *endTime){    struct tm *temp_time;    time_t secs;    secs = startSeconds + UnixEpochOffset - GPStoUTCSecondsOffset;    temp_time = gmtime(&secs);    *startTime = *temp_time;        secs += duration;    temp_time = gmtime(&secs);    *endTime = *temp_time;}static void DumpDescriptor(char *prefix, dvbpsi_descriptor_t *descriptor){    int i;    char line[(16 * 3) + 1];    line[0] = 0;    LogModule(LOG_DEBUGV, ATSCTOEPG, "%sTag : 0x%02x (Length %d)\n", prefix, descriptor->i_tag, descriptor->i_length);    for (i = 0; i < descriptor->i_length; i ++)    {        if (i && ((i % 16) == 0))        {            LogModule(LOG_DEBUGV, ATSCTOEPG, "%s%s\n", prefix, line);            line[0] = 0;        }        sprintf(line + strlen(line), "%02x ", descriptor->p_data[i]);    }    if (line[0])    {        LogModule(LOG_DEBUGV, ATSCTOEPG, "%s%s\n", prefix, line);    }}

⌨️ 快捷键说明

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