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

« back to all changes in this revision

Viewing changes to gst/vaapi/gstvaapidecode.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
35
35
 
36
36
#include "gstvaapidecode.h"
37
37
#include "gstvaapipluginutil.h"
38
 
#include "gstvaapivideocontext.h"
39
38
#include "gstvaapivideobuffer.h"
40
 
#if GST_CHECK_VERSION(1,1,0)
 
39
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
41
40
#include "gstvaapivideometa_texture.h"
42
41
#endif
43
42
#if GST_CHECK_VERSION(1,0,0)
50
49
#include <gst/vaapi/gstvaapidecoder_mpeg2.h>
51
50
#include <gst/vaapi/gstvaapidecoder_mpeg4.h>
52
51
#include <gst/vaapi/gstvaapidecoder_vc1.h>
 
52
#include <gst/vaapi/gstvaapidecoder_vp8.h>
53
53
 
54
54
#define GST_PLUGIN_NAME "vaapidecode"
55
55
#define GST_PLUGIN_DESC "A VA-API based video decoder"
56
56
 
 
57
#define GST_VAAPI_DECODE_FLOW_PARSE_DATA        GST_FLOW_CUSTOM_SUCCESS_2
 
58
 
57
59
GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapidecode);
58
60
#define GST_CAT_DEFAULT gst_debug_vaapidecode
59
61
 
68
70
    GST_CAPS_CODEC("video/x-h263")
69
71
    GST_CAPS_CODEC("video/x-h264")
70
72
    GST_CAPS_CODEC("video/x-wmv")
 
73
    GST_CAPS_CODEC("video/x-vp8")
71
74
    GST_CAPS_CODEC("image/jpeg")
72
75
    ;
73
76
 
74
77
static const char gst_vaapidecode_src_caps_str[] =
75
78
#if GST_CHECK_VERSION(1,1,0)
76
79
    GST_VIDEO_CAPS_MAKE_WITH_FEATURES(
77
 
        GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12 }") ";"
 
80
        GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, I420, YV12, NV12 }") ";"
78
81
    GST_VIDEO_CAPS_MAKE_WITH_FEATURES(
79
 
        GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA");
 
82
        GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA") ";"
 
83
    GST_VIDEO_CAPS_MAKE("{ I420, YV12, NV12 }");
80
84
#else
81
85
    GST_VAAPI_SURFACE_CAPS;
82
86
#endif
95
99
        GST_PAD_ALWAYS,
96
100
        GST_STATIC_CAPS(gst_vaapidecode_src_caps_str));
97
101
 
98
 
/* GstImplementsInterface interface */
99
 
#if !GST_CHECK_VERSION(1,0,0)
100
 
static gboolean
101
 
gst_vaapidecode_implements_interface_supported(
102
 
    GstImplementsInterface *iface,
103
 
    GType                   type
104
 
)
105
 
{
106
 
    return (type == GST_TYPE_VIDEO_CONTEXT);
107
 
}
108
 
 
109
 
static void
110
 
gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface)
111
 
{
112
 
    iface->supported = gst_vaapidecode_implements_interface_supported;
113
 
}
114
 
#endif
115
 
 
116
 
/* GstVideoContext interface */
117
 
#if !GST_CHECK_VERSION(1,1,0)
118
 
static void
119
 
gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type,
120
 
    const GValue *value)
121
 
{
122
 
    GstVaapiDecode *decode = GST_VAAPIDECODE (context);
123
 
    gst_vaapi_set_display (type, value, &decode->display);
124
 
}
125
 
 
126
 
static void
127
 
gst_video_context_interface_init(GstVideoContextInterface *iface)
128
 
{
129
 
    iface->set_context = gst_vaapidecode_set_video_context;
130
 
}
131
 
 
132
 
#define GstVideoContextClass GstVideoContextInterface
133
 
#endif
134
 
 
135
102
G_DEFINE_TYPE_WITH_CODE(
136
103
    GstVaapiDecode,
137
104
    gst_vaapidecode,
138
105
    GST_TYPE_VIDEO_DECODER,
139
 
#if !GST_CHECK_VERSION(1,0,0)
140
 
    G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE,
141
 
                          gst_vaapidecode_implements_iface_init);
142
 
#endif
143
 
#if !GST_CHECK_VERSION(1,1,0)
144
 
    G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT,
145
 
                          gst_video_context_interface_init)
146
 
#endif
147
 
    )
 
106
    GST_VAAPI_PLUGIN_BASE_INIT_INTERFACES)
