From patchwork Mon Feb 15 09:33:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: sharpbai X-Patchwork-Id: 25632 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 0057F448D3D for ; Mon, 15 Feb 2021 11:40:59 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C758D680987; Mon, 15 Feb 2021 11:40:59 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-vs1-f50.google.com (mail-vs1-f50.google.com [209.85.217.50]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C091068010B for ; Mon, 15 Feb 2021 11:40:52 +0200 (EET) Received: by mail-vs1-f50.google.com with SMTP id w13so241622vsw.6 for ; Mon, 15 Feb 2021 01:40:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=rY/LHNv5MikP1zk0hX/XyX4HuxIFVsioJPBa7JE5F14=; b=PRPaKegAH5JgYjn0Gqb9D35GbjQc5nndRjx+XkqgwPb4iryzEUvNaW0y3eFg6Q0Hui pDFG+KbDMCKpeQ48xu50P+gnquSQ/Yc+dI/GXry/bdfc2Jk1QsUoy4mKtnP7eBn23MH5 r6jQgRlOMS5SMzWh7ljH82lJ1ksMgMOfJkdhMFAx95o+kfkStIk5uF7ts6M3MRUfpnd4 c6rYGK5tzcqUx4RBaXpRNHlTigEJO7q/sMGnPNI7Gj9Y3vCL6nNL1KuyG0v5S+UXw4tt veef958ABvgnwgWPrKL6WrTfqbp/yyPSwgCCZJChRZDOnSi7UndzPW4TFjRx2tKmigJ6 eHhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=rY/LHNv5MikP1zk0hX/XyX4HuxIFVsioJPBa7JE5F14=; b=NJCljzOkCuN56Qa+NThNTu+Y3rEDqfpE4O97LE2Rsn3J31kxl2VkKPG44tjtqkGZMK sEjND3bHGf63Q5EU+dMIWiXl197rvdqzZq/sm6Z9ecVXITvKi3jYa1y2xEdmaafv31a5 cn2fRhmbLFSKcUeBfgXYNW+YiwmzGstxEL7nmUxnXmIgIdGd93wa/plvUiN5MA1noF6d 2tmNlDbYnWbPygkLgn5cWZKIwbzmyLok4WnVHj88UZo0U0eKeX2ThvXpKomdeSxrnt/Y shMlHEZ3+SudXEU+2qnzknNtizSolruDyKRjgArQHwJmsqYYNiGOv0Gp876fUM1/TPMD OLdg== X-Gm-Message-State: AOAM5308vPEAFt8o2KP+PjHB/uEG0WW6Wi2uxcyIB1cqVyqlMzwTAq80 bRTjaeZevcAn90gJkw1yK1TIbohaYUM= X-Google-Smtp-Source: ABdhPJzukCRZdbuC/Xh+PsHlN2IYat8ZiZsxHz9oIwc1cqkY6TWh8Swod4TOAMsNNl2GJZvdO2KADg== X-Received: by 2002:a05:6a00:1693:b029:1ec:b0af:d1d with SMTP id k19-20020a056a001693b02901ecb0af0d1dmr903691pfc.42.1613381610391; Mon, 15 Feb 2021 01:33:30 -0800 (PST) Received: from localhost.localdomain ([2406:da14:d1a:ec00:3024:f98c:b881:66b3]) by smtp.gmail.com with ESMTPSA id n1sm17624725pgn.94.2021.02.15.01.33.28 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Feb 2021 01:33:30 -0800 (PST) From: sharpbai To: ffmpeg-devel@ffmpeg.org Date: Mon, 15 Feb 2021 17:33:04 +0800 Message-Id: <20210215093304.33955-1-sharpbai@gmail.com> X-Mailer: git-send-email 2.30.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avcodec/videotoolboxenc: ignore encoded h264 SEI nalu by default 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 Cc: sharpbai Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Before macOS 11, the encoded h264 sample contains fixed SEI before IDR frame, which the content is below 06 05 10 b9 ed b9 30 5d 21 4b 71 83 71 2c 10 a3 14 bb 29 80 The length of the encoded SEI nalu is 20 byte. According to the ITU-T H.264 Recommendation section 7.3.2.3.1, the last byte 0x80 means type. Then there is no length byte, which make the SEI nonstandard. On macOS 11, the encoded h264 sample still contains fixed SEI before IDR frame, which length is 5 bytes longer than before. 06 05 10 b9 ed b9 30 5d 21 4b 71 83 71 2c 10 a3 14 bb 29 80 00 00 03 00 01 ^^ ^^ ^^ ^^ ^^ This time type the content of the SEI has type 0 payload but invalid length payload data, which violates recommendation appendix D. Whether it is a bug or not, these SEI nalus should be erased to keep the output bytestream not violating the standard. But we may not come across the situration we do need these encoded SEI nalu, so we just reserve a switch and set not to output by default. Signed-off-by: sharpbai --- libavcodec/videotoolboxenc.c | 51 +++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c index cc08cf6a50..c240090f10 100644 --- a/libavcodec/videotoolboxenc.c +++ b/libavcodec/videotoolboxenc.c @@ -221,6 +221,7 @@ typedef struct VTEncContext { int64_t allow_sw; int64_t require_sw; + int64_t ignore_internal_sei; bool flushing; bool has_b_frames; @@ -1690,7 +1691,8 @@ static int copy_replace_length_codes( CMSampleBufferRef sample_buffer, ExtraSEI *sei, uint8_t *dst_data, - size_t dst_size) + size_t dst_size, + int ignore_internal_sei) { size_t src_size = CMSampleBufferGetTotalSampleSize(sample_buffer); size_t remaining_src_size = src_size; @@ -1707,8 +1709,8 @@ static int copy_replace_length_codes( } while (remaining_src_size > 0) { - size_t curr_src_len; - size_t curr_dst_len; + size_t curr_src_len = 0; + size_t curr_dst_len = 0; size_t box_len = 0; size_t i; @@ -1740,7 +1742,8 @@ static int copy_replace_length_codes( box_len |= size_buf[i]; } - if (sei && !wrote_sei && is_post_sei_nal_type(nal_type)) { + if (sei && !wrote_sei && + (ignore_internal_sei || is_post_sei_nal_type(nal_type))) { //No SEI NAL unit - insert. int wrote_bytes; @@ -1775,27 +1778,30 @@ static int copy_replace_length_codes( } curr_src_len = box_len + length_code_size; - curr_dst_len = box_len + sizeof(start_code); - if (remaining_src_size < curr_src_len) { - return AVERROR_BUFFER_TOO_SMALL; - } + if (!(ignore_internal_sei && nal_type == H264_NAL_SEI)) { + curr_dst_len = box_len + sizeof(start_code); - if (remaining_dst_size < curr_dst_len) { - return AVERROR_BUFFER_TOO_SMALL; - } + if (remaining_src_size < curr_src_len) { + return AVERROR_BUFFER_TOO_SMALL; + } + + if (remaining_dst_size < curr_dst_len) { + return AVERROR_BUFFER_TOO_SMALL; + } - dst_box = dst_data + sizeof(start_code); + dst_box = dst_data + sizeof(start_code); - memcpy(dst_data, start_code, sizeof(start_code)); - status = CMBlockBufferCopyDataBytes(block, - src_offset + length_code_size, - box_len, - dst_box); + memcpy(dst_data, start_code, sizeof(start_code)); + status = CMBlockBufferCopyDataBytes(block, + src_offset + length_code_size, + box_len, + dst_box); - if (status) { - av_log(avctx, AV_LOG_ERROR, "Cannot copy data: %d\n", status); - return AVERROR_EXTERNAL; + if (status) { + av_log(avctx, AV_LOG_ERROR, "Cannot copy data: %d\n", status); + return AVERROR_EXTERNAL; + } } if (sei && !wrote_sei && nal_type == H264_NAL_SEI) { @@ -1931,7 +1937,8 @@ static int vtenc_cm_to_avpacket( sample_buffer, sei, pkt->data + header_size, - pkt->size - header_size + pkt->size - header_size, + vtctx->ignore_internal_sei ); if (status) { @@ -2543,6 +2550,8 @@ static const enum AVPixelFormat hevc_pix_fmts[] = { { .i64 = 0 }, 0, 1, VE }, \ { "require_sw", "Require software encoding", OFFSET(require_sw), AV_OPT_TYPE_BOOL, \ { .i64 = 0 }, 0, 1, VE }, \ + { "ignore_internal_sei", "Ignore SEI nalu generated by videotoolbox", OFFSET(ignore_internal_sei), AV_OPT_TYPE_BOOL, \ + { .i64 = 1 }, 0, 1, VE }, \ { "realtime", "Hint that encoding should happen in real-time if not faster (e.g. capturing from camera).", \ OFFSET(realtime), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \ { "frames_before", "Other frames will come before the frames in this session. This helps smooth concatenation issues.", \