[vlc-devel] [PATCH 1/2] Ogg: split opus frame duration in its own file

Rafaël Carré funman at videolan.org
Tue Sep 9 17:46:44 CEST 2014


---
 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;
+}
-- 
2.1.0




More information about the vlc-devel mailing list