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

📄 siinfo.c

📁 Parses UK Profile 1.05/1.06 Object Carousel and saves files to disk (all stored under /tmp/cache at
💻 C
📖 第 1 页 / 共 2 页
字号:
{  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 + -