mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-08 21:28:45 +00:00
[MOVED FROM BAD 50/56] deinterlace2: Rename line_length to row_stride and remove output_stride
This commit is contained in:
parent
3354937f05
commit
b9659ac68b
9 changed files with 58 additions and 58 deletions
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* GStreamer
|
* GStreamer
|
||||||
* Copyright (C) 2005 Martin Eikermann <meiker@upb.de>
|
* Copyright (C) 2005 Martin Eikermann <meiker@upb.de>
|
||||||
* Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
|
* Copyright (C) 2008-2009 Sebastian Dröge <slomo@collabora.co.uk>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -104,7 +104,7 @@ gst_deinterlace_simple_method_interpolate_scanline (GstDeinterlaceMethod * self,
|
||||||
GstDeinterlace2 * parent, guint8 * out,
|
GstDeinterlace2 * parent, guint8 * out,
|
||||||
GstDeinterlaceScanlineData * scanlines, gint width)
|
GstDeinterlaceScanlineData * scanlines, gint width)
|
||||||
{
|
{
|
||||||
oil_memcpy (out, scanlines->m1, parent->line_length);
|
oil_memcpy (out, scanlines->m1, parent->row_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -112,7 +112,7 @@ gst_deinterlace_simple_method_copy_scanline (GstDeinterlaceMethod * self,
|
||||||
GstDeinterlace2 * parent, guint8 * out,
|
GstDeinterlace2 * parent, guint8 * out,
|
||||||
GstDeinterlaceScanlineData * scanlines, gint width)
|
GstDeinterlaceScanlineData * scanlines, gint width)
|
||||||
{
|
{
|
||||||
oil_memcpy (out, scanlines->m0, parent->line_length);
|
oil_memcpy (out, scanlines->m0, parent->row_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -143,12 +143,12 @@ gst_deinterlace_simple_method_deinterlace_frame (GstDeinterlaceMethod * self,
|
||||||
|
|
||||||
if (cur_field_flags == PICTURE_INTERLACED_BOTTOM) {
|
if (cur_field_flags == PICTURE_INTERLACED_BOTTOM) {
|
||||||
/* double the first scanline of the bottom field */
|
/* double the first scanline of the bottom field */
|
||||||
oil_memcpy (out, field0, parent->line_length);
|
oil_memcpy (out, field0, parent->row_stride);
|
||||||
out += parent->output_stride;
|
out += parent->row_stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
oil_memcpy (out, field0, parent->line_length);
|
oil_memcpy (out, field0, parent->row_stride);
|
||||||
out += parent->output_stride;
|
out += parent->row_stride;
|
||||||
|
|
||||||
for (line = 2; line <= parent->field_height; line++) {
|
for (line = 2; line <= parent->field_height; line++) {
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ gst_deinterlace_simple_method_deinterlace_frame (GstDeinterlaceMethod * self,
|
||||||
|
|
||||||
dsm_class->interpolate_scanline (self, parent, out, &scanlines,
|
dsm_class->interpolate_scanline (self, parent, out, &scanlines,
|
||||||
parent->frame_width);
|
parent->frame_width);
|
||||||
out += parent->output_stride;
|
out += parent->row_stride;
|
||||||
|
|
||||||
memset (&scanlines, 0, sizeof (scanlines));
|
memset (&scanlines, 0, sizeof (scanlines));
|
||||||
scanlines.bottom_field = (cur_field_flags == PICTURE_INTERLACED_BOTTOM);
|
scanlines.bottom_field = (cur_field_flags == PICTURE_INTERLACED_BOTTOM);
|
||||||
|
@ -227,12 +227,12 @@ gst_deinterlace_simple_method_deinterlace_frame (GstDeinterlaceMethod * self,
|
||||||
|
|
||||||
dsm_class->copy_scanline (self, parent, out, &scanlines,
|
dsm_class->copy_scanline (self, parent, out, &scanlines,
|
||||||
parent->frame_width);
|
parent->frame_width);
|
||||||
out += parent->output_stride;
|
out += parent->row_stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_field_flags == PICTURE_INTERLACED_TOP) {
|
if (cur_field_flags == PICTURE_INTERLACED_TOP) {
|
||||||
/* double the last scanline of the top field */
|
/* double the last scanline of the top field */
|
||||||
oil_memcpy (out, field0, parent->line_length);
|
oil_memcpy (out, field0, parent->row_stride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,8 +570,7 @@ gst_deinterlace2_reset_history (GstDeinterlace2 * self)
|
||||||
static void
|
static void
|
||||||
gst_deinterlace2_reset (GstDeinterlace2 * self)
|
gst_deinterlace2_reset (GstDeinterlace2 * self)
|
||||||
{
|
{
|
||||||
self->output_stride = 0;
|
self->row_stride = 0;
|
||||||
self->line_length = 0;
|
|
||||||
self->frame_width = 0;
|
self->frame_width = 0;
|
||||||
self->frame_height = 0;
|
self->frame_height = 0;
|
||||||
self->frame_rate_n = 0;
|
self->frame_rate_n = 0;
|
||||||
|
@ -719,13 +718,13 @@ gst_deinterlace2_push_history (GstDeinterlace2 * self, GstBuffer * buffer)
|
||||||
GST_DEBUG ("Top field first");
|
GST_DEBUG ("Top field first");
|
||||||
field1 = gst_buffer_ref (buffer);
|
field1 = gst_buffer_ref (buffer);
|
||||||
field1_flags = PICTURE_INTERLACED_TOP;
|
field1_flags = PICTURE_INTERLACED_TOP;
|
||||||
field2 = gst_buffer_create_sub (buffer, self->line_length,
|
field2 = gst_buffer_create_sub (buffer, self->row_stride,
|
||||||
GST_BUFFER_SIZE (buffer) - self->line_length);
|
GST_BUFFER_SIZE (buffer) - self->row_stride);
|
||||||
field2_flags = PICTURE_INTERLACED_BOTTOM;
|
field2_flags = PICTURE_INTERLACED_BOTTOM;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG ("Bottom field first");
|
GST_DEBUG ("Bottom field first");
|
||||||
field1 = gst_buffer_create_sub (buffer, self->line_length,
|
field1 = gst_buffer_create_sub (buffer, self->row_stride,
|
||||||
GST_BUFFER_SIZE (buffer) - self->line_length);
|
GST_BUFFER_SIZE (buffer) - self->row_stride);
|
||||||
field1_flags = PICTURE_INTERLACED_BOTTOM;
|
field1_flags = PICTURE_INTERLACED_BOTTOM;
|
||||||
field2 = gst_buffer_ref (buffer);
|
field2 = gst_buffer_ref (buffer);
|
||||||
field2_flags = PICTURE_INTERLACED_TOP;
|
field2_flags = PICTURE_INTERLACED_TOP;
|
||||||
|
@ -1132,7 +1131,6 @@ gst_deinterlace2_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
goto caps_not_accepted;
|
goto caps_not_accepted;
|
||||||
gst_caps_unref (othercaps);
|
gst_caps_unref (othercaps);
|
||||||
|
|
||||||
/* TODO: introduce self->field_stride */
|
|
||||||
self->field_height = self->frame_height / 2;
|
self->field_height = self->frame_height / 2;
|
||||||
|
|
||||||
fmt = gst_video_format_from_fourcc (fourcc);
|
fmt = gst_video_format_from_fourcc (fourcc);
|
||||||
|
@ -1141,11 +1139,9 @@ gst_deinterlace2_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
change when the buffer-fields concept has landed */
|
change when the buffer-fields concept has landed */
|
||||||
self->field_stride =
|
self->field_stride =
|
||||||
gst_video_format_get_row_stride (fmt, 0, self->frame_width) * 2;
|
gst_video_format_get_row_stride (fmt, 0, self->frame_width) * 2;
|
||||||
self->output_stride =
|
|
||||||
gst_video_format_get_row_stride (fmt, 0, self->frame_width);
|
|
||||||
|
|
||||||
/* in bytes */
|
/* in bytes */
|
||||||
self->line_length =
|
self->row_stride =
|
||||||
gst_video_format_get_row_stride (fmt, 0, self->frame_width);
|
gst_video_format_get_row_stride (fmt, 0, self->frame_width);
|
||||||
self->frame_size =
|
self->frame_size =
|
||||||
gst_video_format_get_size (fmt, self->frame_width, self->frame_height);
|
gst_video_format_get_size (fmt, self->frame_width, self->frame_height);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* GStreamer
|
* GStreamer
|
||||||
* Copyright (C) 2005 Martin Eikermann <meiker@upb.de>
|
* Copyright (C) 2005 Martin Eikermann <meiker@upb.de>
|
||||||
* Copyright (C) 2008 Sebastian Dröge <slomo@collabora.co.uk>
|
* Copyright (C) 2008-2009 Sebastian Dröge <slomo@collabora.co.uk>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -187,12 +187,19 @@ typedef enum
|
||||||
GST_DEINTERLACE2_LAYOUT_BFF
|
GST_DEINTERLACE2_LAYOUT_BFF
|
||||||
} GstDeinterlace2FieldLayout;
|
} GstDeinterlace2FieldLayout;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GST_DEINTERLACE2_MODE_AUTO,
|
||||||
|
GST_DEINTERLACE2_MODE_INTERLACED
|
||||||
|
} GstDeinterlace2Mode;
|
||||||
|
|
||||||
struct _GstDeinterlace2
|
struct _GstDeinterlace2
|
||||||
{
|
{
|
||||||
GstElement parent;
|
GstElement parent;
|
||||||
|
|
||||||
GstPad *srcpad, *sinkpad;
|
GstPad *srcpad, *sinkpad;
|
||||||
|
|
||||||
|
GstDeinterlace2Mode mode;
|
||||||
|
|
||||||
GstDeinterlace2FieldLayout field_layout;
|
GstDeinterlace2FieldLayout field_layout;
|
||||||
|
|
||||||
guint frame_size;
|
guint frame_size;
|
||||||
|
@ -215,14 +222,11 @@ struct _GstDeinterlace2
|
||||||
GstPicture field_history[MAX_FIELD_HISTORY];
|
GstPicture field_history[MAX_FIELD_HISTORY];
|
||||||
guint history_count;
|
guint history_count;
|
||||||
|
|
||||||
/* Overlay pitch (number of bytes between scanlines). */
|
|
||||||
guint output_stride;
|
|
||||||
|
|
||||||
/* Number of bytes of actual data in each scanline. May be less than
|
/* Number of bytes of actual data in each scanline. May be less than
|
||||||
OverlayPitch since the overlay's scanlines might have alignment
|
OverlayPitch since the overlay's scanlines might have alignment
|
||||||
requirements. Generally equal to FrameWidth * 2.
|
requirements. Generally equal to FrameWidth * 2.
|
||||||
*/
|
*/
|
||||||
guint line_length;
|
guint row_stride;
|
||||||
|
|
||||||
/* Number of pixels in each scanline. */
|
/* Number of pixels in each scanline. */
|
||||||
gint frame_width;
|
gint frame_width;
|
||||||
|
|
|
@ -365,8 +365,8 @@ deinterlace_frame_di_greedy (GstDeinterlaceMethod * d_method,
|
||||||
GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf);
|
GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf);
|
||||||
|
|
||||||
// copy first even line
|
// copy first even line
|
||||||
oil_memcpy (Dest, L1, object->line_length);
|
oil_memcpy (Dest, L1, object->row_stride);
|
||||||
Dest += object->output_stride;
|
Dest += object->row_stride;
|
||||||
} else {
|
} else {
|
||||||
InfoIsOdd = 0;
|
InfoIsOdd = 0;
|
||||||
L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
|
L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
|
||||||
|
@ -379,18 +379,18 @@ deinterlace_frame_di_greedy (GstDeinterlaceMethod * d_method,
|
||||||
|
|
||||||
// copy first even line
|
// copy first even line
|
||||||
oil_memcpy (Dest, GST_BUFFER_DATA (object->field_history[0].buf),
|
oil_memcpy (Dest, GST_BUFFER_DATA (object->field_history[0].buf),
|
||||||
object->line_length);
|
object->row_stride);
|
||||||
Dest += object->output_stride;
|
Dest += object->row_stride;
|
||||||
// then first odd line
|
// then first odd line
|
||||||
oil_memcpy (Dest, L1, object->line_length);
|
oil_memcpy (Dest, L1, object->row_stride);
|
||||||
Dest += object->output_stride;
|
Dest += object->row_stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Line = 0; Line < (object->field_height - 1); ++Line) {
|
for (Line = 0; Line < (object->field_height - 1); ++Line) {
|
||||||
klass->scanline (self, L2, L1, L3, L2P, Dest, object->line_length);
|
klass->scanline (self, L2, L1, L3, L2P, Dest, object->row_stride);
|
||||||
Dest += object->output_stride;
|
Dest += object->row_stride;
|
||||||
oil_memcpy (Dest, L3, object->line_length);
|
oil_memcpy (Dest, L3, object->row_stride);
|
||||||
Dest += object->output_stride;
|
Dest += object->row_stride;
|
||||||
|
|
||||||
L1 += Pitch;
|
L1 += Pitch;
|
||||||
L2 += Pitch;
|
L2 += Pitch;
|
||||||
|
@ -399,7 +399,7 @@ deinterlace_frame_di_greedy (GstDeinterlaceMethod * d_method,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InfoIsOdd) {
|
if (InfoIsOdd) {
|
||||||
oil_memcpy (Dest, L2, object->line_length);
|
oil_memcpy (Dest, L2, object->row_stride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -266,8 +266,8 @@ deinterlace_frame_di_greedyh (GstDeinterlaceMethod * d_method,
|
||||||
GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf);
|
GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf);
|
||||||
|
|
||||||
// copy first even line
|
// copy first even line
|
||||||
oil_memcpy (Dest, L1, object->line_length);
|
oil_memcpy (Dest, L1, object->row_stride);
|
||||||
Dest += object->output_stride;
|
Dest += object->row_stride;
|
||||||
} else {
|
} else {
|
||||||
InfoIsOdd = 0;
|
InfoIsOdd = 0;
|
||||||
L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
|
L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
|
||||||
|
@ -280,18 +280,18 @@ deinterlace_frame_di_greedyh (GstDeinterlaceMethod * d_method,
|
||||||
|
|
||||||
// copy first even line
|
// copy first even line
|
||||||
oil_memcpy (Dest, GST_BUFFER_DATA (object->field_history[0].buf),
|
oil_memcpy (Dest, GST_BUFFER_DATA (object->field_history[0].buf),
|
||||||
object->line_length);
|
object->row_stride);
|
||||||
Dest += object->output_stride;
|
Dest += object->row_stride;
|
||||||
// then first odd line
|
// then first odd line
|
||||||
oil_memcpy (Dest, L1, object->line_length);
|
oil_memcpy (Dest, L1, object->row_stride);
|
||||||
Dest += object->output_stride;
|
Dest += object->row_stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Line = 0; Line < (object->field_height - 1); ++Line) {
|
for (Line = 0; Line < (object->field_height - 1); ++Line) {
|
||||||
klass->scanline (self, L1, L2, L3, L2P, Dest, object->line_length);
|
klass->scanline (self, L1, L2, L3, L2P, Dest, object->row_stride);
|
||||||
Dest += object->output_stride;
|
Dest += object->row_stride;
|
||||||
oil_memcpy (Dest, L3, object->line_length);
|
oil_memcpy (Dest, L3, object->row_stride);
|
||||||
Dest += object->output_stride;
|
Dest += object->row_stride;
|
||||||
|
|
||||||
L1 += Pitch;
|
L1 += Pitch;
|
||||||
L2 += Pitch;
|
L2 += Pitch;
|
||||||
|
@ -300,7 +300,7 @@ deinterlace_frame_di_greedyh (GstDeinterlaceMethod * d_method,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InfoIsOdd) {
|
if (InfoIsOdd) {
|
||||||
oil_memcpy (Dest, L2, object->line_length);
|
oil_memcpy (Dest, L2, object->row_stride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ deinterlace_scanline_scaler_bob (GstDeinterlaceMethod * self,
|
||||||
GstDeinterlace2 * parent, guint8 * out,
|
GstDeinterlace2 * parent, guint8 * out,
|
||||||
GstDeinterlaceScanlineData * scanlines, gint width)
|
GstDeinterlaceScanlineData * scanlines, gint width)
|
||||||
{
|
{
|
||||||
oil_memcpy (out, scanlines->t0, parent->line_length);
|
oil_memcpy (out, scanlines->t0, parent->row_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstDeinterlaceMethodScalerBob, gst_deinterlace_method_scaler_bob,
|
G_DEFINE_TYPE (GstDeinterlaceMethodScalerBob, gst_deinterlace_method_scaler_bob,
|
||||||
|
|
|
@ -80,8 +80,8 @@ void FUNCT_NAME(GstDeinterlaceMethod *d_method, GstDeinterlace2* object, GstBuff
|
||||||
|
|
||||||
/* double stride do address just every odd/even scanline */
|
/* double stride do address just every odd/even scanline */
|
||||||
src_pitch = object->field_stride;
|
src_pitch = object->field_stride;
|
||||||
dst_pitch = object->output_stride;
|
dst_pitch = object->row_stride;
|
||||||
rowsize = object->line_length;
|
rowsize = object->row_stride;
|
||||||
FldHeight = object->field_height;
|
FldHeight = object->field_height;
|
||||||
|
|
||||||
pCopySrc = GST_BUFFER_DATA(object->field_history[object->history_count-1].buf);
|
pCopySrc = GST_BUFFER_DATA(object->field_history[object->history_count-1].buf);
|
||||||
|
|
|
@ -47,14 +47,14 @@ deinterlace_scanline_weave (GstDeinterlaceMethod * self,
|
||||||
GstDeinterlace2 * parent, guint8 * out,
|
GstDeinterlace2 * parent, guint8 * out,
|
||||||
GstDeinterlaceScanlineData * scanlines, gint width)
|
GstDeinterlaceScanlineData * scanlines, gint width)
|
||||||
{
|
{
|
||||||
oil_memcpy (out, scanlines->m1, parent->line_length);
|
oil_memcpy (out, scanlines->m1, parent->row_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copy_scanline (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
|
copy_scanline (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
|
||||||
guint8 * out, GstDeinterlaceScanlineData * scanlines, gint width)
|
guint8 * out, GstDeinterlaceScanlineData * scanlines, gint width)
|
||||||
{
|
{
|
||||||
oil_memcpy (out, scanlines->m0, parent->line_length);
|
oil_memcpy (out, scanlines->m0, parent->row_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstDeinterlaceMethodWeave, gst_deinterlace_method_weave,
|
G_DEFINE_TYPE (GstDeinterlaceMethodWeave, gst_deinterlace_method_weave,
|
||||||
|
|
|
@ -47,7 +47,7 @@ deinterlace_scanline_weave (GstDeinterlaceMethod * self,
|
||||||
GstDeinterlace2 * parent, guint8 * out,
|
GstDeinterlace2 * parent, guint8 * out,
|
||||||
GstDeinterlaceScanlineData * scanlines, gint width)
|
GstDeinterlaceScanlineData * scanlines, gint width)
|
||||||
{
|
{
|
||||||
oil_memcpy (out, scanlines->m1, parent->line_length);
|
oil_memcpy (out, scanlines->m1, parent->row_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -56,9 +56,9 @@ copy_scanline (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
|
||||||
{
|
{
|
||||||
/* FIXME: original code used m2 and m0 but this looks really bad */
|
/* FIXME: original code used m2 and m0 but this looks really bad */
|
||||||
if (scanlines->bottom_field) {
|
if (scanlines->bottom_field) {
|
||||||
oil_memcpy (out, scanlines->bb2, parent->line_length);
|
oil_memcpy (out, scanlines->bb2, parent->row_stride);
|
||||||
} else {
|
} else {
|
||||||
oil_memcpy (out, scanlines->bb0, parent->line_length);
|
oil_memcpy (out, scanlines->bb0, parent->row_stride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ deinterlace_scanline_weave (GstDeinterlaceMethod * self,
|
||||||
GstDeinterlace2 * parent, guint8 * out,
|
GstDeinterlace2 * parent, guint8 * out,
|
||||||
GstDeinterlaceScanlineData * scanlines, gint width)
|
GstDeinterlaceScanlineData * scanlines, gint width)
|
||||||
{
|
{
|
||||||
oil_memcpy (out, scanlines->m1, parent->line_length);
|
oil_memcpy (out, scanlines->m1, parent->row_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -56,9 +56,9 @@ copy_scanline (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
|
||||||
{
|
{
|
||||||
/* FIXME: original code used m2 and m0 but this looks really bad */
|
/* FIXME: original code used m2 and m0 but this looks really bad */
|
||||||
if (scanlines->bottom_field) {
|
if (scanlines->bottom_field) {
|
||||||
oil_memcpy (out, scanlines->bb0, parent->line_length);
|
oil_memcpy (out, scanlines->bb0, parent->row_stride);
|
||||||
} else {
|
} else {
|
||||||
oil_memcpy (out, scanlines->bb2, parent->line_length);
|
oil_memcpy (out, scanlines->bb2, parent->row_stride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue