FFmpeg  4.4.4
nvdec_h264.c
Go to the documentation of this file.
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 static void dpb_add(const H264Context *h, CUVIDH264DPBENTRY *dst, const H264Picture *src,
33  int frame_idx)
34 {
35  FrameDecodeData *fdd = (FrameDecodeData*)src->f->private_ref->data;
36  const NVDECFrame *cf = fdd->hwaccel_priv;
37 
38  dst->PicIdx = cf ? cf->idx : -1;
39  dst->FrameIdx = frame_idx;
40  dst->is_long_term = src->long_ref;
41  dst->not_existing = 0;
42  dst->used_for_reference = src->reference & 3;
43  dst->FieldOrderCnt[0] = src->field_poc[0];
44  dst->FieldOrderCnt[1] = src->field_poc[1];
45 }
46 
48  const uint8_t *buffer, uint32_t size)
49 {
50  const H264Context *h = avctx->priv_data;
51  const PPS *pps = h->ps.pps;
52  const SPS *sps = h->ps.sps;
53 
55  CUVIDPICPARAMS *pp = &ctx->pic_params;
56  CUVIDH264PICPARAMS *ppc = &pp->CodecSpecific.h264;
57  FrameDecodeData *fdd;
58  NVDECFrame *cf;
59 
60  int i, dpb_size, ret;
61 
62  ret = ff_nvdec_start_frame(avctx, h->cur_pic_ptr->f);
63  if (ret < 0)
64  return ret;
65 
66  fdd = (FrameDecodeData*)h->cur_pic_ptr->f->private_ref->data;
67  cf = (NVDECFrame*)fdd->hwaccel_priv;
68 
69  *pp = (CUVIDPICPARAMS) {
70  .PicWidthInMbs = h->mb_width,
71  .FrameHeightInMbs = h->mb_height,
72  .CurrPicIdx = cf->idx,
73  .field_pic_flag = FIELD_PICTURE(h),
74  .bottom_field_flag = h->picture_structure == PICT_BOTTOM_FIELD,
75  .second_field = FIELD_PICTURE(h) && !h->first_field,
76  .ref_pic_flag = h->nal_ref_idc != 0,
77  .intra_pic_flag = 1,
78 
79  .CodecSpecific.h264 = {
80  .log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4,
81  .pic_order_cnt_type = sps->poc_type,
82  .log2_max_pic_order_cnt_lsb_minus4 = FFMAX(sps->log2_max_poc_lsb - 4, 0),
83  .delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag,
84  .frame_mbs_only_flag = sps->frame_mbs_only_flag,
85  .direct_8x8_inference_flag = sps->direct_8x8_inference_flag,
86  .num_ref_frames = sps->ref_frame_count,
87  .residual_colour_transform_flag = sps->residual_color_transform_flag,
88  .bit_depth_luma_minus8 = sps->bit_depth_luma - 8,
89  .bit_depth_chroma_minus8 = sps->bit_depth_chroma - 8,
90  .qpprime_y_zero_transform_bypass_flag = sps->transform_bypass,
91 
92  .entropy_coding_mode_flag = pps->cabac,
93  .pic_order_present_flag = pps->pic_order_present,
94  .num_ref_idx_l0_active_minus1 = pps->ref_count[0] - 1,
95  .num_ref_idx_l1_active_minus1 = pps->ref_count[1] - 1,
96  .weighted_pred_flag = pps->weighted_pred,
97  .weighted_bipred_idc = pps->weighted_bipred_idc,
98  .pic_init_qp_minus26 = pps->init_qp - 26,
99  .deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present,
100  .redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present,
101  .transform_8x8_mode_flag = pps->transform_8x8_mode,
102  .MbaffFrameFlag = sps->mb_aff && !FIELD_PICTURE(h),
103  .constrained_intra_pred_flag = pps->constrained_intra_pred,
104  .chroma_qp_index_offset = pps->chroma_qp_index_offset[0],
105  .second_chroma_qp_index_offset = pps->chroma_qp_index_offset[1],
106  .ref_pic_flag = h->nal_ref_idc != 0,
107  .frame_num = h->poc.frame_num,
108  .CurrFieldOrderCnt[0] = h->cur_pic_ptr->field_poc[0],
109  .CurrFieldOrderCnt[1] = h->cur_pic_ptr->field_poc[1],
110  },
111  };
112 
113  memcpy(ppc->WeightScale4x4, pps->scaling_matrix4, sizeof(ppc->WeightScale4x4));
114  memcpy(ppc->WeightScale8x8[0], pps->scaling_matrix8[0], sizeof(ppc->WeightScale8x8[0]));
115  memcpy(ppc->WeightScale8x8[1], pps->scaling_matrix8[3], sizeof(ppc->WeightScale8x8[0]));
116 
117  dpb_size = 0;
118  for (i = 0; i < h->short_ref_count; i++)
119  dpb_add(h, &ppc->dpb[dpb_size++], h->short_ref[i], h->short_ref[i]->frame_num);
120  for (i = 0; i < 16; i++) {
121  if (h->long_ref[i])
122  dpb_add(h, &ppc->dpb[dpb_size++], h->long_ref[i], i);
123  }
124 
125  for (i = dpb_size; i < FF_ARRAY_ELEMS(ppc->dpb); i++)
126  ppc->dpb[i].PicIdx = -1;
127 
128  return 0;
129 }
130 
132  uint32_t size)
133 {
135  CUVIDPICPARAMS *pp = &ctx->pic_params;
136  const H264Context *h = avctx->priv_data;
137  const H264SliceContext *sl = &h->slice_ctx[0];
138  void *tmp;
139 
140  tmp = av_fast_realloc(ctx->bitstream, &ctx->bitstream_allocated,
141  ctx->bitstream_len + size + 3);
142  if (!tmp)
143  return AVERROR(ENOMEM);
144  ctx->bitstream = tmp;
145 
146  tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
147  (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
148  if (!tmp)
149  return AVERROR(ENOMEM);
150  ctx->slice_offsets = tmp;
151 
152  AV_WB24(ctx->bitstream + ctx->bitstream_len, 1);
153  memcpy(ctx->bitstream + ctx->bitstream_len + 3, buffer, size);
154  ctx->slice_offsets[ctx->nb_slices] = ctx->bitstream_len ;
155  ctx->bitstream_len += size + 3;
156  ctx->nb_slices++;
157 
159  pp->intra_pic_flag = 0;
160 
161  return 0;
162 }
163 
165  AVBufferRef *hw_frames_ctx)
166 {
167  const H264Context *h = avctx->priv_data;
168  const SPS *sps = h->ps.sps;
169  return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->ref_frame_count + sps->num_reorder_frames, 0);
170 }
171 
173  .name = "h264_nvdec",
174  .type = AVMEDIA_TYPE_VIDEO,
175  .id = AV_CODEC_ID_H264,
176  .pix_fmt = AV_PIX_FMT_CUDA,
177  .start_frame = nvdec_h264_start_frame,
178  .end_frame = ff_nvdec_end_frame,
179  .decode_slice = nvdec_h264_decode_slice,
180  .frame_params = nvdec_h264_frame_params,
181  .init = ff_nvdec_decode_init,
182  .uninit = ff_nvdec_decode_uninit,
183  .priv_data_size = sizeof(NVDECContext),
184 };
uint8_t
Libavcodec external API header.
static int FUNC() pps(CodedBitstreamContext *ctx, RWContext *rw, H264RawPPS *current)
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
#define FFMAX(a, b)
Definition: common.h:103
@ AV_CODEC_ID_H264
Definition: codec_id.h:76
#define AVERROR(e)
Definition: error.h:43
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:478
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
@ AV_PICTURE_TYPE_SI
Switching Intra.
Definition: avutil.h:278
H.264 / AVC / MPEG-4 part10 codec.
#define FIELD_PICTURE(h)
Definition: h264dec.h:75
int i
Definition: input.c:407
#define AV_WB24(p, d)
Definition: intreadwrite.h:450
common internal API header
#define PICT_BOTTOM_FIELD
Definition: mpegutils.h:38
int ff_nvdec_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx, int dpb_size, int supports_444)
Definition: nvdec.c:695
int ff_nvdec_decode_init(AVCodecContext *avctx)
Definition: nvdec.c:330
int ff_nvdec_end_frame(AVCodecContext *avctx)
Definition: nvdec.c:635
int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: nvdec.c:559
int ff_nvdec_decode_uninit(AVCodecContext *avctx)
Definition: nvdec.c:262
static int nvdec_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: nvdec_h264.c:131
static int nvdec_h264_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: nvdec_h264.c:164
static void dpb_add(const H264Context *h, CUVIDH264DPBENTRY *dst, const H264Picture *src, int frame_idx)
Definition: nvdec_h264.c:32
static int nvdec_h264_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: nvdec_h264.c:47
const AVHWAccel ff_h264_nvdec_hwaccel
Definition: nvdec_h264.c:172
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
Definition: pixfmt.h:235
static char buffer[20]
Definition: seek.c:32
#define FF_ARRAY_ELEMS(a)
A reference to a data buffer.
Definition: buffer.h:84
main external API structure.
Definition: avcodec.h:536
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:571
void * priv_data
Definition: avcodec.h:563
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:180
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:2444
This struct stores per-frame lavc-internal data and is attached to it via private_ref.
Definition: decode.h:34
void * hwaccel_priv
Per-frame private data for hwaccels.
Definition: decode.h:52
H264Context.
Definition: h264dec.h:344
unsigned int idx
Definition: nvdec.h:45
Picture parameter set.
Definition: h264_ps.h:111
Sequence parameter set.
Definition: h264_ps.h:44
static uint8_t tmp[11]
Definition: aes_ctr.c:27
#define src
Definition: vp8dsp.c:255
int dpb_size
Definition: h264_levels.c:107
AVFormatContext * ctx
Definition: movenc.c:48
int size