[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