2 * MPEG-4 / H.263 HW decode acceleration through VA API
4 * Copyright (C) 2008-2009 Splitted-Desktop Systems
6 * This file is part of FFmpeg.
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.
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.
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
23 #include "config_components.h"
27 #include "mpeg4videodec.h"
28 #include "mpegvideo.h"
29 #include "mpegvideodec.h"
30 #include "vaapi_decode.h"
32 /** Reconstruct bitstream intra_dc_vlc_thr */
33 static int mpeg4_get_intra_dc_vlc_thr(Mpeg4DecContext
*s
)
35 switch (s
->intra_dc_threshold
) {
48 static int vaapi_mpeg4_start_frame(AVCodecContext
*avctx
, av_unused
const uint8_t *buffer
, av_unused
uint32_t size
)
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
;
56 pic
->output_surface
= ff_vaapi_get_surface_id(s
->current_picture_ptr
->f
);
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
,
64 .short_video_header
= avctx
->codec
->id
== AV_CODEC_ID_H263
,
65 .chroma_format
= CHROMA_420
,
66 .interlaced
= !s
->progressive_sequence
,
68 .sprite_enable
= ctx
->vol_sprite_usage
,
69 .sprite_warping_accuracy
= s
->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
,
76 .no_of_sprite_warping_points
= ctx
->num_sprite_warping_points
,
77 .quant_precision
= s
->quant_precision
,
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
,
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
),
92 (s
->mb_width
* s
->mb_height
) / (s
->mb_width
* H263_GOB_HEIGHT(s
->height
)),
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];
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
);
107 err
= ff_vaapi_decode_make_param_buffer(avctx
, pic
,
108 VAPictureParameterBufferType
,
109 &pic_param
, sizeof(pic_param
));
113 /* Only the first inverse quantisation method uses the weighting matrices */
114 if (pic_param
.vol_fields
.bits
.quant_type
) {
115 VAIQMatrixBufferMPEG4 iq_matrix
;
117 iq_matrix
.load_intra_quant_mat
= 1;
118 iq_matrix
.load_non_intra_quant_mat
= 1;
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
];
126 err
= ff_vaapi_decode_make_param_buffer(avctx
, pic
,
127 VAIQMatrixBufferType
,
128 &iq_matrix
, sizeof(iq_matrix
));
135 ff_vaapi_decode_cancel(avctx
, pic
);
139 static int vaapi_mpeg4_end_frame(AVCodecContext
*avctx
)
141 MpegEncContext
*s
= avctx
->priv_data
;
142 VAAPIDecodePicture
*pic
= s
->current_picture_ptr
->hwaccel_picture_private
;
145 ret
= ff_vaapi_decode_issue(avctx
, pic
);
149 ff_mpeg_draw_horiz_band(s
, 0, s
->avctx
->height
);
155 static int vaapi_mpeg4_decode_slice(AVCodecContext
*avctx
, const uint8_t *buffer
, uint32_t size
)
157 MpegEncContext
*s
= avctx
->priv_data
;
158 VAAPIDecodePicture
*pic
= s
->current_picture_ptr
->hwaccel_picture_private
;
159 VASliceParameterBufferMPEG4 slice_param
;
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
,
171 err
= ff_vaapi_decode_make_slice_buffer(avctx
, pic
,
172 &slice_param
, sizeof(slice_param
),
175 ff_vaapi_decode_cancel(avctx
, pic
);
182 #if CONFIG_MPEG4_VAAPI_HWACCEL
183 const AVHWAccel ff_mpeg4_vaapi_hwaccel
= {
184 .name
= "mpeg4_vaapi",
185 .type
= AVMEDIA_TYPE_VIDEO
,
186 .id
= AV_CODEC_ID_MPEG4
,
187 .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
),
192 .init
= &ff_vaapi_decode_init
,
193 .uninit
= &ff_vaapi_decode_uninit
,
194 .frame_params
= &ff_vaapi_common_frame_params
,
195 .priv_data_size
= sizeof(VAAPIDecodeContext
),
196 .caps_internal
= HWACCEL_CAP_ASYNC_SAFE
,
200 #if CONFIG_H263_VAAPI_HWACCEL
201 const AVHWAccel ff_h263_vaapi_hwaccel
= {
202 .name
= "h263_vaapi",
203 .type
= AVMEDIA_TYPE_VIDEO
,
204 .id
= AV_CODEC_ID_H263
,
205 .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
),
210 .init
= &ff_vaapi_decode_init
,
211 .uninit
= &ff_vaapi_decode_uninit
,
212 .frame_params
= &ff_vaapi_common_frame_params
,
213 .priv_data_size
= sizeof(VAAPIDecodeContext
),
214 .caps_internal
= HWACCEL_CAP_ASYNC_SAFE
,