Merging gst-plugins-bad
[platform/upstream/gstreamer.git] / sys / d3d11 / gstd3d11h265dec.cpp
1 /* GStreamer
2  * Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /**
21  * SECTION:element-d3d11h265dec
22  * @title: d3d11h265dec
23  *
24  * A Direct3D11/DXVA based H.265 video decoder
25  *
26  * ## Example launch line
27  * ```
28  * gst-launch-1.0 filesrc location=/path/to/hevc/file ! parsebin ! d3d11h265dec ! d3d11videosink
29  * ```
30  *
31  * Since: 1.18
32  *
33  */
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include "gstd3d11h265dec.h"
40
41 #include <gst/codecs/gsth265decoder.h>
42 #include <string.h>
43 #include <vector>
44
45 /* HACK: to expose dxva data structure on UWP */
46 #ifdef WINAPI_PARTITION_DESKTOP
47 #undef WINAPI_PARTITION_DESKTOP
48 #endif
49 #define WINAPI_PARTITION_DESKTOP 1
50 #include <d3d9.h>
51 #include <dxva.h>
52
53 GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_h265_dec_debug);
54 #define GST_CAT_DEFAULT gst_d3d11_h265_dec_debug
55
56 /* *INDENT-OFF* */
57 typedef struct _GstD3D11H265DecInner
58 {
59   GstD3D11Device *device = nullptr;
60   GstD3D11Decoder *d3d11_decoder = nullptr;
61
62   DXVA_PicParams_HEVC pic_params;
63   DXVA_Qmatrix_HEVC iq_matrix;
64
65   std::vector<DXVA_Slice_HEVC_Short> slice_list;
66   std::vector<guint8> bitstream_buffer;
67
68   gboolean submit_iq_data;
69
70   gint width = 0;
71   gint height = 0;
72   gint coded_width = 0;
73   gint coded_height = 0;
74   guint bitdepth = 0;
75   guint8 chroma_format_idc = 0;
76   GstVideoFormat out_format = GST_VIDEO_FORMAT_UNKNOWN;
77   GstVideoInterlaceMode interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
78 } GstD3D11H265DecInner;
79 /* *INDENT-ON* */
80
81 typedef struct _GstD3D11H265Dec
82 {
83   GstH265Decoder parent;
84   GstD3D11H265DecInner *inner;
85 } GstD3D11H265Dec;
86
87 typedef struct _GstD3D11H265DecClass
88 {
89   GstH265DecoderClass parent_class;
90   GstD3D11DecoderSubClassData class_data;
91 } GstD3D11H265DecClass;
92
93 static GstElementClass *parent_class = NULL;
94
95 #define GST_D3D11_H265_DEC(object) ((GstD3D11H265Dec *) (object))
96 #define GST_D3D11_H265_DEC_GET_CLASS(object) \
97     (G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstD3D11H265DecClass))
98
99 static void gst_d3d11_h265_dec_get_property (GObject * object,
100     guint prop_id, GValue * value, GParamSpec * pspec);
101 static void gst_d3d11_h265_dec_finalize (GObject * object);
102 static void gst_d3d11_h265_dec_set_context (GstElement * element,
103     GstContext * context);
104
105 static gboolean gst_d3d11_h265_dec_open (GstVideoDecoder * decoder);
106 static gboolean gst_d3d11_h265_dec_close (GstVideoDecoder * decoder);
107 static gboolean gst_d3d11_h265_dec_negotiate (GstVideoDecoder * decoder);
108 static gboolean gst_d3d11_h265_dec_decide_allocation (GstVideoDecoder *
109     decoder, GstQuery * query);
110 static gboolean gst_d3d11_h265_dec_src_query (GstVideoDecoder * decoder,
111     GstQuery * query);
112 static gboolean gst_d3d11_h265_dec_sink_event (GstVideoDecoder * decoder,
113     GstEvent * event);
114
115 /* GstH265Decoder */
116 static gboolean gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder,
117     const GstH265SPS * sps, gint max_dpb_size);
118 static gboolean gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder,
119     GstVideoCodecFrame * cframe, GstH265Picture * picture);
120 static GstFlowReturn gst_d3d11_h265_dec_output_picture (GstH265Decoder *
121     decoder, GstVideoCodecFrame * frame, GstH265Picture * picture);
122 static gboolean gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
123     GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb);
124 static gboolean gst_d3d11_h265_dec_decode_slice (GstH265Decoder * decoder,
125     GstH265Picture * picture, GstH265Slice * slice,
126     GArray * ref_pic_list0, GArray * ref_pic_list1);
127 static gboolean gst_d3d11_h265_dec_end_picture (GstH265Decoder * decoder,
128     GstH265Picture * picture);
129
130 static void
131 gst_d3d11_h265_dec_class_init (GstD3D11H265DecClass * klass, gpointer data)
132 {
133   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
134   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
135   GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
136   GstH265DecoderClass *h265decoder_class = GST_H265_DECODER_CLASS (klass);
137   GstD3D11DecoderClassData *cdata = (GstD3D11DecoderClassData *) data;
138
139   gobject_class->get_property = gst_d3d11_h265_dec_get_property;
140   gobject_class->finalize = gst_d3d11_h265_dec_finalize;
141
142   element_class->set_context =
143       GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_set_context);
144
145   parent_class = (GstElementClass *) g_type_class_peek_parent (klass);
146   gst_d3d11_decoder_class_data_fill_subclass_data (cdata, &klass->class_data);
147   gst_d3d11_decoder_proxy_class_init (element_class, cdata,
148       "Seungha Yang <seungha.yang@navercorp.com>");
149
150   decoder_class->open = GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_open);
151   decoder_class->close = GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_close);
152   decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_negotiate);
153   decoder_class->decide_allocation =
154       GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_decide_allocation);
155   decoder_class->src_query = GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_src_query);
156   decoder_class->sink_event = GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_sink_event);
157
158   h265decoder_class->new_sequence =
159       GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_new_sequence);
160   h265decoder_class->new_picture =
161       GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_new_picture);
162   h265decoder_class->output_picture =
163       GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_output_picture);
164   h265decoder_class->start_picture =
165       GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_start_picture);
166   h265decoder_class->decode_slice =
167       GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_decode_slice);
168   h265decoder_class->end_picture =
169       GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_end_picture);
170 }
171
172 static void
173 gst_d3d11_h265_dec_init (GstD3D11H265Dec * self)
174 {
175   self->inner = new GstD3D11H265DecInner ();
176 }
177
178 static void
179 gst_d3d11_h265_dec_get_property (GObject * object, guint prop_id,
180     GValue * value, GParamSpec * pspec)
181 {
182   GstD3D11H265DecClass *klass = GST_D3D11_H265_DEC_GET_CLASS (object);
183   GstD3D11DecoderSubClassData *cdata = &klass->class_data;
184
185   gst_d3d11_decoder_proxy_get_property (object, prop_id, value, pspec, cdata);
186 }
187
188 static void
189 gst_d3d11_h265_dec_finalize (GObject * object)
190 {
191   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (object);
192
193   delete self->inner;
194
195   G_OBJECT_CLASS (parent_class)->finalize (object);
196 }
197
198 static void
199 gst_d3d11_h265_dec_set_context (GstElement * element, GstContext * context)
200 {
201   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (element);
202   GstD3D11H265DecInner *inner = self->inner;
203   GstD3D11H265DecClass *klass = GST_D3D11_H265_DEC_GET_CLASS (self);
204   GstD3D11DecoderSubClassData *cdata = &klass->class_data;
205
206   gst_d3d11_handle_set_context (element, context, cdata->adapter,
207       &inner->device);
208
209   GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
210 }
211
212 static gboolean
213 gst_d3d11_h265_dec_open (GstVideoDecoder * decoder)
214 {
215   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
216   GstD3D11H265DecInner *inner = self->inner;
217   GstD3D11H265DecClass *klass = GST_D3D11_H265_DEC_GET_CLASS (self);
218   GstD3D11DecoderSubClassData *cdata = &klass->class_data;
219
220   if (!gst_d3d11_ensure_element_data (GST_ELEMENT_CAST (self), cdata->adapter,
221           &inner->device)) {
222     GST_ERROR_OBJECT (self, "Cannot create d3d11device");
223     return FALSE;
224   }
225
226   inner->d3d11_decoder = gst_d3d11_decoder_new (inner->device,
227       GST_DXVA_CODEC_H265);
228
229   if (!inner->d3d11_decoder) {
230     GST_ERROR_OBJECT (self, "Cannot create d3d11 decoder");
231     gst_clear_object (&inner->device);
232     return FALSE;
233   }
234
235   return TRUE;
236 }
237
238 static gboolean
239 gst_d3d11_h265_dec_close (GstVideoDecoder * decoder)
240 {
241   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
242   GstD3D11H265DecInner *inner = self->inner;
243
244   gst_clear_object (&inner->d3d11_decoder);
245   gst_clear_object (&inner->device);
246
247   return TRUE;
248 }
249
250 static gboolean
251 gst_d3d11_h265_dec_negotiate (GstVideoDecoder * decoder)
252 {
253   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
254   GstD3D11H265DecInner *inner = self->inner;
255
256   if (!gst_d3d11_decoder_negotiate (inner->d3d11_decoder, decoder))
257     return FALSE;
258
259   return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
260 }
261
262 static gboolean
263 gst_d3d11_h265_dec_decide_allocation (GstVideoDecoder * decoder,
264     GstQuery * query)
265 {
266   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
267   GstD3D11H265DecInner *inner = self->inner;
268
269   if (!gst_d3d11_decoder_decide_allocation (inner->d3d11_decoder,
270           decoder, query)) {
271     return FALSE;
272   }
273
274   return GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation
275       (decoder, query);
276 }
277
278 static gboolean
279 gst_d3d11_h265_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
280 {
281   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
282   GstD3D11H265DecInner *inner = self->inner;
283
284   switch (GST_QUERY_TYPE (query)) {
285     case GST_QUERY_CONTEXT:
286       if (gst_d3d11_handle_context_query (GST_ELEMENT (decoder),
287               query, inner->device)) {
288         return TRUE;
289       }
290       break;
291     default:
292       break;
293   }
294
295   return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (decoder, query);
296 }
297
298 static gboolean
299 gst_d3d11_h265_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event)
300 {
301   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
302   GstD3D11H265DecInner *inner = self->inner;
303
304   switch (GST_EVENT_TYPE (event)) {
305     case GST_EVENT_FLUSH_START:
306       if (inner->d3d11_decoder)
307         gst_d3d11_decoder_set_flushing (inner->d3d11_decoder, decoder, TRUE);
308       break;
309     case GST_EVENT_FLUSH_STOP:
310       if (inner->d3d11_decoder)
311         gst_d3d11_decoder_set_flushing (inner->d3d11_decoder, decoder, FALSE);
312     default:
313       break;
314   }
315
316   return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event);
317 }
318
319 static gboolean
320 gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder,
321     const GstH265SPS * sps, gint max_dpb_size)
322 {
323   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
324   GstD3D11H265DecInner *inner = self->inner;
325   gint crop_width, crop_height;
326   gboolean modified = FALSE;
327   GstVideoInterlaceMode interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
328
329   GST_LOG_OBJECT (self, "new sequence");
330
331   if (sps->conformance_window_flag) {
332     crop_width = sps->crop_rect_width;
333     crop_height = sps->crop_rect_height;
334   } else {
335     crop_width = sps->width;
336     crop_height = sps->height;
337   }
338
339   if (inner->width != crop_width || inner->height != crop_height ||
340       inner->coded_width != sps->width || inner->coded_height != sps->height) {
341     GST_INFO_OBJECT (self, "resolution changed %dx%d -> %dx%d",
342         crop_width, crop_height, sps->width, sps->height);
343     inner->width = crop_width;
344     inner->height = crop_height;
345     inner->coded_width = sps->width;
346     inner->coded_height = sps->height;
347     modified = TRUE;
348   }
349
350   if (inner->bitdepth != (guint) sps->bit_depth_luma_minus8 + 8) {
351     GST_INFO_OBJECT (self, "bitdepth changed");
352     inner->bitdepth = sps->bit_depth_luma_minus8 + 8;
353     modified = TRUE;
354   }
355
356   if (sps->vui_parameters_present_flag && sps->vui_params.field_seq_flag) {
357     interlace_mode = GST_VIDEO_INTERLACE_MODE_ALTERNATE;
358   } else {
359     /* 7.4.4 Profile, tier and level sementics */
360     if (sps->profile_tier_level.progressive_source_flag &&
361         !sps->profile_tier_level.interlaced_source_flag) {
362       interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
363     } else {
364       interlace_mode = GST_VIDEO_INTERLACE_MODE_MIXED;
365     }
366   }
367
368   if (inner->interlace_mode != interlace_mode) {
369     GST_INFO_OBJECT (self, "Interlace mode change %d -> %d",
370         inner->interlace_mode, interlace_mode);
371     inner->interlace_mode = interlace_mode;
372     modified = TRUE;
373   }
374
375   if (inner->chroma_format_idc != sps->chroma_format_idc) {
376     GST_INFO_OBJECT (self, "chroma format changed");
377     inner->chroma_format_idc = sps->chroma_format_idc;
378     modified = TRUE;
379   }
380
381   if (modified || !gst_d3d11_decoder_is_configured (inner->d3d11_decoder)) {
382     GstVideoInfo info;
383
384     inner->out_format = GST_VIDEO_FORMAT_UNKNOWN;
385
386     if (inner->bitdepth == 8) {
387       if (inner->chroma_format_idc == 1) {
388         inner->out_format = GST_VIDEO_FORMAT_NV12;
389       } else {
390         GST_FIXME_OBJECT (self, "Could not support 8bits non-4:2:0 format");
391       }
392     } else if (inner->bitdepth == 10) {
393       if (inner->chroma_format_idc == 1) {
394         inner->out_format = GST_VIDEO_FORMAT_P010_10LE;
395       } else {
396         GST_FIXME_OBJECT (self, "Could not support 10bits non-4:2:0 format");
397       }
398     }
399
400     if (inner->out_format == GST_VIDEO_FORMAT_UNKNOWN) {
401       GST_ERROR_OBJECT (self, "Could not support bitdepth/chroma format");
402       return FALSE;
403     }
404
405     gst_video_info_set_format (&info,
406         inner->out_format, inner->width, inner->height);
407     GST_VIDEO_INFO_INTERLACE_MODE (&info) = inner->interlace_mode;
408
409     if (!gst_d3d11_decoder_configure (inner->d3d11_decoder,
410             decoder->input_state, &info,
411             inner->coded_width, inner->coded_height,
412             /* Additional 4 views margin for zero-copy rendering */
413             max_dpb_size + 4)) {
414       GST_ERROR_OBJECT (self, "Failed to create decoder");
415       return FALSE;
416     }
417
418     if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
419       GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
420       return FALSE;
421     }
422   }
423
424   return TRUE;
425 }
426
427 static gboolean
428 gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder,
429     GstVideoCodecFrame * cframe, GstH265Picture * picture)
430 {
431   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
432   GstD3D11H265DecInner *inner = self->inner;
433   GstBuffer *view_buffer;
434
435   view_buffer = gst_d3d11_decoder_get_output_view_buffer (inner->d3d11_decoder,
436       GST_VIDEO_DECODER (decoder));
437   if (!view_buffer) {
438     GST_DEBUG_OBJECT (self, "No available output view buffer");
439     return FALSE;
440   }
441
442   GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT, view_buffer);
443
444   gst_h265_picture_set_user_data (picture,
445       view_buffer, (GDestroyNotify) gst_buffer_unref);
446
447   GST_LOG_OBJECT (self, "New h265picture %p", picture);
448
449   return TRUE;
450 }
451
452 static void
453 gst_d3d11_h265_dec_picture_params_from_sps (GstD3D11H265Dec * self,
454     const GstH265SPS * sps, DXVA_PicParams_HEVC * params)
455 {
456 #define COPY_FIELD(f) \
457   (params)->f = (sps)->f
458 #define COPY_FIELD_WITH_PREFIX(f) \
459   (params)->G_PASTE(sps_,f) = (sps)->f
460
461   params->PicWidthInMinCbsY =
462       sps->width >> (sps->log2_min_luma_coding_block_size_minus3 + 3);
463   params->PicHeightInMinCbsY =
464       sps->height >> (sps->log2_min_luma_coding_block_size_minus3 + 3);
465   params->sps_max_dec_pic_buffering_minus1 =
466       sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1];
467
468   COPY_FIELD (chroma_format_idc);
469   COPY_FIELD (separate_colour_plane_flag);
470   COPY_FIELD (bit_depth_luma_minus8);
471   COPY_FIELD (bit_depth_chroma_minus8);
472   COPY_FIELD (log2_max_pic_order_cnt_lsb_minus4);
473   COPY_FIELD (log2_min_luma_coding_block_size_minus3);
474   COPY_FIELD (log2_diff_max_min_luma_coding_block_size);
475   COPY_FIELD (log2_min_transform_block_size_minus2);
476   COPY_FIELD (log2_diff_max_min_transform_block_size);
477   COPY_FIELD (max_transform_hierarchy_depth_inter);
478   COPY_FIELD (max_transform_hierarchy_depth_intra);
479   COPY_FIELD (num_short_term_ref_pic_sets);
480   COPY_FIELD (num_long_term_ref_pics_sps);
481   COPY_FIELD (scaling_list_enabled_flag);
482   COPY_FIELD (amp_enabled_flag);
483   COPY_FIELD (sample_adaptive_offset_enabled_flag);
484   COPY_FIELD (pcm_enabled_flag);
485
486   if (sps->pcm_enabled_flag) {
487     COPY_FIELD (pcm_sample_bit_depth_luma_minus1);
488     COPY_FIELD (pcm_sample_bit_depth_chroma_minus1);
489     COPY_FIELD (log2_min_pcm_luma_coding_block_size_minus3);
490     COPY_FIELD (log2_diff_max_min_pcm_luma_coding_block_size);
491   }
492
493   COPY_FIELD (pcm_loop_filter_disabled_flag);
494   COPY_FIELD (long_term_ref_pics_present_flag);
495   COPY_FIELD_WITH_PREFIX (temporal_mvp_enabled_flag);
496   COPY_FIELD (strong_intra_smoothing_enabled_flag);
497
498 #undef COPY_FIELD
499 #undef COPY_FIELD_WITH_PREFIX
500 }
501
502 static void
503 gst_d3d11_h265_dec_picture_params_from_pps (GstD3D11H265Dec * self,
504     const GstH265PPS * pps, DXVA_PicParams_HEVC * params)
505 {
506   guint i;
507
508 #define COPY_FIELD(f) \
509   (params)->f = (pps)->f
510 #define COPY_FIELD_WITH_PREFIX(f) \
511   (params)->G_PASTE(pps_,f) = (pps)->f
512
513   COPY_FIELD (num_ref_idx_l0_default_active_minus1);
514   COPY_FIELD (num_ref_idx_l1_default_active_minus1);
515   COPY_FIELD (init_qp_minus26);
516   COPY_FIELD (dependent_slice_segments_enabled_flag);
517   COPY_FIELD (output_flag_present_flag);
518   COPY_FIELD (num_extra_slice_header_bits);
519   COPY_FIELD (sign_data_hiding_enabled_flag);
520   COPY_FIELD (cabac_init_present_flag);
521   COPY_FIELD (constrained_intra_pred_flag);
522   COPY_FIELD (transform_skip_enabled_flag);
523   COPY_FIELD (cu_qp_delta_enabled_flag);
524   COPY_FIELD_WITH_PREFIX (slice_chroma_qp_offsets_present_flag);
525   COPY_FIELD (weighted_pred_flag);
526   COPY_FIELD (weighted_bipred_flag);
527   COPY_FIELD (transquant_bypass_enabled_flag);
528   COPY_FIELD (tiles_enabled_flag);
529   COPY_FIELD (entropy_coding_sync_enabled_flag);
530   COPY_FIELD (uniform_spacing_flag);
531
532   if (pps->tiles_enabled_flag)
533     COPY_FIELD (loop_filter_across_tiles_enabled_flag);
534
535   COPY_FIELD_WITH_PREFIX (loop_filter_across_slices_enabled_flag);
536   COPY_FIELD (deblocking_filter_override_enabled_flag);
537   COPY_FIELD_WITH_PREFIX (deblocking_filter_disabled_flag);
538   COPY_FIELD (lists_modification_present_flag);
539   COPY_FIELD (slice_segment_header_extension_present_flag);
540   COPY_FIELD_WITH_PREFIX (cb_qp_offset);
541   COPY_FIELD_WITH_PREFIX (cr_qp_offset);
542
543   if (pps->tiles_enabled_flag) {
544     COPY_FIELD (num_tile_columns_minus1);
545     COPY_FIELD (num_tile_rows_minus1);
546     if (!pps->uniform_spacing_flag) {
547       for (i = 0; i < pps->num_tile_columns_minus1 &&
548           i < G_N_ELEMENTS (params->column_width_minus1); i++)
549         COPY_FIELD (column_width_minus1[i]);
550
551       for (i = 0; i < pps->num_tile_rows_minus1 &&
552           i < G_N_ELEMENTS (params->row_height_minus1); i++)
553         COPY_FIELD (row_height_minus1[i]);
554     }
555   }
556
557   COPY_FIELD (diff_cu_qp_delta_depth);
558   COPY_FIELD_WITH_PREFIX (beta_offset_div2);
559   COPY_FIELD_WITH_PREFIX (tc_offset_div2);
560   COPY_FIELD (log2_parallel_merge_level_minus2);
561
562 #undef COPY_FIELD
563 #undef COPY_FIELD_WITH_PREFIX
564 }
565
566 static void
567 gst_d3d11_h265_dec_picture_params_from_slice_header (GstD3D11H265Dec *
568     self, const GstH265SliceHdr * slice_header, DXVA_PicParams_HEVC * params)
569 {
570   if (slice_header->short_term_ref_pic_set_sps_flag == 0) {
571     params->ucNumDeltaPocsOfRefRpsIdx =
572         slice_header->short_term_ref_pic_sets.NumDeltaPocsOfRefRpsIdx;
573     params->wNumBitsForShortTermRPSInSlice =
574         slice_header->short_term_ref_pic_set_size;
575   }
576 }
577
578 static gboolean
579 gst_d3d11_h265_dec_fill_picture_params (GstD3D11H265Dec * self,
580     const GstH265SliceHdr * slice_header, DXVA_PicParams_HEVC * params)
581 {
582   const GstH265SPS *sps;
583   const GstH265PPS *pps;
584
585   g_return_val_if_fail (slice_header->pps != NULL, FALSE);
586   g_return_val_if_fail (slice_header->pps->sps != NULL, FALSE);
587
588   pps = slice_header->pps;
589   sps = pps->sps;
590
591   /* not related to hevc syntax */
592   params->NoPicReorderingFlag = 0;
593   params->NoBiPredFlag = 0;
594   params->ReservedBits1 = 0;
595   params->StatusReportFeedbackNumber = 1;
596
597   gst_d3d11_h265_dec_picture_params_from_sps (self, sps, params);
598   gst_d3d11_h265_dec_picture_params_from_pps (self, pps, params);
599   gst_d3d11_h265_dec_picture_params_from_slice_header (self,
600       slice_header, params);
601
602   return TRUE;
603 }
604
605 static ID3D11VideoDecoderOutputView *
606 gst_d3d11_h265_dec_get_output_view_from_picture (GstD3D11H265Dec * self,
607     GstH265Picture * picture, guint8 * view_id)
608 {
609   GstD3D11H265DecInner *inner = self->inner;
610   GstBuffer *view_buffer;
611   ID3D11VideoDecoderOutputView *view;
612
613   view_buffer = (GstBuffer *) gst_h265_picture_get_user_data (picture);
614   if (!view_buffer) {
615     GST_DEBUG_OBJECT (self, "current picture does not have output view buffer");
616     return NULL;
617   }
618
619   view = gst_d3d11_decoder_get_output_view_from_buffer (inner->d3d11_decoder,
620       view_buffer, view_id);
621   if (!view) {
622     GST_DEBUG_OBJECT (self, "current picture does not have output view handle");
623     return NULL;
624   }
625
626   return view;
627 }
628
629 static UCHAR
630 gst_d3d11_h265_dec_get_ref_index (const DXVA_PicParams_HEVC * pic_params,
631     guint8 view_id)
632 {
633   for (UCHAR i = 0; i < G_N_ELEMENTS (pic_params->RefPicList); i++) {
634     if (pic_params->RefPicList[i].Index7Bits == view_id)
635       return i;
636   }
637
638   return 0xff;
639 }
640
641 static inline void
642 init_pic_params (DXVA_PicParams_HEVC * params)
643 {
644   memset (params, 0, sizeof (DXVA_PicParams_HEVC));
645   for (guint i = 0; i < G_N_ELEMENTS (params->RefPicList); i++)
646     params->RefPicList[i].bPicEntry = 0xff;
647
648   for (guint i = 0; i < G_N_ELEMENTS (params->RefPicSetStCurrBefore); i++) {
649     params->RefPicSetStCurrBefore[i] = 0xff;
650     params->RefPicSetStCurrAfter[i] = 0xff;
651     params->RefPicSetLtCurr[i] = 0xff;
652   }
653 }
654
655 static gboolean
656 gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
657     GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb)
658 {
659   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
660   GstD3D11H265DecInner *inner = self->inner;
661   DXVA_PicParams_HEVC *pic_params = &inner->pic_params;
662   DXVA_Qmatrix_HEVC *iq_matrix = &inner->iq_matrix;
663   ID3D11VideoDecoderOutputView *view;
664   guint8 view_id = 0xff;
665   guint i, j;
666   GArray *dpb_array;
667   GstH265SPS *sps;
668   GstH265PPS *pps;
669   GstH265ScalingList *scaling_list = nullptr;
670
671   pps = slice->header.pps;
672   sps = pps->sps;
673
674   view = gst_d3d11_h265_dec_get_output_view_from_picture (self, picture,
675       &view_id);
676   if (!view) {
677     GST_ERROR_OBJECT (self, "current picture does not have output view handle");
678     return FALSE;
679   }
680
681   init_pic_params (pic_params);
682   gst_d3d11_h265_dec_fill_picture_params (self, &slice->header, pic_params);
683
684   pic_params->CurrPic.Index7Bits = view_id;
685   pic_params->IrapPicFlag = GST_H265_IS_NAL_TYPE_IRAP (slice->nalu.type);
686   pic_params->IdrPicFlag = GST_H265_IS_NAL_TYPE_IDR (slice->nalu.type);
687   pic_params->IntraPicFlag = GST_H265_IS_NAL_TYPE_IRAP (slice->nalu.type);
688   pic_params->CurrPicOrderCntVal = picture->pic_order_cnt;
689
690   dpb_array = gst_h265_dpb_get_pictures_all (dpb);
691   for (i = 0, j = 0;
692       i < dpb_array->len && j < G_N_ELEMENTS (pic_params->RefPicList); i++) {
693     GstH265Picture *other = g_array_index (dpb_array, GstH265Picture *, i);
694     guint8 id = 0xff;
695
696     if (!other->ref) {
697       GST_LOG_OBJECT (self, "%dth picture in dpb is not reference, skip", i);
698       continue;
699     }
700
701     gst_d3d11_h265_dec_get_output_view_from_picture (self, other, &id);
702     pic_params->RefPicList[j].Index7Bits = id;
703     pic_params->RefPicList[j].AssociatedFlag = other->long_term;
704     pic_params->PicOrderCntValList[j] = other->pic_order_cnt;
705     j++;
706   }
707   g_array_unref (dpb_array);
708
709   for (i = 0, j = 0; i < G_N_ELEMENTS (pic_params->RefPicSetStCurrBefore); i++) {
710     GstH265Picture *other = nullptr;
711     guint8 other_view_id = 0xff;
712     guint8 id = 0xff;
713
714     while (!other && j < decoder->NumPocStCurrBefore)
715       other = decoder->RefPicSetStCurrBefore[j++];
716
717     if (other) {
718       ID3D11VideoDecoderOutputView *other_view;
719
720       other_view = gst_d3d11_h265_dec_get_output_view_from_picture (self,
721           other, &other_view_id);
722
723       if (other_view)
724         id = gst_d3d11_h265_dec_get_ref_index (pic_params, other_view_id);
725     }
726
727     pic_params->RefPicSetStCurrBefore[i] = id;
728   }
729
730   for (i = 0, j = 0; i < G_N_ELEMENTS (pic_params->RefPicSetStCurrAfter); i++) {
731     GstH265Picture *other = nullptr;
732     guint8 other_view_id = 0xff;
733     guint8 id = 0xff;
734
735     while (!other && j < decoder->NumPocStCurrAfter)
736       other = decoder->RefPicSetStCurrAfter[j++];
737
738     if (other) {
739       ID3D11VideoDecoderOutputView *other_view;
740
741       other_view = gst_d3d11_h265_dec_get_output_view_from_picture (self,
742           other, &other_view_id);
743
744       if (other_view)
745         id = gst_d3d11_h265_dec_get_ref_index (pic_params, other_view_id);
746     }
747
748     pic_params->RefPicSetStCurrAfter[i] = id;
749   }
750
751   for (i = 0, j = 0; i < G_N_ELEMENTS (pic_params->RefPicSetLtCurr); i++) {
752     GstH265Picture *other = nullptr;
753     guint8 other_view_id = 0xff;
754     guint8 id = 0xff;
755
756     while (!other && j < decoder->NumPocLtCurr)
757       other = decoder->RefPicSetLtCurr[j++];
758
759     if (other) {
760       ID3D11VideoDecoderOutputView *other_view;
761
762       other_view = gst_d3d11_h265_dec_get_output_view_from_picture (self,
763           other, &other_view_id);
764
765       if (other_view)
766         id = gst_d3d11_h265_dec_get_ref_index (pic_params, other_view_id);
767     }
768
769     pic_params->RefPicSetLtCurr[i] = id;
770   }
771
772   if (pps->scaling_list_data_present_flag ||
773       (sps->scaling_list_enabled_flag
774           && !sps->scaling_list_data_present_flag)) {
775     scaling_list = &pps->scaling_list;
776   } else if (sps->scaling_list_enabled_flag &&
777       sps->scaling_list_data_present_flag) {
778     scaling_list = &sps->scaling_list;
779   }
780
781   if (scaling_list) {
782     G_STATIC_ASSERT (sizeof (iq_matrix->ucScalingLists0) ==
783         sizeof (scaling_list->scaling_lists_4x4));
784     G_STATIC_ASSERT (sizeof (iq_matrix->ucScalingLists1) ==
785         sizeof (scaling_list->scaling_lists_8x8));
786     G_STATIC_ASSERT (sizeof (iq_matrix->ucScalingLists2) ==
787         sizeof (scaling_list->scaling_lists_16x16));
788     G_STATIC_ASSERT (sizeof (iq_matrix->ucScalingLists3) ==
789         sizeof (scaling_list->scaling_lists_32x32));
790
791     memcpy (iq_matrix->ucScalingLists0, scaling_list->scaling_lists_4x4,
792         sizeof (iq_matrix->ucScalingLists0));
793     memcpy (iq_matrix->ucScalingLists1, scaling_list->scaling_lists_8x8,
794         sizeof (iq_matrix->ucScalingLists1));
795     memcpy (iq_matrix->ucScalingLists2, scaling_list->scaling_lists_16x16,
796         sizeof (iq_matrix->ucScalingLists2));
797     memcpy (iq_matrix->ucScalingLists3, scaling_list->scaling_lists_32x32,
798         sizeof (iq_matrix->ucScalingLists3));
799
800     for (i = 0; i < G_N_ELEMENTS (iq_matrix->ucScalingListDCCoefSizeID2); i++) {
801       iq_matrix->ucScalingListDCCoefSizeID2[i] =
802           scaling_list->scaling_list_dc_coef_minus8_16x16[i] + 8;
803     }
804
805     for (i = 0; i < G_N_ELEMENTS (iq_matrix->ucScalingListDCCoefSizeID3); i++) {
806       iq_matrix->ucScalingListDCCoefSizeID3[i] =
807           scaling_list->scaling_list_dc_coef_minus8_32x32[i] + 8;
808     }
809
810     inner->submit_iq_data = TRUE;
811   } else {
812     inner->submit_iq_data = FALSE;
813   }
814
815   inner->slice_list.resize (0);
816   inner->bitstream_buffer.resize (0);
817
818   return TRUE;
819 }
820
821 static gboolean
822 gst_d3d11_h265_dec_decode_slice (GstH265Decoder * decoder,
823     GstH265Picture * picture, GstH265Slice * slice,
824     GArray * ref_pic_list0, GArray * ref_pic_list1)
825 {
826   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
827   GstD3D11H265DecInner *inner = self->inner;
828   DXVA_Slice_HEVC_Short dxva_slice;
829   static const guint8 start_code[] = { 0, 0, 1 };
830   const size_t start_code_size = sizeof (start_code);
831
832   dxva_slice.BSNALunitDataLocation = inner->bitstream_buffer.size ();
833   /* Includes 3 bytes start code prefix */
834   dxva_slice.SliceBytesInBuffer = slice->nalu.size + start_code_size;
835   dxva_slice.wBadSliceChopping = 0;
836
837   inner->slice_list.push_back (dxva_slice);
838
839   size_t pos = inner->bitstream_buffer.size ();
840   inner->bitstream_buffer.resize (pos + start_code_size + slice->nalu.size);
841
842   /* Fill start code prefix */
843   memcpy (&inner->bitstream_buffer[0] + pos, start_code, start_code_size);
844
845   /* Copy bitstream */
846   memcpy (&inner->bitstream_buffer[0] + pos + start_code_size,
847       slice->nalu.data + slice->nalu.offset, slice->nalu.size);
848
849   return TRUE;
850 }
851
852 static gboolean
853 gst_d3d11_h265_dec_end_picture (GstH265Decoder * decoder,
854     GstH265Picture * picture)
855 {
856   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
857   GstD3D11H265DecInner *inner = self->inner;
858   ID3D11VideoDecoderOutputView *view;
859   guint8 view_id = 0xff;
860   size_t bitstream_buffer_size;
861   size_t bitstream_pos;
862   GstD3D11DecodeInputStreamArgs input_args;
863
864   GST_LOG_OBJECT (self, "end picture %p, (poc %d)",
865       picture, picture->pic_order_cnt);
866
867   if (inner->bitstream_buffer.empty () || inner->slice_list.empty ()) {
868     GST_ERROR_OBJECT (self, "No bitstream buffer to submit");
869     return FALSE;
870   }
871
872   view = gst_d3d11_h265_dec_get_output_view_from_picture (self, picture,
873       &view_id);
874   if (!view) {
875     GST_ERROR_OBJECT (self, "current picture does not have output view handle");
876     return FALSE;
877   }
878
879   memset (&input_args, 0, sizeof (GstD3D11DecodeInputStreamArgs));
880
881   bitstream_pos = inner->bitstream_buffer.size ();
882   bitstream_buffer_size = GST_ROUND_UP_128 (bitstream_pos);
883
884   if (bitstream_buffer_size > bitstream_pos) {
885     size_t padding = bitstream_buffer_size - bitstream_pos;
886
887     /* As per DXVA spec, total amount of bitstream buffer size should be
888      * 128 bytes aligned. If actual data is not multiple of 128 bytes,
889      * the last slice data needs to be zero-padded */
890     inner->bitstream_buffer.resize (bitstream_buffer_size, 0);
891
892     DXVA_Slice_HEVC_Short & slice = inner->slice_list.back ();
893     slice.SliceBytesInBuffer += padding;
894   }
895
896   input_args.picture_params = &inner->pic_params;
897   input_args.picture_params_size = sizeof (DXVA_PicParams_HEVC);
898   input_args.slice_control = &inner->slice_list[0];
899   input_args.slice_control_size =
900       sizeof (DXVA_Slice_HEVC_Short) * inner->slice_list.size ();
901   input_args.bitstream = &inner->bitstream_buffer[0];
902   input_args.bitstream_size = inner->bitstream_buffer.size ();
903
904   if (inner->submit_iq_data) {
905     input_args.inverse_quantization_matrix = &inner->iq_matrix;
906     input_args.inverse_quantization_matrix_size = sizeof (DXVA_Qmatrix_HEVC);
907   }
908
909   return gst_d3d11_decoder_decode_frame (inner->d3d11_decoder,
910       view, &input_args);
911 }
912
913 static GstFlowReturn
914 gst_d3d11_h265_dec_output_picture (GstH265Decoder * decoder,
915     GstVideoCodecFrame * frame, GstH265Picture * picture)
916 {
917   GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
918   GstD3D11H265DecInner *inner = self->inner;
919   GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
920   GstBuffer *view_buffer;
921
922   GST_LOG_OBJECT (self, "Outputting picture %p, poc %d, picture_struct %d, "
923       "buffer flags 0x%x", picture, picture->pic_order_cnt, picture->pic_struct,
924       picture->buffer_flags);
925
926   view_buffer = (GstBuffer *) gst_h265_picture_get_user_data (picture);
927
928   if (!view_buffer) {
929     GST_ERROR_OBJECT (self, "Could not get output view");
930     goto error;
931   }
932
933   if (!gst_d3d11_decoder_process_output (inner->d3d11_decoder, vdec,
934           inner->width, inner->height, view_buffer, &frame->output_buffer)) {
935     GST_ERROR_OBJECT (self, "Failed to copy buffer");
936     goto error;
937   }
938
939   GST_BUFFER_FLAG_SET (frame->output_buffer, picture->buffer_flags);
940   gst_h265_picture_unref (picture);
941
942   return gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
943
944 error:
945   gst_h265_picture_unref (picture);
946   gst_video_decoder_release_frame (vdec, frame);
947
948   return GST_FLOW_ERROR;
949 }
950
951 void
952 gst_d3d11_h265_dec_register (GstPlugin * plugin, GstD3D11Device * device,
953     guint rank)
954 {
955   GType type;
956   gchar *type_name;
957   gchar *feature_name;
958   guint index = 0;
959   guint i;
960   const GUID *profile = NULL;
961   GTypeInfo type_info = {
962     sizeof (GstD3D11H265DecClass),
963     NULL,
964     NULL,
965     (GClassInitFunc) gst_d3d11_h265_dec_class_init,
966     NULL,
967     NULL,
968     sizeof (GstD3D11H265Dec),
969     0,
970     (GInstanceInitFunc) gst_d3d11_h265_dec_init,
971   };
972   const GUID *main_10_guid = NULL;
973   const GUID *main_guid = NULL;
974   GstCaps *sink_caps = NULL;
975   GstCaps *src_caps = NULL;
976   GstCaps *src_caps_copy;
977   GstCaps *tmp;
978   GstCapsFeatures *caps_features;
979   guint max_width = 0;
980   guint max_height = 0;
981   guint resolution;
982   gboolean have_main10 = FALSE;
983   gboolean have_main = FALSE;
984   DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
985
986   have_main10 = gst_d3d11_decoder_get_supported_decoder_profile (device,
987       GST_DXVA_CODEC_H265, GST_VIDEO_FORMAT_P010_10LE, &main_10_guid);
988   if (!have_main10) {
989     GST_DEBUG_OBJECT (device, "decoder does not support HEVC_VLD_MAIN10");
990   } else {
991     have_main10 &=
992         gst_d3d11_decoder_supports_format (device, main_10_guid,
993         DXGI_FORMAT_P010);
994     if (!have_main10) {
995       GST_FIXME_OBJECT (device, "device does not support P010 format");
996     }
997   }
998
999   have_main = gst_d3d11_decoder_get_supported_decoder_profile (device,
1000       GST_DXVA_CODEC_H265, GST_VIDEO_FORMAT_NV12, &main_guid);
1001   if (!have_main) {
1002     GST_DEBUG_OBJECT (device, "decoder does not support HEVC_VLD_MAIN");
1003   } else {
1004     have_main =
1005         gst_d3d11_decoder_supports_format (device, main_guid, DXGI_FORMAT_NV12);
1006     if (!have_main) {
1007       GST_FIXME_OBJECT (device, "device does not support NV12 format");
1008     }
1009   }
1010
1011   if (!have_main10 && !have_main) {
1012     GST_INFO_OBJECT (device, "device does not support h.265 decoding");
1013     return;
1014   }
1015
1016   if (have_main) {
1017     profile = main_guid;
1018     format = DXGI_FORMAT_NV12;
1019   } else {
1020     profile = main_10_guid;
1021     format = DXGI_FORMAT_P010;
1022   }
1023
1024   for (i = 0; i < G_N_ELEMENTS (gst_dxva_resolutions); i++) {
1025     if (gst_d3d11_decoder_supports_resolution (device, profile,
1026             format, gst_dxva_resolutions[i].width,
1027             gst_dxva_resolutions[i].height)) {
1028       max_width = gst_dxva_resolutions[i].width;
1029       max_height = gst_dxva_resolutions[i].height;
1030
1031       GST_DEBUG_OBJECT (device,
1032           "device support resolution %dx%d", max_width, max_height);
1033     } else {
1034       break;
1035     }
1036   }
1037
1038   if (max_width == 0 || max_height == 0) {
1039     GST_WARNING_OBJECT (device, "Couldn't query supported resolution");
1040     return;
1041   }
1042
1043   sink_caps = gst_caps_from_string ("video/x-h265, "
1044       "stream-format=(string) { hev1, hvc1, byte-stream }, "
1045       "alignment= (string) au");
1046   src_caps = gst_caps_new_empty_simple ("video/x-raw");
1047
1048   if (have_main10) {
1049     /* main10 profile covers main and main10 */
1050     GValue profile_list = G_VALUE_INIT;
1051     GValue profile_value = G_VALUE_INIT;
1052     GValue format_list = G_VALUE_INIT;
1053     GValue format_value = G_VALUE_INIT;
1054
1055     g_value_init (&profile_list, GST_TYPE_LIST);
1056
1057     g_value_init (&profile_value, G_TYPE_STRING);
1058     g_value_set_string (&profile_value, "main");
1059     gst_value_list_append_and_take_value (&profile_list, &profile_value);
1060
1061     g_value_init (&profile_value, G_TYPE_STRING);
1062     g_value_set_string (&profile_value, "main-10");
1063     gst_value_list_append_and_take_value (&profile_list, &profile_value);
1064
1065
1066     g_value_init (&format_list, GST_TYPE_LIST);
1067
1068     g_value_init (&format_value, G_TYPE_STRING);
1069     g_value_set_string (&format_value, "NV12");
1070     gst_value_list_append_and_take_value (&format_list, &format_value);
1071
1072     g_value_init (&format_value, G_TYPE_STRING);
1073     g_value_set_string (&format_value, "P010_10LE");
1074     gst_value_list_append_and_take_value (&format_list, &format_value);
1075
1076     gst_caps_set_value (sink_caps, "profile", &profile_list);
1077     gst_caps_set_value (src_caps, "format", &format_list);
1078     g_value_unset (&profile_list);
1079     g_value_unset (&format_list);
1080   } else {
1081     gst_caps_set_simple (sink_caps, "profile", G_TYPE_STRING, "main", NULL);
1082     gst_caps_set_simple (src_caps, "format", G_TYPE_STRING, "NV12", NULL);
1083   }
1084
1085   /* To cover both landscape and portrait, select max value */
1086   resolution = MAX (max_width, max_height);
1087   gst_caps_set_simple (sink_caps,
1088       "width", GST_TYPE_INT_RANGE, 1, resolution,
1089       "height", GST_TYPE_INT_RANGE, 1, resolution, NULL);
1090   gst_caps_set_simple (src_caps,
1091       "width", GST_TYPE_INT_RANGE, 1, resolution,
1092       "height", GST_TYPE_INT_RANGE, 1, resolution, NULL);
1093
1094   /* Copy src caps to append other capsfeatures */
1095   src_caps_copy = gst_caps_copy (src_caps);
1096
1097   /* System memory with alternate interlace-mode */
1098   tmp = gst_caps_copy (src_caps_copy);
1099   caps_features = gst_caps_features_new (GST_CAPS_FEATURE_FORMAT_INTERLACED,
1100       NULL);
1101   gst_caps_set_features_simple (tmp, caps_features);
1102   gst_caps_set_simple (tmp, "interlace-mode", G_TYPE_STRING, "alternate", NULL);
1103   gst_caps_append (src_caps, tmp);
1104
1105   /* D3D11 memory feature */
1106   tmp = gst_caps_copy (src_caps_copy);
1107   caps_features = gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY,
1108       NULL);
1109   gst_caps_set_features_simple (tmp, caps_features);
1110   gst_caps_append (src_caps, tmp);
1111
1112   /* FIXME: D3D11 deinterlace element is not prepared, so this D3D11 with
1113    * interlaced caps feature is pointless at the moment */
1114 #if 0
1115   /* D3D11 memory with alternate interlace-mode */
1116   tmp = gst_caps_copy (src_caps_copy);
1117   caps_features = gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY,
1118       GST_CAPS_FEATURE_FORMAT_INTERLACED, NULL);
1119   gst_caps_set_features_simple (tmp, caps_features);
1120   gst_caps_set_simple (tmp, "interlace-mode", G_TYPE_STRING, "alternate", NULL);
1121   gst_caps_append (src_caps, tmp);
1122 #endif
1123
1124   gst_caps_unref (src_caps_copy);
1125
1126   type_info.class_data =
1127       gst_d3d11_decoder_class_data_new (device, GST_DXVA_CODEC_H265,
1128       sink_caps, src_caps);
1129
1130   type_name = g_strdup ("GstD3D11H265Dec");
1131   feature_name = g_strdup ("d3d11h265dec");
1132
1133   while (g_type_from_name (type_name)) {
1134     index++;
1135     g_free (type_name);
1136     g_free (feature_name);
1137     type_name = g_strdup_printf ("GstD3D11H265Device%dDec", index);
1138     feature_name = g_strdup_printf ("d3d11h265device%ddec", index);
1139   }
1140
1141   type = g_type_register_static (GST_TYPE_H265_DECODER,
1142       type_name, &type_info, (GTypeFlags) 0);
1143
1144   /* make lower rank than default device */
1145   if (rank > 0 && index != 0)
1146     rank--;
1147
1148   if (!gst_element_register (plugin, feature_name, rank, type))
1149     GST_WARNING ("Failed to register plugin '%s'", type_name);
1150
1151   g_free (type_name);
1152   g_free (feature_name);
1153 }