static GstFlowReturn gst_vaapidecode_drain (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); if (!decode->decoder) return GST_FLOW_NOT_NEGOTIATED; return gst_vaapidecode_push_all_decoded_frames (decode); }
static GstFlowReturn gst_vaapidecode_drain (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); if (!decode->decoder) return GST_FLOW_NOT_NEGOTIATED; GST_LOG_OBJECT (decode, "drain"); gst_vaapidecode_flush_output_adapter (decode); return gst_vaapidecode_push_all_decoded_frames (decode); }
static GstFlowReturn gst_vaapidecode_finish (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); gboolean flushed; GstFlowReturn ret; if (!decode->decoder) return GST_FLOW_OK; flushed = gst_vaapidecode_internal_flush (vdec); ret = gst_vaapidecode_push_all_decoded_frames (decode); if (!flushed) return GST_FLOW_ERROR; return ret; }
static GstFlowReturn gst_vaapidecode_finish (GstVideoDecoder * vdec) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstVaapiDecoderStatus status; GstFlowReturn ret; if (!decode->decoder) return GST_FLOW_OK; gst_vaapidecode_flush_output_adapter (decode); status = gst_vaapi_decoder_flush (decode->decoder); ret = gst_vaapidecode_push_all_decoded_frames (decode); if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto error_decoder_flush; return ret; /* ERRORS: */ error_decoder_flush: { GST_WARNING_OBJECT (decode, "failed to flush decoder (status %d)", status); return GST_FLOW_ERROR; } }
static GstFlowReturn gst_vaapidecode_handle_frame (GstVideoDecoder * vdec, GstVideoCodecFrame * frame) { GstVaapiDecode *const decode = GST_VAAPIDECODE (vdec); GstVaapiDecoderStatus status; GstFlowReturn ret; if (!decode->input_state) goto not_negotiated; /* Decode current frame */ for (;;) { status = gst_vaapi_decoder_decode (decode->decoder, frame); if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) { /* Make sure that there are no decoded frames waiting in the output queue. */ ret = gst_vaapidecode_push_all_decoded_frames (decode); if (ret != GST_FLOW_OK) goto error_push_all_decoded_frames; g_mutex_lock (&decode->surface_ready_mutex); if (gst_vaapi_decoder_check_status (decode->decoder) == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) g_cond_wait (&decode->surface_ready, &decode->surface_ready_mutex); g_mutex_unlock (&decode->surface_ready_mutex); continue; } if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) goto error_decode; break; } /* Note that gst_vaapi_decoder_decode cannot return success without completing the decode and pushing all decoded frames into the output queue */ return gst_vaapidecode_push_all_decoded_frames (decode); /* ERRORS */ error_push_all_decoded_frames: { GST_ERROR ("push loop error while decoding %d", ret); gst_video_decoder_drop_frame (vdec, frame); return ret; } error_decode: { GST_ERROR ("decode error %d", status); switch (status) { case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: ret = GST_FLOW_NOT_SUPPORTED; break; default: GST_VIDEO_DECODER_ERROR (vdec, 1, STREAM, DECODE, ("Decoding error"), ("Decode error %d", status), ret); break; } gst_video_decoder_drop_frame (vdec, frame); return ret; } not_negotiated: { GST_ERROR_OBJECT (decode, "not negotiated"); ret = GST_FLOW_NOT_NEGOTIATED; gst_video_decoder_drop_frame (vdec, frame); return ret; } }