[FFmpeg-devel] avformat/oggdec: improve playback of chained opus file

Submitted by Paul B Mahol on April 26, 2019, 9:58 p.m.

Details

Message ID 20190426215821.12388-1-onemda@gmail.com
State New
Headers show

Commit Message

Paul B Mahol April 26, 2019, 9:58 p.m.
Improves decoding of: https://jmvalin.ca/misc_stuff/chain_works.opus

Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 libavformat/oggdec.c       | 10 +++++++++-
 libavformat/oggdec.h       |  1 +
 libavformat/oggparseopus.c |  1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index e815f42134..8f9ff69d70 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -177,6 +177,7 @@  static int ogg_reset(AVFormatContext *s)
         if (start_pos <= s->internal->data_offset) {
             os->lastpts = 0;
         }
+        os->start_trimming = 0;
         os->end_trimming = 0;
         av_freep(&os->new_metadata);
         os->new_metadata_size = 0;
@@ -237,6 +238,11 @@  static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs)
     os = &ogg->streams[i];
 
     os->serial  = serial;
+    os->header  = -1;
+    os->lastpts = 0;
+    os->lastdts = 0;
+    os->start_trimming = 0;
+    os->end_trimming = 0;
     return i;
 
 #if 0
@@ -846,13 +852,15 @@  retry:
     pkt->duration = os->pduration;
     pkt->pos      = fpos;
 
-    if (os->end_trimming) {
+    if (os->end_trimming || os->start_trimming) {
         uint8_t *side_data = av_packet_new_side_data(pkt,
                                                      AV_PKT_DATA_SKIP_SAMPLES,
                                                      10);
         if(!side_data)
             goto fail;
+        AV_WL32(side_data + 0, os->start_trimming);
         AV_WL32(side_data + 4, os->end_trimming);
+        os->start_trimming = 0;
         os->end_trimming = 0;
     }
 
diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h
index 4a2b6ddee8..b4eb6e31d2 100644
--- a/libavformat/oggdec.h
+++ b/libavformat/oggdec.h
@@ -84,6 +84,7 @@  struct ogg_stream {
     int got_start;
     int got_data;   ///< 1 if the stream got some data (non-initial packets), 0 otherwise
     int nb_header; ///< set to the number of parsed headers
+    int start_trimming; ///< set the number of packets to drop from the end
     int end_trimming; ///< set the number of packets to drop from the end
     uint8_t *new_metadata;
     unsigned int new_metadata_size;
diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c
index cd34cf23ba..e6e0780df5 100644
--- a/libavformat/oggparseopus.c
+++ b/libavformat/oggparseopus.c
@@ -58,6 +58,7 @@  static int opus_header(AVFormatContext *avf, int idx)
 
         priv->pre_skip        = AV_RL16(packet + 10);
         st->codecpar->initial_padding = priv->pre_skip;
+        os->start_trimming = priv->pre_skip;
         /*orig_sample_rate    = AV_RL32(packet + 12);*/
         /*gain                = AV_RL16(packet + 16);*/
         /*channel_map         = AV_RL8 (packet + 18);*/