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

📄 demux_real.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
//    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 + -