📄 demuxer.c
字号:
ds->current=p; ds->first=p->next; if(!ds->first) ds->last=NULL; --ds->packs; return 1; //ds->buffer_size; } if(demux->audio->packs>=MAX_PACKS || demux->audio->bytes>=MAX_PACK_BYTES){ mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_TooManyAudioInBuffer,demux->audio->packs,demux->audio->bytes); mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI); break; } if(demux->video->packs>=MAX_PACKS || demux->video->bytes>=MAX_PACK_BYTES){ mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_TooManyVideoInBuffer,demux->video->packs,demux->video->bytes); mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI); break; } if(!demux_fill_buffer(demux,ds)){ mp_dbg(MSGT_DEMUXER,MSGL_DBG2,"ds_fill_buffer()->demux_fill_buffer() failed\n"); break; // EOF } } ds->buffer_pos=ds->buffer_size=0; ds->buffer=NULL; ds->current=NULL; mp_msg(MSGT_DEMUXER,MSGL_V,"ds_fill_buffer: EOF reached (stream: %s) \n",ds==demux->audio?"audio":"video"); ds->eof=1; return 0;}int demux_read_data(demux_stream_t *ds,unsigned char* mem,int len){int x;int bytes=0;while(len>0){ x=ds->buffer_size-ds->buffer_pos; if(x==0){ if(!ds_fill_buffer(ds)) return bytes; } else { if(x>len) x=len; if(mem) memcpy(mem+bytes,&ds->buffer[ds->buffer_pos],x); bytes+=x;len-=x;ds->buffer_pos+=x; }}return bytes;}int demux_read_data_pack(demux_stream_t *ds,unsigned char* mem,int len){int x;int bytes=0;while(len>0){ x=ds->buffer_size-ds->buffer_pos; if(x==0){ if(!ds_fill_buffer(ds)) return bytes; } else { if(x>len) x=len; if(mem) memcpy(mem+bytes,&ds->buffer[ds->buffer_pos],x); bytes+=x;len-=x;ds->buffer_pos+=x; return bytes; // stop at end of package! (for correct timestamping) }}return bytes;}void ds_free_packs(demux_stream_t *ds){ demux_packet_t *dp=ds->first; while(dp){ demux_packet_t *dn=dp->next; free_demux_packet(dp); dp=dn; } if(ds->asf_packet){ // free unfinished .asf fragments: free(ds->asf_packet->buffer); free(ds->asf_packet); ds->asf_packet=NULL; } ds->first=ds->last=NULL; ds->packs=0; // !!!!! ds->bytes=0; if(ds->current) free_demux_packet(ds->current); ds->current=NULL; ds->buffer=NULL; ds->buffer_pos=ds->buffer_size; ds->pts=0; ds->pts_bytes=0;}int ds_get_packet(demux_stream_t *ds,unsigned char **start){ while(1){ int len; if(ds->buffer_pos>=ds->buffer_size){ if(!ds_fill_buffer(ds)){ // EOF *start = NULL; return -1; } } len=ds->buffer_size-ds->buffer_pos; *start = &ds->buffer[ds->buffer_pos]; ds->buffer_pos+=len; return len; }}int ds_get_packet_sub(demux_stream_t *ds,unsigned char **start){ while(1){ int len; if(ds->buffer_pos>=ds->buffer_size){ *start = NULL; if(!ds->packs) return -1; // no sub if(!ds_fill_buffer(ds)) return -1; // EOF } len=ds->buffer_size-ds->buffer_pos; *start = &ds->buffer[ds->buffer_pos]; ds->buffer_pos+=len; return len; }}float ds_get_next_pts(demux_stream_t *ds) { demuxer_t* demux = ds->demuxer; while(!ds->first) { if(demux->audio->packs>=MAX_PACKS || demux->audio->bytes>=MAX_PACK_BYTES){ mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_TooManyAudioInBuffer,demux->audio->packs,demux->audio->bytes); mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI); return -1; } if(demux->video->packs>=MAX_PACKS || demux->video->bytes>=MAX_PACK_BYTES){ mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_TooManyVideoInBuffer,demux->video->packs,demux->video->bytes); mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI); return -1; } if(!demux_fill_buffer(demux,ds)) return -1; } return ds->first->pts;}// ====================================================================// feed-back from demuxers:extern int num_elementary_packets100; // for MPEG-ES fileformat detectionextern int num_elementary_packets101;extern int num_elementary_packetsPES;extern int num_elementary_packets1B6;extern int num_elementary_packets12x;extern int num_h264_slice; //combined sliceextern int num_h264_dpa; //DPA Sliceextern int num_h264_dpb; //DPB Sliceextern int num_h264_dpc; //DPC Sliceextern int num_h264_idr; //IDR Sliceextern int num_h264_sps;extern int num_h264_pps;extern int num_mp3audio_packets;// commandline options, flags:extern int force_ni;extern int pts_from_bps;//extern int audio_id;//extern int video_id;//extern int dvdsub_id;int asf_check_header(demuxer_t *demuxer);int read_asf_header(demuxer_t *demuxer);demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id);demuxer_t* demux_open_avi(demuxer_t* demuxer);//int mov_check_file(demuxer_t* demuxer);//int mov_read_header(demuxer_t* demuxer);int demux_open_fli(demuxer_t* demuxer);int demux_open_mf(demuxer_t* demuxer);int demux_open_film(demuxer_t* demuxer);int demux_open_roq(demuxer_t* demuxer);#ifdef HAVE_LIBDV095int demux_open_rawdv(demuxer_t* demuxer);extern int rawdv_check_file(demuxer_t *demuxer);#endif#ifdef USE_WIN32DLLint avs_check_file(demuxer_t *demuxer, const char *filename);#endifextern int vivo_check_file(demuxer_t *demuxer);extern void demux_open_vivo(demuxer_t *demuxer);extern int y4m_check_file(demuxer_t *demuxer);extern void demux_open_y4m(demuxer_t *demuxer);extern int roq_check_file(demuxer_t *demuxer);extern int pva_check_file(demuxer_t * demuxer);extern demuxer_t * demux_open_pva(demuxer_t * demuxer);extern int real_check_file(demuxer_t *demuxer);extern void demux_open_real(demuxer_t *demuxer);extern int nsv_check_file(demuxer_t *demuxer);extern int nuv_check_file(demuxer_t *demuxer);extern void demux_open_nsv(demuxer_t *demuxer);extern void demux_open_nuv(demuxer_t *demuxer);extern int demux_audio_open(demuxer_t* demuxer);extern int demux_ogg_open(demuxer_t* demuxer);extern int demux_mpg_open(demuxer_t* demuxer);extern int demux_rawaudio_open(demuxer_t* demuxer);extern int demux_rawvideo_open(demuxer_t* demuxer);extern int smjpeg_check_file(demuxer_t *demuxer);extern int demux_open_smjpeg(demuxer_t* demuxer);extern int demux_xmms_open(demuxer_t* demuxer);extern int gif_check_file(demuxer_t *demuxer);extern int demux_open_gif(demuxer_t* demuxer);extern int lmlm4_check_file(demuxer_t* demuxer);extern int demux_open_lmlm4(demuxer_t* demuxer);extern int ts_check_file(demuxer_t * demuxer);extern int demux_open_ts(demuxer_t *demuxer);extern int demux_open_mkv(demuxer_t *demuxer);extern int ra_check_file(demuxer_t *demuxer);extern int demux_open_ra(demuxer_t* demuxer);//extern int demux_probe_vqf(demuxer_t *demuxer);//extern int demux_open_vqf(demuxer_t* demuxer);#ifdef HAVE_MATROSKAextern int demux_mkv_open(demuxer_t *demuxer);#endifextern int lavf_check_file(demuxer_t *demuxer);extern int demux_open_lavf(demuxer_t* demuxer);#ifdef USE_WIN32DLLextern int demux_open_avs(demuxer_t* demuxer);#endifextern demuxer_t* init_avi_with_ogg(demuxer_t* demuxer);#ifdef STREAMING_LIVE_DOT_COMextern demuxer_t* demux_open_rtp(demuxer_t* demuxer);#endifint extension_parsing=1; // 0=off 1=mixed (used only for unstable formats)/* NOTE : Several demuxers may be opened at the same time so demuxers should NEVER rely on an external var to enable them self. If a demuxer can't do any autodection it should only use file_format. The user can explictly set file_format with the -demuxer option so there is really no need for another extra var. For conivence an option can be added to set file_format directly to the right type (ex: rawaudio,rawvideo). Also the stream can override the file_format so a demuxer wich rely on a special stream type can set file_format at the stream level (ex: tv,mf).*/static demuxer_t* demux_open_stream(stream_t *stream,int file_format,int audio_id,int video_id,int dvdsub_id,char* filename){//int file_format=(*file_format_ptr);demuxer_t *demuxer=NULL;demux_stream_t *d_audio=NULL;demux_stream_t *d_video=NULL;sh_audio_t *sh_audio=NULL;sh_video_t *sh_video=NULL;//printf("demux_open(%p,%d,%d,%d,%d) \n",stream,file_format,audio_id,video_id,dvdsub_id);if(file_format == DEMUXER_TYPE_RAWAUDIO) { demuxer = new_demuxer(stream,DEMUXER_TYPE_RAWAUDIO,audio_id,video_id,dvdsub_id);}if(file_format == DEMUXER_TYPE_RAWVIDEO) { demuxer = new_demuxer(stream,DEMUXER_TYPE_RAWVIDEO,audio_id,video_id,dvdsub_id);}#ifdef USE_TV//=============== Try to open as TV-input: =================if(file_format==DEMUXER_TYPE_TV){ demuxer=new_demuxer(stream,DEMUXER_TYPE_TV,audio_id,video_id,dvdsub_id); mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_DetectedTV);}#endif//=============== Try to open as multi file: =================if(file_format==DEMUXER_TYPE_MF){ demuxer=new_demuxer(stream,DEMUXER_TYPE_MF,audio_id,video_id,dvdsub_id); mp_msg( MSGT_DEMUXER,MSGL_INFO,"[demuxer] mf support.\n" );}//=============== Try to open as AVI file: =================if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_AVI){ demuxer=new_demuxer(stream,DEMUXER_TYPE_AVI,audio_id,video_id,dvdsub_id); { //---- RIFF header: int id=stream_read_dword_le(demuxer->stream); // "RIFF" if((id==mmioFOURCC('R','I','F','F')) || (id==mmioFOURCC('O','N','2',' '))){ stream_read_dword_le(demuxer->stream); //filesize id=stream_read_dword_le(demuxer->stream); // "AVI " if(id==formtypeAVI){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"AVI"); file_format=DEMUXER_TYPE_AVI; } if(id==mmioFOURCC('O','N','2','f')){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"ON2 AVI"); file_format=DEMUXER_TYPE_AVI; } } if (file_format==DEMUXER_TYPE_UNKNOWN) { free_demuxer(demuxer); demuxer = NULL; } }}//=============== Try to open as Y4M file: =================if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_Y4M){ demuxer=new_demuxer(stream,DEMUXER_TYPE_Y4M,audio_id,video_id,dvdsub_id); if(y4m_check_file(demuxer)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"YUV4MPEG2"); file_format=DEMUXER_TYPE_Y4M; } else { free_demuxer(demuxer); demuxer = NULL; }}//=============== Try to open as ASF file: =================if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_ASF){ demuxer=new_demuxer(stream,DEMUXER_TYPE_ASF,audio_id,video_id,dvdsub_id); if(asf_check_header(demuxer)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"ASF"); file_format=DEMUXER_TYPE_ASF; } else { free_demuxer(demuxer); demuxer = NULL; }}//=============== Try to open as NSV file: =================if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_NSV){ demuxer=new_demuxer(stream,DEMUXER_TYPE_NSV,audio_id,video_id,dvdsub_id); if(file_format==DEMUXER_TYPE_NSV||nsv_check_file(demuxer)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"Nullsoft Streaming Video"); file_format=DEMUXER_TYPE_NSV; } else { free_demuxer(demuxer); demuxer = NULL; }}//=============== Try to open as NUV file: =================if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_NUV){ demuxer=new_demuxer(stream,DEMUXER_TYPE_NUV,audio_id,video_id,dvdsub_id); if(nuv_check_file(demuxer)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"NuppelVideo"); file_format=DEMUXER_TYPE_NUV; } else { free_demuxer(demuxer); demuxer = NULL; }}//=============== Try to open as REAL file: =================if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_REAL){ demuxer=new_demuxer(stream,DEMUXER_TYPE_REAL,audio_id,video_id,dvdsub_id); if(real_check_file(demuxer)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"REAL"); file_format=DEMUXER_TYPE_REAL; } else { free_demuxer(demuxer); demuxer = NULL; }}//=============== Try to open as SMJPEG file: =================if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_SMJPEG){ demuxer=new_demuxer(stream,DEMUXER_TYPE_SMJPEG,audio_id,video_id,dvdsub_id); if(smjpeg_check_file(demuxer)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"SMJPEG"); file_format=DEMUXER_TYPE_SMJPEG; } else { free_demuxer(demuxer); demuxer = NULL; }}#ifdef HAVE_MATROSKA//=============== Try to open as Matroska file: =================if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MATROSKA){ demuxer=new_demuxer(stream,DEMUXER_TYPE_MATROSKA,audio_id,video_id,dvdsub_id); if(demux_mkv_open(demuxer)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"Matroska"); file_format=DEMUXER_TYPE_MATROSKA; } else { free_demuxer(demuxer); demuxer = NULL; }}#endif//=============== Try to open as REALAUDIO file: =================if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_REALAUDIO){ demuxer=new_demuxer(stream,DEMUXER_TYPE_REALAUDIO,audio_id,video_id,dvdsub_id); if(ra_check_file(demuxer)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"REALAUDIO"); file_format=DEMUXER_TYPE_REALAUDIO; } else { free_demuxer(demuxer); demuxer = NULL; }}//=============== Try to open as VQF file: =================/*if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_VQF){ demuxer=new_demuxer(stream,DEMUXER_TYPE_VQF,audio_id,video_id,dvdsub_id); if(demux_probe_vqf(demuxer)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"VQF"); file_format=DEMUXER_TYPE_VQF; } else { free_demuxer(demuxer); demuxer = NULL; }}*///=============== Try based on filename EXTENSION: =================// Ok. We're over the stable detectable fileformats, the next ones are a bit// fuzzy. So by default (extension_parsing==1) try extension-based detection// first:if(file_format==DEMUXER_TYPE_UNKNOWN && filename && extension_parsing==1){ file_format=demuxer_type_by_filename(filename); if(file_format!=DEMUXER_TYPE_UNKNOWN){ // we like recursion :) demuxer=demux_open_stream(stream,file_format,audio_id,video_id,dvdsub_id,filename); if(demuxer) return demuxer; // done! file_format=DEMUXER_TYPE_UNKNOWN; // continue fuzzy guessing... mp_msg(MSGT_DEMUXER,MSGL_V,"demuxer: continue fuzzy content-based format guessing...\n"); }}//=============== Try to open as MOV file: =================/*if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MOV){ demuxer=new_demuxer(stream,DEMUXER_TYPE_MOV,audio_id,video_id,dvdsub_id); if(mov_check_file(demuxer)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"QuickTime/MOV"); file_format=demuxer->type; } else { free_demuxer(demuxer); demuxer = NULL; }}*///=============== Try to open as VIVO file: =================if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_VIVO){ demuxer=new_demuxer(stream,DEMUXER_TYPE_VIVO,audio_id,video_id,dvdsub_id); if(vivo_check_file(demuxer)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat, "VIVO"); file_format=DEMUXER_TYPE_VIVO; } else { free_demuxer(demuxer); demuxer = NULL; }}//=============== Try to open as FLI file: =================if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_FLI){ demuxer=new_demuxer(stream,DEMUXER_TYPE_FLI,audio_id,video_id,dvdsub_id); { int id; stream_seek(demuxer->stream, 4); id=stream_read_word_le(demuxer->stream);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -