From patchwork Wed Jun 24 13:43:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Wang X-Patchwork-Id: 20574 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 BFA2C44AEEF for ; Wed, 24 Jun 2020 16:44:21 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A31D868B58A; Wed, 24 Jun 2020 16:44:21 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f173.google.com (mail-pf1-f173.google.com [209.85.210.173]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3152D68B100 for ; Wed, 24 Jun 2020 16:44:13 +0300 (EEST) Received: by mail-pf1-f173.google.com with SMTP id a127so1171736pfa.12 for ; Wed, 24 Jun 2020 06:44:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3juGMTKDkFYDeDXHLr7vLpsD+CR+W4qJD3qoCTSK/Fg=; b=PlUsLUiuWfoRLCYJfmaZ7X8sQ/uvlXNOOKiKUJ7Wv/kCvy7iPHdJGxMwyXPZbeaMiV UmrNLUusV94KJBmpb+5Ll1YDH691CGEOiYXt9MwE3iUmEl17b4eRuhl9wckLeSnLbOKi 9lDVn8OCv8Dg/2Xh0eNri6sY7uL4fnpICpSilOMmi611KFHw9AXHJUeSuX97PEUWaQCs UNZkzAS1XOdn9AEc/N3seqmD+AGW6MD2hD6ZefT/iKSLlZKxRhTO6fKsV2XDfpa3QnmT TZMx68VIm565bk5TtlXTEW+PRndk2kWyOzdpt8V1hxIrEkxPKwfX2L+GNh2RjS+buAlc LSlg== 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:in-reply-to :references; bh=3juGMTKDkFYDeDXHLr7vLpsD+CR+W4qJD3qoCTSK/Fg=; b=o8l6O8e2qx+VJBmbkqHBZLgaPsTCEojU2rZb6BKa8U0NXVcS9NP+KpxLMz6U5WPVAT OmFNy7gCayZt+k9pTnZD/2uLAzkFBSj+MWvFzDCCTvyfBBDcV9Pjut9RmnbgH2sjK6Gd 3NzUYKpfgYOs2lHWsxlhHd1ZCjJbf/MwISmrZlwlpImWScWsgys41e9l8DhRGaSAGUnP kXSzGv8hBFw/t9ST7FPj1fXoUipOWi3odRHiP3IzduQh2gTTHwG1pMwWc6sAYvGxATdb t/C9weNZGVyLqXHSSOVOW9KD7HoE85IZvRK0bWzIYEM0foAivWKxReX8yG8fpsFwLbt+ v8MA== X-Gm-Message-State: AOAM533kfr9enflk8S9qUgWvvHUDo+hG4EjHBFgGkA8Bff+aUQhUqEUf 51pntSBO6lUPIcOA5BC6YlsXKoG3 X-Google-Smtp-Source: ABdhPJywJfriiJ0xy/zPbj4HRj4/WOJtKv6gpLA1TMZdonmBOFpIqWPEf0zXOmeM8b72URLC+5+DIA== X-Received: by 2002:a63:5509:: with SMTP id j9mr15020376pgb.195.1593006251069; Wed, 24 Jun 2020 06:44:11 -0700 (PDT) Received: from vpn2.localdomain ([161.117.202.209]) by smtp.gmail.com with ESMTPSA id z144sm21622329pfc.195.2020.06.24.06.44.09 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Jun 2020 06:44:10 -0700 (PDT) From: lance.lmwang@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Wed, 24 Jun 2020 21:43:19 +0800 Message-Id: <1593006200-23911-6-git-send-email-lance.lmwang@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1593006200-23911-1-git-send-email-lance.lmwang@gmail.com> References: <1592410030-6553-1-git-send-email-lance.lmwang@gmail.com> <1593006200-23911-1-git-send-email-lance.lmwang@gmail.com> Subject: [FFmpeg-devel] [PATCH v4 6/7] avcodec/utils: add ff_alloc_timecode_sei() for hevc timecode sei 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: Limin Wang MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Limin Wang Signed-off-by: Limin Wang --- libavcodec/internal.h | 15 ++++++++++++ libavcodec/utils.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 21708df..8771078 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -380,6 +380,21 @@ int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, void **data, size_t *sei_size); /** + * Check AVFrame for S12M timecode side data and allocate and fill TC SEI message with timecode info + * + * @param frame Raw frame to get S12M timecode side data from + * @param prefix_len Number of bytes to allocate before SEI message + * @param data Pointer to a variable to store allocated memory + * Upon return the variable will hold NULL on error or if frame has no S12M timecode info. + * Otherwise it will point to prefix_len uninitialized bytes followed by + * *sei_size SEI message + * @param sei_size Pointer to a variable to store generated SEI message length + * @return Zero on success, negative error code on failure + */ +int ff_alloc_timecode_sei(const AVFrame *frame, size_t prefix_len, + void **data, size_t *sei_size); + +/** * Get an estimated video bitrate based on frame size, frame rate and coded * bits per pixel. */ diff --git a/libavcodec/utils.c b/libavcodec/utils.c index b61f274..2ece34f 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -50,6 +50,7 @@ #include "thread.h" #include "frame_thread_encoder.h" #include "internal.h" +#include "put_bits.h" #include "raw.h" #include "bytestream.h" #include "version.h" @@ -2244,6 +2245,68 @@ int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, return 0; } +static unsigned bcd2uint(uint8_t bcd) +{ + unsigned low = bcd & 0xf; + unsigned high = bcd >> 4; + if (low > 9 || high > 9) + return 0; + return low + 10*high; +} + +int ff_alloc_timecode_sei(const AVFrame *frame, size_t prefix_len, + void **data, size_t *sei_size) +{ + AVFrameSideData *sd = NULL; + uint8_t *sei_data; + PutBitContext pb; + uint32_t *tc; + int m; + + if (frame) + sd = av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE); + + if (!sd) { + *data = NULL; + return 0; + } + tc = (uint32_t*)sd->data; + m = tc[0] & 3; + + *sei_size = sizeof(uint32_t) * 4; + *data = av_mallocz(*sei_size + prefix_len); + if (!*data) + return AVERROR(ENOMEM); + sei_data = (uint8_t*)*data + prefix_len; + + init_put_bits(&pb, sei_data, *sei_size); + put_bits(&pb, 2, m); // num_clock_ts + + for (int j = 1; j <= m; j++) { + uint32_t tcsmpte = tc[j]; + unsigned hh = bcd2uint(tcsmpte & 0x3f); // 6-bit hours + unsigned mm = bcd2uint(tcsmpte>>8 & 0x7f); // 7-bit minutes + unsigned ss = bcd2uint(tcsmpte>>16 & 0x7f); // 7-bit seconds + unsigned ff = bcd2uint(tcsmpte>>24 & 0x3f); // 6-bit frames + unsigned drop = tcsmpte & 1<<30 && !0; // 1-bit drop if not arbitrary bit + + put_bits(&pb, 1, 1); // clock_timestamp_flag + put_bits(&pb, 1, 1); // units_field_based_flag + put_bits(&pb, 5, 0); // counting_type + put_bits(&pb, 1, 1); // full_timestamp_flag + put_bits(&pb, 1, 0); // discontinuity_flag + put_bits(&pb, 1, drop); + put_bits(&pb, 9, ff); + put_bits(&pb, 6, ss); + put_bits(&pb, 6, mm); + put_bits(&pb, 5, hh); + put_bits(&pb, 5, 0); + } + flush_put_bits(&pb); + + return 0; +} + int64_t ff_guess_coded_bitrate(AVCodecContext *avctx) { AVRational framerate = avctx->framerate;