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

📄 aviobuf.c

📁 ts流的解复用
💻 C
📖 第 1 页 / 共 2 页
字号:
        *state= tmp + *(p++);
        if(tmp == 0x100 || p==end)
            return p;
    }

    while(p<end){
        if     (p[-1] > 1      ) p+= 3;
        else if(p[-2]          ) p+= 2;
        else if(p[-3]|(p[-1]-1)) p++;
        else{
            p++;
            break;
        }
    }

    p= FFMIN(p, end)-4;
    *state= AV_RB32(p);

    return p+4;
}

static int  frame_start_found = 0;
static u32	find_state = 0;

int find_frame_end(const u8 *buf, int buf_size)
{
    int i;
    uint32_t state= find_state;

    /* EOF considered as end of frame */
    if (buf_size == 0)
        return 0;

/*
 0  frame start         -> 1/4
 1  first_SEQEXT        -> 0/2
 2  first field start   -> 3/0
 3  second_SEQEXT       -> 2/0
 4  searching end
*/
	printf("parse size = %d  state = 0x%x\n", buf_size, state);
    for(i=0; i<buf_size; i++){
//        assert(frame_start_found>=0 && frame_start_found<=4);
        if(frame_start_found&1)
		{
            if(state == EXT_START_CODE && (buf[i]&0xF0) != 0x80)
                frame_start_found--;
            else if(state == EXT_START_CODE+2)
			{
                if((buf[i]&3) == 3) frame_start_found= 0;
                else                frame_start_found= (frame_start_found+1)&3;
            }
            state++;
        }
		else
		{
			printf("find start code\n");
            i= ff_find_start_code(buf+i, buf+buf_size, &state) - buf - 1;
            if(frame_start_found==0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE)
			{
                i++;
                frame_start_found=4;
            }
            if(state == SEQ_END_CODE)
			{
                find_state=-1;
                return i+1;
            }
            if(frame_start_found==2 && state == SEQ_START_CODE)
                frame_start_found= 0;
            if(frame_start_found<4 && state == EXT_START_CODE)
                frame_start_found++;
            if(frame_start_found == 4 && (state&0xFFFFFF00) == 0x100)
			{
                if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE)
				{
                    frame_start_found=0;
                    find_state=-1;
                    return i-3;
                }
            }
        }
    }
    find_state= state;
    return END_NOT_FOUND;
}




static int find_start = 0;
static u8	temp_frame[1024*512];
static int index = 0;
static int find_i=0;

static int mpegvideo_parse(const uint8_t *buf, int buf_size)
{
	int next;
	int i;
	u8 x;
	int w,h, ratio, rate, bitrate;

	for(i=0;i<buf_size;i++)
	{
		if(buf[i] == 0 && i < buf_size -3)
		{
			if(buf[i+1]==0 && buf[i+2]==0x01)
			{
				//hex_dump(buf, buf_size);
#if 1
				if(buf[i+3] == 0xb3 )
				{
					w = ((buf[i+4] << 8)|buf[i+5])>>4;
					//w = w | buf[i+5];
					//w = w>>4;

					h = ((buf[i+5]&0x0f) << 8 ) | buf[i+6];
					//h = h << 8;
					//h = h | buf[i+6];

					ratio = buf[i+7]>>4;

					rate = buf[i+7] & 0x0f;

					bitrate = ((buf[i+8]<<16)|(buf[i+9]<<8)|buf[i+10]) >> 6;
					bitrate *= 400;

					printf("find sequence header...w = %d h = %d ", w, h);

					if(ratio == 2)		printf("ratio = 4:3    ");
					else if(ratio == 3) printf("ratio = 16:9   ");
					else if(ratio == 4) printf("ratio = 1:2.21 ");

					if(rate == 1) printf("rate = 23.976  ");
					if(rate == 2) printf("rate = 24      ");
					if(rate == 3) printf("rate = 25      ");
					if(rate == 4) printf("rate = 29.97   ");
					if(rate == 5) printf("rate = 30      ");
					if(rate == 6) printf("rate = 50      ");
					if(rate == 7) printf("rate = 59.94   ");
					if(rate == 7) printf("rate = 60      ");
					
					printf("bit_rate = %d b/s", bitrate);

					printf("\n");

					//find_start = 1;
					//memcpy(temp_frame, &buf[i], buf_size-i);

					//return 0;
				}
#endif				
				if(buf[i+3] == 0)
				{
					
					x = (buf[i+5]>>3)&0x07;
					//printf("type = %d \n", x);

					if(x == 1) 
					{
					//	hex_dump(buf, buf_size);
						printf("find I frame\n");
					}
					else if(x == 2) printf("find P frame\n");
					else if(x == 3) printf("find B frame\n");

					return x;
				}
			}
		}
	}


	//将分析出的数据放入temp_frame空间
	//next = find_frame_end(buf, buf_size);

	//if(next == 0) 
	//	printf("find...\n");

	return -1;
}



