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

📄 mpeg2dec.c

📁 mpeg2 decoder filter过滤服务端
💻 C
📖 第 1 页 / 共 2 页
字号:
		    bytes = (x);				\		} else {					\		    memcpy (header + bytes, buf, end - buf);	\		    state_bytes = bytes + end - buf;		\		    return 0;					\		}						\	    } else {						\		memcpy (head_buf, header, bytes);		\		state = DEMUX_HEADER;				\		state_bytes = bytes;				\		return 0;					\	    }							\	}							\    } while (0)#define DONEBYTES(x)		\    do {			\	if (header != head_buf)	\	    buf = header + (x);	\    } while (0)    if (flags & DEMUX_PAYLOAD_START)	goto payload_start;    switch (state) {    case DEMUX_HEADER:	if (state_bytes > 0) {	    header = head_buf;	    bytes = state_bytes;	    goto continue_header;	}	break;    case DEMUX_DATA:	if (demux_pid || (state_bytes > end - buf)) {	    decode_mpeg2 (buf, end);	    state_bytes -= end - buf;	    return 0;	}	decode_mpeg2 (buf, buf + state_bytes);	buf += state_bytes;	break;    case DEMUX_SKIP:	if (demux_pid || (state_bytes > end - buf)) {	    state_bytes -= end - buf;	    return 0;	}	buf += state_bytes;	break;    }    while (1) {	if (demux_pid) {	    state = DEMUX_SKIP;	    return 0;	}    payload_start:	header = buf;	bytes = end - buf;    continue_header:	NEEDBYTES (4);	if (header[0] || header[1] || (header[2] != 1)) {	    if (demux_pid) {		state = DEMUX_SKIP;		return 0;	    } else if (header != head_buf) {		buf++;		goto payload_start;	    } else {		header[0] = header[1];		header[1] = header[2];		header[2] = header[3];		bytes = 3;		goto continue_header;	    }	}	if (demux_pid) {	    if ((header[3] >= 0xe0) && (header[3] <= 0xef))		goto pes;	    fprintf (stderr, "bad stream id %x\n", header[3]);	    exit (1);	}	switch (header[3]) {	case 0xb9:	/* program end code */	    /* DONEBYTES (4); */	    /* break;         */	    return 1;	case 0xba:	/* pack header */	    NEEDBYTES (5);	    if ((header[4] & 0xc0) == 0x40) {	/* mpeg2 */		NEEDBYTES (14);		len = 14 + (header[13] & 7);		NEEDBYTES (len);		DONEBYTES (len);		/* header points to the mpeg2 pack header */	    } else if ((header[4] & 0xf0) == 0x20) {	/* mpeg1 */		NEEDBYTES (12);		DONEBYTES (12);		/* header points to the mpeg1 pack header */	    } else {		fprintf (stderr, "weird pack header\n");		DONEBYTES (5);	    }	    break;	default:	    if (header[3] == demux_track) {	    pes:		NEEDBYTES (7);		if ((header[6] & 0xc0) == 0x80) {	/* mpeg2 */		    NEEDBYTES (9);		    len = 9 + header[8];		    NEEDBYTES (len);		    /* header points to the mpeg2 pes header */		    if (header[7] & 0x80) {			uint32_t pts, dts;			pts = (((header[9] >> 1) << 30) |			       (header[10] << 22) | ((header[11] >> 1) << 15) |			       (header[12] << 7) | (header[13] >> 1));			dts = (!(header[7] & 0x40) ? pts :			       (((header[14] >> 1) << 30) |				(header[15] << 22) |				((header[16] >> 1) << 15) |				(header[17] << 7) | (header[18] >> 1)));			mpeg2_tag_picture (mpeg2dec, pts, dts);		    }		} else {	/* mpeg1 */		    int len_skip;		    uint8_t * ptsbuf;		    len = 7;		    while (header[len - 1] == 0xff) {			len++;			NEEDBYTES (len);			if (len > 23) {			    fprintf (stderr, "too much stuffing\n");			    break;			}		    }		    if ((header[len - 1] & 0xc0) == 0x40) {			len += 2;			NEEDBYTES (len);		    }		    len_skip = len;		    len += mpeg1_skip_table[header[len - 1] >> 4];		    NEEDBYTES (len);		    /* header points to the mpeg1 pes header */		    ptsbuf = header + len_skip;		    if ((ptsbuf[-1] & 0xe0) == 0x20) {			uint32_t pts, dts;			pts = (((ptsbuf[-1] >> 1) << 30) |			       (ptsbuf[0] << 22) | ((ptsbuf[1] >> 1) << 15) |			       (ptsbuf[2] << 7) | (ptsbuf[3] >> 1));			dts = (((ptsbuf[-1] & 0xf0) != 0x30) ? pts :			       (((ptsbuf[4] >> 1) << 30) |				(ptsbuf[5] << 22) | ((ptsbuf[6] >> 1) << 15) |				(ptsbuf[7] << 7) | (ptsbuf[18] >> 1)));			mpeg2_tag_picture (mpeg2dec, pts, dts);		    }		}		DONEBYTES (len);		bytes = 6 + (header[4] << 8) + header[5] - len;		if (demux_pid || (bytes > end - buf)) {		    decode_mpeg2 (buf, end);		    state = DEMUX_DATA;		    state_bytes = bytes - (end - buf);		    return 0;		} else if (bytes > 0) {		    decode_mpeg2 (buf, buf + bytes);		    buf += bytes;		}	    } else if (header[3] < 0xb9) {		fprintf (stderr,			 "looks like a video stream, not system stream\n");		DONEBYTES (4);	    } else {		NEEDBYTES (6);		DONEBYTES (6);		bytes = (header[4] << 8) + header[5];		if (bytes > end - buf) {		    state = DEMUX_SKIP;		    state_bytes = bytes - (end - buf);		    return 0;		}		buf += bytes;	    }	}    }}static void ps_loop (void){    uint8_t * buffer = (uint8_t *) malloc (buffer_size);    uint8_t * end;    if (buffer == NULL)	exit (1);    do {	end = buffer + fread (buffer, 1, buffer_size, in_file);	if (demux (buffer, end, 0))	    break;	/* hit program_end_code */    } while (end == buffer + buffer_size && !sigint);    free (buffer);}static int pva_demux (uint8_t * buf, uint8_t * end){    static int state = DEMUX_SKIP;    static int state_bytes = 0;    static uint8_t head_buf[15];    uint8_t * header;    int bytes;    int len;    switch (state) {    case DEMUX_HEADER:        if (state_bytes > 0) {            header = head_buf;            bytes = state_bytes;            goto continue_header;        }        break;    case DEMUX_DATA:        if (state_bytes > end - buf) {            decode_mpeg2 (buf, end);            state_bytes -= end - buf;            return 0;        }        decode_mpeg2 (buf, buf + state_bytes);        buf += state_bytes;        break;    case DEMUX_SKIP:        if (state_bytes > end - buf) {            state_bytes -= end - buf;            return 0;        }        buf += state_bytes;        break;    }    while (1) {    payload_start:	header = buf;	bytes = end - buf;    continue_header:	NEEDBYTES (2);	if (header[0] != 0x41 || header[1] != 0x56) {	    if (header != head_buf) {		buf++;		goto payload_start;	    } else {		header[0] = header[1];		bytes = 1;		goto continue_header;	    }	}	NEEDBYTES (8);	if (header[2] != 1) {	    DONEBYTES (8);	    bytes = (header[6] << 8) + header[7];	    if (bytes > end - buf) {		state = DEMUX_SKIP;		state_bytes = bytes - (end - buf);		return 0;	    } 	    buf += bytes; 	} else {	    len = 8;	    if (header[5] & 0x10) {		len = 12 + (header[5] & 3);		NEEDBYTES (len);		decode_mpeg2 (header + 12, header + len);		mpeg2_tag_picture (mpeg2dec,				   ((header[8] << 24) | (header[9] << 16) |				    (header[10] << 8) | header[11]), 0);	    }	    DONEBYTES (len);	    bytes = (header[6] << 8) + header[7] + 8 - len;	    if (bytes > end - buf) {		decode_mpeg2 (buf, end);		state = DEMUX_DATA;		state_bytes = bytes - (end - buf);		return 0;	    } else if (bytes > 0) {		decode_mpeg2 (buf, buf + bytes);		buf += bytes;	    }	}    }}static void pva_loop (void){    uint8_t * buffer = (uint8_t *) malloc (buffer_size);    uint8_t * end;    if (buffer == NULL)	exit (1);    do {	end = buffer + fread (buffer, 1, buffer_size, in_file);	pva_demux (buffer, end);    } while (end == buffer + buffer_size && !sigint);    free (buffer);}static void ts_loop (void){    uint8_t * buffer = (uint8_t *) malloc (buffer_size);    uint8_t * buf;    uint8_t * nextbuf;    uint8_t * data;    uint8_t * end;    int pid;    if (buffer == NULL || buffer_size < 188)	exit (1);    buf = buffer;    do {	end = buf + fread (buf, 1, buffer + buffer_size - buf, in_file);	buf = buffer;	for (; (nextbuf = buf + 188) <= end; buf = nextbuf) {	    if (*buf != 0x47) {		fprintf (stderr, "bad sync byte\n");		nextbuf = buf + 1;		continue;	    }	    pid = ((buf[1] << 8) + buf[2]) & 0x1fff;	    if (pid != demux_pid)		continue;	    data = buf + 4;	    if (buf[3] & 0x20) {	/* buf contains an adaptation field */		data = buf + 5 + buf[4];		if (data > nextbuf)		    continue;	    }	    if (buf[3] & 0x10)		demux (data, nextbuf,		       (buf[1] & 0x40) ? DEMUX_PAYLOAD_START : 0);	}	if (end != buffer + buffer_size)	    break;	memcpy (buffer, buf, end - buf);	buf = buffer + (end - buf);    } while (!sigint);    free (buffer);}static void es_loop (void){    uint8_t * buffer = (uint8_t *) malloc (buffer_size);    uint8_t * end;    if (buffer == NULL)	exit (1);    do {	end = buffer + fread (buffer, 1, buffer_size, in_file);	decode_mpeg2 (buffer, end);    } while (end == buffer + buffer_size && !sigint);    free (buffer);}int main (int argc, char ** argv){#ifdef HAVE_IO_H    setmode (fileno (stdin), O_BINARY);    setmode (fileno (stdout), O_BINARY);#endif    fprintf (stderr, PACKAGE"-"VERSION	     " - by Michel Lespinasse <walken@zoy.org> and Aaron Holtzman\n");    handle_args (argc, argv);    output = output_open ();    if (output == NULL) {	fprintf (stderr, "Can not open output\n");	return 1;    }    mpeg2dec = mpeg2_init ();    if (mpeg2dec == NULL)	exit (1);    mpeg2_malloc_hooks (malloc_hook, NULL);    if (demux_pva)	pva_loop ();    else if (demux_pid)	ts_loop ();    else if (demux_track)	ps_loop ();    else	es_loop ();    mpeg2_close (mpeg2dec);    if (output->close)	output->close (output);    print_fps (1);    fclose (in_file);    return 0;}

⌨️ 快捷键说明

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