y4menc: create an output video info without padding

The unpadded strides and offsets calculations for the video info are inspired
from y4mdec.

A boolean flags is toggled if the video info is padded for the given resolution.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8654>
This commit is contained in:
Víctor Manuel Jáquez Leal 2025-03-27 12:46:54 +01:00
parent c5733c84b1
commit fb0bea8fef
2 changed files with 51 additions and 3 deletions

View File

@ -122,6 +122,7 @@ static void
gst_y4m_encode_reset (GstY4mEncode * filter) gst_y4m_encode_reset (GstY4mEncode * filter)
{ {
filter->header = FALSE; filter->header = FALSE;
gst_video_info_init (&filter->info);
} }
static gboolean static gboolean
@ -129,30 +130,74 @@ gst_y4m_encode_set_format (GstVideoEncoder * encoder,
GstVideoCodecState * state) GstVideoCodecState * state)
{ {
GstY4mEncode *y4menc; GstY4mEncode *y4menc;
GstVideoInfo *info; GstVideoInfo *info, out_info;
GstVideoCodecState *output_state; GstVideoCodecState *output_state;
gint width, height;
GstVideoFormat format;
gsize cr_h;
y4menc = GST_Y4M_ENCODE (encoder); y4menc = GST_Y4M_ENCODE (encoder);
info = &state->info; info = &state->info;
switch (GST_VIDEO_INFO_FORMAT (info)) { format = GST_VIDEO_INFO_FORMAT (info);
width = GST_VIDEO_INFO_WIDTH (info);
height = GST_VIDEO_INFO_HEIGHT (info);
gst_video_info_set_format (&out_info, format, width, height);
switch (format) {
case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_I420:
y4menc->colorspace = "420"; y4menc->colorspace = "420";
out_info.stride[0] = width;
out_info.stride[1] = GST_ROUND_UP_2 (width) / 2;
out_info.stride[2] = out_info.stride[1];
out_info.offset[0] = 0;
out_info.offset[1] = out_info.stride[0] * height;
cr_h = GST_ROUND_UP_2 (height) / 2;
if (GST_VIDEO_INFO_IS_INTERLACED (info))
cr_h = GST_ROUND_UP_2 (height);
out_info.offset[2] = out_info.offset[1] + out_info.stride[1] * cr_h;
out_info.size = out_info.offset[2] + out_info.stride[2] * cr_h;
break; break;
case GST_VIDEO_FORMAT_Y42B: case GST_VIDEO_FORMAT_Y42B:
y4menc->colorspace = "422"; y4menc->colorspace = "422";
out_info.stride[0] = width;
out_info.stride[1] = GST_ROUND_UP_2 (width) / 2;
out_info.stride[2] = out_info.stride[1];
out_info.offset[0] = 0;
out_info.offset[1] = out_info.stride[0] * height;
out_info.offset[2] = out_info.offset[1] + out_info.stride[1] * height;
/* simplification of ROUNDUP4(w)*h + 2*(ROUNDUP8(w)/2)*h */
out_info.size = out_info.offset[2] + out_info.stride[2] * height;
break; break;
case GST_VIDEO_FORMAT_Y41B: case GST_VIDEO_FORMAT_Y41B:
y4menc->colorspace = "411"; y4menc->colorspace = "411";
info->stride[0] = width;
info->stride[1] = GST_ROUND_UP_2 (width) / 4;
info->stride[2] = out_info.stride[1];
info->offset[0] = 0;
info->offset[1] = info->stride[0] * height;
info->offset[2] = info->offset[1] + info->stride[1] * height;
/* simplification of ROUNDUP4(w)*h + 2*((ROUNDUP16(w)/4)*h */
info->size = (width + (GST_ROUND_UP_2 (width) / 2)) * height;
break; break;
case GST_VIDEO_FORMAT_Y444: case GST_VIDEO_FORMAT_Y444:
y4menc->colorspace = "444"; y4menc->colorspace = "444";
out_info.stride[0] = width;
out_info.stride[1] = out_info.stride[0];
out_info.stride[2] = out_info.stride[0];
out_info.offset[0] = 0;
out_info.offset[1] = out_info.stride[0] * height;
out_info.offset[2] = out_info.offset[1] * 2;
out_info.size = out_info.stride[0] * height * 3;
break; break;
default: default:
goto invalid_format; goto invalid_format;
} }
y4menc->info = *info; y4menc->info = *info;
y4menc->out_info = out_info;
y4menc->padded = !gst_video_info_is_equal (info, &out_info);
output_state = output_state =
gst_video_encoder_set_output_state (encoder, gst_video_encoder_set_output_state (encoder,
@ -166,7 +211,6 @@ invalid_format:
GST_ERROR_OBJECT (y4menc, "Invalid format"); GST_ERROR_OBJECT (y4menc, "Invalid format");
return FALSE; return FALSE;
} }
} }
static inline GstBuffer * static inline GstBuffer *

View File

@ -48,9 +48,13 @@ struct _GstY4mEncode {
/* caps information */ /* caps information */
GstVideoInfo info; GstVideoInfo info;
/* output buffer layout */
GstVideoInfo out_info;
const gchar *colorspace; const gchar *colorspace;
/* state information */ /* state information */
gboolean header; gboolean header;
gboolean padded;
}; };
struct _GstY4mEncodeClass { struct _GstY4mEncodeClass {