#if 1
static int first = 0;
static void mpegts_push_data(const uint8_t *buf, int buf_size, int is_start)
{
	const uint8_t *p;
	int len, code;

	if (is_start) {
		if(first == 0) first = 1;

//		hex_dump(buf, buf_size);
		//pes->state = MPEGTS_HEADER;
		//pes->data_index = 0;
		memset(pes, 0, sizeof(struct PESContext));
	}
	p = buf;
    
	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 (pes->header[0] == 0x00 && pes->header[1] == 0x00 &&
                    pes->header[2] == 0x01) {
                    /* it must be an mpeg2 PES stream , stream_id*/
                    code = pes->header[3] | 0x100;

					if(code == 0x1ba) printf("pack header start..\n");
					//printf("stream id = 0x%x \n", pes->header[3]);

                    if (!((code >= 0x1c0 && code <= 0x1df) ||
                          (code >= 0x1e0 && code <= 0x1ef) ||
                          (code == 0x1bd) || (code == 0x1fd)))
                        goto skip;
#if 0
                    if (!pes->st) {
                        /* allocate stream */
                        new_pes_av_stream(pes, code);
                    }
#endif
                    pes->state = MPEGTS_PESHEADER_FILL;
                    pes->total_size = (pes->header[4] << 8) | pes->header[5];	//pes_packet_length
                    /* 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;

					//printf("pes header size = %d \n", pes->pes_header_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;

				//printf("pts = %x \n", r[0]);

                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) 
			{
				mpegvideo_parse(p, len);
			//	hex_dump(p, len);
			//	if(first)
			//	if(find_start)	
			//		fwrite(p, len, 1, wfp);
			//	printf("copy to packet...\n");
#if 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;
                }
#endif
            }
            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)
{

    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);

}

//返回一个完整的帧,并放入对应的队列
void av_read_frame(RingBuffer_s *rb, int pid, AVPacket *pkt)
{
	u8 buff[TS_PACKET_SIZE];
	for(;;)
	{
		if(read_packet(rb, buff, TS_PACKET_SIZE) == 0)
		{
			uint16_t i_pid = ((uint16_t)(buff[1] & 0x1f) << 8) + buff[2];
			
			//处理对应pid的帧
			if(i_pid == pid)
			{
				handle_packet(buff, 188);
			}
		}
	}
}

//创建一个帧的空间,并将数据拷入,再放入对应的队列
void add_frame(PacketQueue *q, char *buf, int size)
{
	AVPacket		*pkt;

	pkt = malloc(sizeof(AVPacket));
	if(pkt)
		av_new_packet(pkt, size);

	memcpy(pkt->data, buf, size);

	packet_queue_put(q, pkt);
}

int main()
{
	RingBuffer_s		rb;
	u8 buff[TS_PACKET_SIZE];
	
	int i;
	PacketQueue		vp;
	

	dvbpsi_handle h_dvbpsi;

	avio_init(&rb, RINGBUFFER_SIZE);
	packet_queue_init(&vp);

	wfp = fopen("./1.ts", "wb");

	h_dvbpsi = dvbpsi_AttachPAT(DumpPAT, NULL);

	while(1)
	{
		if(read_packet(&rb, buff, TS_PACKET_SIZE) == 0)
		{

			uint16_t i_pid = ((uint16_t)(buff[1] & 0x1f) << 8) + buff[2];
			//printf("pid = %d\n", i_pid);
#if 0
			if(i_pid == 0x0 && scan_pat == 0)
			{
				//hex_dump(buff, TS_PACKET_SIZE);
				
				dvbpsi_PushPacket(h_dvbpsi, buff);
				//break;
			}
			for(i=0;i < pmt_count;i++)
			{
				if(i_pid == pmt_array[i].pmt_pid)
					dvbpsi_PushPacket(pmt_array[i].handle, buff);
			}
#else			
			if(i_pid == 620)//110)
			{
				handle_packet(buff, 188);
				//fwrite(buff, TS_PACKET_SIZE, 1, wfp);
			}
#endif
		}
		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 + -