FFmpeg
vaapi_mpeg4.c
Go to the documentation of this file.
1 /*
2  * MPEG-4 / H.263 HW decode acceleration through VA API
3  *
4  * Copyright (C) 2008-2009 Splitted-Desktop Systems
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 "config_components.h"
24 
25 #include "h263.h"
26 #include "hwaccel_internal.h"
27 #include "mpeg4videodec.h"
28 #include "mpegvideo.h"
29 #include "mpegvideodec.h"
30 #include "vaapi_decode.h"
31 
32 /** Reconstruct bitstream intra_dc_vlc_thr */
34 {
35  switch (s->intra_dc_threshold) {
36  case 99: return 0;
37  case 13: return 1;
38  case 15: return 2;
39  case 17: return 3;
40  case 19: return 4;
41  case 21: return 5;
42  case 23: return 6;
43  case 0: return 7;
44  }
45  return 0;
46 }
47 
48 static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
49 {
50  Mpeg4DecContext *ctx = avctx->priv_data;
51  MpegEncContext *s = &ctx->m;
52  VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private;
53  VAPictureParameterBufferMPEG4 pic_param;
54  int i, err;
55 
56  pic->output_surface = ff_vaapi_get_surface_id(s->current_picture_ptr->f);
57 
58  pic_param = (VAPictureParameterBufferMPEG4) {
59  .vop_width = s->width,
60  .vop_height = s->height,
61  .forward_reference_picture = VA_INVALID_ID,
62  .backward_reference_picture = VA_INVALID_ID,
63  .vol_fields.bits = {
64  .short_video_header = avctx->codec->id == AV_CODEC_ID_H263,
65  .chroma_format = CHROMA_420,
66  .interlaced = !s->progressive_sequence,
67  .obmc_disable = 1,
68  .sprite_enable = ctx->vol_sprite_usage,
69  .sprite_warping_accuracy = ctx->sprite_warping_accuracy,
70  .quant_type = s->mpeg_quant,
71  .quarter_sample = s->quarter_sample,
72  .data_partitioned = s->data_partitioning,
73  .reversible_vlc = ctx->rvlc,
74  .resync_marker_disable = !ctx->resync_marker,
75  },
76  .no_of_sprite_warping_points = ctx->num_sprite_warping_points,
77  .quant_precision = s->quant_precision,
78  .vop_fields.bits = {
79  .vop_coding_type = s->pict_type - AV_PICTURE_TYPE_I,
80  .backward_reference_vop_coding_type =
81  s->pict_type == AV_PICTURE_TYPE_B ? s->next_picture.f->pict_type - AV_PICTURE_TYPE_I : 0,
82  .vop_rounding_type = s->no_rounding,
83  .intra_dc_vlc_thr = mpeg4_get_intra_dc_vlc_thr(ctx),
84  .top_field_first = s->top_field_first,
85  .alternate_vertical_scan_flag = s->alternate_scan,
86  },
87  .vop_fcode_forward = s->f_code,
88  .vop_fcode_backward = s->b_code,
89  .vop_time_increment_resolution = avctx->framerate.num,
90  .num_macroblocks_in_gob = s->mb_width * H263_GOB_HEIGHT(s->height),
91  .num_gobs_in_vop =
92  (s->mb_width * s->mb_height) / (s->mb_width * H263_GOB_HEIGHT(s->height)),
93  .TRB = s->pb_time,
94  .TRD = s->pp_time,
95  };
96 
97  for (i = 0; i < ctx->num_sprite_warping_points && i < 3; i++) {
98  pic_param.sprite_trajectory_du[i] = ctx->sprite_traj[i][0];
99  pic_param.sprite_trajectory_dv[i] = ctx->sprite_traj[i][1];
100  }
101 
102  if (s->pict_type == AV_PICTURE_TYPE_B)
103  pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_picture.f);
104  if (s->pict_type != AV_PICTURE_TYPE_I)
105  pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_picture.f);
106 
107  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
108  VAPictureParameterBufferType,
109  &pic_param, sizeof(pic_param));
110  if (err < 0)
111  goto fail;
112 
113  /* Only the first inverse quantisation method uses the weighting matrices */
114  if (pic_param.vol_fields.bits.quant_type) {
115  VAIQMatrixBufferMPEG4 iq_matrix;
116 
117  iq_matrix.load_intra_quant_mat = 1;
118  iq_matrix.load_non_intra_quant_mat = 1;
119 
120  for (i = 0; i < 64; i++) {
121  int n = s->idsp.idct_permutation[ff_zigzag_direct[i]];
122  iq_matrix.intra_quant_mat[i] = s->intra_matrix[n];
123  iq_matrix.non_intra_quant_mat[i] = s->inter_matrix[n];
124  }
125 
126  err = ff_vaapi_decode_make_param_buffer(avctx, pic,
127  VAIQMatrixBufferType,
128  &iq_matrix, sizeof(iq_matrix));
129  if (err < 0)
130  goto fail;
131  }
132  return 0;
133 
134 fail:
135  ff_vaapi_decode_cancel(avctx, pic);
136  return err;
137 }
138 
140 {
141  MpegEncContext *s = avctx->priv_data;
142  VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private;
143  int ret;
144 
145  ret = ff_vaapi_decode_issue(avctx, pic);
146  if (ret < 0)
147  goto fail;
148 
149  ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
150 
151 fail:
152  return ret;
153 }
154 
155 static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
156 {
157  MpegEncContext *s = avctx->priv_data;
158  VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private;
159  VASliceParameterBufferMPEG4 slice_param;
160  int err;
161 
162  slice_param = (VASliceParameterBufferMPEG4) {
163  .slice_data_size = size,
164  .slice_data_offset = 0,
165  .slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
166  .macroblock_offset = get_bits_count(&s->gb) % 8,
167  .macroblock_number = 0,
168  .quant_scale = s->qscale,
169  };
170 
171  err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
172  &slice_param, 1, sizeof(slice_param),
173  buffer, size);
174  if (err < 0) {
175  ff_vaapi_decode_cancel(avctx, pic);
176  return err;
177  }
178 
179  return 0;
180 }
181 
182 #if CONFIG_MPEG4_VAAPI_HWACCEL
184  .p.name = "mpeg4_vaapi",
185  .p.type = AVMEDIA_TYPE_VIDEO,
186  .p.id = AV_CODEC_ID_MPEG4,
187  .p.pix_fmt = AV_PIX_FMT_VAAPI,
188  .start_frame = &vaapi_mpeg4_start_frame,
189  .end_frame = &vaapi_mpeg4_end_frame,
190  .decode_slice = &vaapi_mpeg4_decode_slice,
191  .frame_priv_data_size = sizeof(VAAPIDecodePicture),
194  .frame_params = &ff_vaapi_common_frame_params,
195  .priv_data_size = sizeof(VAAPIDecodeContext),
196  .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
197 };
198 #endif
199 
200 #if CONFIG_H263_VAAPI_HWACCEL
202  .p.name = "h263_vaapi",
203  .p.type = AVMEDIA_TYPE_VIDEO,
204  .p.id = AV_CODEC_ID_H263,
205  .p.pix_fmt = AV_PIX_FMT_VAAPI,
206  .start_frame = &vaapi_mpeg4_start_frame,
207  .end_frame = &vaapi_mpeg4_end_frame,
208  .decode_slice = &vaapi_mpeg4_decode_slice,
209  .frame_priv_data_size = sizeof(VAAPIDecodePicture),
212  .frame_params = &ff_vaapi_common_frame_params,
213  .priv_data_size = sizeof(VAAPIDecodeContext),
214  .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
215 };
216 #endif
vaapi_mpeg4_decode_slice
static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vaapi_mpeg4.c:155
H263_GOB_HEIGHT
#define H263_GOB_HEIGHT(h)
Definition: h263.h:28
ff_vaapi_get_surface_id
static VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic)
Definition: vaapi_decode.h:30
VAAPIDecodeContext
Definition: vaapi_decode.h:50
mpeg4videodec.h
vaapi_decode.h
vaapi_mpeg4_end_frame
static int vaapi_mpeg4_end_frame(AVCodecContext *avctx)
Definition: vaapi_mpeg4.c:139
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:266
av_unused
#define av_unused
Definition: attributes.h:131
FFHWAccel::p
AVHWAccel p
The public AVHWAccel.
Definition: hwaccel_internal.h:38
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
ff_h263_vaapi_hwaccel
const struct FFHWAccel ff_h263_vaapi_hwaccel
VAAPIDecodePicture
Definition: vaapi_decode.h:39
vaapi_mpeg4_start_frame
static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: vaapi_mpeg4.c:48
mpegvideo.h
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:560
ff_vaapi_decode_make_param_buffer
int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, int type, const void *data, size_t size)
Definition: vaapi_decode.c:33
FFHWAccel
Definition: hwaccel_internal.h:34
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:454
fail
#define fail()
Definition: checkasm.h:179
AVRational::num
int num
Numerator.
Definition: rational.h:59
VAAPIDecodePicture::output_surface
VASurfaceID output_surface
Definition: vaapi_decode.h:40
mpegvideodec.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
ff_vaapi_decode_init
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:661
ff_vaapi_common_frame_params
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:637
ctx
AVFormatContext * ctx
Definition: movenc.c:48
ff_vaapi_decode_uninit
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:707
ff_vaapi_decode_issue
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:152
ff_mpeg4_vaapi_hwaccel
const struct FFHWAccel ff_mpeg4_vaapi_hwaccel
HWACCEL_CAP_ASYNC_SAFE
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
Definition: hwaccel_internal.h:31
hwaccel_internal.h
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
Mpeg4DecContext
Definition: mpeg4videodec.h:34
mpeg4_get_intra_dc_vlc_thr
static int mpeg4_get_intra_dc_vlc_thr(Mpeg4DecContext *s)
Reconstruct bitstream intra_dc_vlc_thr.
Definition: vaapi_mpeg4.c:33
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:365
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:56
size
int size
Definition: twinvq_data.h:10344
ff_mpeg_draw_horiz_band
void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
Definition: mpegvideo_dec.c:535
ff_vaapi_decode_cancel
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:226
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:126
AVCodec::id
enum AVCodecID id
Definition: codec.h:201
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:2094
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
CHROMA_420
#define CHROMA_420
Definition: mpegvideo.h:449
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:98
ret
ret
Definition: filter_design.txt:187
AVCodecContext
main external API structure.
Definition: avcodec.h:445
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:281
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
ff_vaapi_decode_make_slice_buffer
int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, const void *params_data, int nb_params, size_t params_size, const void *slice_data, size_t slice_size)
Definition: vaapi_decode.c:62
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:67
h263.h