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 "vaapi_internal.h"
25 /** Reconstruct bitstream intra_dc_vlc_thr */
26 static int mpeg4_get_intra_dc_vlc_thr(MpegEncContext
*s
)
28 switch (s
->intra_dc_threshold
) {
41 static int vaapi_mpeg4_start_frame(AVCodecContext
*avctx
, av_unused
const uint8_t *buffer
, av_unused
uint32_t size
)
43 MpegEncContext
* const s
= avctx
->priv_data
;
44 struct vaapi_context
* const vactx
= avctx
->hwaccel_context
;
45 VAPictureParameterBufferMPEG4
*pic_param
;
46 VAIQMatrixBufferMPEG4
*iq_matrix
;
49 dprintf(avctx
, "vaapi_mpeg4_start_frame()\n");
51 vactx
->slice_param_size
= sizeof(VASliceParameterBufferMPEG4
);
53 /* Fill in VAPictureParameterBufferMPEG4 */
54 pic_param
= ff_vaapi_alloc_picture(vactx
, sizeof(VAPictureParameterBufferMPEG4
));
57 pic_param
->vop_width
= s
->width
;
58 pic_param
->vop_height
= s
->height
;
59 pic_param
->forward_reference_picture
= 0xffffffff;
60 pic_param
->backward_reference_picture
= 0xffffffff;
61 pic_param
->vol_fields
.value
= 0; /* reset all bits */
62 pic_param
->vol_fields
.bits
.short_video_header
= avctx
->codec
->id
== CODEC_ID_H263
;
63 pic_param
->vol_fields
.bits
.chroma_format
= CHROMA_420
;
64 pic_param
->vol_fields
.bits
.interlaced
= !s
->progressive_sequence
;
65 pic_param
->vol_fields
.bits
.obmc_disable
= 1;
66 pic_param
->vol_fields
.bits
.sprite_enable
= s
->vol_sprite_usage
;
67 pic_param
->vol_fields
.bits
.sprite_warping_accuracy
= s
->sprite_warping_accuracy
;
68 pic_param
->vol_fields
.bits
.quant_type
= s
->mpeg_quant
;
69 pic_param
->vol_fields
.bits
.quarter_sample
= s
->quarter_sample
;
70 pic_param
->vol_fields
.bits
.data_partitioned
= s
->data_partitioning
;
71 pic_param
->vol_fields
.bits
.reversible_vlc
= s
->rvlc
;
72 pic_param
->no_of_sprite_warping_points
= s
->num_sprite_warping_points
;
73 for (i
= 0; i
< s
->num_sprite_warping_points
&& i
< 3; i
++) {
74 pic_param
->sprite_trajectory_du
[i
] = s
->sprite_traj
[i
][0];
75 pic_param
->sprite_trajectory_dv
[i
] = s
->sprite_traj
[i
][1];
77 pic_param
->quant_precision
= s
->quant_precision
;
78 pic_param
->vop_fields
.value
= 0; /* reset all bits */
79 pic_param
->vop_fields
.bits
.vop_coding_type
= s
->pict_type
- FF_I_TYPE
;
80 pic_param
->vop_fields
.bits
.backward_reference_vop_coding_type
= s
->pict_type
== FF_B_TYPE
? s
->next_picture
.pict_type
- FF_I_TYPE
: 0;
81 pic_param
->vop_fields
.bits
.vop_rounding_type
= s
->no_rounding
;
82 pic_param
->vop_fields
.bits
.intra_dc_vlc_thr
= mpeg4_get_intra_dc_vlc_thr(s
);
83 pic_param
->vop_fields
.bits
.top_field_first
= s
->top_field_first
;
84 pic_param
->vop_fields
.bits
.alternate_vertical_scan_flag
= s
->alternate_scan
;
85 pic_param
->vop_fcode_forward
= s
->f_code
;
86 pic_param
->vop_fcode_backward
= s
->b_code
;
87 pic_param
->num_macroblocks_in_gob
= s
->mb_width
* ff_h263_get_gob_height(s
);
88 pic_param
->num_gobs_in_vop
= (s
->mb_width
* s
->mb_height
) / pic_param
->num_macroblocks_in_gob
;
89 pic_param
->TRB
= s
->pb_time
;
90 pic_param
->TRD
= s
->pp_time
;
92 if (s
->pict_type
== FF_B_TYPE
)
93 pic_param
->backward_reference_picture
= ff_vaapi_get_surface(&s
->next_picture
);
94 if (s
->pict_type
!= FF_I_TYPE
)
95 pic_param
->forward_reference_picture
= ff_vaapi_get_surface(&s
->last_picture
);
97 /* Fill in VAIQMatrixBufferMPEG4 */
98 /* Only the first inverse quantisation method uses the weighthing matrices */
99 if (pic_param
->vol_fields
.bits
.quant_type
) {
100 iq_matrix
= ff_vaapi_alloc_iq_matrix(vactx
, sizeof(VAIQMatrixBufferMPEG4
));
103 iq_matrix
->load_intra_quant_mat
= 1;
104 iq_matrix
->load_non_intra_quant_mat
= 1;
106 for (i
= 0; i
< 64; i
++) {
107 int n
= s
->dsp
.idct_permutation
[ff_zigzag_direct
[i
]];
108 iq_matrix
->intra_quant_mat
[i
] = s
->intra_matrix
[n
];
109 iq_matrix
->non_intra_quant_mat
[i
] = s
->inter_matrix
[n
];
115 static int vaapi_mpeg4_end_frame(AVCodecContext
*avctx
)
117 return ff_vaapi_common_end_frame(avctx
->priv_data
);
120 static int vaapi_mpeg4_decode_slice(AVCodecContext
*avctx
, const uint8_t *buffer
, uint32_t size
)
122 MpegEncContext
* const s
= avctx
->priv_data
;
123 VASliceParameterBufferMPEG4
*slice_param
;
125 dprintf(avctx
, "vaapi_mpeg4_decode_slice(): buffer %p, size %d\n", buffer
, size
);
127 /* video_plane_with_short_video_header() contains all GOBs
128 * in-order, and this is what VA API (Intel backend) expects: only
129 * a single slice param. So fake macroblock_number for FFmpeg so
130 * that we don't call vaapi_mpeg4_decode_slice() again
132 if (avctx
->codec
->id
== CODEC_ID_H263
)
133 size
= s
->gb
.buffer_end
- buffer
;
135 /* Fill in VASliceParameterBufferMPEG4 */
136 slice_param
= (VASliceParameterBufferMPEG4
*)ff_vaapi_alloc_slice(avctx
->hwaccel_context
, buffer
, size
);
139 slice_param
->macroblock_offset
= get_bits_count(&s
->gb
) % 8;
140 slice_param
->macroblock_number
= s
->mb_y
* s
->mb_width
+ s
->mb_x
;
141 slice_param
->quant_scale
= s
->qscale
;
143 if (avctx
->codec
->id
== CODEC_ID_H263
)
144 s
->mb_y
= s
->mb_height
;
149 #if CONFIG_MPEG4_VAAPI_HWACCEL
150 AVHWAccel mpeg4_vaapi_hwaccel
= {
151 .name
= "mpeg4_vaapi",
152 .type
= CODEC_TYPE_VIDEO
,
153 .id
= CODEC_ID_MPEG4
,
154 .pix_fmt
= PIX_FMT_VAAPI_VLD
,
156 .start_frame
= vaapi_mpeg4_start_frame
,
157 .end_frame
= vaapi_mpeg4_end_frame
,
158 .decode_slice
= vaapi_mpeg4_decode_slice
,
163 #if CONFIG_H263_VAAPI_HWACCEL
164 AVHWAccel h263_vaapi_hwaccel
= {
165 .name
= "h263_vaapi",
166 .type
= CODEC_TYPE_VIDEO
,
168 .pix_fmt
= PIX_FMT_VAAPI_VLD
,
170 .start_frame
= vaapi_mpeg4_start_frame
,
171 .end_frame
= vaapi_mpeg4_end_frame
,
172 .decode_slice
= vaapi_mpeg4_decode_slice
,