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

📄 parse-mpeg.c

📁 It s a tool designed to extract as much information as possible from Bluetooth devices without the r
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * parse mpeg program + transport streams. * */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <iconv.h>#include <inttypes.h>#include "grab-ng.h"#include "parse-mpeg.h"#define FILE_BUF_MIN       (512*1024)#define FILE_BUF_MAX    (8*1024*1024)#define FILE_BLKSIZE        (16*1024)#ifndef PRId64# warning Hmm, your C99 support is incomplete, will guess (should be ok for 32bit archs)# define PRId64 "lld"# define PRIx64 "llx"# define PRIu64 "llu"#endifint  ng_mpeg_vpid    = 0;int  ng_mpeg_apid    = 0;int  ng_read_timeout = 3; /* seconds *//* ----------------------------------------------------------------------- *//* static data                                                             */int mpeg_rate_n[16] = {    [ 1 ] = 24000,    [ 2 ] = 24000,    [ 3 ] = 25000,    [ 4 ] = 30000,    [ 5 ] = 30000,    [ 6 ] = 50000,    [ 7 ] = 60000,    [ 8 ] = 60000,};int mpeg_rate_d[16] = {    [ 1 ] = 1001,    [ 2 ] = 1000,    [ 3 ] = 1000,    [ 4 ] = 1001,    [ 5 ] = 1000,    [ 6 ] = 1000,    [ 7 ] = 1001,    [ 8 ] = 1000,};static char *rate_s[16] = {    [        0 ] = "illegal",    [        1 ] = "24000/1001",    [        2 ] = "24",    [        3 ] = "25",    [        4 ] = "30000/1001",    [        5 ] = "30",    [        6 ] = "50",    [        7 ] = "60000/1001",    [        8 ] = "60",    [ 9 ... 15 ] = "reserved",};static char *ratio_s[] = {    [        0 ] = "illegal",    [        1 ] = "square sample",    [        2 ] = "3:4",    [        3 ] = "9:16",    [        4 ] = "1:2,21",    [ 5 ... 15 ] = "reserved",};const char *mpeg_frame_s[] = {    [ NG_FRAME_UNKNOWN ] = "unknown",    [ NG_FRAME_I_FRAME ] = "I frame",    [ NG_FRAME_P_FRAME ] = "P frame",    [ NG_FRAME_B_FRAME ] = "B frame",};static const char *pes_s[] = {    [ 0x00 ... 0xff ] = "*UNKNOWN* stream",    [ 0xbc          ] = "program stream map",    [ 0xbd          ] = "private stream 1",    [ 0xbe          ] = "padding stream",    [ 0xbf          ] = "private stream 2",    [ 0xc0 ... 0xdf ] = "audio stream",    [ 0xe0 ... 0xef ] = "video stream",    [ 0xf0          ] = "ECM stream",    [ 0xf1          ] = "EMM stream",    [ 0xf2          ] = "DSMCC stream",    [ 0xf3          ] = "13522 stream",    [ 0xf4          ] = "H.222.1 type A",    [ 0xf5          ] = "H.222.1 type B",    [ 0xf6          ] = "H.222.1 type C",    [ 0xf7          ] = "H.222.1 type D",    [ 0xf8          ] = "H.222.1 type E",    [ 0xf9          ] = "ancillary stream",    [ 0xfa ... 0xfe ] = "reserved data stream",    [ 0xff          ] = "program stream directory",};static const char *stream_type_s[] = {    [ 0x00          ] = "reserved",    [ 0x01          ] = "ISO 11172     Video",    [ 0x02          ] = "ISO 13818-2   Video",    [ 0x03          ] = "ISO 11172     Audio",    [ 0x04          ] = "ISO 13818-3   Audio",    [ 0x05          ] = "ISO 13818-1   private sections",    [ 0x06          ] = "ISO 13818-1   private data",    [ 0x07          ] = "ISO 13522     MHEG",    [ 0x08          ] = "ISO 13818-1   Annex A DSS CC",    [ 0x09          ] = "ITU-T H.222.1",    [ 0x0a          ] = "ISO 13818-6   type A",    [ 0x0b          ] = "ISO 13818-6   type B",    [ 0x0c          ] = "ISO 13818-6   type C",    [ 0x0d          ] = "ISO 13818-6   type D",    [ 0x0e          ] = "ISO 13818-6   auxiliary",    [ 0x0f ... 0x7f ] = "reserved",    [ 0x80 ... 0xff ] = "user private",};/* ----------------------------------------------------------------------- */char *psi_charset[0x20] = {    [ 0x00 ... 0x1f ] = "reserved",    [ 0x00 ] = "ISO-8859-1",    [ 0x01 ] = "ISO-8859-5",    [ 0x02 ] = "ISO-8859-6",    [ 0x03 ] = "ISO-8859-7",    [ 0x04 ] = "ISO-8859-8",    [ 0x05 ] = "ISO-8859-9",    [ 0x06 ] = "ISO-8859-10",    [ 0x07 ] = "ISO-8859-11",    [ 0x08 ] = "ISO-8859-12",    [ 0x09 ] = "ISO-8859-13",    [ 0x0a ] = "ISO-8859-14",    [ 0x0b ] = "ISO-8859-15",    [ 0x10 ] = "fixme",    [ 0x11 ] = "UCS-2BE",        // correct?    [ 0x12 ] = "EUC-KR",    [ 0x13 ] = "GB2312",    [ 0x14 ] = "BIG5"};char *psi_service_type[0x100] = {    [ 0x00 ... 0xff ] = "reserved",    [ 0x80 ... 0xfe ] = "user defined",    [ 0x01 ] = "digital television service",    [ 0x02 ] = "digital radio sound service",    [ 0x03 ] = "teletext service",    [ 0x04 ] = "NVOD reference service",    [ 0x05 ] = "NVOD time-shifted service",    [ 0x06 ] = "mosaic service",    [ 0x07 ] = "PAL coded signal",    [ 0x08 ] = "SECAM coded signal",    [ 0x09 ] = "D/D2-MAC",    [ 0x0a ] = "FM Radio",    [ 0x0b ] = "NTSC coded signal",    [ 0x0c ] = "data broadcast service",    [ 0x0d ] = "reserved for CI",    [ 0x0e ] = "RCS Map",    [ 0x0f ] = "RCS FLS",    [ 0x10 ] = "DVB MHP service",};/* ----------------------------------------------------------------------- *//* handle psi_ structs                                                     */struct psi_info* psi_info_alloc(void){    struct psi_info *info;    info = malloc(sizeof(*info));    memset(info,0,sizeof(*info));    INIT_LIST_HEAD(&info->streams);    INIT_LIST_HEAD(&info->programs);    info->pat_version = PSI_NEW;    info->sdt_version = PSI_NEW;    info->nit_version = PSI_NEW;    return info;}void psi_info_free(struct psi_info *info){    struct psi_program *program;    struct psi_stream  *stream;    struct list_head   *item,*safe;    list_for_each_safe(item,safe,&info->streams) {	stream = list_entry(item, struct psi_stream, next);	list_del(&stream->next);	free(stream);    }    list_for_each_safe(item,safe,&info->programs) {	program = list_entry(item, struct psi_program, next);	list_del(&program->next);	free(program);    }    free(info);}struct psi_stream* psi_stream_get(struct psi_info *info, int tsid, int alloc){    struct psi_stream *stream;    struct list_head  *item;    list_for_each(item,&info->streams) {        stream = list_entry(item, struct psi_stream, next);	if (stream->tsid == tsid)	    return stream;    }    if (!alloc)	return NULL;    stream = malloc(sizeof(*stream));    memset(stream,0,sizeof(*stream));    stream->tsid    = tsid;    stream->updated = 1;    list_add_tail(&stream->next,&info->streams);    return stream;}struct psi_program* psi_program_get(struct psi_info *info, int tsid,				    int pnr, int alloc){    struct psi_program *program;    struct list_head   *item;    list_for_each(item,&info->programs) {        program = list_entry(item, struct psi_program, next);	if (program->tsid == tsid &&	    program->pnr  == pnr)	    return program;    }    if (!alloc)	return NULL;    program = malloc(sizeof(*program));    memset(program,0,sizeof(*program));    program->tsid    = tsid;    program->pnr     = pnr;    program->version = PSI_NEW;    program->updated = 1;    list_add_tail(&program->next,&info->programs);    return program;}/* ----------------------------------------------------------------------- *//* bit fiddeling                                                           */unsigned int mpeg_getbits(unsigned char *buf, int start, int count){    unsigned int result = 0;    unsigned char bit;    while (count) {	result <<= 1;	bit      = 1 << (7 - (start % 8));	result  |= (buf[start/8] & bit) ? 1 : 0;	start++;	count--;    }    return result;}void hexdump(char *prefix, unsigned char *data, size_t size){    char ascii[17];    int i;    for (i = 0; i < size; i++) {	if (0 == (i%16)) {	    fprintf(stderr,"%s%s%04x:",		    prefix ? prefix : "",		    prefix ? ": "   : "",		    i);	    memset(ascii,0,sizeof(ascii));	}	if (0 == (i%4))	    fprintf(stderr," ");	fprintf(stderr," %02x",data[i]);	ascii[i%16] = isprint(data[i]) ? data[i] : '.';	if (15 == (i%16))	    fprintf(stderr," %s\n",ascii);    }    if (0 != (i%16)) {	while (0 != (i%16)) {	    if (0 == (i%4))		fprintf(stderr," ");	    fprintf(stderr,"   ");	    i++;	};	fprintf(stderr," %s\n",ascii);    }}/* ----------------------------------------------------------------------- *//* common code                                                             */struct mpeg_handle* mpeg_init(void){    struct mpeg_handle *h;        h = malloc(sizeof(*h));    if (NULL == h)	return NULL;    memset(h,0,sizeof(*h));    h->fd     = -1;    h->pgsize = getpagesize();    h->init   = 1;    return h;}void mpeg_fini(struct mpeg_handle *h){    if (h->vbuf)	ng_release_video_buf(h->vbuf);    if (-1 != h->fd)	close(h->fd);    if (h->buffer)	free(h->buffer);    free(h);}unsigned char* mpeg_get_data(struct mpeg_handle *h, off_t pos, size_t size){    fd_set set;    struct timeval tv;    off_t  low;    size_t rdbytes;    int rc;        if (pos < h->boff) {	/* shouldn't happen */	fprintf(stderr,"mpeg: panic: seek backwards [pos=%ld,boff=%ld]\n",		(long)pos,(long)h->boff);	exit(1);    }    low = 0;    if (!h->init && pos > h->init_offset*6) {	if (h->video_offset > h->init_offset &&	    h->audio_offset > h->init_offset)	    low = (h->video_offset < h->audio_offset)		? h->video_offset : h->audio_offset;	else if (h->audio_offset > h->init_offset)	    low = h->audio_offset;	else if (h->video_offset > h->init_offset)	    low = h->video_offset;    }        if (low > h->boff + h->balloc*3/4  &&	low < h->boff + h->bsize       &&	!h->beof) {	/* move data window */	rdbytes = (low - h->boff) & ~(h->pgsize - 1);	memmove(h->buffer, h->buffer + rdbytes, h->balloc - rdbytes);	h->boff  += rdbytes;	h->bsize -= rdbytes;	if (ng_debug)	    fprintf(stderr,"mpeg: %dk file buffer shift\n", (int)(rdbytes >> 10));    }        while (pos+size + 2*TS_SIZE > h->boff + h->balloc  &&  !h->beof) {	/* enlarge buffer */	if (0 == h->bsize) {	    h->balloc = FILE_BUF_MIN;	    h->buffer = malloc(h->balloc);	} else {	    h->balloc *= 2;	    if (h->balloc > FILE_BUF_MAX) {		fprintf(stderr,"mpeg: panic: file buffer limit exceeded "			"(l=%d,b=%d,v=%d,a=%d)\n",			FILE_BUF_MAX,(int)h->balloc,			(int)h->video_offset,(int)h->audio_offset);		exit(1);	    }	    h->buffer  = realloc(h->buffer,h->balloc);	}	if (ng_debug)	    fprintf(stderr,"mpeg: %dk file buffer\n",(int)(h->balloc >> 10));    }    while (pos+size > h->boff + h->bsize) {	if (h->beof)	    return NULL;	/* read data */	rdbytes  = h->balloc - h->bsize;	if (rdbytes > FILE_BLKSIZE)	    rdbytes = FILE_BLKSIZE;	rdbytes -= rdbytes % TS_SIZE;	rc = read(h->fd, h->buffer + h->bsize, rdbytes);	switch (rc) {	case -1:	    switch (errno) {	    case EAGAIN:		/* must wait for data ... */		if (!h->init) {		    if (ng_log_resync)			fprintf(stderr,"mpeg: sync: must wait for data\n");		    h->slowdown++;		}		FD_ZERO(&set);		FD_SET(h->fd,&set);		tv.tv_sec  = ng_read_timeout;		tv.tv_usec = 0;		switch (select(h->fd+1,&set,NULL,NULL,&tv)) {		case -1:		    fprintf(stderr,"mpeg: select: %s\n",strerror(errno));		    h->beof = 1;		    break;		case 0:		    fprintf(stderr,"mpeg: select: timeout (%d sec)\n",			    ng_read_timeout);		    h->beof = 1;		    break;		}		break;	    case EOVERFLOW:		if (ng_log_resync)		    fprintf(stderr,"mpeg: sync: kernel buffer overflow\n");		break;	    default:		fprintf(stderr,"mpeg: read: %s [%d]\n",strerror(errno),errno);		h->beof = 1;		break;	    }	    break;	case 0:	    if (ng_debug)		fprintf(stderr,"mpeg: EOF\n");	    h->beof = 1;	    break;	default:	    h->bsize += rc;	    break;	}    }    return h->buffer + (pos - h->boff);}size_t mpeg_parse_pes_packet(struct mpeg_handle *h, unsigned char *packet,			     uint64_t *ts, int *al){    uint64_t pts, dts;    int id;    size_t size;    int i, val;    pts = 0;    dts = 0;    id  = 0;    *al = 0;        for (i = 48; i < 48 + 8*16; i += 8)	if (0xff != mpeg_getbits(packet,i,8))	    break;    if (mpeg_getbits(packet,i,2) == 0x02) {	/* MPEG 2 */	id   = mpeg_getbits(packet, i-24, 8);	*al  = mpeg_getbits(packet, i+ 5, 1);	size = mpeg_getbits(packet, i+16, 8);	size += i/8 + 3;	switch (mpeg_getbits(packet, i+8, 2)) {	case 3:	    dts  = (uint64_t)mpeg_getbits(packet, i + 68,  3) << 30;	    dts |= (uint64_t)mpeg_getbits(packet, i + 72, 15) << 15;	    dts |= (uint64_t)mpeg_getbits(packet, i + 88, 15);	    /* fall */	case 2:	    pts  = (uint64_t)mpeg_getbits(packet, i + 28,  3) << 30;	    pts |= (uint64_t)mpeg_getbits(packet, i + 32, 15) << 15;	    pts |= (uint64_t)mpeg_getbits(packet, i + 48, 15);	    break;	}	if (ng_debug > 2)	    fprintf(stderr,"mpeg2 pes: pl=%d al=%d copy=%d orig=%d ts=%d hl=%d | "		    " pts=%" PRIx64 " dts=%" PRIx64 " size=%d\n",		    mpeg_getbits(packet, i - 16, 16),		    mpeg_getbits(packet, i +  5,  1),		    mpeg_getbits(packet, i +  6,  1),		    mpeg_getbits(packet, i +  7,  1),		    mpeg_getbits(packet, i +  8,  2),		    mpeg_getbits(packet, i + 16,  8),		    pts, dts, (int)size);	if (ng_debug > 3) {	    hexdump("mpeg2 pes",packet,32);	    fprintf(stderr,"--\n");	}    } else {	/* MPEG 1 */	if (mpeg_getbits(packet,i,2) == 0x01)	    i += 16;	val = mpeg_getbits(packet,i,8);	if ((val & 0xf0) == 0x20) {	    pts  = (uint64_t)mpeg_getbits(packet, i +  4,  3) << 30;	    pts |= (uint64_t)mpeg_getbits(packet, i +  8, 15) << 15;	    pts |= (uint64_t)mpeg_getbits(packet, i + 24, 15);	    i += 40;	} else if ((val & 0xf0) == 0x30) {	    pts  = (uint64_t)mpeg_getbits(packet, i +  4,  3) << 30;	    pts |= (uint64_t)mpeg_getbits(packet, i +  8, 15) << 15;	    pts |= (uint64_t)mpeg_getbits(packet, i + 24, 15);	    i += 80;	} else if (val == 0x0f)	    i += 8;	size = i/8;    }    if (pts) {

⌨️ 快捷键说明

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