~ubuntu-branches/ubuntu/vivid/gstreamer-vaapi/vivid

« back to all changes in this revision

Viewing changes to gst/vaapi/gstvaapisink.c

  • Committer: Package Import Robot
  • Author(s): Vincent Cheng
  • Date: 2014-08-06 23:56:00 UTC
  • mfrom: (0.1.4 sid) (1.1.3)
  • Revision ID: package-import@ubuntu.com-20140806235600-fg1kcmiu67k315q5
Tags: 0.5.9-2
* Remove spurious build-deps: libva-drm1, libavcodec-dev. (Closes: #757283)
* Drop Build-Depends-Indep and build docs unconditionally on all archs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *
4
4
 *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5
5
 *    Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6
 
 *  Copyright (C) 2011-2013 Intel Corporation
 
6
 *  Copyright (C) 2011-2014 Intel Corporation
7
7
 *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
8
8
 *
9
9
 *  This library is free software; you can redistribute it and/or
71
71
 
72
72
#include "gstvaapisink.h"
73
73
#include "gstvaapipluginutil.h"
74
 
#include "gstvaapivideocontext.h"
75
74
#include "gstvaapivideometa.h"
76
75
#if GST_CHECK_VERSION(1,0,0)
77
76
#include "gstvaapivideobufferpool.h"
88
87
static const char gst_vaapisink_sink_caps_str[] =
89
88
#if GST_CHECK_VERSION(1,1,0)
90
89
    GST_VIDEO_CAPS_MAKE_WITH_FEATURES(
91
 
        GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }");
 
90
        GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ";"
 
91
    GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL);
92
92
#else
93
93
#if GST_CHECK_VERSION(1,0,0)
94
94
    GST_VIDEO_CAPS_MAKE(GST_VIDEO_FORMATS_ALL) "; "
107
107
        GST_PAD_ALWAYS,
108
108
        GST_STATIC_CAPS(gst_vaapisink_sink_caps_str));
109
109
 
110
 
/* GstImplementsInterface interface */
111
 
#if !GST_CHECK_VERSION(1,0,0)
112
110
static gboolean
113
 
gst_vaapisink_implements_interface_supported(
114
 
    GstImplementsInterface *iface,
115
 
    GType                   type
116
 
)
117
 
{
118
 
    return (type == GST_TYPE_VIDEO_CONTEXT ||
119
 
            type == GST_TYPE_VIDEO_OVERLAY);
120
 
}
121
 
 
122
 
static void
123
 
gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface)
124
 
{
125
 
    iface->supported = gst_vaapisink_implements_interface_supported;
126
 
}
127
 
#endif
128
 
 
129
 
/* GstVideoContext interface */
130
 
#if !GST_CHECK_VERSION(1,1,0)
131
 
static void
132
 
gst_vaapisink_set_video_context(GstVideoContext *context, const gchar *type,
133
 
    const GValue *value)
134
 
{
135
 
  GstVaapiSink *sink = GST_VAAPISINK (context);
136
 
  gst_vaapi_set_display (type, value, &sink->display);
137
 
}
138
 
 
139
 
static void
140
 
gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface)
141
 
{
142
 
    iface->set_context = gst_vaapisink_set_video_context;
143
 
}
144
 
#endif
 
111
gst_vaapisink_has_interface(GstVaapiPluginBase *plugin, GType type)
 
112
{
 
113
    return type == GST_TYPE_VIDEO_OVERLAY;
 
114
}
145
115
 
146
116
static void
147
117
gst_vaapisink_video_overlay_iface_init(GstVideoOverlayInterface *iface);
150
120
    GstVaapiSink,
151
121
    gst_vaapisink,
152
122
    GST_TYPE_VIDEO_SINK,
153
 
#if !GST_CHECK_VERSION(1,0,0)
154
 
    G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE,
155
 
                          gst_vaapisink_implements_iface_init);
156
 
#endif
157
 
#if !GST_CHECK_VERSION(1,1,0)
158
 
    G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT,
159
 
                          gst_vaapisink_video_context_iface_init);
160
 
#endif
 
123
    GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES
161
124
    G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_OVERLAY,
162
125
                          gst_vaapisink_video_overlay_iface_init))
163
126
 
165
128
    PROP_0,
166
129
 
167
130
    PROP_DISPLAY_TYPE,
 
131
    PROP_DISPLAY_NAME,
168
132
    PROP_FULLSCREEN,
169
133
    PROP_SYNCHRONOUS,
170
134
    PROP_USE_GLX,
171
135
    PROP_USE_REFLECTION,
172
136
    PROP_ROTATION,
173
137
    PROP_FORCE_ASPECT_RATIO,
 
138
    PROP_VIEW_ID,
174
139
};
175
140
 
176
141
#define DEFAULT_DISPLAY_TYPE            GST_VAAPI_DISPLAY_TYPE_ANY
177
142
#define DEFAULT_ROTATION                GST_VAAPI_ROTATION_0
178
143
 
 
144
static inline gboolean
 
145
gst_vaapisink_ensure_display(GstVaapiSink *sink);
 
146
 
179
147
/* GstVideoOverlay interface */
180
148
 
181
149
#if USE_X11
187
155
gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer);
188
156
 
189
157
static void
190
 
gst_vaapisink_video_overlay_set_window_handle(GstVideoOverlay *overlay, guintptr window)
 
158
gst_vaapisink_video_overlay_set_window_handle(GstVideoOverlay *overlay,
 
159
    guintptr window)
191
160
{
192
161
    GstVaapiSink * const sink = GST_VAAPISINK(overlay);
 
162
    GstVaapiDisplayType display_type;
 
163
 
 
164
    if (!gst_vaapisink_ensure_display(sink))
 
165
        return;
 
166
    display_type = GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink);
193
167
 
194
168
    /* Disable GLX rendering when vaapisink is using a foreign X
195
169
       window. It's pretty much useless */
196
 
    if (sink->display_type == GST_VAAPI_DISPLAY_TYPE_GLX)
197
 
        sink->display_type = GST_VAAPI_DISPLAY_TYPE_X11;
 
170
    if (display_type == GST_VAAPI_DISPLAY_TYPE_GLX) {
 
171
        display_type = GST_VAAPI_DISPLAY_TYPE_X11;
 
172
        gst_vaapi_plugin_base_set_display_type(GST_VAAPI_PLUGIN_BASE(sink),
 
173
            display_type);
 
174
    }
198
175
 
199
176
    sink->foreign_window = TRUE;
