2 * Video Acceleration API (video decoding)
3 * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
5 * Copyright (C) 2008-2009 Splitted-Desktop Systems
7 * This file is part of FFmpeg.
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "vaapi_internal.h"
28 * @addtogroup VAAPI_Decoding
33 static void destroy_buffers(VADisplay display
, VABufferID
*buffers
, unsigned int n_buffers
)
36 for (i
= 0; i
< n_buffers
; i
++) {
38 vaDestroyBuffer(display
, buffers
[i
]);
44 int ff_vaapi_render_picture(struct vaapi_context
*vactx
, VASurfaceID surface
)
46 VABufferID va_buffers
[3];
47 unsigned int n_va_buffers
= 0;
49 if (!vactx
->pic_param_buf_id
)
52 vaUnmapBuffer(vactx
->display
, vactx
->pic_param_buf_id
);
53 va_buffers
[n_va_buffers
++] = vactx
->pic_param_buf_id
;
55 if (vactx
->iq_matrix_buf_id
) {
56 vaUnmapBuffer(vactx
->display
, vactx
->iq_matrix_buf_id
);
57 va_buffers
[n_va_buffers
++] = vactx
->iq_matrix_buf_id
;
60 if (vactx
->bitplane_buf_id
) {
61 vaUnmapBuffer(vactx
->display
, vactx
->bitplane_buf_id
);
62 va_buffers
[n_va_buffers
++] = vactx
->bitplane_buf_id
;
65 if (vaBeginPicture(vactx
->display
, vactx
->context_id
,
66 surface
) != VA_STATUS_SUCCESS
)
69 if (vaRenderPicture(vactx
->display
, vactx
->context_id
,
70 va_buffers
, n_va_buffers
) != VA_STATUS_SUCCESS
)
73 if (vaRenderPicture(vactx
->display
, vactx
->context_id
,
75 vactx
->n_slice_buf_ids
) != VA_STATUS_SUCCESS
)
78 if (vaEndPicture(vactx
->display
, vactx
->context_id
) != VA_STATUS_SUCCESS
)
84 int ff_vaapi_commit_slices(struct vaapi_context
*vactx
)
86 VABufferID
*slice_buf_ids
;
87 VABufferID slice_param_buf_id
, slice_data_buf_id
;
89 if (vactx
->slice_count
== 0)
93 av_fast_realloc(vactx
->slice_buf_ids
,
94 &vactx
->slice_buf_ids_alloc
,
95 (vactx
->n_slice_buf_ids
+ 2) * sizeof(slice_buf_ids
[0]));
98 vactx
->slice_buf_ids
= slice_buf_ids
;
100 slice_param_buf_id
= 0;
101 if (vaCreateBuffer(vactx
->display
, vactx
->context_id
,
102 VASliceParameterBufferType
,
103 vactx
->slice_param_size
,
104 vactx
->slice_count
, vactx
->slice_params
,
105 &slice_param_buf_id
) != VA_STATUS_SUCCESS
)
107 vactx
->slice_count
= 0;
109 slice_data_buf_id
= 0;
110 if (vaCreateBuffer(vactx
->display
, vactx
->context_id
,
111 VASliceDataBufferType
,
112 vactx
->slice_data_size
,
113 1, (void *)vactx
->slice_data
,
114 &slice_data_buf_id
) != VA_STATUS_SUCCESS
)
116 vactx
->slice_data
= NULL
;
117 vactx
->slice_data_size
= 0;
119 slice_buf_ids
[vactx
->n_slice_buf_ids
++] = slice_param_buf_id
;
120 slice_buf_ids
[vactx
->n_slice_buf_ids
++] = slice_data_buf_id
;
124 static void *alloc_buffer(struct vaapi_context
*vactx
, int type
, unsigned int size
, uint32_t *buf_id
)
129 if (vaCreateBuffer(vactx
->display
, vactx
->context_id
,
130 type
, size
, 1, NULL
, buf_id
) == VA_STATUS_SUCCESS
)
131 vaMapBuffer(vactx
->display
, *buf_id
, &data
);
136 void *ff_vaapi_alloc_pic_param(struct vaapi_context
*vactx
, unsigned int size
)
138 return alloc_buffer(vactx
, VAPictureParameterBufferType
, size
, &vactx
->pic_param_buf_id
);
141 void *ff_vaapi_alloc_iq_matrix(struct vaapi_context
*vactx
, unsigned int size
)
143 return alloc_buffer(vactx
, VAIQMatrixBufferType
, size
, &vactx
->iq_matrix_buf_id
);
146 uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context
*vactx
, uint32_t size
)
148 return alloc_buffer(vactx
, VABitPlaneBufferType
, size
, &vactx
->bitplane_buf_id
);
151 VASliceParameterBufferBase
*ff_vaapi_alloc_slice(struct vaapi_context
*vactx
, const uint8_t *buffer
, uint32_t size
)
153 uint8_t *slice_params
;
154 VASliceParameterBufferBase
*slice_param
;
156 if (!vactx
->slice_data
)
157 vactx
->slice_data
= buffer
;
158 if (vactx
->slice_data
+ vactx
->slice_data_size
!= buffer
) {
159 if (ff_vaapi_commit_slices(vactx
) < 0)
161 vactx
->slice_data
= buffer
;
165 av_fast_realloc(vactx
->slice_params
,
166 &vactx
->slice_params_alloc
,
167 (vactx
->slice_count
+ 1) * vactx
->slice_param_size
);
170 vactx
->slice_params
= slice_params
;
172 slice_param
= (VASliceParameterBufferBase
*)(slice_params
+ vactx
->slice_count
* vactx
->slice_param_size
);
173 slice_param
->slice_data_size
= size
;
174 slice_param
->slice_data_offset
= vactx
->slice_data_size
;
175 slice_param
->slice_data_flag
= VA_SLICE_DATA_FLAG_ALL
;
177 vactx
->slice_count
++;
178 vactx
->slice_data_size
+= size
;
182 void ff_vaapi_common_end_frame(AVCodecContext
*avctx
)
184 struct vaapi_context
* const vactx
= avctx
->hwaccel_context
;
186 av_dlog(avctx
, "ff_vaapi_common_end_frame()\n");
188 destroy_buffers(vactx
->display
, &vactx
->pic_param_buf_id
, 1);
189 destroy_buffers(vactx
->display
, &vactx
->iq_matrix_buf_id
, 1);
190 destroy_buffers(vactx
->display
, &vactx
->bitplane_buf_id
, 1);
191 destroy_buffers(vactx
->display
, vactx
->slice_buf_ids
, vactx
->n_slice_buf_ids
);
192 av_freep(&vactx
->slice_buf_ids
);
193 av_freep(&vactx
->slice_params
);
194 vactx
->n_slice_buf_ids
= 0;
195 vactx
->slice_buf_ids_alloc
= 0;
196 vactx
->slice_count
= 0;
197 vactx
->slice_params_alloc
= 0;