summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure2
-rw-r--r--libavcodec/librsvgdec.c81
2 files changed, 63 insertions, 20 deletions
diff --git a/configure b/configure
index 953104150f..edbd8bf021 100755
--- a/configure
+++ b/configure
@@ -6786,7 +6786,7 @@ enabled libpulse && require_pkg_config libpulse libpulse pulse/pulseaud
enabled librabbitmq && require_pkg_config librabbitmq "librabbitmq >= 0.7.1" amqp.h amqp_new_connection
enabled librav1e && require_pkg_config librav1e "rav1e >= 0.5.0" rav1e.h rav1e_context_new
enabled librist && require_pkg_config librist "librist >= 0.2.7" librist/librist.h rist_receiver_create
-enabled librsvg && require_pkg_config librsvg librsvg-2.0 librsvg-2.0/librsvg/rsvg.h rsvg_handle_render_cairo
+enabled librsvg && require_pkg_config librsvg librsvg-2.0 librsvg-2.0/librsvg/rsvg.h rsvg_handle_new_from_data
enabled librtmp && require_pkg_config librtmp librtmp librtmp/rtmp.h RTMP_Socket
enabled librubberband && require_pkg_config librubberband "rubberband >= 1.8.1" rubberband/rubberband-c.h rubberband_new -lstdc++ && append librubberband_extralibs "-lstdc++"
enabled libshaderc && require_pkg_config spirv_compiler "shaderc >= 2019.1" shaderc/shaderc.h shaderc_compiler_initialize
diff --git a/libavcodec/librsvgdec.c b/libavcodec/librsvgdec.c
index 2f160edcdf..c328fbc774 100644
--- a/libavcodec/librsvgdec.c
+++ b/libavcodec/librsvgdec.c
@@ -38,48 +38,75 @@ static int librsvg_decode_frame(AVCodecContext *avctx, AVFrame *frame,
{
int ret;
LibRSVGContext *s = avctx->priv_data;
-
- RsvgHandle *handle;
- RsvgDimensionData unscaled_dimensions, dimensions;
- cairo_surface_t *image;
+ RsvgHandle *handle = NULL;
+ RsvgDimensionData dimensions;
+#if LIBRSVG_MAJOR_VERSION > 2 || LIBRSVG_MAJOR_VERSION == 2 && LIBRSVG_MINOR_VERSION >= 52
+ RsvgRectangle viewport = { 0 };
+#else
+ RsvgDimensionData unscaled_dimensions;
+#endif
+ cairo_surface_t *image = NULL;
cairo_t *crender = NULL;
GError *error = NULL;
+ gboolean gret;
*got_frame = 0;
handle = rsvg_handle_new_from_data(pkt->data, pkt->size, &error);
if (error) {
- av_log(avctx, AV_LOG_ERROR, "Error parsing svg!\n");
- g_error_free(error);
- return AVERROR_INVALIDDATA;
+ av_log(avctx, AV_LOG_ERROR, "Error parsing svg: %s\n", error->message);
+ ret = AVERROR_INVALIDDATA;
+ goto end;
}
+#if LIBRSVG_MAJOR_VERSION > 2 || LIBRSVG_MAJOR_VERSION == 2 && LIBRSVG_MINOR_VERSION >= 52
+ gret = rsvg_handle_get_intrinsic_size_in_pixels(handle, &viewport.width, &viewport.height);
+ if (!gret) {
+ viewport.width = s->width ? s->width : 100;
+ viewport.height = s->height ? s->height : 100;
+ }
+ dimensions.width = (int)viewport.width;
+ dimensions.height = (int)viewport.height;
+#else
rsvg_handle_get_dimensions(handle, &dimensions);
rsvg_handle_get_dimensions(handle, &unscaled_dimensions);
+#endif
dimensions.width = s->width ? s->width : dimensions.width;
dimensions.height = s->height ? s->height : dimensions.height;
if (s->keep_ar && (s->width || s->height)) {
+#if LIBRSVG_MAJOR_VERSION > 2 || LIBRSVG_MAJOR_VERSION == 2 && LIBRSVG_MINOR_VERSION >= 52
+ double default_ar = viewport.width / viewport.height;
+#else
double default_ar = unscaled_dimensions.width/(double)unscaled_dimensions.height;
+#endif
if (!s->width)
dimensions.width = lrintf(dimensions.height * default_ar);
else
dimensions.height = lrintf(dimensions.width / default_ar);
}
- if ((ret = ff_set_dimensions(avctx, dimensions.width, dimensions.height)))
- return ret;
+ ret = ff_set_dimensions(avctx, dimensions.width, dimensions.height);
+ if (ret < 0)
+ goto end;
+
avctx->pix_fmt = AV_PIX_FMT_RGB32;
+ viewport.width = dimensions.width;
+ viewport.height = dimensions.height;
+
+ ret = ff_get_buffer(avctx, frame, 0);
+ if (ret < 0)
+ goto end;
- if ((ret = ff_get_buffer(avctx, frame, 0)))
- return ret;
frame->pict_type = AV_PICTURE_TYPE_I;
frame->flags |= AV_FRAME_FLAG_KEY;
image = cairo_image_surface_create_for_data(frame->data[0], CAIRO_FORMAT_ARGB32,
frame->width, frame->height,
frame->linesize[0]);
- if (cairo_surface_status(image) != CAIRO_STATUS_SUCCESS)
- return AVERROR_INVALIDDATA;
+ if (cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) {
+ ret = AVERROR_EXTERNAL;
+ goto end;
+ }
crender = cairo_create(image);
@@ -88,18 +115,34 @@ static int librsvg_decode_frame(AVCodecContext *avctx, AVFrame *frame,
cairo_paint(crender);
cairo_restore(crender);
+#if LIBRSVG_MAJOR_VERSION > 2 || LIBRSVG_MAJOR_VERSION == 2 && LIBRSVG_MINOR_VERSION >= 52
+ gret = rsvg_handle_render_document(handle, crender, &viewport, &error);
+#else
cairo_scale(crender, dimensions.width / (double)unscaled_dimensions.width,
dimensions.height / (double)unscaled_dimensions.height);
+ gret = rsvg_handle_render_cairo(handle, crender);
+#endif
- rsvg_handle_render_cairo(handle, crender);
-
- cairo_destroy(crender);
- cairo_surface_destroy(image);
- g_object_unref(handle);
+ if (!gret) {
+ av_log(avctx, AV_LOG_ERROR, "Error rendering svg: %s\n", error ? error->message : "unknown error");
+ ret = AVERROR_EXTERNAL;
+ goto end;
+ }
*got_frame = 1;
+ ret = 0;
- return 0;
+end:
+ if (error)
+ g_error_free(error);
+ if (handle)
+ g_object_unref(handle);
+ if (crender)
+ cairo_destroy(crender);
+ if (image)
+ cairo_surface_destroy(image);
+
+ return ret;
}
#define OFFSET(x) offsetof(LibRSVGContext, x)