demux_real_1.c

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

C
1,824
字号
		    if ( mp_msg_test(MSGT_DEMUX,MSGL_V) )		    print_wave_header(sh->wf, MSGL_V);		    /* Select audio stream with highest bitrate if multirate file*/		    if (priv->is_multirate && ((demuxer->audio->id == -1) ||		                               ((demuxer->audio->id >= 0) && priv->a_bitrate && (bitrate > priv->a_bitrate)))) {			    demuxer->audio->id = stream_id;			    priv->a_bitrate = bitrate;			    mp_msg(MSGT_DEMUX,MSGL_DBG2,"Multirate autoselected audio id %d with bitrate %d\n", stream_id, bitrate);		    }		    if(demuxer->audio->id==stream_id){			sh->ds=demuxer->audio;			demuxer->audio->sh=sh;        	priv->audio_buf = calloc(priv->sub_packet_h[demuxer->audio->id], priv->audiopk_size[demuxer->audio->id]);        	priv->audio_timestamp = calloc(priv->sub_packet_h[demuxer->audio->id], sizeof(double));		    }		    		    ++a_streams;#ifdef stream_skip#undef stream_skip#endif		}	  } else if (strstr(mimet,"X-MP3-draft-00")) {		    sh_audio_t *sh = new_sh_audio(demuxer, stream_id);    		    mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "real", stream_id);		    /* Emulate WAVEFORMATEX struct: */		    sh->wf = malloc(sizeof(WAVEFORMATEX));		    memset(sh->wf, 0, sizeof(WAVEFORMATEX));		    sh->wf->nChannels = 0;//sh->channels;		    sh->wf->wBitsPerSample = 16;		    sh->wf->nSamplesPerSec = 0;//sh->samplerate;		    sh->wf->nAvgBytesPerSec = 0;//bitrate;		    sh->wf->nBlockAlign = 0;//frame_size;		    sh->wf->cbSize = 0;		    sh->wf->wFormatTag = sh->format = mmioFOURCC('a','d','u',0x55);		    		    if(demuxer->audio->id==stream_id){			    sh->ds=demuxer->audio;			    demuxer->audio->sh=sh;		    }		    		    ++a_streams;	  } else if (strstr(mimet,"x-ralf-mpeg4")) {		 mp_msg(MSGT_DEMUX,MSGL_ERR,"Real lossless audio not supported yet\n");	  } else {		 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown audio stream format\n");		}	} else if (!strncmp(mimet,"video/",6)) {	  if (strstr(mimet,"x-pn-realvideo") || strstr(mimet,"x-pn-multirate-realvideo")) {		stream_skip(demuxer->stream, 4);  // VIDO length, same as codec_data_size		tmp = stream_read_dword(demuxer->stream);		if(tmp != MKTAG('O', 'D', 'I', 'V'))		{		    mp_msg(MSGT_DEMUX,MSGL_V,"Video: can't find VIDO in codec data\n");		} else {		    /* video header */		    sh_video_t *sh = new_sh_video(demuxer, stream_id);		    mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "real", stream_id);		    sh->format = stream_read_dword_le(demuxer->stream); /* fourcc */		    mp_msg(MSGT_DEMUX,MSGL_V,"video fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format);		    /* emulate BITMAPINFOHEADER */		    sh->bih = malloc(sizeof(BITMAPINFOHEADER));		    memset(sh->bih, 0, sizeof(BITMAPINFOHEADER));	    	    sh->bih->biSize = sizeof(BITMAPINFOHEADER);		    sh->disp_w = sh->bih->biWidth = stream_read_word(demuxer->stream);		    sh->disp_h = sh->bih->biHeight = stream_read_word(demuxer->stream);		    sh->bih->biPlanes = 1;		    sh->bih->biBitCount = 24;		    sh->bih->biCompression = sh->format;		    sh->bih->biSizeImage= sh->bih->biWidth*sh->bih->biHeight*3;		    sh->fps = (float) stream_read_word(demuxer->stream);		    if (sh->fps<=0) sh->fps=24; // we probably won't even care about fps		    sh->frametime = 1.0f/sh->fps;		    #if 1		    stream_skip(demuxer->stream, 4);#else		    mp_msg(MSGT_DEMUX, MSGL_V,"unknown1: 0x%X  \n",stream_read_dword(demuxer->stream));		    mp_msg(MSGT_DEMUX, MSGL_V,"unknown2: 0x%X  \n",stream_read_word(demuxer->stream));		    mp_msg(MSGT_DEMUX, MSGL_V,"unknown3: 0x%X  \n",stream_read_word(demuxer->stream));#endif//		    if(sh->format==0x30335652 || sh->format==0x30325652 )		    if(1)		    {			int tmp=stream_read_word(demuxer->stream);			if(tmp>0){			    sh->fps=tmp; sh->frametime = 1.0f/sh->fps;			}		    } else {	    		int fps=stream_read_word(demuxer->stream);			mp_msg(MSGT_DEMUX, MSGL_WARN,"realvid: ignoring FPS = %d\n",fps);		    }		    stream_skip(demuxer->stream, 2);		    		    {			    // read and store codec extradata			    unsigned int cnt = codec_data_size - (stream_tell(demuxer->stream) - codec_pos);			    if (cnt > 0x7fffffff - sizeof(BITMAPINFOHEADER)) {			        mp_msg(MSGT_DEMUX, MSGL_ERR,"Extradata too big (%u)\n", cnt);			    } else  {				sh->bih = realloc(sh->bih, sizeof(BITMAPINFOHEADER) + cnt);			        sh->bih->biSize += cnt;				stream_read(demuxer->stream, ((unsigned char*)(sh->bih+1)), cnt);			    }		    } 		    if(sh->format == 0x30315652 && ((unsigned char*)(sh->bih+1))[6] == 0x30)			    sh->bih->biCompression = sh->format = mmioFOURCC('R', 'V', '1', '3');		    		    /* 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){			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 ((unsigned)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 ((unsigned)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); /* 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 && parse_index_chunk(demuxer))	    {		demuxer->seekable = 1;	    }	    break;	case 1: // use (generate index)	    if (priv->index_chunk_offset && 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",	    (char *)&sh->format,((unsigned int*)(sh->bih+1))[1],((unsigned int*)(sh->bih+1))[0],	    sh->disp_w,sh->disp_h,sh->aspect,sh->fps);    }    if(demuxer->audio->sh){	sh_audio_t *sh=demuxer->audio->sh;	mp_msg(MSGT_DEMUX,MSGL_V,"AUDIO:  %.4s [%08X]\n",	    (char *)&sh->format,sh->format);    }    return demuxer;}static 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]);    if (priv->audio_buf)        free(priv->audio_buf);    if (priv->audio_timestamp)        free(priv->audio_timestamp);	free(priv);    }    return;}/* please upload RV10 samples WITH INDEX CHUNK */static void demux_seek_real(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, 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;    int64_t 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;    if (flags & 1)	/* seek absolute */	priv->current_apacket = priv->current_vpacket = 0;    if (flags & 2) // percent seek        rel_seek_secs *= priv->duration;    if ((streams & 1) && priv->current_vpacket >= priv->index_table_size[vid])

⌨️ 快捷键说明

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