LCOV - code coverage report
Current view: top level - libavcodec - nvdec_h264.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 94 0.0 %
Date: 2017-12-16 01:21:47 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /*
       2             :  * MPEG-4 Part 10 / AVC / H.264 HW decode acceleration through NVDEC
       3             :  *
       4             :  * Copyright (c) 2016 Anton Khirnov
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : #include <stdint.h>
      24             : #include <string.h>
      25             : 
      26             : #include "avcodec.h"
      27             : #include "nvdec.h"
      28             : #include "decode.h"
      29             : #include "internal.h"
      30             : #include "h264dec.h"
      31             : 
      32           0 : static void dpb_add(const H264Context *h, CUVIDH264DPBENTRY *dst, const H264Picture *src,
      33             :                     int frame_idx)
      34             : {
      35           0 :     FrameDecodeData *fdd = (FrameDecodeData*)src->f->private_ref->data;
      36           0 :     const NVDECFrame *cf = fdd->hwaccel_priv;
      37             : 
      38           0 :     dst->PicIdx             = cf ? cf->idx : -1;
      39           0 :     dst->FrameIdx           = frame_idx;
      40           0 :     dst->is_long_term       = src->long_ref;
      41           0 :     dst->not_existing       = 0;
      42           0 :     dst->used_for_reference = src->reference & 3;
      43           0 :     dst->FieldOrderCnt[0]   = src->field_poc[0];
      44           0 :     dst->FieldOrderCnt[1]   = src->field_poc[1];
      45           0 : }
      46             : 
      47           0 : static int nvdec_h264_start_frame(AVCodecContext *avctx,
      48             :                                   const uint8_t *buffer, uint32_t size)
      49             : {
      50           0 :     const H264Context *h = avctx->priv_data;
      51           0 :     const PPS *pps = h->ps.pps;
      52           0 :     const SPS *sps = h->ps.sps;
      53             : 
      54           0 :     NVDECContext       *ctx = avctx->internal->hwaccel_priv_data;
      55           0 :     CUVIDPICPARAMS      *pp = &ctx->pic_params;
      56           0 :     CUVIDH264PICPARAMS *ppc = &pp->CodecSpecific.h264;
      57             :     FrameDecodeData *fdd;
      58             :     NVDECFrame *cf;
      59             : 
      60             :     int i, dpb_size, ret;
      61             : 
      62           0 :     ret = ff_nvdec_start_frame(avctx, h->cur_pic_ptr->f);
      63           0 :     if (ret < 0)
      64           0 :         return ret;
      65             : 
      66           0 :     fdd = (FrameDecodeData*)h->cur_pic_ptr->f->private_ref->data;
      67           0 :     cf  = (NVDECFrame*)fdd->hwaccel_priv;
      68             : 
      69           0 :     *pp = (CUVIDPICPARAMS) {
      70           0 :         .PicWidthInMbs     = h->mb_width,
      71           0 :         .FrameHeightInMbs  = h->mb_height,
      72           0 :         .CurrPicIdx        = cf->idx,
      73           0 :         .field_pic_flag    = FIELD_PICTURE(h),
      74           0 :         .bottom_field_flag = h->picture_structure == PICT_BOTTOM_FIELD,
      75           0 :         .second_field      = FIELD_PICTURE(h) && !h->first_field,
      76           0 :         .ref_pic_flag      = h->nal_ref_idc != 0,
      77             :         .intra_pic_flag    = 0,
      78             : 
      79             :         .CodecSpecific.h264 = {
      80           0 :             .log2_max_frame_num_minus4            = sps->log2_max_frame_num - 4,
      81           0 :             .pic_order_cnt_type                   = sps->poc_type,
      82           0 :             .log2_max_pic_order_cnt_lsb_minus4    = FFMAX(sps->log2_max_poc_lsb - 4, 0),
      83           0 :             .delta_pic_order_always_zero_flag     = sps->delta_pic_order_always_zero_flag,
      84           0 :             .frame_mbs_only_flag                  = sps->frame_mbs_only_flag,
      85           0 :             .direct_8x8_inference_flag            = sps->direct_8x8_inference_flag,
      86           0 :             .num_ref_frames                       = sps->ref_frame_count,
      87           0 :             .residual_colour_transform_flag       = sps->residual_color_transform_flag,
      88           0 :             .bit_depth_luma_minus8                = sps->bit_depth_luma - 8,
      89           0 :             .bit_depth_chroma_minus8              = sps->bit_depth_chroma - 8,
      90           0 :             .qpprime_y_zero_transform_bypass_flag = sps->transform_bypass,
      91             : 
      92           0 :             .entropy_coding_mode_flag               = pps->cabac,
      93           0 :             .pic_order_present_flag                 = pps->pic_order_present,
      94           0 :             .num_ref_idx_l0_active_minus1           = pps->ref_count[0] - 1,
      95           0 :             .num_ref_idx_l1_active_minus1           = pps->ref_count[1] - 1,
      96           0 :             .weighted_pred_flag                     = pps->weighted_pred,
      97           0 :             .weighted_bipred_idc                    = pps->weighted_bipred_idc,
      98           0 :             .pic_init_qp_minus26                    = pps->init_qp - 26,
      99           0 :             .deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present,
     100           0 :             .redundant_pic_cnt_present_flag         = pps->redundant_pic_cnt_present,
     101           0 :             .transform_8x8_mode_flag                = pps->transform_8x8_mode,
     102           0 :             .MbaffFrameFlag                         = sps->mb_aff && !FIELD_PICTURE(h),
     103           0 :             .constrained_intra_pred_flag            = pps->constrained_intra_pred,
     104           0 :             .chroma_qp_index_offset                 = pps->chroma_qp_index_offset[0],
     105           0 :             .second_chroma_qp_index_offset          = pps->chroma_qp_index_offset[1],
     106           0 :             .ref_pic_flag                           = h->nal_ref_idc != 0,
     107           0 :             .frame_num                              = h->poc.frame_num,
     108           0 :             .CurrFieldOrderCnt[0]                   = h->cur_pic_ptr->field_poc[0],
     109           0 :             .CurrFieldOrderCnt[1]                   = h->cur_pic_ptr->field_poc[1],
     110             :         },
     111             :     };
     112             : 
     113           0 :     memcpy(ppc->WeightScale4x4,    pps->scaling_matrix4,    sizeof(ppc->WeightScale4x4));
     114           0 :     memcpy(ppc->WeightScale8x8[0], pps->scaling_matrix8[0], sizeof(ppc->WeightScale8x8[0]));
     115           0 :     memcpy(ppc->WeightScale8x8[1], pps->scaling_matrix8[3], sizeof(ppc->WeightScale8x8[0]));
     116             : 
     117           0 :     dpb_size = 0;
     118           0 :     for (i = 0; i < h->short_ref_count; i++)
     119           0 :         dpb_add(h, &ppc->dpb[dpb_size++], h->short_ref[i], h->short_ref[i]->frame_num);
     120           0 :     for (i = 0; i < 16; i++) {
     121           0 :         if (h->long_ref[i])
     122           0 :             dpb_add(h, &ppc->dpb[dpb_size++], h->long_ref[i], i);
     123             :     }
     124             : 
     125           0 :     for (i = dpb_size; i < FF_ARRAY_ELEMS(ppc->dpb); i++)
     126           0 :         ppc->dpb[i].PicIdx = -1;
     127             : 
     128           0 :     return 0;
     129             : }
     130             : 
     131           0 : static int nvdec_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer,
     132             :                                    uint32_t size)
     133             : {
     134           0 :     NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
     135             :     void *tmp;
     136             : 
     137           0 :     tmp = av_fast_realloc(ctx->bitstream, &ctx->bitstream_allocated,
     138           0 :                           ctx->bitstream_len + size + 3);
     139           0 :     if (!tmp)
     140           0 :         return AVERROR(ENOMEM);
     141           0 :     ctx->bitstream = tmp;
     142             : 
     143           0 :     tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
     144           0 :                           (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
     145           0 :     if (!tmp)
     146           0 :         return AVERROR(ENOMEM);
     147           0 :     ctx->slice_offsets = tmp;
     148             : 
     149           0 :     AV_WB24(ctx->bitstream + ctx->bitstream_len, 1);
     150           0 :     memcpy(ctx->bitstream + ctx->bitstream_len + 3, buffer, size);
     151           0 :     ctx->slice_offsets[ctx->nb_slices] = ctx->bitstream_len ;
     152           0 :     ctx->bitstream_len += size + 3;
     153           0 :     ctx->nb_slices++;
     154             : 
     155           0 :     return 0;
     156             : }
     157             : 
     158           0 : static int nvdec_h264_frame_params(AVCodecContext *avctx,
     159             :                                    AVBufferRef *hw_frames_ctx)
     160             : {
     161           0 :     const H264Context *h = avctx->priv_data;
     162           0 :     const SPS       *sps = h->ps.sps;
     163           0 :     return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->ref_frame_count + sps->num_reorder_frames);
     164             : }
     165             : 
     166             : const AVHWAccel ff_h264_nvdec_hwaccel = {
     167             :     .name                 = "h264_nvdec",
     168             :     .type                 = AVMEDIA_TYPE_VIDEO,
     169             :     .id                   = AV_CODEC_ID_H264,
     170             :     .pix_fmt              = AV_PIX_FMT_CUDA,
     171             :     .start_frame          = nvdec_h264_start_frame,
     172             :     .end_frame            = ff_nvdec_end_frame,
     173             :     .decode_slice         = nvdec_h264_decode_slice,
     174             :     .frame_params         = nvdec_h264_frame_params,
     175             :     .init                 = ff_nvdec_decode_init,
     176             :     .uninit               = ff_nvdec_decode_uninit,
     177             :     .priv_data_size       = sizeof(NVDECContext),
     178             : };

Generated by: LCOV version 1.13