2 * Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
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.
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.
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.
21 * Copyright 2015 The Chromium Authors. All rights reserved.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions are
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
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.
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.
50 * SECTION:gstvp9decoder
51 * @title: Gstvp9Decoder
52 * @short_description: Base class to implement stateless VP9 decoders
61 #include <gst/base/base.h>
62 #include "gstvp9decoder.h"
64 GST_DEBUG_CATEGORY (gst_vp9_decoder_debug);
65 #define GST_CAT_DEFAULT gst_vp9_decoder_debug
67 struct _GstVp9DecoderPrivate
71 GstVP9Profile profile;
73 gboolean had_sequence;
75 GstVp9StatefulParser *parser;
78 gboolean wait_keyframe;
79 /* controls how many frames to delay when calling output_picture() */
80 guint preferred_output_delay;
81 GstQueueArray *output_queue;
87 GstVideoCodecFrame *frame;
88 GstVp9Picture *picture;
90 } GstVp9DecoderOutputFrame;
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"));
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);
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);
115 gst_vp9_decoder_class_init (GstVp9DecoderClass * klass)
117 GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
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);
130 gst_vp9_decoder_init (GstVp9Decoder * self)
132 gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE);
134 self->priv = gst_vp9_decoder_get_instance_private (self);
138 gst_vp9_decoder_start (GstVideoDecoder * decoder)
140 GstVp9Decoder *self = GST_VP9_DECODER (decoder);
141 GstVp9DecoderPrivate *priv = self->priv;
143 priv->parser = gst_vp9_stateful_parser_new ();
144 priv->dpb = gst_vp9_dpb_new ();
145 priv->wait_keyframe = TRUE;
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);
156 gst_vp9_decoder_stop (GstVideoDecoder * decoder)
158 GstVp9Decoder *self = GST_VP9_DECODER (decoder);
159 GstVp9DecoderPrivate *priv = self->priv;
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);
170 gst_vp9_decoder_check_codec_change (GstVp9Decoder * self,
171 const GstVp9FrameHeader * frame_hdr)
173 GstVp9DecoderPrivate *priv = self->priv;
174 GstFlowReturn ret = GST_FLOW_OK;
175 gboolean changed = FALSE;
177 if (priv->width != frame_hdr->width || priv->height != frame_hdr->height) {
178 GST_INFO_OBJECT (self, "resolution changed %dx%d", frame_hdr->width,
180 priv->width = frame_hdr->width;
181 priv->height = frame_hdr->height;
185 if (priv->profile != frame_hdr->profile) {
186 GST_INFO_OBJECT (self, "profile changed %d", frame_hdr->profile);
187 priv->profile = frame_hdr->profile;
191 if (changed || !priv->had_sequence) {
192 GstVp9DecoderClass *klass = GST_VP9_DECODER_GET_CLASS (self);
194 priv->had_sequence = TRUE;
196 if (klass->get_preferred_output_delay) {
197 priv->preferred_output_delay =
198 klass->get_preferred_output_delay (self, priv->is_live);
200 priv->preferred_output_delay = 0;
203 if (klass->new_sequence)
204 ret = klass->new_sequence (self, frame_hdr);
206 if (ret != GST_FLOW_OK)
207 priv->had_sequence = FALSE;
214 gst_vp9_decoder_set_format (GstVideoDecoder * decoder,
215 GstVideoCodecState * state)
217 GstVp9Decoder *self = GST_VP9_DECODER (decoder);
218 GstVp9DecoderPrivate *priv = self->priv;
221 GST_DEBUG_OBJECT (decoder, "Set format");
223 if (self->input_state)
224 gst_video_codec_state_unref (self->input_state);
226 self->input_state = gst_video_codec_state_ref (state);
228 priv->width = GST_VIDEO_INFO_WIDTH (&state->info);
229 priv->height = GST_VIDEO_INFO_HEIGHT (&state->info);
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);
240 gst_vp9_decoder_reset (GstVp9Decoder * self)
242 GstVp9DecoderPrivate *priv = self->priv;
245 gst_vp9_dpb_clear (priv->dpb);
247 priv->wait_keyframe = TRUE;
248 gst_queue_array_clear (priv->output_queue);
252 gst_vp9_decoder_finish (GstVideoDecoder * decoder)
254 GstFlowReturn ret = GST_FLOW_OK;
256 GST_DEBUG_OBJECT (decoder, "finish");
258 gst_vp9_decoder_drain_output_queue (GST_VP9_DECODER (decoder), 0, &ret);
259 gst_vp9_decoder_reset (GST_VP9_DECODER (decoder));
265 gst_vp9_decoder_flush (GstVideoDecoder * decoder)
267 GST_DEBUG_OBJECT (decoder, "flush");
269 gst_vp9_decoder_reset (GST_VP9_DECODER (decoder));
275 gst_vp9_decoder_drain (GstVideoDecoder * decoder)
277 GstFlowReturn ret = GST_FLOW_OK;
279 GST_DEBUG_OBJECT (decoder, "drain");
281 gst_vp9_decoder_drain_output_queue (GST_VP9_DECODER (decoder), 0, &ret);
282 gst_vp9_decoder_reset (GST_VP9_DECODER (decoder));
288 gst_vp9_decoder_clear_output_frame (GstVp9DecoderOutputFrame * output_frame)
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;
299 gst_vp9_picture_clear (&output_frame->picture);
303 gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder,
304 GstVideoCodecFrame * frame)
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;
314 GstFlowReturn ret = GST_FLOW_OK;
315 gboolean intra_only = FALSE;
316 gboolean check_codec_change = FALSE;
317 GstVp9DecoderOutputFrame output_frame;
319 GST_LOG_OBJECT (self, "handle frame %" GST_PTR_FORMAT, in_buf);
321 if (!gst_buffer_map (in_buf, &map, GST_MAP_READ)) {
322 GST_ERROR_OBJECT (self, "Cannot map input buffer");
326 pres = gst_vp9_stateful_parser_parse_frame_header (priv->parser, &frame_hdr,
329 if (pres != GST_VP9_PARSER_OK) {
330 GST_ERROR_OBJECT (self, "Failed to parsing frame header");
331 goto unmap_and_error;
334 if (frame_hdr.show_existing_frame) {
335 /* This is a non-intra, dummy frame */
337 } else if (frame_hdr.frame_type == GST_VP9_KEY_FRAME || frame_hdr.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;
352 if (priv->wait_keyframe && !intra_only) {
353 GST_DEBUG_OBJECT (self, "Drop frame before initial keyframe");
354 gst_buffer_unmap (in_buf, &map);
356 gst_video_decoder_release_frame (decoder, frame);;
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;
369 if (!priv->had_sequence) {
370 GST_WARNING_OBJECT (self, "No handled frame header, drop frame");
371 goto unmap_and_error;
374 priv->wait_keyframe = FALSE;
376 if (frame_hdr.show_existing_frame) {
377 GstVp9Picture *pic_to_dup;
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;
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);
393 gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
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);
400 GST_ERROR_OBJECT (self, "subclass didn't provide duplicated picture");
401 goto unmap_and_error;
404 picture = gst_vp9_picture_new ();
405 picture->frame_hdr = frame_hdr;
407 picture->data = map.data;
408 picture->size = map.size;
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;
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;
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;
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;
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));
449 gst_buffer_unmap (in_buf, &map);
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);
455 gst_vp9_picture_unref (picture);
457 ret = gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
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);
465 gst_vp9_decoder_drain_output_queue (self, priv->preferred_output_delay, &ret);
467 if (ret == GST_FLOW_ERROR) {
468 GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
469 ("Failed to decode data"), (NULL), ret);
477 gst_buffer_unmap (in_buf, &map);
484 gst_vp9_picture_unref (picture);
486 if (ret == GST_FLOW_OK)
487 ret = GST_FLOW_ERROR;
489 gst_video_decoder_drop_frame (decoder, frame);
490 GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
491 ("Failed to decode data"), (NULL), ret);
498 gst_vp9_decoder_drain_output_queue (GstVp9Decoder * self, guint num,
501 GstVp9DecoderPrivate *priv = self->priv;
502 GstVp9DecoderClass *klass = GST_VP9_DECODER_GET_CLASS (self);
504 g_assert (klass->output_picture);
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
511 GstFlowReturn flow_ret = klass->output_picture (self,
512 output_frame->frame, output_frame->picture);
514 /* Then, update @ret with new flow return value only if @ret was
515 * GST_FLOW_OK. This is to avoid pattern such that
517 * GstFlowReturn my_return = GST_FLOW_OK;
520 * if (my_return == GST_FLOW_OK) {
521 * my_return = gst_vp9_decoder_drain_output_queue ();
523 * // Ignore flow return of this method, but current `my_return` error code
524 * gst_vp9_decoder_drain_output_queue ();
530 if (*ret == GST_FLOW_OK)