200
177
 
201
 
    switch (sink->display_type) {
 
178
    switch (display_type) {
202
179
#if USE_X11
203
180
    case GST_VAAPI_DISPLAY_TYPE_X11:
204
181
        gst_vaapisink_ensure_window_xid(sink, window);
235
212
gst_vaapisink_video_overlay_expose(GstVideoOverlay *overlay)
236
213
{
237
214
    GstVaapiSink * const sink = GST_VAAPISINK(overlay);
238
 
    GstBaseSink * const base_sink = GST_BASE_SINK(overlay);
239
 
    GstBuffer *buffer;
240
215
 
241
 
    if (sink->use_overlay)
242
 
        buffer = sink->video_buffer ? gst_buffer_ref(sink->video_buffer) : NULL;
243
 
    else {
244
 
#if GST_CHECK_VERSION(1,0,0)
245
 
        GstSample * const sample = gst_base_sink_get_last_sample(base_sink);
246
 
        if (!sample)
247
 
            return;
248
 
        buffer = gst_buffer_ref(gst_sample_get_buffer(sample));
249
 
        gst_sample_unref(sample);
250
 
#else
251
 
        buffer = gst_base_sink_get_last_buffer(base_sink);
252
 
#endif
253
 
    }
254
 
    if (buffer) {
255
 
        gst_vaapisink_show_frame(base_sink, buffer);
256
 
        gst_buffer_unref(buffer);
257
 
    }
 
216
    if (sink->video_buffer)
 
217
        gst_vaapisink_show_frame(GST_BASE_SINK_CAST(sink), sink->video_buffer);
258
218
}
259
219
 
260
220
static void
272
232
#if USE_GLX
273
233
    gst_vaapi_texture_replace(&sink->texture, NULL);
274
234
#endif
275
 
    gst_vaapi_display_replace(&sink->display, NULL);
276
 
    g_clear_object(&sink->uploader);
277
 
 
278
235
    gst_caps_replace(&sink->caps, NULL);
279
236
}
280
237
 
313
270
    guint         height
314
271
)
315
272
{
 
273
    GstVaapiDisplayX11 * const display =
 
274
        GST_VAAPI_DISPLAY_X11(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink));
316
275
    ConfigureNotifyEventPendingArgs args;
317
276
    XEvent xev;
318
277
 
323
282
 
324
283
    /* XXX: don't use XPeekIfEvent() because it might block */
325
284
    XCheckIfEvent(
326
 
        gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)),
 
285
        gst_vaapi_display_x11_get_display(display),
327
286
        &xev,
328
287
        configure_notify_event_pending_cb, (XPointer)&args
329
288
    );
345
304
static inline gboolean
346
305
gst_vaapisink_ensure_display(GstVaapiSink *sink)
347
306
{
348
 
    GstVaapiDisplayType display_type;
 
307
    return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(sink));
 
308
}
 
309
 
 
310
static void
 
311
gst_vaapisink_display_changed(GstVaapiPluginBase *plugin)
 
312
{
 
313
    GstVaapiSink * const sink = GST_VAAPISINK(plugin);
349
314
    GstVaapiRenderMode render_mode;
350
 
    const gboolean had_display = sink->display != NULL;
351
 
 
352
 
    if (!gst_vaapi_ensure_display(sink, sink->display_type, &sink->display))
353
 
        return FALSE;
354
 
 
355
 
    display_type = gst_vaapi_display_get_display_type(sink->display);
356
 
    if (display_type != sink->display_type || (!had_display && sink->display)) {
357
 
        GST_INFO("created %s %p", get_display_type_name(display_type),
358
 
            sink->display);
359
 
        sink->display_type = display_type;
360
 
 
361
 
        sink->use_overlay =
362
 
            gst_vaapi_display_get_render_mode(sink->display, &render_mode) &&
363
 
            render_mode == GST_VAAPI_RENDER_MODE_OVERLAY;
364
 
        GST_DEBUG("use %s rendering mode", sink->use_overlay ? "overlay" : "texture");
365
 
 
366
 
        sink->use_rotation = gst_vaapi_display_has_property(
367
 
            sink->display, GST_VAAPI_DISPLAY_PROP_ROTATION);
368
 
    }
369
 
    return TRUE;
 
315
 
 
316
    GST_INFO("created %s %p", get_display_type_name(plugin->display_type),
 
317
             plugin->display);
 
318
 
 
319
    sink->use_overlay =
 
320
        gst_vaapi_display_get_render_mode(plugin->display, &render_mode) &&
 
321
        render_mode == GST_VAAPI_RENDER_MODE_OVERLAY;
 
322
    GST_DEBUG("use %s rendering mode",
 
323
              sink->use_overlay ? "overlay" : "texture");
 
324
 
 
325
    sink->use_rotation = gst_vaapi_display_has_property(plugin->display,
 
326
        GST_VAAPI_DISPLAY_PROP_ROTATION);
370
327
}
371
328
 
372
329
static gboolean
374
331
{
375
332
    if (!gst_vaapisink_ensure_display(sink))
376
333
        return FALSE;
377
 
 
378
 
    if (!sink->uploader) {
379
 
        sink->uploader = gst_vaapi_uploader_new(sink->display);
380
 
        if (!sink->uploader)
381
 
            return FALSE;
382
 
    }
 
334
    if (!gst_vaapi_plugin_base_ensure_uploader(GST_VAAPI_PLUGIN_BASE(sink)))
 
335
        return FALSE;
383
336
    return TRUE;
384
337
}
385
338
 
410
363
    GST_DEBUG("ensure render rect within %ux%u bounds", width, height);
411
364
 
412
365
    gst_vaapi_display_get_pixel_aspect_ratio(
413
 
        sink->display,
 
366
        GST_VAAPI_PLUGIN_BASE_DISPLAY(sink),
414
367
        &display_par_n, &display_par_d
415
368
    );