148
107
 
149
108
static gboolean
150
109
gst_vaapidecode_update_src_caps(GstVaapiDecode *decode,
155
114
    const GstVideoCodecState *codec_state, gpointer user_data)
156
115
{
157
116
    GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data);
 
117
    GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
158
118
 
159
119
    g_assert(decode->decoder == decoder);
160
120
 
161
121
    gst_vaapidecode_update_src_caps(decode, codec_state);
 
122
    gst_video_decoder_negotiate(vdec);
162
123
}
163
124
 
164
125
static inline gboolean
168
129
    return TRUE;
169
130
}
170
131
 
 
132
#if GST_CHECK_VERSION(1,1,0)
 
133
static void
 
134
gst_vaapidecode_video_info_change_format(GstVideoInfo *info,
 
135
    GstVideoFormat format, guint width, guint height)
 
136
{
 
137
    GstVideoInfo vi = *info;
 
138
 
 
139
    gst_video_info_set_format (info, format, width, height);
 
140
 
 
141
    info->interlace_mode = vi.interlace_mode;
 
142
    info->flags = vi.flags;
 
143
    info->views = vi.views;
 
144
    info->par_n = vi.par_n;
 
145
    info->par_d = vi.par_d;
 
146
    info->fps_n = vi.fps_n;
 
147
    info->fps_d = vi.fps_d;
 
148
}
 
149
#endif
 
150
 
171
151
static gboolean
172
152
gst_vaapidecode_update_src_caps(GstVaapiDecode *decode,
173
153
    const GstVideoCodecState *ref_state)
175
155
    GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
176
156
    GstVideoCodecState *state;
177
157
    GstVideoInfo *vi, vis;
178
 
 
179
 
    state = gst_video_decoder_set_output_state(vdec,
180
 
        GST_VIDEO_INFO_FORMAT(&ref_state->info),
 
158
    GstVideoFormat format, out_format;
 
159
#if GST_CHECK_VERSION(1,1,0)
 
160
    GstCapsFeatures *features = NULL;
 
161
    GstVaapiCapsFeature feature;
 
162
 
 
163
    feature = gst_vaapi_find_preferred_caps_feature(
 
164
        GST_VIDEO_DECODER_SRC_PAD(vdec),
 
165
        GST_VIDEO_INFO_FORMAT(&ref_state->info));
 
166
#endif
 
167
 
 
168
    format = GST_VIDEO_INFO_FORMAT(&ref_state->info);
 
169
 
 
170
    state = gst_video_decoder_set_output_state(vdec, format,
181
171
        ref_state->info.width, ref_state->info.height,
182
172
        (GstVideoCodecState *)ref_state);
183
173
    if (!state)
184
174
        return FALSE;
185
175
 
186
176
    vi = &state->info;
187
 
    if (GST_VIDEO_INFO_FORMAT(vi) == GST_VIDEO_FORMAT_ENCODED) {
 
177
    out_format = format;
 
178
    if (format == GST_VIDEO_FORMAT_ENCODED) {
 
179
        out_format = GST_VIDEO_FORMAT_I420;
188
180
        gst_video_info_init(&vis);
189
 
        gst_video_info_set_format(&vis, GST_VIDEO_FORMAT_NV12,
 
181
        gst_video_info_set_format(&vis, out_format,
190
182
            GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi));
191
183
        vi->size = vis.size;
192
184
    }
194
186
 
195
187
#if GST_CHECK_VERSION(1,1,0)
196
188
    vis = *vi;
197
 
    if (GST_VIDEO_INFO_FORMAT(vi) == GST_VIDEO_FORMAT_ENCODED) {
198
 
        /* XXX: this is a workaround until auto-plugging is fixed when
199
 
           format=ENCODED + memory:VASurface caps feature are provided.
200
 
           Meanwhile, providing a random format here works but this is
201
 
           a terribly wrong thing per se. */
202
 
        gst_video_info_set_format(&vis, GST_VIDEO_FORMAT_NV12,
 
189
    switch (feature) {
 
190
    case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META:
 
191
        gst_vaapidecode_video_info_change_format(&vis, GST_VIDEO_FORMAT_RGBA,
203
192
            GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi));
 
193
        features = gst_caps_features_new(
 
194
            GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL);
 
195
        break;
 
196
    default:
 
197
        if (format == GST_VIDEO_FORMAT_ENCODED) {
 
198
            /* XXX: this is a workaround until auto-plugging is fixed when
 
199
               format=ENCODED + memory:VASurface caps feature are provided.
 
200
               Meanwhile, providing a random format here works but this is
 
201
               a terribly wrong thing per se. */
 
202
            gst_vaapidecode_video_info_change_format(&vis, out_format,
 
203
                GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi));
 
204
#if GST_CHECK_VERSION(1,5,0)
 
205
            if (feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE)
 
206
                features = gst_caps_features_new(
 
207
                    GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, NULL);
 
208
#endif
 
209
        }
 
210
        break;
204
211
    }
205
212
    state->caps = gst_video_info_to_caps(&vis);
 
213
    if (features)
 
214
        gst_caps_set_features(state->caps, 0, features);
206
215
#else
207
216
    /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not
208
217
       reconstruct suitable caps for "encoded" video formats */
341
350
            }
342
351
        }
