codecs: vp8decoder: Use GstFlowReturn everywhere
authorSeungha Yang <seungha@centricular.com>
Fri, 17 Sep 2021 14:23:06 +0000 (23:23 +0900)
committerNicolas Dufresne <nicolas@ndufresne.ca>
Mon, 20 Sep 2021 13:03:44 +0000 (13:03 +0000)
boolean return value is not sufficient for representing the reason
of error in most cases. For instance, any errors around new_sequence()
would mean negotiation error, not just *ERROR*.
And some subclasses will allocate buffer/memory/surface on new_picture()
but it could be failed because of expected error, likely flushing

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2528>

gst-libs/gst/codecs/gstvp8decoder.c
gst-libs/gst/codecs/gstvp8decoder.h
sys/d3d11/gstd3d11vp8dec.cpp
sys/nvcodec/gstnvvp8dec.c
sys/v4l2codecs/gstv4l2codecvp8dec.c
sys/va/gstvavp8dec.c

index 2a9f834..0a22868 100644 (file)
@@ -75,7 +75,7 @@ static GstFlowReturn gst_vp8_decoder_handle_frame (GstVideoDecoder * decoder,
 static void gst_vp8_decoder_clear_output_frame (GstVp8DecoderOutputFrame *
     output_frame);
 static void gst_vp8_decoder_drain_output_queue (GstVp8Decoder * self,
-    guint num);
+    guint num, GstFlowReturn * ret);
 
 
 static void
@@ -148,12 +148,12 @@ gst_vp8_decoder_stop (GstVideoDecoder * decoder)
   return TRUE;
 }
 
