vlc | branch: master | Rafaël Carré <[email protected]> | Tue Sep 9 17:19:18 2014 +0200| [5740f2d1c6d7d160c54117bd08e7a8ec3fd7265e] | committer: Rafaël Carré
Ogg: split opus frame duration in its own file > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=5740f2d1c6d7d160c54117bd08e7a8ec3fd7265e --- modules/demux/Makefile.am | 2 +- modules/demux/ogg.c | 64 +++++++-------------------------------------- modules/demux/opus.h | 63 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 55 deletions(-) diff --git a/modules/demux/Makefile.am b/modules/demux/Makefile.am index 64f9884..84c4568 100644 --- a/modules/demux/Makefile.am +++ b/modules/demux/Makefile.am @@ -6,7 +6,7 @@ libflacsys_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) demux_LTLIBRARIES += libflacsys_plugin.la libogg_plugin_la_SOURCES = demux/ogg.c demux/ogg.h demux/oggseek.c demux/oggseek.h \ - demux/xiph_metadata.h demux/xiph.h demux/xiph_metadata.c + demux/xiph_metadata.h demux/xiph.h demux/xiph_metadata.c demux/opus.h libogg_plugin_la_CFLAGS = $(AM_CFLAGS) $(CFLAGS_ogg) $(LIBVORBIS_CFLAGS) libogg_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(demuxdir)' libogg_plugin_la_LIBADD = $(LIBS_ogg) $(LIBVORBIS_LIBS) diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c index 192e3e0..3c87732 100644 --- a/modules/demux/ogg.c +++ b/modules/demux/ogg.c @@ -44,6 +44,7 @@ #include "xiph_metadata.h" #include "ogg.h" #include "oggseek.h" +#include "opus.h" /***************************************************************************** * Module descriptor @@ -119,7 +120,7 @@ static int Control( demux_t *, int, va_list ); static int Ogg_ReadPage ( demux_t *, ogg_page * ); static void Ogg_UpdatePCR ( demux_t *, logical_stream_t *, ogg_packet * ); static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * ); -static int Ogg_OpusPacketDuration( logical_stream_t *, ogg_packet * ); +static int Ogg_OpusPacketDuration( ogg_packet * ); static void Ogg_SendOrQueueBlocks( demux_t *, logical_stream_t *, block_t * ); static void Ogg_CreateES( demux_t *p_demux ); @@ -502,7 +503,6 @@ static int Demux( demux_t * p_demux ) ogg_packet dumb_packet; dumb_packet.bytes = p_block->i_buffer; dumb_packet.packet = p_block->p_buffer; - int i_duration; switch( p_stream->fmt.i_codec ) { @@ -511,8 +511,7 @@ static int Demux( demux_t * p_demux ) p_stream->special.speex.i_framesperpacket; break; case VLC_CODEC_OPUS: - i_duration = Ogg_OpusPacketDuration( p_stream, &dumb_packet ); - p_block->i_nb_samples = i_duration; + p_block->i_nb_samples = Ogg_OpusPacketDuration( &dumb_packet ); break; #ifdef HAVE_LIBVORBIS case VLC_CODEC_VORBIS: @@ -520,11 +519,10 @@ static int Demux( demux_t * p_demux ) long i_blocksize = vorbis_packet_blocksize( p_stream->special.vorbis.p_info, &dumb_packet ); if ( i_prev_blocksize ) - i_duration = ( i_blocksize + i_prev_blocksize ) / 4; + p_block->i_nb_samples = ( i_blocksize + i_prev_blocksize ) / 4; else - i_duration = i_blocksize / 2; + p_block->i_nb_samples = i_blocksize / 2; i_prev_blocksize = i_blocksize; - p_block->i_nb_samples = i_duration; } #endif } @@ -963,7 +961,7 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream, if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s ) { - int duration = Ogg_OpusPacketDuration( p_stream, p_oggpacket ); + int duration = Ogg_OpusPacketDuration( p_oggpacket ); if( duration > 0 ) { ogg_int64_t end_sample = p_oggpacket->granulepos; @@ -1024,7 +1022,7 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream, else if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_stream->i_previous_granulepos > 0 && ( i_duration = - Ogg_OpusPacketDuration( p_stream, p_oggpacket ) ) > 0 ) + Ogg_OpusPacketDuration( p_oggpacket ) ) > 0 ) { ogg_int64_t sample; p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration; @@ -1292,7 +1290,7 @@ static void Ogg_DecodePacket( demux_t *p_demux, p_oggpacket->granulepos, p_stream->i_pcr, p_stream->i_skip_frames); ) if( p_stream->fmt.i_codec == VLC_CODEC_OPUS ) - p_block->i_nb_samples = Ogg_OpusPacketDuration( p_stream, p_oggpacket ); + p_block->i_nb_samples = Ogg_OpusPacketDuration( p_oggpacket ); /* may need to preroll after a seek or in case of preskip */ if ( p_stream->i_skip_frames > 0 ) @@ -1414,51 +1412,9 @@ static void Ogg_DecodePacket( demux_t *p_demux, Ogg_SendOrQueueBlocks( p_demux, p_stream, p_block ); } -/* Re-implemented to avoid linking against libopus from the demuxer. */ -static int Ogg_OpusDataDuration( logical_stream_t *p_stream, - unsigned char *data, long i_datalen ) +static int Ogg_OpusPacketDuration( ogg_packet *p_oggpacket ) { - static const int silk_fs_div[4] = { 6000, 3000, 1500, 1000 }; - int toc; - int nframes; - int frame_size; - int nsamples; - int i_rate; - if( i_datalen < 1 ) - return VLC_EGENERIC; - toc = data[0]; - switch( toc&3 ) - { - case 0: - nframes = 1; - break; - case 1: - case 2: - nframes = 2; - break; - default: - if( i_datalen < 2 ) - return VLC_EGENERIC; - nframes = data[1]&0x3F; - break; - } - i_rate = (int)p_stream->fmt.audio.i_rate; - if( toc&0x80 ) - frame_size = (i_rate << (toc >> 3 & 3)) / 400; - else if( ( toc&0x60 ) == 0x60 ) - frame_size = i_rate/(100 >> (toc >> 3 & 1)); - else - frame_size = i_rate*60 / silk_fs_div[toc >> 3 & 3]; - nsamples = nframes*frame_size; - if( nsamples*25 > i_rate*3 ) - return VLC_EGENERIC; - return nsamples; -} - -static int Ogg_OpusPacketDuration( logical_stream_t *p_stream, - ogg_packet *p_oggpacket ) -{ - return Ogg_OpusDataDuration( p_stream, p_oggpacket->packet, p_oggpacket->bytes ); + return opus_frame_duration(p_oggpacket->packet, p_oggpacket->bytes); } /**************************************************************************** diff --git a/modules/demux/opus.h b/modules/demux/opus.h new file mode 100644 index 0000000..9721bc1 --- /dev/null +++ b/modules/demux/opus.h @@ -0,0 +1,63 @@ +/***************************************************************************** + * opus.h : Opus demux helpers + ***************************************************************************** + * Copyright (C) 2012 VLC authors and VideoLAN + * $Id$ + * + * Authors: Timothy B. Terriberry <[email protected]> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +/* Returns Opus frame duration in samples */ + +static inline int opus_frame_duration(unsigned char *data, long len) +{ + static const int silk_fs_div[4] = { 6000, 3000, 1500, 1000 }; + int toc; + int nframes; + int frame_size; + int nsamples; + int i_rate; + if( len < 1 ) + return 0; + toc = data[0]; + switch( toc&3 ) + { + case 0: + nframes = 1; + break; + case 1: + case 2: + nframes = 2; + break; + default: + if( len < 2 ) + return 0; + nframes = data[1]&0x3F; + break; + } + i_rate = 48000; + if( toc&0x80 ) + frame_size = (i_rate << (toc >> 3 & 3)) / 400; + else if( ( toc&0x60 ) == 0x60 ) + frame_size = i_rate/(100 >> (toc >> 3 & 1)); + else + frame_size = i_rate*60 / silk_fs_div[toc >> 3 & 3]; + nsamples = nframes*frame_size; + if( nsamples*25 > i_rate*3 ) + return 0; + return nsamples; +} _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
