From 137c0d6cc8234c7939e5ad836f53b87efdc5d671 Mon Sep 17 00:00:00 2001 From: arpi Date: Sun, 31 Mar 2002 20:08:19 +0000 Subject: vorbis driver ported, and also fixed a bug, as nominal_bitrate can be -1 git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@5428 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpcodecs/Makefile | 2 +- libmpcodecs/ad_vorbis.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 libmpcodecs/ad_vorbis.c (limited to 'libmpcodecs') diff --git a/libmpcodecs/Makefile b/libmpcodecs/Makefile index c774513e93..682556b6bd 100644 --- a/libmpcodecs/Makefile +++ b/libmpcodecs/Makefile @@ -3,7 +3,7 @@ include ../config.mak LIBNAME = libmpcodecs.a -AUDIO_SRCS=dec_audio.c ad.c ad_a52.c ad_acm.c ad_alaw.c ad_dk3adpcm.c ad_dshow.c ad_dvdpcm.c ad_ffmpeg.c ad_hwac3.c ad_imaadpcm.c ad_mp3.c ad_msadpcm.c ad_pcm.c ad_roqaudio.c ad_msgsm.c ad_faad.c +AUDIO_SRCS=dec_audio.c ad.c ad_a52.c ad_acm.c ad_alaw.c ad_dk3adpcm.c ad_dshow.c ad_dvdpcm.c ad_ffmpeg.c ad_hwac3.c ad_imaadpcm.c ad_mp3.c ad_msadpcm.c ad_pcm.c ad_roqaudio.c ad_msgsm.c ad_faad.c ad_vorbis.c VIDEO_SRCS=dec_video.c vd.c vd_null.c vd_cinepak.c vd_qtrpza.c vd_ffmpeg.c vd_dshow.c vd_vfw.c vd_odivx.c vd_divx4.c vd_raw.c vd_xanim.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_nuv.c vd_libmpeg2.c vd_msrle.c vd_huffyuv.c vd_zlib.c ifeq ($(PNG),yes) diff --git a/libmpcodecs/ad_vorbis.c b/libmpcodecs/ad_vorbis.c new file mode 100644 index 0000000000..b792f9d149 --- /dev/null +++ b/libmpcodecs/ad_vorbis.c @@ -0,0 +1,184 @@ + +#include +#include +#include + +#include "config.h" +#include "ad_internal.h" + +#ifdef HAVE_OGGVORBIS + +static ad_info_t info = +{ + "Ogg/Vorbis audio decoder", + "libvorbis", + AFM_VORBIS, + "Felix Buenemann, A'rpi", + "libvorbis", + "buggy" +}; + +LIBAD_EXTERN(vorbis) + +#include +#include + +// This struct is also defined in demux_ogg.c => common header ? +typedef struct ov_struct_st { + vorbis_info vi; /* struct that stores all the static vorbis bitstream + settings */ + vorbis_comment vc; /* struct that stores all the bitstream user comments */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ +} ov_struct_t; + +static int preinit(sh_audio_t *sh) +{ + sh->audio_out_minsize=1024*4; // 1024 samples/frame + return 1; +} + +static int init(sh_audio_t *sh) +{ + ogg_packet op; + vorbis_comment vc; + struct ov_struct_st *ov; + + /// Init the decoder with the 3 header packets + ov = (struct ov_struct_st*)malloc(sizeof(struct ov_struct_st)); + vorbis_info_init(&ov->vi); + vorbis_comment_init(&vc); + op.bytes = ds_get_packet(sh->ds,&op.packet); + op.b_o_s = 1; + /// Header + if(vorbis_synthesis_headerin(&ov->vi,&vc,&op) <0) { + mp_msg(MSGT_DECAUDIO,MSGL_ERR,"OggVorbis: initial (identification) header broken!\n"); + free(ov); + return 0; + } + op.bytes = ds_get_packet(sh->ds,&op.packet); + op.b_o_s = 0; + /// Comments + if(vorbis_synthesis_headerin(&ov->vi,&vc,&op) <0) { + mp_msg(MSGT_DECAUDIO,MSGL_ERR,"OggVorbis: comment header broken!\n"); + free(ov); + return 0; + } + op.bytes = ds_get_packet(sh->ds,&op.packet); + //// Codebook + if(vorbis_synthesis_headerin(&ov->vi,&vc,&op)<0) { + mp_msg(MSGT_DECAUDIO,MSGL_WARN,"OggVorbis: codebook header broken!\n"); + free(ov); + return 0; + } else { /// Print the infos + char **ptr=vc.user_comments; + while(*ptr){ + mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbisComment: %s\n",*ptr); + ++ptr; + } + mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Bitstream is %d channel, %dHz, %dbit/s %cBR\n",(int)ov->vi.channels,(int)ov->vi.rate,(int)ov->vi.bitrate_nominal, + (ov->vi.bitrate_lower!=ov->vi.bitrate_nominal)||(ov->vi.bitrate_upper!=ov->vi.bitrate_nominal)?'V':'C'); + mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Encoded by: %s\n",vc.vendor); + } + +// printf("lower=%d upper=%d \n",(int)ov->vi.bitrate_lower,(int)ov->vi.bitrate_upper); + + // Setup the decoder + sh->channels=ov->vi.channels; + sh->samplerate=ov->vi.rate; + // assume 128kbit if bitrate not specified in the header + sh->i_bps=((ov->vi.bitrate_nominal>0) ? ov->vi.bitrate_nominal : 128000)/8; + sh->context = ov; + + /// Finish the decoder init + vorbis_synthesis_init(&ov->vd,&ov->vi); + vorbis_block_init(&ov->vd,&ov->vb); + mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Init OK!\n"); + + return 1; +} + +static void uninit(sh_audio_t *sh) +{ +} + +static int control(sh_audio_t *sh,int cmd,void* arg, ...) +{ + switch(cmd) + { +#if 0 + case ADCTRL_RESYNC_STREAM: + return CONTROL_TRUE; + case ADCTRL_SKIP_FRAME: + return CONTROL_TRUE; +#endif + } + return CONTROL_UNKNOWN; +} + +static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen) +{ + int len = 0; + int samples; + float **pcm; + ogg_packet op; + char* np; + struct ov_struct_st *ov = sh->context; + op.b_o_s = op.e_o_s = 0; + while(len < minlen) { + op.bytes = ds_get_packet(sh->ds,&op.packet); + if(!op.packet) + break; + if(vorbis_synthesis(&ov->vb,&op)==0) /* test for success! */ + vorbis_synthesis_blockin(&ov->vd,&ov->vb); + while((samples=vorbis_synthesis_pcmout(&ov->vd,&pcm))>0){ + int i,j; + int clipflag=0; + int convsize=(maxlen-len)/(2*ov->vi.channels); // max size! + int bout=(samplesvi.channels;i++){ + ogg_int16_t *convbuffer=(ogg_int16_t *)(&buf[len]); + ogg_int16_t *ptr=convbuffer+i; + float *mono=pcm[i]; + for(j=0;j32767){ + val=32767; + clipflag=1; + } + if(val<-32768){ + val=-32768; + clipflag=1; + } + *ptr=val; + ptr+=ov->vi.channels; + } + } + + if(clipflag) + mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"Clipping in frame %ld\n",(long)(ov->vd.sequence)); + len+=2*ov->vi.channels*bout; + mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"\n[decoded: %d / %d ]\n",bout,samples); + vorbis_synthesis_read(&ov->vd,bout); /* tell libvorbis how + many samples we + actually consumed */ + } + } + + + + return len; +} + +#endif /* !HAVE_OGGVORBIS */ + -- cgit v1.2.3