From patchwork Tue Nov 20 15:57:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: msanders X-Patchwork-Id: 11093 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 162D044C8A9 for ; Tue, 20 Nov 2018 17:58:10 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 87A26689B9E; Tue, 20 Nov 2018 17:58:10 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-40136.protonmail.ch (mail-40136.protonmail.ch [185.70.40.136]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 29057689A89 for ; Tue, 20 Nov 2018 17:58:05 +0200 (EET) Date: Tue, 20 Nov 2018 15:57:58 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=default; t=1542729486; bh=ChtpKM7n40VmPH5pjdLGmVBIsZPHWrhFmI06IPkxUcY=; h=Date:To:From:Reply-To:Subject:Feedback-ID:From; b=NqSGD/kSVc5vOTWyyRGBRgw2xhmkGNZzoMQrHmL4zW29LraYydC3BEzqkswr8pq6w fGnGieoXAIV5uuOyspVJ8vD7N/2bVHDCf4E++QR4gUo2NskIFkcl4Nkkzfi6jUEGQl Wry/LcEk5bSi4GUdA0LMQRQ7ULGJIeO03sxhFntM= To: "ffmpeg-devel@ffmpeg.org" From: msanders Message-ID: Feedback-ID: hxVIcPzxvPRBewlNhpteUTv_4-N7gEzUoa5RGYAcfYt7NnoUnD-6ZZ-GI3i3cXkBY60X3toqu87_pcSsszad1Q==:Ext:ProtonMail MIME-Version: 1.0 X-Spam-Status: No, score=-1.1 required=7.0 tests=ALL_TRUSTED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,HTML_MESSAGE autolearn=ham autolearn_force=no version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.protonmail.ch X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: [FFmpeg-devel] [PATCH] libavformat: add multiple PCR streams in MPEGTS muxer [v2] X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This new patch adds three new options to the MPEG-TS muxer. You can use them to mark PCRs in additional VIDEO/AUDIO/DATA streams. It's useful when you will remux the output with pid filtering tools. For example, if you put PCR in all audio streams, then you can filter each audio stream to create a radio service. PCR marks do not disturb outgoing stream, but it is not recommended to do so as a regular rule. Anyway the resulting stream is conformant with specs. Supersedes: [FFmpeg-devel] libavformat: add multiple PCR streams in MPEGTS muxer M. Sanders. From 198f1cfd65d2735fd86c5fc32c7b2a9f41cff79d Mon Sep 17 00:00:00 2001 From: M. Sanders Date: Tue, 20 Nov 2018 15:40:57 +0000 Subject: [PATCH] libavformat: add multiple PCR streams in MPEGTS muxer [v2] --- This new patch adds three new options to the MPEG-TS muxer. You can use them to mark PCRs in additional VIDEO/AUDIO/DATA streams. It's useful when you will remux the output with pid filtering tools. For example, if you put PCR in all audio streams, then you can filter each audio stream to create a radio service. PCR marks do not disturb outgoing stream, but it is not recommended to do so as a regular rule. Anyway the resulting stream is conformant with specs. Supersedes: [FFmpeg-devel] libavformat: add multiple PCR streams in MPEGTS muxer doc/muxers.texi | 9 +++++++++ libavformat/mpegtsenc.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 62f4091..8f0c5a1 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -1528,6 +1528,15 @@ is @code{-1}, which results in shifting timestamps so that they start from 0. @item omit_video_pes_length @var{boolean} Omit the PES packet length for video packets. Default is @code{1} (true). +@item pcr_all_video @var{boolean} +Include PCR values in all video streams. Default is @code{0} (false). + +@item pcr_all_audio @var{boolean} +Include PCR values in all audio streams. Default is @code{0} (false). + +@item pcr_all_data @var{boolean} +Include PCR values in all data streams. Default is @code{0} (false). + @item pcr_period @var{integer} Override the default PCR retransmission time in milliseconds. Ignored if variable muxrate is selected. Default is @code{20}. diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 3339e26..fb7f11a 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -113,6 +113,9 @@ typedef struct MpegTSWrite { double sdt_period; int64_t last_pat_ts; int64_t last_sdt_ts; + int pcr_all_video; + int pcr_all_audio; + int pcr_all_data; int omit_video_pes_length; } MpegTSWrite; @@ -237,6 +240,7 @@ typedef struct MpegTSWriteStream { int prev_payload_key; int64_t payload_pts; int64_t payload_dts; + int local_pcr_packet_count; int payload_flags; uint8_t *payload; AVFormatContext *amux; @@ -902,6 +906,7 @@ static int mpegts_init(AVFormatContext *s) pids[i] = ts_st->pid; ts_st->payload_pts = AV_NOPTS_VALUE; ts_st->payload_dts = AV_NOPTS_VALUE; + ts_st->local_pcr_packet_count = -1; ts_st->first_pts_check = 1; ts_st->cc = 15; ts_st->discontinuity = ts->flags & MPEGTS_FLAG_DISCONT; @@ -1178,11 +1183,17 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, int64_t pcr = -1; /* avoid warning */ int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key; + int force_pcr = 0; av_assert0(ts_st->payload != buf || st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO); if (ts->flags & MPEGTS_FLAG_PAT_PMT_AT_FRAMES && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { force_pat = 1; } + if ((ts->pcr_all_video && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) || + (ts->pcr_all_audio && st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) || + (ts->pcr_all_data && st->codecpar->codec_type == AVMEDIA_TYPE_DATA)) { + force_pcr = 1; + } is_start = 1; while (payload_size > 0) { @@ -1198,6 +1209,16 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, ts_st->service->pcr_packet_count = 0; write_pcr = 1; } + } else if (force_pcr) { // for streams other than the primary PCR stream + if (ts_st->local_pcr_packet_count < 0) // copy from primary + ts_st->local_pcr_packet_count = ts_st->service->pcr_packet_count; + if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames + ts_st->local_pcr_packet_count++; + if (ts_st->local_pcr_packet_count >= + ts_st->service->pcr_packet_period) { + ts_st->local_pcr_packet_count = 0; + write_pcr = 1; + } } if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE && @@ -1228,7 +1249,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, } if (key && is_start && pts != AV_NOPTS_VALUE) { // set Random Access for key frames - if (ts_st->pid == ts_st->service->pcr_pid) + if (ts_st->pid == ts_st->service->pcr_pid || force_pcr) write_pcr = 1; set_af_flag(buf, 0x40); q = get_ts_payload_start(buf); @@ -1951,6 +1972,15 @@ static const AVOption options[] = { { "omit_video_pes_length", "Omit the PES packet length for video packets", offsetof(MpegTSWrite, omit_video_pes_length), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, + { "pcr_all_video", "Include PCR values in all video streams", + offsetof(MpegTSWrite, pcr_all_video), AV_OPT_TYPE_BOOL, + { .i64 = 0 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, + { "pcr_all_audio", "Include PCR values in all audio streams", + offsetof(MpegTSWrite, pcr_all_audio), AV_OPT_TYPE_BOOL, + { .i64 = 0 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, + { "pcr_all_data", "Include PCR values in all data streams", + offsetof(MpegTSWrite, pcr_all_data), AV_OPT_TYPE_BOOL, + { .i64 = 0 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, { "pcr_period", "PCR retransmission time in milliseconds", offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_INT, { .i64 = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },