📄 demux_real.c
字号:
// 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;}#endifint 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 1;}void hexdump(char *, unsigned long);#define SKIP_BITS(n) buffer<<=n#define SHOW_BITS(n) ((buffer)>>(32-(n)))static float real_fix_timestamp(real_priv_t* priv, unsigned char* s, int timestamp, float frametime, unsigned int format){ float v_pts; uint32_t buffer= (s[0]<<24) + (s[1]<<16) + (s[2]<<8) + s[3]; int kf=timestamp; int pict_type; 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=timestamp-kf; mp_msg(MSGT_DEMUX, MSGL_DBG2,"\nTS: base=%08X\n",priv->kf_base); kf=timestamp; } else { // P/B frame, merge timestamps: int tmp=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 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 %5d\n",timestamp,kf,orig_kf,pict_type,s[0],s[1],s[2],s[3],kf-(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; 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 packetint demux_real_fill_buffer(demuxer_t *demuxer){ real_priv_t *priv = demuxer->priv; demux_stream_t *ds = NULL; int len; int timestamp; int stream_id;#ifdef CRACK_MATRIX int i;#endif int flags; int version; int reserved; demux_packet_t *dp; while(1){ /* 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); continue; //goto loop; } 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);// 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: %d, 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); // 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, sub_packets, i; /* 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 */ sub_packets = (stream_read_word(demuxer->stream) & 0xf0) >> 4; sub_packet_lengths = calloc(sub_packets, sizeof(uint16_t)); for (i = 0; i < sub_packets; i++) sub_packet_lengths[i] = stream_read_word(demuxer->stream); 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]); dp->pts = (priv->a_pts == timestamp) ? 0 : (timestamp / 1000.0f); priv->a_pts = timestamp; dp->pos = demuxer->filepos; ds_add_packet(ds, dp); } free(sub_packet_lengths); return 1; } dp = new_demux_packet(len); stream_read(demuxer->stream, dp->buffer, len);#ifdef CRACK_MATRIX mp_msg(MSGT_DEMUX, MSGL_V,"*** audio block len=%d\n",len); { // HACK - used for reverse engineering the descrambling matrix FILE* f=fopen("test.rm","r+"); fseek(f,spos,SEEK_SET); ++cnt;// for(i=0;i<len;i++) dp->buffer[i]=i/0x12;// for(i=0;i<len;i++) dp->buffer[i]=i;// for(i=0;i<len;i++) dp->buffer[i]=cnt;// for(i=0;i<len;i++) dp->buffer[i]=cnt<<4; for(i=0;i<len;i++) dp->buffer[i]=(i==cnt2) ? (cnt+16*(8+cnt)) : 0; if(cnt==6){ cnt=0; ++cnt2; } fwrite(dp->buffer, len, 1, f); fclose(f); if(cnt2>0x150) *((int*)NULL)=1; // sig11 :) }#endif#if 0 if( ((sh_audio_t *)ds->sh)->format == 0x2000) { // if DNET, swap bytes, as DNET is byte-swapped AC3: char *ptr = dp->buffer; int i; for (i = 0; i < len; i += 2) { const char tmp = ptr[0]; ptr[0] = ptr[1]; ptr[1] = tmp; ptr += 2; } }#endif if (priv->audio_need_keyframe == 1) { dp->pts = 0; priv->audio_need_keyframe = 0; }else dp->pts = (priv->a_pts==timestamp) ? 0 : (timestamp/1000.0f); priv->a_pts=timestamp; dp->pos = demuxer->filepos; dp->flags = (flags & 0x2) ? 0x10 : 0; ds_add_packet(ds, dp); }// we will not use audio index if we use -idx and have a video if(!demuxer->video->sh && index_mode == 2 && (unsigned)demuxer->audio->id < MAX_STREAMS) while (priv->current_apacket + 1 < priv->index_table_size[demuxer->audio->id] && timestamp > priv->index_table[demuxer->audio->id][priv->current_apacket].timestamp) priv->current_apacket += 1; if(priv->is_multirate) while (priv->a_idx_ptr + 1 < priv->index_table_size[demuxer->audio->id] && timestamp > priv->index_table[demuxer->audio->id][priv->a_idx_ptr + 1].timestamp) { priv->a_idx_ptr++; priv->audio_curpos = stream_tell(demuxer->stream); priv->stream_switch = 1; } return 1; } if(demuxer->video->id==stream_id){got_video: ds=demuxer->video; mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is video (id: %d)\n", stream_id); // parse video chunk: { // we need a more complicated, 2nd level demuxing, as the video // frames are stored fragmented in the video chunks :( sh_video_t *sh_video = ds->sh; demux_packet_t *dp; int vpkg_header, vpkg_length, vpkg_offset; int vpkg_seqnum=-1; int vpkg_subseq=0; while(len>2){ dp_hdr_t* dp_hdr; unsigned char* dp_data; uint32_t* extra;// printf("xxx len=%d \n",len); // read packet header // bit 7: 1=last block in block chain // bit 6: 1=short header (only one block?) vpkg_header=stream_read_char(demuxer->stream); --len; mp_dbg(MSGT_DEMUX,MSGL_DBG2, "hdr: %02X (len=%d) ",vpkg_header,len); if (0x40==(vpkg_header&0xc0)) { // seems to be a very short header // 2 bytes, purpose of the second byte yet unknown int bummer; bummer=stream_read_char(demuxer->stream); --len; mp_dbg(MSGT_DEMUX,MSGL_DBG2, "%02X",bummer); vpkg_offset=0; vpkg_length=len; } else { if (0==(vpkg_header&0x40)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -