y4m: share common code among encoder and decoder
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8719>
This commit is contained in:
parent
6bcf0e3276
commit
4cf598bcf3
@ -37,6 +37,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "gsty4mdec.h"
|
#include "gsty4mdec.h"
|
||||||
|
#include "gsty4mformat.h"
|
||||||
|
|
||||||
#define MAX_SIZE 32768
|
#define MAX_SIZE 32768
|
||||||
|
|
||||||
@ -387,6 +388,7 @@ gst_y4m_dec_parse_header (GstY4mDec * y4mdec, char *header)
|
|||||||
gulong par_n = 0, par_d = 0;
|
gulong par_n = 0, par_d = 0;
|
||||||
gulong width = 0, height = 0;
|
gulong width = 0, height = 0;
|
||||||
GstVideoFormat format = GST_VIDEO_FORMAT_I420;
|
GstVideoFormat format = GST_VIDEO_FORMAT_I420;
|
||||||
|
GstVideoInterlaceMode interlace_mode;
|
||||||
|
|
||||||
if (memcmp (header, "YUV4MPEG2 ", 10) != 0) {
|
if (memcmp (header, "YUV4MPEG2 ", 10) != 0) {
|
||||||
GST_ERROR_OBJECT (y4mdec, "y4m start code not found");
|
GST_ERROR_OBJECT (y4mdec, "y4m start code not found");
|
||||||
@ -458,59 +460,15 @@ gst_y4m_dec_parse_header (GstY4mDec * y4mdec, char *header)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_video_info_init (&y4mdec->info);
|
|
||||||
gst_video_info_set_format (&y4mdec->out_info, format, width, height);
|
|
||||||
y4mdec->info = y4mdec->out_info;
|
|
||||||
|
|
||||||
switch (y4mdec->info.finfo->format) {
|
|
||||||
case GST_VIDEO_FORMAT_I420:
|
|
||||||
y4mdec->info.offset[0] = 0;
|
|
||||||
y4mdec->info.stride[0] = width;
|
|
||||||
y4mdec->info.offset[1] = y4mdec->info.stride[0] * height;
|
|
||||||
y4mdec->info.stride[1] = GST_ROUND_UP_2 (width) / 2;
|
|
||||||
y4mdec->info.offset[2] =
|
|
||||||
y4mdec->info.offset[1] +
|
|
||||||
y4mdec->info.stride[1] * (GST_ROUND_UP_2 (height) / 2);
|
|
||||||
y4mdec->info.stride[2] = GST_ROUND_UP_2 (width) / 2;
|
|
||||||
y4mdec->info.size =
|
|
||||||
y4mdec->info.offset[2] +
|
|
||||||
y4mdec->info.stride[2] * (GST_ROUND_UP_2 (height) / 2);
|
|
||||||
break;
|
|
||||||
case GST_VIDEO_FORMAT_Y42B:
|
|
||||||
y4mdec->info.offset[0] = 0;
|
|
||||||
y4mdec->info.stride[0] = width;
|
|
||||||
y4mdec->info.offset[1] = y4mdec->info.stride[0] * height;
|
|
||||||
y4mdec->info.stride[1] = GST_ROUND_UP_2 (width) / 2;
|
|
||||||
y4mdec->info.offset[2] =
|
|
||||||
y4mdec->info.offset[1] + y4mdec->info.stride[1] * height;
|
|
||||||
y4mdec->info.stride[2] = GST_ROUND_UP_2 (width) / 2;
|
|
||||||
y4mdec->info.size =
|
|
||||||
y4mdec->info.offset[2] + y4mdec->info.stride[2] * height;
|
|
||||||
break;
|
|
||||||
case GST_VIDEO_FORMAT_Y444:
|
|
||||||
y4mdec->info.offset[0] = 0;
|
|
||||||
y4mdec->info.stride[0] = width;
|
|
||||||
y4mdec->info.offset[1] = y4mdec->info.stride[0] * height;
|
|
||||||
y4mdec->info.stride[1] = width;
|
|
||||||
y4mdec->info.offset[2] =
|
|
||||||
y4mdec->info.offset[1] + y4mdec->info.stride[1] * height;
|
|
||||||
y4mdec->info.stride[2] = width;
|
|
||||||
y4mdec->info.size =
|
|
||||||
y4mdec->info.offset[2] + y4mdec->info.stride[2] * height;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (interlaced_char) {
|
switch (interlaced_char) {
|
||||||
case 0:
|
case 0:
|
||||||
case '?':
|
case '?':
|
||||||
case 'p':
|
case 'p':
|
||||||
y4mdec->info.interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
|
interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
case 'b':
|
case 'b':
|
||||||
y4mdec->info.interlace_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
|
interlace_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GST_ERROR_OBJECT (y4mdec, "Unknown interlaced char '%c'",
|
GST_ERROR_OBJECT (y4mdec, "Unknown interlaced char '%c'",
|
||||||
@ -528,10 +486,17 @@ gst_y4m_dec_parse_header (GstY4mDec * y4mdec, char *header)
|
|||||||
if (par_d == 0)
|
if (par_d == 0)
|
||||||
par_d = 1;
|
par_d = 1;
|
||||||
|
|
||||||
y4mdec->info.fps_n = fps_n;
|
gst_video_info_set_interlaced_format (&y4mdec->out_info, format,
|
||||||
y4mdec->info.fps_d = fps_d;
|
interlace_mode, width, height);
|
||||||
y4mdec->info.par_n = par_n;
|
|
||||||
y4mdec->info.par_d = par_d;
|
GST_VIDEO_INFO_FPS_N (&y4mdec->out_info) = fps_n;
|
||||||
|
GST_VIDEO_INFO_FPS_D (&y4mdec->out_info) = fps_d;
|
||||||
|
GST_VIDEO_INFO_PAR_N (&y4mdec->out_info) = par_n;
|
||||||
|
GST_VIDEO_INFO_PAR_D (&y4mdec->out_info) = par_d;
|
||||||
|
|
||||||
|
if (!gst_y4m_video_unpadded_info (&y4mdec->info, &y4mdec->out_info))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "gsty4menc.h"
|
#include "gsty4menc.h"
|
||||||
|
#include "gsty4mformat.h"
|
||||||
|
|
||||||
/* Filter signals and args */
|
/* Filter signals and args */
|
||||||
enum
|
enum
|
||||||
@ -139,69 +140,30 @@ gst_y4m_encode_set_format (GstVideoEncoder * encoder,
|
|||||||
GstY4mEncode *y4menc;
|
GstY4mEncode *y4menc;
|
||||||
GstVideoInfo *info, out_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;
|
||||||
|
|
||||||
format = GST_VIDEO_INFO_FORMAT (info);
|
switch (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";
|
||||||
out_info.stride[0] = width;
|
|
||||||
out_info.stride[1] = GST_ROUND_UP_2 (width) / 4;
|
|
||||||
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*((ROUNDUP16(w)/4)*h */
|
|
||||||
out_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gst_y4m_video_unpadded_info (&out_info, info))
|
||||||
|
goto invalid_format;
|
||||||
|
|
||||||
y4menc->info = *info;
|
y4menc->info = *info;
|
||||||
y4menc->out_info = out_info;
|
y4menc->out_info = out_info;
|
||||||
y4menc->padded = !gst_video_info_is_equal (info, &out_info);
|
y4menc->padded = !gst_video_info_is_equal (info, &out_info);
|
||||||
|
93
subprojects/gst-plugins-good/gst/y4m/gsty4mformat.c
Normal file
93
subprojects/gst-plugins-good/gst/y4m/gsty4mformat.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2025 Igalia, S.L.
|
||||||
|
* Author: Victor Jaquez <vjaquez@igalia.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gsty4mformat.h"
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_y4m_video_unpadded_info (GstVideoInfo * y4m_info,
|
||||||
|
const GstVideoInfo * vinfo)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (y4m_info && vinfo, FALSE);
|
||||||
|
|
||||||
|
gsize cr_h;
|
||||||
|
guint width, height;
|
||||||
|
GstVideoFormat format;
|
||||||
|
GstVideoInfo out_info;
|
||||||
|
|
||||||
|
format = GST_VIDEO_INFO_FORMAT (vinfo);
|
||||||
|
width = GST_VIDEO_INFO_WIDTH (vinfo);
|
||||||
|
height = GST_VIDEO_INFO_HEIGHT (vinfo);
|
||||||
|
|
||||||
|
out_info = *vinfo;
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case GST_VIDEO_FORMAT_I420:
|
||||||
|
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 (vinfo))
|
||||||
|
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;
|
||||||
|
case GST_VIDEO_FORMAT_Y42B:
|
||||||
|
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;
|
||||||
|
case GST_VIDEO_FORMAT_Y41B:
|
||||||
|
out_info.stride[0] = width;
|
||||||
|
out_info.stride[1] = GST_ROUND_UP_2 (width) / 4;
|
||||||
|
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*((ROUNDUP16(w)/4)*h */
|
||||||
|
out_info.size = (width + (GST_ROUND_UP_2 (width) / 2)) * height;
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_FORMAT_Y444:
|
||||||
|
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;
|
||||||
|
default:
|
||||||
|
GST_FIXME ("%s is not supported", gst_video_format_to_string (format));
|
||||||
|
}
|
||||||
|
|
||||||
|
*y4m_info = out_info;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
27
subprojects/gst-plugins-good/gst/y4m/gsty4mformat.h
Normal file
27
subprojects/gst-plugins-good/gst/y4m/gsty4mformat.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2025 Igalia, S.L.
|
||||||
|
* Author: Victor Jaquez <vjaquez@igalia.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
|
gboolean gst_y4m_video_unpadded_info (GstVideoInfo * y4m_info,
|
||||||
|
const GstVideoInfo * vinfo);
|
@ -1,5 +1,6 @@
|
|||||||
y4m_sources = [
|
y4m_sources = [
|
||||||
'plugin.c',
|
'plugin.c',
|
||||||
|
'gsty4mformat.c',
|
||||||
'gsty4menc.c',
|
'gsty4menc.c',
|
||||||
'gsty4mdec.c'
|
'gsty4mdec.c'
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user