ffmpeg / libavcodec / vaapi_mpeg4.c @ 2912e87a
History | View | Annotate | Download (7.56 KB)
1 | b4df9736 | Gwenole Beauchesne | /*
|
---|---|---|---|
2 | * MPEG-4 / H.263 HW decode acceleration through VA API
|
||
3 | *
|
||
4 | * Copyright (C) 2008-2009 Splitted-Desktop Systems
|
||
5 | *
|
||
6 | 2912e87a | Mans Rullgard | * This file is part of Libav.
|
7 | b4df9736 | Gwenole Beauchesne | *
|
8 | 2912e87a | Mans Rullgard | * Libav is free software; you can redistribute it and/or
|
9 | b4df9736 | Gwenole Beauchesne | * 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 | 2912e87a | Mans Rullgard | * Libav is distributed in the hope that it will be useful,
|
14 | b4df9736 | Gwenole Beauchesne | * 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 | 2912e87a | Mans Rullgard | * License along with Libav; if not, write to the Free Software
|
20 | b4df9736 | Gwenole Beauchesne | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21 | */
|
||
22 | |||
23 | #include "vaapi_internal.h" |
||
24 | 7447204d | Måns Rullgård | #include "h263.h" |
25 | b4df9736 | Gwenole Beauchesne | |
26 | /** Reconstruct bitstream intra_dc_vlc_thr */
|
||
27 | static int mpeg4_get_intra_dc_vlc_thr(MpegEncContext *s) |
||
28 | { |
||
29 | switch (s->intra_dc_threshold) {
|
||
30 | case 99: return 0; |
||
31 | case 13: return 1; |
||
32 | case 15: return 2; |
||
33 | case 17: return 3; |
||
34 | case 19: return 4; |
||
35 | case 21: return 5; |
||
36 | case 23: return 6; |
||
37 | case 0: return 7; |
||
38 | } |
||
39 | return 0; |
||
40 | } |
||
41 | |||
42 | static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) |
||
43 | { |
||
44 | MpegEncContext * const s = avctx->priv_data;
|
||
45 | struct vaapi_context * const vactx = avctx->hwaccel_context; |
||
46 | VAPictureParameterBufferMPEG4 *pic_param; |
||
47 | VAIQMatrixBufferMPEG4 *iq_matrix; |
||
48 | int i;
|
||
49 | |||
50 | dfd2a005 | Luca Barbato | av_dlog(avctx, "vaapi_mpeg4_start_frame()\n");
|
51 | b4df9736 | Gwenole Beauchesne | |
52 | vactx->slice_param_size = sizeof(VASliceParameterBufferMPEG4);
|
||
53 | |||
54 | /* Fill in VAPictureParameterBufferMPEG4 */
|
||
55 | 8b086712 | Gwenole Beauchesne | pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferMPEG4));
|
56 | b4df9736 | Gwenole Beauchesne | if (!pic_param)
|
57 | return -1; |
||
58 | pic_param->vop_width = s->width; |
||
59 | pic_param->vop_height = s->height; |
||
60 | e6d3534f | Gwenole Beauchesne | pic_param->forward_reference_picture = VA_INVALID_ID; |
61 | pic_param->backward_reference_picture = VA_INVALID_ID; |
||
62 | b4df9736 | Gwenole Beauchesne | pic_param->vol_fields.value = 0; /* reset all bits */ |
63 | pic_param->vol_fields.bits.short_video_header = avctx->codec->id == CODEC_ID_H263; |
||
64 | pic_param->vol_fields.bits.chroma_format = CHROMA_420; |
||
65 | pic_param->vol_fields.bits.interlaced = !s->progressive_sequence; |
||
66 | pic_param->vol_fields.bits.obmc_disable = 1;
|
||
67 | pic_param->vol_fields.bits.sprite_enable = s->vol_sprite_usage; |
||
68 | pic_param->vol_fields.bits.sprite_warping_accuracy = s->sprite_warping_accuracy; |
||
69 | pic_param->vol_fields.bits.quant_type = s->mpeg_quant; |
||
70 | pic_param->vol_fields.bits.quarter_sample = s->quarter_sample; |
||
71 | pic_param->vol_fields.bits.data_partitioned = s->data_partitioning; |
||
72 | pic_param->vol_fields.bits.reversible_vlc = s->rvlc; |
||
73 | c1977fbb | Gwenole Beauchesne | pic_param->vol_fields.bits.resync_marker_disable = !s->resync_marker; |
74 | b4df9736 | Gwenole Beauchesne | pic_param->no_of_sprite_warping_points = s->num_sprite_warping_points; |
75 | for (i = 0; i < s->num_sprite_warping_points && i < 3; i++) { |
||
76 | pic_param->sprite_trajectory_du[i] = s->sprite_traj[i][0];
|
||
77 | pic_param->sprite_trajectory_dv[i] = s->sprite_traj[i][1];
|
||
78 | } |
||
79 | pic_param->quant_precision = s->quant_precision; |
||
80 | pic_param->vop_fields.value = 0; /* reset all bits */ |
||
81 | pic_param->vop_fields.bits.vop_coding_type = s->pict_type - FF_I_TYPE; |
||
82 | 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;
|
||
83 | pic_param->vop_fields.bits.vop_rounding_type = s->no_rounding; |
||
84 | pic_param->vop_fields.bits.intra_dc_vlc_thr = mpeg4_get_intra_dc_vlc_thr(s); |
||
85 | pic_param->vop_fields.bits.top_field_first = s->top_field_first; |
||
86 | pic_param->vop_fields.bits.alternate_vertical_scan_flag = s->alternate_scan; |
||
87 | pic_param->vop_fcode_forward = s->f_code; |
||
88 | pic_param->vop_fcode_backward = s->b_code; |
||
89 | c1977fbb | Gwenole Beauchesne | pic_param->vop_time_increment_resolution = avctx->time_base.den; |
90 | b4df9736 | Gwenole Beauchesne | pic_param->num_macroblocks_in_gob = s->mb_width * ff_h263_get_gob_height(s); |
91 | pic_param->num_gobs_in_vop = (s->mb_width * s->mb_height) / pic_param->num_macroblocks_in_gob; |
||
92 | pic_param->TRB = s->pb_time; |
||
93 | pic_param->TRD = s->pp_time; |
||
94 | |||
95 | if (s->pict_type == FF_B_TYPE)
|
||
96 | 36ad2b3e | Gwenole Beauchesne | pic_param->backward_reference_picture = ff_vaapi_get_surface_id(&s->next_picture); |
97 | b4df9736 | Gwenole Beauchesne | if (s->pict_type != FF_I_TYPE)
|
98 | 36ad2b3e | Gwenole Beauchesne | pic_param->forward_reference_picture = ff_vaapi_get_surface_id(&s->last_picture); |
99 | b4df9736 | Gwenole Beauchesne | |
100 | /* Fill in VAIQMatrixBufferMPEG4 */
|
||
101 | /* Only the first inverse quantisation method uses the weighthing matrices */
|
||
102 | if (pic_param->vol_fields.bits.quant_type) {
|
||
103 | iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferMPEG4));
|
||
104 | if (!iq_matrix)
|
||
105 | return -1; |
||
106 | iq_matrix->load_intra_quant_mat = 1;
|
||
107 | iq_matrix->load_non_intra_quant_mat = 1;
|
||
108 | |||
109 | for (i = 0; i < 64; i++) { |
||
110 | int n = s->dsp.idct_permutation[ff_zigzag_direct[i]];
|
||
111 | iq_matrix->intra_quant_mat[i] = s->intra_matrix[n]; |
||
112 | iq_matrix->non_intra_quant_mat[i] = s->inter_matrix[n]; |
||
113 | } |
||
114 | } |
||
115 | return 0; |
||
116 | } |
||
117 | |||
118 | static int vaapi_mpeg4_end_frame(AVCodecContext *avctx) |
||
119 | { |
||
120 | return ff_vaapi_common_end_frame(avctx->priv_data);
|
||
121 | } |
||
122 | |||
123 | static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) |
||
124 | { |
||
125 | MpegEncContext * const s = avctx->priv_data;
|
||
126 | VASliceParameterBufferMPEG4 *slice_param; |
||
127 | |||
128 | dfd2a005 | Luca Barbato | av_dlog(avctx, "vaapi_mpeg4_decode_slice(): buffer %p, size %d\n", buffer, size);
|
129 | b4df9736 | Gwenole Beauchesne | |
130 | /* video_plane_with_short_video_header() contains all GOBs
|
||
131 | * in-order, and this is what VA API (Intel backend) expects: only
|
||
132 | * a single slice param. So fake macroblock_number for FFmpeg so
|
||
133 | * that we don't call vaapi_mpeg4_decode_slice() again
|
||
134 | */
|
||
135 | if (avctx->codec->id == CODEC_ID_H263)
|
||
136 | size = s->gb.buffer_end - buffer; |
||
137 | |||
138 | /* Fill in VASliceParameterBufferMPEG4 */
|
||
139 | slice_param = (VASliceParameterBufferMPEG4 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); |
||
140 | if (!slice_param)
|
||
141 | return -1; |
||
142 | slice_param->macroblock_offset = get_bits_count(&s->gb) % 8;
|
||
143 | slice_param->macroblock_number = s->mb_y * s->mb_width + s->mb_x; |
||
144 | slice_param->quant_scale = s->qscale; |
||
145 | |||
146 | if (avctx->codec->id == CODEC_ID_H263)
|
||
147 | s->mb_y = s->mb_height; |
||
148 | |||
149 | return 0; |
||
150 | } |
||
151 | |||
152 | #if CONFIG_MPEG4_VAAPI_HWACCEL
|
||
153 | d1b6f33b | Luca Barbato | AVHWAccel ff_mpeg4_vaapi_hwaccel = { |
154 | b4df9736 | Gwenole Beauchesne | .name = "mpeg4_vaapi",
|
155 | 72415b2a | Stefano Sabatini | .type = AVMEDIA_TYPE_VIDEO, |
156 | b4df9736 | Gwenole Beauchesne | .id = CODEC_ID_MPEG4, |
157 | .pix_fmt = PIX_FMT_VAAPI_VLD, |
||
158 | .capabilities = 0,
|
||
159 | .start_frame = vaapi_mpeg4_start_frame, |
||
160 | .end_frame = vaapi_mpeg4_end_frame, |
||
161 | .decode_slice = vaapi_mpeg4_decode_slice, |
||
162 | .priv_data_size = 0,
|
||
163 | }; |
||
164 | #endif
|
||
165 | |||
166 | #if CONFIG_H263_VAAPI_HWACCEL
|
||
167 | d1b6f33b | Luca Barbato | AVHWAccel ff_h263_vaapi_hwaccel = { |
168 | b4df9736 | Gwenole Beauchesne | .name = "h263_vaapi",
|
169 | 72415b2a | Stefano Sabatini | .type = AVMEDIA_TYPE_VIDEO, |
170 | b4df9736 | Gwenole Beauchesne | .id = CODEC_ID_H263, |
171 | .pix_fmt = PIX_FMT_VAAPI_VLD, |
||
172 | .capabilities = 0,
|
||
173 | .start_frame = vaapi_mpeg4_start_frame, |
||
174 | .end_frame = vaapi_mpeg4_end_frame, |
||
175 | .decode_slice = vaapi_mpeg4_decode_slice, |
||
176 | .priv_data_size = 0,
|
||
177 | }; |
||
178 | #endif |