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 Libav.
9 * Libav 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 * Libav 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 Libav; 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 vaUnmapBuffer(vactx
->display
, vactx
->pic_param_buf_id
);
50 va_buffers
[n_va_buffers
++] = vactx
->pic_param_buf_id
;
52 if (vactx
->iq_matrix_buf_id
) {
53 vaUnmapBuffer(vactx
->display
, vactx
->iq_matrix_buf_id
);
54 va_buffers
[n_va_buffers
++] = vactx
->iq_matrix_buf_id
;
57 if (vactx
->bitplane_buf_id
) {
58 vaUnmapBuffer(vactx
->display
, vactx
->bitplane_buf_id
);
59 va_buffers
[n_va_buffers
++] = vactx
->bitplane_buf_id
;
62 if (vaBeginPicture(vactx
->display
, vactx
->context_id
,
63 surface
) != VA_STATUS_SUCCESS
)
66 if (vaRenderPicture(vactx
->display
, vactx
->context_id
,
67 va_buffers
, n_va_buffers
) != VA_STATUS_SUCCESS
)
70 if (vaRenderPicture(vactx
->display
, vactx
->context_id
,
72 vactx
->n_slice_buf_ids
) != VA_STATUS_SUCCESS
)
75 if (vaEndPicture(vactx
->display
, vactx
->context_id
) != VA_STATUS_SUCCESS
)
81 int ff_vaapi_commit_slices(struct vaapi_context
*vactx
)
83 VABufferID
*slice_buf_ids
;
84 VABufferID slice_param_buf_id
, slice_data_buf_id
;
86 if (vactx
->slice_count
== 0)
90 av_fast_realloc(vactx
->slice_buf_ids
,
91 &vactx
->slice_buf_ids_alloc
,
92 (vactx
->n_slice_buf_ids
+ 2) * sizeof(slice_buf_ids
[0]));
95 vactx
->slice_buf_ids
= slice_buf_ids
;
97 slice_param_buf_id
= 0;
98 if (vaCreateBuffer(vactx
->display
, vactx
->context_id
,
99 VASliceParameterBufferType
,
100 vactx
->slice_param_size
,
101 vactx
->slice_count
, vactx
->slice_params
,
102 &slice_param_buf_id
) != VA_STATUS_SUCCESS
)
104 vactx
->slice_count
= 0;
106 slice_data_buf_id
= 0;
107 if (vaCreateBuffer(vactx
->display
, vactx
->context_id
,
108 VASliceDataBufferType
,
109 vactx
->slice_data_size
,
110 1, (void *)vactx
->slice_data
,
111 &slice_data_buf_id
) != VA_STATUS_SUCCESS
)
113 vactx
->slice_data
= NULL
;
114 vactx
->slice_data_size
= 0;
116 slice_buf_ids
[vactx
->n_slice_buf_ids
++] = slice_param_buf_id
;
117 slice_buf_ids
[vactx
->n_slice_buf_ids
++] = slice_data_buf_id
;
121 static void *alloc_buffer(struct vaapi_context
*vactx
, int type
, unsigned int size
, uint32_t *buf_id
)
126 if (vaCreateBuffer(vactx
->display
, vactx
->context_id
,
127 type
, size
, 1, NULL
, buf_id
) == VA_STATUS_SUCCESS
)
128 vaMapBuffer(vactx
->display
, *buf_id
, &data
);
133 void *ff_vaapi_alloc_pic_param(struct vaapi_context
*vactx
, unsigned int size
)
135 return alloc_buffer(vactx
, VAPictureParameterBufferType
, size
, &vactx
->pic_param_buf_id
);
138 void *ff_vaapi_alloc_iq_matrix(struct vaapi_context
*vactx
, unsigned int size
)
140 return alloc_buffer(vactx
, VAIQMatrixBufferType
, size
, &vactx
->iq_matrix_buf_id
);
143 uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context
*vactx
, uint32_t size
)
145 return alloc_buffer(vactx
, VABitPlaneBufferType
, size
, &vactx
->bitplane_buf_id
);
148 VASliceParameterBufferBase
*ff_vaapi_alloc_slice(struct vaapi_context
*vactx
, const uint8_t *buffer
, uint32_t size
)
150 uint8_t *slice_params
;
151 VASliceParameterBufferBase
*slice_param
;
153 if (!vactx
->slice_data
)
154 vactx
->slice_data
= buffer
;
155 if (vactx
->slice_data
+ vactx
->slice_data_size
!= buffer
) {
156 if (ff_vaapi_commit_slices(vactx
) < 0)
158 vactx
->slice_data
= buffer
;
162 av_fast_realloc(vactx
->slice_params
,
163 &vactx
->slice_params_alloc
,
164 (vactx
->slice_count
+ 1) * vactx
->slice_param_size
);
167 vactx
->slice_params
= slice_params
;
169 slice_param
= (VASliceParameterBufferBase
*)(slice_params
+ vactx
->slice_count
* vactx
->slice_param_size
);
170 slice_param
->slice_data_size
= size
;
171 slice_param
->slice_data_offset
= vactx
->slice_data_size
;
172 slice_param
->slice_data_flag
= VA_SLICE_DATA_FLAG_ALL
;
174 vactx
->slice_count
++;
175 vactx
->slice_data_size
+= size
;
179 void ff_vaapi_common_end_frame(AVCodecContext
*avctx
)
181 struct vaapi_context
* const vactx
= avctx
->hwaccel_context
;
183 av_dlog(avctx
, "ff_vaapi_common_end_frame()\n");
185 destroy_buffers(vactx
->display
, &vactx
->pic_param_buf_id
, 1);
186 destroy_buffers(vactx
->display
, &vactx
->iq_matrix_buf_id
, 1);
187 destroy_buffers(vactx
->display
, &vactx
->bitplane_buf_id
, 1);
188 destroy_buffers(vactx
->display
, vactx
->slice_buf_ids
, vactx
->n_slice_buf_ids
);
189 av_freep(&vactx
->slice_buf_ids
);
190 av_freep(&vactx
->slice_params
);
191 vactx
->n_slice_buf_ids
= 0;
192 vactx
->slice_buf_ids_alloc
= 0;
193 vactx
->slice_count
= 0;
194 vactx
->slice_params_alloc
= 0;
197 int ff_vaapi_mpeg_end_frame(AVCodecContext
*avctx
)
199 struct vaapi_context
* const vactx
= avctx
->hwaccel_context
;
200 MpegEncContext
*s
= avctx
->priv_data
;
203 ret
= ff_vaapi_commit_slices(vactx
);
207 ret
= ff_vaapi_render_picture(vactx
,
208 ff_vaapi_get_surface_id(s
->current_picture_ptr
));
212 ff_mpeg_draw_horiz_band(s
, 0, s
->avctx
->height
);
215 ff_vaapi_common_end_frame(avctx
->priv_data
);