~ubuntu-branches/ubuntu/quantal/gstreamer-vaapi/quantal

« back to all changes in this revision

Viewing changes to gst-libs/gst/vaapi/gstvaapisubpicture.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2012-02-10 14:35:09 UTC
  • Revision ID: package-import@ubuntu.com-20120210143509-wq9j8uqb5leu1iik
Tags: upstream-0.3.4
ImportĀ upstreamĀ versionĀ 0.3.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  gstvaapisubpicture.c - VA subpicture abstraction
 
3
 *
 
4
 *  Copyright (C) 2010-2011 Splitted-Desktop Systems
 
5
 *  Copyright (C) 2011 Intel Corporation
 
6
 *
 
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.
 
11
 *
 
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.
 
16
 *
 
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
 
21
 */
 
22
 
 
23
/**
 
24
 * SECTION:gstvaapisubpicture
 
25
 * @short_description: VA subpicture abstraction
 
26
 */
 
27
 
 
28
#include "sysdeps.h"
 
29
#include <string.h>
 
30
#include "gstvaapicompat.h"
 
31
#include "gstvaapiutils.h"
 
32
#include "gstvaapisubpicture.h"
 
33
#include "gstvaapi_priv.h"
 
34
 
 
35
#define DEBUG 1
 
36
#include "gstvaapidebug.h"
 
37
 
 
38
G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, GST_VAAPI_TYPE_OBJECT);
 
39
 
 
40
#define GST_VAAPI_SUBPICTURE_GET_PRIVATE(obj)                   \
 
41
    (G_TYPE_INSTANCE_GET_PRIVATE((obj),                         \
 
42
                                 GST_VAAPI_TYPE_SUBPICTURE,     \
 
43
                                 GstVaapiSubpicturePrivate))
 
44
 
 
45
struct _GstVaapiSubpicturePrivate {
 
46
    GstVaapiImage      *image;
 
47
};
 
48
 
 
49
enum {
 
50
    PROP_0,
 
51
 
 
52
    PROP_IMAGE
 
53
};
 
54
 
 
55
static void
 
56
gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture)
 
57
{
 
58
    GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture);
 
59
    GstVaapiSubpicturePrivate * const priv = subpicture->priv;
 
60
    VASubpictureID subpicture_id;
 
61
    VAStatus status;
 
62
 
 
63
    subpicture_id = GST_VAAPI_OBJECT_ID(subpicture);
 
64
    GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT,
 
65
              GST_VAAPI_ID_ARGS(subpicture_id));
 
66
 
 
67
    if (subpicture_id != VA_INVALID_ID) {
 
68
        if (display) {
 
69
            GST_VAAPI_DISPLAY_LOCK(display);
 
70
            status = vaDestroySubpicture(
 
71
                GST_VAAPI_DISPLAY_VADISPLAY(display),
 
72
                subpicture_id
 
73
            );
 
74
            GST_VAAPI_DISPLAY_UNLOCK(display);
 
75
            if (!vaapi_check_status(status, "vaDestroySubpicture()"))
 
76
                g_warning("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT,
 
77
                          GST_VAAPI_ID_ARGS(subpicture_id));
 
78
        }
 
79
        GST_VAAPI_OBJECT_ID(subpicture) = VA_INVALID_ID;
 
80
    }
 
81
 
 
82
    if (priv->image) {
 
83
        g_object_unref(priv->image);
 
84
        priv->image = NULL;
 
85
    }
 
86
}
 
87
 
 
88
static gboolean
 
89
gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture)
 
90
{
 
91
    GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture);
 
92
    GstVaapiSubpicturePrivate * const priv = subpicture->priv;
 
93
    VASubpictureID subpicture_id;
 
94
    VAStatus status;
 
95
 
 
96
    if (!priv->image)
 
97
        return FALSE;
 
98
 
 
99
    GST_VAAPI_DISPLAY_LOCK(display);
 
100
    status = vaCreateSubpicture(
 
101
        GST_VAAPI_DISPLAY_VADISPLAY(display),
 
102
        GST_VAAPI_OBJECT_ID(priv->image),
 
103
        &subpicture_id
 
104
    );
 
105
    GST_VAAPI_DISPLAY_UNLOCK(display);
 
106
    if (!vaapi_check_status(status, "vaCreateSubpicture()"))
 
107
        return FALSE;
 
108
 
 
109
    GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT,
 
110
              GST_VAAPI_ID_ARGS(subpicture_id));
 
111
    GST_VAAPI_OBJECT_ID(subpicture) = subpicture_id;
 
