Mercurial > libavcodec.hg
annotate vaapi.c @ 11352:6e0af2cfdcfe libavcodec
Do MC and IDCT in coding (hilbert) order
This increases the slice size to 64 pixels, due to having to decode an
entire chroma superblock row per slice.
This can be up to 6% slower depending on clip and CPU, but is necessary
for future optimizations that gain significantly more than was lost.
author | conrad |
---|---|
date | Wed, 03 Mar 2010 23:27:40 +0000 |
parents | de8d07d87c45 |
children |
rev | line source |
---|---|
9225 | 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 | |
9292
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
48 vaUnmapBuffer(vactx->display, vactx->pic_param_buf_id); |
9225 | 49 va_buffers[n_va_buffers++] = vactx->pic_param_buf_id; |
50 | |
9292
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
51 if (vactx->iq_matrix_buf_id) { |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
52 vaUnmapBuffer(vactx->display, vactx->iq_matrix_buf_id); |
9225 | 53 va_buffers[n_va_buffers++] = vactx->iq_matrix_buf_id; |
54 } | |
55 | |
9292
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
56 if (vactx->bitplane_buf_id) { |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
57 vaUnmapBuffer(vactx->display, vactx->bitplane_buf_id); |
9225 | 58 va_buffers[n_va_buffers++] = vactx->bitplane_buf_id; |
59 } | |
60 | |
61 if (vaBeginPicture(vactx->display, vactx->context_id, | |
62 surface) != VA_STATUS_SUCCESS) | |
63 return -1; | |
64 | |
65 if (vaRenderPicture(vactx->display, vactx->context_id, | |
66 va_buffers, n_va_buffers) != VA_STATUS_SUCCESS) | |
67 return -1; | |
68 | |
69 if (vaRenderPicture(vactx->display, vactx->context_id, | |
70 vactx->slice_buf_ids, | |
71 vactx->n_slice_buf_ids) != VA_STATUS_SUCCESS) | |
72 return -1; | |
73 | |
74 if (vaEndPicture(vactx->display, vactx->context_id) != VA_STATUS_SUCCESS) | |
75 return -1; | |
76 | |
77 return 0; | |
78 } | |
79 | |
80 static int commit_slices(struct vaapi_context *vactx) | |
81 { | |
82 VABufferID *slice_buf_ids; | |
83 VABufferID slice_param_buf_id, slice_data_buf_id; | |
84 | |
85 if (vactx->slice_count == 0) | |
86 return 0; | |
87 | |
88 slice_buf_ids = | |
89 av_fast_realloc(vactx->slice_buf_ids, | |
90 &vactx->slice_buf_ids_alloc, | |
91 (vactx->n_slice_buf_ids + 2) * sizeof(slice_buf_ids[0])); | |
92 if (!slice_buf_ids) | |
93 return -1; | |
94 vactx->slice_buf_ids = slice_buf_ids; | |
95 | |
96 slice_param_buf_id = 0; | |
97 if (vaCreateBuffer(vactx->display, vactx->context_id, | |
98 VASliceParameterBufferType, | |
99 vactx->slice_param_size, | |
100 vactx->slice_count, vactx->slice_params, | |
101 &slice_param_buf_id) != VA_STATUS_SUCCESS) | |
102 return -1; | |
103 vactx->slice_count = 0; | |
104 | |
105 slice_data_buf_id = 0; | |
106 if (vaCreateBuffer(vactx->display, vactx->context_id, | |
107 VASliceDataBufferType, | |
108 vactx->slice_data_size, | |
109 1, (void *)vactx->slice_data, | |
110 &slice_data_buf_id) != VA_STATUS_SUCCESS) | |
111 return -1; | |
112 vactx->slice_data = NULL; | |
113 vactx->slice_data_size = 0; | |
114 | |
115 slice_buf_ids[vactx->n_slice_buf_ids++] = slice_param_buf_id; | |
116 slice_buf_ids[vactx->n_slice_buf_ids++] = slice_data_buf_id; | |
117 return 0; | |
118 } | |
119 | |
9292
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
120 static void *alloc_buffer(struct vaapi_context *vactx, int type, unsigned int size, uint32_t *buf_id) |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
121 { |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
122 void *data = NULL; |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
123 |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
124 *buf_id = 0; |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
125 if (vaCreateBuffer(vactx->display, vactx->context_id, |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
126 type, size, 1, NULL, buf_id) == VA_STATUS_SUCCESS) |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
127 vaMapBuffer(vactx->display, *buf_id, &data); |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
128 |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
129 return data; |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
130 } |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
131 |
10724
de8d07d87c45
Rename ff_vaapi_alloc_picture() to ff_vaapi_alloc_pic_param().
gb
parents:
10723
diff
changeset
|
132 void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size) |
9292
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
133 { |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
134 return alloc_buffer(vactx, VAPictureParameterBufferType, size, &vactx->pic_param_buf_id); |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
135 } |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
136 |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
137 void *ff_vaapi_alloc_iq_matrix(struct vaapi_context *vactx, unsigned int size) |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
138 { |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
139 return alloc_buffer(vactx, VAIQMatrixBufferType, size, &vactx->iq_matrix_buf_id); |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
140 } |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
141 |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
142 uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size) |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
143 { |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
144 return alloc_buffer(vactx, VABitPlaneBufferType, size, &vactx->bitplane_buf_id); |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
145 } |
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9225
diff
changeset
|
146 |
9225 | 147 VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size) |
148 { | |
149 uint8_t *slice_params; | |
150 VASliceParameterBufferBase *slice_param; | |
151 | |
152 if (!vactx->slice_data) | |
153 vactx->slice_data = buffer; | |
154 if (vactx->slice_data + vactx->slice_data_size != buffer) { | |
155 if (commit_slices(vactx) < 0) | |
156 return NULL; | |
157 vactx->slice_data = buffer; | |
158 } | |
159 | |
160 slice_params = | |
161 av_fast_realloc(vactx->slice_params, | |
162 &vactx->slice_params_alloc, | |
163 (vactx->slice_count + 1) * vactx->slice_param_size); | |
164 if (!slice_params) | |
165 return NULL; | |
166 vactx->slice_params = slice_params; | |
167 | |
168 slice_param = (VASliceParameterBufferBase *)(slice_params + vactx->slice_count * vactx->slice_param_size); | |
169 slice_param->slice_data_size = size; | |
170 slice_param->slice_data_offset = vactx->slice_data_size; | |
171 slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL; | |
172 | |
173 vactx->slice_count++; | |
174 vactx->slice_data_size += size; | |
175 return slice_param; | |
176 } | |
177 | |
178 int ff_vaapi_common_end_frame(MpegEncContext *s) | |
179 { | |
180 struct vaapi_context * const vactx = s->avctx->hwaccel_context; | |
181 int ret = -1; | |
182 | |
183 dprintf(s->avctx, "ff_vaapi_common_end_frame()\n"); | |
184 | |
185 if (commit_slices(vactx) < 0) | |
186 goto done; | |
187 if (vactx->n_slice_buf_ids > 0) { | |
10723
3f08c340020f
Rename ff_vaapi_get_surface() to ff_vaapi_get_surface_id().
gb
parents:
9292
diff
changeset
|
188 if (render_picture(vactx, ff_vaapi_get_surface_id(s->current_picture_ptr)) < 0) |
9225 | 189 goto done; |
190 ff_draw_horiz_band(s, 0, s->avctx->height); | |
191 } | |
192 ret = 0; | |
193 | |
194 done: | |
195 destroy_buffers(vactx->display, &vactx->pic_param_buf_id, 1); | |
196 destroy_buffers(vactx->display, &vactx->iq_matrix_buf_id, 1); | |
197 destroy_buffers(vactx->display, &vactx->bitplane_buf_id, 1); | |
198 destroy_buffers(vactx->display, vactx->slice_buf_ids, vactx->n_slice_buf_ids); | |
199 av_freep(&vactx->slice_buf_ids); | |
200 av_freep(&vactx->slice_params); | |
201 vactx->n_slice_buf_ids = 0; | |
202 vactx->slice_buf_ids_alloc = 0; | |
203 vactx->slice_count = 0; | |
204 vactx->slice_params_alloc = 0; | |
205 return ret; | |
206 } | |
207 | |
208 /* @} */ |