demux_real_1.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,824 行 · 第 1/5 页

C
1,824
字号
  for (i = 0; i < MAX_STREAMS; i++)  {    if (priv->index_table_size[i] > 0)    {      dump_index(demuxer, i);    }  }  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;    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);	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: %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, 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]);		    if (priv->a_pts != timestamp)			dp->pts = timestamp / 1000.0;		    priv->a_pts = timestamp;		    dp->pos = demuxer->filepos;		    ds_add_packet(ds, dp);		}		free(sub_packet_lengths);		return 1;	    }        if ((priv->intl_id[stream_id] == mmioFOURCC('I', 'n', 't', '4')) ||            (priv->intl_id[stream_id] == mmioFOURCC('g', 'e', 'n', 'r')) ||            (priv->intl_id[stream_id] == mmioFOURCC('s', 'i', 'p', 'r'))) {            sps = priv->sub_packet_size[stream_id];            sph = priv->sub_packet_h[stream_id];            cfs = priv->coded_framesize[stream_id];            w = priv->audiopk_size[stream_id];            spc = priv->sub_packet_cnt;            switch (priv->intl_id[stream_id]) {                case mmioFOURCC('I', 'n', 't', '4'):                    for (x = 0; x < sph / 2; x++)                        stream_read(demuxer->stream, priv->audio_buf + x * 2 * w + spc * cfs, cfs);                    break;                case mmioFOURCC('g', 'e', 'n', 'r'):                    for (x = 0; x < w / sps; x++)                        stream_read(demuxer->stream, priv->audio_buf + sps * (sph * x + ((sph + 1) / 2) * (spc & 1) +                                    (spc >> 1)), sps);                    break;                case mmioFOURCC('s', 'i', 'p', 'r'):                    stream_read(demuxer->stream, priv->audio_buf + spc * w, w);                    if (spc == sph - 1) {                        int n;                        int bs = sph * w * 2 / 96;  // nibbles per subpacket                        // Perform reordering                        for(n=0; n < 38; n++) {                            int j;                            int i = bs * sipr_swaps[n][0];                            int o = bs * sipr_swaps[n][1];                            // swap nibbles of block 'i' with 'o'      TODO: optimize

⌨️ 快捷键说明

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