416
369
    GST_DEBUG("display pixel-aspect-ratio %d/%d",
455
408
static void
456
409
gst_vaapisink_ensure_window_size(GstVaapiSink *sink, guint *pwidth, guint *pheight)
457
410
{
 
411
    GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
458
412
    GstVideoRectangle src_rect, dst_rect, out_rect;
459
413
    guint num, den, display_width, display_height, display_par_n, display_par_d;
460
414
    gboolean success, scale;
465
419
        return;
466
420
    }
467
421
 
468
 
    gst_vaapi_display_get_size(sink->display, &display_width, &display_height);
 
422
    gst_vaapi_display_get_size(display, &display_width, &display_height);
469
423
    if (sink->fullscreen) {
470
424
        *pwidth  = display_width;
471
425
        *pheight = display_height;
473
427
    }
474
428
 
475
429
    gst_vaapi_display_get_pixel_aspect_ratio(
476
 
        sink->display,
 
430
        display,
477
431
        &display_par_n, &display_par_d
478
432
    );
479
433
 
505
459
static inline gboolean
506
460
gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height)
507
461
{
508
 
    GstVaapiDisplay * const display = sink->display;
 
462
    GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
509
463
 
510
464
    if (!sink->window) {
511
 
        switch (sink->display_type) {
 
465
        const GstVaapiDisplayType display_type =
 
466
            GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink);
 
467
        switch (display_type) {
512
468
#if USE_GLX
513
469
        case GST_VAAPI_DISPLAY_TYPE_GLX:
514
470
            sink->window = gst_vaapi_window_glx_new(display, width, height);
532
488
            break;
533
489
#endif
534
490
        default:
535
 
            GST_ERROR("unsupported display type %d", sink->display_type);
 
491
            GST_ERROR("unsupported display type %d", display_type);
536
492
            return FALSE;
537
493
        }
538
494
    }
543
499
static gboolean
544
500
gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id)
545
501
{
 
502
    GstVaapiDisplay *display;
546
503
    Window rootwin;
547
504
    unsigned int width, height, border_width, depth;
548
505
    int x, y;
550
507
 
551
508
    if (!gst_vaapisink_ensure_display(sink))
552
509
        return FALSE;
 
510
    display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
553
511
 
554
 
    gst_vaapi_display_lock(sink->display);
 
512
    gst_vaapi_display_lock(display);
555
513
    XGetGeometry(
556
 
        gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)),
 
514
        gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)),
557
515
        xid,
558
516
        &rootwin,
559
517
        &x, &y, &width, &height, &border_width, &depth
560
518
    );
561
 
    gst_vaapi_display_unlock(sink->display);
 
519
    gst_vaapi_display_unlock(display);
562
520
 
563
521
    if ((width != sink->window_width || height != sink->window_height) &&
564
522
        !configure_notify_event_pending(sink, xid, width, height)) {
574
532
 
575
533
    gst_vaapi_window_replace(&sink->window, NULL);
576
534
 
577
 
    switch (sink->display_type) {
 
535
    switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) {
578
536
#if USE_GLX
579
537
    case GST_VAAPI_DISPLAY_TYPE_GLX:
580
 
        sink->window = gst_vaapi_window_glx_new_with_xid(sink->display, xid);
 
538
        sink->window = gst_vaapi_window_glx_new_with_xid(display, xid);
581
539
        break;
582
540
#endif
583
541
    case GST_VAAPI_DISPLAY_TYPE_X11:
584
 
        sink->window = gst_vaapi_window_x11_new_with_xid(sink->display, xid);
 
542
        sink->window = gst_vaapi_window_x11_new_with_xid(display, xid);
585
543
        break;
586
544
    default:
587
 
        GST_ERROR("unsupported display type %d", sink->display_type);
 
545
        GST_ERROR("unsupported display type %d",
 
546
                  GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink));
588
547
        return FALSE;
589
548
    }
590
549
    return sink->window != NULL;
594
553
static gboolean
595
554
gst_vaapisink_ensure_rotation(GstVaapiSink *sink, gboolean recalc_display_rect)
596
555
{
 
556
    GstVaapiDisplay * const display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
597
557
    gboolean success = FALSE;
598
558
 
599
 
    g_return_val_if_fail(sink->display, FALSE);
 
559
    g_return_val_if_fail(display, FALSE);
600
560
 
601
561
    if (sink->rotation == sink->rotation_req)
602
562
        return TRUE;
606
566
        goto end;
607
567
    }
608
568
 
609
 
    gst_vaapi_display_lock(sink->display);
610
 
    success = gst_vaapi_display_set_rotation(sink->display, sink->rotation_req);
611
 
    gst_vaapi_display_unlock(sink->display);
 
569
    gst_vaapi_display_lock(display);
 
570
    success = gst_vaapi_display_set_rotation(display, sink->rotation_req);
 
571
    gst_vaapi_display_unlock(display);
612
572
    if (!success) {
613
573
        GST_ERROR("failed to change VA display rotation mode");
614
574
        goto end;
631
591
}
632
592
 
633
593
static gboolean
634
 
gst_vaapisink_ensure_video_buffer_pool(GstVaapiSink *sink, GstCaps *caps)
635
 
{
636
 
#if GST_CHECK_VERSION(1,0,0)
637
 
    GstBufferPool *pool;
638
 
    GstCaps *pool_caps;
639
 
    GstStructure *config;
640
 
    GstVideoInfo vi;
641
 
    gboolean need_pool;
642
 
 
643
 
    if (!gst_vaapisink_ensure_display(sink))
644
 
        return FALSE;
645
 
 
646
 
    if (sink->video_buffer_pool) {
647
 
        config = gst_buffer_pool_get_config(sink->video_buffer_pool);
648
 
        gst_buffer_pool_config_get_params(config, &pool_caps, NULL, NULL, NULL);
649
 
        need_pool = !gst_caps_is_equal(caps, pool_caps);
650
 
        gst_structure_free(config);
651
 
        if (!need_pool)
652
 
            return TRUE;
653
 
        g_clear_object(&sink->video_buffer_pool);
654
 
        sink->video_buffer_size = 0;
655
 
    }
656
 
 
657
 
    pool = gst_vaapi_video_buffer_pool_new(sink->display);
658
 
    if (!pool)
659
 
        goto error_create_pool;
660
 
 
661
 
    gst_video_info_init(&vi);
662
 
    gst_video_info_from_caps(&vi, caps);
663
 
    if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) {
664
 
        GST_DEBUG("assume video buffer pool format is NV12");
665
 
        gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12,
666
 
            GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi));
667
 
    }
668
 
    sink->video_buffer_size = vi.size;
669
 
 
670
 
    config = gst_buffer_pool_get_config(pool);
671
 
    gst_buffer_pool_config_set_params(config, caps, sink->video_buffer_size,
672
 
        0, 0);
673
 
    gst_buffer_pool_config_add_option(config,
674
 
        GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META);
675
 
    gst_buffer_pool_config_add_option(config,
676
 
        GST_BUFFER_POOL_OPTION_VIDEO_META);