-static gboolean
+static GstFlowReturn
 gst_vp8_decoder_check_codec_change (GstVp8Decoder * self,
     const GstVp8FrameHdr * frame_hdr)
 {
   GstVp8DecoderPrivate *priv = self->priv;
-  gboolean ret = TRUE;
+  GstFlowReturn ret = GST_FLOW_OK;
   gboolean changed = FALSE;
 
   if (priv->width != frame_hdr->width || priv->height != frame_hdr->height) {
@@ -276,12 +276,13 @@ static GstFlowReturn
 gst_vp8_decoder_finish (GstVideoDecoder * decoder)
 {
   GstVp8Decoder *self = GST_VP8_DECODER (decoder);
+  GstFlowReturn ret = GST_FLOW_OK;
 
   GST_DEBUG_OBJECT (self, "finish");
 
-  gst_vp8_decoder_drain_output_queue (GST_VP8_DECODER (decoder), 0);
+  gst_vp8_decoder_drain_output_queue (GST_VP8_DECODER (decoder), 0, &ret);
 
-  return GST_FLOW_OK;
+  return ret;
 }
 
 static gboolean
@@ -300,13 +301,14 @@ static GstFlowReturn
 gst_vp8_decoder_drain (GstVideoDecoder * decoder)
 {
   GstVp8Decoder *self = GST_VP8_DECODER (decoder);
+  GstFlowReturn ret = GST_FLOW_OK;
 
   GST_DEBUG_OBJECT (self, "drain");
 
-  gst_vp8_decoder_drain_output_queue (GST_VP8_DECODER (decoder), 0);
+  gst_vp8_decoder_drain_output_queue (GST_VP8_DECODER (decoder), 0, &ret);
   gst_vp8_decoder_reset (self);
 
-  return GST_FLOW_OK;
+  return ret;
 }
 
 static void
@@ -346,7 +348,6 @@ gst_vp8_decoder_handle_frame (GstVideoDecoder * decoder,
 
   if (!gst_buffer_map (in_buf, &map, GST_MAP_READ)) {
     GST_ERROR_OBJECT (self, "Cannot map buffer");
-
     goto error;
   }
 
@@ -355,7 +356,6 @@ gst_vp8_decoder_handle_frame (GstVideoDecoder * decoder,
 
   if (pres != GST_VP8_PARSER_OK) {
     GST_ERROR_OBJECT (self, "Cannot parser frame header");
-
     goto unmap_and_error;
   }
 
@@ -373,10 +373,12 @@ gst_vp8_decoder_handle_frame (GstVideoDecoder * decoder,
 
   priv->wait_keyframe = FALSE;
 
-  if (frame_hdr.key_frame &&
-      !gst_vp8_decoder_check_codec_change (self, &frame_hdr)) {
-    GST_ERROR_OBJECT (self, "Subclass cannot handle codec change");
-    goto unmap_and_error;
+  if (frame_hdr.key_frame) {
+    ret = gst_vp8_decoder_check_codec_change (self, &frame_hdr);
+    if (ret != GST_FLOW_OK) {
+      GST_WARNING_OBJECT (self, "Subclass cannot handle codec change");
+      goto unmap_and_error;
+    }
   }
 
   picture = gst_vp8_picture_new ();
@@ -387,29 +389,33 @@ gst_vp8_decoder_handle_frame (GstVideoDecoder * decoder,
   picture->system_frame_number = frame->system_frame_number;
 
   if (klass->new_picture) {
-    if (!klass->new_picture (self, frame, picture)) {
-      GST_ERROR_OBJECT (self, "subclass cannot handle new picture");
+    ret = klass->new_picture (self, frame, picture);
+    if (ret != GST_FLOW_OK) {
+      GST_WARNING_OBJECT (self, "subclass failed to handle new picture");
       goto unmap_and_error;
     }
   }
 
   if (klass->start_picture) {
-    if (!klass->start_picture (self, picture)) {
-      GST_ERROR_OBJECT (self, "subclass cannot handle start picture");
+    ret = klass->start_picture (self, picture);
+    if (ret != GST_FLOW_OK) {
+      GST_WARNING_OBJECT (self, "subclass failed to handle start picture");
       goto unmap_and_error;
     }
   }
 
   if (klass->decode_picture) {
-    if (!klass->decode_picture (self, picture, &priv->parser)) {
-      GST_ERROR_OBJECT (self, "subclass cannot decode current picture");
+    ret = klass->decode_picture (self, picture, &priv->parser);
+    if (ret != GST_FLOW_OK) {
+      GST_WARNING_OBJECT (self, "subclass failed to decode current picture");
       goto unmap_and_error;
     }
   }
 
   if (klass->end_picture) {
-    if (!klass->end_picture (self, picture)) {
-      GST_ERROR_OBJECT (self, "subclass cannot handle end picture");
+    ret = klass->end_picture (self, picture);
+    if (ret != GST_FLOW_OK) {
+      GST_WARNING_OBJECT (self, "subclass failed to handle end picture");
       goto unmap_and_error;
     }
   }
@@ -432,7 +438,14 @@ gst_vp8_decoder_handle_frame (GstVideoDecoder * decoder,
     gst_queue_array_push_tail_struct (priv->output_queue, &output_frame);
   }
 
-  gst_vp8_decoder_drain_output_queue (self, priv->preferred_output_delay);
+  gst_vp8_decoder_drain_output_queue (self, priv->preferred_output_delay, &ret);
+
+  if (ret == GST_FLOW_ERROR) {
+    GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
+        ("Failed to decode data"), (NULL), ret);
+    return ret;
+  }
+
   return ret;
 
 unmap_and_error:
@@ -446,6 +459,9 @@ error:
     if (picture)
       gst_vp8_picture_unref (picture);
 
+    if (ret == GST_FLOW_OK)
+      ret = GST_FLOW_ERROR;
+
     gst_video_decoder_drop_frame (decoder, frame);
     GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
         ("Failed to decode data"), (NULL), ret);
@@ -455,15 +471,39 @@ error:
 }
 
 static void
-gst_vp8_decoder_drain_output_queue (GstVp8Decoder * self, guint num)
+gst_vp8_decoder_drain_output_queue (GstVp8Decoder * self, guint num,
+    GstFlowReturn * ret)
 {
   GstVp8DecoderPrivate *priv = self->priv;
   GstVp8DecoderClass *klass = GST_VP8_DECODER_GET_CLASS (self);
+
   g_assert (klass->output_picture);
 
   while (gst_queue_array_get_length (priv->output_queue) > num) {
     GstVp8DecoderOutputFrame *output_frame = (GstVp8DecoderOutputFrame *)
         gst_queue_array_pop_head_struct (priv->output_queue);
-    klass->output_picture (self, output_frame->frame, output_frame->picture);
+    /* Output queued fraems whatever the return value is, in order to empty
+     * the queue */
+    GstFlowReturn flow_ret = klass->output_picture (self,
+        output_frame->frame, output_frame->picture);
+
+    /* Then, update @ret with new flow return value only if @ret was
+     * GST_FLOW_OK. This is to avoid pattern such that
+     * ```c
+     * GstFlowReturn my_return = GST_FLOW_OK;
+     * do something
+     *
+     * if (my_return == GST_FLOW_OK) {
+     *   my_return = gst_vp8_decoder_drain_output_queue ();
+     * } else {
+     *   // Ignore flow return of this method, but current `my_return` error code
+     *   gst_vp8_decoder_drain_output_queue ();
+     * }
+     *
+     * return my_return;
+     * ```
+     */
+    if (*ret == GST_FLOW_OK)
+      *ret = flow_ret;
   }
 }
index 9541088..e147afb 100644 (file)
@@ -88,31 +88,31 @@ struct _GstVp8DecoderClass
 {
   GstVideoDecoderClass parent_class;
 
-  gboolean        (*new_sequence)      (GstVp8Decoder * decoder,
+  GstFlowReturn   (*new_sequence)      (GstVp8Decoder * decoder,
                                         const GstVp8FrameHdr * frame_hdr);
 
   /**
-   * GstVp8Decoder:new_picture:
+   * GstVp8DecoderClass:new_picture:
    * @decoder: a #GstVp8Decoder
    * @frame: (transfer none): a #GstVideoCodecFrame
    * @picture: (transfer none): a #GstVp8Picture
    */
-  gboolean        (*new_picture)       (GstVp8Decoder * decoder,
+  GstFlowReturn   (*new_picture)       (GstVp8Decoder * decoder,
                                         GstVideoCodecFrame * frame,
                                         GstVp8Picture * picture);
 
-  gboolean        (*start_picture)     (GstVp8Decoder * decoder,
+  GstFlowReturn   (*start_picture)     (GstVp8Decoder * decoder,
                                         GstVp8Picture * picture);
 
-  gboolean        (*decode_picture)    (GstVp8Decoder * decoder,
+  GstFlowReturn   (*decode_picture)    (GstVp8Decoder * decoder,
                                         GstVp8Picture * picture,
                                         GstVp8Parser * parser);
 
-  gboolean        (*end_picture)       (GstVp8Decoder * decoder,
+  GstFlowReturn   (*end_picture)       (GstVp8Decoder * decoder,
                                         GstVp8Picture * picture);
 
   /**
-   * GstVp8Decoder:output_picture:
+   * GstVp8DecoderClass:output_picture:
    * @decoder: a #GstVp8Decoder
    * @frame: (transfer full): a #GstVideoCodecFrame
    * @picture: (transfer full): a #GstVp8Picture
index 9e18c12..a870a64 100644 (file)
@@ -110,15 +110,15 @@ static gboolean gst_d3d11_vp8_sink_event (GstVideoDecoder * decoder,
     GstEvent * event);
 
 /* GstVp8Decoder */
-static gboolean gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
+static GstFlowReturn gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
     const GstVp8FrameHdr * frame_hdr);
-static gboolean gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
+static GstFlowReturn gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
     GstVideoCodecFrame * frame, GstVp8Picture * picture);
-static gboolean gst_d3d11_vp8_dec_start_picture (GstVp8Decoder * decoder,
+static GstFlowReturn gst_d3d11_vp8_dec_start_picture (GstVp8Decoder * decoder,
     GstVp8Picture * picture);
-static gboolean gst_d3d11_vp8_dec_decode_picture (GstVp8Decoder * decoder,
+static GstFlowReturn gst_d3d11_vp8_dec_decode_picture (GstVp8Decoder * decoder,
     GstVp8Picture * picture, GstVp8Parser * parser);
-static gboolean gst_d3d11_vp8_dec_end_picture (GstVp8Decoder * decoder,
+static GstFlowReturn gst_d3d11_vp8_dec_end_picture (GstVp8Decoder * decoder,
     GstVp8Picture * picture);
 static GstFlowReturn gst_d3d11_vp8_dec_output_picture (GstVp8Decoder *
     decoder, GstVideoCodecFrame * frame, GstVp8Picture * picture);
@@ -312,7 +312,7 @@ gst_d3d11_vp8_sink_event (GstVideoDecoder * decoder, GstEvent * event)
   return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event);
 }
 
-static gboolean
+static GstFlowReturn
 gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
     const GstVp8FrameHdr * frame_hdr)
 {
@@ -334,18 +334,18 @@ gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
           decoder->input_state, &info, inner->width, inner->height,
           NUM_OUTPUT_VIEW)) {
     GST_ERROR_OBJECT (self, "Failed to create decoder");
-    return FALSE;
+    return GST_FLOW_NOT_NEGOTIATED;
   }
 
   if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
     GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
-    return FALSE;
+    return GST_FLOW_NOT_NEGOTIATED;
   }
 
-  return TRUE;
+  return GST_FLOW_OK;
 }
 
-static gboolean
+static GstFlowReturn
 gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
     GstVideoCodecFrame * frame, GstVp8Picture * picture)
 {
@@ -357,7 +357,7 @@ gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
       GST_VIDEO_DECODER (decoder));
   if (!view_buffer) {
     GST_DEBUG_OBJECT (self, "No available output view buffer");
-    return FALSE;
+    return GST_FLOW_FLUSHING;
   }
 
   GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT, view_buffer);
@@ -367,10 +367,10 @@ gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
 
   GST_LOG_OBJECT (self, "New VP8 picture %p", picture);
 
-  return TRUE;
+  return GST_FLOW_OK;
 }
 
-static gboolean
+static GstFlowReturn
 gst_d3d11_vp8_dec_start_picture (GstVp8Decoder * decoder,
     GstVp8Picture * picture)
 {
@@ -379,7 +379,7 @@ gst_d3d11_vp8_dec_start_picture (GstVp8Decoder * decoder,
 
   inner->bitstream_buffer.resize (0);
 
-  return TRUE;
+  return GST_FLOW_OK;
 }
 
 static ID3D11VideoDecoderOutputView *
@@ -537,7 +537,7 @@ gst_d3d11_vp8_dec_copy_segmentation_params (GstD3D11Vp8Dec * self,
   }
 }
 
-static gboolean
+static GstFlowReturn
 gst_d3d11_vp8_dec_decode_picture (GstVp8Decoder * decoder,
     GstVp8Picture * picture, GstVp8Parser * parser)
 {
@@ -553,7 +553,7 @@ gst_d3d11_vp8_dec_decode_picture (GstVp8Decoder * decoder,
       picture, &view_id);
   if (!view) {
     GST_ERROR_OBJECT (self, "current picture does not have output view handle");
-    return FALSE;
+    return GST_FLOW_ERROR;
   }
 
   memset (pic_params, 0, sizeof (DXVA_PicParams_VP8));
@@ -575,10 +575,10 @@ gst_d3d11_vp8_dec_decode_picture (GstVp8Decoder * decoder,
   slice->SliceBytesInBuffer = inner->bitstream_buffer.size ();
   slice->wBadSliceChopping = 0;
 
-  return TRUE;
+  return GST_FLOW_OK;
 }
 
-static gboolean
+static GstFlowReturn
 gst_d3d11_vp8_dec_end_picture (GstVp8Decoder * decoder, GstVp8Picture * picture)
 {
   GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
@@ -591,14 +591,14 @@ gst_d3d11_vp8_dec_end_picture (GstVp8Decoder * decoder, GstVp8Picture * picture)
 
   if (inner->bitstream_buffer.empty ()) {
     GST_ERROR_OBJECT (self, "No bitstream buffer to submit");
-    return FALSE;
+    return GST_FLOW_ERROR;
   }
 
   view = gst_d3d11_vp8_dec_get_output_view_from_picture (self,
       picture, &view_id);
   if (!view) {
     GST_ERROR_OBJECT (self, "current picture does not have output view handle");
-    return FALSE;
+    return GST_FLOW_ERROR;
   }
 
   memset (&input_args, 0, sizeof (GstD3D11DecodeInputStreamArgs));
@@ -624,8 +624,10 @@ gst_d3d11_vp8_dec_end_picture (GstVp8Decoder * decoder, GstVp8Picture * picture)
   input_args.bitstream = &inner->bitstream_buffer[0];
   input_args.bitstream_size = inner->bitstream_buffer.size ();
 
-  return gst_d3d11_decoder_decode_frame (inner->d3d11_decoder,
-      view, &input_args);
+  if (!gst_d3d11_decoder_decode_frame (inner->d3d11_decoder, view, &input_args))
+    return GST_FLOW_ERROR;
+
+  return GST_FLOW_OK;
 }
 
 static GstFlowReturn
index b4cb8f5..e2739e0 100644 (file)
@@ -72,11 +72,11 @@ static gboolean gst_nv_vp8_dec_src_query (GstVideoDecoder * decoder,
     GstQuery * query);
 
 /* GstVp8Decoder */
-static gboolean gst_nv_vp8_dec_new_sequence (GstVp8Decoder * decoder,
+static GstFlowReturn gst_nv_vp8_dec_new_sequence (GstVp8Decoder * decoder,
     const GstVp8FrameHdr * frame_hdr);
-static gboolean gst_nv_vp8_dec_new_picture (GstVp8Decoder * decoder,
+static GstFlowReturn gst_nv_vp8_dec_new_picture (GstVp8Decoder * decoder,
     GstVideoCodecFrame * frame, GstVp8Picture * picture);
-static gboolean gst_nv_vp8_dec_decode_picture (GstVp8Decoder * decoder,
+static GstFlowReturn gst_nv_vp8_dec_decode_picture (GstVp8Decoder * decoder,
     GstVp8Picture * picture, GstVp8Parser * parser);
 static GstFlowReturn gst_nv_vp8_dec_output_picture (GstVp8Decoder *
     decoder, GstVideoCodecFrame * frame, GstVp8Picture * picture);
@@ -225,7 +225,7 @@ gst_nv_vp8_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
   return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (decoder, query);
 }
 
-static gboolean
+static GstFlowReturn
 gst_nv_vp8_dec_new_sequence (GstVp8Decoder * decoder,
     const GstVp8FrameHdr * frame_hdr)
 {
@@ -256,12 +256,12 @@ gst_nv_vp8_dec_new_sequence (GstVp8Decoder * decoder,
             cudaVideoCodec_VP8, &info, self->width, self->height,
             NUM_OUTPUT_VIEW)) {
       GST_ERROR_OBJECT (self, "Failed to configure decoder");
-      return FALSE;
+      return GST_FLOW_NOT_NEGOTIATED;
     }
 
     if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
       GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
-      return FALSE;
+      return GST_FLOW_NOT_NEGOTIATED;
     }
 
     memset (&self->params, 0, sizeof (CUVIDPICPARAMS));
@@ -273,10 +273,10 @@ gst_nv_vp8_dec_new_sequence (GstVp8Decoder * decoder,
     self->params.CodecSpecific.vp8.height = self->height;
   }
 
-  return TRUE;
+  return GST_FLOW_OK;
 }
 
-static gboolean
+static GstFlowReturn
 gst_nv_vp8_dec_new_picture (GstVp8Decoder * decoder,
     GstVideoCodecFrame * frame, GstVp8Picture * picture)
 {
@@ -286,7 +286,7 @@ gst_nv_vp8_dec_new_picture (GstVp8Decoder * decoder,
   nv_frame = gst_nv_decoder_new_frame (self->decoder);
   if (!nv_frame) {
     GST_ERROR_OBJECT (self, "No available decoder frame");
-    return FALSE;
+    return GST_FLOW_ERROR;
   }
 
   GST_LOG_OBJECT (self,
@@ -295,7 +295,7 @@ gst_nv_vp8_dec_new_picture (GstVp8Decoder * decoder,
   gst_vp8_picture_set_user_data (picture,
       nv_frame, (GDestroyNotify) gst_nv_decoder_frame_unref);
 
-  return TRUE;
+  return GST_FLOW_OK;
 }
 
 static GstNvDecoderFrame *
@@ -312,7 +312,7 @@ gst_nv_vp8_dec_get_decoder_frame_from_picture (GstNvVp8Dec * self,
   return frame;
 }
 
-static gboolean
+static GstFlowReturn
 gst_nv_vp8_dec_decode_picture (GstVp8Decoder * decoder,
     GstVp8Picture * picture, GstVp8Parser * parser)
 {
@@ -327,7 +327,7 @@ gst_nv_vp8_dec_decode_picture (GstVp8Decoder * decoder,
   frame = gst_nv_vp8_dec_get_decoder_frame_from_picture (self, picture);
   if (!frame) {
     GST_ERROR_OBJECT (self, "Decoder frame is unavailable");
-    return FALSE;
+    return GST_FLOW_ERROR;
   }
 
   self->params.nBitstreamDataLen = picture->size;
@@ -346,7 +346,7 @@ gst_nv_vp8_dec_decode_picture (GstVp8Decoder * decoder,
         decoder->alt_ref_picture);
     if (!other_frame) {
       GST_ERROR_OBJECT (self, "Couldn't get decoder frame for AltRef");
-      return FALSE;
+      return GST_FLOW_ERROR;
     }
 
     self->params.CodecSpecific.vp8.AltRefIdx = other_frame->index;
@@ -360,7 +360,7 @@ gst_nv_vp8_dec_decode_picture (GstVp8Decoder * decoder,
         decoder->golden_ref_picture);
     if (!other_frame) {
       GST_ERROR_OBJECT (self, "Couldn't get decoder frame for GoldenRef");
-      return FALSE;
+      return GST_FLOW_ERROR;
     }
 
     self->params.CodecSpecific.vp8.GoldenRefIdx = other_frame->index;
@@ -374,7 +374,7 @@ gst_nv_vp8_dec_decode_picture (GstVp8Decoder * decoder,
         decoder->last_picture);
     if (!other_frame) {
       GST_ERROR_OBJECT (self, "Couldn't get decoder frame for LastRef");
-      return FALSE;
+      return GST_FLOW_ERROR;
     }
 
     self->params.CodecSpecific.vp8.LastRefIdx = other_frame->index;
@@ -391,7 +391,10 @@ gst_nv_vp8_dec_decode_picture (GstVp8Decoder * decoder,
       parser->segmentation.segmentation_enabled ?
       parser->segmentation.update_segment_feature_data : 0;
 
-  return gst_nv_decoder_decode_picture (self->decoder, &self->params);
+  if (!gst_nv_decoder_decode_picture (self->decoder, &self->params))
+    return GST_FLOW_ERROR;
+
+  return GST_FLOW_OK;
 }
 
 static GstFlowReturn
index 557b317..fd2a690 100644 (file)
@@ -435,7 +435,7 @@ gst_v4l2_codec_vp8_dec_fill_references (GstV4l2CodecVp8Dec * self)
       (guint32) self->frame_header.alt_frame_ts / 1000);
 }
 
-static gboolean
+static GstFlowReturn
 gst_v4l2_codec_vp8_dec_new_sequence (GstVp8Decoder * decoder,
     const GstVp8FrameHdr * frame_hdr)
 {
@@ -460,7 +460,7 @@ gst_v4l2_codec_vp8_dec_new_sequence (GstVp8Decoder * decoder,
     self->need_negotiation = TRUE;
     if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
       GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
-      return FALSE;
+      return GST_FLOW_NOT_NEGOTIATED;
     }
   }
 
@@ -485,10 +485,10 @@ gst_v4l2_codec_vp8_dec_new_sequence (GstVp8Decoder * decoder,
     self->copy_frames = FALSE;
   }
 
-  return TRUE;
+  return GST_FLOW_OK;
 }
 
-static gboolean
+static GstFlowReturn
 gst_v4l2_codec_vp8_dec_start_picture (GstVp8Decoder * decoder,
     GstVp8Picture * picture)
 {
@@ -496,7 +496,7 @@ gst_v4l2_codec_vp8_dec_start_picture (GstVp8Decoder * decoder,
 
   /* FIXME base class should not call us if negotiation failed */
   if (!self->sink_allocator)
-    return FALSE;
+    return GST_FLOW_NOT_NEGOTIATED;
 
   /* Ensure we have a bitstream to write into */
   if (!self->bitstream) {
@@ -505,24 +505,24 @@ gst_v4l2_codec_vp8_dec_start_picture (GstVp8Decoder * decoder,
     if (!self->bitstream) {
       GST_ELEMENT_ERROR (decoder, RESOURCE, NO_SPACE_LEFT,
           ("Not enough memory to decode VP8 stream."), (NULL));
-      return FALSE;
+      return GST_FLOW_ERROR;
     }
 
     if (!gst_memory_map (self->bitstream, &self->bitstream_map, GST_MAP_WRITE)) {
       GST_ELEMENT_ERROR (decoder, RESOURCE, WRITE,
           ("Could not access bitstream memory for writing"), (NULL));
       g_clear_pointer (&self->bitstream, gst_memory_unref);
-      return FALSE;
+      return GST_FLOW_ERROR;
     }
   }
 
   /* We use this field to track how much we have written */
   self->bitstream_map.size = 0;
 
-  return TRUE;
+  return GST_FLOW_OK;
 }
 
-static gboolean
+static GstFlowReturn
 gst_v4l2_codec_vp8_dec_decode_picture (GstVp8Decoder * decoder,
     GstVp8Picture * picture, GstVp8Parser * parser)
 {
@@ -532,7 +532,7 @@ gst_v4l2_codec_vp8_dec_decode_picture (GstVp8Decoder * decoder,
   if (self->bitstream_map.maxsize < picture->size) {
     GST_ELEMENT_ERROR (decoder, RESOURCE, NO_SPACE_LEFT,
         ("Not enough space to send picture bitstream."), (NULL));
-    return FALSE;
+    return GST_FLOW_ERROR;
   }
 
   gst_v4l2_codec_vp8_dec_fill_frame_header (self, &picture->frame_hdr);
@@ -545,7 +545,7 @@ gst_v4l2_codec_vp8_dec_decode_picture (GstVp8Decoder * decoder,
   memcpy (bitstream_data, picture->data, picture->size);
   self->bitstream_map.size = picture->size;
 
-  return TRUE;
+  return GST_FLOW_OK;
 }
 
 static void
@@ -559,7 +559,7 @@ gst_v4l2_codec_vp8_dec_reset_picture (GstV4l2CodecVp8Dec * self)
   }
 }
 
-static gboolean
+static GstFlowReturn
 gst_v4l2_codec_vp8_dec_end_picture (GstVp8Decoder * decoder,
     GstVp8Picture * picture)
 {
@@ -567,7 +567,7 @@ gst_v4l2_codec_vp8_dec_end_picture (GstVp8Decoder * decoder,
   GstVideoCodecFrame *frame;
   GstV4l2Request *request;
   GstBuffer *buffer;
-  GstFlowReturn flow_ret;
+  GstFlowReturn flow_ret = GST_FLOW_OK;
   gsize bytesused;
 
   /* *INDENT-OFF* */
@@ -598,7 +598,7 @@ gst_v4l2_codec_vp8_dec_end_picture (GstVp8Decoder * decoder,
 
   frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
       picture->system_frame_number);
-  g_return_val_if_fail (frame, FALSE);
+  g_return_val_if_fail (frame, GST_FLOW_ERROR);
   g_warn_if_fail (frame->output_buffer == NULL);
   frame->output_buffer = buffer;
   gst_video_codec_frame_unref (frame);
@@ -628,11 +628,16 @@ gst_v4l2_codec_vp8_dec_end_picture (GstVp8Decoder * decoder,
   }
 
   gst_v4l2_codec_vp8_dec_reset_picture (self);
-  return TRUE;
+
+  return GST_FLOW_OK;
 
 fail:
   gst_v4l2_codec_vp8_dec_reset_picture (self);
-  return FALSE;
+
+  if (flow_ret != GST_FLOW_OK)
+    return flow_ret;
+
+  return GST_FLOW_ERROR;
 }
 
 static gboolean
index 18fc3cd..c8f2001 100644 (file)
@@ -142,7 +142,7 @@ _get_profile (GstVaVp8Dec * self, const GstVp8FrameHdr * frame_hdr)
   return VAProfileVP8Version0_3;
 }
 
-static gboolean
+static GstFlowReturn
 gst_va_vp8_dec_new_sequence (GstVp8Decoder * decoder,
     const GstVp8FrameHdr * frame_hdr)
 {
@@ -156,12 +156,12 @@ gst_va_vp8_dec_new_sequence (GstVp8Decoder * decoder,
 
   profile = _get_profile (self, frame_hdr);
   if (profile == VAProfileNone)
-    return FALSE;
+    return GST_FLOW_NOT_NEGOTIATED;
 
   if (!gst_va_decoder_has_profile (base->decoder, profile)) {
     GST_ERROR_OBJECT (self, "Profile %s is not supported",
         gst_va_profile_name (profile));
-    return FALSE;
+    return GST_FLOW_NOT_NEGOTIATED;
   }
 
   /* VP8 always use 8 bits 4:2:0 */
@@ -182,14 +182,14 @@ gst_va_vp8_dec_new_sequence (GstVp8Decoder * decoder,
     self->need_negotiation = TRUE;
     if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
       GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
-      return FALSE;
+      return GST_FLOW_NOT_NEGOTIATED;
     }
   }
 
-  return TRUE;
+  return GST_FLOW_OK;
 }
 
-static gboolean
+static GstFlowReturn
 gst_va_vp8_dec_new_picture (GstVp8Decoder * decoder,
     GstVideoCodecFrame * frame, GstVp8Picture * picture)
 {
@@ -209,14 +209,15 @@ gst_va_vp8_dec_new_picture (GstVp8Decoder * decoder,
 
   GST_LOG_OBJECT (self, "New va decode picture %p - %#x", pic,
       gst_va_decode_picture_get_surface (pic));
-  return TRUE;
+
+  return GST_FLOW_OK;
 
 error:
   {
     GST_WARNING_OBJECT (self,
         "Failed to allocated output buffer, return %s",
         gst_flow_get_name (self->last_ret));
-    return FALSE;
+    return self->last_ret;
   }
 }
 
@@ -412,11 +413,14 @@ static gboolean
 gst_va_vp8_dec_decode_picture (GstVp8Decoder * decoder, GstVp8Picture * picture,
     GstVp8Parser * parser)
 {
-  return _fill_picture (decoder, picture, parser) &&
-      _add_slice (decoder, picture, parser);
+  if (_fill_picture (decoder, picture, parser) &&
+      _add_slice (decoder, picture, parser))
+    return GST_FLOW_OK;
+
+  return GST_FLOW_ERROR;
 }
 
-static gboolean
+static GstFlowReturn
 gst_va_vp8_dec_end_picture (GstVp8Decoder * decoder, GstVp8Picture * picture)
 {
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
@@ -427,7 +431,10 @@ gst_va_vp8_dec_end_picture (GstVp8Decoder * decoder, GstVp8Picture * picture)
 
   va_pic = gst_vp8_picture_get_user_data (picture);
 
-  return gst_va_decoder_decode (base->decoder, va_pic);
+  if (!gst_va_decoder_decode (base->decoder, va_pic))
+    return GST_FLOW_ERROR;
+
+  return GST_FLOW_OK;
 }
 
 static GstFlowReturn