[vlc-commits] codec: opus: replace bogus end trim hack

Francois Cartegnie git at videolan.org
Tue Jun 9 16:26:55 CEST 2020


vlc/vlc-3.0 | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Jun  9 15:47:48 2020 +0200| [a197b635423524130647bb4c34a69658d9b0e3ae] | committer: Francois Cartegnie

codec: opus: replace bogus end trim hack

refs #24830

> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=a197b635423524130647bb4c34a69658d9b0e3ae
---

 modules/codec/opus.c | 17 ++++++++++++++---
 modules/demux/ogg.c  | 20 ++++++++++++--------
 modules/demux/ogg.h  |  2 +-
 3 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/modules/codec/opus.c b/modules/codec/opus.c
index 87dcb15eb3..02960b58da 100644
--- a/modules/codec/opus.c
+++ b/modules/codec/opus.c
@@ -161,7 +161,7 @@ static int  ProcessHeaders( decoder_t * );
 static int  ProcessInitialHeader ( decoder_t *, ogg_packet * );
 static block_t *ProcessPacket( decoder_t *, ogg_packet *, block_t * );
 
-static block_t *DecodePacket( decoder_t *, ogg_packet *, int, int );
+static block_t *DecodePacket( decoder_t *, ogg_packet *, int, mtime_t );
 
 /*****************************************************************************
  * OpenDecoder: probe the decoder and return score
@@ -423,7 +423,7 @@ static block_t *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
 
     block_t *p_aout_buffer = DecodePacket( p_dec, p_oggpacket,
                                            p_block->i_nb_samples,
-                                           (int)p_block->i_length );
+                                           p_block->i_length );
 
     block_Release( p_block );
     return p_aout_buffer;
@@ -433,7 +433,7 @@ static block_t *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
  * DecodePacket: decodes a Opus packet.
  *****************************************************************************/
 static block_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
-                              int i_nb_samples, int i_end_trim )
+                              int i_nb_samples, mtime_t i_duration )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
 
@@ -450,6 +450,17 @@ static block_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
     if(!i_nb_samples)
         i_nb_samples = spp;
 
+    int i_duration_samples = ((i_duration + (CLOCK_FREQ / 48000)) * 48000)
+                             / CLOCK_FREQ;
+    int i_end_trim;
+    if(i_duration_samples && i_duration_samples < i_nb_samples)
+    {
+        i_end_trim = spp - i_duration_samples;
+        msg_Dbg(p_dec, "truncating %d off %d samples", i_end_trim, i_nb_samples);
+    }
+    else
+        i_end_trim = 0;
+
     if( decoder_UpdateAudioFormat( p_dec ) )
         return NULL;
     block_t *p_aout_buffer=decoder_NewAudioBuffer( p_dec, spp );
diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c
index 73bfa2d9f9..e8d855dd45 100644
--- a/modules/demux/ogg.c
+++ b/modules/demux/ogg.c
@@ -1008,7 +1008,7 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
                            ogg_packet *p_oggpacket )
 {
     demux_sys_t *p_ogg = p_demux->p_sys;
-    p_stream->i_end_trim = 0;
+    p_stream->i_end_length = 0;
 
     /* Convert the granulepos into a pcr */
     if ( p_oggpacket->granulepos == 0 )
@@ -1040,14 +1040,17 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
         {
             ogg_int64_t sample = p_stream->i_previous_granulepos;
 
-            if( p_stream->fmt.i_codec == VLC_CODEC_OPUS && p_oggpacket->e_o_s )
+            if( p_oggpacket->e_o_s &&
+                (p_stream->fmt.i_codec == VLC_CODEC_OPUS ||
+                 p_stream->fmt.i_codec == VLC_CODEC_VORBIS) )
             {
                 unsigned duration = Ogg_OpusPacketDuration( p_oggpacket );
-                if( duration > 0 )
+                if( duration > 0 && p_stream->f_rate &&
+                    p_oggpacket->granulepos > sample )
                 {
-                    ogg_int64_t end_sample = p_oggpacket->granulepos;
-                    if( end_sample < ( sample + duration ) )
-                        p_stream->i_end_trim = sample + duration - end_sample;
+                    ogg_int64_t samples = p_oggpacket->granulepos - sample;
+                    if( samples < duration )
+                        p_stream->i_end_length = samples * CLOCK_FREQ / p_stream->f_rate;
                 }
             }
 
@@ -1477,8 +1480,9 @@ static void Ogg_DecodePacket( demux_t *p_demux,
             msleep(10000);
         }
 
-        /* Blatant abuse of the i_length field. */
-        p_block->i_length = p_stream->i_end_trim;
+        /* Handle explicit packet duration truncation */
+        if( p_stream->i_end_length )
+            p_block->i_length = p_stream->i_end_length;
         p_block->i_dts = p_stream->i_pcr;
         p_block->i_pts = p_stream->b_interpolation_failed ? VLC_TS_INVALID : p_stream->i_pcr;
     }
diff --git a/modules/demux/ogg.h b/modules/demux/ogg.h
index b7e52a1993..0159ab1737 100644
--- a/modules/demux/ogg.h
+++ b/modules/demux/ogg.h
@@ -95,7 +95,7 @@ typedef struct logical_stream_s
     /* Opus has a starting offset in the headers. */
     int i_pre_skip;
     /* Vorbis and Opus can trim the end of a stream using granule positions. */
-    int i_end_trim;
+    mtime_t i_end_length;
 
     /* offset of first keyframe for theora; can be 0 or 1 depending on version number */
     int8_t i_keyframe_offset;



More information about the vlc-commits mailing list