📄 aviobuf.c
字号:
*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 + -