codecs: vp9decoder: add support for render delay
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / gst-libs / gst / codecs / gstvp9decoder.c
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  * Copyright 2015 The Chromium Authors. All rights reserved.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions are
25  * met:
26  *
27  *    * Redistributions of source code must retain the above copyright
28  * notice, this list of conditions and the following disclaimer.
29  *    * Redistributions in binary form must reproduce the above
30  * copyright notice, this list of conditions and the following disclaimer
31  * in the documentation and/or other materials provided with the
32  * distribution.
33  *    * Neither the name of Google Inc. nor the names of its
34  * contributors may be used to endorse or promote products derived from
35  * this software without specific prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
38  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
40  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
41  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  */
49 /**
50  * SECTION:gstvp9decoder
51  * @title: Gstvp9Decoder
52  * @short_description: Base class to implement stateless VP9 decoders
53  * @sources:
54  * - gstvp9picture.h
55  */
56
57 #ifdef HAVE_CONFIG_H
58 #include <config.h>
59 #endif
60
61 #include <gst/base/base.h>
62 #include "gstvp9decoder.h"
63
64 GST_DEBUG_CATEGORY (gst_vp9_decoder_debug);
65 #define GST_CAT_DEFAULT gst_vp9_decoder_debug
66
67 struct _GstVp9DecoderPrivate
68 {
69   gint width;
70   gint height;
71   GstVP9Profile profile;
72
73   gboolean had_sequence;
74
75   GstVp9StatefulParser *parser;
76   GstVp9Dpb *dpb;
77
78   gboolean wait_keyframe;
79   /* controls how many frames to delay when calling output_picture() */
80   guint preferred_output_delay;
81   GstQueueArray *output_queue;
82   gboolean is_live;
83 };
84
85 typedef struct
86 {
87   GstVideoCodecFrame *frame;
88   GstVp9Picture *picture;
89   GstVp9Decoder *self;
90 } GstVp9DecoderOutputFrame;
91
92 #define parent_class gst_vp9_decoder_parent_class
93 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstVp9Decoder, gst_vp9_decoder,
94     GST_TYPE_VIDEO_DECODER,
95     G_ADD_PRIVATE (GstVp9Decoder);
96     GST_DEBUG_CATEGORY_INIT (gst_vp9_decoder_debug, "vp9decoder", 0,
97         "VP9 Video Decoder"));
98
99 static gboolean gst_vp9_decoder_start (GstVideoDecoder * decoder);
100 static gboolean gst_vp9_decoder_stop (GstVideoDecoder * decoder);
101 static gboolean gst_vp9_decoder_set_format (GstVideoDecoder * decoder,
102     GstVideoCodecState * state);
103 static GstFlowReturn gst_vp9_decoder_finish (GstVideoDecoder * decoder);
104 static gboolean gst_vp9_decoder_flush (GstVideoDecoder * decoder);
105 static GstFlowReturn gst_vp9_decoder_drain (GstVideoDecoder * decoder);
106 static GstFlowReturn gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder,
107     GstVideoCodecFrame * frame);
108
109 static void
110 gst_vp9_decoder_clear_output_frame (GstVp9DecoderOutputFrame * output_frame);
111 static void gst_vp9_decoder_drain_output_queue (GstVp9Decoder * self,
112     guint num, GstFlowReturn * ret);
113
114 static void
115 gst_vp9_decoder_class_init (GstVp9DecoderClass * klass)
116 {
117   GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
118
119   decoder_class->start = GST_DEBUG_FUNCPTR (gst_vp9_decoder_start);
120   decoder_class->stop = GST_DEBUG_FUNCPTR (gst_vp9_decoder_stop);
121   decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_vp9_decoder_set_format);
122   decoder_class->finish = GST_DEBUG_FUNCPTR (gst_vp9_decoder_finish);
123   decoder_class->flush = GST_DEBUG_FUNCPTR (gst_vp9_decoder_flush);
124   decoder_class->drain = GST_DEBUG_FUNCPTR (gst_vp9_decoder_drain);
125   decoder_class->handle_frame =
126       GST_DEBUG_FUNCPTR (gst_vp9_decoder_handle_frame);
127 }
128
129 static void
130 gst_vp9_decoder_init (GstVp9Decoder * self)
131 {
132   gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE);
133
134   self->priv = gst_vp9_decoder_get_instance_private (self);
135 }
136
137 static gboolean
138 gst_vp9_decoder_start (GstVideoDecoder * decoder)
139 {
140   GstVp9Decoder *self = GST_VP9_DECODER (decoder);
141   GstVp9DecoderPrivate *priv = self->priv;
142
143   priv->parser = gst_vp9_stateful_parser_new ();
144   priv->dpb = gst_vp9_dpb_new ();
145   priv->wait_keyframe = TRUE;
146
147   priv->output_queue =
148       gst_queue_array_new_for_struct (sizeof (GstVp9DecoderOutputFrame), 1);
149   gst_queue_array_set_clear_func (priv->output_queue,
150       (GDestroyNotify) gst_vp9_decoder_clear_output_frame);
151
152   return TRUE;
153 }
154
155 static gboolean
156 gst_vp9_decoder_stop (GstVideoDecoder * decoder)
157 {
158   GstVp9Decoder *self = GST_VP9_DECODER (decoder);
159   GstVp9DecoderPrivate *priv = self->priv;
160
161   g_clear_pointer (&self->input_state, gst_video_codec_state_unref);
162   g_clear_pointer (&priv->parser, gst_vp9_stateful_parser_free);
163   g_clear_pointer (&priv->dpb, gst_vp9_dpb_free);
164   gst_queue_array_free (priv->output_queue);
165
166   return TRUE;
167 }
168
169 static GstFlowReturn
170 gst_vp9_decoder_check_codec_change (GstVp9Decoder * self,
171     const GstVp9FrameHeader * frame_hdr)
172 {
173   GstVp9DecoderPrivate *priv = self->priv;
174   GstFlowReturn ret = GST_FLOW_OK;
175   gboolean changed = FALSE;
176
177   if (priv->width != frame_hdr->width || priv->height != frame_hdr->height) {
178     GST_INFO_OBJECT (self, "resolution changed %dx%d", frame_hdr->width,
179         frame_hdr->height);
180     priv->width = frame_hdr->width;
181     priv->height = frame_hdr->height;
182     changed = TRUE;
183   }
184
185   if (priv->profile != frame_hdr->profile) {
186     GST_INFO_OBJECT (self, "profile changed %d", frame_hdr->profile);
187     priv->profile = frame_hdr->profile;
188     changed = TRUE;
189   }
190
191   if (changed || !priv->had_sequence) {
192     GstVp9DecoderClass *klass = GST_VP9_DECODER_GET_CLASS (self);
193
194     priv->had_sequence = TRUE;
195
196     if (klass->get_preferred_output_delay) {
197       priv->preferred_output_delay =
198           klass->get_preferred_output_delay (self, priv->is_live);
199     } else {
200       priv->preferred_output_delay = 0;
201     }
202
203     if (klass->new_sequence)
204       ret = klass->new_sequence (self, frame_hdr);
205
206     if (ret != GST_FLOW_OK)
207       priv->had_sequence = FALSE;
208   }
209
210   return ret;
211 }
212
213 static gboolean
214 gst_vp9_decoder_set_format (GstVideoDecoder * decoder,
215     GstVideoCodecState * state)
216 {
217   GstVp9Decoder *self = GST_VP9_DECODER (decoder);
218   GstVp9DecoderPrivate *priv = self->priv;
219   GstQuery *query;
220
221   GST_DEBUG_OBJECT (decoder, "Set format");
222
223   if (self->input_state)
224     gst_video_codec_state_unref (self->input_state);
225
226   self->input_state = gst_video_codec_state_ref (state);
227
228   priv->width = GST_VIDEO_INFO_WIDTH (&state->info);
229   priv->height = GST_VIDEO_INFO_HEIGHT (&state->info);
230
231   query = gst_query_new_latency ();
232   if (gst_pad_peer_query (GST_VIDEO_DECODER_SINK_PAD (self), query))
233     gst_query_parse_latency (query, &priv->is_live, NULL, NULL);
234   gst_query_unref (query);
235
236   return TRUE;
237 }
238
239 static void
240 gst_vp9_decoder_reset (GstVp9Decoder * self)
241 {
242   GstVp9DecoderPrivate *priv = self->priv;
243
244   if (priv->dpb)
245     gst_vp9_dpb_clear (priv->dpb);
246
247   priv->wait_keyframe = TRUE;
248   gst_queue_array_clear (priv->output_queue);
249 }
250
251 static GstFlowReturn
252 gst_vp9_decoder_finish (GstVideoDecoder * decoder)
253 {
254   GstFlowReturn ret = GST_FLOW_OK;
255
256   GST_DEBUG_OBJECT (decoder, "finish");
257
258   gst_vp9_decoder_drain_output_queue (GST_VP9_DECODER (decoder), 0, &ret);
259   gst_vp9_decoder_reset (GST_VP9_DECODER (decoder));
260
261   return ret;
262 }
263
264 static gboolean
265 gst_vp9_decoder_flush (GstVideoDecoder * decoder)
266 {
267   GST_DEBUG_OBJECT (decoder, "flush");
268
269   gst_vp9_decoder_reset (GST_VP9_DECODER (decoder));
270
271   return TRUE;
272 }
273
274 static GstFlowReturn
275 gst_vp9_decoder_drain (GstVideoDecoder * decoder)
276 {
277   GstFlowReturn ret = GST_FLOW_OK;
278
279   GST_DEBUG_OBJECT (decoder, "drain");
280
281   gst_vp9_decoder_drain_output_queue (GST_VP9_DECODER (decoder), 0, &ret);
282   gst_vp9_decoder_reset (GST_VP9_DECODER (decoder));
283
284   return ret;
285 }
286
287 static void
288 gst_vp9_decoder_clear_output_frame (GstVp9DecoderOutputFrame * output_frame)
289 {
290   if (!output_frame)
291     return;
292
293   if (output_frame->frame) {
294     gst_video_decoder_release_frame (GST_VIDEO_DECODER (output_frame->self),
295         output_frame->frame);
296     output_frame->frame = NULL;
297   }
298
299   gst_vp9_picture_clear (&output_frame->picture);
300 }
301
302 static GstFlowReturn
303 gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder,
304     GstVideoCodecFrame * frame)
305 {
306   GstVp9Decoder *self = GST_VP9_DECODER (decoder);
307   GstVp9DecoderClass *klass = GST_VP9_DECODER_GET_CLASS (self);
308   GstVp9DecoderPrivate *priv = self->priv;
309   GstBuffer *in_buf = frame->input_buffer;
310   GstVp9FrameHeader frame_hdr;
311   GstVp9Picture *picture = NULL;
312   GstVp9ParserResult pres;
313   GstMapInfo map;
314   GstFlowReturn ret = GST_FLOW_OK;
315   gboolean intra_only = FALSE;
316   gboolean check_codec_change = FALSE;
317   GstVp9DecoderOutputFrame output_frame;
318
319   GST_LOG_OBJECT (self, "handle frame %" GST_PTR_FORMAT, in_buf);
320
321   if (!gst_buffer_map (in_buf, &map, GST_MAP_READ)) {
322     GST_ERROR_OBJECT (self, "Cannot map input buffer");
323     goto error;
324   }
325
326   pres = gst_vp9_stateful_parser_parse_frame_header (priv->parser, &frame_hdr,
327       map.data, map.size);
328
329   if (pres != GST_VP9_PARSER_OK) {
330     GST_ERROR_OBJECT (self, "Failed to parsing frame header");
331     goto unmap_and_error;
332   }
333
334   if (frame_hdr.show_existing_frame) {
335     /* This is a non-intra, dummy frame */
336     intra_only = FALSE;
337   } else if (frame_hdr.frame_type == GST_VP9_KEY_FRAME || frame_hdr.intra_only) {
338     intra_only = TRUE;
339   }
340
341   if (intra_only) {
342     if (frame_hdr.frame_type == GST_VP9_KEY_FRAME) {
343       /* Always check codec change per keyframe */
344       check_codec_change = TRUE;
345     } else if (priv->wait_keyframe) {
346       /* Or, if we are waiting for leading keyframe, but this is intra-only,
347        * try decoding this frame, it's allowed as per spec */
348       check_codec_change = TRUE;
349     }
350   }
351
352   if (priv->wait_keyframe && !intra_only) {
353     GST_DEBUG_OBJECT (self, "Drop frame before initial keyframe");
354     gst_buffer_unmap (in_buf, &map);
355
356     gst_video_decoder_release_frame (decoder, frame);;
357
358     return GST_FLOW_OK;
359   }
360
361   if (check_codec_change) {
362     ret = gst_vp9_decoder_check_codec_change (self, &frame_hdr);
363     if (ret != GST_FLOW_OK) {
364       GST_WARNING_OBJECT (self, "Subclass cannot handle codec change");
365       goto unmap_and_error;
366     }
367   }
368
369   if (!priv->had_sequence) {
370     GST_WARNING_OBJECT (self, "No handled frame header, drop frame");
371     goto unmap_and_error;
372   }
373
374   priv->wait_keyframe = FALSE;
375
376   if (frame_hdr.show_existing_frame) {
377     GstVp9Picture *pic_to_dup;
378
379     if (frame_hdr.frame_to_show_map_idx >= GST_VP9_REF_FRAMES ||
380         !priv->dpb->pic_list[frame_hdr.frame_to_show_map_idx]) {
381       GST_ERROR_OBJECT (self, "Invalid frame_to_show_map_idx %d",
382           frame_hdr.frame_to_show_map_idx);
383       goto unmap_and_error;
384     }
385
386     /* If not implemented by subclass, we can just drop this picture
387      * since this frame header indicates the frame index to be duplicated
388      * and also this frame header doesn't affect reference management */
389     if (!klass->duplicate_picture) {
390       gst_buffer_unmap (in_buf, &map);
391       GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame);
392
393       gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
394     }
395
396     pic_to_dup = priv->dpb->pic_list[frame_hdr.frame_to_show_map_idx];
397     picture = klass->duplicate_picture (self, frame, pic_to_dup);
398
399     if (!picture) {
400       GST_ERROR_OBJECT (self, "subclass didn't provide duplicated picture");
401       goto unmap_and_error;
402     }
403   } else {
404     picture = gst_vp9_picture_new ();
405     picture->frame_hdr = frame_hdr;
406
407     picture->data = map.data;
408     picture->size = map.size;
409
410     if (klass->new_picture) {
411       ret = klass->new_picture (self, frame, picture);
412       if (ret != GST_FLOW_OK) {
413         GST_WARNING_OBJECT (self, "subclass failed to handle new picture");
414         goto unmap_and_error;
415       }
416     }
417
418     if (klass->start_picture) {
419       ret = klass->start_picture (self, picture);
420       if (ret != GST_FLOW_OK) {
421         GST_WARNING_OBJECT (self, "subclass failed to handle start picture");
422         goto unmap_and_error;
423       }
424     }
425
426     if (klass->decode_picture) {
427       ret = klass->decode_picture (self, picture, priv->dpb);
428       if (ret != GST_FLOW_OK) {
429         GST_WARNING_OBJECT (self, "subclass failed to decode current picture");
430         goto unmap_and_error;
431       }
432     }
433
434     if (klass->end_picture) {
435       ret = klass->end_picture (self, picture);
436       if (ret != GST_FLOW_OK) {
437         GST_WARNING_OBJECT (self, "subclass failed to handle end picture");
438         goto unmap_and_error;
439       }
440     }
441
442     /* Just pass our picture to dpb object.
443      * Even if this picture does not need to be added to dpb
444      * (i.e., not a reference frame), gst_vp9_dpb_add() will take care of
445      * the case as well */
446     gst_vp9_dpb_add (priv->dpb, gst_vp9_picture_ref (picture));
447   }
448
449   gst_buffer_unmap (in_buf, &map);
450
451   if (!frame_hdr.show_frame && !frame_hdr.show_existing_frame) {
452     GST_LOG_OBJECT (self, "Decode only picture %p", picture);
453     GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame);
454
455     gst_vp9_picture_unref (picture);
456
457     ret = gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
458   } else {
459     output_frame.frame = frame;
460     output_frame.picture = picture;
461     output_frame.self = self;
462     gst_queue_array_push_tail_struct (priv->output_queue, &output_frame);
463   }
464
465   gst_vp9_decoder_drain_output_queue (self, priv->preferred_output_delay, &ret);
466
467   if (ret == GST_FLOW_ERROR) {
468     GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
469         ("Failed to decode data"), (NULL), ret);
470     return ret;
471   }
472
473   return ret;
474
475 unmap_and_error:
476   {
477     gst_buffer_unmap (in_buf, &map);
478     goto error;
479   }
480
481 error:
482   {
483     if (picture)
484       gst_vp9_picture_unref (picture);
485
486     if (ret == GST_FLOW_OK)
487       ret = GST_FLOW_ERROR;
488
489     gst_video_decoder_drop_frame (decoder, frame);
490     GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
491         ("Failed to decode data"), (NULL), ret);
492
493     return ret;
494   }
495 }
496
497 static void
498 gst_vp9_decoder_drain_output_queue (GstVp9Decoder * self, guint num,
499     GstFlowReturn * ret)
500 {
501   GstVp9DecoderPrivate *priv = self->priv;
502   GstVp9DecoderClass *klass = GST_VP9_DECODER_GET_CLASS (self);
503
504   g_assert (klass->output_picture);
505
506   while (gst_queue_array_get_length (priv->output_queue) > num) {
507     GstVp9DecoderOutputFrame *output_frame = (GstVp9DecoderOutputFrame *)
508         gst_queue_array_pop_head_struct (priv->output_queue);
509     /* Output queued frames whatever the return value is, in order to empty
510      * the queue */
511     GstFlowReturn flow_ret = klass->output_picture (self,
512         output_frame->frame, output_frame->picture);
513
514     /* Then, update @ret with new flow return value only if @ret was
515      * GST_FLOW_OK. This is to avoid pattern such that
516      * ```c
517      * GstFlowReturn my_return = GST_FLOW_OK;
518      * do something
519      *
520      * if (my_return == GST_FLOW_OK) {
521      *   my_return = gst_vp9_decoder_drain_output_queue ();
522      * } else {
523      *   // Ignore flow return of this method, but current `my_return` error code
524      *   gst_vp9_decoder_drain_output_queue ();
525      * }
526      *
527      * return my_return;
528      * ```
529      */
530     if (*ret == GST_FLOW_OK)
531       *ret = flow_ret;
532   }
533 }