FFmpeg
vdpau_h264.c
Go to the documentation of this file.
1 /*
2  * MPEG-4 Part 10 / AVC / H.264 HW decode acceleration through VDPAU
3  *
4  * Copyright (c) 2008 NVIDIA
5  * Copyright (c) 2013 Rémi Denis-Courmont
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include <vdpau/vdpau.h>
25 
26 #include "avcodec.h"
27 #include "h264dec.h"
28 #include "h264_ps.h"
29 #include "hwaccel_internal.h"
30 #include "mpegutils.h"
31 #include "vdpau.h"
32 #include "vdpau_internal.h"
33 
34 static int32_t h264_foc(int foc)
35 {
36  if (foc == INT_MAX)
37  foc = 0;
38  return foc;
39 }
40 
41 static void vdpau_h264_clear_rf(VdpReferenceFrameH264 *rf)
42 {
43  rf->surface = VDP_INVALID_HANDLE;
44  rf->is_long_term = VDP_FALSE;
45  rf->top_is_reference = VDP_FALSE;
46  rf->bottom_is_reference = VDP_FALSE;
47  rf->field_order_cnt[0] = 0;
48  rf->field_order_cnt[1] = 0;
49  rf->frame_idx = 0;
50 }
51 
52 static void vdpau_h264_set_rf(VdpReferenceFrameH264 *rf, H264Picture *pic,
53  int pic_structure)
54 {
55  VdpVideoSurface surface = ff_vdpau_get_surface_id(pic->f);
56 
57  if (pic_structure == 0)
58  pic_structure = pic->reference;
59 
60  rf->surface = surface;
61  rf->is_long_term = pic->reference && pic->long_ref;
62  rf->top_is_reference = (pic_structure & PICT_TOP_FIELD) != 0;
63  rf->bottom_is_reference = (pic_structure & PICT_BOTTOM_FIELD) != 0;
64  rf->field_order_cnt[0] = h264_foc(pic->field_poc[0]);
65  rf->field_order_cnt[1] = h264_foc(pic->field_poc[1]);
66  rf->frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
67 }
68 
70 {
71  H264Context * const h = avctx->priv_data;
72  struct vdpau_picture_context *pic_ctx = h->cur_pic_ptr->hwaccel_picture_private;
73  VdpPictureInfoH264 *info = &pic_ctx->info.h264;
74  int list;
75 
76  VdpReferenceFrameH264 *rf = &info->referenceFrames[0];
77 #define H264_RF_COUNT FF_ARRAY_ELEMS(info->referenceFrames)
78 
79  for (list = 0; list < 2; ++list) {
80  H264Picture **lp = list ? h->long_ref : h->short_ref;
81  int i, ls = list ? 16 : h->short_ref_count;
82 
83  for (i = 0; i < ls; ++i) {
84  H264Picture *pic = lp[i];
85  VdpReferenceFrameH264 *rf2;
86  VdpVideoSurface surface_ref;
87  int pic_frame_idx;
88 
89  if (!pic || !pic->reference)
90  continue;
91  pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
92  surface_ref = ff_vdpau_get_surface_id(pic->f);
93 
94  rf2 = &info->referenceFrames[0];
95  while (rf2 != rf) {
96  if ((rf2->surface == surface_ref) &&
97  (rf2->is_long_term == pic->long_ref) &&
98  (rf2->frame_idx == pic_frame_idx))
99  break;
100  ++rf2;
101  }
102  if (rf2 != rf) {
103  rf2->top_is_reference |= (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE;
104  rf2->bottom_is_reference |= (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
105  continue;
106  }
107 
108  if (rf >= &info->referenceFrames[H264_RF_COUNT])
109  continue;
110 
111  vdpau_h264_set_rf(rf, pic, pic->reference);
112  ++rf;
113  }
114  }
115 
116  for (; rf < &info->referenceFrames[H264_RF_COUNT]; ++rf)
118 }
119 
121  const uint8_t *buffer, uint32_t size)
122 {
123  H264Context * const h = avctx->priv_data;
124  const PPS *pps = h->ps.pps;
125  const SPS *sps = h->ps.sps;
126  H264Picture *pic = h->cur_pic_ptr;
127  struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
128  VdpPictureInfoH264 *info = &pic_ctx->info.h264;
129 #ifdef VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE
130  VdpPictureInfoH264Predictive *info2 = &pic_ctx->info.h264_predictive;
131 #endif
132 
133  /* init VdpPictureInfoH264 */
134  info->slice_count = 0;
135  info->field_order_cnt[0] = h264_foc(pic->field_poc[0]);
136  info->field_order_cnt[1] = h264_foc(pic->field_poc[1]);
137  info->is_reference = h->nal_ref_idc != 0;
138  info->frame_num = h->poc.frame_num;
139  info->field_pic_flag = h->picture_structure != PICT_FRAME;
140  info->bottom_field_flag = h->picture_structure == PICT_BOTTOM_FIELD;
141  info->num_ref_frames = sps->ref_frame_count;
142  info->mb_adaptive_frame_field_flag = sps->mb_aff && !info->field_pic_flag;
143  info->constrained_intra_pred_flag = pps->constrained_intra_pred;
144  info->weighted_pred_flag = pps->weighted_pred;
145  info->weighted_bipred_idc = pps->weighted_bipred_idc;
146  info->frame_mbs_only_flag = sps->frame_mbs_only_flag;
147  info->transform_8x8_mode_flag = pps->transform_8x8_mode;
148  info->chroma_qp_index_offset = pps->chroma_qp_index_offset[0];
149  info->second_chroma_qp_index_offset = pps->chroma_qp_index_offset[1];
150  info->pic_init_qp_minus26 = pps->init_qp - 26;
151  info->num_ref_idx_l0_active_minus1 = pps->ref_count[0] - 1;
152  info->num_ref_idx_l1_active_minus1 = pps->ref_count[1] - 1;
153  info->log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4;
154  info->pic_order_cnt_type = sps->poc_type;
155  info->log2_max_pic_order_cnt_lsb_minus4 = sps->poc_type ? 0 : sps->log2_max_poc_lsb - 4;
156  info->delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag;
157  info->direct_8x8_inference_flag = sps->direct_8x8_inference_flag;
158 #ifdef VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE
159  info2->qpprime_y_zero_transform_bypass_flag = sps->transform_bypass;
160  info2->separate_colour_plane_flag = sps->residual_color_transform_flag;
161 #endif
162  info->entropy_coding_mode_flag = pps->cabac;
163  info->pic_order_present_flag = pps->pic_order_present;
164  info->deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present;
165  info->redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present;
166 
167  memcpy(info->scaling_lists_4x4, pps->scaling_matrix4,
168  sizeof(info->scaling_lists_4x4));
169  memcpy(info->scaling_lists_8x8[0], pps->scaling_matrix8[0],
170  sizeof(info->scaling_lists_8x8[0]));
171  memcpy(info->scaling_lists_8x8[1], pps->scaling_matrix8[3],
172  sizeof(info->scaling_lists_8x8[1]));
173 
175 
176  return ff_vdpau_common_start_frame(pic_ctx, buffer, size);
177 }
178 
179 static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
180 
182  const uint8_t *buffer, uint32_t size)
183 {
184  H264Context *h = avctx->priv_data;
185  H264Picture *pic = h->cur_pic_ptr;
186  struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
187  int val;
188 
190  if (val)
191  return val;
192 
193  val = ff_vdpau_add_buffer(pic_ctx, buffer, size);
194  if (val)
195  return val;
196 
197  pic_ctx->info.h264.slice_count++;
198  return 0;
199 }
200 
202 {
203  H264Context *h = avctx->priv_data;
204  H264SliceContext *sl = &h->slice_ctx[0];
205  H264Picture *pic = h->cur_pic_ptr;
206  struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
207  int val;
208 
209  val = ff_vdpau_common_end_frame(avctx, pic->f, pic_ctx);
210  if (val < 0)
211  return val;
212 
213  ff_h264_draw_horiz_band(h, sl, 0, h->avctx->height);
214  return 0;
215 }
216 
217 static int vdpau_h264_init(AVCodecContext *avctx)
218 {
219  VdpDecoderProfile profile;
220  uint32_t level = avctx->level;
221 
222  switch (avctx->profile & ~AV_PROFILE_H264_INTRA) {
224  profile = VDP_DECODER_PROFILE_H264_BASELINE;
225  break;
227 #ifdef VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE
228  profile = VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE;
229  break;
230 #endif
232  profile = VDP_DECODER_PROFILE_H264_MAIN;
233  break;
235  profile = VDP_DECODER_PROFILE_H264_HIGH;
236  break;
237 #ifdef VDP_DECODER_PROFILE_H264_EXTENDED
239  profile = VDP_DECODER_PROFILE_H264_EXTENDED;
240  break;
241 #endif
243  /* XXX: High 10 can be treated as High so long as only 8 bits per
244  * format are supported. */
245  profile = VDP_DECODER_PROFILE_H264_HIGH;
246  break;
247 #ifdef VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE
251  profile = VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE;
252  break;
253 #endif
254  default:
255  return AVERROR(ENOTSUP);
256  }
257 
258  if ((avctx->profile & AV_PROFILE_H264_INTRA) && avctx->level == 11)
259  level = VDP_DECODER_LEVEL_H264_1b;
260 
261  return ff_vdpau_common_init(avctx, profile, level);
262 }
263 
265  .p.name = "h264_vdpau",
266  .p.type = AVMEDIA_TYPE_VIDEO,
267  .p.id = AV_CODEC_ID_H264,
268  .p.pix_fmt = AV_PIX_FMT_VDPAU,
269  .start_frame = vdpau_h264_start_frame,
270  .end_frame = vdpau_h264_end_frame,
271  .decode_slice = vdpau_h264_decode_slice,
272  .frame_priv_data_size = sizeof(struct vdpau_picture_context),
274  .uninit = ff_vdpau_common_uninit,
275  .frame_params = ff_vdpau_common_frame_params,
276  .priv_data_size = sizeof(VDPAUContext),
277  .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
278 };
PICT_FRAME
#define PICT_FRAME
Definition: mpegutils.h:38
vdpau_h264_init
static int vdpau_h264_init(AVCodecContext *avctx)
Definition: vdpau_h264.c:217
level
uint8_t level
Definition: svq3.c:204
ff_vdpau_common_frame_params
int ff_vdpau_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vdpau.c:124
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
H264_RF_COUNT
#define H264_RF_COUNT
AV_PROFILE_H264_INTRA
#define AV_PROFILE_H264_INTRA
Definition: defs.h:107
H264Picture::f
AVFrame * f
Definition: h264dec.h:107
AV_PROFILE_H264_MAIN
#define AV_PROFILE_H264_MAIN
Definition: defs.h:111
FFHWAccel::p
AVHWAccel p
The public AVHWAccel.
Definition: hwaccel_internal.h:38
ff_h264_vdpau_hwaccel
const FFHWAccel ff_h264_vdpau_hwaccel
Definition: vdpau_h264.c:264
PICT_BOTTOM_FIELD
#define PICT_BOTTOM_FIELD
Definition: mpegutils.h:37
mpegutils.h
vdpau_internal.h
H264Picture::frame_num
int frame_num
frame_num (raw frame_num from slice header)
Definition: h264dec.h:129
H264SliceContext
Definition: h264dec.h:171
AV_PROFILE_H264_EXTENDED
#define AV_PROFILE_H264_EXTENDED
Definition: defs.h:112
vdpau_picture_context
Definition: vdpau_internal.h:98
FFHWAccel
Definition: hwaccel_internal.h:34
val
static double val(void *priv, double ch)
Definition: aeval.c:78
vdpau_h264_decode_slice
static int vdpau_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vdpau_h264.c:181
ff_vdpau_add_buffer
int ff_vdpau_add_buffer(struct vdpau_picture_context *pic_ctx, const uint8_t *buf, uint32_t size)
Definition: vdpau.c:387
ff_vdpau_common_init
int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, int level)
Definition: vdpau.c:143
vdpau.h
vdpau_h264_set_reference_frames
static void vdpau_h264_set_reference_frames(AVCodecContext *avctx)
Definition: vdpau_h264.c:69
AV_PROFILE_H264_HIGH_10
#define AV_PROFILE_H264_HIGH_10
Definition: defs.h:114
info
MIPS optimizations info
Definition: mips.txt:2
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:365
VDPAUPictureInfo::h264
VdpPictureInfoH264 h264
Definition: vdpau_internal.h:44
PICT_TOP_FIELD
#define PICT_TOP_FIELD
Definition: mpegutils.h:36
vdpau_h264_clear_rf
static void vdpau_h264_clear_rf(VdpReferenceFrameH264 *rf)
Definition: vdpau_h264.c:41
ff_vdpau_common_start_frame
int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic_ctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: vdpau.c:332
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
ff_vdpau_get_surface_id
static uintptr_t ff_vdpau_get_surface_id(AVFrame *pic)
Extract VdpVideoSurface from an AVFrame.
Definition: vdpau_internal.h:38
AV_PROFILE_H264_HIGH_422
#define AV_PROFILE_H264_HIGH_422
Definition: defs.h:117
ff_h264_draw_horiz_band
void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y, int height)
Definition: h264dec.c:101
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
Definition: hwaccel_internal.h:31
hwaccel_internal.h
SPS
Sequence parameter set.
Definition: h264_ps.h:44
ff_vdpau_common_end_frame
int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame, struct vdpau_picture_context *pic_ctx)
Definition: vdpau.c:342
PPS
Picture parameter set.
Definition: h264_ps.h:110
list
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining list
Definition: filter_design.txt:25
AVCodecContext::level
int level
Encoding level descriptor.
Definition: avcodec.h:1740
vdpau_h264_end_frame
static int vdpau_h264_end_frame(AVCodecContext *avctx)
Definition: vdpau_h264.c:201
h264_ps.h
H264Picture::pic_id
int pic_id
pic_num (short -> no wrap version of pic_num, pic_num & max_pic_num; long -> long_pic_num)
Definition: h264dec.h:132
ff_vdpau_common_uninit
int ff_vdpau_common_uninit(AVCodecContext *avctx)
Definition: vdpau.c:294
VDPAUContext
Definition: vdpau_internal.h:73
H264Picture::reference
int reference
Definition: h264dec.h:145
pps
static int FUNC() pps(CodedBitstreamContext *ctx, RWContext *rw, H264RawPPS *current)
Definition: cbs_h264_syntax_template.c:404
AV_PROFILE_H264_CAVLC_444
#define AV_PROFILE_H264_CAVLC_444
Definition: defs.h:123
size
int size
Definition: twinvq_data.h:10344
AV_PIX_FMT_VDPAU
@ AV_PIX_FMT_VDPAU
HW acceleration through VDPAU, Picture.data[3] contains a VdpVideoSurface.
Definition: pixfmt.h:187
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:2135
h264dec.h
start_code_prefix
static const uint8_t start_code_prefix[3]
Definition: vdpau_h264.c:179
H264Context
H264Context.
Definition: h264dec.h:331
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
profile
int profile
Definition: mxfenc.c:2115
avcodec.h
AV_PROFILE_H264_HIGH_444_PREDICTIVE
#define AV_PROFILE_H264_HIGH_444_PREDICTIVE
Definition: defs.h:121
h264_foc
static int32_t h264_foc(int foc)
Definition: vdpau_h264.c:34
AV_PROFILE_H264_BASELINE
#define AV_PROFILE_H264_BASELINE
Definition: defs.h:109
sps
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
Definition: cbs_h264_syntax_template.c:260
AVCodecContext
main external API structure.
Definition: avcodec.h:441
AV_PROFILE_H264_HIGH
#define AV_PROFILE_H264_HIGH
Definition: defs.h:113
vdpau_picture_context::info
union VDPAUPictureInfo info
VDPAU picture information.
Definition: vdpau_internal.h:102
H264Picture::field_poc
int field_poc[2]
top/bottom POC
Definition: h264dec.h:127
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1596
H264Picture
Definition: h264dec.h:106
vdpau_h264_start_frame
static int vdpau_h264_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vdpau_h264.c:120
AV_PROFILE_H264_CONSTRAINED_BASELINE
#define AV_PROFILE_H264_CONSTRAINED_BASELINE
Definition: defs.h:110
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
H264Picture::hwaccel_picture_private
void * hwaccel_picture_private
RefStruct reference for hardware accelerator private data.
Definition: h264dec.h:122
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:468
vdpau_h264_set_rf
static void vdpau_h264_set_rf(VdpReferenceFrameH264 *rf, H264Picture *pic, int pic_structure)
Definition: vdpau_h264.c:52
int32_t
int32_t
Definition: audioconvert.c:56
h
h
Definition: vp9dsp_template.c:2038
H264Picture::long_ref
int long_ref
1->long term reference 0->short term reference
Definition: h264dec.h:134