demux_real.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,820 行 · 第 1/5 页
C
1,820 行
} stream_reset(demuxer->stream); stream_seek(demuxer->stream, origpos); return 0;}#elsestatic int generate_index(demuxer_t *demuxer){ real_priv_t *priv = demuxer->priv; int origpos = stream_tell(demuxer->stream); int data_pos = priv->data_chunk_offset-10; int num_of_packets = 0; int i, entries = 0; int len, stream_id = 0, flags; unsigned int timestamp; int tab_pos = 0;read_index: stream_seek(demuxer->stream, data_pos); i = stream_read_dword_le(demuxer->stream); if ((i == -256) || (i != MKTAG('D', 'A', 'T', 'A'))) { mp_msg(MSGT_DEMUX, MSGL_WARN,"Something went wrong, no data chunk found on given address (%d)\n", data_pos); goto end; } stream_skip(demuxer->stream, 4); /* chunk size */ stream_skip(demuxer->stream, 2); /* version */ num_of_packets = stream_read_dword(demuxer->stream); mp_msg(MSGT_DEMUX, MSGL_V,"Generating index table from raw data (pos: 0x%x) for %d packets\n", data_pos, num_of_packets); data_pos = stream_read_dword_le(demuxer->stream)-10; /* next data chunk */ for (i = 0; i < MAX_STREAMS; i++) { priv->index_table_size[i] = num_of_packets; priv->index_table[i] = calloc(priv->index_table_size[i], sizeof(real_index_table_t));// priv->index_table[stream_id] = realloc(priv->index_table[stream_id],// priv->index_table_size[stream_id] * sizeof(real_index_table_t)); } tab_pos = 0; // memset(priv->index_table_size, 0, sizeof(int)*MAX_STREAMS);// memset(priv->index_table, 0, sizeof(real_index_table_t)*MAX_STREAMS); while (tab_pos < num_of_packets) { i = stream_read_char(demuxer->stream); if (i == -256) goto end; stream_skip(demuxer->stream, 1);// stream_skip(demuxer->stream, 2); /* version */ len = stream_read_word(demuxer->stream); stream_id = stream_read_word(demuxer->stream); timestamp = stream_read_dword(demuxer->stream); stream_skip(demuxer->stream, 1); /* reserved */ flags = stream_read_char(demuxer->stream); i = tab_pos;// priv->index_table_size[stream_id] = i;// if (priv->index_table[stream_id] == NULL)// priv->index_table[stream_id] = malloc(priv->index_table_size[stream_id] * sizeof(real_index_table_t));// else// priv->index_table[stream_id] = realloc(priv->index_table[stream_id],// priv->index_table_size[stream_id] * sizeof(real_index_table_t)); priv->index_table[stream_id][i].timestamp = timestamp; priv->index_table[stream_id][i].offset = stream_tell(demuxer->stream)-12; priv->index_table[stream_id][i].len = len; priv->index_table[stream_id][i].packetno = entries; priv->index_table[stream_id][i].flags = flags; tab_pos++; /* skip data */ stream_skip(demuxer->stream, len-12); } dump_index(demuxer, stream_id); if (data_pos) goto read_index;end: if (i == -256) stream_reset(demuxer->stream); stream_seek(demuxer->stream, origpos); if (i == -256) return 0; else return 1;}#endifstatic int real_check_file(demuxer_t* demuxer){ real_priv_t *priv; int c; mp_msg(MSGT_DEMUX,MSGL_V,"Checking for REAL\n"); c = stream_read_dword_le(demuxer->stream); if (c == -256) return 0; /* EOF */ if (c != MKTAG('.', 'R', 'M', 'F')) return 0; /* bad magic */ priv = malloc(sizeof(real_priv_t)); memset(priv, 0, sizeof(real_priv_t)); demuxer->priv = priv; return DEMUXER_TYPE_REAL;}void hexdump(char *, unsigned long);#define SKIP_BITS(n) buffer<<=n#define SHOW_BITS(n) ((buffer)>>(32-(n)))static double real_fix_timestamp(real_priv_t* priv, unsigned char* s, unsigned int timestamp, double frametime, unsigned int format){ double v_pts; uint32_t buffer= (s[0]<<24) + (s[1]<<16) + (s[2]<<8) + s[3]; unsigned int kf=timestamp; int pict_type; unsigned int orig_kf;#if 1 if(format==mmioFOURCC('R','V','3','0') || format==mmioFOURCC('R','V','4','0')){ if(format==mmioFOURCC('R','V','3','0')){ SKIP_BITS(3); pict_type= SHOW_BITS(2); SKIP_BITS(2 + 7); }else{ SKIP_BITS(1); pict_type= SHOW_BITS(2); SKIP_BITS(2 + 7 + 3); } orig_kf= kf= SHOW_BITS(13); // kf= 2*SHOW_BITS(12);// if(pict_type==0) if(pict_type<=1){ // I frame, sync timestamps: priv->kf_base=(int64_t)timestamp-kf; mp_msg(MSGT_DEMUX, MSGL_DBG2,"\nTS: base=%08"PRIX64"\n",priv->kf_base); kf=timestamp; } else { // P/B frame, merge timestamps: int64_t tmp=(int64_t)timestamp-priv->kf_base; kf|=tmp&(~0x1fff); // combine with packet timestamp if(kf<tmp-4096) kf+=8192; else // workaround wrap-around problems if(kf>tmp+4096) kf-=8192; kf+=priv->kf_base; } if(pict_type != 3){ // P || I frame -> swap timestamps unsigned int tmp=kf; kf=priv->kf_pts; priv->kf_pts=tmp;// if(kf<=tmp) kf=0; } mp_msg(MSGT_DEMUX, MSGL_DBG2,"\nTS: %08X -> %08X (%04X) %d %02X %02X %02X %02X %5u\n",timestamp,kf,orig_kf,pict_type,s[0],s[1],s[2],s[3],kf-(unsigned int)(1000.0*priv->v_pts)); }#endif v_pts=kf*0.001f;// if(v_pts<priv->v_pts || !kf) v_pts=priv->v_pts+frametime; priv->v_pts=v_pts; //mp_msg(MSGT_DEMUX,MSGL_INFO,"%4.2f fps\n",v_pts); return v_pts;}typedef struct dp_hdr_s { uint32_t chunks; // number of chunks uint32_t timestamp; // timestamp from packet header uint32_t len; // length of actual data uint32_t chunktab; // offset to chunk offset array} dp_hdr_t;// return value:// 0 = EOF or no stream found// 1 = successfully read a packetstatic int demux_real_fill_buffer(demuxer_t *demuxer, demux_stream_t *dsds){ real_priv_t *priv = demuxer->priv; demux_stream_t *ds = NULL; int len; unsigned int timestamp; int stream_id;#ifdef CRACK_MATRIX int i;#endif int flags; int version; int reserved; demux_packet_t *dp; int x, sps, cfs, sph, spc, w; int audioreorder_getnextpk = 0; // Don't demux video if video codec init failed if (demuxer->video->id >= 0 && !demuxer->video->sh) demuxer->video->id = -2; while(!stream_eof(demuxer->stream)){ /* Handle audio/video demxing switch for multirate files (non-interleaved) */ if (priv->is_multirate && priv->stream_switch) { if (priv->a_idx_ptr >= priv->index_table_size[demuxer->audio->id]) demuxer->audio->eof = 1; if (priv->v_idx_ptr >= priv->index_table_size[demuxer->video->id]) demuxer->video->eof = 1; if (demuxer->audio->eof && demuxer->video->eof) { return 0; } else if (!demuxer->audio->eof && demuxer->video->eof) { stream_seek(demuxer->stream, priv->audio_curpos); // Get audio } else if (demuxer->audio->eof && !demuxer->video->eof) { stream_seek(demuxer->stream, priv->video_curpos); // Get video } else if (priv->index_table[demuxer->audio->id][priv->a_idx_ptr].timestamp < priv->index_table[demuxer->video->id][priv->v_idx_ptr].timestamp) { stream_seek(demuxer->stream, priv->audio_curpos); // Get audio } else { stream_seek(demuxer->stream, priv->video_curpos); // Get video } priv->stream_switch = 0; } demuxer->filepos = stream_tell(demuxer->stream); version = stream_read_word(demuxer->stream); /* version */ len = stream_read_word(demuxer->stream); if ((version==0x4441) && (len==0x5441)) { // new data chunk mp_msg(MSGT_DEMUX,MSGL_INFO,"demux_real: New data chunk is coming!!!\n"); if (priv->is_multirate) { return 0; // EOF } stream_skip(demuxer->stream,14); demuxer->filepos = stream_tell(demuxer->stream); version = stream_read_word(demuxer->stream); /* version */ len = stream_read_word(demuxer->stream); } else if ((version == 0x494e) && (len == 0x4458)) { mp_msg(MSGT_DEMUX,MSGL_V,"demux_real: Found INDX chunk. EOF.\n"); demuxer->stream->eof=1; return 0; } if (len == -256){ /* EOF */// printf("len==-256!\n"); return 0; } if (len < 12){ mp_msg(MSGT_DEMUX, MSGL_V,"%08X: packet v%d len=%d \n",(int)demuxer->filepos,(int)version,(int)len); mp_msg(MSGT_DEMUX, MSGL_WARN,"bad packet len (%d)\n", len); //stream_skip(demuxer->stream, len); F("aaaa %d\n",priv->current_vpacket); if((priv->current_vpacket - 1) > 0) { int pos; priv->current_vpacket--; pos = priv->index_table[demuxer->video->id][priv->current_vpacket].offset; F("aaaa pos = %d\n",pos); stream_seek(demuxer->stream, pos); seterrorseek(); continue; //goto loop; }else return 0; } stream_id = stream_read_word(demuxer->stream); timestamp = stream_read_dword(demuxer->stream); reserved = stream_read_char(demuxer->stream); flags = stream_read_char(demuxer->stream); /* flags: */ /* 0x1 - reliable */ /* 0x2 - keyframe */ if (version == 1) { int tmp; tmp = stream_read_char(demuxer->stream); mp_msg(MSGT_DEMUX, MSGL_DBG2,"Version: %d, skipped byte is %d\n", version, tmp); len--; } if (flags & 2) add_index_item(demuxer, stream_id, timestamp, demuxer->filepos);//show // printf("%08X: packet v%d len=%4d id=%d pts=%6d rvd=%d flags=%d \n",// (int)demuxer->filepos,(int)version,(int)len, stream_id,// (int) timestamp, reserved, flags); mp_dbg(MSGT_DEMUX,MSGL_DBG2, "\npacket#%d: pos: 0x%0x, len: %d, id: %d, pts: %u, flags: %x rvd:%d\n", priv->current_packet, (int)demuxer->filepos, len, stream_id, timestamp, flags, reserved); priv->current_packet++; len -= 12; // printf("s_id=%d aid=%d vid=%d \n",stream_id,demuxer->audio->id,demuxer->video->id); /* check stream_id: */ if(demuxer->audio->id==stream_id){ if (priv->audio_need_keyframe == 1&& flags != 0x2) goto discard;got_audio: ds=demuxer->audio; mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is audio (id: %d)\n", stream_id); if (flags & 2) { priv->sub_packet_cnt = 0; audioreorder_getnextpk = 0; } // parse audio chunk: {#ifdef CRACK_MATRIX int spos=stream_tell(demuxer->stream); static int cnt=0; static int cnt2=CRACK_MATRIX;#endif if (((sh_audio_t *)ds->sh)->format == mmioFOURCC('M', 'P', '4', 'A')) { uint16_t sub_packet_lengths[16], sub_packets, i; int totlen = 0; /* AAC in Real: several AAC frames in one Real packet. */ /* Second byte, upper four bits: number of AAC frames */ /* next n * 2 bytes: length of the AAC frames in bytes, BE */ if (len < 2) goto discard; sub_packets = (stream_read_word(demuxer->stream) & 0xf0) >> 4; if (len < 2 * sub_packets) goto discard; for (i = 0; i < sub_packets; i++) totlen += sub_packet_lengths[i] = stream_read_word(demuxer->stream); if (len < totlen ) goto discard; for (i = 0; i < sub_packets; i++) { demux_packet_t *dp = new_demux_packet(sub_packet_lengths[i]); stream_read(demuxer->stream, dp->buffer, sub_packet_lengths[i]); if (priv->a_pts != timestamp) dp->pts = timestamp / 1000.0; priv->a_pts = timestamp; dp->pos = demuxer->filepos; ds_add_packet(ds, dp); } return 1; } if ((priv->intl_id[stream_id] == mmioFOURCC('I', 'n', 't', '4')) ||
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?