343
352
 
344
 
#if GST_CHECK_VERSION(1,1,0)
 
353
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
345
354
        if (decode->has_texture_upload_meta)
346
 
            gst_buffer_add_texture_upload_meta(out_frame->output_buffer);
 
355
            gst_buffer_ensure_texture_upload_meta(out_frame->output_buffer);
347
356
#endif
348
357
#else
349
358
        out_frame->output_buffer =
430
439
    decode->decoder_loop_status = ret;
431
440
    GST_VIDEO_DECODER_STREAM_UNLOCK(vdec);
432
441
 
433
 
    if (ret == GST_FLOW_OK)
434
 
        return;
435
 
 
436
442
    /* If invoked from gst_vaapidecode_finish(), then return right
437
443
       away no matter the errors, or the GstVaapiDecoder needs further
438
444
       data to complete decoding (there no more data to feed in) */
439
445
    if (decode->decoder_finish) {
440
446
        g_mutex_lock(&decode->decoder_mutex);
 
447
        decode->decoder_loop_status = GST_FLOW_EOS;
441
448
        g_cond_signal(&decode->decoder_finish_done);
442
449
        g_mutex_unlock(&decode->decoder_mutex);
443
450
        return;
444
451
    }
445
452
 
 
453
    if (ret == GST_FLOW_OK)
 
454
        return;
 
455
 
446
456
    /* Suspend the task if an error occurred */
447
457
    if (ret != GST_VIDEO_DECODER_FLOW_NEED_DATA)
448
 
        gst_pad_pause_task(decode->srcpad);
 
458
        gst_pad_pause_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode));
449
459
}
450
460
 
451
461
static gboolean
485
495
 
486
496
    /* Make sure the decode loop function has a chance to return, thus
487
497
       possibly unlocking gst_video_decoder_finish_frame() */
488
 
    GST_VIDEO_DECODER_STREAM_UNLOCK(vdec);
489
 
    g_mutex_lock(&decode->decoder_mutex);
490
498
    decode->decoder_finish = TRUE;
491
 
    g_cond_wait(&decode->decoder_finish_done, &decode->decoder_mutex);
492
 
    g_mutex_unlock(&decode->decoder_mutex);
493
 
    gst_pad_stop_task(decode->srcpad);
494
 
    GST_VIDEO_DECODER_STREAM_LOCK(vdec);
 
499
    if (decode->decoder_loop_status == GST_FLOW_OK) {
 
500
        GST_VIDEO_DECODER_STREAM_UNLOCK(vdec);
 
501
        g_mutex_lock(&decode->decoder_mutex);
 
502
        while (decode->decoder_loop_status != GST_FLOW_OK)
 
503
            g_cond_wait(&decode->decoder_finish_done, &decode->decoder_mutex);
 
504
        g_mutex_unlock(&decode->decoder_mutex);
 
505
        gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode));
 
506
        GST_VIDEO_DECODER_STREAM_LOCK(vdec);
 
507
    }
495
508
    return ret;
496
509
}
497
510
 
506
519
    GstVideoInfo vi;
507
520
    guint size, min, max;
508
521
    gboolean need_pool, update_pool;
 
522
    gboolean has_video_meta = FALSE;
 
523
    gboolean has_video_alignment = FALSE;
 
524
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
 
525
    gboolean has_texture_upload_meta = FALSE;
 
526
#endif
 
527
    GstVideoCodecState *state;
509
528
 
510
529
    gst_query_parse_allocation(query, &caps, &need_pool);
511
530
 
512
531
    if (!caps)
513
532
        goto error_no_caps;
514
533
 
 
534
    state = gst_video_decoder_get_output_state(vdec);
 