677
 
    if (!gst_buffer_pool_set_config(pool, config))
678
 
        goto error_pool_config;
679
 
    sink->video_buffer_pool = pool;
680
 
    return TRUE;
681
 
 
682
 
    /* ERRORS */
683
 
error_create_pool:
684
 
    {
685
 
        GST_ERROR("failed to create buffer pool");
686
 
        return FALSE;
687
 
    }
688
 
error_pool_config:
689
 
    {
690
 
        GST_ERROR("failed to reset buffer pool config");
691
 
        gst_object_unref(pool);
692
 
        return FALSE;
693
 
    }
694
 
#else
695
 
    return TRUE;
696
 
#endif
697
 
}
698
 
 
699
 
static gboolean
700
594
gst_vaapisink_start(GstBaseSink *base_sink)
701
595
{
702
596
    GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
703
597
 
 
598
    if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(sink)))
 
599
        return FALSE;
704
600
    return gst_vaapisink_ensure_uploader(sink);
705
601
}
706
602
 
714
610
    g_clear_object(&sink->video_buffer_pool);
715
611
#endif
716
612
    gst_vaapi_window_replace(&sink->window, NULL);
717
 
    gst_vaapi_display_replace(&sink->display, NULL);
718
 
    g_clear_object(&sink->uploader);
719
613
 
 
614
    gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(sink));
720
615
    return TRUE;
721
616
}
722
617
 
735
630
        return NULL;
736
631
 
737
632
    if (gst_vaapisink_ensure_uploader(sink)) {
738
 
        yuv_caps = gst_vaapi_uploader_get_caps(sink->uploader);
 
633
        yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(sink);
739
634
        if (yuv_caps) {
740
635
            out_caps = gst_caps_make_writable(out_caps);
741
636
            gst_caps_append(out_caps, gst_caps_copy(yuv_caps));
764
659
#define gst_vaapisink_get_caps gst_vaapisink_get_caps_impl
765
660
#endif
766
661
 
 
662
static void
 
663
update_colorimetry(GstVaapiSink *sink, GstVideoColorimetry *cinfo)
 
664
{
 
665
#if GST_CHECK_VERSION(1,0,0)
 
666
    if (gst_video_colorimetry_matches(cinfo,
 
667
            GST_VIDEO_COLORIMETRY_BT601))
 
668
        sink->color_standard = GST_VAAPI_COLOR_STANDARD_ITUR_BT_601;
 
669
    else if (gst_video_colorimetry_matches(cinfo,
 
670
            GST_VIDEO_COLORIMETRY_BT709))
 
671
        sink->color_standard = GST_VAAPI_COLOR_STANDARD_ITUR_BT_709;
 
672
    else if (gst_video_colorimetry_matches(cinfo,
 
673
            GST_VIDEO_COLORIMETRY_SMPTE240M))
 
674
        sink->color_standard = GST_VAAPI_COLOR_STANDARD_SMPTE_240M;
 
675
    else
 
676
        sink->color_standard = 0;
 
677
 
 
678
    GST_DEBUG("colorimetry %s", gst_video_colorimetry_to_string(cinfo));
 
679
#endif
 
680
}
 
681
 
767
682
static gboolean
768
683
gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)
769
684
{
 
685
    GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(base_sink);
770
686
    GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
771
 
    GstVideoInfo * const vip = &sink->video_info;
 
687
    GstVideoInfo * const vip = GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO(sink);
 
688
    GstVaapiDisplay *display;
772
689
    guint win_width, win_height;
773
690
 
 
691
    if (!gst_vaapisink_ensure_display(sink))
 
692
        return FALSE;
 
693
    display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
 
694
 
774
695
#if USE_DRM
775
 
    if (sink->display_type == GST_VAAPI_DISPLAY_TYPE_DRM)
 
696
    if (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink) == GST_VAAPI_DISPLAY_TYPE_DRM)
776
697
        return TRUE;
777
698
#endif
778
699
 
779
 
    if (!gst_vaapisink_ensure_video_buffer_pool(sink, caps))
 
700
    if (!gst_vaapi_plugin_base_set_caps(plugin, caps, NULL))
780
701
        return FALSE;
781
702
 
782
 
    if (!gst_video_info_from_caps(vip, caps))
783
 
        return FALSE;
784
 
    sink->use_video_raw = GST_VIDEO_INFO_IS_YUV(vip);
785
703
    sink->video_width   = GST_VIDEO_INFO_WIDTH(vip);
786
704
    sink->video_height  = GST_VIDEO_INFO_HEIGHT(vip);
787
705
    sink->video_par_n   = GST_VIDEO_INFO_PAR_N(vip);
789
707
    GST_DEBUG("video pixel-aspect-ratio %d/%d",
790
708
              sink->video_par_n, sink->video_par_d);
791
709
 
 
710
    update_colorimetry(sink, &vip->colorimetry);
792
711
    gst_caps_replace(&sink->caps, caps);
793
712
 
794
 
    if (!gst_vaapisink_ensure_display(sink))
795
 
        return FALSE;
796
 
 
797
 
#if !GST_CHECK_VERSION(1,0,0)
798
 
    if (sink->use_video_raw) {
799
 
        /* Ensure the uploader is set up for upstream allocated buffers */
800
 
        if (!gst_vaapi_uploader_ensure_display(sink->uploader, sink->display))
801
 
            return FALSE;
802
 
        if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL))
803
 
            return FALSE;
804
 
    }
805
 
#endif
806
 
 
807
713
    gst_vaapisink_ensure_rotation(sink, FALSE);
808
714
 
809
715
    gst_vaapisink_ensure_window_size(sink, &win_width, &win_height);
812
718
            gst_vaapi_window_set_size(sink->window, win_width, win_height);
813
719
    }
