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

📄 复件 aviobuf.c

📁 ts流的解复用
💻 C
📖 第 1 页 / 共 2 页
字号:
	}							\    } 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;	    }	}    }}//-------------------------------------------------------------------enum MpegTSState {    MPEGTS_HEADER = 0,    MPEGTS_PESHEADER_FILL,    MPEGTS_PAYLOAD,    MPEGTS_SKIP,};/* enough for PES header + length */#define PES_START_SIZE 9#define MAX_PES_HEADER_SIZE (9 + 255)struct PESContext {    int pid;    int stream_type;//    MpegTSContext *ts;//    AVFormatContext *stream;//    AVStream *st;    enum MpegTSState state;    /* used to get the format */    int data_index;    int total_size;    int pes_header_size;    int64_t pts, dts;    uint8_t header[MAX_PES_HEADER_SIZE];};static int64_t get_pts(const uint8_t *p){    int64_t pts;    int val;    pts = (int64_t)((p[0] >> 1) & 0x07) << 30;    val = (p[1] << 8) | p[2];    pts |= (int64_t)(val >> 1) << 15;    val = (p[3] << 8) | p[4];    pts |= (int64_t)(val >> 1);    return pts;}#if 0/* return non zero if a packet could be constructed */static void mpegts_push_data(const uint8_t *buf, int buf_size, int is_start){    PESContext *pes = opaque;    MpegTSContext *ts = pes->ts;    const uint8_t *p;    int len, code;    if (is_start) {        pes->state = MPEGTS_HEADER;        pes->data_index = 0;    }    p = buf;   // printf("push data...buf_size = %d \n", buf_size);    while (buf_size > 0) {        switch(pes->state) {        case MPEGTS_HEADER:            len = PES_START_SIZE - pes->data_index;            if (len > buf_size)                len = buf_size;            memcpy(pes->header + pes->data_index, p, len);            pes->data_index += len;            p += len;            buf_size -= len;            if (pes->data_index == PES_START_SIZE) {                /* we got all the PES or section header. We can now                   decide */#if 1                av_log(ts->stream, AV_LOG_INFO, "PES HEADER:\n");                av_hex_dump(stdout, pes->header, pes->data_index);#endif                if (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&                    pes->header[2] == 0x01) {                    /* it must be an mpeg2 PES stream */                    code = pes->header[3] | 0x100;                    if (!((code >= 0x1c0 && code <= 0x1df) ||                          (code >= 0x1e0 && code <= 0x1ef) ||                          (code == 0x1bd) || (code == 0x1fd)))                        goto skip;                    if (!pes->st) {                        /* allocate stream */                        new_pes_av_stream(pes, code);                    }                    pes->state = MPEGTS_PESHEADER_FILL;                    pes->total_size = (pes->header[4] << 8) | pes->header[5];                    /* NOTE: a zero total size means the PES size is                       unbounded */                    if (pes->total_size)                        pes->total_size += 6;                    pes->pes_header_size = pes->header[8] + 9;   // av_hex_dump(stdout, buf, buf_size);                } else {                    /* otherwise, it should be a table */                    /* skip packet */                skip:                    pes->state = MPEGTS_SKIP;                    continue;                }            }            break;            /**********************************************/            /* PES packing parsing */        case MPEGTS_PESHEADER_FILL:            len = pes->pes_header_size - pes->data_index;            if (len > buf_size)                len = buf_size;            memcpy(pes->header + pes->data_index, p, len);            pes->data_index += len;            p += len;            buf_size -= len;            if (pes->data_index == pes->pes_header_size) {                const uint8_t *r;                unsigned int flags;                flags = pes->header[7];                r = pes->header + 9;                pes->pts = AV_NOPTS_VALUE;                pes->dts = AV_NOPTS_VALUE;                if ((flags & 0xc0) == 0x80) {                    pes->pts = get_pts(r);                    r += 5;                } else if ((flags & 0xc0) == 0xc0) {                    pes->pts = get_pts(r);                    r += 5;                    pes->dts = get_pts(r);                    r += 5;                }                /* we got the full header. We parse it and get the payload */                pes->state = MPEGTS_PAYLOAD;            }            break;        case MPEGTS_PAYLOAD:            if (pes->total_size) {                len = pes->total_size - pes->data_index;                if (len > buf_size)                    len = buf_size;            } else {                len = buf_size;            }            if (len > 0) {                AVPacket *pkt = ts->pkt;                if (pes->st && av_new_packet(pkt, len) == 0) {                    memcpy(pkt->data, p, len);                    pkt->stream_index = pes->st->index;                    pkt->pts = pes->pts;                    pkt->dts = pes->dts;                    /* reset pts values */                    pes->pts = AV_NOPTS_VALUE;                    pes->dts = AV_NOPTS_VALUE;                    ts->stop_parse = 1;                    return;                }            }            buf_size = 0;            break;        case MPEGTS_SKIP:            buf_size = 0;            break;        }    }}#endif/* handle one TS packet *///记录每个流的最后的连续计数哿static int last_cc=0;static void handle_packet(const uint8_t *packet, int packet_size){	static int last_cc;    int len, pid, cc, cc_ok, afc, is_start;    const uint8_t *p, *p_end;    pid = ((packet[1] & 0x1f) << 8) | packet[2];    is_start = packet[1] & 0x40;    /* continuity check (currently not used) */    cc = (packet[3] & 0xf);    cc_ok = (last_cc < 0) || ((((last_cc + 1) & 0x0f) == cc));    last_cc = cc;    /* skip adaptation field */    afc = (packet[3] >> 4) & 3;    p = packet + 4;    if (afc == 0) /* reserved value */        return;    if (afc == 2) /* adaptation field only */        return;    if (afc == 3) {        /* skip adapation field */        p += p[0] + 1;    }    /* if past the end of packet, ignore */    p_end = packet + packet_size;    if (p >= p_end)        return;          //处理pes数据   //   mpegts_push_data(p, p_end - p, is_start);}int main(){	RingBuffer_s		rb;	u8 buff[TS_PACKET_SIZE];	uint8_t * data;	int i;	dvbpsi_handle h_dvbpsi;	avio_init(&rb, RINGBUFFER_SIZE);	wfp = fopen("./1.ts", "wb");	h_dvbpsi = dvbpsi_AttachPAT(DumpPAT, NULL);	while(1)	{		if(read_packet(&rb, buff, TS_PACKET_SIZE) == 0)		{						//fprintf(wfp, "\n");						uint16_t i_pid = ((uint16_t)(buff[1] & 0x1f) << 8) + buff[2];#if 0							//			//if(i_pid == 0x0 && scan_pat == 0)			if(i_pid == 0x0 )			{				//hex_dump(buff, TS_PACKET_SIZE);				//printf("pid = %d\n", i_pid);				dvbpsi_PushPacket(h_dvbpsi, buff);				//getchar();				//break;			}					for(i=0;i < pmt_count;i++)			{				if(i_pid == pmt_array[i].pmt_pid)				{					printf("pid = %d \n", i_pid);					dvbpsi_PushPacket(pmt_array[i].handle, buff);				}			}#endif			if(i_pid == 310)// || i_pid == 320)			{#if 0				data = buff + 4;				if (buff[3] & 0x20) {	/* buf contains an adaptation field */					data = buff + 5 + buff[4];					if (data > buff+TS_PACKET_SIZE)						continue;				}				if (buff[3] & 0x10)					//fwrite(data, buff+TS_PACKET_SIZE -data, 1, wfp);					//demux (data, buff+TS_PACKET_SIZE,					//	(buff[1] & 0x40) ? DEMUX_PAYLOAD_START : 0);#endif					//demux(buff, buff+TS_PACKET_SIZE, 0);				fwrite(buff, TS_PACKET_SIZE, 1, wfp);			}			//fwrite(buff, TS_PACKET_SIZE, 1, wfp);		}		else break;//		printf("r = %-8d w = %-8d free=%d    avail=%d\r", rb.ptr_r, rb.ptr_w, rb_free(&rb), rb_avail(&rb));		//getchar();	}	fflush(wfp);	fclose(wfp);	printf("\ngame over...\n");	system("PAUSE");	return 0;}

⌨️ 快捷键说明

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