From patchwork Mon May 1 22:41:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 3536 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.3.129 with SMTP id 123csp1600958vsd; Mon, 1 May 2017 15:41:46 -0700 (PDT) X-Received: by 10.223.142.35 with SMTP id n32mr20461826wrb.131.1493678506891; Mon, 01 May 2017 15:41:46 -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 42si8691769wrm.49.2017.05.01.15.41.46; Mon, 01 May 2017 15:41:46 -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 B4C4B68922F; Tue, 2 May 2017 01:41:40 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qk0-f195.google.com (mail-qk0-f195.google.com [209.85.220.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0B2736891D5 for ; Tue, 2 May 2017 01:41:34 +0300 (EEST) Received: by mail-qk0-f195.google.com with SMTP id u68so3588248qkd.2 for ; Mon, 01 May 2017 15:41:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=b2Unpj7F3+otmnNrRSpv0CMG66RRv0azZbk0AsRz9m4=; b=dHCaGG0x7mhG8aR0cCnAjXGdFtkvf5NGYuUwCJ74IUBzYD1GNgPqNNir8lgny1nLEi AOnfVyjoztGaUQVz4QJx9Fh1Dzc7ZOyPnipmgkGTpPLeMSB+6N2b8J0tYXppscUKJyBU 2VMLN9D42GVvLVsM5cAAldZIGHjLSP84Wyy6Y0L2Q/tf/TnyW5k9Woz2S1TK9k81baN0 MrqdNF5SoqgDqpVo0MT5jQSC7MBhrHtFz2rV4+YlFjZv+cn12khM5VFAnN4xuOcRnqnH lrP3gsJTkK7uM1vL1UDhlvw9YR5RirFwnK/8WqBi19cmSkS8bnep23ivpycxV2dXP91y IhHw== 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:in-reply-to :references; bh=b2Unpj7F3+otmnNrRSpv0CMG66RRv0azZbk0AsRz9m4=; b=tOrnuBDCmvsWQo4Zr7AF6gWRQHSo7GSIIus7mDRaB8JC2OPrSMhwk9uR/E9hXP59yS hqZAeV8vH3LLKNivzTpC34cmmnkHhkDPMVtlfwS/ubBci50oWORyTIhp1ZSjIKaDJYbR AwQpoOOcuaY+HFlYK4wG/Eew725H9LyvG5ptfHBViDcQAyp1L2EzXig05nRlbbUesCIw pgpsepfXZeup63FrTOhmf0xmCiTxs2ahx/vKV0cTkYDeXZT412aUrW84XdJahOwswbI/ 4SjxpHOcrCt60XbAGxTOBc+76dLwC20dZloLeDAINEVPp7rvBrUaOm07SLm95t/7vdll lkCA== X-Gm-Message-State: AN3rC/73p1VxMbxWt9+3Jiazy0Ewg3ezAIwScaLzVmZnNYASXyPV2yY2 MjpWD3I8Z0pVsv8m X-Received: by 10.55.103.129 with SMTP id b123mr22149642qkc.46.1493678496549; Mon, 01 May 2017 15:41:36 -0700 (PDT) Received: from localhost.localdomain ([181.231.62.139]) by smtp.gmail.com with ESMTPSA id t45sm12232097qtt.9.2017.05.01.15.41.35 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 01 May 2017 15:41:36 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Mon, 1 May 2017 19:41:19 -0300 Message-Id: <20170501224119.9776-1-jamrial@gmail.com> X-Mailer: git-send-email 2.12.1 In-Reply-To: <20170430203410.7128-1-jamrial@gmail.com> References: <20170430203410.7128-1-jamrial@gmail.com> Subject: [FFmpeg-devel] [PATCH 9/9] hevc_parser: move slice header parsing to its own function 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 | 227 +++++++++++++++++++++++++---------------------- 1 file changed, 120 insertions(+), 107 deletions(-) diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index 57f2b2bb3e..4f41b78f66 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -92,6 +92,122 @@ static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf, return END_NOT_FOUND; } +static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal, + AVCodecContext *avctx) +{ + HEVCParserContext *ctx = s->priv_data; + HEVCParamSets *ps = &ctx->ps; + HEVCSEIContext *sei = &ctx->sei; + SliceHeader *sh = &ctx->sh; + GetBitContext *gb = &nal->gb; + int i, num = 0, den = 0; + + sh->first_slice_in_pic_flag = get_bits1(gb); + s->picture_structure = sei->picture_timing.picture_struct; + s->field_order = sei->picture_timing.picture_struct; + + if (IS_IRAP_NAL(nal)) { + s->key_frame = 1; + sh->no_output_of_prior_pics_flag = get_bits1(gb); + } + + sh->pps_id = get_ue_golomb(gb); + if (sh->pps_id >= HEVC_MAX_PPS_COUNT || !ps->pps_list[sh->pps_id]) { + av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", sh->pps_id); + return AVERROR_INVALIDDATA; + } + ps->pps = (HEVCPPS*)ps->pps_list[sh->pps_id]->data; + + if (ps->pps->sps_id >= HEVC_MAX_SPS_COUNT || !ps->sps_list[ps->pps->sps_id]) { + av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", ps->pps->sps_id); + return AVERROR_INVALIDDATA; + } + if (ps->sps != (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data) { + ps->sps = (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data; + ps->vps = (HEVCVPS*)ps->vps_list[ps->sps->vps_id]->data; + } + + s->coded_width = ps->sps->width; + s->coded_height = ps->sps->height; + s->width = ps->sps->output_width; + s->height = ps->sps->output_height; + s->format = ps->sps->pix_fmt; + avctx->profile = ps->sps->ptl.general_ptl.profile_idc; + avctx->level = ps->sps->ptl.general_ptl.level_idc; + + if (ps->vps->vps_timing_info_present_flag) { + num = ps->vps->vps_num_units_in_tick; + den = ps->vps->vps_time_scale; + } else if (ps->sps->vui.vui_timing_info_present_flag) { + num = ps->sps->vui.vui_num_units_in_tick; + den = ps->sps->vui.vui_time_scale; + } + + if (num != 0 && den != 0) + av_reduce(&avctx->framerate.den, &avctx->framerate.num, + num, den, 1 << 30); + + if (!sh->first_slice_in_pic_flag) { + int slice_address_length; + + if (ps->pps->dependent_slice_segments_enabled_flag) + sh->dependent_slice_segment_flag = get_bits1(gb); + else + sh->dependent_slice_segment_flag = 0; + + slice_address_length = av_ceil_log2_c(ps->sps->ctb_width * + ps->sps->ctb_height); + sh->slice_segment_addr = get_bitsz(gb, slice_address_length); + if (sh->slice_segment_addr >= ps->sps->ctb_width * ps->sps->ctb_height) { + av_log(avctx, AV_LOG_ERROR, "Invalid slice segment address: %u.\n", + sh->slice_segment_addr); + return AVERROR_INVALIDDATA; + } + } else + sh->dependent_slice_segment_flag = 0; + + if (sh->dependent_slice_segment_flag) + return 0; /* break; */ + + for (i = 0; i < ps->pps->num_extra_slice_header_bits; i++) + skip_bits(gb, 1); // slice_reserved_undetermined_flag[] + + sh->slice_type = get_ue_golomb(gb); + if (!(sh->slice_type == HEVC_SLICE_I || sh->slice_type == HEVC_SLICE_P || + sh->slice_type == HEVC_SLICE_B)) { + av_log(avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n", + sh->slice_type); + return AVERROR_INVALIDDATA; + } + s->pict_type = sh->slice_type == HEVC_SLICE_B ? AV_PICTURE_TYPE_B : + sh->slice_type == HEVC_SLICE_P ? AV_PICTURE_TYPE_P : + AV_PICTURE_TYPE_I; + + if (ps->pps->output_flag_present_flag) + sh->pic_output_flag = get_bits1(gb); + + if (ps->sps->separate_colour_plane_flag) + sh->colour_plane_id = get_bits(gb, 2); + + if (!IS_IDR_NAL(nal)) { + sh->pic_order_cnt_lsb = get_bits(gb, ps->sps->log2_max_poc_lsb); + s->output_picture_number = ctx->poc = ff_hevc_compute_poc(ps->sps, ctx->pocTid0, sh->pic_order_cnt_lsb, nal->type); + } else + s->output_picture_number = ctx->poc = 0; + + if (nal->temporal_id == 0 && + nal->type != HEVC_NAL_TRAIL_N && + nal->type != HEVC_NAL_TSA_N && + nal->type != HEVC_NAL_STSA_N && + nal->type != HEVC_NAL_RADL_N && + nal->type != HEVC_NAL_RASL_N && + nal->type != HEVC_NAL_RADL_R && + nal->type != HEVC_NAL_RASL_R) + ctx->pocTid0 = ctx->poc; + + return 1; /* no need to evaluate the rest */ +} + /** * Parse NAL units of found picture and decode some basic information. * @@ -104,7 +220,6 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, int buf_size, AVCodecContext *avctx) { HEVCParserContext *ctx = s->priv_data; - SliceHeader *sh = &ctx->sh; HEVCParamSets *ps = &ctx->ps; HEVCSEIContext *sei = &ctx->sei; int is_global = buf == avctx->extradata; @@ -125,8 +240,6 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, for (i = 0; i < ctx->pkt.nb_nals; i++) { H2645NAL *nal = &ctx->pkt.nals[i]; GetBitContext *gb = &nal->gb; - int num = 0, den = 0; - switch (nal->type) { case HEVC_NAL_VPS: @@ -164,110 +277,10 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, return AVERROR_INVALIDDATA; } - sh->first_slice_in_pic_flag = get_bits1(gb); - s->picture_structure = sei->picture_timing.picture_struct; - s->field_order = sei->picture_timing.picture_struct; - - if (IS_IRAP_NAL(nal)) { - s->key_frame = 1; - sh->no_output_of_prior_pics_flag = get_bits1(gb); - } - - sh->pps_id = get_ue_golomb(gb); - if (sh->pps_id >= HEVC_MAX_PPS_COUNT || !ps->pps_list[sh->pps_id]) { - av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", sh->pps_id); - return AVERROR_INVALIDDATA; - } - ps->pps = (HEVCPPS*)ps->pps_list[sh->pps_id]->data; - - if (ps->pps->sps_id >= HEVC_MAX_SPS_COUNT || !ps->sps_list[ps->pps->sps_id]) { - av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", ps->pps->sps_id); - return AVERROR_INVALIDDATA; - } - if (ps->sps != (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data) { - ps->sps = (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data; - ps->vps = (HEVCVPS*)ps->vps_list[ps->sps->vps_id]->data; - } - - s->coded_width = ps->sps->width; - s->coded_height = ps->sps->height; - s->width = ps->sps->output_width; - s->height = ps->sps->output_height; - s->format = ps->sps->pix_fmt; - avctx->profile = ps->sps->ptl.general_ptl.profile_idc; - avctx->level = ps->sps->ptl.general_ptl.level_idc; - - if (ps->vps->vps_timing_info_present_flag) { - num = ps->vps->vps_num_units_in_tick; - den = ps->vps->vps_time_scale; - } else if (ps->sps->vui.vui_timing_info_present_flag) { - num = ps->sps->vui.vui_num_units_in_tick; - den = ps->sps->vui.vui_time_scale; - } - - if (num != 0 && den != 0) - av_reduce(&avctx->framerate.den, &avctx->framerate.num, - num, den, 1 << 30); - - if (!sh->first_slice_in_pic_flag) { - int slice_address_length; - - if (ps->pps->dependent_slice_segments_enabled_flag) - sh->dependent_slice_segment_flag = get_bits1(gb); - else - sh->dependent_slice_segment_flag = 0; - - slice_address_length = av_ceil_log2_c(ps->sps->ctb_width * - ps->sps->ctb_height); - sh->slice_segment_addr = get_bitsz(gb, slice_address_length); - if (sh->slice_segment_addr >= ps->sps->ctb_width * ps->sps->ctb_height) { - av_log(avctx, AV_LOG_ERROR, "Invalid slice segment address: %u.\n", - sh->slice_segment_addr); - return AVERROR_INVALIDDATA; - } - } else - sh->dependent_slice_segment_flag = 0; - - if (sh->dependent_slice_segment_flag) - break; - - for (i = 0; i < ps->pps->num_extra_slice_header_bits; i++) - skip_bits(gb, 1); // slice_reserved_undetermined_flag[] - - sh->slice_type = get_ue_golomb(gb); - if (!(sh->slice_type == HEVC_SLICE_I || sh->slice_type == HEVC_SLICE_P || - sh->slice_type == HEVC_SLICE_B)) { - av_log(avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n", - sh->slice_type); - return AVERROR_INVALIDDATA; - } - s->pict_type = sh->slice_type == HEVC_SLICE_B ? AV_PICTURE_TYPE_B : - sh->slice_type == HEVC_SLICE_P ? AV_PICTURE_TYPE_P : - AV_PICTURE_TYPE_I; - - if (ps->pps->output_flag_present_flag) - sh->pic_output_flag = get_bits1(gb); - - if (ps->sps->separate_colour_plane_flag) - sh->colour_plane_id = get_bits(gb, 2); - - if (!IS_IDR_NAL(nal)) { - sh->pic_order_cnt_lsb = get_bits(gb, ps->sps->log2_max_poc_lsb); - s->output_picture_number = ctx->poc = ff_hevc_compute_poc(ps->sps, ctx->pocTid0, sh->pic_order_cnt_lsb, nal->type); - } else - s->output_picture_number = ctx->poc = 0; - - if (nal->temporal_id == 0 && - nal->type != HEVC_NAL_TRAIL_N && - nal->type != HEVC_NAL_TSA_N && - nal->type != HEVC_NAL_STSA_N && - nal->type != HEVC_NAL_RADL_N && - nal->type != HEVC_NAL_RASL_N && - nal->type != HEVC_NAL_RADL_R && - nal->type != HEVC_NAL_RASL_R) - ctx->pocTid0 = ctx->poc; - - return 0; /* no need to evaluate the rest */ + ret = hevc_parse_slice_header(s, nal, avctx); + if (ret) + return ret; + break; } } /* didn't find a picture! */