814
720
    else {
815
 
        gst_vaapi_display_lock(sink->display);
 
721
        gst_vaapi_display_lock(display);
816
722
        gst_video_overlay_prepare_window_handle(GST_VIDEO_OVERLAY(sink));
817
 
        gst_vaapi_display_unlock(sink->display);
 
723
        gst_vaapi_display_unlock(display);
818
724
        if (sink->window)
819
725
            return TRUE;
820
726
        if (!gst_vaapisink_ensure_window(sink, win_width, win_height))
935
841
static gboolean
936
842
gst_vaapisink_ensure_texture(GstVaapiSink *sink, GstVaapiSurface *surface)
937
843
{
 
844
    GstVaapiDisplay * display = GST_VAAPI_PLUGIN_BASE_DISPLAY(sink);
938
845
    GstVideoRectangle tex_rect, dis_rect, out_rect;
939
846
    guint width, height;
940
847
 
947
854
    tex_rect.w = width;
948
855
    tex_rect.h = height;
949
856
 
950
 
    gst_vaapi_display_get_size(sink->display, &width, &height);
 
857
    gst_vaapi_display_get_size(display, &width, &height);
951
858
    dis_rect.x = 0;
952
859
    dis_rect.y = 0;
953
860
    dis_rect.w = width;
963
870
    height = tex_rect.h;
964
871
    GST_INFO("texture size %ux%u", width, height);
965
872
 
966
 
    sink->texture = gst_vaapi_texture_new(sink->display,
 
873
    sink->texture = gst_vaapi_texture_new(display,
967
874
        GL_TEXTURE_2D, GL_BGRA, width, height);
968
875
    return sink->texture != NULL;
969
876
}
976
883
    guint                       flags
977
884
)
978
885
{
979
 
    GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window);
 
886
    GstVaapiWindowGLX *window;
980
887
    GLenum target;
981
888
    GLuint texture;
982
889
 
 
890
    if (!sink->window)
 
891
        return FALSE;
 
892
    window = GST_VAAPI_WINDOW_GLX(sink->window);
 
893
 
983
894
    gst_vaapi_window_glx_make_current(window);
984
895
    if (!gst_vaapisink_ensure_texture(sink, surface))
985
896
        goto error_create_texture;
1038
949
    guint                       flags
1039
950
)
1040
951
{
 
952
    if (!sink->window)
 
953
        return FALSE;
 
954
 
1041
955
    if (!gst_vaapi_window_put_surface(sink->window, surface,
1042
956
                surface_rect, &sink->display_rect, flags)) {
1043
957
        GST_DEBUG("could not render VA surface");
1046
960
    return TRUE;
1047
961
}
1048
962
 
1049
 
#if GST_CHECK_VERSION(1,0,0)
1050
 
static GstFlowReturn
1051
 
gst_vaapisink_get_render_buffer(GstVaapiSink *sink, GstBuffer *src_buffer,
1052
 
    GstBuffer **out_buffer_ptr)
1053
 
{
1054
 
    GstVaapiVideoMeta *meta;
1055
 
    GstBuffer *out_buffer;
1056
 
    GstBufferPoolAcquireParams params = { 0, };
1057
 
    GstVideoFrame src_frame, out_frame;
1058
 
    GstFlowReturn ret;
1059
 
 
1060
 
    meta = gst_buffer_get_vaapi_video_meta(src_buffer);
1061
 
    if (meta) {
1062
 
        *out_buffer_ptr = gst_buffer_ref(src_buffer);
1063
 
        return GST_FLOW_OK;
1064
 
    }
1065
 
 
1066
 
    if (!sink->use_video_raw) {
1067
 
        GST_ERROR("unsupported video buffer");
1068
 
        return GST_FLOW_EOS;
1069
 
    }
1070
 
 
1071
 
    GST_DEBUG("buffer %p not from our pool, copying", src_buffer);
1072
 
 
1073
 
    *out_buffer_ptr = NULL;
1074
 
    if (!sink->video_buffer_pool)
1075
 
        goto error_no_pool;
1076
 
 
1077
 
    if (!gst_buffer_pool_set_active(sink->video_buffer_pool, TRUE))
1078
 
        goto error_activate_pool;
1079
 
 
1080
 
    params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT;
1081
 
    ret = gst_buffer_pool_acquire_buffer(sink->video_buffer_pool, &out_buffer,
1082
 
        &params);
1083
 
    if (ret != GST_FLOW_OK)
1084
 
        goto error_create_buffer;
1085
 
 
1086
 
    if (!gst_video_frame_map(&src_frame, &sink->video_info, src_buffer,
1087
 
            GST_MAP_READ))
1088
 
        goto error_map_src_buffer;
1089
 
 
1090
 
    if (!gst_video_frame_map(&out_frame, &sink->video_info, out_buffer,
1091
 
            GST_MAP_WRITE))
1092
 
        goto error_map_dst_buffer;
1093
 
 
1094
 
    gst_video_frame_copy(&out_frame, &src_frame);
1095
 
    gst_video_frame_unmap(&out_frame);
1096
 
    gst_video_frame_unmap(&src_frame);
1097
 
 
1098
 
    *out_buffer_ptr = out_buffer;
1099
 
    return GST_FLOW_OK;
1100
 
 
1101
 
    /* ERRORS */
1102
 
error_no_pool:
1103
 
    GST_ERROR("no buffer pool was negotiated");
1104
 
    return GST_FLOW_ERROR;
1105
 
error_activate_pool:
1106
 
    GST_ERROR("failed to activate buffer pool");
1107
 
    return GST_FLOW_ERROR;
1108
 
error_create_buffer:
1109
 
    GST_WARNING("failed to create image. Skipping this frame");
1110
 
    return GST_FLOW_OK;
1111
 
error_map_dst_buffer:
1112
 
    gst_video_frame_unmap(&src_frame);
1113
 
    // fall-through
1114
 
error_map_src_buffer:
1115
 
    GST_WARNING("failed to map buffer. Skipping this frame");
1116
 
    gst_buffer_unref(out_buffer);
1117
 
    return GST_FLOW_OK;
1118
 
}
1119
 
#else
1120
 
static GstFlowReturn
1121
 
gst_vaapisink_get_render_buffer(GstVaapiSink *sink, GstBuffer *src_buffer,
1122
 
    GstBuffer **out_buffer_ptr)
1123
 
{
1124
 
    GstVaapiVideoMeta *meta;
1125
 
    GstBuffer *out_buffer;
1126
 
 
1127
 
    *out_buffer_ptr = NULL;
1128
 
    meta = gst_buffer_get_vaapi_video_meta(src_buffer);
1129
 
    if (meta)
1130
 
        out_buffer = gst_buffer_ref(src_buffer);
1131
 
    else if (sink->use_video_raw) {
1132
 
        out_buffer = gst_vaapi_uploader_get_buffer(sink->uploader);
1133
 
        if (!out_buffer)
1134
 
            goto error_create_buffer;
1135
 
    }
1136
 
    else {
1137
 
        GST_ERROR("unsupported video buffer");
1138
 
        return GST_FLOW_EOS;
1139
 
    }
1140
 
 
1141
 
    if (sink->use_video_raw &&
1142
 
        !gst_vaapi_uploader_process(sink->uploader, src_buffer, out_buffer))
1143
 
        goto error_copy_buffer;
1144
 
 
1145
 
    *out_buffer_ptr = out_buffer;
1146
 
    return GST_FLOW_OK;
1147
 
 
1148
 
    /* ERRORS */
1149
 
error_create_buffer:
1150
 
    GST_WARNING("failed to create buffer. Skipping this frame");
1151
 
    return GST_FLOW_OK;
1152
 
error_copy_buffer:
1153
 
    GST_WARNING("failed to copy buffers. Skipping this frame");
1154
 
    gst_buffer_unref(out_buffer);
1155
 
    return GST_FLOW_OK;
1156
 
}
1157
 
#endif
1158
 
 
1159
963
static GstFlowReturn
1160
964
gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer)
1161
965
{
1162
966
    GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
1163
967
    GstVaapiVideoMeta *meta;
 
968
    GstVaapiSurfaceProxy *proxy;
1164
969
    GstVaapiSurface *surface;
1165
970
    GstBuffer *buffer;
1166
971
    guint flags;
1170
975
    GstVaapiRectangle tmp_rect;
1171
976
#endif
1172
977
    GstFlowReturn ret;
 
978
    gint32 view_id;
1173
979
 
1174
980
#if GST_CHECK_VERSION(1,0,0)
1175
981
    GstVideoCropMeta * const crop_meta =
1183
989
    }
