+static void CloseDecoder( vlc_object_t *p_this )
+{
+ decoder_t *p_dec = (decoder_t *)p_this;
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+ if( !p_sys->b_packetizer && p_sys->i_headers >= 3 )
+ {
+ vorbis_block_clear( &p_sys->vb );
+ vorbis_dsp_clear( &p_sys->vd );
+ }
+
+ vorbis_comment_clear( &p_sys->vc );
+ vorbis_info_clear( &p_sys->vi ); /* must be called last */
+
+ free( p_sys );
+}
+
+#if defined(HAVE_VORBIS_VORBISENC_H) && !defined(MODULE_NAME_IS_tremor)
+
+/*****************************************************************************
+ * encoder_sys_t : theora encoder descriptor
+ *****************************************************************************/
+struct encoder_sys_t
+{
+ /*
+ * Input properties
+ */
+ int i_headers;
+
+ /*
+ * Vorbis properties
+ */
+ 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 */
+
+ int i_last_block_size;
+ int i_samples_delay;
+ int i_channels;
+
+ /*
+ * Common properties
+ */
+ mtime_t i_pts;
+};
+
+/*****************************************************************************
+ * OpenEncoder: probe the encoder and return score
+ *****************************************************************************/
+static int OpenEncoder( vlc_object_t *p_this )
+{
+ encoder_t *p_enc = (encoder_t *)p_this;
+ encoder_sys_t *p_sys;
+
+ if( p_enc->fmt_out.i_codec != VLC_FOURCC('v','o','r','b') )
+ {
+ return VLC_EGENERIC;
+ }
+
+ /* Allocate the memory needed to store the decoder's structure */
+ if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
+ {
+ msg_Err( p_enc, "out of memory" );
+ return VLC_EGENERIC;
+ }
+ p_enc->p_sys = p_sys;
+
+ p_enc->pf_header = Headers;
+ p_enc->pf_encode_audio = Encode;
+ p_enc->fmt_in.i_codec = VLC_FOURCC('f','l','3','2');
+
+ /* Initialize vorbis encoder */
+ vorbis_info_init( &p_sys->vi );
+
+ if( vorbis_encode_setup_managed( &p_sys->vi,
+ p_enc->fmt_in.audio.i_channels, p_enc->fmt_in.audio.i_rate,
+ -1, p_enc->fmt_out.i_bitrate, -1 ) ||
+ vorbis_encode_ctl( &p_sys->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) ||
+ vorbis_encode_setup_init( &p_sys->vi ) ){}
+
+ /* add a comment */
+ vorbis_comment_init( &p_sys->vc);
+ vorbis_comment_add_tag( &p_sys->vc, "ENCODER", "VLC media player");
+
+ /* set up the analysis state and auxiliary encoding storage */
+ vorbis_analysis_init( &p_sys->vd, &p_sys->vi );
+ vorbis_block_init( &p_sys->vd, &p_sys->vb );
+
+ p_sys->i_channels = p_enc->fmt_in.audio.i_channels;
+ p_sys->i_last_block_size = 0;
+ p_sys->i_samples_delay = 0;
+ p_sys->i_headers = 0;
+ p_sys->i_pts = 0;
+
+ return VLC_SUCCESS;
+}
+
+/****************************************************************************
+ * Encode: the whole thing
+ ****************************************************************************
+ * This function spits out ogg packets.
+ ****************************************************************************/
+static block_t *Headers( encoder_t *p_enc )