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 "internal.h"
28 #include "h264dec.h"
29 #include "h264_ps.h"
30 #include "hwconfig.h"
31 #include "mpegutils.h"
32 #include "vdpau.h"
33 #include "vdpau_internal.h"
34 
35 static int32_t h264_foc(int foc)
36 {
37  if (foc == INT_MAX)
38  foc = 0;
39  return foc;
40 }
41 
42 static void vdpau_h264_clear_rf(VdpReferenceFrameH264 *rf)
43 {
44  rf->surface = VDP_INVALID_HANDLE;
45  rf->is_long_term = VDP_FALSE;
46  rf->top_is_reference = VDP_FALSE;
47  rf->bottom_is_reference = VDP_FALSE;
48  rf->field_order_cnt[0] = 0;
49  rf->field_order_cnt[1] = 0;
50  rf->frame_idx = 0;
51 }
52 
53 static void vdpau_h264_set_rf(VdpReferenceFrameH264 *rf, H264Picture *pic,
54  int pic_structure)
55 {
56  VdpVideoSurface surface = ff_vdpau_get_surface_id(pic->f);
57 
58  if (pic_structure == 0)
59  pic_structure = pic->reference;
60 
61  rf->surface = surface;
62  rf->is_long_term = pic->reference && pic->long_ref;
63  rf->top_is_reference = (pic_structure & PICT_TOP_FIELD) != 0;
64  rf->bottom_is_reference = (pic_structure & PICT_BOTTOM_FIELD) != 0;
65  rf->field_order_cnt[0] = h264_foc(pic->field_poc[0]);
66  rf->field_order_cnt[1] = h264_foc(pic->field_poc[1]);
67  rf->frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
68 }
69 
71 {
72  H264Context * const h = avctx->priv_data;
73  struct vdpau_picture_context *pic_ctx = h->cur_pic_ptr->hwaccel_picture_private;
74  VdpPictureInfoH264 *info = &pic_ctx->info.h264;
75  int list;
76 
77  VdpReferenceFrameH264 *rf = &info->referenceFrames[0];
78 #define H264_RF_COUNT FF_ARRAY_ELEMS(info->referenceFrames)
79 
80  for (list = 0; list < 2; ++list) {
81  H264Picture **lp = list ? h->long_ref : h->short_ref;
82  int i, ls = list ? 16 : h->short_ref_count;
83 
84  for (i = 0; i < ls; ++i) {
85  H264Picture *pic = lp[i];
86  VdpReferenceFrameH264 *rf2;
87  VdpVideoSurface surface_ref;
88  int pic_frame_idx;
89 
90  if (!pic || !pic->reference)
91  continue;
92  pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
93  surface_ref = ff_vdpau_get_surface_id(pic->f);
94 
95  rf2 = &info->referenceFrames[0];
96  while (rf2 != rf) {
97  if ((rf2->surface == surface_ref) &&
98  (rf2->is_long_term == pic->long_ref) &&
99  (rf2->frame_idx == pic_frame_idx))
100  break;
101  ++rf2;
102  }
103  if (rf2 != rf) {
104  rf2->top_is_reference |= (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE;
105  rf2->bottom_is_reference |= (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
106  continue;
107  }
108 
109  if (rf >= &info->referenceFrames[H264_RF_COUNT])
110  continue;
111 
112  vdpau_h264_set_rf(rf, pic, pic->reference);
113  ++rf;
114  }
115  }
116 
117  for (; rf < &info->referenceFrames[H264_RF_COUNT]; ++rf)
119 }
120 
122  const uint8_t *buffer, uint32_t size)
123 {
124  H264Context * const h = avctx->priv_data;
125  const PPS *pps = h->ps.pps;
126  const SPS *sps = h->ps.sps;
127  H264Picture *pic = h->cur_pic_ptr;
128  struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
129  VdpPictureInfoH264 *info = &pic_ctx->info.h264;
130 #ifdef VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE
131  VdpPictureInfoH264Predictive *info2 = &pic_ctx->info.h264_predictive;
132 #endif
133 
134  /* init VdpPictureInfoH264 */
135  info->slice_count = 0;
136  info->field_order_cnt[0] = h264_foc(pic->field_poc[0]);
137  info->field_order_cnt[1] = h264_foc(pic->field_poc[1]);
138  info->is_reference = h->nal_ref_idc != 0;
139  info->frame_num = h->poc.frame_num;
140  info->field_pic_flag = h->picture_structure != PICT_FRAME;
141  info->bottom_field_flag = h->picture_structure == PICT_BOTTOM_FIELD;
142  info->num_ref_frames = sps->ref_frame_count;
143  info->mb_adaptive_frame_field_flag = sps->mb_aff && !info->field_pic_flag;
144  info->constrained_intra_pred_flag = pps->constrained_intra_pred;
145  info->weighted_pred_flag = pps->weighted_pred;
146  info->weighted_bipred_idc = pps->weighted_bipred_idc;
147  info->frame_mbs_only_flag = sps->frame_mbs_only_flag;
148  info->transform_8x8_mode_flag = pps->transform_8x8_mode;
149  info->chroma_qp_index_offset = pps->chroma_qp_index_offset[0];
150  info->second_chroma_qp_index_offset = pps->chroma_qp_index_offset[1];
151  info->pic_init_qp_minus26 = pps->init_qp - 26;
152  info->num_ref_idx_l0_active_minus1 = pps->ref_count[0] - 1;
153  info->num_ref_idx_l1_active_minus1 = pps->ref_count[1] - 1;
154  info->log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4;
155  info->pic_order_cnt_type = sps->poc_type;
156  info->log2_max_pic_order_cnt_lsb_minus4 = sps->poc_type ? 0 : sps->log2_max_poc_lsb - 4;
157  info->delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag;
158  info->direct_8x8_inference_flag = sps->direct_8x8_inference_flag;
159 #ifdef VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE
160  info2->qpprime_y_zero_transform_bypass_flag = sps->transform_bypass;
161  info2->separate_colour_plane_flag = sps->residual_color_transform_flag;
162 #endif
163  info->entropy_coding_mode_flag = pps->cabac;
164  info->pic_order_present_flag = pps->pic_order_present;
165  info->deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present;
166  info->redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present;
167 
168  memcpy(info->scaling_lists_4x4, pps->scaling_matrix4,
169  sizeof(info->scaling_lists_4x4));
170  memcpy(info->scaling_lists_8x8[0], pps->scaling_matrix8[0],
171  sizeof(info->scaling_lists_8x8[0]));
172  memcpy(info->scaling_lists_8x8[1], pps->scaling_matrix8[3],
173  sizeof(info->scaling_lists_8x8[1]));
174 
176 
177  return ff_vdpau_common_start_frame(pic_ctx, buffer, size);
178 }
179 
180 static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
181 
183  const uint8_t *buffer, uint32_t size)
184 {
185  H264Context *h = avctx->priv_data;
186  H264Picture *pic = h->cur_pic_ptr;
187  struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
188  int val;
189 
191  if (val)
192  return val;
193 
194  val = ff_vdpau_add_buffer(pic_ctx, buffer, size);
195  if (val)
196  return val;
197 
198  pic_ctx->info.h264.slice_count++;
199  return 0;
200 }
201 
203 {
204  H264Context *h = avctx->priv_data;
205  H264SliceContext *sl = &h->slice_ctx[0];
206  H264Picture *pic = h->cur_pic_ptr;
207  struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
208  int val;
209 
210  val = ff_vdpau_common_end_frame(avctx, pic->f, pic_ctx);
211  if (val < 0)
212  return val;
213 
214  ff_h264_draw_horiz_band(h, sl, 0, h->avctx->height);
215  return 0;
216 }
217 
218 static int vdpau_h264_init(AVCodecContext *avctx)
219 {
220  VdpDecoderProfile profile;
221  uint32_t level = avctx->level;
222 
223  switch (avctx->profile & ~FF_PROFILE_H264_INTRA) {
225  profile = VDP_DECODER_PROFILE_H264_BASELINE;
226  break;
228 #ifdef VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE
229  profile = VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE;
230  break;
231 #endif
233  profile = VDP_DECODER_PROFILE_H264_MAIN;
234  break;
236  profile = VDP_DECODER_PROFILE_H264_HIGH;
237  break;
238 #ifdef VDP_DECODER_PROFILE_H264_EXTENDED
240  profile = VDP_DECODER_PROFILE_H264_EXTENDED;
241  break;
242 #endif
244  /* XXX: High 10 can be treated as High so long as only 8 bits per
245  * format are supported. */
246  profile = VDP_DECODER_PROFILE_H264_HIGH;
247  break;
248 #ifdef VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE
252  profile = VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE;
253  break;
254 #endif
255  default:
256  return AVERROR(ENOTSUP);
257  }
258 
259  if ((avctx->profile & FF_PROFILE_H264_INTRA) && avctx->level == 11)
260  level = VDP_DECODER_LEVEL_H264_1b;
261 
262  return ff_vdpau_common_init(avctx, profile, level);
263 }
264 
266  .name = "h264_vdpau",
267  .type = AVMEDIA_TYPE_VIDEO,
268  .id = AV_CODEC_ID_H264,
269  .pix_fmt = AV_PIX_FMT_VDPAU,
270  .start_frame = vdpau_h264_start_frame,
271  .end_frame = vdpau_h264_end_frame,
272  .decode_slice = vdpau_h264_decode_slice,
273  .frame_priv_data_size = sizeof(struct vdpau_picture_context),
275  .uninit = ff_vdpau_common_uninit,
276  .frame_params = ff_vdpau_common_frame_params,
277  .priv_data_size = sizeof(VDPAUContext),
278  .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
279 };
PICT_FRAME
#define PICT_FRAME
Definition: mpegutils.h:39
hwconfig.h
vdpau_h264_init
static int vdpau_h264_init(AVCodecContext *avctx)
Definition: vdpau_h264.c:218
level
uint8_t level
Definition: svq3.c:210
ff_vdpau_common_frame_params
int ff_vdpau_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vdpau.c:114
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
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
H264Picture::f
AVFrame * f
Definition: h264dec.h:129
FF_PROFILE_H264_INTRA
#define FF_PROFILE_H264_INTRA
Definition: avcodec.h:1896
FF_PROFILE_H264_BASELINE
#define FF_PROFILE_H264_BASELINE
Definition: avcodec.h:1898
FF_PROFILE_H264_CONSTRAINED_BASELINE
#define FF_PROFILE_H264_CONSTRAINED_BASELINE
Definition: avcodec.h:1899
profile
mfxU16 profile
Definition: qsvenc.c:45
internal.h
FF_PROFILE_H264_HIGH_444_PREDICTIVE
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE
Definition: avcodec.h:1910
PICT_BOTTOM_FIELD
#define PICT_BOTTOM_FIELD
Definition: mpegutils.h:38
FF_PROFILE_H264_CAVLC_444
#define FF_PROFILE_H264_CAVLC_444
Definition: avcodec.h:1912
mpegutils.h
vdpau_internal.h
H264Picture::frame_num
int frame_num
frame_num (raw frame_num from slice header)
Definition: h264dec.h:149
H264SliceContext
Definition: h264dec.h:183
AVHWAccel
Definition: avcodec.h:2410
vdpau_picture_context
Definition: vdpau_internal.h:95
FF_PROFILE_H264_HIGH
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:1902
val
static double val(void *priv, double ch)
Definition: aeval.c:76
vdpau_h264_decode_slice
static int vdpau_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vdpau_h264.c:182
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:377
ff_vdpau_common_init
int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, int level)
Definition: vdpau.c:133
vdpau.h
vdpau_h264_set_reference_frames
static void vdpau_h264_set_reference_frames(AVCodecContext *avctx)
Definition: vdpau_h264.c:70
FF_PROFILE_H264_EXTENDED
#define FF_PROFILE_H264_EXTENDED
Definition: avcodec.h:1901
info
MIPS optimizations info
Definition: mips.txt:2
VDPAUPictureInfo::h264
VdpPictureInfoH264 h264
Definition: vdpau_internal.h:44
PICT_TOP_FIELD
#define PICT_TOP_FIELD
Definition: mpegutils.h:37
vdpau_h264_clear_rf
static void vdpau_h264_clear_rf(VdpReferenceFrameH264 *rf)
Definition: vdpau_h264.c:42
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:322
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:76
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
ff_h264_draw_horiz_band
void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y, int height)
Definition: h264dec.c:103
int32_t
int32_t
Definition: audio_convert.c:194
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:332
PPS
Picture parameter set.
Definition: h264_ps.h:111
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
level
Definition: avcodec.h:1982
vdpau_h264_end_frame
static int vdpau_h264_end_frame(AVCodecContext *avctx)
Definition: vdpau_h264.c:202
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:152
ff_vdpau_common_uninit
int ff_vdpau_common_uninit(AVCodecContext *avctx)
Definition: vdpau.c:284
VDPAUContext
Definition: vdpau_internal.h:70
H264Picture::reference
int reference
Definition: h264dec.h:160
pps
static int FUNC() pps(CodedBitstreamContext *ctx, RWContext *rw, H264RawPPS *current)
Definition: cbs_h264_syntax_template.c:404
FF_PROFILE_H264_HIGH_422
#define FF_PROFILE_H264_HIGH_422
Definition: avcodec.h:1906
size
int size
Definition: twinvq_data.h:11134
ff_h264_vdpau_hwaccel
const AVHWAccel ff_h264_vdpau_hwaccel
Definition: vdpau_h264.c:265
AV_PIX_FMT_VDPAU
@ AV_PIX_FMT_VDPAU
HW acceleration through VDPAU, Picture.data[3] contains a VdpVideoSurface.
Definition: pixfmt.h:197
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:2416
h264dec.h
start_code_prefix
static const uint8_t start_code_prefix[3]
Definition: vdpau_h264.c:180
H264Context
H264Context.
Definition: h264dec.h:343
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Definition: hwconfig.h:26
uint8_t
uint8_t
Definition: audio_convert.c:194
avcodec.h
h264_foc
static int32_t h264_foc(int foc)
Definition: vdpau_h264.c:35
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:526
vdpau_picture_context::info
union VDPAUPictureInfo info
VDPAU picture information.
Definition: vdpau_internal.h:99
H264Picture::field_poc
int field_poc[2]
top/bottom POC
Definition: h264dec.h:147
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:1859
H264Picture
Definition: h264dec.h:128
vdpau_h264_start_frame
static int vdpau_h264_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vdpau_h264.c:121
FF_PROFILE_H264_MAIN
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:1900
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
H264Picture::hwaccel_picture_private
void * hwaccel_picture_private
hardware accelerator private data
Definition: h264dec.h:142
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:553
FF_PROFILE_H264_HIGH_10
#define FF_PROFILE_H264_HIGH_10
Definition: avcodec.h:1903
vdpau_h264_set_rf
static void vdpau_h264_set_rf(VdpReferenceFrameH264 *rf, H264Picture *pic, int pic_structure)
Definition: vdpau_h264.c:53
h
h
Definition: vp9dsp_template.c:2038
H264Picture::long_ref
int long_ref
1->long term reference 0->short term reference
Definition: h264dec.h:154