1184
990
#endif
1185
991
 
1186
 
    ret = gst_vaapisink_get_render_buffer(sink, src_buffer, &buffer);
1187
 
    if (ret != GST_FLOW_OK || !buffer)
 
992
    ret = gst_vaapi_plugin_base_get_input_buffer(GST_VAAPI_PLUGIN_BASE(sink),
 
993
        src_buffer, &buffer);
 
994
    if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_SUPPORTED)
1188
995
        return ret;
1189
996
 
1190
997
    meta = gst_buffer_get_vaapi_video_meta(buffer);
1191
 
    if (sink->display != gst_vaapi_video_meta_get_display(meta))
1192
 
        gst_vaapi_display_replace(&sink->display,
1193
 
            gst_vaapi_video_meta_get_display(meta));
1194
 
 
1195
 
    if (!sink->window)
1196
 
        goto error;
 
998
    GST_VAAPI_PLUGIN_BASE_DISPLAY_REPLACE(sink,
 
999
        gst_vaapi_video_meta_get_display(meta));
1197
1000
 
1198
1001
    gst_vaapisink_ensure_rotation(sink, TRUE);
1199
1002
 
 
1003
    proxy = gst_vaapi_video_meta_get_surface_proxy(meta);
 
1004
    if (!proxy)
 
1005
        goto error;
 
1006
 
 
1007
    /* Valide view component to display */
 
1008
    view_id = GST_VAAPI_SURFACE_PROXY_VIEW_ID(proxy);
 
1009
    if (G_UNLIKELY(sink->view_id == -1))
 
1010
        sink->view_id = view_id;
 
1011
    else if (sink->view_id != view_id) {
 
1012
        gst_buffer_unref(buffer);
 
1013
        return GST_FLOW_OK;
 
1014
    }
 
1015
 
1200
1016
    surface = gst_vaapi_video_meta_get_surface(meta);
1201
1017
    if (!surface)
1202
1018
        goto error;
1215
1031
 
1216
1032
    flags = gst_vaapi_video_meta_get_render_flags(meta);
1217
1033
 
 
1034
    /* Append default color standard obtained from caps if none was
 
1035
       available on a per-buffer basis */
 
1036
    if (!(flags & GST_VAAPI_COLOR_STANDARD_MASK))
 
1037
        flags |= sink->color_standard;
 
1038
 
1218
1039
    if (!gst_vaapi_apply_composition(surface, src_buffer))
1219
1040
        GST_WARNING("could not update subtitles");
1220
1041
 
1221
 
    switch (sink->display_type) {
 
1042
    switch (GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink)) {
1222
1043
#if USE_DRM
1223
1044
    case GST_VAAPI_DISPLAY_TYPE_DRM:
1224
1045
        success = TRUE;
1244
1065
        break;
1245
1066
#endif
1246
1067
    default:
1247
 
        GST_ERROR("unsupported display type %d", sink->display_type);
 
1068
        GST_ERROR("unsupported display type %d",
 
1069
                  GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink));
1248
1070
        success = FALSE;
1249
1071
        break;
1250
1072
    }
1252
1074
        goto error;
1253
1075
 
1254
1076
    /* Retain VA surface until the next one is displayed */
1255
 
    if (sink->use_overlay)
1256
 
        gst_buffer_replace(&sink->video_buffer, buffer);
 
1077
    gst_buffer_replace(&sink->video_buffer, buffer);
1257
1078
    gst_buffer_unref(buffer);
1258
1079
    return GST_FLOW_OK;
1259
1080
 
