demuxer.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,287 行 · 第 1/3 页
C
1,287 行
//=================== DEMUXER v2.5 =========================#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include "m_config.h"#include "libvo/fastmemcpy.h"#include "stream/stream.h"#include "demuxer.h"#include "stheader.h"#include "mf.h"#include "libaf/af_format.h"extern void resync_video_stream(sh_video_t *sh_video);extern void resync_audio_stream(sh_audio_t *sh_audio);// Demuxer listextern demuxer_desc_t demuxer_desc_rawaudio;extern demuxer_desc_t demuxer_desc_rawvideo;extern demuxer_desc_t demuxer_desc_tv;extern demuxer_desc_t demuxer_desc_mf;extern demuxer_desc_t demuxer_desc_avi;extern demuxer_desc_t demuxer_desc_y4m;extern demuxer_desc_t demuxer_desc_asf;extern demuxer_desc_t demuxer_desc_nuv;extern demuxer_desc_t demuxer_desc_real;extern demuxer_desc_t demuxer_desc_smjpeg;extern demuxer_desc_t demuxer_desc_matroska;extern demuxer_desc_t demuxer_desc_realaudio;extern demuxer_desc_t demuxer_desc_vqf;extern demuxer_desc_t demuxer_desc_mov;extern demuxer_desc_t demuxer_desc_vivo;extern demuxer_desc_t demuxer_desc_fli;extern demuxer_desc_t demuxer_desc_film;extern demuxer_desc_t demuxer_desc_roq;extern demuxer_desc_t demuxer_desc_gif;extern demuxer_desc_t demuxer_desc_ogg;extern demuxer_desc_t demuxer_desc_avs;extern demuxer_desc_t demuxer_desc_pva;extern demuxer_desc_t demuxer_desc_nsv;extern demuxer_desc_t demuxer_desc_mpeg_ts;extern demuxer_desc_t demuxer_desc_lmlm4;extern demuxer_desc_t demuxer_desc_mpeg_ps;extern demuxer_desc_t demuxer_desc_mpeg_pes;extern demuxer_desc_t demuxer_desc_mpeg_es;extern demuxer_desc_t demuxer_desc_mpeg_gxf;extern demuxer_desc_t demuxer_desc_mpeg4_es;extern demuxer_desc_t demuxer_desc_h264_es;extern demuxer_desc_t demuxer_desc_rawdv;extern demuxer_desc_t demuxer_desc_mpc;extern demuxer_desc_t demuxer_desc_audio;extern demuxer_desc_t demuxer_desc_xmms;extern demuxer_desc_t demuxer_desc_mpeg_ty;extern demuxer_desc_t demuxer_desc_rtp;extern demuxer_desc_t demuxer_desc_lavf;extern demuxer_desc_t demuxer_desc_lavf_preferred;extern demuxer_desc_t demuxer_desc_aac;extern demuxer_desc_t demuxer_desc_nut;demuxer_desc_t* demuxer_list[] = { &demuxer_desc_rawaudio, &demuxer_desc_rawvideo,#ifdef USE_TV &demuxer_desc_tv,#endif &demuxer_desc_mf,#ifdef USE_LIBAVFORMAT &demuxer_desc_lavf_preferred,#endif &demuxer_desc_avi, &demuxer_desc_y4m, &demuxer_desc_asf, &demuxer_desc_nsv, &demuxer_desc_nuv, &demuxer_desc_real, &demuxer_desc_smjpeg, &demuxer_desc_matroska, &demuxer_desc_realaudio, &demuxer_desc_vqf, &demuxer_desc_mov, &demuxer_desc_vivo, &demuxer_desc_fli, &demuxer_desc_film, &demuxer_desc_roq,#ifdef HAVE_GIF &demuxer_desc_gif,#endif#ifdef HAVE_OGGVORBIS#ifdef USE_16M_SDRAM (void *)1,#else &demuxer_desc_ogg,#endif#endif#ifdef USE_WIN32DLL &demuxer_desc_avs,#endif &demuxer_desc_pva, &demuxer_desc_mpeg_ts, &demuxer_desc_lmlm4, &demuxer_desc_mpeg_ps, &demuxer_desc_mpeg_pes, &demuxer_desc_mpeg_es, &demuxer_desc_mpeg_gxf, &demuxer_desc_mpeg4_es, &demuxer_desc_h264_es,#ifdef MUSEPACK &demuxer_desc_mpc,#endif &demuxer_desc_audio, &demuxer_desc_mpeg_ty,#if defined(STREAMING_LIVE555) || defined(LIBNEMESI) &demuxer_desc_rtp,#endif#ifdef USE_LIBAVFORMAT &demuxer_desc_lavf,#endif#ifdef HAVE_LIBDV095 &demuxer_desc_rawdv,#endif &demuxer_desc_aac,#ifdef HAVE_LIBNUT &demuxer_desc_nut,#endif#ifdef HAVE_XMMS &demuxer_desc_xmms,#endif NULL};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;}/** * Get demuxer description structure for a given demuxer type * * @param file_format type of the demuxer * @return structure for the demuxer, NULL if not found */static demuxer_desc_t* get_demuxer_desc_from_type(int file_format){ int i; for (i = 0; demuxer_list[i]; i++) if (file_format == demuxer_list[i]->type) return demuxer_list[i]; return NULL;}demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename){ demuxer_t *d=malloc(sizeof(demuxer_t)); memset(d,0,sizeof(demuxer_t)); d->stream=stream; d->stream_pts = MP_NOPTS_VALUE; 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; if(type) if (!(d->desc = get_demuxer_desc_from_type(type))) mp_msg(MSGT_DEMUXER,MSGL_ERR,"BUG! Invalid demuxer type in new_demuxer(), big troubles ahead."); if(filename) // Filename hack for avs_check_file d->filename=strdup(filename); stream_reset(stream); stream_seek(stream,stream->start_pos); return d;}extern int dvdsub_id;sh_sub_t *new_sh_sub_sid(demuxer_t *demuxer, int id, int sid) { if (id > MAX_S_STREAMS - 1 || id < 0) { mp_msg(MSGT_DEMUXER,MSGL_WARN,"Requested sub stream id overflow (%d > %d)\n", id, MAX_S_STREAMS); return NULL; } if (demuxer->s_streams[id]) mp_msg(MSGT_DEMUXER, MSGL_WARN, "Sub stream %i redefined\n", id); else { sh_sub_t *sh = calloc(1, sizeof(sh_sub_t)); demuxer->s_streams[id] = sh; sh->sid = sid; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SUBTITLE_ID=%d\n", sid); if (dvdsub_id == id) { demuxer->sub->id = id; demuxer->sub->sh = sh; } } return demuxer->s_streams[id];}void free_sh_sub(sh_sub_t *sh) { mp_msg(MSGT_DEMUXER, MSGL_DBG2, "DEMUXER: freeing sh_sub at %p\n", sh); free(sh);}sh_audio_t* new_sh_audio_aid(demuxer_t *demuxer,int id,int aid){ 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]=calloc(1, 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*/ sh->pts=MP_NOPTS_VALUE; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_ID=%d\n", aid); } ((sh_audio_t *)demuxer->a_streams[id])->aid = aid; return demuxer->a_streams[id];}void free_sh_audio(demuxer_t *demuxer, int id) { sh_audio_t *sh = demuxer->a_streams[id]; demuxer->a_streams[id] = NULL; mp_msg(MSGT_DEMUXER,MSGL_DBG2,"DEMUXER: freeing sh_audio at %p\n",sh); if(sh->wf) free(sh->wf); if((sh->codecdatatype == 1)&&(sh->codecdata)) { free(sh->codecdata); sh->codecdata = NULL; } free(sh);}sh_video_t* new_sh_video_vid(demuxer_t *demuxer,int id,int vid){ 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]=calloc(1, sizeof(sh_video_t)); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ID=%d\n", vid); } ((sh_video_t *)demuxer->v_streams[id])->vid = vid; 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);}void free_demuxer(demuxer_t *demuxer){ int i; mp_msg(MSGT_DEMUXER,MSGL_DBG2,"DEMUXER: freeing demuxer at %p\n",demuxer); if(demuxer->desc->close) demuxer->desc->close(demuxer); // Very ugly hack to make it behave like old implementation if (demuxer->desc->type == DEMUXER_TYPE_DEMUXERS) goto skip_streamfree; // free streams: for(i = 0; i < MAX_A_STREAMS; i++) if(demuxer->a_streams[i]) free_sh_audio(demuxer, i); for(i = 0; i < MAX_V_STREAMS; i++) if(demuxer->v_streams[i]) free_sh_video(demuxer->v_streams[i]); for(i = 0; i < MAX_S_STREAMS; i++) if(demuxer->s_streams[i]) free_sh_sub(demuxer->s_streams[i]); // free demuxers: free_demuxer_stream(demuxer->audio); free_demuxer_stream(demuxer->video); free_demuxer_stream(demuxer->sub);skip_streamfree: if(demuxer->info) { for(i=0;demuxer->info[i] != NULL; i++) free(demuxer->info[i]); free(demuxer->info); } if(demuxer->filename) free(demuxer->filename); if (demuxer->chapters) { for (i=0; i<demuxer->num_chapters; i++) if (demuxer->chapters[i].name) free(demuxer->chapters[i].name); free(demuxer->chapters); } free(demuxer); deinit_parse_ex();}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, double 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_fill_buffer(demuxer_t *demux,demux_stream_t *ds){ // Note: parameter 'ds' can be NULL! //F("demux->type=%d\n",demux->type); return demux->desc->fill_buffer(demux, ds);}// 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( mp_msg_test(MSGT_DEMUXER,MSGL_DBG3) ){ 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 != (correct_pts ? MP_NOPTS_VALUE : 0)) { ds->pts=p->pts; ds->pts_bytes=0; } ds->pts_bytes+=p->len; // !!! if(p->stream_pts != MP_NOPTS_VALUE) demux->stream_pts=p->stream_pts; ds->flags=p->flags; // unlink packet: ds->bytes-=p->len; ds->current=p; ds->first=p->next; if(!ds->first) ds->last=NULL; --ds->packs; return 1; //ds->buffer_size; }#ifdef JZ47_OPT if(/*demux->audio->packs>=MAX_PACKS ||*/ demux->audio->bytes>=MAX_PACK_BYTES){#else if(demux->audio->packs>=MAX_PACKS || demux->audio->bytes>=MAX_PACK_BYTES){#endif mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_TooManyAudioInBuffer,demux->audio->packs,demux->audio->bytes); mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI); break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?