webpenc: don't allow changing resolution in animation mode

- fails on image resolution changes in animation mode
- fails with a log message on invalid color spaces

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5994>
This commit is contained in:
Loïc Le Page 2024-01-25 20:06:46 +01:00 committed by GStreamer Marge Bot
parent 9fe504c423
commit 05bd35f625

View file

@ -190,11 +190,10 @@ gst_webp_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
{ {
GstWebpEnc *enc = GST_WEBP_ENC (encoder); GstWebpEnc *enc = GST_WEBP_ENC (encoder);
GstVideoCodecState *output_state; GstVideoCodecState *output_state;
GstVideoInfo *info; GstVideoInfo *info = &state->info;
GstVideoFormat format; GstVideoFormat format = GST_VIDEO_INFO_FORMAT (info);
gint width = GST_VIDEO_INFO_WIDTH (info);
info = &state->info; gint height = GST_VIDEO_INFO_HEIGHT (info);
format = GST_VIDEO_INFO_FORMAT (info);
if (GST_VIDEO_INFO_IS_YUV (info)) { if (GST_VIDEO_INFO_IS_YUV (info)) {
switch (format) { switch (format) {
@ -203,36 +202,51 @@ gst_webp_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
enc->webp_color_space = WEBP_YUV420; enc->webp_color_space = WEBP_YUV420;
break; break;
default: default:
break; GST_ERROR_OBJECT (enc, "Invalid color format");
return FALSE;
} }
} else { } else if (GST_VIDEO_INFO_IS_RGB (info)) {
if (GST_VIDEO_INFO_IS_RGB (info)) {
enc->rgb_format = format; enc->rgb_format = format;
enc->use_argb = 1; enc->use_argb = 1;
} } else {
GST_ERROR_OBJECT (enc, "Invalid color format");
return FALSE;
} }
if (enc->input_state) if (enc->input_state) {
gst_video_codec_state_unref (enc->input_state);
enc->input_state = gst_video_codec_state_ref (state);
if (enc->anim_enc) { if (enc->anim_enc) {
WebPAnimEncoderDelete (enc->anim_enc); gint prev_width = GST_VIDEO_INFO_WIDTH (&enc->input_state->info);
enc->anim_enc = NULL; gint prev_height = GST_VIDEO_INFO_HEIGHT (&enc->input_state->info);
if (prev_width != width || prev_height != height) {
GST_ERROR_OBJECT (enc, "Image size is changing in animation mode");
return FALSE;
}
} }
if (enc->animated) { gst_video_codec_state_unref (enc->input_state);
WebPAnimEncoderOptions enc_options = { 0 };
WebPAnimEncoderOptionsInit (&enc_options);
enc->anim_enc =
WebPAnimEncoderNew (info->width, info->height, &enc_options);
} }
enc->input_state = gst_video_codec_state_ref (state);
output_state = output_state =
gst_video_encoder_set_output_state (GST_VIDEO_ENCODER (enc), gst_video_encoder_set_output_state (GST_VIDEO_ENCODER (enc),
gst_caps_new_empty_simple ("image/webp"), enc->input_state); gst_caps_new_empty_simple ("image/webp"), enc->input_state);
gst_video_codec_state_unref (output_state); gst_video_codec_state_unref (output_state);
if (enc->animated && !enc->anim_enc) {
WebPAnimEncoderOptions enc_options = { 0 };
if (!WebPAnimEncoderOptionsInit (&enc_options)) {
GST_ERROR_OBJECT (enc, "Failed to initialize animation encoder options");
return FALSE;
}
enc->anim_enc = WebPAnimEncoderNew (width, height, &enc_options);
if (!enc->anim_enc) {
GST_ERROR_OBJECT (enc, "Failed to create the animation encoder");
return FALSE;
}
}
return TRUE; return TRUE;
} }