1266
1087
static gboolean
1267
1088
gst_vaapisink_propose_allocation(GstBaseSink *base_sink, GstQuery *query)
1268
1089
{
1269
 
    GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
1270
 
    GstCaps *caps = NULL;
1271
 
    gboolean need_pool;
1272
 
 
1273
 
    gst_query_parse_allocation(query, &caps, &need_pool);
1274
 
 
1275
 
    if (need_pool) {
1276
 
        if (!caps)
1277
 
            goto error_no_caps;
1278
 
        if (!gst_vaapisink_ensure_video_buffer_pool(sink, caps))
1279
 
            return FALSE;
1280
 
        gst_query_add_allocation_pool(query, sink->video_buffer_pool,
1281
 
            sink->video_buffer_size, 0, 0);
1282
 
    }
1283
 
 
1284
 
    gst_query_add_allocation_meta(query,
1285
 
        GST_VAAPI_VIDEO_META_API_TYPE, NULL);
1286
 
    gst_query_add_allocation_meta(query,
1287
 
        GST_VIDEO_META_API_TYPE, NULL);
1288
 
    gst_query_add_allocation_meta(query,
1289
 
        GST_VIDEO_CROP_META_API_TYPE, NULL);
 
1090
    GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(base_sink);
 
1091
 
 
1092
    if (!gst_vaapi_plugin_base_propose_allocation(plugin, query))
 
1093
        return FALSE;
 
1094
 
 
1095
    gst_query_add_allocation_meta(query, GST_VIDEO_CROP_META_API_TYPE, NULL);
1290
1096
    gst_query_add_allocation_meta(query,
1291
1097
        GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
1292
1098
    return TRUE;
1293
 
 
1294
 
    /* ERRORS */
1295
 
error_no_caps:
1296
 
    {
1297
 
        GST_ERROR("no caps specified");
1298
 
        return FALSE;
1299
 
    }
1300
1099
}
1301
1100
#else
1302
1101
static GstFlowReturn
1303
 
gst_vaapisink_buffer_alloc(
1304
 
    GstBaseSink        *base_sink,
1305
 
    guint64             offset,
1306
 
    guint               size,
1307
 
    GstCaps            *caps,
1308
 
    GstBuffer         **pbuf
1309
 
)
1310
 
{
1311
 
    GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
1312
 
    GstVideoInfo vi;
1313
 
    GstBuffer *buf;
1314
 
 
1315
 
    *pbuf = NULL;
1316
 
 
1317
 
    if (!sink->use_video_raw) {
1318
 
        /* Note: this code path is rarely used but for raw YUV formats
1319
 
           from custom pipeline. Otherwise, GstBaseSink::set_caps() is
1320
 
           called first, and GstBaseSink::buffer_alloc() is not called
1321
 
           in VA surface format mode */
1322
 
        if (!gst_video_info_from_caps(&vi, caps))
1323
 
            return GST_FLOW_NOT_SUPPORTED;
1324
 
        if (!GST_VIDEO_INFO_IS_YUV(&vi))
1325
 
            return GST_FLOW_OK;
1326
 
    }
1327
 
 
1328
 
    if (!gst_vaapi_uploader_ensure_display(sink->uploader, sink->display))
1329
 
        return GST_FLOW_NOT_SUPPORTED;
1330
 
    if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL))
1331
 
        return GST_FLOW_NOT_SUPPORTED;
1332
 
 
1333
 
    buf = gst_vaapi_uploader_get_buffer(sink->uploader);
1334
 
    if (!buf) {
1335
 
        GST_WARNING("failed to allocate resources for raw YUV buffer");
1336
 
        return GST_FLOW_NOT_SUPPORTED;
1337
 
    }
1338
 
 
1339
 
    *pbuf = buf;
1340
 
    return GST_FLOW_OK;
1341
 
}
1342
 
#endif
1343
 
 
1344
 
#if GST_CHECK_VERSION(1,1,0)
1345
 
static void
1346
 
gst_vaapisink_set_context(GstElement *element, GstContext *context)
1347
 
