+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <getopt.h>
-#include <iconv.h>
-#include <time.h>
-
-#include "ts.h"
-#include "psi.h"
-#include "sdt.h"
-#include "sdtt.h"
-#include "eit.h"
-#include "tot.h"
-#include "dsmcc.h"
-#include "ts_ctl.h"
-#include "util.h"
-
-typedef struct _ContentTYPE{
- char *japanese ;
- char *english ;
-}CONTENT_TYPE;
-
-#define CAT_COUNT 16
-static CONTENT_TYPE ContentCatList[CAT_COUNT] = {
- { "ニュース・報道", "news" },
- { "スポーツ", "sports" },
- { "情報", "information" },
- { "ドラマ", "drama" },
- { "音楽", "music" },
- { "バラエティ", "variety" },
- { "映画", "cinema" },
- { "アニメ・特撮", "anime" },
- { "ドキュメンタリー・教養", "documentary" },
- { "演劇", "stage" },
- { "趣味・実用", "hobby" },
- { "福祉", "welfare" },
- { "予備", "etc" },
- { "予備", "etc" },
- { "予備", "etc" },
- { "その他", "etc" }
-};
-
-
-SVT_CONTROL *svttop = NULL;
-DSM_CONTROL dsmctl[1024];
-#define SECCOUNT 64
-static unsigned char *base64 = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-static void base64_char(unsigned long bb, int srclen, unsigned char *dest, int j)
-{
- int x, i, base;
-
- /* 最終位置の計算 */
- for ( i = srclen; i < 2; i++ )
- bb <<= 8;
-
- /* BASE64変換 */
- for ( base = 18, x = 0; x < srclen + 2; x++, base -= 6) {
- dest[j++] = base64[ (unsigned long)((bb>>base) & 0x3F) ];
- }
-
- /* 端数の判断 */
- for ( i = x; i < 4; i++ ) {
- dest[j++] = (unsigned char)'='; /* 端数 */
- }
-
-}
-
-static void base64_encode(unsigned char *dest, const unsigned char *src, int len)
-{
- unsigned char *p = src;
- unsigned long bb = (unsigned long)0;
- int i = 0, j = 0;
-
- while (len--)
- {
- bb <<= 8;
- bb |= (unsigned long)*p;
-
- /* 24bit単位に編集 */
- if (i == 2) {
- base64_char(bb, i, dest, j);
-
- j = j + 4;
- i = 0;
- bb = 0;
- } else
- i++;
-
- p++;
- }
-
- /* 24bitに満たない場合 */
- if (i) base64_char(bb, i - 1, dest, j);
-
-}
-
-void xmlspecialchars(char *str)
-{
- strrep(str, "&", "&");
- strrep(str, "'", "'");
- strrep(str, "\"", """);
- strrep(str, "<", "<");
- strrep(str, ">", ">");
-}
-
-
-
-void GetSDT(FILE *infile, SVT_CONTROL *svttop, SECcache *secs,
- int count, STATION **station, int * station_count, char *header, int is_logo)
-{
- SECcache *bsecs;
- int pmtpids[SECCOUNT];
- memset(pmtpids, 0, sizeof(pmtpids));
- int dsmccpids[SECCOUNT];
- memset(dsmccpids, 0, sizeof(dsmccpids));
- int i = 0 , downloadDataId = 0;
-
- while((bsecs = readTS(infile, secs, count)) != NULL) {
- /* SDT */
- if((bsecs->pid & 0xFF) == 0x11) {
- dumpSDT(bsecs->buf, svttop, station, station_count, header);
- }
- /* TOT */
- else if((bsecs->pid & 0xFF) == 0x14) {
- dumpTOT(bsecs->buf);
- }
- /* SDTT */
- //else if((bsecs->pid & 0xFF) == 0x23) {
- // dumpSDTT(bsecs->buf, *station, *station_count);
- //}
- /* BIT */
- else if((bsecs->pid & 0xFF) == 0x24) {
- dumpBIT(bsecs->buf);
- }
- /* CDT */
- else if((bsecs->pid & 0xFF) == 0x29) {
- dumpCDT(bsecs->buf, *station, *station_count);
- }
- else if ( is_logo ) {
- /* PAT */
- if((bsecs->pid & 0xFF) == 0x00) {
- dumpPAT(bsecs->buf, secs, count, pmtpids);
- }
- /* PMT */
- for ( i = 1; i < SECCOUNT; i++ ) {
- if ( pmtpids[i] == 0 ) {
- break;
- }
- /* PMT specified by PAT */
- if ( bsecs->pid == pmtpids[i] ) {
- dumpPMT(bsecs->buf, secs, count, dsmccpids);
- }
- }
- /* DSM-CC */
- for ( i = 0; i < SECCOUNT; i++ ) {
- if ( dsmccpids[i] == 0 ) {
- break;
- }
- /* DSM-CC specified by PMT */
- if ( bsecs->pid == dsmccpids[i] ) {
- dumpDSMCC(bsecs->buf, &downloadDataId, &dsmctl);
- }
- }
- }
- }
-}
-
-void GetEIT(FILE *infile, FILE *outfile, STATION *psta, SECcache *secs)
-{
- SECcache *bsecs;
- EIT_CONTROL *eitcur ;
- EIT_CONTROL *eitnext ;
- EIT_CONTROL *eittop = NULL;
- time_t l_time ;
- time_t end_time ;
- struct tm tl ;
- struct tm *endtl ;
- char cendtime[32];
- char cstarttime[32];
-
- char title[1024];
- char subtitle[1024];
- char desc[102400] = {0};
- char Category[1024];
- char VideoType[1024];
- char AudioType[1024];
-
- memset(secs, 0, sizeof(SECcache) * SECCOUNT);
- secs[0].pid = 0x12; /* EIT */
- secs[1].pid = 0x26; /* EIT */
- secs[2].pid = 0x27; /* EIT */
-
- eittop = calloc(1, sizeof(EIT_CONTROL));
- eitcur = eittop ;
- fseek(infile, 0, SEEK_SET);
- while((bsecs = readTS(infile, secs, SECCOUNT)) != NULL) {
- /* EIT */
- if((bsecs->pid & 0xFF) == 0x12) {
- dumpEIT(bsecs->buf, psta->svId, psta->onId, psta->tsId, eittop);
- }else if((bsecs->pid & 0xFF) == 0x26) {
- dumpEIT(bsecs->buf, psta->svId, psta->onId, psta->tsId, eittop);
- }else if((bsecs->pid & 0xFF) == 0x27) {
- dumpEIT(bsecs->buf, psta->svId, psta->onId, psta->tsId, eittop);
- }
- }
- eitcur = eittop ;
- while(eitcur != NULL){
- if(!eitcur->servid){
- eitcur = eitcur->next ;
- continue ;
- }
- if(eitcur->content_type > CAT_COUNT){
- eitcur->content_type = CAT_COUNT -1 ;
- }
- memset(title, '\0', sizeof(title));
- strcpy(title, eitcur->title);
- xmlspecialchars(title);
-
- memset(subtitle, '\0', sizeof(subtitle));
- strcpy(subtitle, eitcur->subtitle);
- xmlspecialchars(subtitle);
-
- memset(desc, '\0', sizeof(desc));
- if ( eitcur->desc ) {
- strcpy(desc, eitcur->desc);
- xmlspecialchars(desc);
- }
-
- memset(Category, '\0', sizeof(Category));
- strcpy(Category, ContentCatList[eitcur->content_type].japanese);
- xmlspecialchars(Category);
-
- memset(VideoType, '\0', sizeof(VideoType));
- strcpy(VideoType, parseComponentDescType(eitcur->video_type));
- xmlspecialchars(VideoType);
-
- memset(AudioType, '\0', sizeof(AudioType));
- strcpy(AudioType, parseAudioComponentDescType(eitcur->audio_type));
- xmlspecialchars(AudioType);
-
- tl.tm_sec = eitcur->ss ;
- tl.tm_min = eitcur->hm ;
- tl.tm_hour = eitcur->hh ;
- tl.tm_mday = eitcur->dd ;
- tl.tm_mon = (eitcur->mm - 1);
- tl.tm_year = (eitcur->yy - 1900);
- tl.tm_wday = 0;
- tl.tm_isdst = 0;
- tl.tm_yday = 0;
- l_time = mktime(&tl);
- if((eitcur->ehh == 0) && (eitcur->emm == 0) && (eitcur->ess == 0)){
- (void)time(&l_time);
- end_time = l_time + (60 * 5); // 5分後に設定
- endtl = localtime(&end_time);
- }else{
- end_time = l_time + eitcur->ehh * 3600 + eitcur->emm * 60 + eitcur->ess;
- endtl = localtime(&end_time);
- }
- memset(cendtime, '\0', sizeof(cendtime));
- memset(cstarttime, '\0', sizeof(cstarttime));
- strftime(cendtime, (sizeof(cendtime) - 1), "%Y%m%d%H%M%S", endtl);
- strftime(cstarttime, (sizeof(cstarttime) - 1), "%Y%m%d%H%M%S", &tl);
-
- fprintf(outfile, " <programme start=\"%s +0900\" stop=\"%s +0900\" channel=\"%s\" event=\"%d\">\n",
- cstarttime, cendtime, psta->ontv, eitcur->event_id);
- fprintf(outfile, " <title lang=\"ja_JP\">%s</title>\n", title);
- fprintf(outfile, " <desc lang=\"ja_JP\">%s</desc>\n", subtitle);
- fprintf(outfile, " <longdesc lang=\"ja_JP\">%s</longdesc>\n", desc);
- fprintf(outfile, " <category lang=\"ja_JP\">%s</category>\n", Category);
- fprintf(outfile, " <video type=\"%d\">%s</video>\n", eitcur->video_type, VideoType);
- fprintf(outfile, " <audio type=\"%d\" multi=\"%d\">%s</audio>\n", eitcur->audio_type, eitcur->multi_type, AudioType);
- //fprintf(outfile, " <category lang=\"en\">%s</category>\n", ContentCatList[eitcur->content_type].english);
- fprintf(outfile, " </programme>\n");
-#if 0
- fprintf(outfile, "(%x:%x:%x)%s,%s,%s,%s,%s,%s\n",
- eitcur->servid, eitcur->table_id, eitcur->event_id,
- cstarttime, cendtime,
- title, subtitle,
- Category,
- ContentCatList[eitcur->content_type].english);
-
- fprintf(outfile, "(%x:%x)%04d/%02d/%02d,%02d:%02d:%02d,%02d:%02d:%02d,%s,%s,%s,%s\n",
- eitcur->table_id, eitcur->event_id,
- eitcur->yy, eitcur->mm, eitcur->dd,
- eitcur->hh, eitcur->hm, eitcur->ss,
- eitcur->ehh, eitcur->emm, eitcur->ess,
- eitcur->title, eitcur->subtitle,
- ContentCatList[eitcur->content_type].japanese,
- ContentCatList[eitcur->content_type].english);
-#endif
- eitnext = eitcur->next ;
- free(eitcur->title);
- free(eitcur->subtitle);
- free(eitcur);
- eitcur = eitnext ;
- }
- free(eittop);
- eittop = NULL;
-}
-
-void checkSta(STATION **station,int *stalength){
- STATION *statmp;
- int chl[90];
- int chlt = 0;
- int stal = 0;
- STATION * statin = *station;
- statmp = malloc( sizeof(STATION) * 2 );
- for (int i = 0 ; i < *stalength ; i++){
- int noidinchl = 1;
- for (int j = 0 ; j < chlt ; j++){
- if ( chl[j] == statin[i].svId ) {
- noidinchl = 0;
- }
- }
- if ( noidinchl == 1 ) {
- statmp = realloc(statmp, (stal+1) * sizeof(STATION));
- statmp[stal] = statin[i];
- chl[chlt] = statin[i].svId;
- chlt++;
- stal++;
- }
- }
- *station = statmp;
- *stalength = stal;//ここいらが怪しい
- //memcpy(statin,statmp,chlt*sizeof(STATION));
- //free(statmp);
- return;
-}
-
-int main(int argc, char *argv[])
-{
-
- FILE *infile = stdin;
- FILE *outfile = stdout;
- char *arg_onTV ;
- int staCount ;
- int inclose = 0;
- int outclose = 0;
- SVT_CONTROL *svtcur ;
- SVT_CONTROL *svtsave ;
- SECcache secs[SECCOUNT];
- int lp ;
- STATION *pStas ;
- int act = 0;
- int i , j, k ;
- int is_logo = 0;
- SDTTdata sdtd;
- SDTTdataLoop *loop;
- SDTTdataService *service;
-
- memset(dsmctl, 0, sizeof(dsmctl));
-
- if(argc == 5 && strcmp(argv[1], "/LOGO") == 0){
- argc--;
- argv[1] = argv[2];
- argv[2] = argv[3];
- argv[3] = argv[4];
- is_logo = 1;
- }
- if(argc == 4){
- arg_onTV = argv[1];
- if(strcmp(argv[2], "-")) {
- infile = fopen(argv[2], "r");
- if ( !infile) {
- printf( "tsFile not found (Can't open file: %s)\n", argv[2] );
- exit( -1 );
- }
- inclose = 1;
- }
- else {
- infile = stdin;
- }
- if(strcmp(argv[3], "-")) {
- outfile = fopen(argv[3], "w+");
- if ( !outfile) {
- printf( "xmlFile not found (Can't open file: %s)\n", argv[3] );
- exit( -1 );
- }
- outclose = 1;
- }
- else {
- outfile = stdout;
- }
- }else{
- fprintf(stdout, "Usage : %s (/LOGO) {/BS|/CS|<id>} <tsFile> <outfile>\n", argv[0]);
- fprintf(stdout, "\n");
- fprintf(stdout, "/LOGO ロゴ取得モード。独立して指定し、番組表の出力を行ないません。\n");
- fprintf(stdout, " 必要なTSの長さ 地上波は10分 BS/CSは20分です。\n");
- fprintf(stdout, "id チャンネル識別子。地上波の物理チャンネルを与えます。\n");
- fprintf(stdout, "/BS BSモード。一つのTSからBS全局のデータを読み込みます。\n");
- fprintf(stdout, "/CS CSモード。一つのTSから複数局のデータを読み込みます。\n");
- fprintf(stdout, "/TIME 時刻合わせモード。TSからTOT(Time Offset Table)を読み込みます。\n");
- fprintf(stdout, " recpt1 <任意> 10(秒以上) - | epgdump /TIME - <任意>の形で使用してください。\n");
- fprintf(stdout, " TOTは5秒に1回しか来ないため、recpt1に与える時間をある程度長くしてください。\n");
-/*
- fprintf(stdout, " ontvcode Channel identifier (ex. ****.ontvjapan.com)\n");
- fprintf(stdout, " /BS BS mode\n");
- fprintf(stdout, " This mode reads the data of all BS TV stations\n");
- fprintf(stdout, " from one TS data.\n");
- fprintf(stdout, " /CS CS mode\n");
- fprintf(stdout, " This mode reads the data of two or more CS TV stations\n");
- fprintf(stdout, " from one TS data.\n");
-*/
- return 0;
- }
-
- pStas = NULL;
- staCount = 0;
- svttop = calloc(1, sizeof(SVT_CONTROL));
- act = 0 ;
-
- /* 興味のあるpidを指定 */
- if ( is_logo ) {
- memset(secs, 0, sizeof(SECcache) * SECCOUNT);
- secs[0].pid = 0x00; /* PAT */
- secs[1].pid = 0x11; /* SDT */
- secs[2].pid = 0x29; /* CDT */
- }
- else {
- memset(secs, 0, sizeof(SECcache) * SECCOUNT);
- secs[0].pid = 0x00; /* PAT */
- secs[1].pid = 0x11; /* SDT */
- secs[2].pid = 0x12; /* EIT */
- secs[3].pid = 0x23; /* SDTT */
- secs[4].pid = 0x26; /* EIT */
- secs[5].pid = 0x27; /* EIT */
- secs[6].pid = 0x29; /* CDT */
- }
-
- if(strcmp(arg_onTV, "/TIME") == 0){
- printf("TSに載っている時刻データは2秒ほど早めてあるのかもしれません。\n");
- memset(secs, 0, sizeof(SECcache) * SECCOUNT);
- secs[0].pid = 0x14; /* TOT */
-
- GetSDT(infile, NULL, secs, SECCOUNT,NULL, NULL,NULL, 0);
-
- goto cleanup;
- }else if(strcmp(arg_onTV, "/BS") == 0){
- char *head = "BS";
- GetSDT(infile, svttop, secs, SECCOUNT, &pStas, &staCount, head, is_logo);
- }else if(strcmp(arg_onTV, "/CS") == 0){
- char *head = "CS";
- GetSDT(infile, svttop, secs, SECCOUNT, &pStas, &staCount, head, is_logo);
- }else if(strcmp(arg_onTV, "/TEST") == 0){
- memset(secs, 0, sizeof(SECcache) * SECCOUNT);
- secs[0].pid = 0x24; /* BIT */
-
- char *head = "TEST";
- GetSDT(infile, svttop, secs, SECCOUNT, &pStas, &staCount, head, 0);
- //if (sta_count)
- // printf("Station count: %d\n1st ontv=%s,name=%s\n",staCount, pStas[0].ontv, pStas[0].name);
- }else{
- GetSDT(infile, svttop, secs, SECCOUNT, &pStas, &staCount, arg_onTV, 0);
-
- // 地上波のマルチチャンネル対応のためコメントアウト
- /*
- act = 1 ;
- svttop = calloc(1, sizeof(SVT_CONTROL));
- GetSDT(infile, svttop, secs, SECCOUNT);
- svtcur = svttop->next ; //先頭
- if(svtcur == NULL){
- free(svttop);
- return 1;
- }
-
- pStas = calloc(1, sizeof(STATION));
- pStas->tsId = svtcur->transport_stream_id ;
- pStas->onId = svtcur->original_network_id ;
- pStas->svId = svtcur->event_id ;
- pStas->ontv = arg_onTV ;
- pStas->name = svtcur->servicename ;
- staCount = 1;
- */
- }
- checkSta(&pStas, &staCount);
-
- fprintf(outfile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- fprintf(outfile, "<!DOCTYPE tv SYSTEM \"xmltv.dtd\">\n\n");
- fprintf(outfile, "<tv generator-info-name=\"tsEPG2xml\" generator-info-url=\"http://localhost/\">\n");
-
- char ServiceName[1024];
- char Logo[8192];
-
- if ( is_logo ) {
- memset(Logo, '\0', sizeof(Logo));
- for(lp = 0 ; lp < staCount ; lp++){
- for ( i = 0 ; i < 6 ; i++) {
- if (pStas[lp].logo_array[i].logo) {
- base64_encode(Logo, pStas[lp].logo_array[i].logo, pStas[lp].logo_array[i].logo_size);
- xmlspecialchars(Logo);
- fprintf(outfile, " <logo ts=\"%d\" on=\"%d\" sv=\"%d\" type=\"%d\">%s</logo>\n",
- pStas[lp].tsId,
- pStas[lp].onId,
- pStas[lp].svId,
- i,
- Logo);
- }
- }
- }
-
- for ( i = 0; i < 1024; i++) {
- if ( dsmctl[i].isUsed == 0 ) break;
- parseSDTTdata(dsmctl[i].blockData, &sdtd);
-
- for (j = 0; j < sdtd.number_of_loop; j++) {
- loop = sdtd.loop + sizeof(SDTTdataLoop) * j;
-
- for ( k = 0; k < loop->number_of_services; k++) {
- service = loop->services + sizeof(SDTTdataService) * k;
-
- /*
- for(lp = 0 ; lp < staCount ; lp++){
- if (
- pStas[lp].tsId == service->transport_stream_id &&
- pStas[lp].onId == service->original_network_id &&
- pStas[lp].svId == service->service_id
- ) {
- clt2png(loop->data,
- &pStas[lp].logo_array[sdtd.logo_type].logo,
- &pStas[lp].logo_array[sdtd.logo_type].logo_size);
- }
- }
- */
-
- #if 0
- printf( "SDTTdataLoop (%d:%d) %d:%d[%d:%d:%d]%d\n",
- i, j,
- sdtd.logo_type,
- loop->logo_id,
- service->transport_stream_id,
- service->original_network_id,
- service->service_id,
- loop->data_size
- );
- #endif
-
-
- void* logo = NULL;
- int logo_size = 0;
-
- clt2png(loop->data, &logo, &logo_size);
- memset(Logo, '\0', sizeof(Logo));
- base64_encode(Logo, logo, logo_size);
- xmlspecialchars(Logo);
-
- fprintf(outfile, " <logo ts=\"%d\" on=\"%d\" sv=\"%d\" type=\"%d\" dlid=\"%d\">%s</logo>\n",
- service->transport_stream_id,
- service->original_network_id,
- service->service_id,
- sdtd.logo_type,
- loop->logo_id,
- Logo);
- }
-
- }
- }
- }
- for(lp = 0 ; lp < staCount ; lp++){
- memset(ServiceName, '\0', sizeof(ServiceName));
- strcpy(ServiceName, pStas[lp].name);
- xmlspecialchars(ServiceName);
-
- fprintf(outfile, " <channel id=\"%s\">\n", pStas[lp].ontv);
- fprintf(outfile, " <display-name lang=\"ja_JP\">%s</display-name>\n", ServiceName);
- fprintf(outfile, " <id ts=\"%d\" on=\"%d\" sv=\"%d\"/>\n", pStas[lp].tsId, pStas[lp].onId, pStas[lp].svId);
-
- fprintf(outfile, " </channel>\n");
- }
- if ( is_logo ) {
- fprintf(outfile, "</tv>\n");
- goto cleanup;
- }
- for(lp = 0 ; lp < staCount ; lp++){
- GetEIT(infile, outfile, &pStas[lp], secs);
- }
- fprintf(outfile, "</tv>\n");
-cleanup:
- if(inclose) {
- fclose(infile);
- }
- if(outclose) {
- fclose(outfile);
- }
- if(act){
- free(pStas);
- svtcur = svttop ; //先頭
- while(svtcur != NULL){
- svtsave = svtcur->next ;
- free(svtcur);
- svtcur = svtsave ;
- }
- }
-
- return 0;
-}
-