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

📄 demux_real.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
			    break;			case 0x10003000:			case 0x10003001:			    /* sub id: 3 */			    /* codec id: rv10 */			    sh->bih->biCompression = sh->format = mmioFOURCC('R', 'V', '1', '3');			    break;			case 0x20001000:			case 0x20100001:			case 0x20200002:			    /* codec id: rv20 */			    break;			case 0x30202002:			    /* codec id: rv30 */			    break;			case 0x40000000:			    /* codec id: rv40 */			    break;			default:			    /* codec id: none */			    mp_msg(MSGT_DEMUX,MSGL_V,"unknown id: %x\n", tmp);		    }		    if((sh->format<=0x30335652) && (tmp>=0x20200002)){			    // read data for the cmsg24[] (see vd_realvid.c)			    unsigned int cnt = codec_data_size - (stream_tell(demuxer->stream) - codec_pos);			    if (cnt < 2) {			        mp_msg(MSGT_DEMUX, MSGL_ERR,"realvid: cmsg24 data too short (size %u)\n", cnt);			    } else  {			        int ii;			        if (cnt > 6) {			            mp_msg(MSGT_DEMUX, MSGL_WARN,"realvid: cmsg24 data too big, please report (size %u)\n", cnt);			            cnt = 6;			        }			        for (ii = 0; ii < cnt; ii++)			            ((unsigned char*)(sh->bih+1))[8+ii]=(unsigned short)stream_read_char(demuxer->stream);			    }		    } 		    		    /* Select video stream with highest bitrate if multirate file*/		    if (priv->is_multirate && ((demuxer->video->id == -1) ||		                               ((demuxer->video->id >= 0) && priv->v_bitrate && (bitrate > priv->v_bitrate)))) {			    demuxer->video->id = stream_id;			    priv->v_bitrate = bitrate;			    mp_msg(MSGT_DEMUX,MSGL_DBG2,"Multirate autoselected video id %d with bitrate %d\n", stream_id, bitrate);		    }		    if(demuxer->video->id==stream_id){			demuxer->video->id=stream_id;			sh->ds=demuxer->video;			demuxer->video->sh=sh;		    }		    		    ++v_streams;		}	  } else {		 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown video stream format\n");	  }	} else if (strstr(mimet,"logical-")) {		 if (strstr(mimet,"fileinfo")) {		     mp_msg(MSGT_DEMUX,MSGL_V,"Got a logical-fileinfo chunk\n");		 } else if (strstr(mimet,"-audio") || strstr(mimet,"-video")) {		    int i, stream_cnt;		    int stream_list[MAX_STREAMS];		    		    priv->is_multirate = 1;		    stream_skip(demuxer->stream, 4); // Length of codec data (repeated)		    stream_cnt = stream_read_dword(demuxer->stream); // Get number of audio or video streams		    if (stream_cnt >= MAX_STREAMS) {		        mp_msg(MSGT_DEMUX,MSGL_ERR,"Too many streams in %s. Big troubles ahead.\n", mimet);		        goto skip_this_chunk;		    }		    for (i = 0; i < stream_cnt; i++)		        stream_list[i] = stream_read_word(demuxer->stream);		    for (i = 0; i < stream_cnt; i++)		        if (stream_list[i] >= MAX_STREAMS) {		            mp_msg(MSGT_DEMUX,MSGL_ERR,"Stream id out of range: %d. Ignored.\n", stream_list[i]);		            stream_skip(demuxer->stream, 4); // Skip DATA offset for broken stream		        } else {		            priv->str_data_offset[stream_list[i]] = stream_read_dword(demuxer->stream);		            mp_msg(MSGT_DEMUX,MSGL_V,"Stream %d with DATA offset 0x%08x\n", stream_list[i], priv->str_data_offset[stream_list[i]]);		        }		    // Skip the rest of this chunk		 } else 		     mp_msg(MSGT_DEMUX,MSGL_V,"Unknown logical stream\n");		}		else {		    mp_msg(MSGT_DEMUX, MSGL_ERR, "Not audio/video stream or unsupported!\n");		}//		break;//	    default:skip_this_chunk:		/* skip codec info */		tmp = stream_tell(demuxer->stream) - codec_pos;		mp_msg(MSGT_DEMUX,MSGL_V,"### skipping %d bytes of codec info\n", codec_data_size - tmp);#if 0		{ int i;		  for(i=0;i<codec_data_size - tmp;i++)		      mp_msg(MSGT_DEMUX, MSGL_V," %02X",stream_read_char(demuxer->stream));		  mp_msg(MSGT_DEMUX, MSGL_V,"\n");		}#else		stream_skip(demuxer->stream, codec_data_size - tmp);#endif		if (mimet)		    free (mimet);		break;//	    }	    }	    case MKTAG('D', 'A', 'T', 'A'):		goto header_end;	    case MKTAG('I', 'N', 'D', 'X'):	    default:		mp_msg(MSGT_DEMUX,MSGL_V,"Unknown chunk: %x\n", chunk_id);		stream_skip(demuxer->stream, chunk_size - 10);		break;	}    }header_end:    if(priv->is_multirate) {        mp_msg(MSGT_DEMUX,MSGL_V,"Selected video id %d audio id %d\n", demuxer->video->id, demuxer->audio->id);        /* Perform some sanity checks to avoid checking streams id all over the code*/        if (demuxer->audio->id >= MAX_STREAMS) {            mp_msg(MSGT_DEMUX,MSGL_ERR,"Invalid audio stream %d. No sound will be played.\n", demuxer->audio->id);            demuxer->audio->id = -2;        } else if ((demuxer->audio->id >= 0) && (priv->str_data_offset[demuxer->audio->id] == 0)) {            mp_msg(MSGT_DEMUX,MSGL_ERR,"Audio stream %d not found. No sound will be played.\n", demuxer->audio->id);            demuxer->audio->id = -2;        }        if (demuxer->video->id >= MAX_STREAMS) {            mp_msg(MSGT_DEMUX,MSGL_ERR,"Invalid video stream %d. No video will be played.\n", demuxer->video->id);            demuxer->video->id = -2;        } else if ((demuxer->video->id >= 0) && (priv->str_data_offset[demuxer->video->id] == 0)) {            mp_msg(MSGT_DEMUX,MSGL_ERR,"Video stream %d not found. No video will be played.\n", demuxer->video->id);            demuxer->video->id = -2;        }    }    if(priv->is_multirate && ((demuxer->video->id >= 0) || (demuxer->audio->id  >=0))) {        /* If audio or video only, seek to right place and behave like standard file */        if (demuxer->video->id < 0) {            // Stream is audio only, or -novideo            stream_seek(demuxer->stream, priv->data_chunk_offset = priv->str_data_offset[demuxer->audio->id]+10);            priv->is_multirate = 0;        }        if (demuxer->audio->id < 0) {            // Stream is video only, or -nosound            stream_seek(demuxer->stream, priv->data_chunk_offset = priv->str_data_offset[demuxer->video->id]+10);            priv->is_multirate = 0;        }    }  if(!priv->is_multirate) {//    printf("i=%d num_of_headers=%d   \n",i,num_of_headers);    priv->num_of_packets = stream_read_dword(demuxer->stream);//    stream_skip(demuxer->stream, 4); /* number of packets */    stream_skip(demuxer->stream, 4); /* next data header */    mp_msg(MSGT_DEMUX,MSGL_V,"Packets in file: %d\n", priv->num_of_packets);    if (priv->num_of_packets == 0)	priv->num_of_packets = -10;  } else {        priv->audio_curpos = priv->str_data_offset[demuxer->audio->id] + 18;        stream_seek(demuxer->stream, priv->str_data_offset[demuxer->audio->id]+10);        priv->a_num_of_packets=priv->a_num_of_packets = stream_read_dword(demuxer->stream);        priv->video_curpos = priv->str_data_offset[demuxer->video->id] + 18;        stream_seek(demuxer->stream, priv->str_data_offset[demuxer->video->id]+10);        priv->v_num_of_packets = stream_read_dword(demuxer->stream);        priv->stream_switch = 1;        /* Index required for multirate playback, force building if it's not there */        /* but respect user request to force index regeneration */        if (index_mode == -1)            index_mode = 1;    }    priv->audio_need_keyframe = 0;    priv->video_after_seek = 0;    switch (index_mode){	case -1: // untouched	    if (priv->index_chunk_offset && (priv->index_chunk_offset < demuxer->movi_end))	    {		parse_index_chunk(demuxer);		demuxer->seekable = 1;	    }	    break;	case 1: // use (generate index)	    if (priv->index_chunk_offset && (priv->index_chunk_offset < demuxer->movi_end))	    {		parse_index_chunk(demuxer);		demuxer->seekable = 1;	    } else {		generate_index(demuxer);		demuxer->seekable = 1;	    }	    break;	case 2: // force generating index	    generate_index(demuxer);	    demuxer->seekable = 1;	    break;	default: // do nothing    	    break;    }    if(priv->is_multirate)        demuxer->seekable = 0; // No seeking yet for multirate streams    // detect streams:    if(demuxer->video->id==-1 && v_streams>0){	// find the valid video stream:	if(!ds_fill_buffer(demuxer->video)){          mp_msg(MSGT_DEMUXER,MSGL_INFO,"RM: " MSGTR_MissingVideoStream);	}    }    if(demuxer->audio->id==-1 && a_streams>0){	// find the valid audio stream:	if(!ds_fill_buffer(demuxer->audio)){          mp_msg(MSGT_DEMUXER,MSGL_INFO,"RM: " MSGTR_MissingAudioStream);	}    }    if(demuxer->video->sh){	sh_video_t *sh=demuxer->video->sh;	mp_msg(MSGT_DEMUX,MSGL_V,"VIDEO:  %.4s [%08X,%08X]  %dx%d  (aspect %4.2f)  %4.2f fps\n",	    &sh->format,((unsigned int*)(sh->bih+1))[1],((unsigned int*)(sh->bih+1))[0],	    sh->disp_w,sh->disp_h,sh->aspect,sh->fps);    }}void demux_close_real(demuxer_t *demuxer){    int i;    real_priv_t* priv = demuxer->priv;     if (priv){    	for(i=0; i<MAX_STREAMS; i++)	    if(priv->index_table[i])	        free(priv->index_table[i]);	free(priv);    }    return;}extern void resync_audio_stream(sh_audio_t * sh_audio);/* please upload RV10 samples WITH INDEX CHUNK */int demux_seek_real(demuxer_t *demuxer, float rel_seek_secs, int flags){    real_priv_t *priv = demuxer->priv;    demux_stream_t *d_audio = demuxer->audio;    demux_stream_t *d_video = demuxer->video;    sh_audio_t *sh_audio = d_audio->sh;    sh_video_t *sh_video = d_video->sh;    int vid = d_video->id, aid = d_audio->id;    int next_offset = 0;    int cur_timestamp = 0;    int streams = 0;    int retried = 0;    if (sh_video && (unsigned)vid < MAX_STREAMS && priv->index_table_size[vid])	streams |= 1;    if (sh_audio && (unsigned)aid < MAX_STREAMS && priv->index_table_size[aid])	streams |= 2;//    printf("streams: %d\n", streams);    if (!streams)	return 0;    if (flags & 1)	/* seek absolute */	priv->current_apacket = priv->current_vpacket = 0;    if ((streams & 1) && priv->current_vpacket >= priv->index_table_size[vid])	priv->current_vpacket = priv->index_table_size[vid] - 1;    if ((streams & 2) && priv->current_apacket >= priv->index_table_size[aid])	priv->current_apacket = priv->index_table_size[aid] - 1;//    if (index_mode == 1 || index_mode == 2) {    	if (streams & 1) {// use the video index if we have one            cur_timestamp = priv->index_table[vid][priv->current_vpacket].timestamp;	    if (rel_seek_secs > 0)	    	while ((priv->index_table[vid][priv->current_vpacket].timestamp - cur_timestamp) < rel_seek_secs * 1000){	    		priv->current_vpacket += 1;	    		if (priv->current_vpacket >= priv->index_table_size[vid]) {	    			priv->current_vpacket = priv->index_table_size[vid] - 1;				if (!retried) {					stream_seek(demuxer->stream, priv->index_table[vid][priv->current_vpacket].offset);					add_index_segment(demuxer, vid, cur_timestamp + rel_seek_secs * 1000);					retried = 1;				}				else	    				break;	    		}	    	} 	    else if (rel_seek_secs < 0)	    	while ((cur_timestamp - priv->index_table[vid][priv->current_vpacket].timestamp) < - rel_seek_secs * 1000){	    		priv->current_vpacket -= 1;	    		if (priv->current_vpacket < 0) {	    			priv->current_vpacket = 0;	    			break;	    		}	    	}	    next_offset = priv->index_table[vid][priv->current_vpacket].offset;	    priv->audio_need_keyframe = 1;	    priv->video_after_seek = 1;        }    	else if (streams & 2) {            cur_timestamp = priv->index_table[aid][priv->current_apacket].timestamp;	    if (rel_seek_secs > 0)	    	while ((priv->index_table[aid][priv->current_apacket].timestamp - cur_timestamp) < rel_seek_secs * 1000){	    		priv->current_apacket += 1;	    		if (priv->current_apacket >= priv->index_table_size[aid]) {	    			priv->current_apacket = priv->index_table_size[aid] - 1;	    			break;	    		}	    	}	    else if (rel_seek_secs < 0)	    	while ((cur_timestamp - priv->index_table[aid][priv->current_apacket].timestamp) < - rel_seek_secs * 1000){	    		priv->current_apacket -= 1;	    		if (priv->current_apacket < 0) {	    			priv->current_apacket = 0;	    			break;	    		}	    	}	    next_offset = priv->index_table[aid][priv->current_apacket].offset;        }//    }//    printf("seek: pos: %d, current packets: a: %d, v: %d\n",//	next_offset, priv->current_apacket, priv->current_vpacket);    if (next_offset)        stream_seek(demuxer->stream, next_offset);    demux_real_fill_buffer(demuxer);    if (sh_audio)        resync_audio_stream(sh_audio);    return 1;}int demux_real_control(demuxer_t *demuxer, int cmd, void *arg){    real_priv_t *priv = demuxer->priv;    int lastpts = priv->v_pts ? priv->v_pts : priv->a_pts;        switch (cmd) {        case DEMUXER_CTRL_GET_TIME_LENGTH:	    if (priv->duration == 0)	        return DEMUXER_CTRL_DONTKNOW;	    	    *((unsigned long *)arg) = priv->duration;	    return DEMUXER_CTRL_OK;	case DEMUXER_CTRL_GET_PERCENT_POS:	    if (priv->duration == 0)	        return DEMUXER_CTRL_DONTKNOW;	    	    *((int *)arg) = (int)(100 * lastpts / priv->duration);	    return DEMUXER_CTRL_OK;		default:	    return DEMUXER_CTRL_NOTIMPL;    }}

⌨️ 快捷键说明

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