{
1348
 
    GstVaapiSink * const sink = GST_VAAPISINK(element);
1349
 
    GstVaapiDisplay *display = NULL;
1350
 
 
1351
 
    if (gst_vaapi_video_context_get_display(context, &display)) {
1352
 
        GST_INFO_OBJECT(element, "set display %p", display);
1353
 
        gst_vaapi_display_replace(&sink->display, display);
1354
 
    }
 
1102
gst_vaapisink_buffer_alloc(GstBaseSink *base_sink, guint64 offset, guint size,
 
1103
    GstCaps *caps, GstBuffer **outbuf_ptr)
 
1104
{
 
1105
    return gst_vaapi_plugin_base_allocate_input_buffer(
 
1106
        GST_VAAPI_PLUGIN_BASE(base_sink), caps, outbuf_ptr);
1355
1107
}
1356
1108
#endif
1357
1109
 
1362
1114
 
1363
1115
    GST_INFO_OBJECT(sink, "query type %s", GST_QUERY_TYPE_NAME(query));
1364
1116
 
1365
 
    if (gst_vaapi_reply_to_query(query, sink->display)) {
1366
 
        GST_DEBUG("sharing display %p", sink->display);
 
1117
    if (gst_vaapi_reply_to_query(query, GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) {
 
1118
        GST_DEBUG("sharing display %p", GST_VAAPI_PLUGIN_BASE_DISPLAY(sink));
1367
1119
        return TRUE;
1368
1120
    }
1369
1121
 
1376
1128
{
1377
1129
    gst_vaapisink_destroy(GST_VAAPISINK(object));
1378
1130
 
 
1131
    gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object));
1379
1132
    G_OBJECT_CLASS(gst_vaapisink_parent_class)->finalize(object);
1380
1133
}
1381
1134
 
1391
1144
 
1392
1145
    switch (prop_id) {
1393
1146
    case PROP_DISPLAY_TYPE:
1394
 
        sink->display_type = g_value_get_enum(value);
 
1147
        gst_vaapi_plugin_base_set_display_type(GST_VAAPI_PLUGIN_BASE(sink),
 
1148
            g_value_get_enum(value));
 
1149
        break;
 
1150
    case PROP_DISPLAY_NAME:
 
1151
        gst_vaapi_plugin_base_set_display_name(GST_VAAPI_PLUGIN_BASE(sink),
 
1152
            g_value_get_string(value));
1395
1153
        break;
1396
1154
    case PROP_FULLSCREEN:
1397
1155
        sink->fullscreen = g_value_get_boolean(value);
1399
1157
    case PROP_SYNCHRONOUS:
1400
1158
        sink->synchronous = g_value_get_boolean(value);
1401
1159
        break;
 
1160
    case PROP_VIEW_ID:
 
1161
        sink->view_id = g_value_get_int(value);
 
1162
        break;
1402
1163
    case PROP_USE_GLX:
1403
1164
        sink->use_glx = g_value_get_boolean(value);
1404
1165
        break;
1429
1190
 
1430
1191
    switch (prop_id) {
1431
1192
    case PROP_DISPLAY_TYPE:
1432
 
        g_value_set_enum(value, sink->display_type);
 
1193
        g_value_set_enum(value, GST_VAAPI_PLUGIN_BASE_DISPLAY_TYPE(sink));
 
1194
        break;
 
1195
    case PROP_DISPLAY_NAME:
 
1196
        g_value_set_string(value, GST_VAAPI_PLUGIN_BASE_DISPLAY_NAME(sink));
1433
1197
        break;
1434
1198
    case PROP_FULLSCREEN:
1435
1199
        g_value_set_boolean(value, sink->fullscreen);
1437
1201
    case PROP_SYNCHRONOUS:
1438
1202
        g_value_set_boolean(value, sink->synchronous);
1439
1203
        break;
 
1204
    case PROP_VIEW_ID:
 
1205
        g_value_set_int(value, sink->view_id);
 
1206
        break;
1440
1207
    case PROP_USE_GLX:
1441
1208
        g_value_set_boolean(value, sink->use_glx);
1442
1209
        break;
1456
1223
}
1457
1224
 
1458
1225
static void
 
1226
gst_vaapisink_set_bus(GstElement *element, GstBus *bus)
 
1227
{
 
1228
    /* Make sure to allocate a VA display in the sink element first,
 
1229
       so that upstream elements could query a display that was
 
1230
       allocated here, and that exactly matches what the user
 
1231
       requested through the "display" property */
 
1232
    if (!GST_ELEMENT_BUS(element) && bus)
 
1233
        gst_vaapisink_ensure_display(GST_VAAPISINK(element));
 
1234
 
 
1235
    GST_ELEMENT_CLASS(gst_vaapisink_parent_class)->set_bus(element, bus);
 
1236
}
 
1237
 
 
1238
static void
1459
1239
gst_vaapisink_class_init(GstVaapiSinkClass *klass)
1460
1240
{
1461
1241
    GObjectClass * const     object_class   = G_OBJECT_CLASS(klass);
1462
1242
    GstElementClass * const  element_class  = GST_ELEMENT_CLASS(klass);
1463
1243
    GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass);
 
1244
    GstVaapiPluginBaseClass * const base_plugin_class =
 
1245
        GST_VAAPI_PLUGIN_BASE_CLASS(klass);
1464
1246
    GstPadTemplate *pad_template;
1465
1247
 
1466
1248
    GST_DEBUG_CATEGORY_INIT(gst_debug_vaapisink,
1467
1249
                            GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
1468
1250
 
 
1251
    gst_vaapi_plugin_base_class_init(base_plugin_class);
 
1252
    base_plugin_class->has_interface    = gst_vaapisink_has_interface;
 
1253
    base_plugin_class->display_changed  = gst_vaapisink_display_changed;
 
1254
 
1469
1255
    object_class->finalize       = gst_vaapisink_finalize;
1470
1256
    object_class->set_property   = gst_vaapisink_set_property;
1471
1257
    object_class->get_property   = gst_vaapisink_get_property;
1483
1269
    basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc;
1484
1270
#endif
1485
1271
 
1486
 
#if GST_CHECK_VERSION(1,1,0)
1487
 
    element_class->set_context = gst_vaapisink_set_context;
1488
 
#endif
1489
 
 
 
1272
    element_class->set_bus = gst_vaapisink_set_bus;
1490
1273
    gst_element_class_set_static_metadata(element_class,
1491
1274
        "VA-API sink",
1492
1275
        "Sink/Video",
1506
1289
                           GST_VAAPI_DISPLAY_TYPE_ANY,
1507
1290
                           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1508
1291
 
 
1292
    g_object_class_install_property
 
1293
        (object_class,
 
1294
         PROP_DISPLAY_NAME,
 
1295
         g_param_spec_string("display-name",
 
1296
                             "display name",
 
1297
                             "display name to use",
 
1298
                             NULL,
 
1299
                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
1300
 
1509
1301
#if USE_GLX
1510
1302
    g_object_class_install_property
1511
1303
        (object_class,
1514
1306
                              "OpenGL rendering",
1515
1307
                              "Enables OpenGL rendering",
1516
1308
                              FALSE,
1517
 
                              G_PARAM_READWRITE));
 
1309
                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1518
1310
 
1519
1311
    g_object_class_install_property
1520
1312
        (object_class,
1523
1315
                              "Reflection effect",
1524
1316
                              "Enables OpenGL reflection effect",
1525
1317
                              FALSE,
1526
 
                              G_PARAM_READWRITE));
 
1318
                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1527
1319
#endif
1528
1320
 
1529
1321
    g_object_class_install_property
1533
1325
                              "Fullscreen",
1534
1326
                              "Requests window in fullscreen state",
1535
1327
                              FALSE,
1536
 
                              G_PARAM_READWRITE));
 
1328
                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1537
1329
 
1538
1330
    /**
1539
1331
     * GstVaapiSink:synchronous:
1548
1340
                              "Synchronous mode",
1549
1341
                              "Toggles X display synchronous mode",
1550
1342
                              FALSE,
1551
 
                              G_PARAM_READWRITE));
 
1343
                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1552
1344
 
1553
1345
    /**
1554
1346
     * GstVaapiSink:rotation:
1578
1370
                              "Force aspect ratio",
1579
1371
                              "When enabled, scaling will respect original aspect ratio",
1580
1372
                              TRUE,
1581
 
                              G_PARAM_READWRITE));
 
1373
                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
1374
 
 
1375
    /**
 
1376
     * GstVaapiSink:view-id:
 
1377
     *
 
1378
     * When not set to -1, the displayed frame will always be the one
 
1379
     * that matches the view-id of the very first displayed frame. Any
 
1380
     * other number will indicate the desire to display the supplied
 
1381
     * view-id only.
 
1382
     */
 
1383
    g_object_class_install_property
 
1384
        (object_class,
 
1385
         PROP_VIEW_ID,
 
1386
         g_param_spec_int("view-id",
 
1387
                          "View ID",
 
1388
                          "ID of the view component of interest to display",
 
1389
                          -1, G_MAXINT32, -1,
 
1390
                          G_PARAM_READWRITE));
1582
1391
}
1583
1392
 
1584
1393
static void
1585
1394
gst_vaapisink_init(GstVaapiSink *sink)
1586
1395
{
 
1396
    GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(sink);
 
1397
 
 
1398
    gst_vaapi_plugin_base_init(plugin, GST_CAT_DEFAULT);
 
1399
    gst_vaapi_plugin_base_set_display_type(plugin, DEFAULT_DISPLAY_TYPE);
 
1400
 
1587
1401
    sink->caps           = NULL;
1588
 
    sink->display        = NULL;
1589
1402
    sink->window         = NULL;
1590
1403
    sink->window_width   = 0;
1591
1404
    sink->window_height  = 0;
1595
1408
    sink->video_height   = 0;
1596
1409
    sink->video_par_n    = 1;
1597
1410
    sink->video_par_d    = 1;
 
1411
    sink->view_id        = -1;
1598
1412
    sink->foreign_window = FALSE;
1599
1413
    sink->fullscreen     = FALSE;
1600
1414
    sink->synchronous    = FALSE;
1601
 
    sink->display_type   = DEFAULT_DISPLAY_TYPE;
1602
1415
    sink->rotation       = DEFAULT_ROTATION;
1603
1416
    sink->rotation_req   = DEFAULT_ROTATION;
1604
1417
    sink->use_reflection = FALSE;