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

📄 parse-mpeg.c

📁 It s a tool designed to extract as much information as possible from Bluetooth devices without the r
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (ng_debug > 1)	    fprintf(stderr,"pts: %8.3f | id 0x%02x %s\n",		    pts/90000.0,id,pes_s[id]);	if (ts)	    *ts = pts;    }    return size;}int mpeg_get_audio_rate(unsigned char *header){    int rate = 44100;    if (mpeg_getbits(header,12,1) == 1) {	/* MPEG 1.0 */	switch (mpeg_getbits(header,20,2)) {	case 0: rate  = 44100; break;	case 1: rate  = 48000; break;	case 2: rate  = 32000; break;	}	if (ng_debug)	    fprintf(stderr,"mpeg: MPEG1 audio, rate %d\n",rate);    } else {	/* MPEG 2.0 */	switch (mpeg_getbits(header,20,2)) {	case 0: rate  = 22050; break;	case 1: rate  = 24000; break;	case 2: rate  = 16000; break;	}	if (ng_debug)	    fprintf(stderr,"mpeg: MPEG2 audio, rate %d\n",rate);    }    return rate;}unsigned char* mpeg_find_audio_hdr(unsigned char *buf, int off, int size){    int i;        for (i = off; i < size-1; i++) {	if (0xff != buf[i])	    continue;	if (0xf0 == (buf[i+1] & 0xf0))	    return buf+i;    }    return NULL;}int mpeg_get_video_fmt(struct mpeg_handle *h, unsigned char *header){    if (header[0] != 0x00  ||  header[1] != 0x00  ||	header[2] != 0x01  ||  header[3] != 0xb3)	return -1;    h->vfmt.fmtid  = VIDEO_MPEG;    h->vfmt.width  = (mpeg_getbits(header,32,12) + 15) & ~15;    h->vfmt.height = (mpeg_getbits(header,44,12) + 15) & ~15;    h->ratio  = mpeg_getbits(header,56,4);    h->rate   = mpeg_getbits(header,60,4);    if (ng_debug)	fprintf(stderr,"mpeg: MPEG video, %dx%d [ratio=%s,rate=%s]\n",		h->vfmt.width, h->vfmt.height,		ratio_s[h->ratio], rate_s[h->rate]);    return 0;}int mpeg_check_video_fmt(struct mpeg_handle *h, unsigned char *header){    int width, height, ratio;    int change = 0;    if (header[0] != 0x00  ||  header[1] != 0x00  ||	header[2] != 0x01  ||  header[3] != 0xb3)	return 0;    width  = (mpeg_getbits(header,32,12) + 15) & ~15;    height = (mpeg_getbits(header,44,12) + 15) & ~15;    ratio  = mpeg_getbits(header,56,4);    if (width != h->vfmt.width || height != h->vfmt.height) {	if (ng_debug)	    fprintf(stderr,"mpeg: size change: %dx%d => %dx%d\n",		    h->vfmt.width, h->vfmt.height, width, height);	change++;    }    if (ratio != h->ratio) {	if (ng_debug)	    fprintf(stderr,"mpeg: ratio change: %s => %s\n",		    ratio_s[h->ratio], ratio_s[ratio]);	change++;    }    h->vfmt.height = height;    h->vfmt.width  = width;    h->ratio       = ratio;    return change;}/* ----------------------------------------------------------------------- *//* program streams                                                         */size_t mpeg_find_ps_packet(struct mpeg_handle *h, int packet, int mask, off_t *pos){    unsigned char *buf;    size_t size;    off_t start = *pos;    /* read header */    for (;;) {	buf = mpeg_get_data(h,*pos,16);	if (NULL == buf)	    return 0;	if (buf[0] != 0x00 ||	    buf[1] != 0x00 ||	    buf[2] != 0x01)	    return 0;	size = mpeg_getbits(buf,32,16) + 6;	/* handle special cases */	switch (buf[3]) {	case 0xba:	    /* packet start code */	    if (0x01 == mpeg_getbits(buf,32,2)) {		/* MPEG 2 */		size = 14 + mpeg_getbits(buf,109,3);	    } else if (0x02 == mpeg_getbits(buf,32,4)) {		/* MPEG 1 */		size = 12;	    } else {		/* Huh? */		return 0;	    }	    break;	case 0xb9:	    /* mpeg program end code */	    return 0;	}	if (ng_debug > 1)	    fprintf(stderr,"mpeg: packet 0x%x at 0x%08" PRIx64 "+%d [need 0x%x]\n",		    (int)buf[3],(int64_t)*pos,(int)size,packet);	/* our packet ? */	if ((buf[3] & mask) == packet)	    return size;	*pos += size;	/* don't search unlimited ... */	if (*pos - start > FILE_BUF_MIN)	    return 0;    }}/* ----------------------------------------------------------------------- *//* transport streams                                                       */static void parse_pmt_desc(unsigned char *desc, int dlen,			   struct psi_program *program, int pid){    int i,t,l;    for (i = 0; i < dlen; i += desc[i+1] +2) {	t = desc[i];	l = desc[i+1];	switch (t) {	case 0x56:	    if (!program->t_pid)		program->t_pid = pid;	    break;	}    }}static char* get_lang_tag(unsigned char *desc, int dlen){    int i,t,l;    for (i = 0; i < dlen; i += desc[i+1] +2) {	t = desc[i];	l = desc[i+1];	if (0x0a == t)	    return desc+i+2;    }    return NULL;}static void dump_data(unsigned char *data, int len){    int i;        for (i = 0; i < len; i++) {	if (isprint(data[i]))	    fprintf(stderr,"%c", data[i]);	else	    fprintf(stderr,"\\x%02x", (int)data[i]);    }}void mpeg_dump_desc(unsigned char *desc, int dlen){    int i,j,t,l,l2,l3;    for (i = 0; i < dlen; i += desc[i+1] +2) {	t = desc[i];	l = desc[i+1];	switch (t) {	case 0x0a: /* ??? (pmt) */	    fprintf(stderr," lang=%3.3s",desc+i+2);	    break;	case 0x45: /* vbi data (pmt) */	    fprintf(stderr," vbidata=");	    dump_data(desc+i+2,l);	    break;	case 0x52: /* stream identifier */	    fprintf(stderr," sid=%d",(int)desc[i+2]);	    break;	case 0x56: /* teletext (pmt) */	    fprintf(stderr," teletext=%3.3s",desc+i+2);	    break;	case 0x59: /* subtitles (pmt) */	    fprintf(stderr," subtitles=%3.3s",desc+i+2);	    break;	case 0x6a: /* ac3 (pmt) */	    fprintf(stderr," ac3");	    break;	case 0x40: /* network name (nit) */	    fprintf(stderr," name=");	    dump_data(desc+i+2,l);	    break;	case 0x43: /* satellite delivery system (nit) */	    fprintf(stderr," dvb-s");	    break;	case 0x44: /* cable delivery system (nit) */	    fprintf(stderr," dvb-c");	    break;	case 0x5a: /* terrestrial delivery system (nit) */	    fprintf(stderr," dvb-t");	    break;	case 0x48: /* service (sdt) */	    fprintf(stderr," service=%d,",desc[i+2]);	    l2 = desc[i+3];	    dump_data(desc+i+4,desc[i+3]);	    fprintf(stderr,",");	    dump_data(desc+i+l2+5,desc[i+l2+4]);	    break;	case 0x4d: /*  event (eid) */	    fprintf(stderr," short=[%3.3s|",desc+i+2);	    l2 = desc[i+5];	    l3 = desc[i+6+l2];	    dump_data(desc+i+6,l2);	    fprintf(stderr,"|");	    dump_data(desc+i+7+l2,l3);	    fprintf(stderr,"]");	    break;	case 0x4e: /*  event (eid) */	    fprintf(stderr," *ext event");	    break;	case 0x4f: /*  event (eid) */	    fprintf(stderr," *time shift event");	    break;	case 0x50: /*  event (eid) */	    fprintf(stderr," *component");	    break;	case 0x54: /*  event (eid) */	    fprintf(stderr," content=");	    for (j = 0; j < l; j+=2)		fprintf(stderr,"%s0x%02x", j ? "," : "", desc[i+j+2]);	    break;	case 0x55: /*  event (eid) */	    fprintf(stderr," *parental rating");	    break;	    	default:	    fprintf(stderr," %02x[",desc[i]);	    dump_data(desc+i+2,l);	    fprintf(stderr,"]");	}    }}int mpeg_parse_psi_pat(struct psi_info *info, unsigned char *data, int verbose){    struct list_head   *item;    struct psi_program *pr;    int tsid,pnr,version,current;    int j,len,pid;    len     = mpeg_getbits(data,12,12) + 3 - 4;    tsid    = mpeg_getbits(data,24,16);    version = mpeg_getbits(data,42,5);    current = mpeg_getbits(data,47,1);    if (!current)	return len+4;    if (info->tsid == tsid && info->pat_version == version)	return len+4;    info->tsid         = tsid;    info->pat_version  = version;    info->pat_updated  = 1;        if (verbose)	fprintf(stderr, "ts [pat]: tsid %d ver %2d [%d/%d]\n",		tsid, version,		mpeg_getbits(data,48, 8),		mpeg_getbits(data,56, 8));    for (j = 64; j < len*8; j += 32) {	pnr    = mpeg_getbits(data,j+0,16);	pid    = mpeg_getbits(data,j+19,13);	if (0 == pnr) {	    /* network */	    if (verbose > 1)		fprintf(stderr,"   pid 0x%04x [network]\n",			pid);	} else {	    /* program */	    pr = psi_program_get(info, tsid, pnr, 1);	    pr->p_pid   = pid;	    pr->updated = 1;	    pr->seen    = 1;	    if (NULL == info->pr)		info->pr = pr;	}    }    if (verbose > 1) {	list_for_each(item,&info->programs) {	    pr = list_entry(item, struct psi_program, next);	    if (pr->tsid != tsid)		continue;	    fprintf(stderr,"   pid 0x%04x => pnr %2d [program map%s]\n",		    pr->p_pid, pr->pnr,		    pr->seen ? ",seen" : "");	}	fprintf(stderr,"\n");    }    return len+4;}int mpeg_parse_psi_pmt(struct psi_program *program, unsigned char *data, int verbose){    int pnr,version,current;    int j,len,dlen,type,pid,slen;    char *lang;    len     = mpeg_getbits(data,12,12) + 3 - 4;    pnr     = mpeg_getbits(data,24,16);    version = mpeg_getbits(data,42,5);    current = mpeg_getbits(data,47,1);    if (!current)	return len+4;    if (program->pnr == pnr && program->version == version)	return len+4;    program->version = version;    program->updated = 1;    dlen = mpeg_getbits(data,84,12);    /* TODO: decode descriptor? */    if (verbose) {	fprintf(stderr,		"ts [pmt]: pnr %d ver %2d [%d/%d]  pcr 0x%04x  "		"pid 0x%04x  type %2d #",		pnr, version,		mpeg_getbits(data,48, 8),		mpeg_getbits(data,56, 8),		mpeg_getbits(data,69,13),		program->p_pid, program->type);	mpeg_dump_desc(data + 96/8, dlen);	fprintf(stderr,"\n");    }    j = 96 + dlen*8;    program->v_pid = 0;    program->a_pid = 0;    program->t_pid = 0;    memset(program->audio,0,sizeof(program->audio));    while (j < len*8) {	type = mpeg_getbits(data,j,8);	pid  = mpeg_getbits(data,j+11,13);	dlen = mpeg_getbits(data,j+28,12);	switch (type) {	case 1:	case 2:	    /* video */	    if (!program->v_pid)		program->v_pid = pid;	    break;	case 3:	case 4:	    /* audio */	    if (!program->a_pid)		program->a_pid = pid;	    lang = get_lang_tag(data + (j+40)/8, dlen);	    slen = strlen(program->audio);	    snprintf(program->audio + slen, sizeof(program->audio) - slen,		     "%s%.3s:%d", slen ? " " : "", lang ? lang : "xxx", pid);	    break;	case 6:	    /* private data */	    parse_pmt_desc(data + (j+40)/8, dlen, program, pid);	    break;	}	if (verbose > 1) {	    fprintf(stderr, "   pid 0x%04x => %-32s #",		    pid, stream_type_s[type]);	    mpeg_dump_desc(data + (j+40)/8, dlen);	    fprintf(stderr,"\n");	}	j += 40 + dlen*8;    }    if (verbose > 1)	fprintf(stderr,"\n");    return len+4;}int mpeg_parse_psi(struct psi_info *info, struct mpeg_handle *h, int verbose){    int i,tid;    if (h->ts.payload) {	for (i = h->ts.data[0]+1; i < h->ts.size;) {	    tid = mpeg_getbits(h->ts.data,i*8,8);	    switch (tid) {	    case 0:		i += mpeg_parse_psi_pat(info, h->ts.data+i, verbose);		break;	    case 1:		fprintf(stderr, "ts: conditional access\n");		return 0;	    case 2:		i += mpeg_parse_psi_pmt(info->pr, h->ts.data+i, verbose);		break;	    case 3:		fprintf(stderr, "ts: description\n");		return 0;	    case 0xff:		/* end of data */		return 0;	    default:		fprintf(stderr, "ts: unknown table id %d\n",tid);		return 0;	    }	}    }    return 0;}/* ----------------------------------------------------------------------- */int mpeg_find_ts_packet(struct mpeg_handle *h, int wanted, off_t *pos){    unsigned char *packet;    int asize = 0;    off_t start;    for (start = *pos; *pos - start < FILE_BUF_MIN; *pos += TS_SIZE) {	memset(&h->ts, 0, sizeof(h->ts));	packet = mpeg_get_data(h, *pos, TS_SIZE);	if (NULL == packet) {	    fprintf(stderr,"mpeg ts: no more data\n");	    return -1;	}	if (packet[0] != 0x47) {	    if (ng_log_bad_stream)		fprintf(stderr,"mpeg ts: warning %d: packet id mismatch\n",			h->errors);	    h->errors++;	    continue;	}	h->ts.tei      = mpeg_getbits(packet, 8,1);	h->ts.payload  = mpeg_getbits(packet, 9,1);	h->ts.pid      = mpeg_getbits(packet,11,13);	h->ts.scramble = mpeg_getbits(packet,24,2);	h->ts.adapt    = mpeg_getbits(packet,26,2);	h->ts.cont     = mpeg_getbits(packet,28,4);	if (0 == h->ts.adapt)	    /* reserved -- should discard */	    continue;	if (0x1fff == h->ts.pid)	    /* NULL packet -- discard */	    continue;	if (h->ts.pid != wanted)	    /* need something else */	    continue;	switch (h->ts.adapt) {	case 3:	    /* adaptation + payload */	    asize      = mpeg_getbits(packet,32,8) +1;	    h->ts.data = packet  + (4 + asize);	    h->ts.size = TS_SIZE - (4 + asize);	    if (h->ts.size > TS_SIZE) {		if (ng_log_bad_stream)		    fprintf(stderr,"mpeg ts: warning %d: broken adaptation"			    " size [%lx]\n",h->errors,(unsigned long)(*pos));		h->errors++;		continue;	    }	    /* fall throuth */	case 2:	    /* adaptation only */	    /* TODO: parse adaptation field */	    break;	case 1:	    /* payload only */	    h->ts.data = packet  + 4;	    h->ts.size = TS_SIZE - 4;	    break;	}	if (ng_debug > 2)	    fprintf(stderr,"mpeg ts: pl=%d pid=%d adapt=%d cont=%d size=%d [%d]\n",		    h->ts.payload, h->ts.pid, h->ts.adapt,		    h->ts.cont, h->ts.size, asize);	return 0;    }    return -1;}

⌨️ 快捷键说明

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