112
    return TRUE;
 
113
}
 
114
 
 
115
static void
 
116
gst_vaapi_subpicture_finalize(GObject *object)
 
117
{
 
118
    gst_vaapi_subpicture_destroy(GST_VAAPI_SUBPICTURE(object));
 
119
 
 
120
    G_OBJECT_CLASS(gst_vaapi_subpicture_parent_class)->finalize(object);
 
121
}
 
122
 
 
123
static void
 
124
gst_vaapi_subpicture_set_property(
 
125
    GObject      *object,
 
126
    guint         prop_id,
 
127
    const GValue *value,
 
128
    GParamSpec   *pspec
 
129
)
 
130
{
 
131
    GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object);
 
132
 
 
133
    switch (prop_id) {
 
134
    case PROP_IMAGE:
 
135
        gst_vaapi_subpicture_set_image(subpicture, g_value_get_object(value));
 
136
        break;
 
137
    default:
 
138
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 
139
        break;
 
140
    }
 
141
}
 
142
 
 
143
static void
 
144
gst_vaapi_subpicture_get_property(
 
145
    GObject    *object,
 
146
    guint       prop_id,
 
147
    GValue     *value,
 
148
    GParamSpec *pspec
 
149
)
 
150
{
 
151
    GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object);
 
152
 
 
153
    switch (prop_id) {
 
154
    case PROP_IMAGE:
 
155
        g_value_set_object(value, gst_vaapi_subpicture_get_image(subpicture));
 
156
        break;
 
157
    default:
 
158
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 
159
        break;
 
160
    }
 
161
}
 
162
 
 
163
static void
 
164
gst_vaapi_subpicture_class_init(GstVaapiSubpictureClass *klass)
 
165
{
 
166
    GObjectClass * const object_class = G_OBJECT_CLASS(klass);
 
167
 
 
168
    g_type_class_add_private(klass, sizeof(GstVaapiSubpicturePrivate));
 
169
 
 
170
    object_class->finalize     = gst_vaapi_subpicture_finalize;
 
171
    object_class->set_property = gst_vaapi_subpicture_set_property;
 
172
    object_class->get_property = gst_vaapi_subpicture_get_property;
 
173
 
 
174
    /**
 
175
     * GstVaapiSubpicture:image:
 
176
     *
 
177
     * The #GstVaapiImage this subpicture is bound to.
 
178
     */
 
179
    g_object_class_install_property
 
180
        (object_class,
 
181
         PROP_IMAGE,
 
182
         g_param_spec_object("image",
 
183
                             "Image",
 
184
                             "The GstVaapiImage this subpicture is bound to",
 
185
                             GST_VAAPI_TYPE_IMAGE,
 
186
                             G_PARAM_READWRITE));
 
187
}
 
188
 
 
189
static void
 
190
gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture)
 
191
{
 
192
    GstVaapiSubpicturePrivate *priv = GST_VAAPI_SUBPICTURE_GET_PRIVATE(subpicture);
 
193
 
 
194
    subpicture->priv    = priv;
 
195
    priv->image         = NULL;
 
196
}
 
197
 
 
198
/**
 
199
 * gst_vaapi_subpicture_new:
 
200
 * @image: a #GstVaapiImage
 
201
 *
 
202
 * Creates a new #GstVaapiSubpicture with @image as source pixels. The
 
203
 * newly created object holds a reference on @image.
 
204
 *
 
205
 * Return value: the newly allocated #GstVaapiSubpicture object
 
206
 */
 
207
GstVaapiSubpicture *
 
208
gst_vaapi_subpicture_new(GstVaapiImage *image)
 
209
{
 
210
    g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL);
 
211
 
 
212
    GST_DEBUG("create from image %" GST_VAAPI_ID_FORMAT,
 
213
              GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(image)));
 
214
 
 
215
    return g_object_new(GST_VAAPI_TYPE_SUBPICTURE,
 
216
                        "display", GST_VAAPI_OBJECT_DISPLAY(image),
 
217
                        "id",      GST_VAAPI_ID(VA_INVALID_ID),
 
218
                        "image",   image,
 
219
                        NULL);
 
220
}
 
221
 
 
222
/**
 
223
 * gst_vaapi_subpicture_new_from_overlay_rectangle:
 
224
 * @display: a #GstVaapiDisplay
 
225
 * @rect: a #GstVideoOverlayRectangle
 
226
 *
 
227
 * Helper function that creates a new #GstVaapiSubpicture from a
 
228
 * #GstVideoOverlayRectangle. A new #GstVaapiImage is also created
 
229
 * along the way and attached to the resulting subpicture. The
 
230
 * subpicture holds a unique reference to the underlying image.
 
231
 *
 
232
 * Return value: the newly allocated #GstVaapiSubpicture object
 
233
 */
 
