示例#1
0
static gboolean
gst_vaapi_decode_input_state_replace (GstVaapiDecode * decode,
    const GstVideoCodecState * new_state)
{
  if (decode->input_state) {
    if (new_state) {
      const GstCaps *curcaps = decode->input_state->caps;
      /* If existing caps are equal of the new state, keep the
       * existing state without renegotiating. */
      if (gst_caps_is_strictly_equal (curcaps, new_state->caps)) {
        GST_DEBUG ("Ignoring new caps %" GST_PTR_FORMAT
            " since are equal to current ones", new_state->caps);
        return FALSE;
      }
    }
    gst_video_codec_state_unref (decode->input_state);
  }

  if (new_state)
    decode->input_state = copy_video_codec_state (new_state);
  else
    decode->input_state = NULL;

  return TRUE;
}
GST_END_TEST
GST_START_TEST (caps_from_media)
{
  GstSDPMessage *message;
  glong length = -1;
  const GstSDPMedia *media1, *media2, *media3;
  GstCaps *caps_video1, *caps_video2, *caps_audio;
  GstCaps *result_video1, *result_video2, *result_audio;

  gst_sdp_message_new (&message);
  gst_sdp_message_parse_buffer ((guint8 *) sdp, length, message);

  media1 = gst_sdp_message_get_media (message, 0);
  fail_unless (media1 != NULL);

  media2 = gst_sdp_message_get_media (message, 1);
  fail_unless (media2 != NULL);

  media3 = gst_sdp_message_get_media (message, 2);
  fail_unless (media2 != NULL);

  caps_video1 = gst_sdp_media_get_caps_from_media (media1, 96);
  caps_video2 = gst_sdp_media_get_caps_from_media (media1, 97);
  caps_audio = gst_sdp_media_get_caps_from_media (media3, 14);

  result_video1 = gst_caps_from_string (caps_video_string1);
  fail_unless (gst_caps_is_strictly_equal (caps_video1, result_video1));
  gst_caps_unref (result_video1);
  gst_caps_unref (caps_video1);

  result_video2 = gst_caps_from_string (caps_video_string2);
  fail_unless (gst_caps_is_strictly_equal (caps_video2, result_video2));
  gst_caps_unref (result_video2);
  gst_caps_unref (caps_video2);

  result_audio = gst_caps_from_string (caps_audio_string);
  fail_unless (gst_caps_is_strictly_equal (caps_audio, result_audio));
  gst_caps_unref (result_audio);
  gst_caps_unref (caps_audio);

  gst_sdp_message_free (message);
}
GST_END_TEST
GST_START_TEST (caps_from_media_rtcp_fb_all)
{
  GstSDPMessage *message;
  glong length = -1;
  const GstSDPMedia *media1;
  GstCaps *caps1, *caps2, *caps3;
  GstCaps *result1, *result2, *result3;

  gst_sdp_message_new (&message);
  gst_sdp_message_parse_buffer ((guint8 *) sdp_rtcp_fb_all, length, message);

  media1 = gst_sdp_message_get_media (message, 0);
  fail_unless (media1 != NULL);

  caps1 = gst_sdp_media_get_caps_from_media (media1, 100);
  result1 = gst_caps_from_string (caps_video_rtcp_fb_all_pt_100);
  fail_unless (gst_caps_is_strictly_equal (caps1, result1));

  gst_caps_unref (result1);
  gst_caps_unref (caps1);

  caps2 = gst_sdp_media_get_caps_from_media (media1, 101);
  result2 = gst_caps_from_string (caps_video_rtcp_fb_all_pt_101);
  fail_unless (gst_caps_is_strictly_equal (caps2, result2));

  gst_caps_unref (result2);
  gst_caps_unref (caps2);

  caps3 = gst_sdp_media_get_caps_from_media (media1, 102);
  result3 = gst_caps_from_string (caps_video_rtcp_fb_all_pt_102);

  fail_unless (gst_caps_is_strictly_equal (caps3, result3));

  gst_caps_unref (result3);
  gst_caps_unref (caps3);

  gst_sdp_message_free (message);
}
static gboolean
ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo,
    GstCaps * caps)
{
  gboolean different_caps;
  GstVideoInfo vi;
  GstVaapiImageUsageFlags usage_flag =
      GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS;

  /* the received caps are the "allocation caps" which may be
   * different from the "negotiation caps". In this case, we should
   * indicate the allocator to store the negotiation caps since they
   * are the one should be used for frame mapping with GstVideoMeta */
  different_caps = GST_IS_VIDEO_DECODER (plugin) && plugin->srcpad_caps &&
      !gst_caps_is_strictly_equal (plugin->srcpad_caps, caps);

  if (different_caps) {
    vi = plugin->srcpad_info;
  } else {
    vi = *vinfo;
  }

  if (!reset_allocator (plugin->srcpad_allocator, &vi))
    return TRUE;

  plugin->srcpad_allocator = NULL;
  if (caps && gst_caps_is_video_raw (caps)) {
    if (plugin->srcpad_can_dmabuf) {
      if (GST_IS_VIDEO_DECODER (plugin) || GST_IS_BASE_TRANSFORM (plugin)) {
        plugin->srcpad_allocator =
            gst_vaapi_dmabuf_allocator_new (plugin->display, vinfo,
            get_dmabuf_surface_allocation_flags (), GST_PAD_SRC);
      }
    } else if (plugin->enable_direct_rendering) {
      usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER;
      GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator");
    }
  }

  if (!plugin->srcpad_allocator) {
    plugin->srcpad_allocator =
        gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag);
  }

  if (!plugin->srcpad_allocator)
    goto error_create_allocator;

  if (different_caps) {
    guint i, flags = 0;
    const GstVideoInfo *alloc_vi =
        gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, &flags);
    /* update the planes and the size with the allocator image info,
     * but not the resolution */
    if (alloc_vi) {
      for (i = 0; i < GST_VIDEO_INFO_N_PLANES (alloc_vi); i++) {
        GST_VIDEO_INFO_PLANE_OFFSET (&vi, i) =
            GST_VIDEO_INFO_PLANE_OFFSET (alloc_vi, i);
        GST_VIDEO_INFO_PLANE_STRIDE (&vi, i) =
            GST_VIDEO_INFO_PLANE_STRIDE (alloc_vi, i);
      }
      GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (alloc_vi);
      gst_allocator_set_vaapi_video_info (plugin->srcpad_allocator, &vi, flags);
    }
  }

  return TRUE;

  /* ERRORS */
