From patchwork Sat Feb 4 00:41:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aman Karmani X-Patchwork-Id: 40239 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:5494:b0:bf:7b3a:fd32 with SMTP id i20csp1616987pzk; Fri, 3 Feb 2023 16:42:21 -0800 (PST) X-Google-Smtp-Source: AK7set+hl5B7/xV9cglEw6s59gCQxCQyVUys818dcP/v3bOdS0Io2RMhmhZ5d12gC76VY9bjTyXm X-Received: by 2002:a17:906:9c8d:b0:878:78bc:975c with SMTP id fj13-20020a1709069c8d00b0087878bc975cmr10733367ejc.36.1675471341370; Fri, 03 Feb 2023 16:42:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675471341; cv=none; d=google.com; s=arc-20160816; b=w83GWsZvdSenCLxfto5ZhaNdLVxWPU1khZmsUPxR6OCkOMKB5l18z/0V8sObTYqVlh 98iPqWy1HsiC2+C07ukyX4p9GXU29/xRoZ1SDz82fqj5rc9XsnC+M+1bEaESy0hLKye0 wOb/EF8ypnTE1U/cIPZ4FhIj/SyyRfDiyFrveVnlV3sTDGlIseFaFxhMf2A6VcHCvqdU MTwA4ftVCWjqR2t2j7KfQNCSQCLfoWE5LuUZIbZqGWB+0bc/qaIyOp9hZAqFqz3GwDBH oXucxDKqwIvmS7Av/sqxuZW+tp3VvXUPCquYs0g9SfjciisO7Drz/zLSCUeaY+eBbRqe rTfA== 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:to:mime-version:fcc:date:references :in-reply-to:message-id:from:dkim-signature:delivered-to; bh=mZ0yQHNJOawrgLLYMsBkB4OHIrB+//6S+xz6Mzu8Wqg=; b=LjdIQbOvHGADg9FllfKXlScOtFDZGF69x2JljTBZRwBRwxLJoFyPjnAnN+W3qgyjWZ 1O0xfIjPsWO/CZ69IjmropqKNP1p0bKg10Go9G2lT2zYEBa+iwfb6ha/nALzXiRiJxAw ezYaDzlAjs2wlJ2pz2gZQWF2Opm5+QArpqKffdCRpXIs0dZh5yXSwANyZjtHzxC2RA4h JDOw2d10H6wVteG8u/2p9MRXfRjRaGsYKlR5k+D+GO43+HGAHWbMIRnmDqQsJL5z1Pcf ugTq9gc5QGRjUMKkAHOhh3c9/3szUGDmXDnjMiuGqv6D6TwFxc2+Jxmf/OnJCjJi4Cd1 soTg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=ZRdF24wy; 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 j9-20020a170906104900b0088a161c2342si5343459ejj.192.2023.02.03.16.42.21; Fri, 03 Feb 2023 16:42:21 -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; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=ZRdF24wy; 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 E791768BE88; Sat, 4 Feb 2023 02:42:06 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pj1-f48.google.com (mail-pj1-f48.google.com [209.85.216.48]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CCEAE68BC53 for ; Sat, 4 Feb 2023 02:41:59 +0200 (EET) Received: by mail-pj1-f48.google.com with SMTP id nm12-20020a17090b19cc00b0022c2155cc0bso6452653pjb.4 for ; Fri, 03 Feb 2023 16:41:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date :references:in-reply-to:message-id:from:from:to:cc:subject:date :message-id:reply-to; bh=3R+UpWpyPt3/kwa9pCa5gPZIcV7gSjTdcwTllCOEiyo=; b=ZRdF24wyk4FDvJyPVqxWLTVu0qRtRsuJuU3WGuU3EyLCLPtk3QySOcXKb04Pqmu9uV BhpTTUDvSk0dIJJ7BPZ3prj3mq9NKN1cWJyvYcpSzD+mz7ohERyrZBiGrGki3A4eL4PE iysgZGnV3QF/oatSwfOq/JAlpRTQmfTJ1TMUV+Hxb/R1tTm4Eys8DrL2HOyJm0FrhKFX U6JCAziNgA3ZuzwD0ggpK2ekTgugtSjXote3UBuDxBekeqrqc5niIeP/X21c5qo8Xiax ItKcU16VJDIdNlOlvLzPLhjhgKXPBVS8vkCLBMkAP/xfAOiBzIPsrUEo/wOVC8i8uRy4 vdnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date :references:in-reply-to:message-id:from:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=3R+UpWpyPt3/kwa9pCa5gPZIcV7gSjTdcwTllCOEiyo=; b=JucOP8wOvmrZbKqsLniN0akeX5V53dqhvlP1JJ2l8VLDl/9cVhzr6bjhbT+LpEXlto qY7SARjebwmCZg59XhwX6XBEUiXW+JKc/3Qgu5PoY2v59Udu775fots37XeB/nMSITGF B3j8Eag6devr+xFxu1ch+JOioP1IHDM982pAezKaUPSklKpLSbaUACfsiOPmLuan02tO F6hsRHuzk4KnRsscTAIJ3RBiQu46c3ULsynYhFVc1xYYCsiY7vUmSe3CpD0usGqznC6j THVzr8XSn8Dy+XFHGemA1DrnDy/h6hs1B1oIx3XyCh4vKjRzso8y3NBmBezyCItR9fpo uDyQ== X-Gm-Message-State: AO0yUKXz5S63OfnLuyhQXklQfkdZ6695z3SqbTwukQsrG6M2FfWMnhJD 7ymHzQ0rubzCNQDXdXF9EXrQfyLm6PM= X-Received: by 2002:a17:902:db12:b0:198:f13d:1208 with SMTP id m18-20020a170902db1200b00198f13d1208mr688114plx.61.1675471317662; Fri, 03 Feb 2023 16:41:57 -0800 (PST) Received: from [127.0.0.1] (master.gitmailbox.com. [34.83.118.50]) by smtp.gmail.com with ESMTPSA id u13-20020aa7848d000000b00593ce42db6bsm2434757pfn.59.2023.02.03.16.41.57 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Feb 2023 16:41:57 -0800 (PST) From: Mark Thompson X-Google-Original-From: Mark Thompson Message-Id: <9a539e4caab098bc69af9ec30d19608372e3ddd6.1675471315.git.ffmpegagent@gmail.com> In-Reply-To: References: Date: Sat, 04 Feb 2023 00:41:51 +0000 Fcc: Sent MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH 1/5] cbs: Add some common code for read/write of miscellaneous user data 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: Mark Thompson , Aman Gupta Karmani Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 5wK+oc8B7dPB From: Mark Thompson Supports closed captions, active format and bar data as defined by SCTE 128 part 1 or A/53 part 4, suitable for use with both MPEG-2 and H.264. Signed-off-by: Aman Karmani --- libavcodec/cbs_misc.c | 217 ++++++++++++++++++++++++++ libavcodec/cbs_misc.h | 109 +++++++++++++ libavcodec/cbs_misc_syntax_template.c | 150 ++++++++++++++++++ 3 files changed, 476 insertions(+) create mode 100644 libavcodec/cbs_misc.c create mode 100644 libavcodec/cbs_misc.h create mode 100644 libavcodec/cbs_misc_syntax_template.c diff --git a/libavcodec/cbs_misc.c b/libavcodec/cbs_misc.c new file mode 100644 index 0000000000..d0ced562f5 --- /dev/null +++ b/libavcodec/cbs_misc.c @@ -0,0 +1,217 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" + +#include "cbs.h" +#include "cbs_internal.h" +#include "cbs_misc.h" + +#define CHECK(call) do { \ + err = (call); \ + if (err < 0) \ + return err; \ + } while (0) + +#define FUNC_NAME(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name +#define FUNC_MISC(rw, name) FUNC_NAME(rw, misc, name) +#define FUNC(name) FUNC_MISC(READWRITE, name) + + +#define READWRITE read +#define RWContext GetBitContext + +#define xui(width, name, var) do { \ + uint32_t value = 0; \ + CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, NULL, \ + &value, 0, MAX_UINT_BITS(width))); \ + var = value; \ + } while (0) + +#define ui(width, name) \ + xui(width, name, current->name) + +#define fixed(width, name, expected) do { \ + av_unused uint32_t value; \ + CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, NULL, \ + &value, expected, expected)); \ + } while (0) + +#include "cbs_misc_syntax_template.c" + +#undef READWRITE +#undef RWContext +#undef xui +#undef ui +#undef fixed + + +#define READWRITE write +#define RWContext PutBitContext + +#define xui(width, name, var) do { \ + CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, NULL, \ + var, 0, MAX_UINT_BITS(width))); \ + } while (0) + +#define ui(width, name) \ + xui(width, name, current->name) + +#define fixed(width, name, value) do { \ + CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, NULL, \ + value, value, value)); \ + } while (0) + +#include "cbs_misc_syntax_template.c" + +#undef READWRITE +#undef RWContext +#undef xui +#undef ui +#undef fixed + + +int ff_cbs_read_a53_user_data(CodedBitstreamContext *ctx, + A53UserData *data, + const uint8_t *read_buffer, size_t length) +{ + GetBitContext gbc; + int err; + + err = init_get_bits(&gbc, read_buffer, 8 * length); + if (err < 0) + return err; + + return cbs_misc_read_a53_user_data(ctx, &gbc, data); +} + +int ff_cbs_write_a53_user_data(CodedBitstreamContext *ctx, + uint8_t *write_buffer, size_t *length, + A53UserData *data) +{ + PutBitContext pbc; + int err; + + init_put_bits(&pbc, write_buffer, *length); + + err = cbs_misc_write_a53_user_data(ctx, &pbc, data); + if (err < 0) { + // Includes AVERROR(ENOSPC). + return err; + } + + // That output must be aligned. + av_assert0(put_bits_count(&pbc) % 8 == 0); + + *length = put_bits_count(&pbc) / 8; + + flush_put_bits(&pbc); + + return 0; +} + +int ff_cbs_read_a53_cc_side_data(CodedBitstreamContext *ctx, + A53UserData *data, + const uint8_t *side_data, + size_t side_data_size) +{ + GetBitContext gbc; + CEA708CCData *cc; + int err, i, cc_count; + + if (side_data_size % 3) { + av_log(ctx->log_ctx, AV_LOG_ERROR, "A53 CC side data length must " + "be a multiple of 3 (got %zu).\n", side_data_size); + return AVERROR(EINVAL); + } + cc_count = side_data_size / 3; + if (cc_count > 31) { + av_log(ctx->log_ctx, AV_LOG_ERROR, "A53 CC can only fit 31 packets " + "in a single user data block (got %d).\n", cc_count); + return AVERROR(EINVAL); + } + + *data = (A53UserData) { + .user_identifier = A53_USER_IDENTIFIER_ATSC, + + .atsc = { + .user_data_type_code = A53_USER_DATA_TYPE_CODE_CC_DATA, + + .cc_data = { + .process_em_data_flag = 0, + .process_cc_data_flag = 1, + .additional_data_flag = 0, + + .em_data = 0, + + .cc_count = cc_count, + }, + }, + }; + cc = &data->atsc.cc_data; + + err = init_get_bits(&gbc, side_data, 8 * side_data_size); + if (err < 0) + return err; + + for (i = 0; i < cc->cc_count; i++) { + err = cbs_misc_read_cea708_cc_data_packet(ctx, &gbc, + &cc->cc_data_pkts[i]); + if (err < 0) + return err; + } + + return 0; +} + +int ff_cbs_write_a53_cc_side_data(CodedBitstreamContext *ctx, + uint8_t **side_data, + size_t *side_data_size, + A53UserData *data) +{ + PutBitContext pbc; + CEA708CCData *cc; + int err, i; + + if (data->user_identifier != A53_USER_IDENTIFIER_ATSC || + data->atsc.user_data_type_code != A53_USER_DATA_TYPE_CODE_CC_DATA) + return AVERROR(EINVAL); + + cc = &data->atsc.cc_data; + + err = av_reallocp(side_data, *side_data_size + 3 * cc->cc_count); + if (err < 0) + return err; + + init_put_bits(&pbc, *side_data + *side_data_size, 3 * cc->cc_count); + + for (i = 0; i < cc->cc_count; i++) { + err = cbs_misc_write_cea708_cc_data_packet(ctx, &pbc, + &cc->cc_data_pkts[i]); + if (err < 0) { + av_freep(side_data); + return err; + } + } + + flush_put_bits(&pbc); + *side_data_size += 3 * cc->cc_count; + + return 0; +} diff --git a/libavcodec/cbs_misc.h b/libavcodec/cbs_misc.h new file mode 100644 index 0000000000..0d7ab2c8e7 --- /dev/null +++ b/libavcodec/cbs_misc.h @@ -0,0 +1,109 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_CBS_MISC_H +#define AVCODEC_CBS_MISC_H + +#include +#include + +#include "libavutil/common.h" + + +enum { + A53_USER_IDENTIFIER_ATSC = MKBETAG('G', 'A', '9', '4'), + A53_USER_IDENTIFIER_AFD = MKBETAG('D', 'T', 'G', '1'), +}; + +enum { + A53_USER_DATA_TYPE_CODE_CC_DATA = 0x03, + A53_USER_DATA_TYPE_CODE_BAR_DATA = 0x06, +}; + +typedef struct A53BarData { + uint8_t top_bar_flag; + uint8_t bottom_bar_flag; + uint8_t left_bar_flag; + uint8_t right_bar_flag; + + uint16_t line_number_end_of_top_bar; + uint16_t line_number_end_of_bottom_bar; + uint16_t line_number_end_of_left_bar; + uint16_t line_number_end_of_right_bar; +} A53BarData; + +typedef struct CEA708CCDataPacket { + uint8_t cc_valid; + uint8_t cc_type; + uint8_t cc_data_1; + uint8_t cc_data_2; +} CEA708CCDataPacket; + +typedef struct CEA708CCData { + uint8_t process_em_data_flag; + uint8_t process_cc_data_flag; + uint8_t additional_data_flag; + + uint8_t em_data; + + uint8_t cc_count; + CEA708CCDataPacket cc_data_pkts[31]; +} CEA708CCData; + +typedef struct A53ATSCUserData { + uint8_t user_data_type_code; + union { + CEA708CCData cc_data; + A53BarData bar_data; + }; +} A53ATSCUserData; + +typedef struct A53AFDData { + uint8_t active_format_flag; + uint8_t active_format; +} A53AFDData; + +typedef struct A53UserData { + uint32_t user_identifier; + union { + A53ATSCUserData atsc; + A53AFDData afd; + }; +} A53UserData; + + +int ff_cbs_read_a53_user_data(CodedBitstreamContext *ctx, + A53UserData *data, + const uint8_t *read_buffer, size_t length); + +int ff_cbs_write_a53_user_data(CodedBitstreamContext *ctx, + uint8_t *write_buffer, size_t *length, + A53UserData *data); + +int ff_cbs_read_a53_cc_side_data(CodedBitstreamContext *ctx, + A53UserData *data, + const uint8_t *side_data, + size_t side_data_size); + +int ff_cbs_write_a53_cc_side_data(CodedBitstreamContext *ctx, + uint8_t **side_data, + size_t *side_data_length, + A53UserData *data); + + +#endif /* AVCODEC_CBS_MISC_H */ diff --git a/libavcodec/cbs_misc_syntax_template.c b/libavcodec/cbs_misc_syntax_template.c new file mode 100644 index 0000000000..7b98c7cc85 --- /dev/null +++ b/libavcodec/cbs_misc_syntax_template.c @@ -0,0 +1,150 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static int FUNC(a53_bar_data)(CodedBitstreamContext *ctx, RWContext *rw, + A53BarData *current) +{ + int err; + + ui(1, top_bar_flag); + ui(1, bottom_bar_flag); + ui(1, left_bar_flag); + ui(1, right_bar_flag); + fixed(4, reserved, 0xf); + + if (current->top_bar_flag) { + fixed(2, one_bits, 3); + ui(14, line_number_end_of_top_bar); + } + if (current->bottom_bar_flag) { + fixed(2, one_bits, 3); + ui(14, line_number_end_of_bottom_bar); + } + if (current->left_bar_flag) { + fixed(2, one_bits, 3); + ui(14, line_number_end_of_left_bar); + } + if (current->right_bar_flag) { + fixed(2, one_bits, 3); + ui(14, line_number_end_of_right_bar); + } + + return 0; +} + +static int FUNC(cea708_cc_data_packet)(CodedBitstreamContext *ctx, + RWContext *rw, + CEA708CCDataPacket *current) +{ + int err; + + fixed(5, marker_bits, 0x1f); + ui(1, cc_valid); + ui(2, cc_type); + + ui(8, cc_data_1); + ui(8, cc_data_2); + + return 0; +} + +static int FUNC(cea708_cc_data)(CodedBitstreamContext *ctx, RWContext *rw, + CEA708CCData *current) +{ + int err, i; + + ui(1, process_em_data_flag); + ui(1, process_cc_data_flag); + ui(1, additional_data_flag); + + ui(5, cc_count); + + ui(8, em_data); + + for (i = 0; i < current->cc_count; i++) { + CHECK(FUNC(cea708_cc_data_packet)(ctx, rw, + ¤t->cc_data_pkts[i])); + } + + fixed(8, marker_bits, 0xff); + + if (current->additional_data_flag) { + // Ignored. + } + + return 0; +} + +static int FUNC(a53_atsc_user_data)(CodedBitstreamContext *ctx, RWContext *rw, + A53ATSCUserData *current) +{ + int err; + + ui(8, user_data_type_code); + + switch (current->user_data_type_code) { + case A53_USER_DATA_TYPE_CODE_CC_DATA: + return FUNC(cea708_cc_data)(ctx, rw, ¤t->cc_data); + case A53_USER_DATA_TYPE_CODE_BAR_DATA: + return FUNC(a53_bar_data)(ctx, rw, ¤t->bar_data); + default: + av_log(ctx->log_ctx, AV_LOG_WARNING, + "Unknown ATSC user data found: type code %#02x.\n", + current->user_data_type_code); + } + + return 0; +} + +static int FUNC(a53_afd_data)(CodedBitstreamContext *ctx, RWContext *rw, + A53AFDData *current) +{ + int err; + + fixed(1, zero_bit, 0); + ui(1, active_format_flag); + fixed(6, alignment_bits, 1); + + if (current->active_format_flag) { + fixed(4, reserved, 0xf); + ui(4, active_format); + } + + return 0; +} + +static int FUNC(a53_user_data)(CodedBitstreamContext *ctx, RWContext *rw, + A53UserData *current) +{ + int err; + + ui(32, user_identifier); + + switch (current->user_identifier) { + case A53_USER_IDENTIFIER_ATSC: + return FUNC(a53_atsc_user_data)(ctx, rw, ¤t->atsc); + case A53_USER_IDENTIFIER_AFD: + return FUNC(a53_afd_data)(ctx, rw, ¤t->afd); + default: + av_log(ctx->log_ctx, AV_LOG_WARNING, + "Unknown registered user data found: identifier %#08x.\n", + current->user_identifier); + } + + return 0; +}