[vlc-devel] [PATCH 1/2] Ogg: split opus frame duration in its own file
Tristan Matthews
le.businessman at gmail.com
Wed Sep 10 01:23:48 CEST 2014
On Tue, Sep 9, 2014 at 11:46 AM, Rafaël Carré <funman at videolan.org> wrote:
> ---
> modules/demux/Makefile.am | 2 +-
> modules/demux/ogg.c | 64 ++++++++---------------------------------------
> modules/demux/opus.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 74 insertions(+), 55 deletions(-)
> create mode 100644 modules/demux/opus.h
>
> 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 <tterribe at xiph.org>
> + *
> + * 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;
> +}
LGTM.
Best,
Tristan
More information about the vlc-devel
mailing list