535
 
 
536
    decode->has_texture_upload_meta = FALSE;
 
537
    has_video_meta = gst_query_find_allocation_meta(query,
 
538
        GST_VIDEO_META_API_TYPE, NULL);
 
539
 
 
540
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
 
541
    has_texture_upload_meta = gst_query_find_allocation_meta(query,
 
542
        GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL);
 
543
 
 
544
    decode->has_texture_upload_meta =
 
545
        gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec),
 
546
            GST_VIDEO_FORMAT_ENCODED) ==
 
547
        GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META;
 
548
#endif
 
549
 
 
550
    /* Update src caps if feature is not handled downstream */
 
551
    if (!gst_caps_is_always_compatible(caps, state->caps)) {
 
552
        if (decode->has_texture_upload_meta)
 
553
            gst_video_info_set_format(&state->info, GST_VIDEO_FORMAT_RGBA,
 
554
                GST_VIDEO_INFO_WIDTH(&state->info),
 
555
                GST_VIDEO_INFO_HEIGHT(&state->info));
 
556
        gst_vaapidecode_update_src_caps(decode, state);
 
557
    }
 
558
    gst_video_codec_state_unref(state);
 
559
 
515
560
    gst_video_info_init(&vi);
516
561
    gst_video_info_from_caps(&vi, caps);
517
562
    if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED)
518
 
        gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12,
 
563
        gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_I420,
519
564
            GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi));
520
565
 
521
 
    g_return_val_if_fail(decode->display != NULL, FALSE);
 
566
    g_return_val_if_fail(GST_VAAPI_PLUGIN_BASE_DISPLAY(decode) != NULL, FALSE);
522
567
 
523
568
    if (gst_query_get_n_allocation_pools(query) > 0) {
524
569
        gst_query_parse_nth_allocation_pool(query, 0, &pool, &size, &min, &max);
525
570
        size = MAX(size, vi.size);
526
571
        update_pool = TRUE;
 
572
 
 
573
        /* Check whether downstream element proposed a bufferpool but did
 
574
           not provide a correct propose_allocation() implementation */
 
575
        has_video_alignment = gst_buffer_pool_has_option(pool,
 
576
            GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
527
577
    }
528
578
    else {
529
579
        pool = NULL;
536
586
            GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META)) {
537
587
        GST_INFO("no pool or doesn't support GstVaapiVideoMeta, "
538
588
            "making new pool");
539
 
        pool = gst_vaapi_video_buffer_pool_new(decode->display);
 
589
        if (pool)
 
590
            gst_object_unref(pool);
 
591
        pool = gst_vaapi_video_buffer_pool_new(
 
592
            GST_VAAPI_PLUGIN_BASE_DISPLAY(decode));
540
593
        if (!pool)
541
594
            goto error_create_pool;
542
595
 
547
600
        gst_buffer_pool_set_config(pool, config);
548
601
    }
549
602
 
550
 
    decode->has_texture_upload_meta = FALSE;
551
 
    if (gst_query_find_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL)) {
 
603
    if (has_video_meta) {
552
604
        config = gst_buffer_pool_get_config(pool);
553
605
        gst_buffer_pool_config_add_option(config,
554
606
            GST_BUFFER_POOL_OPTION_VIDEO_META);
555
 
        gst_buffer_pool_set_config(pool, config);
556
 
#if GST_CHECK_VERSION(1,1,0)
557
 
        decode->has_texture_upload_meta = gst_query_find_allocation_meta(query,
558
 
            GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL);
559
 
#endif
560
 
    }
 
607
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
 
608
        if (has_texture_upload_meta)
 
609
            gst_buffer_pool_config_add_option(config,
 
610
                GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META);
 
611
#endif
 
612
        gst_buffer_pool_set_config(pool, config);
 
613
    }
 
614
    else if (has_video_alignment) {
 
615
        config = gst_buffer_pool_get_config(pool);
 
616
        gst_buffer_pool_config_add_option(config,
 
617
            GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
 
618
        gst_buffer_pool_set_config(pool, config);
 
619
    }
 
620
 
 
621
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
 
622
    if (decode->has_texture_upload_meta && !has_texture_upload_meta) {
 
623
        config = gst_buffer_pool_get_config(pool);
 
624
        gst_buffer_pool_config_add_option(config,
 
625
            GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META);
 
626
        gst_buffer_pool_set_config(pool, config);
 
627
    }
 
628
#endif
561
629
 
562
630
    if (update_pool)
563
631
        gst_query_set_nth_allocation_pool(query, 0, pool, size, min, max);
581
649
}
582
650
#endif
583
651
 
