From: Sebastian Dröge <sebast...@centricular.com> Signed-off-by: Sebastian Dröge <sebast...@centricular.com> --- libavformat/mpegtsenc.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-)
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 0674064..51d1a0b 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -230,6 +230,8 @@ typedef struct MpegTSWriteStream { /* For Opus */ int opus_queued_samples; + int opus_pending_trim_start; + int opus_pending_trim_end; } MpegTSWriteStream; static void mpegts_write_pat(AVFormatContext *s) @@ -825,6 +827,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); @@ -1506,24 +1511,47 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) if (ret < 0) return ret; } else if (st->codec->codec_id == AV_CODEC_ID_OPUS) { + uint8_t *side_data; + int side_data_size; + if (pkt->size < 2) { av_log(s, AV_LOG_ERROR, "Opus packet too short\n"); return AVERROR_INVALIDDATA; } + side_data = av_packet_get_side_data(pkt, + AV_PKT_DATA_SKIP_SAMPLES, + &side_data_size); + + if (side_data && side_data_size >= 10) { + uint32_t discard_padding = AV_RL32(side_data + 4) * 48000 / st->codec->sample_rate; + ts_st->opus_pending_trim_end += discard_padding; + } + /* Add Opus control header */ if ((AV_RB16(pkt->data) >> 5) != 0x3ff) { 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); + ctrl_header_size = pkt->size + 2 + pkt->size / 255 + 1; + if (ts_st->opus_pending_trim_start) + ctrl_header_size += 2; + if (ts_st->opus_pending_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 (ts_st->opus_pending_trim_end) + data[1] |= 0x08; n = pkt->size; i = 2; @@ -1535,9 +1563,22 @@ 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 (ts_st->opus_pending_trim_end) { + trim_end = FFMIN(ts_st->opus_pending_trim_end, opus_samples - trim_start); + AV_WB16(data + i, trim_end); + i += 2; + ts_st->opus_pending_trim_end -= trim_end; + } + 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! */ -- 2.6.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel