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:
parent
c5733c84b1
commit
fb0bea8fef
@ -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 *
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user