[FFmpeg-cvslog] mpegtsenc: Implement writing of Opus trim_start/trim_end control values

Sebastian Dröge git at videolan.org
Fri Nov 6 03:49:10 CET 2015


ffmpeg | branch: master | Sebastian Dröge <sebastian at centricular.com> | Mon Nov  2 09:06:19 2015 +0200| [7d6a4797f17f29ed6f48eecbf9c50ae99a8fb04d] | committer: Michael Niedermayer

mpegtsenc: Implement writing of Opus trim_start/trim_end control values

Signed-off-by: Sebastian Dröge <sebastian at centricular.com>
Reviewed-by: Kieran Kunhya <kierank at obe.tv>
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7d6a4797f17f29ed6f48eecbf9c50ae99a8fb04d
---

 libavformat/mpegtsenc.c |   43 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 96d277e..252f9c6 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -230,6 +230,7 @@ typedef struct MpegTSWriteStream {
 
     /* For Opus */
     int opus_queued_samples;
+    int opus_pending_trim_start;
 } MpegTSWriteStream;
 
 static void mpegts_write_pat(AVFormatContext *s)
@@ -825,6 +826,9 @@ static int mpegts_write_header(AVFormatContext *s)
             if (ret < 0)
                 goto fail;
         }
+        if (st->codec->codec_id == AV_CODEC_ID_OPUS) {
+            ts_st->opus_pending_trim_start = st->codec->initial_padding * 48000 / st->codec->sample_rate;
+        }
     }
 
     av_freep(&pids);
@@ -1513,17 +1517,38 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
 
         /* Add Opus control header */
         if ((AV_RB16(pkt->data) >> 5) != 0x3ff) {
+            uint8_t *side_data;
+            int side_data_size;
             int i, n;
+            int ctrl_header_size;
+            int trim_start = 0, trim_end = 0;
 
             opus_samples = opus_get_packet_samples(s, pkt);
 
-            data = av_malloc(pkt->size + 2 + pkt->size / 255 + 1);
+            side_data = av_packet_get_side_data(pkt,
+                                                AV_PKT_DATA_SKIP_SAMPLES,
+                                                &side_data_size);
+
+            if (side_data && side_data_size >= 10) {
+                trim_end = AV_RL32(side_data + 4) * 48000 / st->codec->sample_rate;
+            }
+
+            ctrl_header_size = pkt->size + 2 + pkt->size / 255 + 1;
+            if (ts_st->opus_pending_trim_start)
+              ctrl_header_size += 2;
+            if (trim_end)
+              ctrl_header_size += 2;
+
+            data = av_malloc(ctrl_header_size);
             if (!data)
                 return AVERROR(ENOMEM);
 
-            /* TODO: Write trim if needed */
             data[0] = 0x7f;
             data[1] = 0xe0;
+            if (ts_st->opus_pending_trim_start)
+                data[1] |= 0x10;
+            if (trim_end)
+                data[1] |= 0x08;
 
             n = pkt->size;
             i = 2;
@@ -1535,9 +1560,21 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
 
             av_assert0(2 + pkt->size / 255 + 1 == i);
 
+            if (ts_st->opus_pending_trim_start) {
+                trim_start = FFMIN(ts_st->opus_pending_trim_start, opus_samples);
+                AV_WB16(data + i, trim_start);
+                i += 2;
+                ts_st->opus_pending_trim_start -= trim_start;
+            }
+            if (trim_end) {
+                trim_end = FFMIN(trim_end, opus_samples - trim_start);
+                AV_WB16(data + i, trim_end);
+                i += 2;
+            }
+
             memcpy(data + i, pkt->data, pkt->size);
             buf     = data;
-            size    = pkt->size + 2 + pkt->size / 255 + 1;
+            size    = ctrl_header_size;
         } else {
             /* TODO: Can we get TS formatted data here? If so we will
              * need to count the samples of that too! */



More information about the ffmpeg-cvslog mailing list