2 * gstvaapidecoder_objects.c - VA decoder objects helpers
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
5 * Copyright (C) 2011-2012 Intel Corporation
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
25 #include <gst/vaapi/gstvaapicontext.h>
26 #include "gstvaapidecoder_objects.h"
27 #include "gstvaapidecoder_priv.h"
28 #include "gstvaapicompat.h"
29 #include "gstvaapiutils.h"
32 #include "gstvaapidebug.h"
34 #define GET_DECODER(obj) GST_VAAPI_DECODER_CAST((obj)->parent_instance.codec)
35 #define GET_CONTEXT(obj) GET_DECODER(obj)->priv->context
36 #define GET_VA_DISPLAY(obj) GET_DECODER(obj)->priv->va_display
37 #define GET_VA_CONTEXT(obj) GET_DECODER(obj)->priv->va_context
39 /* ------------------------------------------------------------------------- */
40 /* --- Pictures --- */
41 /* ------------------------------------------------------------------------- */
43 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPicture,
45 GST_VAAPI_TYPE_CODEC_OBJECT)
48 destroy_slice_cb(gpointer data, gpointer user_data)
50 GstMiniObject * const object = data;
52 gst_mini_object_unref(object);
56 gst_vaapi_picture_destroy(GstVaapiPicture *picture)
58 if (picture->slices) {
59 g_ptr_array_foreach(picture->slices, destroy_slice_cb, NULL);
60 g_ptr_array_free(picture->slices, TRUE);
61 picture->slices = NULL;
64 if (picture->iq_matrix) {
65 gst_mini_object_unref(GST_MINI_OBJECT(picture->iq_matrix));
66 picture->iq_matrix = NULL;
69 if (picture->bitplane) {
70 gst_mini_object_unref(GST_MINI_OBJECT(picture->bitplane));
71 picture->bitplane = NULL;
75 g_object_unref(picture->proxy);
76 picture->proxy = NULL;
78 else if (picture->surface) {
79 /* Explicitly release any surface that was not bound to a proxy */
80 gst_vaapi_context_put_surface(GET_CONTEXT(picture), picture->surface);
82 picture->surface_id = VA_INVALID_ID;
83 picture->surface = NULL;
85 vaapi_destroy_buffer(GET_VA_DISPLAY(picture), &picture->param_id);
86 picture->param = NULL;
90 gst_vaapi_picture_create(
91 GstVaapiPicture *picture,
92 const GstVaapiCodecObjectConstructorArgs *args
97 picture->surface = gst_vaapi_context_get_surface(GET_CONTEXT(picture));
98 if (!picture->surface)
100 picture->surface_id = gst_vaapi_surface_get_id(picture->surface);
103 gst_vaapi_surface_proxy_new(GET_CONTEXT(picture), picture->surface);
107 success = vaapi_create_buffer(
108 GET_VA_DISPLAY(picture),
109 GET_VA_CONTEXT(picture),
110 VAPictureParameterBufferType,
119 picture->slices = g_ptr_array_new();
120 if (!picture->slices)
126 gst_vaapi_picture_init(GstVaapiPicture *picture)
128 picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
129 picture->surface = NULL;
130 picture->proxy = NULL;
131 picture->surface_id = VA_INVALID_ID;
132 picture->param = NULL;
133 picture->param_id = VA_INVALID_ID;
134 picture->slices = NULL;
135 picture->iq_matrix = NULL;
136 picture->bitplane = NULL;
137 picture->pts = GST_CLOCK_TIME_NONE;
141 gst_vaapi_picture_new(
142 GstVaapiDecoder *decoder,
147 GstVaapiCodecObject *object;
149 g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
151 object = gst_vaapi_codec_object_new(
152 GST_VAAPI_TYPE_PICTURE,
153 GST_VAAPI_CODEC_BASE(decoder),
159 return GST_VAAPI_PICTURE_CAST(object);
163 gst_vaapi_picture_add_slice(GstVaapiPicture *picture, GstVaapiSlice *slice)
165 g_return_if_fail(GST_VAAPI_IS_PICTURE(picture));
166 g_return_if_fail(GST_VAAPI_IS_SLICE(slice));
168 g_ptr_array_add(picture->slices, slice);
172 do_decode(VADisplay dpy, VAContextID ctx, VABufferID *buf_id, void **buf_ptr)
176 vaapi_unmap_buffer(dpy, *buf_id, buf_ptr);
178 status = vaRenderPicture(dpy, ctx, buf_id, 1);
179 if (!vaapi_check_status(status, "vaRenderPicture()"))
182 /* XXX: vaRenderPicture() is meant to destroy the VA buffer implicitly */
183 vaapi_destroy_buffer(dpy, buf_id);
188 gst_vaapi_picture_decode(GstVaapiPicture *picture)
190 GstVaapiIqMatrix *iq_matrix;
191 GstVaapiBitPlane *bitplane;
192 VADisplay va_display;
193 VAContextID va_context;
197 g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE);
199 va_display = GET_VA_DISPLAY(picture);
200 va_context = GET_VA_CONTEXT(picture);
202 GST_DEBUG("decode picture 0x%08x", picture->surface_id);
204 status = vaBeginPicture(va_display, va_context, picture->surface_id);
205 if (!vaapi_check_status(status, "vaBeginPicture()"))
208 if (!do_decode(va_display, va_context, &picture->param_id, &picture->param))
211 iq_matrix = picture->iq_matrix;
212 if (iq_matrix && !do_decode(va_display, va_context,
213 &iq_matrix->param_id, &iq_matrix->param))
216 bitplane = picture->bitplane;
217 if (bitplane && !do_decode(va_display, va_context,
218 &bitplane->data_id, (void **)&bitplane->data))
221 for (i = 0; i < picture->slices->len; i++) {
222 GstVaapiSlice * const slice = g_ptr_array_index(picture->slices, i);
223 VABufferID va_buffers[2];
225 vaapi_unmap_buffer(va_display, slice->param_id, NULL);
226 va_buffers[0] = slice->param_id;
227 va_buffers[1] = slice->data_id;
229 status = vaRenderPicture(va_display, va_context, va_buffers, 2);
230 if (!vaapi_check_status(status, "vaRenderPicture()"))
233 vaapi_destroy_buffer(va_display, &slice->param_id);
234 vaapi_destroy_buffer(va_display, &slice->data_id);
237 status = vaEndPicture(va_display, va_context);
238 if (!vaapi_check_status(status, "vaEndPicture()"))
244 gst_vaapi_picture_output(GstVaapiPicture *picture)
246 GstVaapiSurfaceProxy *proxy;
248 g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE);
253 if (!GST_VAAPI_PICTURE_IS_SKIPPED(picture)) {
254 proxy = g_object_ref(picture->proxy);
255 gst_vaapi_surface_proxy_set_timestamp(proxy, picture->pts);
256 gst_vaapi_decoder_push_surface_proxy(GET_DECODER(picture), proxy);
258 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_OUTPUT);
262 /* ------------------------------------------------------------------------- */
264 /* ------------------------------------------------------------------------- */
266 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSlice,
268 GST_VAAPI_TYPE_CODEC_OBJECT)
271 gst_vaapi_slice_destroy(GstVaapiSlice *slice)
273 VADisplay const va_display = GET_VA_DISPLAY(slice);
275 vaapi_destroy_buffer(va_display, &slice->data_id);
276 vaapi_destroy_buffer(va_display, &slice->param_id);
281 gst_vaapi_slice_create(
282 GstVaapiSlice *slice,
283 const GstVaapiCodecObjectConstructorArgs *args
286 VASliceParameterBufferBase *slice_param;
289 success = vaapi_create_buffer(
290 GET_VA_DISPLAY(slice),
291 GET_VA_CONTEXT(slice),
292 VASliceDataBufferType,
301 success = vaapi_create_buffer(
302 GET_VA_DISPLAY(slice),
303 GET_VA_CONTEXT(slice),
304 VASliceParameterBufferType,
313 slice_param = slice->param;
314 slice_param->slice_data_size = args->data_size;
315 slice_param->slice_data_offset = 0;
316 slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
321 gst_vaapi_slice_init(GstVaapiSlice *slice)
324 slice->param_id = VA_INVALID_ID;
325 slice->data_id = VA_INVALID_ID;
330 GstVaapiDecoder *decoder,
337 GstVaapiCodecObject *object;
339 g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
341 object = gst_vaapi_codec_object_new(
342 GST_VAAPI_TYPE_SLICE,
343 GST_VAAPI_CODEC_BASE(decoder),
347 return GST_VAAPI_SLICE_CAST(object);