• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2017 Ericsson AB. All rights reserved.
3  * Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
4  * Copyright (C) 2020 Seungha Yang <seungha@centricular.com>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer
14  *    in the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * This library is free software; you can redistribute it and/or
30  * modify it under the terms of the GNU Library General Public
31  * License as published by the Free Software Foundation; either
32  * version 2 of the License, or (at your option) any later version.
33  *
34  * This library is distributed in the hope that it will be useful,
35  * but WITHOUT ANY WARRANTY; without even the implied warranty of
36  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
37  * Library General Public License for more details.
38  *
39  * You should have received a copy of the GNU Library General Public
40  * License along with this library; if not, write to the
41  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
42  * Boston, MA 02110-1301, USA.
43  *
44  * Copyright 2015 The Chromium Authors. All rights reserved.
45  *
46  * Redistribution and use in source and binary forms, with or without
47  * modification, are permitted provided that the following conditions are
48  * met:
49  *
50  *    * Redistributions of source code must retain the above copyright
51  * notice, this list of conditions and the following disclaimer.
52  *    * Redistributions in binary form must reproduce the above
53  * copyright notice, this list of conditions and the following disclaimer
54  * in the documentation and/or other materials provided with the
55  * distribution.
56  *    * Neither the name of Google Inc. nor the names of its
57  * contributors may be used to endorse or promote products derived from
58  * this software without specific prior written permission.
59  *
60  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
61  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
62  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
63  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
64  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
65  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
66  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
67  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
68  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
70  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71  */
72 
73 #ifdef HAVE_CONFIG_H
74 #include "config.h"
75 #endif
76 
77 #include "gstnvh264dec.h"
78 #include "gstcudautils.h"
79 #include "gstnvdecoder.h"
80 
81 #include <string.h>
82 
83 GST_DEBUG_CATEGORY_STATIC (gst_nv_h264_dec_debug);
84 #define GST_CAT_DEFAULT gst_nv_h264_dec_debug
85 
86 struct _GstNvH264Dec
87 {
88   GstH264Decoder parent;
89 
90   GstVideoCodecState *output_state;
91 
92   GstCudaContext *context;
93   GstNvDecoder *decoder;
94   CUVIDPICPARAMS params;
95 
96   /* slice buffer which will be passed to CUVIDPICPARAMS::pBitstreamData */
97   guint8 *bitstream_buffer;
98   /* allocated memory size of bitstream_buffer */
99   gsize bitstream_buffer_alloc_size;
100   /* current offset of bitstream_buffer (per frame) */
101   gsize bitstream_buffer_offset;
102 
103   guint *slice_offsets;
104   guint slice_offsets_alloc_len;
105   guint num_slices;
106 
107   guint width, height;
108   guint coded_width, coded_height;
109   guint bitdepth;
110   guint chroma_format_idc;
111   gint max_dpb_size;
112 
113   gboolean interlaced;
114 
115   GArray *ref_list;
116 };
117 
118 struct _GstNvH264DecClass
119 {
120   GstH264DecoderClass parent_class;
121   guint cuda_device_id;
122 };
123 
124 #define gst_nv_h264_dec_parent_class parent_class
125 G_DEFINE_TYPE (GstNvH264Dec, gst_nv_h264_dec, GST_TYPE_H264_DECODER);
126 
127 static void gst_nv_h264_decoder_dispose (GObject * object);
128 static void gst_nv_h264_dec_set_context (GstElement * element,
129     GstContext * context);
130 static gboolean gst_nv_h264_dec_open (GstVideoDecoder * decoder);
131 static gboolean gst_nv_h264_dec_close (GstVideoDecoder * decoder);
132 static gboolean gst_nv_h264_dec_negotiate (GstVideoDecoder * decoder);
133 static gboolean gst_nv_h264_dec_decide_allocation (GstVideoDecoder *
134     decoder, GstQuery * query);
135 static gboolean gst_nv_h264_dec_src_query (GstVideoDecoder * decoder,
136     GstQuery * query);
137 
138 /* GstH264Decoder */
139 static GstFlowReturn gst_nv_h264_dec_new_sequence (GstH264Decoder * decoder,
140     const GstH264SPS * sps, gint max_dpb_size);
141 static GstFlowReturn gst_nv_h264_dec_new_picture (GstH264Decoder * decoder,
142     GstVideoCodecFrame * frame, GstH264Picture * picture);
143 static GstFlowReturn gst_nv_h264_dec_new_field_picture (GstH264Decoder *
144     decoder, const GstH264Picture * first_field, GstH264Picture * second_field);
145 static GstFlowReturn gst_nv_h264_dec_output_picture (GstH264Decoder *
146     decoder, GstVideoCodecFrame * frame, GstH264Picture * picture);
147 static GstFlowReturn gst_nv_h264_dec_start_picture (GstH264Decoder * decoder,
148     GstH264Picture * picture, GstH264Slice * slice, GstH264Dpb * dpb);
149 static GstFlowReturn gst_nv_h264_dec_decode_slice (GstH264Decoder * decoder,
150     GstH264Picture * picture, GstH264Slice * slice, GArray * ref_pic_list0,
151     GArray * ref_pic_list1);
152 static GstFlowReturn gst_nv_h264_dec_end_picture (GstH264Decoder * decoder,
153     GstH264Picture * picture);
154 static guint
155 gst_nv_h264_dec_get_preferred_output_delay (GstH264Decoder * decoder,
156     gboolean live);
157 
158 static void
gst_nv_h264_dec_class_init(GstNvH264DecClass * klass)159 gst_nv_h264_dec_class_init (GstNvH264DecClass * klass)
160 {
161   GObjectClass *object_class = G_OBJECT_CLASS (klass);
162   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
163   GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
164   GstH264DecoderClass *h264decoder_class = GST_H264_DECODER_CLASS (klass);
165 
166   /**
167    * GstNvH264Dec
168    *
169    * Since: 1.18
170    */
171 
172   object_class->dispose = gst_nv_h264_decoder_dispose;
173 
174   element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_set_context);
175 
176   decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_open);
177   decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_close);
178   decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_negotiate);
179   decoder_class->decide_allocation =
180       GST_DEBUG_FUNCPTR (gst_nv_h264_dec_decide_allocation);
181   decoder_class->src_query = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_src_query);
182 
183   h264decoder_class->new_sequence =
184       GST_DEBUG_FUNCPTR (gst_nv_h264_dec_new_sequence);
185   h264decoder_class->new_picture =
186       GST_DEBUG_FUNCPTR (gst_nv_h264_dec_new_picture);
187   h264decoder_class->new_field_picture =
188       GST_DEBUG_FUNCPTR (gst_nv_h264_dec_new_field_picture);
189   h264decoder_class->output_picture =
190       GST_DEBUG_FUNCPTR (gst_nv_h264_dec_output_picture);
191   h264decoder_class->start_picture =
192       GST_DEBUG_FUNCPTR (gst_nv_h264_dec_start_picture);
193   h264decoder_class->decode_slice =
194       GST_DEBUG_FUNCPTR (gst_nv_h264_dec_decode_slice);
195   h264decoder_class->end_picture =
196       GST_DEBUG_FUNCPTR (gst_nv_h264_dec_end_picture);
197   h264decoder_class->get_preferred_output_delay =
198       GST_DEBUG_FUNCPTR (gst_nv_h264_dec_get_preferred_output_delay);
199 
200   GST_DEBUG_CATEGORY_INIT (gst_nv_h264_dec_debug,
201       "nvh264dec", 0, "Nvidia H.264 Decoder");
202 
203   gst_type_mark_as_plugin_api (GST_TYPE_NV_H264_DEC, 0);
204 }
205 
206 static void
gst_nv_h264_dec_init(GstNvH264Dec * self)207 gst_nv_h264_dec_init (GstNvH264Dec * self)
208 {
209   self->ref_list = g_array_sized_new (FALSE, TRUE,
210       sizeof (GstH264Picture *), 16);
211   g_array_set_clear_func (self->ref_list,
212       (GDestroyNotify) gst_h264_picture_clear);
213 }
214 
215 static void
gst_nv_h264_decoder_dispose(GObject * object)216 gst_nv_h264_decoder_dispose (GObject * object)
217 {
218   GstNvH264Dec *self = GST_NV_H264_DEC (object);
219 
220   g_clear_pointer (&self->ref_list, g_array_unref);
221 
222   G_OBJECT_CLASS (parent_class)->dispose (object);
223 }
224 
225 static void
gst_nv_h264_dec_set_context(GstElement * element,GstContext * context)226 gst_nv_h264_dec_set_context (GstElement * element, GstContext * context)
227 {
228   GstNvH264Dec *self = GST_NV_H264_DEC (element);
229   GstNvH264DecClass *klass = GST_NV_H264_DEC_GET_CLASS (self);
230 
231   GST_DEBUG_OBJECT (self, "set context %s",
232       gst_context_get_context_type (context));
233 
234   if (gst_cuda_handle_set_context (element, context, klass->cuda_device_id,
235           &self->context)) {
236     goto done;
237   }
238 
239   if (self->decoder)
240     gst_nv_decoder_handle_set_context (self->decoder, element, context);
241 
242 done:
243   GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
244 }
245 
246 /* Clear all codec specific (e.g., SPS) data */
247 static void
gst_d3d11_h264_dec_reset(GstNvH264Dec * self)248 gst_d3d11_h264_dec_reset (GstNvH264Dec * self)
249 {
250   self->width = 0;
251   self->height = 0;
252   self->coded_width = 0;
253   self->coded_height = 0;
254   self->bitdepth = 0;
255   self->chroma_format_idc = 0;
256   self->max_dpb_size = 0;
257   self->interlaced = FALSE;
258 }
259 
260 static gboolean
gst_nv_h264_dec_open(GstVideoDecoder * decoder)261 gst_nv_h264_dec_open (GstVideoDecoder * decoder)
262 {
263   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
264   GstNvH264DecClass *klass = GST_NV_H264_DEC_GET_CLASS (self);
265 
266   if (!gst_cuda_ensure_element_context (GST_ELEMENT (self),
267           klass->cuda_device_id, &self->context)) {
268     GST_ERROR_OBJECT (self, "Required element data is unavailable");
269     return FALSE;
270   }
271 
272   self->decoder = gst_nv_decoder_new (self->context);
273   if (!self->decoder) {
274     GST_ERROR_OBJECT (self, "Failed to create decoder object");
275     gst_clear_object (&self->context);
276 
277     return FALSE;
278   }
279 
280   gst_d3d11_h264_dec_reset (self);
281 
282   return TRUE;
283 }
284 
285 static gboolean
gst_nv_h264_dec_close(GstVideoDecoder * decoder)286 gst_nv_h264_dec_close (GstVideoDecoder * decoder)
287 {
288   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
289 
290   g_clear_pointer (&self->output_state, gst_video_codec_state_unref);
291   gst_clear_object (&self->decoder);
292   gst_clear_object (&self->context);
293 
294   g_clear_pointer (&self->bitstream_buffer, g_free);
295   g_clear_pointer (&self->slice_offsets, g_free);
296 
297   self->bitstream_buffer_alloc_size = 0;
298   self->slice_offsets_alloc_len = 0;
299 
300   return TRUE;
301 }
302 
303 static gboolean
gst_nv_h264_dec_negotiate(GstVideoDecoder * decoder)304 gst_nv_h264_dec_negotiate (GstVideoDecoder * decoder)
305 {
306   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
307   GstH264Decoder *h264dec = GST_H264_DECODER (decoder);
308 
309   GST_DEBUG_OBJECT (self, "negotiate");
310 
311   gst_nv_decoder_negotiate (self->decoder, decoder, h264dec->input_state,
312       &self->output_state);
313 
314   /* TODO: add support D3D11 memory */
315 
316   return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
317 }
318 
319 static gboolean
gst_nv_h264_dec_decide_allocation(GstVideoDecoder * decoder,GstQuery * query)320 gst_nv_h264_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
321 {
322   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
323 
324   if (!gst_nv_decoder_decide_allocation (self->decoder, decoder, query)) {
325     GST_WARNING_OBJECT (self, "Failed to handle decide allocation");
326     return FALSE;
327   }
328 
329   return GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation
330       (decoder, query);
331 }
332 
333 static gboolean
gst_nv_h264_dec_src_query(GstVideoDecoder * decoder,GstQuery * query)334 gst_nv_h264_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
335 {
336   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
337 
338   switch (GST_QUERY_TYPE (query)) {
339     case GST_QUERY_CONTEXT:
340       if (gst_cuda_handle_context_query (GST_ELEMENT (decoder), query,
341               self->context)) {
342         return TRUE;
343       } else if (self->decoder &&
344           gst_nv_decoder_handle_context_query (self->decoder, decoder, query)) {
345         return TRUE;
346       }
347       break;
348     default:
349       break;
350   }
351 
352   return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (decoder, query);
353 }
354 
355 static GstFlowReturn
gst_nv_h264_dec_new_sequence(GstH264Decoder * decoder,const GstH264SPS * sps,gint max_dpb_size)356 gst_nv_h264_dec_new_sequence (GstH264Decoder * decoder, const GstH264SPS * sps,
357     gint max_dpb_size)
358 {
359   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
360   gint crop_width, crop_height;
361   gboolean modified = FALSE;
362   gboolean interlaced;
363 
364   GST_LOG_OBJECT (self, "new sequence");
365 
366   if (sps->frame_cropping_flag) {
367     crop_width = sps->crop_rect_width;
368     crop_height = sps->crop_rect_height;
369   } else {
370     crop_width = sps->width;
371     crop_height = sps->height;
372   }
373 
374   if (self->width != crop_width || self->height != crop_height ||
375       self->coded_width != sps->width || self->coded_height != sps->height) {
376     GST_INFO_OBJECT (self, "resolution changed %dx%d (%dx%d)",
377         crop_width, crop_height, sps->width, sps->height);
378     self->width = crop_width;
379     self->height = crop_height;
380     self->coded_width = sps->width;
381     self->coded_height = sps->height;
382     modified = TRUE;
383   }
384 
385   if (self->bitdepth != sps->bit_depth_luma_minus8 + 8) {
386     GST_INFO_OBJECT (self, "bitdepth changed");
387     self->bitdepth = sps->bit_depth_luma_minus8 + 8;
388     modified = TRUE;
389   }
390 
391   if (self->chroma_format_idc != sps->chroma_format_idc) {
392     GST_INFO_OBJECT (self, "chroma format changed");
393     self->chroma_format_idc = sps->chroma_format_idc;
394     modified = TRUE;
395   }
396 
397   interlaced = !sps->frame_mbs_only_flag;
398   if (self->interlaced != interlaced) {
399     GST_INFO_OBJECT (self, "interlaced sequence changed");
400     self->interlaced = interlaced;
401     modified = TRUE;
402   }
403 
404   if (self->max_dpb_size < max_dpb_size) {
405     GST_INFO_OBJECT (self, "Requires larger DPB size (%d -> %d)",
406         self->max_dpb_size, max_dpb_size);
407     modified = TRUE;
408   }
409 
410   if (modified || !gst_nv_decoder_is_configured (self->decoder)) {
411     GstVideoInfo info;
412     GstVideoFormat out_format = GST_VIDEO_FORMAT_UNKNOWN;
413 
414     if (self->bitdepth == 8) {
415       if (self->chroma_format_idc == 1)
416         out_format = GST_VIDEO_FORMAT_NV12;
417       else {
418         GST_FIXME_OBJECT (self, "Could not support 8bits non-4:2:0 format");
419       }
420     } else if (self->bitdepth == 10) {
421       if (self->chroma_format_idc == 1)
422         out_format = GST_VIDEO_FORMAT_P010_10LE;
423       else {
424         GST_FIXME_OBJECT (self, "Could not support 10bits non-4:2:0 format");
425       }
426     }
427 
428     if (out_format == GST_VIDEO_FORMAT_UNKNOWN) {
429       GST_ERROR_OBJECT (self, "Could not support bitdepth/chroma format");
430       return GST_FLOW_NOT_NEGOTIATED;
431     }
432 
433     gst_video_info_set_format (&info, out_format, self->width, self->height);
434     if (self->interlaced)
435       GST_VIDEO_INFO_INTERLACE_MODE (&info) = GST_VIDEO_INTERLACE_MODE_MIXED;
436 
437     self->max_dpb_size = max_dpb_size;
438     /* FIXME: add support cudaVideoCodec_H264_SVC and cudaVideoCodec_H264_MVC */
439     if (!gst_nv_decoder_configure (self->decoder,
440             cudaVideoCodec_H264, &info, self->coded_width, self->coded_height,
441             self->bitdepth,
442             /* Additional 4 buffers for render delay */
443             max_dpb_size + 4)) {
444       GST_ERROR_OBJECT (self, "Failed to configure decoder");
445       return GST_FLOW_NOT_NEGOTIATED;
446     }
447 
448     if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
449       GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
450       return GST_FLOW_NOT_NEGOTIATED;
451     }
452 
453     memset (&self->params, 0, sizeof (CUVIDPICPARAMS));
454   }
455 
456   return GST_FLOW_OK;
457 }
458 
459 static GstFlowReturn
gst_nv_h264_dec_new_picture(GstH264Decoder * decoder,GstVideoCodecFrame * frame,GstH264Picture * picture)460 gst_nv_h264_dec_new_picture (GstH264Decoder * decoder,
461     GstVideoCodecFrame * frame, GstH264Picture * picture)
462 {
463   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
464   GstNvDecoderFrame *nv_frame;
465 
466   nv_frame = gst_nv_decoder_new_frame (self->decoder);
467   if (!nv_frame) {
468     GST_ERROR_OBJECT (self, "No available decoder frame");
469     return GST_FLOW_ERROR;
470   }
471 
472   GST_LOG_OBJECT (self,
473       "New decoder frame %p (index %d)", nv_frame, nv_frame->index);
474 
475   gst_h264_picture_set_user_data (picture,
476       nv_frame, (GDestroyNotify) gst_nv_decoder_frame_unref);
477 
478   return GST_FLOW_OK;
479 }
480 
481 static GstFlowReturn
gst_nv_h264_dec_new_field_picture(GstH264Decoder * decoder,const GstH264Picture * first_field,GstH264Picture * second_field)482 gst_nv_h264_dec_new_field_picture (GstH264Decoder * decoder,
483     const GstH264Picture * first_field, GstH264Picture * second_field)
484 {
485   GstNvDecoderFrame *nv_frame;
486 
487   nv_frame = (GstNvDecoderFrame *)
488       gst_h264_picture_get_user_data ((GstH264Picture *) first_field);
489   if (!nv_frame) {
490     GST_ERROR_OBJECT (decoder,
491         "No decoder frame in the first picture %p", first_field);
492     return GST_FLOW_ERROR;
493   }
494 
495   gst_h264_picture_set_user_data (second_field,
496       gst_nv_decoder_frame_ref (nv_frame),
497       (GDestroyNotify) gst_nv_decoder_frame_unref);
498 
499   return GST_FLOW_OK;
500 }
501 
502 static GstFlowReturn
gst_nv_h264_dec_output_picture(GstH264Decoder * decoder,GstVideoCodecFrame * frame,GstH264Picture * picture)503 gst_nv_h264_dec_output_picture (GstH264Decoder * decoder,
504     GstVideoCodecFrame * frame, GstH264Picture * picture)
505 {
506   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
507   GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
508   GstNvDecoderFrame *decoder_frame;
509 
510   GST_LOG_OBJECT (self,
511       "Outputting picture %p (poc %d)", picture, picture->pic_order_cnt);
512 
513   decoder_frame =
514       (GstNvDecoderFrame *) gst_h264_picture_get_user_data (picture);
515   if (!decoder_frame) {
516     GST_ERROR_OBJECT (self, "No decoder frame in picture %p", picture);
517     goto error;
518   }
519 
520   if (!gst_nv_decoder_finish_frame (self->decoder, vdec, decoder_frame,
521           &frame->output_buffer)) {
522     GST_ERROR_OBJECT (self, "Failed to handle output picture");
523     goto error;
524   }
525 
526   if (picture->buffer_flags != 0) {
527     gboolean interlaced =
528         (picture->buffer_flags & GST_VIDEO_BUFFER_FLAG_INTERLACED) != 0;
529     gboolean tff = (picture->buffer_flags & GST_VIDEO_BUFFER_FLAG_TFF) != 0;
530 
531     GST_TRACE_OBJECT (self,
532         "apply buffer flags 0x%x (interlaced %d, top-field-first %d)",
533         picture->buffer_flags, interlaced, tff);
534     GST_BUFFER_FLAG_SET (frame->output_buffer, picture->buffer_flags);
535   }
536 
537   gst_h264_picture_unref (picture);
538 
539   return gst_video_decoder_finish_frame (vdec, frame);
540 
541 error:
542   gst_h264_picture_unref (picture);
543   gst_video_decoder_release_frame (vdec, frame);
544 
545   return GST_FLOW_ERROR;
546 }
547 
548 static GstNvDecoderFrame *
gst_nv_h264_dec_get_decoder_frame_from_picture(GstNvH264Dec * self,GstH264Picture * picture)549 gst_nv_h264_dec_get_decoder_frame_from_picture (GstNvH264Dec * self,
550     GstH264Picture * picture)
551 {
552   GstNvDecoderFrame *frame;
553 
554   frame = (GstNvDecoderFrame *) gst_h264_picture_get_user_data (picture);
555 
556   if (!frame)
557     GST_DEBUG_OBJECT (self, "current picture does not have decoder frame");
558 
559   return frame;
560 }
561 
562 static void
gst_nv_h264_dec_fill_scaling_list_4x4(const GstH264PPS * pps,CUVIDH264PICPARAMS * params)563 gst_nv_h264_dec_fill_scaling_list_4x4 (const GstH264PPS * pps,
564     CUVIDH264PICPARAMS * params)
565 {
566   guint i;
567 
568   for (i = 0; i < G_N_ELEMENTS (params->WeightScale4x4); i++)
569     gst_h264_quant_matrix_4x4_get_raster_from_zigzag (params->WeightScale4x4[i],
570         pps->scaling_lists_4x4[i]);
571 }
572 
573 static void
gst_nv_h264_dec_fill_scaling_list_8x8(const GstH264PPS * pps,CUVIDH264PICPARAMS * params)574 gst_nv_h264_dec_fill_scaling_list_8x8 (const GstH264PPS * pps,
575     CUVIDH264PICPARAMS * params)
576 {
577   guint i;
578 
579   for (i = 0; i < G_N_ELEMENTS (params->WeightScale8x8); i++) {
580     gst_h264_quant_matrix_8x8_get_raster_from_zigzag (params->WeightScale8x8[i],
581         pps->scaling_lists_8x8[i]);
582   }
583 }
584 
585 static void
gst_nv_h264_dec_picture_params_from_sps(GstNvH264Dec * self,const GstH264SPS * sps,gboolean field_pic,CUVIDH264PICPARAMS * params)586 gst_nv_h264_dec_picture_params_from_sps (GstNvH264Dec * self,
587     const GstH264SPS * sps, gboolean field_pic, CUVIDH264PICPARAMS * params)
588 {
589   params->residual_colour_transform_flag = sps->separate_colour_plane_flag;
590   params->MbaffFrameFlag = sps->mb_adaptive_frame_field_flag && !field_pic;
591 
592 #define COPY_FIELD(f) \
593   (params)->f = (sps)->f
594 
595   COPY_FIELD (log2_max_frame_num_minus4);
596   COPY_FIELD (pic_order_cnt_type);
597   COPY_FIELD (log2_max_pic_order_cnt_lsb_minus4);
598   COPY_FIELD (delta_pic_order_always_zero_flag);
599   COPY_FIELD (frame_mbs_only_flag);
600   COPY_FIELD (direct_8x8_inference_flag);
601   COPY_FIELD (num_ref_frames);
602   COPY_FIELD (bit_depth_luma_minus8);
603   COPY_FIELD (bit_depth_chroma_minus8);
604   COPY_FIELD (qpprime_y_zero_transform_bypass_flag);
605 
606 #undef COPY_FIELD
607 }
608 
609 static void
gst_nv_h264_dec_picture_params_from_pps(GstNvH264Dec * self,const GstH264PPS * pps,CUVIDH264PICPARAMS * params)610 gst_nv_h264_dec_picture_params_from_pps (GstNvH264Dec * self,
611     const GstH264PPS * pps, CUVIDH264PICPARAMS * params)
612 {
613   params->second_chroma_qp_index_offset =
614       (gint8) pps->second_chroma_qp_index_offset;
615 
616 #define COPY_FIELD(f) \
617   (params)->f = (pps)->f
618 
619   COPY_FIELD (entropy_coding_mode_flag);
620   COPY_FIELD (pic_order_present_flag);
621   COPY_FIELD (num_ref_idx_l0_active_minus1);
622   COPY_FIELD (num_ref_idx_l1_active_minus1);
623   COPY_FIELD (pic_init_qp_minus26);
624   COPY_FIELD (weighted_pred_flag);
625   COPY_FIELD (weighted_bipred_idc);
626   COPY_FIELD (pic_init_qp_minus26);
627   COPY_FIELD (deblocking_filter_control_present_flag);
628   COPY_FIELD (redundant_pic_cnt_present_flag);
629   COPY_FIELD (transform_8x8_mode_flag);
630   COPY_FIELD (constrained_intra_pred_flag);
631   COPY_FIELD (chroma_qp_index_offset);
632 #undef COPY_FIELD
633 
634   gst_nv_h264_dec_fill_scaling_list_4x4 (pps, params);
635   gst_nv_h264_dec_fill_scaling_list_8x8 (pps, params);
636 }
637 
638 static void
gst_nv_h264_dec_reset_bitstream_params(GstNvH264Dec * self)639 gst_nv_h264_dec_reset_bitstream_params (GstNvH264Dec * self)
640 {
641   self->bitstream_buffer_offset = 0;
642   self->num_slices = 0;
643 
644   self->params.nBitstreamDataLen = 0;
645   self->params.pBitstreamData = NULL;
646   self->params.nNumSlices = 0;
647   self->params.pSliceDataOffsets = NULL;
648 }
649 
650 static void
gst_nv_h264_dec_fill_dpb(GstNvH264Dec * self,GstH264Picture * ref,CUVIDH264DPBENTRY * dpb)651 gst_nv_h264_dec_fill_dpb (GstNvH264Dec * self, GstH264Picture * ref,
652     CUVIDH264DPBENTRY * dpb)
653 {
654   GstNvDecoderFrame *frame;
655 
656   dpb->not_existing = ref->nonexisting;
657   dpb->PicIdx = -1;
658 
659   frame = gst_nv_h264_dec_get_decoder_frame_from_picture (self, ref);
660   if (!frame) {
661     dpb->not_existing = 1;
662   } else if (!dpb->not_existing) {
663     dpb->PicIdx = frame->index;
664   }
665 
666   if (dpb->not_existing)
667     return;
668 
669   if (GST_H264_PICTURE_IS_LONG_TERM_REF (ref)) {
670     dpb->FrameIdx = ref->long_term_frame_idx;
671     dpb->is_long_term = 1;
672   } else {
673     dpb->FrameIdx = ref->frame_num;
674     dpb->is_long_term = 0;
675   }
676 
677   switch (ref->field) {
678     case GST_H264_PICTURE_FIELD_FRAME:
679       dpb->FieldOrderCnt[0] = ref->top_field_order_cnt;
680       dpb->FieldOrderCnt[1] = ref->bottom_field_order_cnt;
681       dpb->used_for_reference = 0x3;
682       break;
683     case GST_H264_PICTURE_FIELD_TOP_FIELD:
684       dpb->FieldOrderCnt[0] = ref->top_field_order_cnt;
685       dpb->used_for_reference = 0x1;
686       if (ref->other_field) {
687         dpb->FieldOrderCnt[1] = ref->other_field->bottom_field_order_cnt;
688         dpb->used_for_reference |= 0x2;
689       } else {
690         dpb->FieldOrderCnt[1] = 0;
691       }
692       break;
693     case GST_H264_PICTURE_FIELD_BOTTOM_FIELD:
694       dpb->FieldOrderCnt[1] = ref->bottom_field_order_cnt;
695       dpb->used_for_reference = 0x2;
696       if (ref->other_field) {
697         dpb->FieldOrderCnt[0] = ref->other_field->bottom_field_order_cnt;
698         dpb->used_for_reference |= 0x1;
699       } else {
700         dpb->FieldOrderCnt[0] = 0;
701       }
702       break;
703     default:
704       dpb->FieldOrderCnt[0] = 0;
705       dpb->FieldOrderCnt[1] = 0;
706       dpb->used_for_reference = 0;
707       break;
708   }
709 }
710 
711 static GstFlowReturn
gst_nv_h264_dec_start_picture(GstH264Decoder * decoder,GstH264Picture * picture,GstH264Slice * slice,GstH264Dpb * dpb)712 gst_nv_h264_dec_start_picture (GstH264Decoder * decoder,
713     GstH264Picture * picture, GstH264Slice * slice, GstH264Dpb * dpb)
714 {
715   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
716   CUVIDPICPARAMS *params = &self->params;
717   CUVIDH264PICPARAMS *h264_params = &params->CodecSpecific.h264;
718   const GstH264SliceHdr *slice_header = &slice->header;
719   const GstH264SPS *sps;
720   const GstH264PPS *pps;
721   GstNvDecoderFrame *frame;
722   GArray *ref_list = self->ref_list;
723   guint i, ref_frame_idx;
724 
725   g_return_val_if_fail (slice_header->pps != NULL, FALSE);
726   g_return_val_if_fail (slice_header->pps->sequence != NULL, FALSE);
727 
728   frame = gst_nv_h264_dec_get_decoder_frame_from_picture (self, picture);
729 
730   if (!frame) {
731     GST_ERROR_OBJECT (self,
732         "Couldn't get decoder frame frame picture %p", picture);
733     return GST_FLOW_ERROR;
734   }
735 
736   gst_nv_h264_dec_reset_bitstream_params (self);
737 
738   sps = slice_header->pps->sequence;
739   pps = slice_header->pps;
740 
741   /* FIXME: update sps/pps related params only when it's required */
742   params->PicWidthInMbs = sps->pic_width_in_mbs_minus1 + 1;
743   if (!sps->frame_mbs_only_flag) {
744     params->FrameHeightInMbs = (sps->pic_height_in_map_units_minus1 + 1) << 1;
745   } else {
746     params->FrameHeightInMbs = sps->pic_height_in_map_units_minus1 + 1;
747   }
748   params->CurrPicIdx = frame->index;
749   params->field_pic_flag = slice_header->field_pic_flag;
750   params->bottom_field_flag =
751       picture->field == GST_H264_PICTURE_FIELD_BOTTOM_FIELD;
752   params->second_field = picture->second_field;
753 
754   if (picture->field == GST_H264_PICTURE_FIELD_TOP_FIELD) {
755     h264_params->CurrFieldOrderCnt[0] = picture->top_field_order_cnt;
756     h264_params->CurrFieldOrderCnt[1] = 0;
757   } else if (picture->field == GST_H264_PICTURE_FIELD_BOTTOM_FIELD) {
758     h264_params->CurrFieldOrderCnt[0] = 0;
759     h264_params->CurrFieldOrderCnt[1] = picture->bottom_field_order_cnt;
760   } else {
761     h264_params->CurrFieldOrderCnt[0] = picture->top_field_order_cnt;
762     h264_params->CurrFieldOrderCnt[1] = picture->bottom_field_order_cnt;
763   }
764 
765   /* nBitstreamDataLen, pBitstreamData, nNumSlices and pSliceDataOffsets
766    * will be set later */
767 
768   params->ref_pic_flag = GST_H264_PICTURE_IS_REF (picture);
769   /* will be updated later, if any slices belong to this frame is not
770    * intra slice */
771   params->intra_pic_flag = 1;
772 
773   h264_params->frame_num = picture->frame_num;
774   h264_params->ref_pic_flag = GST_H264_PICTURE_IS_REF (picture);
775 
776   gst_nv_h264_dec_picture_params_from_sps (self,
777       sps, slice_header->field_pic_flag, h264_params);
778   gst_nv_h264_dec_picture_params_from_pps (self, pps, h264_params);
779 
780   ref_frame_idx = 0;
781   g_array_set_size (ref_list, 0);
782 
783   memset (&h264_params->dpb, 0, sizeof (h264_params->dpb));
784   gst_h264_dpb_get_pictures_short_term_ref (dpb, FALSE, FALSE, ref_list);
785   for (i = 0; ref_frame_idx < 16 && i < ref_list->len; i++) {
786     GstH264Picture *other = g_array_index (ref_list, GstH264Picture *, i);
787     gst_nv_h264_dec_fill_dpb (self, other, &h264_params->dpb[ref_frame_idx]);
788     ref_frame_idx++;
789   }
790   g_array_set_size (ref_list, 0);
791 
792   gst_h264_dpb_get_pictures_long_term_ref (dpb, FALSE, ref_list);
793   for (i = 0; ref_frame_idx < 16 && i < ref_list->len; i++) {
794     GstH264Picture *other = g_array_index (ref_list, GstH264Picture *, i);
795     gst_nv_h264_dec_fill_dpb (self, other, &h264_params->dpb[ref_frame_idx]);
796     ref_frame_idx++;
797   }
798   g_array_set_size (ref_list, 0);
799 
800   for (i = ref_frame_idx; i < 16; i++)
801     h264_params->dpb[i].PicIdx = -1;
802 
803   return GST_FLOW_OK;
804 }
805 
806 static GstFlowReturn
gst_nv_h264_dec_decode_slice(GstH264Decoder * decoder,GstH264Picture * picture,GstH264Slice * slice,GArray * ref_pic_list0,GArray * ref_pic_list1)807 gst_nv_h264_dec_decode_slice (GstH264Decoder * decoder,
808     GstH264Picture * picture, GstH264Slice * slice, GArray * ref_pic_list0,
809     GArray * ref_pic_list1)
810 {
811   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
812   gsize new_size;
813 
814   GST_LOG_OBJECT (self, "Decode slice, nalu size %u", slice->nalu.size);
815 
816   if (self->slice_offsets_alloc_len < self->num_slices + 1) {
817     self->slice_offsets_alloc_len = 2 * (self->num_slices + 1);
818 
819     self->slice_offsets = (guint *) g_realloc_n (self->slice_offsets,
820         self->slice_offsets_alloc_len, sizeof (guint));
821   }
822   self->slice_offsets[self->num_slices] = self->bitstream_buffer_offset;
823   GST_LOG_OBJECT (self, "Slice offset %u for slice %d",
824       self->slice_offsets[self->num_slices], self->num_slices);
825 
826   self->num_slices++;
827 
828   new_size = self->bitstream_buffer_offset + slice->nalu.size + 3;
829   if (self->bitstream_buffer_alloc_size < new_size) {
830     self->bitstream_buffer_alloc_size = 2 * new_size;
831 
832     self->bitstream_buffer = (guint8 *) g_realloc (self->bitstream_buffer,
833         self->bitstream_buffer_alloc_size);
834   }
835 
836   self->bitstream_buffer[self->bitstream_buffer_offset] = 0;
837   self->bitstream_buffer[self->bitstream_buffer_offset + 1] = 0;
838   self->bitstream_buffer[self->bitstream_buffer_offset + 2] = 1;
839 
840   memcpy (self->bitstream_buffer + self->bitstream_buffer_offset + 3,
841       slice->nalu.data + slice->nalu.offset, slice->nalu.size);
842   self->bitstream_buffer_offset = new_size;
843 
844   if (!GST_H264_IS_I_SLICE (&slice->header) &&
845       !GST_H264_IS_SI_SLICE (&slice->header))
846     self->params.intra_pic_flag = 0;
847 
848   return GST_FLOW_OK;
849 }
850 
851 static GstFlowReturn
gst_nv_h264_dec_end_picture(GstH264Decoder * decoder,GstH264Picture * picture)852 gst_nv_h264_dec_end_picture (GstH264Decoder * decoder, GstH264Picture * picture)
853 {
854   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
855   gboolean ret;
856   CUVIDPICPARAMS *params = &self->params;
857 
858   params->nBitstreamDataLen = self->bitstream_buffer_offset;
859   params->pBitstreamData = self->bitstream_buffer;
860   params->nNumSlices = self->num_slices;
861   params->pSliceDataOffsets = self->slice_offsets;
862 
863   GST_LOG_OBJECT (self, "End picture, bitstream len: %" G_GSIZE_FORMAT
864       ", num slices %d", self->bitstream_buffer_offset, self->num_slices);
865 
866   ret = gst_nv_decoder_decode_picture (self->decoder, &self->params);
867 
868   if (!ret) {
869     GST_ERROR_OBJECT (self, "Failed to decode picture");
870     return GST_FLOW_ERROR;
871   }
872 
873   return GST_FLOW_OK;
874 }
875 
876 static guint
gst_nv_h264_dec_get_preferred_output_delay(GstH264Decoder * decoder,gboolean live)877 gst_nv_h264_dec_get_preferred_output_delay (GstH264Decoder * decoder,
878     gboolean live)
879 {
880   /* Prefer to zero latency for live pipeline */
881   if (live)
882     return 0;
883 
884   /* NVCODEC SDK uses 4 frame delay for better throughput performance */
885   return 4;
886 }
887 
888 typedef struct
889 {
890   GstCaps *sink_caps;
891   GstCaps *src_caps;
892   guint cuda_device_id;
893   gboolean is_default;
894 } GstNvH264DecClassData;
895 
896 static void
gst_nv_h264_dec_subclass_init(gpointer klass,GstNvH264DecClassData * cdata)897 gst_nv_h264_dec_subclass_init (gpointer klass, GstNvH264DecClassData * cdata)
898 {
899   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
900   GstNvH264DecClass *nvdec_class = (GstNvH264DecClass *) (klass);
901   gchar *long_name;
902 
903   if (cdata->is_default) {
904     long_name = g_strdup_printf ("NVDEC H.264 Stateless Decoder");
905   } else {
906     long_name = g_strdup_printf ("NVDEC H.264 Stateless Decoder with device %d",
907         cdata->cuda_device_id);
908   }
909 
910   gst_element_class_set_metadata (element_class, long_name,
911       "Codec/Decoder/Video/Hardware",
912       "Nvidia H.264 video decoder", "Seungha Yang <seungha@centricular.com>");
913   g_free (long_name);
914 
915   gst_element_class_add_pad_template (element_class,
916       gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
917           cdata->sink_caps));
918   gst_element_class_add_pad_template (element_class,
919       gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
920           cdata->src_caps));
921 
922   nvdec_class->cuda_device_id = cdata->cuda_device_id;
923 
924   gst_caps_unref (cdata->sink_caps);
925   gst_caps_unref (cdata->src_caps);
926   g_free (cdata);
927 }
928 
929 void
gst_nv_h264_dec_register(GstPlugin * plugin,guint device_id,guint rank,GstCaps * sink_caps,GstCaps * src_caps,gboolean is_primary)930 gst_nv_h264_dec_register (GstPlugin * plugin, guint device_id, guint rank,
931     GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary)
932 {
933   GTypeQuery type_query;
934   GTypeInfo type_info = { 0, };
935   GType subtype;
936   gchar *type_name;
937   gchar *feature_name;
938   GstNvH264DecClassData *cdata;
939   gboolean is_default = TRUE;
940   const GValue *value;
941   GstStructure *s;
942 
943   /**
944    * element-nvh264sldec
945    *
946    * Since: 1.18
947    */
948 
949   cdata = g_new0 (GstNvH264DecClassData, 1);
950   cdata->sink_caps = gst_caps_from_string ("video/x-h264, "
951       "stream-format= (string) { avc, avc3, byte-stream }, "
952       "alignment= (string) au, "
953       "profile = (string) { high, main, constrained-high, constrained-baseline, baseline }, "
954       "framerate = " GST_VIDEO_FPS_RANGE);
955 
956   s = gst_caps_get_structure (sink_caps, 0);
957   value = gst_structure_get_value (s, "width");
958   gst_caps_set_value (cdata->sink_caps, "width", value);
959 
960   value = gst_structure_get_value (s, "height");
961   gst_caps_set_value (cdata->sink_caps, "height", value);
962 
963   GST_MINI_OBJECT_FLAG_SET (cdata->sink_caps,
964       GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
965   cdata->src_caps = gst_caps_ref (src_caps);
966   cdata->cuda_device_id = device_id;
967 
968   g_type_query (GST_TYPE_NV_H264_DEC, &type_query);
969   memset (&type_info, 0, sizeof (type_info));
970   type_info.class_size = type_query.class_size;
971   type_info.instance_size = type_query.instance_size;
972   type_info.class_init = (GClassInitFunc) gst_nv_h264_dec_subclass_init;
973   type_info.class_data = cdata;
974 
975   if (is_primary) {
976     type_name = g_strdup ("GstNvH264StatelessPrimaryDec");
977     feature_name = g_strdup ("nvh264dec");
978   } else {
979     type_name = g_strdup ("GstNvH264StatelessDec");
980     feature_name = g_strdup ("nvh264sldec");
981   }
982 
983   if (g_type_from_name (type_name) != 0) {
984     g_free (type_name);
985     g_free (feature_name);
986     if (is_primary) {
987       type_name =
988           g_strdup_printf ("GstNvH264StatelessPrimaryDevice%dDec", device_id);
989       feature_name = g_strdup_printf ("nvh264device%ddec", device_id);
990     } else {
991       type_name = g_strdup_printf ("GstNvH264StatelessDevice%dDec", device_id);
992       feature_name = g_strdup_printf ("nvh264sldevice%ddec", device_id);
993     }
994 
995     is_default = FALSE;
996   }
997 
998   cdata->is_default = is_default;
999   subtype = g_type_register_static (GST_TYPE_NV_H264_DEC,
1000       type_name, &type_info, 0);
1001 
1002   /* make lower rank than default device */
1003   if (rank > 0 && !is_default)
1004     rank--;
1005 
1006   if (!gst_element_register (plugin, feature_name, rank, subtype))
1007     GST_WARNING ("Failed to register plugin '%s'", type_name);
1008 
1009   g_free (type_name);
1010   g_free (feature_name);
1011 }
1012