584
 
#if GST_CHECK_VERSION(1,1,0)
585
 
static void
586
 
gst_vaapidecode_set_context(GstElement *element, GstContext *context)
587
 
{
588
 
    GstVaapiDecode * const decode = GST_VAAPIDECODE(element);
589
 
    GstVaapiDisplay *display = NULL;
590
 
 
591
 
    if (gst_vaapi_video_context_get_display(context, &display)) {
592
 
        GST_INFO_OBJECT(element, "set display %p", display);
593
 
        gst_vaapi_display_replace(&decode->display, display);
594
 
    }
595
 
}
596
 
#endif
597
 
 
598
652
static inline gboolean
599
653
gst_vaapidecode_ensure_display(GstVaapiDecode *decode)
600
654
{
601
 
    return gst_vaapi_ensure_display(decode, GST_VAAPI_DISPLAY_TYPE_ANY,
602
 
        &decode->display);
 
655
    return gst_vaapi_plugin_base_ensure_display(GST_VAAPI_PLUGIN_BASE(decode));
603
656
}
604
657
 
605
658
static inline guint
615
668
 
616
669
    if (!gst_vaapidecode_ensure_display(decode))
617
670
        return FALSE;
618
 
    dpy = decode->display;
 
671
    dpy = GST_VAAPI_PLUGIN_BASE_DISPLAY(decode);
619
672
 
620
673
    switch (gst_vaapi_codec_from_caps(caps)) {
621
674
    case GST_VAAPI_CODEC_MPEG2:
627
680
        break;
628
681
    case GST_VAAPI_CODEC_H264:
629
682
        decode->decoder = gst_vaapi_decoder_h264_new(dpy, caps);
 
683
 
 
684
        /* Set the stream buffer alignment for better optimizations */
 
685
        if (decode->decoder && caps) {
 
686
            GstStructure * const structure = gst_caps_get_structure(caps, 0);
 
687
            const gchar *str = NULL;
 
688
 
 
689
            if ((str = gst_structure_get_string(structure, "alignment"))) {
 
690
                GstVaapiStreamAlignH264 alignment;
 
691
                if (g_strcmp0(str, "au") == 0)
 
692
                    alignment = GST_VAAPI_STREAM_ALIGN_H264_AU;
 
693
                else if (g_strcmp0(str, "nal") == 0)
 
694
                    alignment = GST_VAAPI_STREAM_ALIGN_H264_NALU;
 
695
                else
 
696
                    alignment = GST_VAAPI_STREAM_ALIGN_H264_NONE;
 
697
                gst_vaapi_decoder_h264_set_alignment(
 
698
                    GST_VAAPI_DECODER_H264(decode->decoder), alignment);
 
699
            }
 
700
        }
630
701
        break;
631
702
    case GST_VAAPI_CODEC_WMV3:
632
703
    case GST_VAAPI_CODEC_VC1:
637
708
        decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps);
638
709
        break;
639
710
#endif
 
711
#if USE_VP8_DECODER
 
712
    case GST_VAAPI_CODEC_VP8:
 
713
        decode->decoder = gst_vaapi_decoder_vp8_new(dpy, caps);
 
714
        break;
 
715
#endif
640
716
    default:
641
717
        decode->decoder = NULL;
642
718
        break;
648
724
        gst_vaapi_decoder_state_changed, decode);
649
725
 
650
726
    decode->decoder_caps = gst_caps_ref(caps);
651
 
    return gst_pad_start_task(decode->srcpad,
 
727
    return gst_pad_start_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode),
652
728
        (GstTaskFunction)gst_vaapidecode_decode_loop, decode, NULL);
653
729
}
654
730
 
655
731
static void
656
732
gst_vaapidecode_destroy(GstVaapiDecode *decode)
657
733
{
658
 
    gst_pad_stop_task(decode->srcpad);
 
734
    gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode));
659
735
    gst_vaapi_decoder_replace(&decode->decoder, NULL);
660
736
    gst_caps_replace(&decode->decoder_caps, NULL);
661
737
    gst_vaapidecode_release(decode);
678
754
 
679
755
        gst_vaapi_decoder_flush(decode->decoder);
680
756
        GST_VIDEO_DECODER_STREAM_UNLOCK(vdec);
681
 
        gst_pad_stop_task(decode->srcpad);
 
