From patchwork Fri Feb 2 15:23:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Gaullier X-Patchwork-Id: 45983 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:1a28:b0:199:de12:6fa6 with SMTP id cj40csp1014252pzb; Fri, 2 Feb 2024 07:24:03 -0800 (PST) X-Google-Smtp-Source: AGHT+IFCAF9nYgIIKwBGe4JtQomZafvQRsmKCbgeKCO85CpGog8etj/bIi7SzPFZzP+Cto8HuTwe X-Received: by 2002:a17:906:7cf:b0:a36:5dd3:6126 with SMTP id m15-20020a17090607cf00b00a365dd36126mr6535573ejc.41.1706887443003; Fri, 02 Feb 2024 07:24:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1706887442; cv=none; d=google.com; s=arc-20160816; b=CpJaPq1nQXk3t9FexPbgXql3dhOUVpYXZSNQy5ZLH13BWEbZfp47QDJiWuiFcs2Bs6 zE2kHfWft/9MYHoFpxOzMDoZU+NhjUV/2mBwph8S6SSj0zyisp24Y2UvC+5Shzy0aAar QHnXrTXBFyLHGUpr7DiKdMjaa0ir//XB39YczmVzB7yuPuUewI9gubd8T1u6ytd3QEmf SAoZMio3G9djds4K5AC2CDz2nI7TfZXFN2KdnuETIwZ8laLBApEoxO5g6bxQArIqLkMg SK2He92Tcyh4gom7SpoHAMxuWibJYnh070wwsHezlCyJI36JwlCNlgO2T/hU3fWny3X/ ebcA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc: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:delivered-to; bh=S0ZJxYo71wVFBHYnNiYyBbmN2CdDthn280DewUvZPtQ=; fh=qVVT1cirzpnbIRBHfdwaPmnNEZnalykOJhHMpYxU/Xs=; b=GGafTi3sqlg6NVBjlQA2qb7tTWQcsm+HU/fMMym904h/6VXHLQ0fzF4x/Cx1PkzhM7 FrdTPNF0oayCBmgHJEaW3fPM5tpYTQ684qknihwhC2rDus70xq/Ge5sPqxM3+8ygzPaP 4YoNkK0mlXxBI+1Jicxb82AJz8WCot/+/X66GbBA7UQ78rK0cml7WaYCXvHUxxPnl13K /AMd/23nXODN5WDUvWstSIqHYDTHPXHWLWEAFRDzQMa6VGxdU+IvaWQNyjJW611pC25n uPvzH052+Lehlt5FiZiK/7RJx7J5PINGUtjaI6UqQxPb5Q4lX5eNxyDqJjtyVsXfkXtv 3q1w==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; 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 X-Forwarded-Encrypted: i=0; AJvYcCURx9O0UtjRg02A9IDT1SLu0KpV0hNaJsJrkC03SHAVZqkT2DEdiZz+SPLZB8+kj590AC0APbZNdpHcvTXN+ZuVhyXzP7QHD4W8+aM4UPXZ2ipRDzp5aYpmu8Ofcg8p5nWNRmSYPY+AYxQKdSfocSCUZw8Pt4FtEcjIdyy8rJHbcqgytw5K3zIDDidK9BOOtYonOB30Bwtm+sa+0HjNUjnBv36Us7uY92A7stk479rMhHxaHbxHCntCIZ6Zwam+MsIHNE4QWpPaGOzumftItBSL1zjg0DszJTAIxFAoH1rSBesDeBBrUL2Q3UjKH/Bhe2q0qBkMQCE99EJAmcFuVjCsl7sNN2LbDktzusUbbLDnWD8gj70HXdOMsloRFg4BdojhZpNqftBCPw8eCSyqIJP8dR6MtAuQteeRLNiJTszgaka+Xu+eXglby+8mSgquryuTPfKgeFG2AXOvaoMxu30iSW8HdLtFcpnoHmdWMdgki4ClgJjkHkgWeBwSzgav2AKsXthQxDWGhdSdmEyg2C3olNyhubN8WFPIfRz5XNUlIbMaNWqaQ51p1MiDKBhVDohPeChz5nhRc2Ehkdgglo9PSrrvb0WaD8OO+DJ2IiKBrflvX1DP+5on6UrMBnkZgLj7Z4MlZ6NKKShkG4022Gfb0qLnoCjC3q8sBx4awqQzCDBj1VvZtnso2AJ3UqUoaQaQL4fX5Q+9zT5/4gDUMs7QHdV+4oSPi4qHYvE4HkgrCM0Mg1wCRQz1dpNZ41z3v2G3Kw9LA0d0vowDRj5mfmasPW8y3zIhviz1h7cUzarILcjh+PWZeaapSaDEQALHkX2ZdJBL+ploD4kYKLVMbAiPL/MUFDxj1pV7GhOqL1GESSjKK4WclS9dZq1miS5gbPLYGDM5NRZTsZRMrxniG5EX6TWn7MtopdzNIXFHPM6z+Ns4JCxiRQMRAv/cMnTpJTIqvr /cJ8YI8ztWr+mY+CYa1Di8aKfRsJvhJgRXGUB+f6F9C7BIlZFGreKoUM3kj88cS90hidCgchDStoCd34qWw71WceSA8IbI0fJfxQoWLcnVDIh56/9oP60O0flwU6VjoweHImDLBY71BPZbHOkOPY5oMsDowtcomj5py4nUmtod0DUI9ZskTtH8O+mVQtZKzlf38sMRTBmC/5MZSPWSPGnTBKYq5BkpOxcjhjxjOe+Ve/DcK5GmvALRXScYGnJkxs+nW2gq46Qy+DPtB8TfaSzGRZBYn9hxRr4/pOzjGKSgsWwHLNLvmfgStcrxagPvagnXhIj8He2tS08do9j0Cl2fLpzR1nl8xqSDLUdrby3JErSPt4GKSTY1pJuCGEg3EaDpScaSf2SBGwYS/NiJn8HlqYxMzhfdSN8w5AcrbhRlRrHemkwqyvVZ8rFY5ccMsmtDqfom4HMhx+uqwTj4dZRy0fXNQdEMKuOd2M4ARNTOeXqTHOYSAspYadfhEQ7R8Rs7hn3SScPGB21SZgc3HTcWaYYse40dVeSlBzowecN8VryNygzdhjyP35b12S/ZMH+IclhA8NKUXRyklV140bbmLypkUYfsNqCp51fUnk7o7Hnv1jsCzSuJotyNotoDJ9L2XOOoFIIm Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id k14-20020a1709065fce00b00a35e32fd8a6si910103ejv.237.2024.02.02.07.24.02; Fri, 02 Feb 2024 07:24:02 -0800 (PST) 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; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id DEBC868D104; Fri, 2 Feb 2024 17:23:49 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from srv-infra-1.infra.inf.glb.tvvideoms.com (www.inf.tvvideoms.com [213.205.126.156]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E082368D008 for ; Fri, 2 Feb 2024 17:23:41 +0200 (EET) Received: from cji.paris (unknown [172.16.3.159]) by srv-infra-1.infra.inf.glb.tvvideoms.com (Postfix) with ESMTP id 0768129B62; Fri, 2 Feb 2024 15:23:40 +0000 (UTC) From: Nicolas Gaullier To: ffmpeg-devel@ffmpeg.org Date: Fri, 2 Feb 2024 16:23:38 +0100 Message-Id: <20240202152338.609500-2-nicolas.gaullier@cji.paris> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20240202152338.609500-1-nicolas.gaullier@cji.paris> References: <20240202152338.609500-1-nicolas.gaullier@cji.paris> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avformat/mpegts: fix first NAL start code splited in two different packets 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 Cc: Nicolas Gaullier Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: IhlJn/nQq03K When PES are not aligned and a tiny nal-encoded frame is contained in a single TS packet, the first NAL startcode may be split by the PES boundary, making the packet unworkable. This patch shift the PES boundaries to avoid this. Signed-off-by: Nicolas Gaullier --- libavformat/mpegts.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index bef00c88e7..4b4cf82fb9 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -1149,6 +1149,7 @@ static int mpegts_push_data(MpegTSFilter *filter, PESContext *pes = filter->u.pes_filter.opaque; MpegTSContext *ts = pes->ts; const uint8_t *p; + int pes_align_shift = 0; int ret, len; if (!ts->pkt) @@ -1156,6 +1157,37 @@ static int mpegts_push_data(MpegTSFilter *filter, if (is_start) { if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) { + if ((pes->st->codecpar->codec_id == AV_CODEC_ID_H264 + || pes->st->codecpar->codec_id == AV_CODEC_ID_HEVC) + && pes->data_index < TS_PACKET_SIZE - 4 - PES_HEADER_SIZE + && pes->data_index >= 4 + && buf_size >= 4 ) { + /* check/avoid spliting the start code + first byte of the first NAL unit in two different packets. + * this could happen with a tiny unaligned PES that fits in a single ts packet. */ + uint8_t *last_p_end = pes->buffer->data + pes->data_index - 4; + p = buf + PES_HEADER_SIZE + buf[PES_HEADER_SIZE - 1]; + if (last_p_end[3] == 0x00 && AV_RB24(p) == 0x000001) + pes_align_shift = 4; + else if (AV_RB16(last_p_end + 2)== 0x0000 && AV_RB16(p) == 0x0001) + pes_align_shift = 3; + else if (AV_RB24(last_p_end + 1)== 0x000000 && *p == 0x01) + pes_align_shift = 2; + else if (AV_RB32(last_p_end) == 0x00000001) + pes_align_shift = 1; + if (pes_align_shift) + { + last_p_end += 4; + if (pes_align_shift > 3) + *last_p_end++ = 0x00; + if (pes_align_shift > 2) + *last_p_end++ = 0x00; + if (pes_align_shift > 1) + *last_p_end++ = 0x01; + *last_p_end = *(p + pes_align_shift - 1); + pes->data_index += pes_align_shift; + buf_size -= pes_align_shift; + } + } ret = new_pes_packet(pes, ts->pkt); if (ret < 0) return ret; @@ -1301,6 +1333,7 @@ skip: /* we got the full header. We parse it and get the payload */ pes->state = MPEGTS_PAYLOAD; pes->data_index = 0; + p += pes_align_shift; if (pes->stream_type == 0x12 && buf_size > 0) { int sl_header_bytes = read_sl_header(pes, &pes->sl, p, buf_size); @@ -1409,9 +1442,13 @@ skip: pes->data_index += buf_size; /* emit complete packets with known packet size * decreases demuxer delay for infrequent packets like subtitles from - * a couple of seconds to milliseconds for properly muxed files. */ + * a couple of seconds to milliseconds for properly muxed files. + * disabled for video/NALs because at this point it could split/break the first NAL start code. + */ if (!ts->stop_parse && pes->PES_packet_length && - pes->pes_header_size + pes->data_index == pes->PES_packet_length + PES_START_SIZE) { + pes->pes_header_size + pes->data_index == pes->PES_packet_length + PES_START_SIZE && + pes->st->codecpar->codec_id != AV_CODEC_ID_H264 && + pes->st->codecpar->codec_id != AV_CODEC_ID_HEVC) { ts->stop_parse = 1; ret = new_pes_packet(pes, ts->pkt); pes->state = MPEGTS_SKIP;