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