757
        gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode));
682
758
        GST_VIDEO_DECODER_STREAM_LOCK(vdec);
683
759
        decode->decoder_loop_status = GST_FLOW_OK;
684
760
 
712
788
    gst_caps_replace(&decode->srcpad_caps,  NULL);
713
789
    gst_caps_replace(&decode->allowed_caps, NULL);
714
790
 
715
 
    gst_vaapi_display_replace(&decode->display, NULL);
716
 
 
717
791
    g_cond_clear(&decode->decoder_finish_done);
718
792
    g_cond_clear(&decode->decoder_ready);
719
793
    g_mutex_clear(&decode->decoder_mutex);
720
794
 
 
795
    gst_vaapi_plugin_base_finalize(GST_VAAPI_PLUGIN_BASE(object));
721
796
    G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object);
722
797
}
723
798
 
725
800
gst_vaapidecode_open(GstVideoDecoder *vdec)
726
801
{
727
802
    GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
728
 
    GstVaapiDisplay * const old_display = decode->display;
 
803
    GstVaapiDisplay * const old_display = GST_VAAPI_PLUGIN_BASE_DISPLAY(decode);
729
804
    gboolean success;
730
805
 
 
806
    if (!gst_vaapi_plugin_base_open(GST_VAAPI_PLUGIN_BASE(decode)))
 
807
        return FALSE;
 
808
 
731
809
    /* Let GstVideoContext ask for a proper display to its neighbours */
732
810
    /* Note: steal old display that may be allocated from get_caps()
733
811
       so that to retain a reference to it, thus avoiding extra
734
812
       initialization steps if we turn out to simply re-use the
735
813
       existing (cached) VA display */
736
 
    decode->display = NULL;
 
814
    GST_VAAPI_PLUGIN_BASE_DISPLAY(decode) = NULL;
737
815
    success = gst_vaapidecode_ensure_display(decode);
738
816
    if (old_display)
739
817
        gst_vaapi_display_unref(old_display);
746
824
    GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
747
825
 
748
826
    gst_vaapidecode_destroy(decode);
749
 
    gst_vaapi_display_replace(&decode->display, NULL);
 
827
    gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(decode));
750
828
    return TRUE;
751
829
}
752
830
 
764
842
static gboolean
765
843
gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state)
766
844
{
 
845
    GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(vdec);
767
846
    GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
768
847
 
769
848
    if (!gst_vaapidecode_update_sink_caps(decode, state->caps))
770
849
        return FALSE;
771
850
    if (!gst_vaapidecode_update_src_caps(decode, state))
772
851
        return FALSE;
 
852
    if (!gst_video_decoder_negotiate(vdec))
 
853
        return FALSE;
 
854
    if (!gst_vaapi_plugin_base_set_caps(plugin, decode->sinkpad_caps,
 
855
            decode->srcpad_caps))
 
856
        return FALSE;
773
857
    if (!gst_vaapidecode_reset_full(decode, decode->sinkpad_caps, FALSE))
774
858
        return FALSE;
775
859
    return TRUE;
776
860
}
777
861
 
778
862
static GstFlowReturn
779
 
gst_vaapidecode_parse(GstVideoDecoder *vdec,
 
863
gst_vaapidecode_parse_frame(GstVideoDecoder *vdec,
780
864
    GstVideoCodecFrame *frame, GstAdapter *adapter, gboolean at_eos)
781
865
{
782
866
    GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
799
883
            decode->current_frame_size = 0;
800
884
        }
801
885
        else
802
 
            ret = GST_FLOW_OK;
 
886
            ret = GST_VAAPI_DECODE_FLOW_PARSE_DATA;
803
887
        break;
804
888
    case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA:
805
889
        ret = GST_VIDEO_DECODER_FLOW_NEED_DATA;
820
904
    return ret;
821
905
}
822
906
 
 
907
static GstFlowReturn
 
908
gst_vaapidecode_parse(GstVideoDecoder *vdec,
 
909
    GstVideoCodecFrame *frame, GstAdapter *adapter, gboolean at_eos)
 
910
{
 
911
    GstFlowReturn ret;
 
912
 
 
913
    do {
 
914
        ret = gst_vaapidecode_parse_frame(vdec, frame, adapter, at_eos);
 
915
    } while (ret == GST_VAAPI_DECODE_FLOW_PARSE_DATA);
 
916
    return ret;
 
917
}
 
918
 
 
919
static GstStateChangeReturn
 