234
GstVaapiSubpicture *
 
235
gst_vaapi_subpicture_new_from_overlay_rectangle(
 
236
    GstVaapiDisplay          *display,
 
237
    GstVideoOverlayRectangle *rect
 
238
)
 
239
{
 
240
    GstVaapiSubpicture *subpicture;
 
241
    GstVaapiImageFormat format;
 
242
    GstVaapiImage *image;
 
243
    GstVaapiImageRaw raw_image;
 
244
    GstBuffer *buffer;
 
245
    guint width, height, stride;
 
246
 
 
247
    g_return_val_if_fail(GST_IS_VIDEO_OVERLAY_RECTANGLE(rect), NULL);
 
248
 
 
249
    buffer = gst_video_overlay_rectangle_get_pixels_unscaled_argb(
 
250
        rect,
 
251
        &width, &height, &stride,
 
252
        GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE
 
253
    );
 
254
    if (!buffer)
 
255
        return NULL;
 
256
 
 
257
    /* XXX: use gst_vaapi_image_format_from_video() */
 
258
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
 
259
    format = GST_VAAPI_IMAGE_BGRA;
 
260
#else
 
261
    format = GST_VAAPI_IMAGE_ARGB;
 
262
#endif
 
263
    image = gst_vaapi_image_new(display, format, width, height);
 
264
    if (!image)
 
265
        return NULL;
 
266
 
 
267
    raw_image.format     = format;
 
268
    raw_image.width      = width;
 
269
    raw_image.height     = height;
 
270
    raw_image.num_planes = 1;
 
271
    raw_image.pixels[0]  = GST_BUFFER_DATA(buffer);
 
272
    raw_image.stride[0]  = stride;
 
273
    if (!gst_vaapi_image_update_from_raw(image, &raw_image, NULL)) {
 
274
        GST_WARNING("could not update VA image with subtitle data");
 
275
        g_object_unref(image);
 
276
        return NULL;
 
277
    }
 
278
 
 
279
    subpicture = gst_vaapi_subpicture_new(image);
 
280
    g_object_unref(image);
 
281
    return subpicture;
 
282
}
 
283
 
 
284
/**
 
285
 * gst_vaapi_subpicture_get_id:
 
286
 * @subpicture: a #GstVaapiSubpicture
 
287
 *
 
288
 * Returns the underlying VASubpictureID of the @subpicture.
 
289
 *
 
290
 * Return value: the underlying VA subpicture id
 
291
 */
 
292
GstVaapiID
 
293
gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture)
 
294
{
 
295
    g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), VA_INVALID_ID);
 
296
 
 
297
    return GST_VAAPI_OBJECT_ID(subpicture);
 
298
}
 
299
 
 
300
/**
 
301
 * gst_vaapi_subpicture_get_image:
 
302
 * @subpicture: a #GstVaapiSubpicture
 
303
 *
 
304
 * Returns the #GstVaapiImage this @subpicture is bound to.
 
305
 *
 
306
 * Return value: the #GstVaapiImage this @subpicture is bound to
 
307
 */
 
308
GstVaapiImage *
 
309
gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture)
 
310
{
 
311
    g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), NULL);
 
312
 
 
313
    return subpicture->priv->image;
 
314
}
 
315
 
 
316
/**
 
317
 * gst_vaapi_subpicture_set_image:
 
318
 * @subpicture: a #GstVaapiSubpicture
 
319
 * @image: a #GstVaapiImage
 
320
 *
 
321
 * Binds a new #GstVaapiImage to the @subpicture. The reference to the
 
322
 * previous image is released and a new one is acquired on @image.
 
323
 */
 
324
void
 
325
gst_vaapi_subpicture_set_image(
 
326
    GstVaapiSubpicture *subpicture,
 
327
    GstVaapiImage      *image
 
328
)
 
329
{
 
330
    g_return_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture));
 
331
    g_return_if_fail(GST_VAAPI_IS_IMAGE(image));
 
332
 
 
333
    gst_vaapi_subpicture_destroy(subpicture);
 
334
 
 
335
    subpicture->priv->image = g_object_ref(image);
 
336
    gst_vaapi_subpicture_create(subpicture);
 
337
}