Beispiel #1
0
static void
gst_vaapi_decoder_notify_caps(GObject *obj, GParamSpec *pspec, void *user_data)
{
    GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data);
    GstCaps *caps;

    g_assert(decode->decoder == GST_VAAPI_DECODER(obj));

    caps = gst_vaapi_decoder_get_caps(decode->decoder);
    gst_vaapidecode_update_src_caps(decode, caps);
}
Beispiel #2
0
static gboolean
gst_vaapidecode_negotiate (GstVaapiDecode * decode)
{
  GstVideoDecoder *const vdec = GST_VIDEO_DECODER (decode);
  GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec);

  GST_DEBUG_OBJECT (decode, "input codec state changed: renegotiating");

  GST_VIDEO_DECODER_STREAM_LOCK (vdec);
  if (!gst_vaapi_plugin_base_set_caps (plugin, decode->sinkpad_caps, NULL))
    return FALSE;
  if (!gst_vaapidecode_update_src_caps (decode))
    return FALSE;
  if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps))
    return FALSE;
  GST_VIDEO_DECODER_STREAM_UNLOCK (vdec);

  if (!gst_video_decoder_negotiate (vdec))
    return FALSE;

  return TRUE;
}
Beispiel #3
0
static gboolean
gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps)
{
    GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad));

    g_return_val_if_fail(pad == decode->sinkpad, FALSE);

    if (!gst_vaapidecode_update_sink_caps(decode, caps))
        return FALSE;
    if (!gst_vaapidecode_update_src_caps(decode, caps))
        return FALSE;
    if (!gst_vaapidecode_reset(decode, decode->sinkpad_caps))
        return FALSE;

    /* Propagate NEWSEGMENT event downstream, now that pads are linked */
    if (decode->delayed_new_seg) {
        if (gst_pad_push_event(decode->srcpad, decode->delayed_new_seg))
            gst_event_unref(decode->delayed_new_seg);
        decode->delayed_new_seg = NULL;
    }
    return TRUE;
}
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;

  if (G_UNLIKELY (!decode->active) ||
      gst_pad_needs_reconfigure (GST_VIDEO_DECODER_SRC_PAD (vdec))) {
    GST_DEBUG_OBJECT (decode, "activating the decoder");
    if (!gst_vaapidecode_update_src_caps (decode))
      goto not_negotiated;

    if (!gst_video_decoder_negotiate (vdec))
      goto not_negotiated;

    GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (vdec);
    if (!gst_vaapi_plugin_base_set_caps (plugin, NULL, decode->srcpad_caps))
      goto not_negotiated;

    decode->active = TRUE;
  }

  /* 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;
  }
}