920
gst_vaapidecode_change_state (GstElement * element, GstStateChange transition)
 
921
{
 
922
    GstVaapiDecode * const decode = GST_VAAPIDECODE(element);
 
923
 
 
924
    switch (transition) {
 
925
    case GST_STATE_CHANGE_PAUSED_TO_READY:
 
926
        gst_pad_stop_task(GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode));
 
927
        break;
 
928
    default:
 
929
        break;
 
930
    }
 
931
    return GST_ELEMENT_CLASS(gst_vaapidecode_parent_class)->change_state(
 
932
        element, transition);
 
933
}
 
934
 
823
935
static void
824
936
gst_vaapidecode_class_init(GstVaapiDecodeClass *klass)
825
937
{
831
943
    GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode,
832
944
                            GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
833
945
 
 
946
    gst_vaapi_plugin_base_class_init(GST_VAAPI_PLUGIN_BASE_CLASS(klass));
 
947
 
834
948
    object_class->finalize   = gst_vaapidecode_finalize;
835
949
 
 
950
    element_class->change_state =
 
951
        GST_DEBUG_FUNCPTR(gst_vaapidecode_change_state);
 
952
 
836
953
    vdec_class->open         = GST_DEBUG_FUNCPTR(gst_vaapidecode_open);
837
954
    vdec_class->close        = GST_DEBUG_FUNCPTR(gst_vaapidecode_close);
838
955
    vdec_class->set_format   = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_format);
846
963
        GST_DEBUG_FUNCPTR(gst_vaapidecode_decide_allocation);
847
964
#endif
848
965
 
849
 
#if GST_CHECK_VERSION(1,1,0)
850
 
    element_class->set_context = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_context);
851
 
#endif
852
 
 
853
966
    gst_element_class_set_static_metadata(element_class,
854
967
        "VA-API decoder",
855
968
        "Codec/Decoder/Video",
868
981
static gboolean
869
982
gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode)
870
983
{
871
 
    GstCaps *decode_caps;
872
 
    guint i, n_decode_caps;
 
984
    GstCaps *caps, *allowed_caps;
 
985
    GArray *profiles;
 
986
    guint i;
873
987
 
874
988
    if (decode->allowed_caps)
875
989
        return TRUE;
877
991
    if (!gst_vaapidecode_ensure_display(decode))
878
992
        goto error_no_display;
879
993
 
880
 
    decode_caps = gst_vaapi_display_get_decode_caps(decode->display);
881
 
    if (!decode_caps)
882
 
        goto error_no_decode_caps;
883
 
    n_decode_caps = gst_caps_get_size(decode_caps);
 
994
    profiles = gst_vaapi_display_get_decode_profiles(
 
995
        GST_VAAPI_PLUGIN_BASE_DISPLAY(decode));
 
996
    if (!profiles)
 
997
        goto error_no_profiles;
884
998
 
885
 
    decode->allowed_caps = gst_caps_new_empty();
886
 
    if (!decode->allowed_caps)
 
999
    allowed_caps = gst_caps_new_empty();
 
1000
    if (!allowed_caps)
887
1001
        goto error_no_memory;
888
1002
 
889
 
    for (i = 0; i < n_decode_caps; i++) {
890
 
        GstStructure *structure;
891
 
        structure = gst_caps_get_structure(decode_caps, i);
892
 
        if (!structure)
893
 
            continue;
894
 
        structure = gst_structure_copy(structure);
895
 
        if (!structure)
896
 
            continue;
897
 
        gst_structure_remove_field(structure, "profile");
898
 
        decode->allowed_caps =
899
 
            gst_caps_merge_structure(decode->allowed_caps, structure);
 
1003
    for (i = 0; i < profiles->len; i++) {
 
1004
        const GstVaapiProfile profile =
 
1005
            g_array_index(profiles, GstVaapiProfile, i);
 
1006
        const gchar *media_type_name;
 
1007
 
 
1008
        media_type_name = gst_vaapi_profile_get_media_type_name(profile);
 
1009
        if (!media_type_name)
 
1010
            continue;
 
1011
 
 
1012
        caps = gst_caps_from_string(media_type_name);
 
1013
        if (!caps)
 
1014
            continue;
 
1015
        allowed_caps = gst_caps_merge(allowed_caps, caps);
900
1016
    }
 
1017
    decode->allowed_caps = allowed_caps;
901
1018
 
902
 
    gst_caps_unref(decode_caps);
 
1019
    g_array_unref(profiles);
903
1020
    return TRUE;
904
1021
 
905
1022
    /* ERRORS */
908
1025
        GST_ERROR("failed to retrieve VA display");
909
1026
        return FALSE;
910
1027
    }
911
 
error_no_decode_caps:
 
1028
error_no_profiles:
912
1029
    {
913
 
        GST_ERROR("failed to retrieve VA decode caps");
 
1030
        GST_ERROR("failed to retrieve VA decode profiles");
914
1031
        return FALSE;
915
1032
    }
916
1033
error_no_memory:
917
1034
    {
918
1035
        GST_ERROR("failed to allocate allowed-caps set");
919
 
        gst_caps_unref(decode_caps);
 
1036
        g_array_unref(profiles);
920
1037
        return FALSE;
921
1038
    }
922
1039
}
937
1054
{
938
1055
    GstVaapiDecode * const decode =
939
1056
        GST_VAAPIDECODE(gst_pad_get_parent_element(pad));
 
1057
    GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(decode);
940
1058
    gboolean res;
941
1059
 
942
1060
    GST_INFO_OBJECT(decode, "query type %s", GST_QUERY_TYPE_NAME(query));
943
1061
 
944
 
    if (gst_vaapi_reply_to_query(query, decode->display)) {
945
 
        GST_DEBUG("sharing display %p", decode->display);
 
1062
    if (gst_vaapi_reply_to_query(query, plugin->display)) {
 
1063
        GST_DEBUG("sharing display %p", plugin->display);
946
1064
        res = TRUE;
947
1065
    }
948
1066
    else if (GST_PAD_IS_SINK(pad)) {
957
1075
        }
958
1076
#endif
959
1077
        default:
960
 
            res = GST_PAD_QUERY_FUNCTION_CALL(decode->sinkpad_query,
961
 
                decode->sinkpad, parent, query);
 
1078
            res = GST_PAD_QUERY_FUNCTION_CALL(plugin->sinkpad_query, pad,
 
1079
                parent, query);
962
1080
            break;
963
1081
        }
964
1082
    }
