From patchwork Sun Apr 30 15:33:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 3517 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.3.129 with SMTP id 123csp1077692vsd; Sun, 30 Apr 2017 08:40:43 -0700 (PDT) X-Received: by 10.223.165.14 with SMTP id i14mr10878308wrb.127.1493566843879; Sun, 30 Apr 2017 08:40:43 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 30si11762386wrg.187.2017.04.30.08.40.43; Sun, 30 Apr 2017 08:40:43 -0700 (PDT) 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; 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=NONE 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 0AADB68981A; Sun, 30 Apr 2017 18:40:37 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt0-f196.google.com (mail-qt0-f196.google.com [209.85.216.196]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 58C46689211 for ; Sun, 30 Apr 2017 18:40:30 +0300 (EEST) Received: by mail-qt0-f196.google.com with SMTP id t52so14167564qtb.3 for ; Sun, 30 Apr 2017 08:40:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=6YTTWjmjr6lFHYe/xfCS7RLrUO6X3Xswn81B75LezQ4=; b=qE2pyVn0YSaLdYVA1yNoGugmkFxXouk1gbaPceZo9Dc99J9VYgZyDjGa2GyJWqajRh qUMfYJmKXWRV3QJG13sl+mOFMW/P8UqvaviyHq4PZoDcgO04Mk/kjOFR0YkroN7KIRHi WweKLyfFCoI7a+48Y2mXN9okOa0+1Bbe00PpfmUAWIn9c7WPnaWybbULP3uQgV5J21L2 4d5vTVgjUc309u3RYed2mpY91zTbEZt/As6fKFvPpu5dZwAjsFdh50oGA/taQkFIvrTC F8xWztsXCgCBCunfkNpGcVnWPpI24UN0LDpoLVAt7LkfZI/XBHKXdfZ04z4V8W0NucgO n0rQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=6YTTWjmjr6lFHYe/xfCS7RLrUO6X3Xswn81B75LezQ4=; b=GR6IXn9RepEJ6IgAH2YCZTxQJioMgVuJ5i7wpl/WB8ZEGT+OGeccEcQeufLDVwBhJW tgYwwrlJxP02iJAkjm5Tix/9k844k7NdSYwbTFJhtwQEZFo7p1gIy0AuWy8H7sjWyb3s S0f8Tceg7rAjn5H6uwsSk+oKlCQ2LaeIJrIDxHH7Wb/DDc8Ga+c+7OqVONBEs+ccNa4n T7lLr8i2JzTvSo6oJLycEplSxIXiWiVnwhe27sNiAjKaXRtVc6Lym+0uJe4P2hIY5wXF mDaEx5TPcMK6cpdicyKoWUbYcUu87RKisqox6BSZySPvhJioa8tHLj67jhven5iUjK77 bWXg== X-Gm-Message-State: AN3rC/5uu9uj+u2RDfwSN451EnlraNzUh+8eDBXgaytaK/W6fwE7xalv wpgL4AD/AEMMx+dR X-Received: by 10.200.40.246 with SMTP id j51mr20362980qtj.58.1493566422717; Sun, 30 Apr 2017 08:33:42 -0700 (PDT) Received: from localhost.localdomain ([181.231.62.139]) by smtp.gmail.com with ESMTPSA id u8sm8251979qtb.55.2017.04.30.08.33.41 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 30 Apr 2017 08:33:42 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Sun, 30 Apr 2017 12:33:14 -0300 Message-Id: <20170430153315.6272-1-jamrial@gmail.com> X-Mailer: git-send-email 2.12.1 Subject: [FFmpeg-devel] [PATCH 1/2] hevcdec: remove HEVCContext usage from hevc_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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: James Almer --- libavcodec/hevc_parser.c | 9 +-- libavcodec/hevc_refs.c | 4 +- libavcodec/hevc_sei.c | 154 +++++++++++++++++++++++------------------------ libavcodec/hevcdec.c | 90 +++++++++++++-------------- libavcodec/hevcdec.h | 95 +++++++++++++++++------------ 5 files changed, 187 insertions(+), 165 deletions(-) diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index 310428d0ff..f82f9fdf5e 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -192,6 +192,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, GetBitContext *gb; SliceHeader *sh = &h->sh; HEVCParamSets *ps = &h->ps; + HEVCSEIContext *sei = &h->sei; H2645Packet *pkt = &ctx->pkt; const uint8_t *buf_end = buf + buf_size; int state = -1, i; @@ -212,7 +213,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, h->avctx = avctx; - ff_hevc_reset_sei(h); + ff_hevc_reset_sei(sei); if (!buf_size) return 0; @@ -265,7 +266,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, break; case HEVC_NAL_SEI_PREFIX: case HEVC_NAL_SEI_SUFFIX: - ff_hevc_decode_nal_sei(h); + ff_hevc_decode_nal_sei(gb, avctx, sei, ps, h->nal_unit_type); break; case HEVC_NAL_TRAIL_N: case HEVC_NAL_TRAIL_R: @@ -290,8 +291,8 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, } sh->first_slice_in_pic_flag = get_bits1(gb); - s->picture_structure = h->picture_struct; - s->field_order = h->picture_struct; + s->picture_structure = h->sei.picture_timing.picture_struct; + s->field_order = h->sei.picture_timing.picture_struct; if (IS_IRAP(h)) { s->key_frame = 1; diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index 9103c84686..6810ffaf17 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -109,8 +109,8 @@ static HEVCFrame *alloc_frame(HEVCContext *s) for (j = 0; j < frame->ctb_count; j++) frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf->data; - frame->frame->top_field_first = s->picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD; - frame->frame->interlaced_frame = (s->picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) || (s->picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD); + frame->frame->top_field_first = s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD; + frame->frame->interlaced_frame = (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) || (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD); if (s->avctx->hwaccel) { const AVHWAccel *hwaccel = s->avctx->hwaccel; diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index bb299d5a9f..1dc0674f81 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -53,13 +53,13 @@ enum HEVC_SEI_TYPE { SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO = 144, }; -static int decode_nal_sei_decoded_picture_hash(HEVCContext *s) +static int decode_nal_sei_decoded_picture_hash(HEVCSEIPictureHash *s, GetBitContext *gb, + void *logctx) { int cIdx, i; uint8_t hash_type; //uint16_t picture_crc; //uint32_t picture_checksum; - GetBitContext *gb = &s->HEVClc->gb; hash_type = get_bits(gb, 8); for (cIdx = 0; cIdx < 3/*((s->sps->chroma_format_idc == 0) ? 1 : 3)*/; cIdx++) { @@ -78,9 +78,9 @@ static int decode_nal_sei_decoded_picture_hash(HEVCContext *s) return 0; } -static int decode_nal_sei_mastering_display_info(HEVCContext *s) +static int decode_nal_sei_mastering_display_info(HEVCSEIMasteringDisplay *s, GetBitContext *gb, + void *logctx) { - GetBitContext *gb = &s->HEVClc->gb; int i; // Mastering primaries for (i = 0; i < 3; i++) { @@ -92,38 +92,38 @@ static int decode_nal_sei_mastering_display_info(HEVCContext *s) s->white_point[1] = get_bits(gb, 16); // Max and min luminance of mastering display - s->max_mastering_luminance = get_bits_long(gb, 32); - s->min_mastering_luminance = get_bits_long(gb, 32); + s->max_luminance = get_bits_long(gb, 32); + s->min_luminance = get_bits_long(gb, 32); // As this SEI message comes before the first frame that references it, // initialize the flag to 2 and decrement on IRAP access unit so it // persists for the coded video sequence (e.g., between two IRAPs) - s->sei_mastering_display_info_present = 2; + s->present = 2; return 0; } -static int decode_nal_sei_content_light_info(HEVCContext *s) +static int decode_nal_sei_content_light_info(HEVCSEIContentLight *s, GetBitContext *gb, + void *logctx) { - GetBitContext *gb = &s->HEVClc->gb; // Max and average light levels s->max_content_light_level = get_bits_long(gb, 16); s->max_pic_average_light_level = get_bits_long(gb, 16); // As this SEI message comes before the first frame that references it, // initialize the flag to 2 and decrement on IRAP access unit so it // persists for the coded video sequence (e.g., between two IRAPs) - s-> sei_content_light_present = 2; + s->present = 2; return 0; } -static int decode_nal_sei_frame_packing_arrangement(HEVCContext *s) +static int decode_nal_sei_frame_packing_arrangement(HEVCSEIFramePacking *s, + GetBitContext *gb, + void *logctx) { - GetBitContext *gb = &s->HEVClc->gb; - get_ue_golomb_long(gb); // frame_packing_arrangement_id - s->sei_frame_packing_present = !get_bits1(gb); + s->present = !get_bits1(gb); - if (s->sei_frame_packing_present) { - s->frame_packing_arrangement_type = get_bits(gb, 7); + if (s->present) { + s->arrangement_type = get_bits(gb, 7); s->quincunx_subsampling = get_bits1(gb); s->content_interpretation_type = get_bits(gb, 6); @@ -132,7 +132,7 @@ static int decode_nal_sei_frame_packing_arrangement(HEVCContext *s) // frame0_self_contained_flag frame1_self_contained_flag skip_bits(gb, 6); - if (!s->quincunx_subsampling && s->frame_packing_arrangement_type != 5) + if (!s->quincunx_subsampling && s->arrangement_type != 5) skip_bits(gb, 16); // frame[01]_grid_position_[xy] skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte skip_bits1(gb); // frame_packing_arrangement_persistence_flag @@ -141,41 +141,41 @@ static int decode_nal_sei_frame_packing_arrangement(HEVCContext *s) return 0; } -static int decode_nal_sei_display_orientation(HEVCContext *s) +static int decode_nal_sei_display_orientation(HEVCSEIDisplayOrientation *s, GetBitContext *gb, + void *logctx) { - GetBitContext *gb = &s->HEVClc->gb; - - s->sei_display_orientation_present = !get_bits1(gb); + s->present = !get_bits1(gb); - if (s->sei_display_orientation_present) { - s->sei_hflip = get_bits1(gb); // hor_flip - s->sei_vflip = get_bits1(gb); // ver_flip + if (s->present) { + s->hflip = get_bits1(gb); // hor_flip + s->vflip = get_bits1(gb); // ver_flip - s->sei_anticlockwise_rotation = get_bits(gb, 16); + s->anticlockwise_rotation = get_bits(gb, 16); skip_bits1(gb); // display_orientation_persistence_flag } return 0; } -static int decode_pic_timing(HEVCContext *s) +static int decode_pic_timing(HEVCSEIContext *s, GetBitContext *gb, void *logctx, + const HEVCParamSets *ps) { - GetBitContext *gb = &s->HEVClc->gb; + HEVCSEIPictureTiming *h = &s->picture_timing; HEVCSPS *sps; - if (!s->ps.sps_list[s->active_seq_parameter_set_id]) + if (!ps->sps_list[s->active_seq_parameter_set_id]) return(AVERROR(ENOMEM)); - sps = (HEVCSPS*)s->ps.sps_list[s->active_seq_parameter_set_id]->data; + sps = (HEVCSPS*)ps->sps_list[s->active_seq_parameter_set_id]->data; if (sps->vui.frame_field_info_present_flag) { int pic_struct = get_bits(gb, 4); - s->picture_struct = AV_PICTURE_STRUCTURE_UNKNOWN; + h->picture_struct = AV_PICTURE_STRUCTURE_UNKNOWN; if (pic_struct == 2) { - av_log(s->avctx, AV_LOG_DEBUG, "BOTTOM Field\n"); - s->picture_struct = AV_PICTURE_STRUCTURE_BOTTOM_FIELD; + av_log(logctx, AV_LOG_DEBUG, "BOTTOM Field\n"); + h->picture_struct = AV_PICTURE_STRUCTURE_BOTTOM_FIELD; } else if (pic_struct == 1) { - av_log(s->avctx, AV_LOG_DEBUG, "TOP Field\n"); - s->picture_struct = AV_PICTURE_STRUCTURE_TOP_FIELD; + av_log(logctx, AV_LOG_DEBUG, "TOP Field\n"); + h->picture_struct = AV_PICTURE_STRUCTURE_TOP_FIELD; } get_bits(gb, 2); // source_scan_type get_bits(gb, 1); // duplicate_flag @@ -183,14 +183,14 @@ static int decode_pic_timing(HEVCContext *s) return 1; } -static int decode_registered_user_data_closed_caption(HEVCContext *s, int size) +static int decode_registered_user_data_closed_caption(HEVCSEIA53Caption *s, + GetBitContext *gb, + void *logctx, int size) { int flag; int user_data_type_code; int cc_count; - GetBitContext *gb = &s->HEVClc->gb; - if (size < 3) return AVERROR(EINVAL); @@ -235,13 +235,13 @@ static int decode_registered_user_data_closed_caption(HEVCContext *s, int size) return 0; } -static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCContext *s, int size) +static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCSEIContext *s, + GetBitContext *gb, + void *logctx, int size) { uint32_t country_code; uint32_t user_identifier; - GetBitContext *gb = &s->HEVClc->gb; - if (size < 7) return AVERROR(EINVAL); size -= 7; @@ -259,7 +259,7 @@ static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCContext *s, int siz switch (user_identifier) { case MKBETAG('G', 'A', '9', '4'): - return decode_registered_user_data_closed_caption(s, size); + return decode_registered_user_data_closed_caption(&s->a53_caption, gb, logctx, size); default: skip_bits_long(gb, size * 8); break; @@ -267,9 +267,8 @@ static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCContext *s, int siz return 0; } -static int active_parameter_sets(HEVCContext *s) +static int active_parameter_sets(HEVCSEIContext *s, GetBitContext *gb, void *logctx) { - GetBitContext *gb = &s->HEVClc->gb; int num_sps_ids_minus1; int i; unsigned active_seq_parameter_set_id; @@ -280,13 +279,13 @@ static int active_parameter_sets(HEVCContext *s) num_sps_ids_minus1 = get_ue_golomb_long(gb); // num_sps_ids_minus1 if (num_sps_ids_minus1 < 0 || num_sps_ids_minus1 > 15) { - av_log(s->avctx, AV_LOG_ERROR, "num_sps_ids_minus1 %d invalid\n", num_sps_ids_minus1); + av_log(logctx, AV_LOG_ERROR, "num_sps_ids_minus1 %d invalid\n", num_sps_ids_minus1); return AVERROR_INVALIDDATA; } active_seq_parameter_set_id = get_ue_golomb_long(gb); if (active_seq_parameter_set_id >= HEVC_MAX_SPS_COUNT) { - av_log(s->avctx, AV_LOG_ERROR, "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id); + av_log(logctx, AV_LOG_ERROR, "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id); return AVERROR_INVALIDDATA; } s->active_seq_parameter_set_id = active_seq_parameter_set_id; @@ -297,63 +296,63 @@ static int active_parameter_sets(HEVCContext *s) return 0; } -static int decode_nal_sei_prefix(HEVCContext *s, int type, int size) +static int decode_nal_sei_prefix(GetBitContext *gb, void *logctx, HEVCSEIContext *s, + const HEVCParamSets *ps, int type, int size) { - GetBitContext *gb = &s->HEVClc->gb; - switch (type) { case 256: // Mismatched value from HM 8.1 - return decode_nal_sei_decoded_picture_hash(s); + return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gb, logctx); case SEI_TYPE_FRAME_PACKING: - return decode_nal_sei_frame_packing_arrangement(s); + return decode_nal_sei_frame_packing_arrangement(&s->frame_packing, + gb, logctx); case SEI_TYPE_DISPLAY_ORIENTATION: - return decode_nal_sei_display_orientation(s); + return decode_nal_sei_display_orientation(&s->display_orientation, + gb, logctx); case SEI_TYPE_PICTURE_TIMING: { - int ret = decode_pic_timing(s); - av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type); + int ret = decode_pic_timing(s, gb, logctx, ps); + av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type); skip_bits(gb, 8 * size); return ret; } case SEI_TYPE_MASTERING_DISPLAY_INFO: - return decode_nal_sei_mastering_display_info(s); + return decode_nal_sei_mastering_display_info(&s->mastering_display, + gb, logctx); case SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO: - return decode_nal_sei_content_light_info(s); + return decode_nal_sei_content_light_info(&s->content_light, gb, logctx); case SEI_TYPE_ACTIVE_PARAMETER_SETS: - active_parameter_sets(s); - av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type); + active_parameter_sets(s, gb, logctx); + av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type); return 0; case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35: - return decode_nal_sei_user_data_registered_itu_t_t35(s, size); + return decode_nal_sei_user_data_registered_itu_t_t35(s, gb, logctx, size); default: - av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type); + av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type); skip_bits_long(gb, 8 * size); return 0; } } -static int decode_nal_sei_suffix(HEVCContext *s, int type, int size) +static int decode_nal_sei_suffix(GetBitContext *gb, void *logctx, HEVCSEIContext *s, + int type, int size) { - GetBitContext *gb = &s->HEVClc->gb; - switch (type) { case SEI_TYPE_DECODED_PICTURE_HASH: - return decode_nal_sei_decoded_picture_hash(s); + return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gb, logctx); default: - av_log(s->avctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", type); + av_log(logctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", type); skip_bits_long(gb, 8 * size); return 0; } } -static int decode_nal_sei_message(HEVCContext *s) +static int decode_nal_sei_message(GetBitContext *gb, void *logctx, HEVCSEIContext *s, + const HEVCParamSets *ps, int type) { - GetBitContext *gb = &s->HEVClc->gb; - int payload_type = 0; int payload_size = 0; int byte = 0xFF; - av_log(s->avctx, AV_LOG_DEBUG, "Decoding SEI\n"); + av_log(logctx, AV_LOG_DEBUG, "Decoding SEI\n"); while (byte == 0xFF) { byte = get_bits(gb, 8); @@ -364,10 +363,10 @@ static int decode_nal_sei_message(HEVCContext *s) byte = get_bits(gb, 8); payload_size += byte; } - if (s->nal_unit_type == HEVC_NAL_SEI_PREFIX) { - return decode_nal_sei_prefix(s, payload_type, payload_size); + if (type == HEVC_NAL_SEI_PREFIX) { + return decode_nal_sei_prefix(gb, logctx, s, ps, payload_type, payload_size); } else { /* nal_unit_type == NAL_SEI_SUFFIX */ - return decode_nal_sei_suffix(s, payload_type, payload_size); + return decode_nal_sei_suffix(gb, logctx, s, payload_type, payload_size); } } @@ -376,20 +375,21 @@ static int more_rbsp_data(GetBitContext *gb) return get_bits_left(gb) > 0 && show_bits(gb, 8) != 0x80; } -int ff_hevc_decode_nal_sei(HEVCContext *s) +int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEIContext *s, + const HEVCParamSets *ps, int type) { int ret; do { - ret = decode_nal_sei_message(s); + ret = decode_nal_sei_message(gb, logctx, s, ps, type); if (ret < 0) return(AVERROR(ENOMEM)); - } while (more_rbsp_data(&s->HEVClc->gb)); + } while (more_rbsp_data(gb)); return 1; } -void ff_hevc_reset_sei(HEVCContext *s) +void ff_hevc_reset_sei(HEVCSEIContext *s) { - s->a53_caption_size = 0; - av_freep(&s->a53_caption); + s->a53_caption.a53_caption_size = 0; + av_freep(&s->a53_caption.a53_caption); } diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 2fb08d81d2..2a02edab28 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -2559,18 +2559,18 @@ static int set_side_data(HEVCContext *s) { AVFrame *out = s->ref->frame; - if (s->sei_frame_packing_present && - s->frame_packing_arrangement_type >= 3 && - s->frame_packing_arrangement_type <= 5 && - s->content_interpretation_type > 0 && - s->content_interpretation_type < 3) { + if (s->sei.frame_packing.present && + s->sei.frame_packing.arrangement_type >= 3 && + s->sei.frame_packing.arrangement_type <= 5 && + s->sei.frame_packing.content_interpretation_type > 0 && + s->sei.frame_packing.content_interpretation_type < 3) { AVStereo3D *stereo = av_stereo3d_create_side_data(out); if (!stereo) return AVERROR(ENOMEM); - switch (s->frame_packing_arrangement_type) { + switch (s->sei.frame_packing.arrangement_type) { case 3: - if (s->quincunx_subsampling) + if (s->sei.frame_packing.quincunx_subsampling) stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX; else stereo->type = AV_STEREO3D_SIDEBYSIDE; @@ -2583,13 +2583,14 @@ static int set_side_data(HEVCContext *s) break; } - if (s->content_interpretation_type == 2) + if (s->sei.frame_packing.content_interpretation_type == 2) stereo->flags = AV_STEREO3D_FLAG_INVERT; } - if (s->sei_display_orientation_present && - (s->sei_anticlockwise_rotation || s->sei_hflip || s->sei_vflip)) { - double angle = s->sei_anticlockwise_rotation * 360 / (double) (1 << 16); + if (s->sei.display_orientation.present && + (s->sei.display_orientation.anticlockwise_rotation || + s->sei.display_orientation.hflip || s->sei.display_orientation.vflip)) { + double angle = s->sei.display_orientation.anticlockwise_rotation * 360 / (double) (1 << 16); AVFrameSideData *rotation = av_frame_new_side_data(out, AV_FRAME_DATA_DISPLAYMATRIX, sizeof(int32_t) * 9); @@ -2598,16 +2599,17 @@ static int set_side_data(HEVCContext *s) av_display_rotation_set((int32_t *)rotation->data, angle); av_display_matrix_flip((int32_t *)rotation->data, - s->sei_hflip, s->sei_vflip); + s->sei.display_orientation.hflip, + s->sei.display_orientation.vflip); } // Decrement the mastering display flag when IRAP frame has no_rasl_output_flag=1 // so the side data persists for the entire coded video sequence. - if (s->sei_mastering_display_info_present > 0 && + if (s->sei.mastering_display.present > 0 && IS_IRAP(s) && s->no_rasl_output_flag) { - s->sei_mastering_display_info_present--; + s->sei.mastering_display.present--; } - if (s->sei_mastering_display_info_present) { + if (s->sei.mastering_display.present) { // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b const int mapping[3] = {2, 0, 1}; const int chroma_den = 50000; @@ -2620,19 +2622,19 @@ static int set_side_data(HEVCContext *s) for (i = 0; i < 3; i++) { const int j = mapping[i]; - metadata->display_primaries[i][0].num = s->display_primaries[j][0]; + metadata->display_primaries[i][0].num = s->sei.mastering_display.display_primaries[j][0]; metadata->display_primaries[i][0].den = chroma_den; - metadata->display_primaries[i][1].num = s->display_primaries[j][1]; + metadata->display_primaries[i][1].num = s->sei.mastering_display.display_primaries[j][1]; metadata->display_primaries[i][1].den = chroma_den; } - metadata->white_point[0].num = s->white_point[0]; + metadata->white_point[0].num = s->sei.mastering_display.white_point[0]; metadata->white_point[0].den = chroma_den; - metadata->white_point[1].num = s->white_point[1]; + metadata->white_point[1].num = s->sei.mastering_display.white_point[1]; metadata->white_point[1].den = chroma_den; - metadata->max_luminance.num = s->max_mastering_luminance; + metadata->max_luminance.num = s->sei.mastering_display.max_luminance; metadata->max_luminance.den = luma_den; - metadata->min_luminance.num = s->min_mastering_luminance; + metadata->min_luminance.num = s->sei.mastering_display.min_luminance; metadata->min_luminance.den = luma_den; metadata->has_luminance = 1; metadata->has_primaries = 1; @@ -2653,31 +2655,31 @@ static int set_side_data(HEVCContext *s) } // Decrement the mastering display flag when IRAP frame has no_rasl_output_flag=1 // so the side data persists for the entire coded video sequence. - if (s->sei_content_light_present > 0 && + if (s->sei.content_light.present > 0 && IS_IRAP(s) && s->no_rasl_output_flag) { - s->sei_content_light_present--; + s->sei.content_light.present--; } - if (s->sei_content_light_present) { + if (s->sei.content_light.present) { AVContentLightMetadata *metadata = av_content_light_metadata_create_side_data(out); if (!metadata) return AVERROR(ENOMEM); - metadata->MaxCLL = s->max_content_light_level; - metadata->MaxFALL = s->max_pic_average_light_level; + metadata->MaxCLL = s->sei.content_light.max_content_light_level; + metadata->MaxFALL = s->sei.content_light.max_pic_average_light_level; av_log(s->avctx, AV_LOG_DEBUG, "Content Light Level Metadata:\n"); av_log(s->avctx, AV_LOG_DEBUG, "MaxCLL=%d, MaxFALL=%d\n", metadata->MaxCLL, metadata->MaxFALL); } - if (s->a53_caption) { + if (s->sei.a53_caption.a53_caption) { AVFrameSideData* sd = av_frame_new_side_data(out, AV_FRAME_DATA_A53_CC, - s->a53_caption_size); + s->sei.a53_caption.a53_caption_size); if (sd) - memcpy(sd->data, s->a53_caption, s->a53_caption_size); - av_freep(&s->a53_caption); - s->a53_caption_size = 0; + memcpy(sd->data, s->sei.a53_caption.a53_caption, s->sei.a53_caption.a53_caption_size); + av_freep(&s->sei.a53_caption.a53_caption); + s->sei.a53_caption.a53_caption_size = 0; s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } @@ -2772,7 +2774,7 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) break; case HEVC_NAL_SEI_PREFIX: case HEVC_NAL_SEI_SUFFIX: - ret = ff_hevc_decode_nal_sei(s); + ret = ff_hevc_decode_nal_sei(gb, s->avctx, &s->sei, &s->ps, s->nal_unit_type); if (ret < 0) goto fail; break; @@ -2966,7 +2968,7 @@ static int verify_md5(HEVCContext *s, AVFrame *frame) int h = (i == 1 || i == 2) ? (height >> desc->log2_chroma_h) : height; uint8_t md5[16]; - av_md5_init(s->md5_ctx); + av_md5_init(s->sei.picture_hash.md5_ctx); for (j = 0; j < h; j++) { const uint8_t *src = frame->data[i] + j * frame->linesize[i]; #if HAVE_BIGENDIAN @@ -2976,11 +2978,11 @@ static int verify_md5(HEVCContext *s, AVFrame *frame) src = s->checksum_buf; } #endif - av_md5_update(s->md5_ctx, src, w << pixel_shift); + av_md5_update(s->sei.picture_hash.md5_ctx, src, w << pixel_shift); } - av_md5_final(s->md5_ctx, md5); + av_md5_final(s->sei.picture_hash.md5_ctx, md5); - if (!memcmp(md5, s->md5[i], 16)) { + if (!memcmp(md5, s->sei.picture_hash.md5[i], 16)) { av_log (s->avctx, AV_LOG_DEBUG, "plane %d - correct ", i); print_md5(s->avctx, AV_LOG_DEBUG, md5); av_log (s->avctx, AV_LOG_DEBUG, "; "); @@ -2988,7 +2990,7 @@ static int verify_md5(HEVCContext *s, AVFrame *frame) av_log (s->avctx, AV_LOG_ERROR, "mismatching checksum of plane %d - ", i); print_md5(s->avctx, AV_LOG_ERROR, md5); av_log (s->avctx, AV_LOG_ERROR, " != "); - print_md5(s->avctx, AV_LOG_ERROR, s->md5[i]); + print_md5(s->avctx, AV_LOG_ERROR, s->sei.picture_hash.md5[i]); av_log (s->avctx, AV_LOG_ERROR, "\n"); return AVERROR_INVALIDDATA; } @@ -3061,7 +3063,7 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output, } else { /* verify the SEI checksum */ if (avctx->err_recognition & AV_EF_CRCCHECK && s->is_decoded && - s->is_md5) { + s->sei.picture_hash.is_md5) { ret = verify_md5(s, s->ref->frame); if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE) { ff_hevc_unref_frame(s, s->ref, ~0); @@ -3069,7 +3071,7 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output, } } } - s->is_md5 = 0; + s->sei.picture_hash.is_md5 = 0; if (s->is_decoded) { av_log(avctx, AV_LOG_DEBUG, "Decoded frame with POC %d.\n", s->poc); @@ -3132,7 +3134,7 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) pic_arrays_free(s); - av_freep(&s->md5_ctx); + av_freep(&s->sei.picture_hash.md5_ctx); av_freep(&s->cabac_state); @@ -3207,8 +3209,8 @@ static av_cold int hevc_init_context(AVCodecContext *avctx) s->max_ra = INT_MAX; - s->md5_ctx = av_md5_alloc(); - if (!s->md5_ctx) + s->sei.picture_hash.md5_ctx = av_md5_alloc(); + if (!s->sei.picture_hash.md5_ctx) goto fail; ff_bswapdsp_init(&s->bdsp); @@ -3216,7 +3218,7 @@ static av_cold int hevc_init_context(AVCodecContext *avctx) s->context_initialized = 1; s->eos = 0; - ff_hevc_reset_sei(s); + ff_hevc_reset_sei(&s->sei); return 0; @@ -3313,7 +3315,7 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) return ret; s->enable_parallel_tiles = 0; - s->picture_struct = 0; + s->sei.picture_timing.picture_struct = 0; s->eos = 1; atomic_init(&s->wpp_err, 0); diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h index dfb12eff8b..b8b8605134 100644 --- a/libavcodec/hevcdec.h +++ b/libavcodec/hevcdec.h @@ -26,7 +26,6 @@ #include #include "libavutil/buffer.h" -#include "libavutil/md5.h" #include "avcodec.h" #include "bswapdsp.h" @@ -464,6 +463,59 @@ typedef struct HEVCLocalContext { int boundary_flags; } HEVCLocalContext; +typedef struct HEVCSEIPictureHash { + struct AVMD5 *md5_ctx; + uint8_t md5[3][16]; + uint8_t is_md5; +} HEVCSEIPictureHash; + +typedef struct HEVCSEIFramePacking { + int present; + int arrangement_type; + int content_interpretation_type; + int quincunx_subsampling; +} HEVCSEIFramePacking; + +typedef struct HEVCSEIDisplayOrientation { + int present; + int anticlockwise_rotation; + int hflip, vflip; +} HEVCSEIDisplayOrientation; + +typedef struct HEVCSEIPictureTiming { + int picture_struct; +} HEVCSEIPictureTiming; + +typedef struct HEVCSEIA53Caption { + int a53_caption_size; + uint8_t *a53_caption; +} HEVCSEIA53Caption; + +typedef struct HEVCSEIMasteringDisplay { + int present; + uint16_t display_primaries[3][2]; + uint16_t white_point[2]; + uint32_t max_luminance; + uint32_t min_luminance; +} HEVCSEIMasteringDisplay; + +typedef struct HEVCSEIContentLight { + int present; + uint16_t max_content_light_level; + uint16_t max_pic_average_light_level; +} HEVCSEIContentLight; + +typedef struct HEVCSEIContext { + HEVCSEIPictureHash picture_hash; + HEVCSEIFramePacking frame_packing; + HEVCSEIDisplayOrientation display_orientation; + HEVCSEIPictureTiming picture_timing; + HEVCSEIA53Caption a53_caption; + HEVCSEIMasteringDisplay mastering_display; + HEVCSEIContentLight content_light; + int active_seq_parameter_set_id; +} HEVCSEIContext; + typedef struct HEVCContext { const AVClass *c; // needed by private avoptions AVCodecContext *avctx; @@ -558,52 +610,19 @@ typedef struct HEVCContext { // type of the first VCL NAL of the current frame enum HEVCNALUnitType first_nal_type; - // for checking the frame checksums - struct AVMD5 *md5_ctx; - uint8_t md5[3][16]; - uint8_t is_md5; - uint8_t context_initialized; int is_nalff; ///< this flag is != 0 if bitstream is encapsulated ///< as a format defined in 14496-15 int apply_defdispwin; - int active_seq_parameter_set_id; - int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4) int nuh_layer_id; - /** frame packing arrangement variables */ - int sei_frame_packing_present; - int frame_packing_arrangement_type; - int content_interpretation_type; - int quincunx_subsampling; - - /** display orientation */ - int sei_display_orientation_present; - int sei_anticlockwise_rotation; - int sei_hflip, sei_vflip; - - int picture_struct; - - uint8_t* a53_caption; - int a53_caption_size; - - /** mastering display */ - int sei_mastering_display_info_present; - uint16_t display_primaries[3][2]; - uint16_t white_point[2]; - uint32_t max_mastering_luminance; - uint32_t min_mastering_luminance; - - /* content light level */ - int sei_content_light_present; - uint16_t max_content_light_level; - uint16_t max_pic_average_light_level; - + HEVCSEIContext sei; } HEVCContext; -int ff_hevc_decode_nal_sei(HEVCContext *s); +int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEIContext *s, + const HEVCParamSets *ps, int type); /** * Mark all frames in DPB as unused for reference. @@ -715,7 +734,7 @@ void ff_hevc_hls_mvd_coding(HEVCContext *s, int x0, int y0, int log2_cb_size); * * @param s HEVCContext. */ -void ff_hevc_reset_sei(HEVCContext *s); +void ff_hevc_reset_sei(HEVCSEIContext *s); extern const uint8_t ff_hevc_qpel_extra_before[4]; extern const uint8_t ff_hevc_qpel_extra_after[4];