summaryrefslogtreecommitdiff
path: root/libavformat/mpegtsenc.c
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2015-11-02 09:06:19 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2015-11-06 03:33:17 +0100
commit7d6a4797f17f29ed6f48eecbf9c50ae99a8fb04d (patch)
tree0bcf7af4df1281186bfc1d6ce660bf9744b2cd5f /libavformat/mpegtsenc.c
parent01509cdf9287b975eced1fd609a8201fbd1438e3 (diff)
mpegtsenc: Implement writing of Opus trim_start/trim_end control values
Signed-off-by: Sebastian Dröge <sebastian@centricular.com> Reviewed-by: Kieran Kunhya <kierank@obe.tv> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavformat/mpegtsenc.c')
-rw-r--r--libavformat/mpegtsenc.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 96d277e042..252f9c676b 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! */