@ -30,6 +30,10 @@
# include "avformat.h"
# include "oggdec.h"
struct speex_params {
int final_packet_duration ;
} ;
static int speex_header ( AVFormatContext * s , int idx ) {
struct ogg * ogg = s - > priv_data ;
struct ogg_stream * os = ogg - > streams + idx ;
@ -69,8 +73,52 @@ static int speex_header(AVFormatContext *s, int idx) {
return 1 ;
}
static int ogg_page_packets ( struct ogg_stream * os )
{
int i ;
int packets = 0 ;
for ( i = 0 ; i < os - > nsegs ; i + + )
if ( os - > segments [ i ] < 255 )
packets + + ;
return packets ;
}
static int speex_packet ( AVFormatContext * s , int idx )
{
struct ogg * ogg = s - > priv_data ;
struct ogg_stream * os = ogg - > streams + idx ;
struct speex_params * spxp = os - > private ;
int packet_size = s - > streams [ idx ] - > codec - > frame_size ;
if ( ! spxp ) {
spxp = av_mallocz ( sizeof ( * spxp ) ) ;
os - > private = spxp ;
}
if ( os - > flags & OGG_FLAG_EOS & & os - > lastgp ! = - 1 & & os - > granule > 0 ) {
/* first packet of final page. we have to calculate the final packet
duration here because it is the only place we know the next - to - last
granule position . */
spxp - > final_packet_duration = os - > granule - os - > lastgp -
packet_size * ( ogg_page_packets ( os ) - 1 ) ;
}
if ( ! os - > lastgp & & os - > granule > 0 )
/* first packet */
os - > pduration = os - > granule - packet_size * ( ogg_page_packets ( os ) - 1 ) ;
else if ( os - > flags & OGG_FLAG_EOS & & os - > segp = = os - > nsegs & &
spxp - > final_packet_duration )
/* final packet */
os - > pduration = spxp - > final_packet_duration ;
else
os - > pduration = packet_size ;
return 0 ;
}
const struct ogg_codec ff_speex_codec = {
. magic = " Speex " ,
. magicsize = 8 ,
. header = speex_header
. header = speex_header ,
. packet = speex_packet
} ;