From patchwork Sun Aug 11 12:47:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moritz Barsnick X-Patchwork-Id: 14406 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 933FB4483B9 for ; Sun, 11 Aug 2019 15:48:38 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8272468ABD0; Sun, 11 Aug 2019 15:48:38 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3832C68ABC1 for ; Sun, 11 Aug 2019 15:48:31 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1565527710; bh=rZG4scP38/joex7vePgZkAU2vNWuDRZeoAV9/vYX2GM=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=Fe/xLORFeHQiKmNjU0alCMjcJCi4EDmUPyZ+AHGdLCxw3EVjE+rXl/d2BvR8GktxQ C5pWqaItCYVPCJ1z73gYLnwlLT1UFmWpnMOeHQC66QWGhhmCeIKgKXIvk2zZ/0Uxs3 U8B80y7n4Raoca6XJzQokMZrRKC7xhlZy6+0sAaM= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from paradise.fritz.box ([89.182.225.44]) by mail.gmx.com (mrgmx003 [212.227.17.190]) with ESMTPSA (Nemesis) id 0MhRUQ-1hbQfE2KbS-00McyY; Sun, 11 Aug 2019 14:48:30 +0200 From: Moritz Barsnick To: FFmpeg development discussions and patches Date: Sun, 11 Aug 2019 14:47:55 +0200 Message-Id: <08b3f8a989581481678dcd0ce5a06105269cdccf.1565527501.git.barsnick@gmx.net> X-Mailer: git-send-email 2.20.1 In-Reply-To: <572abbde623b7857287554aed91b0ea8dc2a437e.1565527501.git.barsnick@gmx.net> References: <26f78761602ecfc977b70a736a2426ab95082e13.1565527501.git.barsnick@gmx.net> <572abbde623b7857287554aed91b0ea8dc2a437e.1565527501.git.barsnick@gmx.net> MIME-Version: 1.0 X-Provags-ID: V03:K1:e23cpsTETOztp2vdGr9OZRT2HpbtCBhcVzoCDF1wOBnz7UdKhBT M0XNxMExsiTy8bJnJbhAuj5s7EV/tNATsc7bmSGeQ1Fkzq/jGzCbggw+m3YPrCcukds+UnX HWIqUyIStjJgHYkoZ77/sW+et261gL2fkuB/V3jqg2O/RXl5L4eoGMnOMLtfJn1zetMLkNM AXBK6TbEEJw/pgsoNFPiA== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1; V03:K0:UWVPSs8CA9Q=:eUWuxsWqls/qq5H2CX2pbh n01mMrp4iSAYov0pnvscAqKOSRJH6TxOFAAzl8Se179lcBU8uGm9S3fMNn+XmPAIQSk6KLdc6 E++IA+ahU2/m1BG2kqKOGXUfKCTND89rUsyV/M5XbgNZLuWNK3h2UtRK2jko0M4AUupVwgNDi Ctl+CZhRpbfQgaeH+pZlTcSuq6X3K276g3ju9twXpP9sgoNmo3uvXv/jc643LU/W8od7o6qm0 AKl+KDLRLnbIStDfs9dwKv0qz0LG6A+ijCF4E/5//ERdKrbNBMB1JXLNLY6+7tMwV8kFyT9NZ fz7SdoF5cPmZgAeL/pksK+CdtisLlN9vyPNVRTjefSYw9hL9Ymsj6VNwkEqJl4woyIvlcsLv/ zZNE8aS/N2wNKprTkj9awAG3Lclg+u542FFOW8C2vE8lp+geJYFC7ld25848Y1jS3PX/DygVV vW3U9TtsSPyUMcP3OwhBd8T1w+ty9lpZtuKgIOTqNSeHqolPTUzF5MiQoV5rvbIwZ++rcFndG gNo/5GjSGko2V8px6OcGsIQAbTaY3IzDKbEk+dnJD+molOcLLD8I0K7SApid55v5HNj4LB604 2jm/nEHiiZ24LdQjridlMqGR/960uj7b8Sq/xnLfn662Ykqx+QLMEAlY35Cu12Z4di8dPpa3Z Rlznd/VhdRyjIY74zmNwBQz+YH2si47FELaqnbc+LyPfFdeU47zJ3Wa3v6sk/1QoZ5G+9XWUQ 6WJdSW2BzbhrmK5QuatmaZLalza0hKJTkqCk3qz3u8Xcy/3gWok0JEqu7Lx35JpRXc31JsZNS SJyuTdaP9JsrM+njq8VkgzsfyMax4Wa3//2SW1YgrZfgqSsK01kh9XFy+aGvFr8WLlk8ESlY3 U75GzURyrBq1xAwK4+nJp+++zSHRsgTizFiLo3qx2zgq+KoBaxBr2K+j+ycEHAAVS5HI+slRT pgYv4dTJKzRXZno73ekpwm6zd4ySrppWdbXy/TCF/9hoH9r/cregMGUZl+tWrlex/5yY0vR9M pxpnXCDQuK4s7nQg1yqSLRRsemAVE872EP+R76lAB4AZMjB5L96/wsl8lC0t/lTqFoVLHk7Yv hfWGOCW0g1mCASMTLhygn+a5M+dujrLvLJtSEXf1MA+KDZAc74XFJH1ag== Subject: [FFmpeg-devel] [PATCH 3/4] avformat/hashenc: add option to create hash per stream 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: Moritz Barsnick Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Non-frame based muxers only, the frame based ones are already per stream. Signed-off-by: Moritz Barsnick --- doc/muxers.texi | 5 +++++ libavformat/hashenc.c | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 12 deletions(-) -- 2.20.1 diff --git a/doc/muxers.texi b/doc/muxers.texi index bc38cf6029..34ca7f07cb 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -511,6 +511,11 @@ Supported values include @code{MD5}, @code{murmur3}, @code{RIPEMD128}, @code{SHA224}, @code{SHA256} (default), @code{SHA512/224}, @code{SHA512/256}, @code{SHA384}, @code{SHA512}, @code{CRC32} and @code{adler32}. +@item per_stream @var{bool} +Whether to calculate a hash per stream, instead of combined over all +packets' payload. Each stream's hash is prefixed with its stream index. +Default is @code{false}. + @end table @subsection Examples diff --git a/libavformat/hashenc.c b/libavformat/hashenc.c index 96e00f580c..394b8a0fce 100644 --- a/libavformat/hashenc.c +++ b/libavformat/hashenc.c @@ -31,6 +31,7 @@ struct HashContext { const AVClass *avclass; struct AVHashContext **hashes; char *hash_name; + int per_stream; int format_version; }; @@ -40,10 +41,13 @@ struct HashContext { { "hash", "set hash to use", OFFSET(hash_name), AV_OPT_TYPE_STRING, {.str = defaulttype}, 0, 0, ENC } #define FORMAT_VERSION_OPT \ { "format_version", "file format version", OFFSET(format_version), AV_OPT_TYPE_INT, {.i64 = 2}, 1, 2, ENC } +#define PER_STREAM_OPT \ + { "per_stream", "whether to calculate a hash per stream", OFFSET(per_stream), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, ENC } #if CONFIG_HASH_MUXER static const AVOption hash_options[] = { HASH_OPT("sha256"), + PER_STREAM_OPT, { NULL }, }; #endif @@ -59,6 +63,7 @@ static const AVOption framehash_options[] = { #if CONFIG_MD5_MUXER static const AVOption md5_options[] = { HASH_OPT("md5"), + PER_STREAM_OPT, { NULL }, }; #endif @@ -74,39 +79,51 @@ static const AVOption framemd5_options[] = { #if CONFIG_HASH_MUXER || CONFIG_MD5_MUXER static int hash_write_header(struct AVFormatContext *s) { - int res; + int i, res; struct HashContext *c = s->priv_data; - c->hashes = av_malloc_array(1, sizeof(c->hashes)); + int num_hashes = c->per_stream ? s->nb_streams : 1; + c->hashes = av_malloc_array(num_hashes, sizeof(c->hashes)); if (!c->hashes) return AVERROR(ENOMEM); - res = av_hash_alloc(&c->hashes[0], c->hash_name); - if (res < 0) { - av_freep(&c->hashes); - return res; + for (i = 0; i < num_hashes; i++) { + res = av_hash_alloc(&c->hashes[i], c->hash_name); + if (res < 0) + goto err; + av_hash_init(c->hashes[i]); } - av_hash_init(c->hashes[0]); return 0; +err: + for (int j = 0; j < i; j++) + av_hash_freep(&c->hashes[j]); + av_freep(&c->hashes); + return res; } static int hash_write_packet(struct AVFormatContext *s, AVPacket *pkt) { struct HashContext *c = s->priv_data; - av_hash_update(c->hashes[0], pkt->data, pkt->size); + av_hash_update(c->hashes[c->per_stream ? pkt->stream_index : 0], pkt->data, pkt->size); return 0; } static int hash_write_trailer(struct AVFormatContext *s) { struct HashContext *c = s->priv_data; + int num_hashes = c->per_stream ? s->nb_streams : 1; + for (int i = 0; i < num_hashes; i++) { char buf[AV_HASH_MAX_SIZE*2+128]; - snprintf(buf, sizeof(buf) - 200, "%s=", av_hash_get_name(c->hashes[0])); - - av_hash_final_hex(c->hashes[0], buf + strlen(buf), sizeof(buf) - strlen(buf)); + if (c->per_stream) { + snprintf(buf, sizeof(buf) - 200, "%d,%s=", i, av_hash_get_name(c->hashes[i])); + } else { + snprintf(buf, sizeof(buf) - 200, "%s=", av_hash_get_name(c->hashes[i])); + } + av_hash_final_hex(c->hashes[i], buf + strlen(buf), sizeof(buf) - strlen(buf)); av_strlcatf(buf, sizeof(buf), "\n"); avio_write(s->pb, buf, strlen(buf)); avio_flush(s->pb); - av_hash_freep(&c->hashes[0]); + av_hash_freep(&c->hashes[i]); + } av_freep(&c->hashes); return 0; }