error_create_allocator:
  {
    GST_ERROR_OBJECT (plugin, "failed to create src pad's allocator");
    return FALSE;
  }
}
static gboolean
ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo,
    GstCaps * caps)
{
  gboolean different_caps;
  const GstVideoInfo *image_info;
  GstVaapiImageUsageFlags usage_flag =
      GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS;

  if (!reset_allocator (plugin->srcpad_allocator, vinfo))
    goto valid_allocator;

  plugin->srcpad_allocator = NULL;
  if (caps && gst_caps_is_video_raw (caps)) {
    GstAllocator *allocator = create_dmabuf_srcpad_allocator (plugin, vinfo,
        !plugin->srcpad_can_dmabuf);
    if (!allocator && plugin->enable_direct_rendering) {
      usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER;
      GST_INFO_OBJECT (plugin, "enabling direct rendering in source allocator");
    }
    plugin->srcpad_allocator = allocator;
  } else if (caps && gst_vaapi_caps_feature_contains (caps,
          GST_VAAPI_CAPS_FEATURE_DMABUF)) {
    plugin->srcpad_allocator =
        create_dmabuf_srcpad_allocator (plugin, vinfo, FALSE);
    if (!plugin->srcpad_allocator)
      goto error_create_allocator;
  }

  if (!plugin->srcpad_allocator) {
    plugin->srcpad_allocator =
        gst_vaapi_video_allocator_new (plugin->display, vinfo, 0, usage_flag);
  }

  if (!plugin->srcpad_allocator)
    goto error_create_allocator;

valid_allocator:
  image_info =
      gst_allocator_get_vaapi_video_info (plugin->srcpad_allocator, NULL);
  g_assert (image_info);        /* both allocators ought set its image
                                 * info */

  /* update the size with the one generated by the allocator */
  GST_VIDEO_INFO_SIZE (vinfo) = GST_VIDEO_INFO_SIZE (image_info);

  /* the received caps are the "allocation caps" which may be
   * different from the "negotiation caps". In this case, we should
   * indicate the allocator to store the negotiation caps since they
   * are the one should be used for frame mapping with GstVideoMeta */
  different_caps = GST_IS_VIDEO_DECODER (plugin) && plugin->srcpad_caps &&
      !gst_caps_is_strictly_equal (plugin->srcpad_caps, caps);

  if (different_caps) {
    guint i;
    GstVideoInfo vi = plugin->srcpad_info;

    /* update the planes and the size with the allocator image/surface
     * info, but not the resolution */
    for (i = 0; i < GST_VIDEO_INFO_N_PLANES (image_info); i++) {
      GST_VIDEO_INFO_PLANE_OFFSET (&vi, i) =
          GST_VIDEO_INFO_PLANE_OFFSET (image_info, i);
      GST_VIDEO_INFO_PLANE_STRIDE (&vi, i) =
          GST_VIDEO_INFO_PLANE_STRIDE (image_info, i);
    }
    GST_VIDEO_INFO_SIZE (&vi) = GST_VIDEO_INFO_SIZE (image_info);
    gst_allocator_set_vaapi_negotiated_video_info (plugin->srcpad_allocator,
        &vi);
  }

  return TRUE;

  /* ERRORS */
error_create_allocator:
  {
    GST_ERROR_OBJECT (plugin, "failed to create src pad's allocator");
    return FALSE;
  }
}