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

📄 demux_real.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
			// sub-seqnum (bits 0-6: number of fragment. bit 7: ???)		        vpkg_subseq=stream_read_char(demuxer->stream);	                --len;		        mp_dbg(MSGT_DEMUX,MSGL_DBG2,  "subseq: %02X ",vpkg_subseq);			vpkg_subseq&=0x7f;	            }	  	    // size of the complete packet		    // bit 14 is always one (same applies to the offset)		    vpkg_length=stream_read_word(demuxer->stream);		    len-=2;		    mp_dbg(MSGT_DEMUX,MSGL_DBG2, "l: %02X %02X ",vpkg_length>>8,vpkg_length&0xff);		    if (!(vpkg_length&0xC000)) {			vpkg_length<<=16;		        vpkg_length|=stream_read_word(demuxer->stream);		        mp_dbg(MSGT_DEMUX,MSGL_DBG2, "l+: %02X %02X ",(vpkg_length>>8)&0xff,vpkg_length&0xff);	    	        len-=2;		    } else		    vpkg_length&=0x3fff;		    // offset of the following data inside the complete packet		    // Note: if (hdr&0xC0)==0x80 then offset is relative to the		    // _end_ of the packet, so it's equal to fragment size!!!		    vpkg_offset=stream_read_word(demuxer->stream);	            len-=2;		    mp_dbg(MSGT_DEMUX,MSGL_DBG2, "o: %02X %02X ",vpkg_offset>>8,vpkg_offset&0xff);		    if (!(vpkg_offset&0xC000)) {			vpkg_offset<<=16;		        vpkg_offset|=stream_read_word(demuxer->stream);		        mp_dbg(MSGT_DEMUX,MSGL_DBG2, "o+: %02X %02X ",(vpkg_offset>>8)&0xff,vpkg_offset&0xff);	    	        len-=2;		    } else		    vpkg_offset&=0x3fff;		    vpkg_seqnum=stream_read_char(demuxer->stream); --len;		    mp_dbg(MSGT_DEMUX,MSGL_DBG2, "seq: %02X ",vpkg_seqnum);	        } 		mp_dbg(MSGT_DEMUX,MSGL_DBG2, "\n");                mp_dbg(MSGT_DEMUX,MSGL_DBG2, "blklen=%d\n", len);		mp_msg(MSGT_DEMUX,MSGL_DBG2, "block: hdr=0x%0x, len=%d, offset=%d, seqnum=%d\n",		    vpkg_header, vpkg_length, vpkg_offset, vpkg_seqnum);		if(ds->asf_packet){		    dp=ds->asf_packet;		    dp_hdr=(dp_hdr_t*)dp->buffer;		    dp_data=dp->buffer+sizeof(dp_hdr_t);		    extra=(uint32_t*)(dp->buffer+dp_hdr->chunktab);		    mp_dbg(MSGT_DEMUX,MSGL_DBG2, "we have an incomplete packet (oldseq=%d new=%d)\n",ds->asf_seq,vpkg_seqnum);		    // we have an incomplete packet:		    if(ds->asf_seq!=vpkg_seqnum){			// this fragment is for new packet, close the old one			mp_msg(MSGT_DEMUX,MSGL_DBG2, "closing probably incomplete packet, len: %d  \n",dp->len);			if(priv->video_after_seek){			    dp->pts=timestamp;				priv->kf_base = 0;				priv->kf_pts = dp_hdr->timestamp;				priv->video_after_seek = 0;			} else 			dp->pts=(dp_hdr->len<3)?0:			    real_fix_timestamp(priv,dp_data,dp_hdr->timestamp,sh_video->frametime,sh_video->format);			ds_add_packet(ds,dp);			ds->asf_packet=NULL;		    } else {			// append data to it!			++dp_hdr->chunks;			mp_msg(MSGT_DEMUX,MSGL_DBG2,"[chunks=%d  subseq=%d]\n",dp_hdr->chunks,vpkg_subseq);			if(dp_hdr->chunktab+8*(1+dp_hdr->chunks)>dp->len){			    // increase buffer size, this should not happen!			    mp_msg(MSGT_DEMUX,MSGL_WARN, "chunktab buffer too small!!!!!\n");			    dp->len=dp_hdr->chunktab+8*(4+dp_hdr->chunks);			    dp->buffer=realloc(dp->buffer,dp->len);			    // re-calc pointers:			    dp_hdr=(dp_hdr_t*)dp->buffer;			    dp_data=dp->buffer+sizeof(dp_hdr_t);			    extra=(uint32_t*)(dp->buffer+dp_hdr->chunktab);			}			extra[2*dp_hdr->chunks+0]=1;			extra[2*dp_hdr->chunks+1]=dp_hdr->len;			if(0x80==(vpkg_header&0xc0)){			    // last fragment!			    if(dp_hdr->len!=vpkg_length-vpkg_offset)				mp_msg(MSGT_DEMUX,MSGL_V,"warning! assembled.len=%d  frag.len=%d  total.len=%d  \n",dp->len,vpkg_offset,vpkg_length-vpkg_offset);            		    stream_read(demuxer->stream, dp_data+dp_hdr->len, vpkg_offset);			    if((dp_data[dp_hdr->len]&0x20) && (sh_video->format==0x30335652)) --dp_hdr->chunks; else			    dp_hdr->len+=vpkg_offset;			    len-=vpkg_offset; 			    mp_dbg(MSGT_DEMUX,MSGL_DBG2, "fragment (%d bytes) appended, %d bytes left\n",vpkg_offset,len);			    // we know that this is the last fragment -> we can close the packet!			    if(priv->video_after_seek){			        dp->pts=timestamp;				    priv->kf_base = 0;				    priv->kf_pts = dp_hdr->timestamp;				    priv->video_after_seek = 0;			    } else 			    dp->pts=(dp_hdr->len<3)?0:				real_fix_timestamp(priv,dp_data,dp_hdr->timestamp,sh_video->frametime,sh_video->format);			    ds_add_packet(ds,dp);			    ds->asf_packet=NULL;			    // continue parsing			    continue;			}			// non-last fragment:			if(dp_hdr->len!=vpkg_offset)			    mp_msg(MSGT_DEMUX,MSGL_V,"warning! assembled.len=%d  offset=%d  frag.len=%d  total.len=%d  \n",dp->len,vpkg_offset,len,vpkg_length);            		stream_read(demuxer->stream, dp_data+dp_hdr->len, len);			if((dp_data[dp_hdr->len]&0x20) && (sh_video->format==0x30335652)) --dp_hdr->chunks; else			dp_hdr->len+=len;			len=0;			break; // no more fragments in this chunk!		    }		}		// create new packet!		dp = new_demux_packet(sizeof(dp_hdr_t)+vpkg_length+8*(1+2*(vpkg_header&0x3F)));	    	// the timestamp seems to be in milliseconds		dp->pts = 0; // timestamp/1000.0f; //timestamp=0;                dp->pos = demuxer->filepos;                dp->flags = (flags & 0x2) ? 0x10 : 0;		ds->asf_seq = vpkg_seqnum;		dp_hdr=(dp_hdr_t*)dp->buffer;		dp_hdr->chunks=0;		dp_hdr->timestamp=timestamp;		dp_hdr->chunktab=sizeof(dp_hdr_t)+vpkg_length;		dp_data=dp->buffer+sizeof(dp_hdr_t);		extra=(uint32_t*)(dp->buffer+dp_hdr->chunktab);		extra[0]=1; extra[1]=0; // offset of the first chunk		if(0x00==(vpkg_header&0xc0)){		    // first fragment:		    dp_hdr->len=len;		    stream_read(demuxer->stream, dp_data, len);		    ds->asf_packet=dp;		    len=0;		    break;		}		// whole packet (not fragmented):		if (vpkg_length > len) {		    mp_msg(MSGT_DEMUX, MSGL_WARN,"\n******** WARNING: vpkg_length=%i > len=%i ********\n", vpkg_length, len);		    /*		     * To keep the video stream rolling, we need to break 		     * here. We shouldn't touch len to make sure rest of the		     * broken packet is skipped.		     */		    break;		}		dp_hdr->len=vpkg_length; len-=vpkg_length;		stream_read(demuxer->stream, dp_data, vpkg_length);		if(priv->video_after_seek){		    dp->pts=timestamp;			priv->kf_base = 0;			priv->kf_pts = dp_hdr->timestamp;			priv->video_after_seek = 0;		} else 		dp->pts=(dp_hdr->len<3)?0:		    real_fix_timestamp(priv,dp_data,dp_hdr->timestamp,sh_video->frametime,sh_video->format);		ds_add_packet(ds,dp);	    } // while(len>0)	    	    if(len){		mp_msg(MSGT_DEMUX, MSGL_WARN,"\n******** !!!!!!!! BUG!! len=%d !!!!!!!!!!! ********\n",len);		if(len>0) stream_skip(demuxer->stream, len);	    }	}	if ((unsigned)demuxer->video->id < MAX_STREAMS)		while (priv->current_vpacket + 1 < priv->index_table_size[demuxer->video->id] && 		       timestamp > priv->index_table[demuxer->video->id][priv->current_vpacket + 1].timestamp)			priv->current_vpacket += 1;	if(priv->is_multirate)		while (priv->v_idx_ptr + 1 < priv->index_table_size[demuxer->video->id] &&		       timestamp > priv->index_table[demuxer->video->id][priv->v_idx_ptr + 1].timestamp) {			priv->v_idx_ptr++;			priv->video_curpos = stream_tell(demuxer->stream);			priv->stream_switch = 1;		}		return 1;    }if(stream_id<256){    if(demuxer->audio->id==-1 && demuxer->a_streams[stream_id]){	sh_audio_t *sh = demuxer->a_streams[stream_id];	demuxer->audio->id=stream_id;	sh->ds=demuxer->audio;	demuxer->audio->sh=sh;        mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM audio ID = %d\n",stream_id);	goto got_audio;    }    if(demuxer->video->id==-1 && demuxer->v_streams[stream_id]){	sh_video_t *sh = demuxer->v_streams[stream_id];	demuxer->video->id=stream_id;	sh->ds=demuxer->video;	demuxer->video->sh=sh;        mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM video ID = %d\n",stream_id);	goto got_video;    }}    mp_msg(MSGT_DEMUX,MSGL_DBG2, "unknown stream id (%d)\n", stream_id);discard:    stream_skip(demuxer->stream, len);  }//    goto loop;}extern void print_wave_header(WAVEFORMATEX *h);void demux_open_real(demuxer_t* demuxer){    real_priv_t* priv = demuxer->priv;    int num_of_headers;    int a_streams=0;    int v_streams=0;    int i;    int header_size;    header_size = stream_read_dword(demuxer->stream); /* header size */    mp_msg(MSGT_DEMUX,MSGL_V, "real: Header size: %d\n", header_size);    i = stream_read_word(demuxer->stream); /* version */    mp_msg(MSGT_DEMUX,MSGL_V, "real: Header object version: %d\n", i);    if (header_size == 0x10)    	i = stream_read_word(demuxer->stream);    else /* we should test header_size here too. */    	i = stream_read_dword(demuxer->stream);    mp_msg(MSGT_DEMUX,MSGL_V, "real: File version: %d\n", i);    num_of_headers = stream_read_dword(demuxer->stream);//    stream_skip(demuxer->stream, 4); /* number of headers */    /* parse chunks */    for (i = 1; i <= num_of_headers; i++)//    for (i = 1; ; i++)    {	int chunk_id, chunk_pos, chunk_size;		chunk_pos = stream_tell(demuxer->stream);	chunk_id = stream_read_dword_le(demuxer->stream);	chunk_size = stream_read_dword(demuxer->stream);	stream_skip(demuxer->stream, 2); /* version */	mp_msg(MSGT_DEMUX,MSGL_V, "Chunk: %.4s (%x) (size: 0x%x, offset: 0x%x)\n",	    (char *)&chunk_id, chunk_id, chunk_size, chunk_pos);		if (chunk_size < 10){	    mp_msg(MSGT_DEMUX,MSGL_ERR,"demux_real: invalid chunksize! (%d)\n",chunk_size);	    break; //return;	}		switch(chunk_id)	{	    case MKTAG('P', 'R', 'O', 'P'):		/* Properties header */		stream_skip(demuxer->stream, 4); /* max bitrate */		stream_skip(demuxer->stream, 4); /* avg bitrate */		stream_skip(demuxer->stream, 4); /* max packet size */		stream_skip(demuxer->stream, 4); /* avg packet size */		stream_skip(demuxer->stream, 4); /* nb packets */		priv->duration = stream_read_dword(demuxer->stream)/1000; /* duration */		//stream_skip(demuxer->stream, 4); /* duration */		stream_skip(demuxer->stream, 4); /* preroll */		priv->index_chunk_offset = stream_read_dword(demuxer->stream);		mp_msg(MSGT_DEMUX,MSGL_V,"First index chunk offset: 0x%x\n", priv->index_chunk_offset);		priv->data_chunk_offset = stream_read_dword(demuxer->stream)+10;		mp_msg(MSGT_DEMUX,MSGL_V,"First data chunk offset: 0x%x\n", priv->data_chunk_offset);		stream_skip(demuxer->stream, 2); /* nb streams */#if 0		stream_skip(demuxer->stream, 2); /* flags */#else		{		    int flags = stream_read_word(demuxer->stream);		    		    if (flags)		    {		    mp_msg(MSGT_DEMUX,MSGL_V,"Flags (%x): ", flags);		    if (flags & 0x1)			mp_msg(MSGT_DEMUX,MSGL_V,"[save allowed] ");		    if (flags & 0x2)			mp_msg(MSGT_DEMUX,MSGL_V,"[perfect play (more buffers)] ");		    if (flags & 0x4)			mp_msg(MSGT_DEMUX,MSGL_V,"[live broadcast] ");		    mp_msg(MSGT_DEMUX,MSGL_V,"\n");		    }		}#endif		break;	    case MKTAG('C', 'O', 'N', 'T'):	    {		/* Content description header */		char *buf;		int len;		len = stream_read_word(demuxer->stream);		if (len > 0)		{		    buf = malloc(len+1);		    stream_read(demuxer->stream, buf, len);		    buf[len] = 0;		    demux_info_add(demuxer, "name", buf);		    free(buf);		}		len = stream_read_word(demuxer->stream);		if (len > 0)		{		    buf = malloc(len+1);		    stream_read(demuxer->stream, buf, len);		    buf[len] = 0;		    demux_info_add(demuxer, "author", buf);		    free(buf);		}		len = stream_read_word(demuxer->stream);		if (len > 0)		{		    buf = malloc(len+1);		    stream_read(demuxer->stream, buf, len);		    buf[len] = 0;		    demux_info_add(demuxer, "copyright", buf);		    free(buf);		}		len = stream_read_word(demuxer->stream);		if (len > 0)		{		    buf = malloc(len+1);	    	    stream_read(demuxer->stream, buf, len);		    buf[len] = 0;		    demux_info_add(demuxer, "comment", buf);		    free(buf);		}		break;	    }	    case MKTAG('M', 'D', 'P', 'R'):	    {		/* Media properties header */		int stream_id;		int bitrate;		int codec_data_size;		int codec_pos;		int tmp;		int len;		char *descr, *mimet;		stream_id = stream_read_word(demuxer->stream);		mp_msg(MSGT_DEMUX,MSGL_V,"Found new stream (id: %d)\n", stream_id);				stream_skip(demuxer->stream, 4); /* max bitrate */		bitrate = stream_read_dword(demuxer->stream); /* avg bitrate */		stream_skip(demuxer->stream, 4); /* max packet size */		stream_skip(demuxer->stream, 4); /* avg packet size */		stream_skip(demuxer->stream, 4); /* start time */		stream_skip(demuxer->stream, 4); /* preroll */		stream_skip(demuxer->stream, 4); /* duration */		//		skip_str(1, demuxer);	/* stream description (name) */		if ((len = stream_read_char(demuxer->stream)) > 0) {		    descr = malloc(len+1);	    	stream_read(demuxer->stream, descr, len);		    descr[len] = 0;		    printf("Stream description: %s\n", descr);		    free(descr);		}//		skip_str(1, demuxer);	/* mimetype */		if ((len = stream_read_char(demuxer->stream)) > 0) {		    mimet = malloc(len+1);	    	stream_read(demuxer->stream, mimet, len);		    mimet[len] = 0;		    printf("Stream mimetype: %s\n", mimet);		}				/* Type specific header */		codec_data_size = stream_read_dword(demuxer->stream);		codec_pos = stream_tell(demuxer->stream);

⌨️ 快捷键说明

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