From patchwork Wed Jul 14 14:34:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 28923 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a5d:965a:0:0:0:0:0 with SMTP id d26csp465398ios; Wed, 14 Jul 2021 07:36:28 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzg7crO7G6+Lj1HshEuIR+WD3/2ilPJE5nD8TTcYV03xyYbJPvsvuj9gXNLvhrKNzKj6RXc X-Received: by 2002:a17:906:2acc:: with SMTP id m12mr2105808eje.231.1626273388268; Wed, 14 Jul 2021 07:36:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626273388; cv=none; d=google.com; s=arc-20160816; b=ieIExgDtW7+v+aFwE2PesZivCPRSGpz08XMZXVQr+vhxI++Hr+5lPRZeEMigSuicVp BTDmB6k2RSD10A6s8z+iUocGLhTAn1YiYgALIm7jpkMzY5DK8KSyCP5DMPnLIuV5kTQO JVwL9Pk0fHoBdMbbEedIj7+rfG7t+xfnqLZckgukGZaOkk6DfX1xqSpTKqeVCTxaM8Jx 3CseJ8mTnDupY2oIxSeynCA9hs6N9eMoWpXYp9TvNAZ9xwcn1lC/XaYqkO6wHoaBtLIy gXCtB38ZarluiBtkodngQDNWCpZw5yeFpbIuXBv810g1pK3R4B+p4maN0EbYTqKzBbGA S6+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=fLfYRd+Y0TXXSo9rQalGrjVXd0kTFrUhMGhb5Sy6msE=; b=XwHjtpvikfEWUzORNirH3oVd4Jh8yxwNtXxT5j+HF8ahhZ0PPD6oVeHAhF2Mqf4kGI 6yJLgaG0SnPJy8Wp8GzcyBlGYcKCoQAF8L08Zc1HXe5mxiIl0K+PHw1ndGcwhmH/RZQz dZeFVANRM/+aIQUaJBo1/h9CTX4EVvlg7BkaLgHltC6hznjFThEmN7PAwCq2Kp65uEJx 11TmXIBYQKIlTfFA/IQTT7pfqWyaNAkR6prQQlTJ7u9pbe6rZ57gcMgiG2glwQjEcNHz bhNn3JhTm6slDj/jNS5x0EvtjPOKRX6LruVPM9g7tMLIp3T11wlD7/2W6tLoDPKNTtNq S3Iw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=mrn0O9+N; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id ee55si2639491edb.109.2021.07.14.07.36.27; Wed, 14 Jul 2021 07:36:28 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=mrn0O9+N; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0558E68A7C8; Wed, 14 Jul 2021 17:36:24 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 137B6687F21 for ; Wed, 14 Jul 2021 17:36:17 +0300 (EEST) Received: by mail-pj1-f47.google.com with SMTP id cu14so1714245pjb.0 for ; Wed, 14 Jul 2021 07:36:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=TMfZQf5V2STqrTmrwyex7Bmk8QKBoXlNRf3CbXnHDvA=; b=mrn0O9+NzNEtHDCJkBoMob+WbAD5viRIz+6KuD2Kzcu3XiqEqQ1ejcJHIdMTdNJYEi xV2WyUMsjOTdeMizemflHOfOhITU0nue9LXdF7Ix2UriFZGQB8q8XJxL0KqbV3JivDDE R7gj/ERS9VRCz00OBgJKXJmTm0Xrnz4wwCPV3+3GPcOx6qf+VyTX0EZ81E9WUhQQSbrC 2PMuX0C4cPuIjFYiNm+Rvd7kx9769ac/rYaOhIYGrHmWwQ0gfHJ3vJ4oWkBk+RkzmkJ9 nHxo4F3UnkUV96EZAkwVfOdksvBOn9Y++xlNFVPqWDsSo+a6RWK6cxG4Ohnotqc2CFHP UUFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TMfZQf5V2STqrTmrwyex7Bmk8QKBoXlNRf3CbXnHDvA=; b=H7RZlkMabw6PztFKvMXvO9pMqiRYXGpIf/JRBZD1fEk22zYtGXCVByTdLP6sWToX4V 1kuNmG93RvxYgg5KS+/ge7cEW8PNoT8fdDgJArR2MiBUZyoH6O12FBO+qfaxgp8NxHRv 1euhJJxYrNhZk+7Ez331dZfKKkm1lXYZ6hQxSLnyMskajWA8g0uW4WwICT9cip7UJIkv PmhS6UNmhA7ONKUhEhopF01h1lLHwrrIwpqTSRMkOEQzTuutm24ZTC9gzTtAtYGPKLHL pshxwIKmktntUkIqHoH5Ky2u7OSDOr9QA1Y711J8piTzRmQI0qzdTUEy3Uw/pNjqV6qY jxuA== X-Gm-Message-State: AOAM532z6SkrbzKSY0WB35Favds5iqwcEXZI4TPaF0LEYexYnnIRkpGM nw5eXEwXsCUpkvsHqLnuuW0ptuu8wPY= X-Received: by 2002:a17:90a:43c3:: with SMTP id r61mr4140808pjg.11.1626273374900; Wed, 14 Jul 2021 07:36:14 -0700 (PDT) Received: from localhost.localdomain ([191.83.217.217]) by smtp.gmail.com with ESMTPSA id b17sm1132030pfm.54.2021.07.14.07.36.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Jul 2021 07:36:14 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Wed, 14 Jul 2021 11:34:00 -0300 Message-Id: <20210714143401.890-2-jamrial@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210714143401.890-1-jamrial@gmail.com> References: <20210714143401.890-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/3] avformat/mpegtsenc: use an AVParser for h264 streams X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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" X-TUID: xFq6eFr8hdGN Use it to enable keyframe tagging heuristics to mark as many RAPs as possible. Signed-off-by: James Almer --- configure | 2 +- libavformat/mpegtsenc.c | 45 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 2d2d125fd3..bbf0283a67 100755 --- a/configure +++ b/configure @@ -3378,7 +3378,7 @@ mp3_demuxer_select="mpegaudio_parser" mp3_muxer_select="mpegaudioheader" mp4_muxer_select="mov_muxer" mpegts_demuxer_select="iso_media" -mpegts_muxer_select="ac3_parser adts_muxer latm_muxer h264_mp4toannexb_bsf hevc_mp4toannexb_bsf" +mpegts_muxer_select="ac3_parser adts_muxer latm_muxer h264_parser h264_mp4toannexb_bsf hevc_mp4toannexb_bsf" mpegtsraw_demuxer_select="mpegts_demuxer" mxf_muxer_select="golomb pcm_rechunk_bsf" mxf_d10_muxer_select="mxf_muxer" diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 98dac17994..4e15f3da07 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -257,6 +257,10 @@ typedef struct MpegTSWriteStream { int opus_queued_samples; int opus_pending_trim_start; + /* For H.264 */ + AVCodecParserContext *parser; + AVCodecContext *parser_avctx; + DVBAC3Descriptor *dvb_ac3_desc; } MpegTSWriteStream; @@ -1216,6 +1220,21 @@ static int mpegts_init(AVFormatContext *s) ts_st->payload_dts = AV_NOPTS_VALUE; ts_st->cc = 15; ts_st->discontinuity = ts->flags & MPEGTS_FLAG_DISCONT; + if (st->codecpar->codec_id == AV_CODEC_ID_H264) { + ts_st->parser = av_parser_init(st->codecpar->codec_id); + if (!ts_st->parser) + return AVERROR(ENOMEM); + ts_st->parser_avctx = avcodec_alloc_context3(NULL); + if (!ts_st->parser_avctx) + return AVERROR(ENOMEM); + ret = avcodec_parameters_to_context(ts_st->parser_avctx, st->codecpar); + if (ret < 0) + return ret; + // We only want to parse frame headers + ts_st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; + // And we want keyframe tagging heuristics + ts_st->parser->flags |= PARSER_FLAG_USE_KEYFRAME_HEURISTICS; + } if (st->codecpar->codec_id == AV_CODEC_ID_AAC && st->codecpar->extradata_size > 0) { AVStream *ast; @@ -1832,6 +1851,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2; const int64_t max_audio_delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) / 2; int64_t dts = pkt->dts, pts = pkt->pts; + int flags = pkt->flags; int opus_samples = 0; size_t side_data_size; uint8_t *side_data = NULL; @@ -1864,11 +1884,18 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) if (st->codecpar->codec_id == AV_CODEC_ID_H264) { const uint8_t *p = buf, *buf_end = p + size; uint32_t state = -1; - int extradd = (pkt->flags & AV_PKT_FLAG_KEY) ? st->codecpar->extradata_size : 0; + int extradd; int ret = ff_check_h264_startcode(s, st, pkt); if (ret < 0) return ret; + av_parser_parse2(ts_st->parser, ts_st->parser_avctx, + &buf, &size, pkt->data, pkt->size, + pkt->pts, pkt->dts, pkt->pos); + if (ts_st->parser->key_frame) + flags |= AV_PKT_FLAG_KEY; + + extradd = (flags & AV_PKT_FLAG_KEY) ? st->codecpar->extradata_size : 0; if (extradd && AV_RB24(st->codecpar->extradata) > 1) extradd = 0; @@ -2106,7 +2133,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) av_assert0(!ts_st->payload_size); // for video and subtitle, write a single pes packet mpegts_write_pes(s, st, buf, size, pts, dts, - pkt->flags & AV_PKT_FLAG_KEY, stream_id); + flags & AV_PKT_FLAG_KEY, stream_id); ts_st->opus_queued_samples = 0; av_free(data); return 0; @@ -2115,7 +2142,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) if (!ts_st->payload_size) { ts_st->payload_pts = pts; ts_st->payload_dts = dts; - ts_st->payload_flags = pkt->flags; + ts_st->payload_flags = flags; } memcpy(ts_st->payload + ts_st->payload_size, buf, size); @@ -2184,6 +2211,9 @@ static void mpegts_deinit(AVFormatContext *s) if (ts_st) { av_freep(&ts_st->dvb_ac3_desc); av_freep(&ts_st->payload); + avcodec_free_context(&ts_st->parser_avctx); + av_parser_close(ts_st->parser); + ts_st->parser = NULL; if (ts_st->amux) { avformat_free_context(ts_st->amux); ts_st->amux = NULL; @@ -2207,8 +2237,15 @@ static int mpegts_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt if (pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 && (AV_RB24(pkt->data) != 0x000001 || (st->codecpar->extradata_size > 0 && - st->codecpar->extradata[0] == 1))) + st->codecpar->extradata[0] == 1))) { ret = ff_stream_add_bitstream_filter(st, "h264_mp4toannexb", NULL); + if (ret == 1) { + MpegTSWriteStream *ts_st = st->priv_data; + int err = avcodec_parameters_to_context(ts_st->parser_avctx, st->internal->bsfc->par_out); + if (err < 0) + return err; + } + } } else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) { if (pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 && (AV_RB24(pkt->data) != 0x000001 ||