📄 siinfo.c
字号:
{ int i; for(i = 0; i < 256; i++) { if(sects[i]) free(sects[i]); }}static void FreeMetadataSects(struct Metadata_sect **sects){ int i; for(i = 0; i < 256; i++) { if(sects[i]) { if (sects[i]->metadata_byte) free(sects[i]->metadata_byte); free(sects[i]); sects[i]->metadata_byte = NULL; sects[i] = NULL; } }}static void ExtractMetadataSection(int card_no, int PID, char *chaname) { FILE *metadata_fd; int numsects; char dirbuf1[256]; char dirbuf2[256]; char filebuf[256]; struct Metadata_sect *metadatasects[256]; int j, i = 0; while (1) { CollectMetadataSections(card_no, PID, 0x06, metadatasects, &numsects); sprintf(dirbuf1, "%s/%s", "/tmp/cache", chaname); mkdir(dirbuf1, 0755); printf("First directory: %s\n", dirbuf1); sprintf(dirbuf2, "%s/%s/%s", "/tmp/cache", chaname, "MetadataSections"); mkdir(dirbuf2, 0755); printf("Second directory: %s\n", dirbuf2); sprintf(filebuf, "%s/%s/%s/%s%d%s%d%s", "/tmp/cache", chaname, "MetadataSections", "file_", j, "_", PID, ".mp7"); metadata_fd = fopen(filebuf, "w"); printf("numsects: %d\n", numsects); for(i = 0; i < numsects; i++) { fwrite(metadatasects[i]->metadata_byte, 1, metadatasects[i]->metadata_length, metadata_fd); } if (fclose(metadata_fd) != 0) { perror("fclose: "); exit(1); } FreeMetadataSects(metadatasects); j++; }}static void ExtractMhegInfo(int card_no, char **pmtsects, int numsects, struct dsmcc_status *status){ int i; int car_num = 0; for(i = 0; i < numsects; i++) { struct PMT_sect *psect; char *sp; char *end; if(status->debug_fd != NULL) { fprintf(status->debug_fd, "[pmtparse] Parsing PMT\n"); } psect = (struct PMT_sect *) pmtsects[i]; end = pmtsects[i] + (psect->syntax_len & 0x3ff) - 7; // skip extra program info sp = ((char*)&(psect->s)) + (ntohs(psect->res_program_info_length) & 0xfff); while(sp < end) { struct PMT_stream *s = (struct PMT_stream *) sp; if(status->debug_fd != NULL) { fprintf(status->debug_fd, "[pmtparse] Stream Type %X\n",s->stream_type); } if(s->stream_type == 0xB) { // ISO/IEC 13818-6 Type B (DSMCC) uint8_t *descr; unsigned int data_id = 0 ; /* TODO these can probably be */ unsigned int component_tag = 0; /* legally set to 0 ? Check spec. */ unsigned long carousel_id = 0; unsigned short app_type_code; unsigned char boot_pri_hint, app_data_length, format_id; char *app_data; for(descr = s->descrs; descr < s->descrs + (ntohs(s->res_ES_info_len) & 0xfff); descr += descr[1] + 2) { if(descr[0] == DATA_BROADCAST_ID) { int length = descr[1]; data_id = descr[2] << 8 | descr[3]; if(data_id == UK_MHEG_DATA) { int index = 4; while(index < length+2) { /* Only 1 app defined... */ app_type_code = descr[index] << 8 | descr[index+1]; index+=2; boot_pri_hint = descr[index++]; app_data_length = descr[index++]; app_data = (char *)malloc(app_data_length); memcpy(app_data, descr+index, app_data_length); /* TODO BBC Parliament seems to have some data here, * no idea what as UKProfile 1.05 says there is * no app data defined. */ } /* TODO verify / save this data */ } else if(data_id == MHP_DATA) { /* MHP Object Carousel */// syslog(LOG_ERR, "MHP Object Carousel data_broadcast_id"); int index = 4; while(index < length) { app_type_code = descr[index] << 8 | descr[index+1]; index+=2; } } } else if(descr[0] == DATA_STREAM) { component_tag = descr[2]; } else if(descr[0] == DATA_CAROUSEL_ID) { /* Set carousel this stream belongs to */ carousel_id = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | descr[5]; format_id = descr[6]; if(format_id == 0x00) { /* Standard Boot - do nothing */ } else if(format_id == 0x01) { /* Enhanced Boot - TODO handle! */ } } else { // syslog(LOG_ERR, "Descriptor - %X", descr[0]); } } /* Now save stream info to correct carousel. If no carousel * descriptor / data_broadcast_id descriptor given we cannot * guess where to save it to yet, so we save the details to * a list of known channels, where it can be collected from later * from information in DSI/DII messages. * If we have data_broadcast_id but no carousel_id we create a * new carousel but do not assign a carousel_id, when parsing the * DSI message we try and find which stream * Hmm, the teletext stream does not send a carousel_id for either * of its carousels... luckily it has no other streams for each * but if it did not sure how to identify which belongs to which */ if(data_id != 0) { struct stream *str = (struct stream *)malloc(sizeof(struct stream)); /* New object carousel */ if(carousel_id) { /* Hurrah! We can create a new object carousel with all the info */ status->carousels[car_num].id = carousel_id; /* TODO Init cache from saved data */ str->pid = ntohs(s->res_PID) & 0x1fff; str->assoc_tag = component_tag; str->next = str->prev = NULL; status->carousels[car_num].streams = str; if(status->debug_fd != NULL) { fprintf(status->debug_fd, "[pmtparse] Initing carousel %d to pid %d (tag %X)\n", car_num, str->pid, str->assoc_tag); } car_num++; } else { /* Hmmm, no carousel_id, set to zero and find out * later hopefully (this is all for you teletext) */ status->carousels[car_num].id = 0; /* TODO Init cache from saved data */ str->pid = ntohs(s->res_PID) & 0x1fff; str->assoc_tag = component_tag; str->next = str->prev = NULL; status->carousels[car_num].streams = str; if(status->debug_fd != NULL) { fprintf(status->debug_fd, "[pmtparse] Initing carousel %d to pid %d (tag %X)\n", car_num, str->pid, str->assoc_tag); } car_num++; } } else { /* New stream belong to unknown carousel */ struct stream *str= (struct stream *)malloc(sizeof(struct stream)); str->pid = ntohs(s->res_PID) & 0x1fff; str->assoc_tag = component_tag; if(status->debug_fd != NULL) { fprintf(status->debug_fd, "[pmtparse] Unassigned stream on pid %d (tag %X)\n", str->pid, str->assoc_tag); } if(status->newstreams == NULL) { status->newstreams = str; str->prev = NULL; } else { struct stream *last; for(last=status->newstreams;last->next!=NULL;last=last->next) {;} last->next = str; str->prev = last; } str->next = NULL; } } else if(s->stream_type == 0x18) { /* Metadata carried in ISO/IEC 1318-6 (DSM-CC) Object Carousel */ uint8_t *descr; unsigned int data_id = 0 ; /* TODO these can probably be */ unsigned int component_tag = 0; /* legally set to 0 ? Check spec. */ unsigned long carousel_id = 0; unsigned short app_type_code; unsigned char boot_pri_hint, app_data_length, format_id; char *app_data; for(descr = s->descrs; descr < s->descrs + (ntohs(s->res_ES_info_len) & 0xfff); descr += descr[1] + 2) { if(descr[0] == DATA_BROADCAST_ID) { int length = descr[1]; data_id = descr[2] << 8 | descr[3]; if(data_id == UK_MHEG_DATA) { int index = 4; while(index < length+2) { /* Only 1 app defined... */ app_type_code = descr[index] << 8 | descr[index+1]; index+=2; boot_pri_hint = descr[index++]; app_data_length = descr[index++]; app_data = (char *)malloc(app_data_length); memcpy(app_data, descr+index, app_data_length); /* TODO BBC Parliament seems to have some data here, * no idea what as UKProfile 1.05 says there is * no app data defined. */ } /* TODO verify / save this data */ } else if(data_id == MHP_DATA) { /* MHP Object Carousel */// syslog(LOG_ERR, "MHP Object Carousel data_broadcast_id"); int index = 4; while(index < length+2) { app_type_code = descr[index] << 8 | descr[index+1]; index+=2; } } } else if(descr[0] == DATA_STREAM) { component_tag = descr[2]; } else if(descr[0] == DATA_CAROUSEL_ID) { /* Set carousel this stream belongs to */ carousel_id = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | descr[5]; format_id = descr[6]; if(format_id == 0x00) { /* Standard Boot - do nothing */ } else if(format_id == 0x01) { /* Enhanced Boot - TODO handle! */ } } else { // syslog(LOG_ERR, "Descriptor - %X", descr[0]); } } /* Now save stream info to correct carousel. If no carousel * descriptor / data_broadcast_id descriptor given we cannot * guess where to save it to yet, so we save the details to * a list of known channels, where it can be collected from later * from information in DSI/DII messages. * If we have data_broadcast_id but no carousel_id we create a * new carousel but do not assign a carousel_id, when parsing the * DSI message we try and find which stream * Hmm, the teletext stream does not send a carousel_id for either * of its carousels... luckily it has no other streams for each * but if it did not sure how to identify which belongs to which */ if(data_id != 0) { struct stream *str = (struct stream *)malloc(sizeof(struct stream)); /* New object carousel */ if(carousel_id) { /* Hurrah! We can create a new object carousel with all the info */ status->carousels[car_num].id = carousel_id; /* TODO Init cache from saved data */ str->pid = ntohs(s->res_PID) & 0x1fff; str->assoc_tag = component_tag; str->next = str->prev = NULL; status->carousels[car_num].streams = str; syslog(LOG_ERR, "Initing carousel %d to pid %d", car_num, str->pid); car_num++; } else { /* Hmmm, no carousel_id, set to zero and find out * later hopefully (this is all for you teletext) */ status->carousels[car_num].id = 0; /* TODO Init cache from saved data */ str->pid = ntohs(s->res_PID) & 0x1fff; str->assoc_tag = component_tag; str->next = str->prev = NULL; status->carousels[car_num].streams = str; syslog(LOG_ERR, "Initing carousel %d to pid %d", car_num, str->pid); car_num++; } } else { /* New stream belong to unknown carousel */ struct stream *str= (struct stream *)malloc(sizeof(struct stream)); str->pid = ntohs(s->res_PID) & 0x1fff;// syslog(LOG_ERR, "Creating stream on pid %d", str->pid); str->assoc_tag = component_tag; if(status->newstreams == NULL) { status->newstreams = str; str->prev = NULL; } else { struct stream *last; for(last=status->newstreams;last->next!=NULL;last=last->next) {;} last->next = str; str->prev = last; } str->next = NULL; } } else if(s->stream_type == 0x16) { ; /* Metadata carried in Metadata Section */printf("------------------ METADATA carried in MetadataSection ----------------------------------------------"); uint8_t *descr; int pidchild; for(descr = s->descrs; descr < s->descrs + (ntohs(s->res_ES_info_len) & 0xfff); descr += descr[1] + 2) { printf("PID: %d\n", ntohs(s->res_PID) & 0x1fff); //ExtractMetadataSTDDescr(descr); pidchild = fork(); if (pidchild == 0) { printf("Child Process!\n"); ExtractMetadataSection(card_no, ntohs(s->res_PID) & 0x1fff, status->name); } else if (pidchild == -1) { perror("FORK "); exit(1); } else { printf("Parent Process!\n"); Pids.pids[++Pids.pidCount] = pidchild; } } } else if(s->stream_type == 0xD) { ; /* TODO ISO/IEC 13818-6 Type D */ } else if(s->stream_type == 0x6) { ; /* TODO PES packets video/audio */ } else if(s->stream_type == 0x5) { uint8_t *descr;// syslog(LOG_ERR, "Detected MHP stream carrying AIT (PID %d)",// ntohs(s->res_PID) & 0x1ffff); for(descr = s->descrs; descr < s->descrs + (ntohs(s->res_ES_info_len) & 0xfff); descr += descr[1] + 2) { if(descr[0] == MHP_BROADCAST_ID) { int length = descr[1]; int index = 2; FILE *ait_fd; char *aitsects[256]; int numsects; ait_fd = fopen("/tmp/ait.version.descr", "a"); while(index < length+2) { int type = descr[index++]; int version = descr[index++] & 0x1F; fprintf(ait_fd, "AIT sub table type %d version %d\n", type, version); /* fprintf(ait_fd, "AIT sub tabla tipo %d version %d", type, version): */ } fclose(ait_fd); /* Receive AIT sections from stream and write to /tmp * TODO - process AIT table */ CollectSections(card_no, ntohs(s->res_PID) & 0x1fff, 0x74, aitsects, &numsects); if(aitsects != NULL) { ait_fd = fopen("/tmp/ait.table", "a"); for(i = 0;i < numsects; i++) { fwrite(aitsects[i], 1, 1024, ait_fd); } fclose(ait_fd); FreeSects(aitsects); } /* This pid has the AIT sections as described above. Subscribe to pid and build up the AIT table. */ } } } sp += (ntohs(s->res_ES_info_len) & 0xfff) + 5; } }}/* * Extract descriptors from PMT ( no vpid in all cases so cannot use that as * a fallback ). */static int FindMhegInfoInPMT(int card_no, int pid, struct dsmcc_status *status){ int ret = -1; char *pmtsects[256]; int numsects; ret = CollectSections(card_no, pid, 0x02, pmtsects, &numsects); if(ret) goto bail; ExtractMhegInfo(card_no, pmtsects, numsects, status); bail: FreeSects(pmtsects); return ret;}/* * find the ttxt_info in the PMT via the PAT, try first with the SID * and if that fails with the VPID * return <> 0 on error; */int GetMhegInfo(int card_no, unsigned short sid, struct dsmcc_status *status){ int ret; char *patsects[256]; int numsects; int i; int j; uint16_t pmt_pid = 0; if(status->debug_fd != NULL) { fprintf(status->debug_fd, "[pmtparse] Collecting MhegInfo\n"); } ret = CollectSections(card_no, 0, 0, patsects, &numsects); if(ret) { syslog(LOG_ERR, "MhegInfo ret - %d", ret); goto bail; } if(status->debug_fd != NULL) { fprintf(status->debug_fd, "[pmtparse] SID - %d\n", sid); } if(sid != 0) { int found; for(i = 0, found = 0; i < numsects && !found; i++) { int numdescrs; struct PAT_sect *s = (struct PAT_sect *) patsects[i]; numdescrs = ((ntohs(s->syntax_len) & 0x3FF) - 7) / 4; /* Mapping Pid to channel number */ for(j = 0; j < numdescrs && !found; j++) { uint16_t pno = ntohs(s->d[j].program_number); if(pno == 0) continue; // network pid if(status->debug_fd != NULL) { fprintf(status->debug_fd, "[pmtparse] Program Number %d / Pid %d\n", pno, ntohs(s->d[j].res_PMTPID) & 0x1fff); } if(pno == sid) { /* Found our channel ? */ pmt_pid = ntohs(s->d[j].res_PMTPID) & 0x1fff; if(status->debug_fd != NULL) { fprintf(status->debug_fd, "[pmtparse] Found Correct channel, retrieving PMT on %d\n", pmt_pid); } found = 1; } } } } if(pmt_pid != 0) { ret = FindMhegInfoInPMT(card_no, pmt_pid, status); } bail: syslog(LOG_ERR, "Bailed"); FreeSects(patsects); return ret;}void KillMetadataPids() { int i; // Loop throught pid_array and kill all sons' pids printf("pid_count = %d\n", Pids.pidCount); //int count = pid_count; //for (int i = 0; i <= count; i++) { for (i = 0; i <= Pids.pidCount; i++) { printf("pid to kill = %d\n", Pids.pids[i]); if (kill(Pids.pids[i], SIGKILL) < 0) { perror("Kill ERROR "); exit(1); } } Pids.pidCount = -1;}void ResetMetadataPids() { Pids.pidCount = -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -