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 #include "mpeg4video.h"
27 /** Reconstruct bitstream intra_dc_vlc_thr */
28 static int mpeg4_get_intra_dc_vlc_thr(Mpeg4DecContext
*s
)
30 switch (s
->intra_dc_threshold
) {
43 static int vaapi_mpeg4_start_frame(AVCodecContext
*avctx
, av_unused
const uint8_t *buffer
, av_unused
uint32_t size
)
45 Mpeg4DecContext
*ctx
= avctx
->priv_data
;
46 MpegEncContext
* const s
= &ctx
->m
;
47 struct vaapi_context
* const vactx
= avctx
->hwaccel_context
;
48 VAPictureParameterBufferMPEG4
*pic_param
;
49 VAIQMatrixBufferMPEG4
*iq_matrix
;
52 av_dlog(avctx
, "vaapi_mpeg4_start_frame()\n");
54 vactx
->slice_param_size
= sizeof(VASliceParameterBufferMPEG4
);
56 /* Fill in VAPictureParameterBufferMPEG4 */
57 pic_param
= ff_vaapi_alloc_pic_param(vactx
, sizeof(VAPictureParameterBufferMPEG4
));
60 pic_param
->vop_width
= s
->width
;
61 pic_param
->vop_height
= s
->height
;
62 pic_param
->forward_reference_picture
= VA_INVALID_ID
;
63 pic_param
->backward_reference_picture
= VA_INVALID_ID
;
64 pic_param
->vol_fields
.value
= 0; /* reset all bits */
65 pic_param
->vol_fields
.bits
.short_video_header
= avctx
->codec
->id
== AV_CODEC_ID_H263
;
66 pic_param
->vol_fields
.bits
.chroma_format
= CHROMA_420
;
67 pic_param
->vol_fields
.bits
.interlaced
= !s
->progressive_sequence
;
68 pic_param
->vol_fields
.bits
.obmc_disable
= 1;
69 pic_param
->vol_fields
.bits
.sprite_enable
= ctx
->vol_sprite_usage
;
70 pic_param
->vol_fields
.bits
.sprite_warping_accuracy
= s
->sprite_warping_accuracy
;
71 pic_param
->vol_fields
.bits
.quant_type
= s
->mpeg_quant
;
72 pic_param
->vol_fields
.bits
.quarter_sample
= s
->quarter_sample
;
73 pic_param
->vol_fields
.bits
.data_partitioned
= s
->data_partitioning
;
74 pic_param
->vol_fields
.bits
.reversible_vlc
= ctx
->rvlc
;
75 pic_param
->vol_fields
.bits
.resync_marker_disable
= !ctx
->resync_marker
;
76 pic_param
->no_of_sprite_warping_points
= ctx
->num_sprite_warping_points
;
77 for (i
= 0; i
< ctx
->num_sprite_warping_points
&& i
< 3; i
++) {
78 pic_param
->sprite_trajectory_du
[i
] = ctx
->sprite_traj
[i
][0];
79 pic_param
->sprite_trajectory_dv
[i
] = ctx
->sprite_traj
[i
][1];
81 pic_param
->quant_precision
= s
->quant_precision
;
82 pic_param
->vop_fields
.value
= 0; /* reset all bits */
83 pic_param
->vop_fields
.bits
.vop_coding_type
= s
->pict_type
- AV_PICTURE_TYPE_I
;
84 pic_param
->vop_fields
.bits
.backward_reference_vop_coding_type
= s
->pict_type
== AV_PICTURE_TYPE_B
? s
->next_picture
.f
->pict_type
- AV_PICTURE_TYPE_I
: 0;
85 pic_param
->vop_fields
.bits
.vop_rounding_type
= s
->no_rounding
;
86 pic_param
->vop_fields
.bits
.intra_dc_vlc_thr
= mpeg4_get_intra_dc_vlc_thr(ctx
);
87 pic_param
->vop_fields
.bits
.top_field_first
= s
->top_field_first
;
88 pic_param
->vop_fields
.bits
.alternate_vertical_scan_flag
= s
->alternate_scan
;
89 pic_param
->vop_fcode_forward
= s
->f_code
;
90 pic_param
->vop_fcode_backward
= s
->b_code
;
91 pic_param
->vop_time_increment_resolution
= avctx
->framerate
.num
;
92 pic_param
->num_macroblocks_in_gob
= s
->mb_width
* ff_h263_get_gob_height(s
);
93 pic_param
->num_gobs_in_vop
= (s
->mb_width
* s
->mb_height
) / pic_param
->num_macroblocks_in_gob
;
94 pic_param
->TRB
= s
->pb_time
;
95 pic_param
->TRD
= s
->pp_time
;
97 if (s
->pict_type
== AV_PICTURE_TYPE_B
)
98 pic_param
->backward_reference_picture
= ff_vaapi_get_surface_id(s
->next_picture
.f
);
99 if (s
->pict_type
!= AV_PICTURE_TYPE_I
)
100 pic_param
->forward_reference_picture
= ff_vaapi_get_surface_id(s
->last_picture
.f
);
102 /* Fill in VAIQMatrixBufferMPEG4 */
103 /* Only the first inverse quantisation method uses the weighting matrices */
104 if (pic_param
->vol_fields
.bits
.quant_type
) {
105 iq_matrix
= ff_vaapi_alloc_iq_matrix(vactx
, sizeof(VAIQMatrixBufferMPEG4
));
108 iq_matrix
->load_intra_quant_mat
= 1;
109 iq_matrix
->load_non_intra_quant_mat
= 1;
111 for (i
= 0; i
< 64; i
++) {
112 int n
= s
->idsp
.idct_permutation
[ff_zigzag_direct
[i
]];
113 iq_matrix
->intra_quant_mat
[i
] = s
->intra_matrix
[n
];
114 iq_matrix
->non_intra_quant_mat
[i
] = s
->inter_matrix
[n
];
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 av_dlog(avctx
, "vaapi_mpeg4_decode_slice(): buffer %p, size %d\n", buffer
, size
);
127 /* Fill in VASliceParameterBufferMPEG4 */
128 slice_param
= (VASliceParameterBufferMPEG4
*)ff_vaapi_alloc_slice(avctx
->hwaccel_context
, buffer
, size
);
131 slice_param
->macroblock_offset
= get_bits_count(&s
->gb
) % 8;
132 slice_param
->macroblock_number
= 0;
133 slice_param
->quant_scale
= s
->qscale
;
138 #if CONFIG_MPEG4_VAAPI_HWACCEL
139 AVHWAccel ff_mpeg4_vaapi_hwaccel
= {
140 .name
= "mpeg4_vaapi",
141 .type
= AVMEDIA_TYPE_VIDEO
,
142 .id
= AV_CODEC_ID_MPEG4
,
143 .pix_fmt
= AV_PIX_FMT_VAAPI_VLD
,
144 .start_frame
= vaapi_mpeg4_start_frame
,
145 .end_frame
= ff_vaapi_mpeg_end_frame
,
146 .decode_slice
= vaapi_mpeg4_decode_slice
,
150 #if CONFIG_H263_VAAPI_HWACCEL
151 AVHWAccel ff_h263_vaapi_hwaccel
= {
152 .name
= "h263_vaapi",
153 .type
= AVMEDIA_TYPE_VIDEO
,
154 .id
= AV_CODEC_ID_H263
,
155 .pix_fmt
= AV_PIX_FMT_VAAPI_VLD
,
156 .start_frame
= vaapi_mpeg4_start_frame
,
157 .end_frame
= ff_vaapi_mpeg_end_frame
,
158 .decode_slice
= vaapi_mpeg4_decode_slice
,