comparison vaapi.c @ 9225:85c7a028316d libavcodec

Add common VA API data structures and helpers.
author gb
date Sun, 22 Mar 2009 01:32:27 +0000
parents
children f0732d44f655
comparison
equal deleted inserted replaced
9224:aed92dbae82e 9225:85c7a028316d
1 /*
2 * Video Acceleration API (video decoding)
3 * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
4 *
5 * Copyright (C) 2008-2009 Splitted-Desktop Systems
6 *
7 * This file is part of FFmpeg.
8 *
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.
13 *
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.
18 *
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
22 */
23
24 #include "vaapi_internal.h"
25
26 /**
27 * \addtogroup VAAPI_Decoding
28 *
29 * @{
30 */
31
32 static void destroy_buffers(VADisplay display, VABufferID *buffers, unsigned int n_buffers)
33 {
34 unsigned int i;
35 for (i = 0; i < n_buffers; i++) {
36 if (buffers[i]) {
37 vaDestroyBuffer(display, buffers[i]);
38 buffers[i] = 0;
39 }
40 }
41 }
42
43 static int render_picture(struct vaapi_context *vactx, VASurfaceID surface)
44 {
45 VABufferID va_buffers[3];
46 unsigned int n_va_buffers = 0;
47
48 if (vaCreateBuffer(vactx->display, vactx->context_id,
49 VAPictureParameterBufferType,
50 vactx->pic_param_size,
51 1, &vactx->pic_param,
52 &vactx->pic_param_buf_id) != VA_STATUS_SUCCESS)
53 return -1;
54 va_buffers[n_va_buffers++] = vactx->pic_param_buf_id;
55
56 if (vactx->iq_matrix_present) {
57 if (vaCreateBuffer(vactx->display, vactx->context_id,
58 VAIQMatrixBufferType,
59 vactx->iq_matrix_size,
60 1, &vactx->iq_matrix,
61 &vactx->iq_matrix_buf_id) != VA_STATUS_SUCCESS)
62 return -1;
63 va_buffers[n_va_buffers++] = vactx->iq_matrix_buf_id;
64 }
65
66 if (vactx->bitplane_buffer) {
67 if (vaCreateBuffer(vactx->display, vactx->context_id,
68 VABitPlaneBufferType,
69 vactx->bitplane_buffer_size,
70 1, vactx->bitplane_buffer,
71 &vactx->bitplane_buf_id) != VA_STATUS_SUCCESS)
72 return -1;
73 va_buffers[n_va_buffers++] = vactx->bitplane_buf_id;
74 }
75
76 if (vaBeginPicture(vactx->display, vactx->context_id,
77 surface) != VA_STATUS_SUCCESS)
78 return -1;
79
80 if (vaRenderPicture(vactx->display, vactx->context_id,
81 va_buffers, n_va_buffers) != VA_STATUS_SUCCESS)
82 return -1;
83
84 if (vaRenderPicture(vactx->display, vactx->context_id,
85 vactx->slice_buf_ids,
86 vactx->n_slice_buf_ids) != VA_STATUS_SUCCESS)
87 return -1;
88
89 if (vaEndPicture(vactx->display, vactx->context_id) != VA_STATUS_SUCCESS)
90 return -1;
91
92 return 0;
93 }
94
95 static int commit_slices(struct vaapi_context *vactx)
96 {
97 VABufferID *slice_buf_ids;
98 VABufferID slice_param_buf_id, slice_data_buf_id;
99
100 if (vactx->slice_count == 0)
101 return 0;
102
103 slice_buf_ids =
104 av_fast_realloc(vactx->slice_buf_ids,
105 &vactx->slice_buf_ids_alloc,
106 (vactx->n_slice_buf_ids + 2) * sizeof(slice_buf_ids[0]));
107 if (!slice_buf_ids)
108 return -1;
109 vactx->slice_buf_ids = slice_buf_ids;
110
111 slice_param_buf_id = 0;
112 if (vaCreateBuffer(vactx->display, vactx->context_id,
113 VASliceParameterBufferType,
114 vactx->slice_param_size,
115 vactx->slice_count, vactx->slice_params,
116 &slice_param_buf_id) != VA_STATUS_SUCCESS)
117 return -1;
118 vactx->slice_count = 0;
119
120 slice_data_buf_id = 0;
121 if (vaCreateBuffer(vactx->display, vactx->context_id,
122 VASliceDataBufferType,
123 vactx->slice_data_size,
124 1, (void *)vactx->slice_data,
125 &slice_data_buf_id) != VA_STATUS_SUCCESS)
126 return -1;
127 vactx->slice_data = NULL;
128 vactx->slice_data_size = 0;
129
130 slice_buf_ids[vactx->n_slice_buf_ids++] = slice_param_buf_id;
131 slice_buf_ids[vactx->n_slice_buf_ids++] = slice_data_buf_id;
132 return 0;
133 }
134
135 VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size)
136 {
137 uint8_t *slice_params;
138 VASliceParameterBufferBase *slice_param;
139
140 if (!vactx->slice_data)
141 vactx->slice_data = buffer;
142 if (vactx->slice_data + vactx->slice_data_size != buffer) {
143 if (commit_slices(vactx) < 0)
144 return NULL;
145 vactx->slice_data = buffer;
146 }
147
148 slice_params =
149 av_fast_realloc(vactx->slice_params,
150 &vactx->slice_params_alloc,
151 (vactx->slice_count + 1) * vactx->slice_param_size);
152 if (!slice_params)
153 return NULL;
154 vactx->slice_params = slice_params;
155
156 slice_param = (VASliceParameterBufferBase *)(slice_params + vactx->slice_count * vactx->slice_param_size);
157 slice_param->slice_data_size = size;
158 slice_param->slice_data_offset = vactx->slice_data_size;
159 slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
160
161 vactx->slice_count++;
162 vactx->slice_data_size += size;
163 return slice_param;
164 }
165
166 int ff_vaapi_common_end_frame(MpegEncContext *s)
167 {
168 struct vaapi_context * const vactx = s->avctx->hwaccel_context;
169 int ret = -1;
170
171 dprintf(s->avctx, "ff_vaapi_common_end_frame()\n");
172
173 if (commit_slices(vactx) < 0)
174 goto done;
175 if (vactx->n_slice_buf_ids > 0) {
176 if (render_picture(vactx, ff_vaapi_get_surface(s->current_picture_ptr)) < 0)
177 goto done;
178 ff_draw_horiz_band(s, 0, s->avctx->height);
179 }
180 ret = 0;
181
182 done:
183 destroy_buffers(vactx->display, &vactx->pic_param_buf_id, 1);
184 destroy_buffers(vactx->display, &vactx->iq_matrix_buf_id, 1);
185 destroy_buffers(vactx->display, &vactx->bitplane_buf_id, 1);
186 destroy_buffers(vactx->display, vactx->slice_buf_ids, vactx->n_slice_buf_ids);
187 av_freep(&vactx->bitplane_buffer);
188 av_freep(&vactx->slice_buf_ids);
189 av_freep(&vactx->slice_params);
190 vactx->n_slice_buf_ids = 0;
191 vactx->slice_buf_ids_alloc = 0;
192 vactx->slice_count = 0;
193 vactx->slice_params_alloc = 0;
194 return ret;
195 }
196
197 /* @} */