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; }
int main(int argc,char ** argv){ int c; FILE *f; FILE *f2; muxer_t* avi; muxer_stream_t* mux; //unsigned char* buffer=malloc(0x200000); int i,len; int v_id=0; int flag2=0; int prefix=0; // check if enough args were given if ( argc < 3 ){ printf("Too few arguments given!\n" "Usage: %s <input_file> <output_file>\n", argv[0]); return -1; } // input if(!(f=fopen(argv[1],"rb"))){ printf("Couldn't open input file.\n"); return -1; } // output if(!(f2=fopen(argv[2],"wb"))){ printf("Couldn't open output file.\n"); return -1; } avi=muxer_new_muxer(MUXER_TYPE_AVI,f2); mux=muxer_new_stream(avi,MUXER_TYPE_VIDEO); mux->buffer_size=0x200000; mux->buffer=malloc(mux->buffer_size); mux->h.dwScale=1; mux->h.dwRate=10; mux->bih=malloc(sizeof(*mux->bih)); mux->bih->biSize=sizeof(*mux->bih); mux->bih->biPlanes=1; mux->bih->biBitCount=24; mux->bih->biCompression=0x6f766976;// 7669766f; muxer_write_header(avi); /* c=fgetc(f); if(c) printf("error! not vivo file?\n"); len=0; while((c=fgetc(f))>=0x80) len+=0x80*(c&0x0F); len+=c; printf("hdr1: %d\n",len); for(i=0;i<len;i++) fgetc(f); */ while((c=fgetc(f))>=0){ printf("%08lX %02X\n",ftell(f),c); prefix=0; if(c==0x82){ prefix=1; //continue; c=fgetc(f); printf("%08lX %02X\n",ftell(f),c); } if(c==0x00){ // header int len=0; while((c=fgetc(f))>=0x80) len+=0x80*(c&0x0F); len+=c; printf("header: 00 (%d)\n",len); for(i=0;i<len;i++) fgetc(f); continue; } if((c&0xF0)==0x40){ // audio len=24; if(prefix) len=fgetc(f); printf("audio: %02X (%d)\n",c,len); for(i=0;i<len;i++) fgetc(f); continue; } if((c&0xF0)==0x30){ // audio len=40; if(prefix) len=fgetc(f); printf("audio: %02X (%d)\n",c,len); for(i=0;i<len;i++) fgetc(f); continue; } if(flag2 || (((c&0xF0)==0x10 || (c&0xF0)==0x20) && (c&0x0F)!=(v_id&0xF))){ // end of frame: printf("Frame size: %d\n",mux->buffer_len); h263_decode_picture_header(mux->buffer); muxer_write_chunk(mux,mux->buffer_len,0x10, MP_NOPTS_VALUE, MP_NOPTS_VALUE); mux->buffer_len=0; if((v_id&0xF0)==0x10) fprintf(stderr,"hmm. last video packet %02X\n",v_id); } flag2=0; if((c&0xF0)==0x10){ // 128 byte len=128; if(prefix) len=fgetc(f); printf("video: %02X (%d)\n",c,len); fread(mux->buffer+mux->buffer_len,len,1,f); mux->buffer_len+=len; v_id=c; continue; } if((c&0xF0)==0x20){ int len=fgetc(f); printf("video: %02X (%d)\n",c,len); fread(mux->buffer+mux->buffer_len,len,1,f); mux->buffer_len+=len; flag2=1; v_id=c; continue; } printf("error: %02X!\n",c); exit(1); } if(!width) width=320; if(!height) height=240; mux->bih->biWidth=width; mux->bih->biHeight=height; mux->bih->biSizeImage=3*width*height; muxer_write_index(avi); fseek(f2,0,SEEK_SET); muxer_write_header(avi); return 0; }