📄 demuxer.c
字号:
//=================== DEMUXER v2.5 =========================#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include "../m_config.h"#include "stream.h"#include "demuxer.h"#include "stheader.h"#include "mf.h"#include "../libaf/af_format.h"//#include "../libvo/fastmemcpy.h"// Should be set to 1 by demux module if ids it passes to new_sh_audio and// new_sh_video don't match aids and vids it accepts from the command lineint demux_aid_vid_mismatch = 0;void free_demuxer_stream(demux_stream_t *ds){ ds_free_packs(ds); free(ds);}demux_stream_t* new_demuxer_stream(struct demuxer_st *demuxer,int id){ demux_stream_t* ds=malloc(sizeof(demux_stream_t)); ds->buffer_pos=ds->buffer_size=0; ds->buffer=NULL; ds->pts=0; ds->pts_bytes=0; ds->eof=0; ds->pos=0; ds->dpos=0; ds->pack_no=0;//--------------- ds->packs=0; ds->bytes=0; ds->first=ds->last=ds->current=NULL; ds->id=id; ds->demuxer=demuxer;//---------------- ds->asf_seq=-1; ds->asf_packet=NULL;//---------------- ds->ss_mul=ds->ss_div=0;//---------------- ds->sh=NULL; return ds;}demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id){ demuxer_t *d=malloc(sizeof(demuxer_t)); memset(d,0,sizeof(demuxer_t)); d->stream=stream; d->movi_start=stream->start_pos; d->movi_end=stream->end_pos; d->seekable=1; d->synced=0; d->filepos=0; d->audio=new_demuxer_stream(d,a_id); d->video=new_demuxer_stream(d,v_id); d->sub=new_demuxer_stream(d,s_id); d->type=type; stream_reset(stream); stream_seek(stream,stream->start_pos); return d;}sh_audio_t* new_sh_audio(demuxer_t *demuxer,int id){ if(id > MAX_A_STREAMS-1 || id < 0) { mp_msg(MSGT_DEMUXER,MSGL_WARN,"Requested audio stream id overflow (%d > %d)\n", id, MAX_A_STREAMS); return NULL; } if(demuxer->a_streams[id]){ mp_msg(MSGT_DEMUXER,MSGL_WARN,MSGTR_AudioStreamRedefined,id); } else { sh_audio_t *sh; mp_msg(MSGT_DEMUXER,MSGL_V,MSGTR_FoundAudioStream,id); demuxer->a_streams[id]=malloc(sizeof(sh_audio_t)); memset(demuxer->a_streams[id],0,sizeof(sh_audio_t)); sh = demuxer->a_streams[id]; // set some defaults sh->samplesize=2; sh->sample_format=AF_FORMAT_S16_NE; sh->audio_out_minsize=8192;/* default size, maybe not enough for Win32/ACM*/ if (identify && !demux_aid_vid_mismatch) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", id); } return demuxer->a_streams[id];}void free_sh_audio(sh_audio_t* sh){ mp_msg(MSGT_DEMUXER,MSGL_DBG2,"DEMUXER: freeing sh_audio at %p\n",sh); if(sh->wf) free(sh->wf); free(sh);}sh_video_t* new_sh_video(demuxer_t *demuxer,int id){ if(id > MAX_V_STREAMS-1 || id < 0) { mp_msg(MSGT_DEMUXER,MSGL_WARN,"Requested video stream id overflow (%d > %d)\n", id, MAX_V_STREAMS); return NULL; } if(demuxer->v_streams[id]){ mp_msg(MSGT_DEMUXER,MSGL_WARN,MSGTR_VideoStreamRedefined,id); } else { mp_msg(MSGT_DEMUXER,MSGL_V,MSGTR_FoundVideoStream,id); demuxer->v_streams[id]=malloc(sizeof(sh_video_t)); memset(demuxer->v_streams[id],0,sizeof(sh_video_t)); if (identify && !demux_aid_vid_mismatch) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_ID=%d\n", id); } return demuxer->v_streams[id];}void free_sh_video(sh_video_t* sh){ mp_msg(MSGT_DEMUXER,MSGL_DBG2,"DEMUXER: freeing sh_video at %p\n",sh); if(sh->bih) free(sh->bih); free(sh);}extern void demux_close_vivo(demuxer_t *demuxer);extern void demux_close_real(demuxer_t *demuxer);extern void demux_close_y4m(demuxer_t *demuxer);extern void demux_close_mf(demuxer_t* demuxer);extern void demux_close_roq(demuxer_t* demuxer);extern void demux_close_film(demuxer_t* demuxer);extern void demux_close_fli(demuxer_t* demuxer);extern void demux_close_nsv(demuxer_t* demuxer);extern void demux_close_nuv(demuxer_t* demuxer);extern void demux_close_audio(demuxer_t* demuxer);extern void demux_close_ogg(demuxer_t* demuxer);extern void demux_close_mpg(demuxer_t* demuxer);extern void demux_close_rtp(demuxer_t* demuxer);extern void demux_close_demuxers(demuxer_t* demuxer);extern void demux_close_avi(demuxer_t *demuxer);extern void demux_close_rawdv(demuxer_t* demuxer);extern void demux_close_pva(demuxer_t* demuxer);extern void demux_close_smjpeg(demuxer_t* demuxer);extern void demux_close_xmms(demuxer_t* demuxer);extern void demux_close_gif(demuxer_t* demuxer);extern void demux_close_lmlm4(demuxer_t* demuxer);extern void demux_close_ts(demuxer_t* demuxer);extern void demux_close_mkv(demuxer_t* demuxer);extern void demux_close_ra(demuxer_t* demuxer);extern void demux_close_ty(demuxer_t* demuxer);extern void demux_close_lavf(demuxer_t* demuxer);//extern void demux_close_vqf(demuxer_t* demuxer);#ifdef USE_WIN32DLLextern void demux_close_avs(demuxer_t* demuxer);#endif#ifdef USE_TV#include "tv.h"extern int tv_param_on;extern int demux_tv_fill_buffer(demuxer_t *demux, demux_stream_t *ds);extern int demux_open_tv(demuxer_t *demuxer);#if defined(USE_TV) && (defined(HAVE_TV_V4L) || defined(HAVE_TV_V4L2))extern void demux_close_tv(demuxer_t *demuxer);#endif#endifvoid free_demuxer(demuxer_t *demuxer){ int i; mp_msg(MSGT_DEMUXER,MSGL_DBG2,"DEMUXER: freeing demuxer at %p\n",demuxer); switch(demuxer->type) { case DEMUXER_TYPE_PVA: demux_close_pva(demuxer); break; case DEMUXER_TYPE_VIVO: demux_close_vivo(demuxer); break; case DEMUXER_TYPE_REAL: demux_close_real(demuxer); break; case DEMUXER_TYPE_Y4M: demux_close_y4m(demuxer); break; case DEMUXER_TYPE_MF: demux_close_mf(demuxer); break; case DEMUXER_TYPE_ROQ: demux_close_roq(demuxer); break; case DEMUXER_TYPE_FILM: demux_close_film(demuxer); break; case DEMUXER_TYPE_FLI: demux_close_fli(demuxer); break; case DEMUXER_TYPE_NSV: demux_close_nsv(demuxer); break; case DEMUXER_TYPE_NUV: demux_close_nuv(demuxer); break;// case DEMUXER_TYPE_MPEG_TY:// demux_close_ty(demuxer); break;#if defined(USE_TV) && (defined(HAVE_TV_V4L) || defined(HAVE_TV_V4L2)) case DEMUXER_TYPE_TV: demux_close_tv(demuxer); break;#endif#ifdef HAVE_LIBDV095 case DEMUXER_TYPE_RAWDV: demux_close_rawdv(demuxer); break;#endif case DEMUXER_TYPE_AUDIO: demux_close_audio(demuxer); break;#ifdef HAVE_OGGVORBIS case DEMUXER_TYPE_OGG: demux_close_ogg(demuxer); break;#endif#ifdef HAVE_MATROSKA case DEMUXER_TYPE_MATROSKA: demux_close_mkv(demuxer); break;#endif#ifdef STREAMING_LIVE_DOT_COM case DEMUXER_TYPE_RTP: demux_close_rtp(demuxer); break;#endif case DEMUXER_TYPE_SMJPEG: demux_close_smjpeg(demuxer); break; case DEMUXER_TYPE_DEMUXERS: demux_close_demuxers(demuxer); break; case DEMUXER_TYPE_AVI: case DEMUXER_TYPE_AVI_NI: case DEMUXER_TYPE_AVI_NINI: demux_close_avi(demuxer); break;#ifdef HAVE_XMMS case DEMUXER_TYPE_XMMS: demux_close_xmms(demuxer); break;#endif#ifdef HAVE_GIF case DEMUXER_TYPE_GIF: demux_close_gif(demuxer); break;#endif case DEMUXER_TYPE_LMLM4: demux_close_lmlm4(demuxer); break; case DEMUXER_TYPE_MPEG_TS: demux_close_ts(demuxer); break; case DEMUXER_TYPE_MPEG_PS: demux_close_mpg(demuxer); break; case DEMUXER_TYPE_REALAUDIO: demux_close_ra(demuxer); break;// case DEMUXER_TYPE_VQF:// demux_close_vqf(demuxer); break;#ifdef USE_LIBAVFORMAT case DEMUXER_TYPE_LAVF: demux_close_lavf(demuxer); break;#endif#ifdef USE_WIN32DLL case DEMUXER_TYPE_AVS: demux_close_avs(demuxer); break;#endif } // free streams: for(i = 0; i < MAX_A_STREAMS; i++) if(demuxer->a_streams[i]) free_sh_audio(demuxer->a_streams[i]); for(i = 0; i < MAX_V_STREAMS; i++) if(demuxer->v_streams[i]) free_sh_video(demuxer->v_streams[i]); //if(sh_audio) free_sh_audio(sh_audio); //if(sh_video) free_sh_video(sh_video); // free demuxers: free_demuxer_stream(demuxer->audio); free_demuxer_stream(demuxer->video); free_demuxer_stream(demuxer->sub); if(demuxer->info) { for(i=0;demuxer->info[i] != NULL; i++) free(demuxer->info[i]); free(demuxer->info); } free(demuxer);}void ds_add_packet(demux_stream_t *ds,demux_packet_t* dp){// demux_packet_t* dp=new_demux_packet(len);// stream_read(stream,dp->buffer,len);// dp->pts=pts; //(float)pts/90000.0f;// dp->pos=pos; // append packet to DS stream: ++ds->packs; ds->bytes+=dp->len; if(ds->last){ // next packet in stream ds->last->next=dp; ds->last=dp; } else { // first packet in stream ds->first=ds->last=dp; } mp_dbg(MSGT_DEMUXER,MSGL_DBG2,"DEMUX: Append packet to %s, len=%d pts=%5.3f pos=%u [packs: A=%d V=%d]\n", (ds==ds->demuxer->audio)?"d_audio":"d_video", dp->len,dp->pts,(unsigned int)dp->pos,ds->demuxer->audio->packs,ds->demuxer->video->packs);}void ds_read_packet(demux_stream_t *ds,stream_t *stream,int len,float pts,off_t pos,int flags){ demux_packet_t* dp=new_demux_packet(len); len = stream_read(stream,dp->buffer,len); resize_demux_packet(dp, len); dp->pts=pts; //(float)pts/90000.0f; dp->pos=pos; dp->flags=flags; // append packet to DS stream: ds_add_packet(ds,dp);}// return value:// 0 = EOF or no stream found or invalid type// 1 = successfully read a packetint demux_mf_fill_buffer( demuxer_t *demux);int demux_roq_fill_buffer(demuxer_t *demux);int demux_film_fill_buffer(demuxer_t *demux);int demux_fli_fill_buffer(demuxer_t *demux);int demux_mpg_es_fill_buffer(demuxer_t *demux);int demux_mpg_fill_buffer(demuxer_t *demux);int demux_ty_fill_buffer(demuxer_t *demux);int demux_avi_fill_buffer(demuxer_t *demux);int demux_avi_fill_buffer_ni(demuxer_t *demux,demux_stream_t *ds);int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t *ds);int demux_asf_fill_buffer(demuxer_t *demux);//int demux_mov_fill_buffer(demuxer_t *demux,demux_stream_t* ds);int demux_vivo_fill_buffer(demuxer_t *demux);int demux_real_fill_buffer(demuxer_t *demuxer);int demux_nsv_fill_buffer(demuxer_t *demux);int demux_nuv_fill_buffer(demuxer_t *demux);int demux_rtp_fill_buffer(demuxer_t *demux, demux_stream_t* ds);int demux_rawdv_fill_buffer(demuxer_t *demuxer);int demux_y4m_fill_buffer(demuxer_t *demux);int demux_audio_fill_buffer(demux_stream_t *ds);int demux_pva_fill_buffer(demuxer_t *demux);int demux_xmms_fill_buffer(demuxer_t *demux,demux_stream_t *ds);int demux_gif_fill_buffer(demuxer_t *demux);int demux_ts_fill_buffer(demuxer_t *demux);int demux_ra_fill_buffer(demuxer_t *demux);//int demux_vqf_fill_buffer(demuxer_t *demux);extern int demux_demuxers_fill_buffer(demuxer_t *demux,demux_stream_t *ds);extern int demux_ogg_fill_buffer(demuxer_t *d);extern int demux_rawaudio_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds);extern int demux_rawvideo_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds);extern int demux_smjpeg_fill_buffer(demuxer_t* demux);extern int demux_lmlm4_fill_buffer(demuxer_t* demux);extern int demux_mkv_fill_buffer(demuxer_t *d);extern int demux_lavf_fill_buffer(demuxer_t *d);#ifdef USE_WIN32DLLextern int demux_avs_fill_buffer(demuxer_t *d);#endifint demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){ // Note: parameter 'ds' can be NULL!// printf("demux->type=%d\n",demux->type); switch(demux->type){ case DEMUXER_TYPE_MF: return demux_mf_fill_buffer(demux); case DEMUXER_TYPE_ROQ: return demux_roq_fill_buffer(demux); case DEMUXER_TYPE_FILM: return demux_film_fill_buffer(demux); case DEMUXER_TYPE_FLI: return demux_fli_fill_buffer(demux);// case DEMUXER_TYPE_MPEG_TY: return demux_ty_fill_buffer( demux ); case DEMUXER_TYPE_MPEG4_ES: case DEMUXER_TYPE_H264_ES: case DEMUXER_TYPE_MPEG_ES: return demux_mpg_es_fill_buffer(demux); case DEMUXER_TYPE_MPEG_PS: return demux_mpg_fill_buffer(demux); case DEMUXER_TYPE_AVI: return demux_avi_fill_buffer(demux); case DEMUXER_TYPE_AVI_NI: return demux_avi_fill_buffer_ni(demux,ds); case DEMUXER_TYPE_AVI_NINI: return demux_avi_fill_buffer_nini(demux,ds); case DEMUXER_TYPE_ASF: return demux_asf_fill_buffer(demux);// case DEMUXER_TYPE_MOV: return demux_mov_fill_buffer(demux,ds); case DEMUXER_TYPE_VIVO: return demux_vivo_fill_buffer(demux); case DEMUXER_TYPE_PVA: return demux_pva_fill_buffer(demux);#ifdef HAVE_LIBDV095 case DEMUXER_TYPE_RAWDV: return demux_rawdv_fill_buffer(demux);#endif case DEMUXER_TYPE_REAL: return demux_real_fill_buffer(demux); case DEMUXER_TYPE_NSV: return demux_nsv_fill_buffer(demux); case DEMUXER_TYPE_NUV: return demux_nuv_fill_buffer(demux);#ifdef USE_TV case DEMUXER_TYPE_TV: return demux_tv_fill_buffer(demux, ds);#endif case DEMUXER_TYPE_Y4M: return demux_y4m_fill_buffer(demux); case DEMUXER_TYPE_AUDIO: return demux_audio_fill_buffer(ds);#ifdef HAVE_XMMS case DEMUXER_TYPE_XMMS: return demux_xmms_fill_buffer(demux,ds);#endif case DEMUXER_TYPE_DEMUXERS: return demux_demuxers_fill_buffer(demux,ds);#ifdef HAVE_OGGVORBIS case DEMUXER_TYPE_OGG: return demux_ogg_fill_buffer(demux);#endif#ifdef HAVE_MATROSKA case DEMUXER_TYPE_MATROSKA: return demux_mkv_fill_buffer(demux);#endif case DEMUXER_TYPE_RAWAUDIO: return demux_rawaudio_fill_buffer(demux,ds); case DEMUXER_TYPE_RAWVIDEO: return demux_rawvideo_fill_buffer(demux,ds);#ifdef STREAMING_LIVE_DOT_COM case DEMUXER_TYPE_RTP: return demux_rtp_fill_buffer(demux, ds);#endif case DEMUXER_TYPE_SMJPEG: return demux_smjpeg_fill_buffer(demux);#ifdef HAVE_GIF case DEMUXER_TYPE_GIF: return demux_gif_fill_buffer(demux);#endif case DEMUXER_TYPE_LMLM4: return demux_lmlm4_fill_buffer(demux); case DEMUXER_TYPE_MPEG_TS: return demux_ts_fill_buffer(demux); case DEMUXER_TYPE_REALAUDIO: return demux_ra_fill_buffer(demux);// case DEMUXER_TYPE_VQF: return demux_vqf_fill_buffer(demux);#ifdef USE_LIBAVFORMAT case DEMUXER_TYPE_LAVF: return demux_lavf_fill_buffer(demux);#endif#ifdef USE_WIN32DLL case DEMUXER_TYPE_AVS: return demux_avs_fill_buffer(demux);#endif } return 0;}// return value:// 0 = EOF// 1 = succesfullint ds_fill_buffer(demux_stream_t *ds){ demuxer_t *demux=ds->demuxer; if(ds->current) free_demux_packet(ds->current); if(verbose>2){ if(ds==demux->audio) mp_dbg(MSGT_DEMUXER,MSGL_DBG3,"ds_fill_buffer(d_audio) called\n");else if(ds==demux->video) mp_dbg(MSGT_DEMUXER,MSGL_DBG3,"ds_fill_buffer(d_video) called\n");else if(ds==demux->sub) mp_dbg(MSGT_DEMUXER,MSGL_DBG3,"ds_fill_buffer(d_sub) called\n");else mp_dbg(MSGT_DEMUXER,MSGL_DBG3,"ds_fill_buffer(unknown 0x%X) called\n",(unsigned int)ds); } while(1){ if(ds->packs){ demux_packet_t *p=ds->first; // copy useful data: ds->buffer=p->buffer; ds->buffer_pos=0; ds->buffer_size=p->len; ds->pos=p->pos; ds->dpos+=p->len; // !!! ++ds->pack_no; if(p->pts){ ds->pts=p->pts; ds->pts_bytes=0; } ds->pts_bytes+=p->len; // !!! ds->flags=p->flags; // unlink packet: ds->bytes-=p->len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -