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_pic_param(vactx
, sizeof(VAPictureParameterBufferMPEG4
));
57 pic_param
->vop_width
= s
->width
;
58 pic_param
->vop_height
= s
->height
;
59 pic_param
->forward_reference_picture
= VA_INVALID_ID
;
60 pic_param
->backward_reference_picture
= VA_INVALID_ID
;
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
->vol_fields
.bits
.resync_marker_disable
= !s
->resync_marker
;
73 pic_param
->no_of_sprite_warping_points
= s
->num_sprite_warping_points
;
74 for (i
= 0; i
< s
->num_sprite_warping_points
&& i
< 3; i
++) {
75 pic_param
->sprite_trajectory_du
[i
] = s
->sprite_traj
[i
][0];
76 pic_param
->sprite_trajectory_dv
[i
] = s
->sprite_traj
[i
][1];
78 pic_param
->quant_precision
= s
->quant_precision
;
79 pic_param
->vop_fields
.value
= 0; /* reset all bits */
80 pic_param
->vop_fields
.bits
.vop_coding_type
= s
->pict_type
- FF_I_TYPE
;
81 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;
82 pic_param
->vop_fields
.bits
.vop_rounding_type
= s
->no_rounding
;
83 pic_param
->vop_fields
.bits
.intra_dc_vlc_thr
= mpeg4_get_intra_dc_vlc_thr(s
);
84 pic_param
->vop_fields
.bits
.top_field_first
= s
->top_field_first
;
85 pic_param
->vop_fields
.bits
.alternate_vertical_scan_flag
= s
->alternate_scan
;
86 pic_param
->vop_fcode_forward
= s
->f_code
;
87 pic_param
->vop_fcode_backward
= s
->b_code
;
88 pic_param
->vop_time_increment_resolution
= avctx
->time_base
.den
;
89 pic_param
->num_macroblocks_in_gob
= s
->mb_width
* ff_h263_get_gob_height(s
);
90 pic_param
->num_gobs_in_vop
= (s
->mb_width
* s
->mb_height
) / pic_param
->num_macroblocks_in_gob
;
91 pic_param
->TRB
= s
->pb_time
;
92 pic_param
->TRD
= s
->pp_time
;
94 if (s
->pict_type
== FF_B_TYPE
)
95 pic_param
->backward_reference_picture
= ff_vaapi_get_surface_id(&s
->next_picture
);
96 if (s
->pict_type
!= FF_I_TYPE
)
97 pic_param
->forward_reference_picture
= ff_vaapi_get_surface_id(&s
->last_picture
);
99 /* Fill in VAIQMatrixBufferMPEG4 */
100 /* Only the first inverse quantisation method uses the weighthing matrices */
101 if (pic_param
->vol_fields
.bits
.quant_type
) {
102 iq_matrix
= ff_vaapi_alloc_iq_matrix(vactx
, sizeof(VAIQMatrixBufferMPEG4
));
105 iq_matrix
->load_intra_quant_mat
= 1;
106 iq_matrix
->load_non_intra_quant_mat
= 1;
108 for (i
= 0; i
< 64; i
++) {
109 int n
= s
->dsp
.idct_permutation
[ff_zigzag_direct
[i
]];
110 iq_matrix
->intra_quant_mat
[i
] = s
->intra_matrix
[n
];
111 iq_matrix
->non_intra_quant_mat
[i
] = s
->inter_matrix
[n
];
117 static int vaapi_mpeg4_end_frame(AVCodecContext
*avctx
)
119 return ff_vaapi_common_end_frame(avctx
->priv_data
);
122 static int vaapi_mpeg4_decode_slice(AVCodecContext
*avctx
, const uint8_t *buffer
, uint32_t size
)
124 MpegEncContext
* const s
= avctx
->priv_data
;
125 VASliceParameterBufferMPEG4
*slice_param
;
127 dprintf(avctx
, "vaapi_mpeg4_decode_slice(): buffer %p, size %d\n", buffer
, size
);
129 /* video_plane_with_short_video_header() contains all GOBs
130 * in-order, and this is what VA API (Intel backend) expects: only
131 * a single slice param. So fake macroblock_number for FFmpeg so
132 * that we don't call vaapi_mpeg4_decode_slice() again
134 if (avctx
->codec
->id
== CODEC_ID_H263
)
135 size
= s
->gb
.buffer_end
- buffer
;
137 /* Fill in VASliceParameterBufferMPEG4 */
138 slice_param
= (VASliceParameterBufferMPEG4
*)ff_vaapi_alloc_slice(avctx
->hwaccel_context
, buffer
, size
);
141 slice_param
->macroblock_offset
= get_bits_count(&s
->gb
) % 8;
142 slice_param
->macroblock_number
= s
->mb_y
* s
->mb_width
+ s
->mb_x
;
143 slice_param
->quant_scale
= s
->qscale
;
145 if (avctx
->codec
->id
== CODEC_ID_H263
)
146 s
->mb_y
= s
->mb_height
;
151 #if CONFIG_MPEG4_VAAPI_HWACCEL
152 AVHWAccel mpeg4_vaapi_hwaccel
= {
153 .name
= "mpeg4_vaapi",
154 .type
= CODEC_TYPE_VIDEO
,
155 .id
= CODEC_ID_MPEG4
,
156 .pix_fmt
= PIX_FMT_VAAPI_VLD
,
158 .start_frame
= vaapi_mpeg4_start_frame
,
159 .end_frame
= vaapi_mpeg4_end_frame
,
160 .decode_slice
= vaapi_mpeg4_decode_slice
,
165 #if CONFIG_H263_VAAPI_HWACCEL
166 AVHWAccel h263_vaapi_hwaccel
= {
167 .name
= "h263_vaapi",
168 .type
= CODEC_TYPE_VIDEO
,
170 .pix_fmt
= PIX_FMT_VAAPI_VLD
,
172 .start_frame
= vaapi_mpeg4_start_frame
,
173 .end_frame
= vaapi_mpeg4_end_frame
,
174 .decode_slice
= vaapi_mpeg4_decode_slice
,