static demuxer_t* demux_open_vivo(demuxer_t* demuxer){ vivo_priv_t* priv=demuxer->priv; if(!ds_fill_buffer(demuxer->video)){ mp_msg(MSGT_DEMUX,MSGL_ERR,"VIVO: " MSGTR_MissingVideoStreamBug); return NULL; } audio_pos=0; h263_decode_picture_header(demuxer->video->buffer); if (vivo_param_version != -1) priv->version = '0' + vivo_param_version; { sh_video_t* sh=new_sh_video(demuxer,0); /* viv1, viv2 (for better codecs.conf) */ sh->format = mmioFOURCC('v', 'i', 'v', priv->version); if(!sh->fps) { if (priv->fps) sh->fps=priv->fps; else sh->fps=15.0f; } sh->frametime=1.0f/sh->fps; /* XXX: FIXME: can't scale image. */ /* hotfix to disable: */ priv->disp_width = priv->width; priv->disp_height = priv->height; if (vivo_param_width != -1) priv->disp_width = priv->width = vivo_param_width; if (vivo_param_height != -1) priv->disp_height = priv->height = vivo_param_height; if (vivo_param_vformat != -1) { priv->disp_width = priv->width = h263_format[vivo_param_vformat][0]; priv->disp_height = priv->height = h263_format[vivo_param_vformat][1]; } if (priv->disp_width) sh->disp_w = priv->disp_width; else sh->disp_w = width; if (priv->disp_height) sh->disp_h = priv->disp_height; else sh->disp_h = height; // emulate BITMAPINFOHEADER: sh->bih=malloc(sizeof(BITMAPINFOHEADER)); memset(sh->bih,0,sizeof(BITMAPINFOHEADER)); sh->bih->biSize=40; if (priv->width) sh->bih->biWidth = priv->width; else sh->bih->biWidth = width; if (priv->height) sh->bih->biHeight = priv->height; else sh->bih->biHeight = height; sh->bih->biPlanes=1; sh->bih->biBitCount=24; sh->bih->biCompression=sh->format; sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight*3; /* insert as stream */ demuxer->video->sh=sh; sh->ds=demuxer->video; demuxer->video->id=0; /* disable seeking */ demuxer->seekable = 0; mp_msg(MSGT_DEMUX,MSGL_V,"VIVO Video stream %d size: display: %dx%d, codec: %ux%u\n", demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth, sh->bih->biHeight); } /* AUDIO init */ if (demuxer->audio->id >= -1){ if(!ds_fill_buffer(demuxer->audio)){ mp_msg(MSGT_DEMUX,MSGL_ERR,"VIVO: " MSGTR_MissingAudioStream); } else { sh_audio_t* sh=new_sh_audio(demuxer,1); /* Select audio codec */ if (priv->audio_codec == 0) { if (priv->version == '2') priv->audio_codec = VIVO_AUDIO_SIREN; else priv->audio_codec = VIVO_AUDIO_G723; } if (vivo_param_acodec != NULL) { if (!strcasecmp(vivo_param_acodec, "g723")) priv->audio_codec = VIVO_AUDIO_G723; if (!strcasecmp(vivo_param_acodec, "siren")) priv->audio_codec = VIVO_AUDIO_SIREN; } if (priv->audio_codec == VIVO_AUDIO_G723) sh->format = 0x111; else if (priv->audio_codec == VIVO_AUDIO_SIREN) sh->format = 0x112; else { mp_msg(MSGT_DEMUX, MSGL_ERR, "VIVO: Not support audio codec (%d)\n", priv->audio_codec); free_sh_audio(demuxer, 1); goto nosound; } // Emulate WAVEFORMATEX struct: sh->wf=malloc(sizeof(WAVEFORMATEX)); memset(sh->wf,0,sizeof(WAVEFORMATEX)); sh->wf->wFormatTag=sh->format; sh->wf->nChannels=1; /* 1 channels for both Siren and G.723 */ /* Set bits per sample */ if (priv->audio_codec == VIVO_AUDIO_SIREN) sh->wf->wBitsPerSample = 16; else if (priv->audio_codec == VIVO_AUDIO_G723) sh->wf->wBitsPerSample = 8; /* Set sampling rate */ if (priv->audio_samplerate) /* got from header */ sh->wf->nSamplesPerSec = priv->audio_samplerate; else { if (priv->audio_codec == VIVO_AUDIO_SIREN) sh->wf->nSamplesPerSec = 16000; if (priv->audio_codec == VIVO_AUDIO_G723) sh->wf->nSamplesPerSec = 8000; } if (vivo_param_samplerate != -1) sh->wf->nSamplesPerSec = vivo_param_samplerate; /* Set audio bitrate */ if (priv->audio_bitrate) /* got from header */ sh->wf->nAvgBytesPerSec = priv->audio_bitrate; else { if (priv->audio_codec == VIVO_AUDIO_SIREN) sh->wf->nAvgBytesPerSec = 2000; if (priv->audio_codec == VIVO_AUDIO_G723) sh->wf->nAvgBytesPerSec = 800; } if (vivo_param_abitrate != -1) sh->wf->nAvgBytesPerSec = vivo_param_abitrate; audio_rate=sh->wf->nAvgBytesPerSec; if (!priv->audio_bytesperblock) { if (priv->audio_codec == VIVO_AUDIO_SIREN) sh->wf->nBlockAlign = 40; if (priv->audio_codec == VIVO_AUDIO_G723) sh->wf->nBlockAlign = 24; } else sh->wf->nBlockAlign = priv->audio_bytesperblock; if (vivo_param_bytesperblock != -1) sh->wf->nBlockAlign = vivo_param_bytesperblock; /*sound_ok:*/ /* insert as stream */ demuxer->audio->sh=sh; sh->ds=demuxer->audio; demuxer->audio->id=1; nosound: return demuxer; } } return demuxer; }
static demuxer_t* demux_open_avi(demuxer_t* demuxer){ demux_stream_t *d_audio=demuxer->audio; demux_stream_t *d_video=demuxer->video; sh_audio_t *sh_audio=NULL; sh_video_t *sh_video=NULL; avi_priv_t* priv=calloc(1, sizeof(avi_priv_t)); demuxer->priv=(void*)priv; //---- AVI header: read_avi_header(demuxer,(demuxer->stream->flags & MP_STREAM_SEEK_BW)?index_mode:-2); if(demuxer->audio->id>=0 && !demuxer->a_streams[demuxer->audio->id]){ mp_tmsg(MSGT_DEMUX,MSGL_WARN,"AVI: invalid audio stream ID: %d - ignoring (nosound)\n",demuxer->audio->id); demuxer->audio->id=-2; // disabled } if(demuxer->video->id>=0 && !demuxer->v_streams[demuxer->video->id]){ mp_tmsg(MSGT_DEMUX,MSGL_WARN,"AVI: invalid video stream ID: %d - ignoring (using default)\n",demuxer->video->id); demuxer->video->id=-1; // autodetect } stream_reset(demuxer->stream); stream_seek(demuxer->stream,demuxer->movi_start); if(priv->idx_size>1){ // decide index format: #if 1 if((AVI_IDX_OFFSET(&((AVIINDEXENTRY *)priv->idx)[0])<demuxer->movi_start || AVI_IDX_OFFSET(&((AVIINDEXENTRY *)priv->idx)[1])<demuxer->movi_start )&& !priv->isodml) priv->idx_offset=demuxer->movi_start-4; #else if(AVI_IDX_OFFSET(&((AVIINDEXENTRY *)priv->idx)[0])<demuxer->movi_start) priv->idx_offset=demuxer->movi_start-4; #endif mp_msg(MSGT_DEMUX,MSGL_V,"AVI index offset: 0x%X (movi=0x%X idx0=0x%X idx1=0x%X)\n", (int)priv->idx_offset,(int)demuxer->movi_start, (int)((AVIINDEXENTRY *)priv->idx)[0].dwChunkOffset, (int)((AVIINDEXENTRY *)priv->idx)[1].dwChunkOffset); } if(priv->idx_size>0){ // check that file is non-interleaved: int i; off_t a_pos=-1; off_t v_pos=-1; for(i=0;i<priv->idx_size;i++){ AVIINDEXENTRY* idx=&((AVIINDEXENTRY *)priv->idx)[i]; demux_stream_t* ds=demux_avi_select_stream(demuxer,idx->ckid); off_t pos = priv->idx_offset + AVI_IDX_OFFSET(idx); if(a_pos==-1 && ds==demuxer->audio){ a_pos=pos; if(v_pos!=-1) break; } if(v_pos==-1 && ds==demuxer->video){ v_pos=pos; if(a_pos!=-1) break; } } if(v_pos==-1){ mp_msg(MSGT_DEMUX, MSGL_ERR, "AVI_NI: %s", mp_gtext("No video stream found.\n")); return NULL; } if(a_pos==-1){ d_audio->sh=sh_audio=NULL; } else { if(force_ni || abs(a_pos-v_pos)>0x100000){ // distance > 1MB mp_tmsg(MSGT_DEMUX,MSGL_INFO,"%s NON-INTERLEAVED AVI file format.\n",force_ni?"Forced":"Detected"); demuxer->type=DEMUXER_TYPE_AVI_NI; // HACK!!!! demuxer->desc=&demuxer_desc_avi_ni; // HACK!!!! pts_from_bps=1; // force BPS sync! } } } else { // no index if(force_ni){ mp_tmsg(MSGT_DEMUX,MSGL_INFO,"Using NON-INTERLEAVED broken AVI file format.\n"); demuxer->type=DEMUXER_TYPE_AVI_NINI; // HACK!!!! demuxer->desc=&demuxer_desc_avi_nini; // HACK!!!! priv->idx_pos_a= priv->idx_pos_v=demuxer->movi_start; pts_from_bps=1; // force BPS sync! } demuxer->seekable=0; } if(!ds_fill_buffer(d_video)){ mp_msg(MSGT_DEMUX, MSGL_ERR, "AVI: %s", mp_gtext("Missing video stream!? Contact the author, " "it may be a bug :(\n")); return NULL; } sh_video=d_video->sh;sh_video->ds=d_video; if(d_audio->id!=-2){ mp_msg(MSGT_DEMUX,MSGL_V,"AVI: Searching for audio stream (id:%d)\n",d_audio->id); if(!priv->audio_streams || !ds_fill_buffer(d_audio)){ mp_msg(MSGT_DEMUX, MSGL_INFO, "AVI: %s", mp_gtext("No audio stream found -> no sound.\n")); d_audio->sh=sh_audio=NULL; } else { sh_audio=d_audio->sh;sh_audio->ds=d_audio; } } // calculating audio/video bitrate: if(priv->idx_size>0){ // we have index, let's count 'em! AVIINDEXENTRY *idx = priv->idx; int64_t vsize=0; int64_t asize=0; size_t vsamples=0; size_t asamples=0; int i; for(i=0;i<priv->idx_size;i++){ int id=avi_stream_id(idx[i].ckid); unsigned len=idx[i].dwChunkLength; if(sh_video->ds->id == id) { vsize+=len; ++vsamples; } else if(sh_audio && sh_audio->ds->id == id) { asize+=len; asamples+=(len+priv->audio_block_size-1)/priv->audio_block_size; } } mp_msg(MSGT_DEMUX,MSGL_V,"AVI video size=%"PRId64" (%u) audio size=%"PRId64" (%u)\n",vsize,vsamples,asize,asamples); priv->numberofframes=vsamples; sh_video->i_bps=((float)vsize/(float)vsamples)*(float)sh_video->video.dwRate/(float)sh_video->video.dwScale; if(sh_audio) sh_audio->i_bps=((float)asize/(float)asamples)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; } else { // guessing, results may be inaccurate: int64_t vsize; int64_t asize=0; if((priv->numberofframes=sh_video->video.dwLength)<=1) // bad video header, try to get number of frames from audio if(sh_audio && sh_audio->wf->nAvgBytesPerSec) priv->numberofframes=sh_video->fps*sh_audio->audio.dwLength/sh_audio->audio.dwRate*sh_audio->audio.dwScale; if(priv->numberofframes<=1){ mp_tmsg(MSGT_SEEK,MSGL_WARN,"Could not determine number of frames (for absolute seek).\n"); priv->numberofframes=0; } if(sh_audio){ if(sh_audio->wf->nAvgBytesPerSec && sh_audio->audio.dwSampleSize!=1){ asize=(float)sh_audio->wf->nAvgBytesPerSec*sh_audio->audio.dwLength*sh_audio->audio.dwScale/sh_audio->audio.dwRate; } else { asize=sh_audio->audio.dwLength; sh_audio->i_bps=(float)asize/(sh_video->frametime*priv->numberofframes); } } vsize=demuxer->movi_end-demuxer->movi_start-asize-8*priv->numberofframes; mp_msg(MSGT_DEMUX,MSGL_V,"AVI video size=%"PRId64" (%u) audio size=%"PRId64"\n",vsize,priv->numberofframes,asize); sh_video->i_bps=(float)vsize/(sh_video->frametime*priv->numberofframes); } return demuxer; }
static demuxer_t* demux_open_lmlm4(demuxer_t* demuxer){ sh_audio_t *sh_audio=NULL; sh_video_t *sh_video=NULL; #if 0 sh_video_t* sh_video; sh_audio_t* sh_audio; unsigned int htype = 0, hleng; int i = 0; sh_video = new_sh_video(demuxer, 0); demuxer->video->sh = sh_video; sh_video->ds = demuxer->video; sh_video->disp_w = 640; sh_video->disp_h = 480; sh_video->format = mmioFOURCC('D','I','V','X'); sh_video->bih = malloc(sizeof(BITMAPINFOHEADER)); memset(sh_video->bih, 0, sizeof(BITMAPINFOHEADER)); /* these are false values */ sh_video->bih->biSize = 40; sh_video->bih->biWidth = sh_video->disp_w; sh_video->bih->biHeight = sh_video->disp_h; sh_video->bih->biPlanes = 3; sh_video->bih->biBitCount = 16; sh_video->bih->biCompression = sh_video->format; sh_video->bih->biSizeImage = sh_video->disp_w*sh_video->disp_h; sh_audio = new_sh_audio(demuxer, 0); demuxer->audio->sh = sh_audio; sh_audio->ds = demuxer->audio; sh_audio->wf = malloc(sizeof(WAVEFORMATEX)); memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX)); sh_audio->samplerate = 48000; sh_audio->wf->wBitsPerSample = 16; sh_audio->channels = 2; sh_audio->format = 0x50; sh_audio->wf->wFormatTag = sh_audio->format; sh_audio->wf->nChannels = sh_audio->channels; sh_audio->wf->nSamplesPerSec = sh_audio->samplerate; sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels* sh_audio->wf->wBitsPerSample*sh_audio->wf->nSamplesPerSec/8; sh_audio->wf->nBlockAlign = sh_audio->channels *2; sh_audio->wf->cbSize = 0; #endif demuxer->seekable = 0; if(!ds_fill_buffer(demuxer->video)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,"LMLM4: " MSGTR_MissingVideoStream); demuxer->video->sh=NULL; } else { sh_video=demuxer->video->sh;sh_video->ds=demuxer->video; } if(demuxer->audio->id!=-2) { if(!ds_fill_buffer(demuxer->audio)){ mp_msg(MSGT_DEMUXER,MSGL_INFO,"LMLM4: " MSGTR_MissingAudioStream); demuxer->audio->sh=NULL; } else { sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio; } } return demuxer; }