[vlc-commits] Ogg: split opus frame duration in its own file
Rafaël Carré
git at videolan.org
Wed Sep 10 10:37:44 CEST 2014
vlc | branch: master | Rafaël Carré <funman at videolan.org> | 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 <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;
+}
More information about the vlc-commits
mailing list