965
1083
    else
966
 
        res = GST_PAD_QUERY_FUNCTION_CALL(decode->srcpad_query,
967
 
            decode->srcpad, parent, query);
 
1084
        res = GST_PAD_QUERY_FUNCTION_CALL(plugin->srcpad_query, pad,
 
1085
            parent, query);
968
1086
 
969
1087
    gst_object_unref(decode);
970
1088
    return res;
974
1092
gst_vaapidecode_init(GstVaapiDecode *decode)
975
1093
{
976
1094
    GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
977
 
 
978
 
    decode->display             = NULL;
 
1095
    GstPad *pad;
 
1096
 
 
1097
    gst_vaapi_plugin_base_init(GST_VAAPI_PLUGIN_BASE(decode), GST_CAT_DEFAULT);
 
1098
 
979
1099
    decode->decoder             = NULL;
980
1100
    decode->decoder_caps        = NULL;
981
1101
    decode->allowed_caps        = NULL;
988
1108
    gst_video_decoder_set_packetized(vdec, FALSE);
989
1109
 
990
1110
    /* Pad through which data comes in to the element */
991
 
    decode->sinkpad = GST_VIDEO_DECODER_SINK_PAD(vdec);
992
 
    decode->sinkpad_query = GST_PAD_QUERYFUNC(decode->sinkpad);
993
 
    gst_pad_set_query_function(decode->sinkpad, gst_vaapidecode_query);
 
1111
    pad = GST_VAAPI_PLUGIN_BASE_SINK_PAD(decode);
 
1112
    gst_pad_set_query_function(pad, gst_vaapidecode_query);
994
1113
#if !GST_CHECK_VERSION(1,0,0)
995
 
    gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps);
 
1114
    gst_pad_set_getcaps_function(pad, gst_vaapidecode_get_caps);
996
1115
#endif
997
1116
 
998
1117
    /* Pad through which data goes out of the element */
999
 
    decode->srcpad = GST_VIDEO_DECODER_SRC_PAD(vdec);
1000
 
    decode->srcpad_query = GST_PAD_QUERYFUNC(decode->srcpad);
1001
 
    gst_pad_set_query_function(decode->srcpad, gst_vaapidecode_query);
 
1118
    pad = GST_VAAPI_PLUGIN_BASE_SRC_PAD(decode);
 
1119
    gst_pad_set_query_function(pad, gst_vaapidecode_query);
1002
1120
}