📄 demux_viv.c
字号:
seq=c&0x0F; if(ds->asf_packet){ if(ds->asf_seq!=seq){ // closed segment, finalize packet: ds_add_packet(ds,ds->asf_packet); ds->asf_packet=NULL;// printf("packet!\n"); } else { // append data to it! demux_packet_t* dp=ds->asf_packet; dp->buffer=realloc(dp->buffer,dp->len+len); //memcpy(dp->buffer+dp->len,data,len); stream_read(demux->stream,dp->buffer+dp->len,len); mp_dbg(MSGT_DEMUX,MSGL_DBG4,"data appended! %d+%d\n",dp->len,len); dp->len+=len; // we are ready now. if((c&0xF0)==0x20) --ds->asf_seq; // hack! return 1; } } // create new packet: { demux_packet_t* dp; dp=new_demux_packet(len); //memcpy(dp->buffer,data,len); stream_read(demux->stream,dp->buffer,len); dp->pts=audio_rate?((float)audio_pos/(float)audio_rate):0;// dp->flags=keyframe;// if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur); dp->pos=demux->filepos; ds->asf_packet=dp; ds->asf_seq=seq; // we are ready now. return 1; }}static const short h263_format[8][2] = { { 0, 0 }, { 128, 96 }, { 176, 144 }, { 352, 288 }, { 704, 576 }, { 1408, 1152 }, { 320, 240 } // ??????? or 240x180 (found in vivo2) ?};static unsigned char* buffer;static int bufptr=0;static int bitcnt=0;static unsigned char buf=0;static int format, width, height;static unsigned int x_get_bits(int n){ unsigned int x=0; while(n-->0){ if(!bitcnt){ // fill buff buf=buffer[bufptr++]; bitcnt=8; } //x=(x<<1)|(buf&1);buf>>=1; x=(x<<1)|(buf>>7);buf<<=1; --bitcnt; } return x;}#define get_bits(xxx,n) x_get_bits(n)#define get_bits1(xxx) x_get_bits(1)#define skip_bits(xxx,n) x_get_bits(n)#define skip_bits1(xxx) x_get_bits(1)/* most is hardcoded. should extend to handle all h263 streams */static int h263_decode_picture_header(unsigned char *b_ptr){// int i; // for(i=0;i<16;i++) printf(" %02X",b_ptr[i]); printf("\n"); buffer=b_ptr; bufptr=bitcnt=buf=0; /* picture header */ if (get_bits(&s->gb, 22) != 0x20){ printf("bad picture header\n"); return -1; } skip_bits(&s->gb, 8); /* picture timestamp */ if (get_bits1(&s->gb) != 1){ printf("bad marker\n"); return -1; /* marker */ } if (get_bits1(&s->gb) != 0){ printf("bad h263 id\n"); return -1; /* h263 id */ } skip_bits1(&s->gb); /* split screen off */ skip_bits1(&s->gb); /* camera off */ skip_bits1(&s->gb); /* freeze picture release off */ format = get_bits(&s->gb, 3); if (format != 7) { printf("h263_plus = 0 format = %d\n",format); /* H.263v1 */ width = h263_format[format][0]; height = h263_format[format][1]; printf("%d x %d\n",width,height);// if (!width) return -1; printf("pict_type=%d\n",get_bits1(&s->gb)); printf("unrestricted_mv=%d\n",get_bits1(&s->gb));#if 1 printf("SAC: %d\n",get_bits1(&s->gb)); printf("advanced prediction mode: %d\n",get_bits1(&s->gb)); printf("PB frame: %d\n",get_bits1(&s->gb));#else if (get_bits1(&s->gb) != 0) return -1; /* SAC: off */ if (get_bits1(&s->gb) != 0) return -1; /* advanced prediction mode: off */ if (get_bits1(&s->gb) != 0) return -1; /* not PB frame */#endif printf("qscale=%d\n",get_bits(&s->gb, 5)); skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ } else { printf("h263_plus = 1\n"); /* H.263v2 */ if (get_bits(&s->gb, 3) != 1){ printf("H.263v2 A error\n"); return -1; } if (get_bits(&s->gb, 3) != 6){ /* custom source format */ printf("custom source format\n"); return -1; } skip_bits(&s->gb, 12); skip_bits(&s->gb, 3); printf("pict_type=%d\n",get_bits(&s->gb, 3) + 1);// if (s->pict_type != I_TYPE &&// s->pict_type != P_TYPE)// return -1; skip_bits(&s->gb, 7); skip_bits(&s->gb, 4); /* aspect ratio */ width = (get_bits(&s->gb, 9) + 1) * 4; skip_bits1(&s->gb); height = get_bits(&s->gb, 9) * 4; printf("%d x %d\n",width,height); //if (height == 0) // return -1; printf("qscale=%d\n",get_bits(&s->gb, 5)); } /* PEI */ while (get_bits1(&s->gb) != 0) { skip_bits(&s->gb, 8); }// s->f_code = 1;// s->width = width;// s->height = height; return 0;}void 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; } 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; printf("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(sh); 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;}}}void demux_close_vivo(demuxer_t *demuxer){ vivo_priv_t* priv=demuxer->priv; if (priv) { if (priv->title) free(priv->title); if (priv->author) free(priv->author); if (priv->copyright) free(priv->copyright); if (priv->producer) free(priv->producer); free(priv); } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -