mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
gst/deinterlace2/tvtime/vfir.c: Implement the VFIR deinterlacing method as simple method.
Original commit message from CVS: * gst/deinterlace2/tvtime/vfir.c: (deinterlace_line_c), (deinterlace_line_mmx), (gst_deinterlace_method_vfir_class_init): Implement the VFIR deinterlacing method as simple method.
This commit is contained in:
parent
163ff0f9a4
commit
cf6cde0d6d
2 changed files with 40 additions and 81 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2008-08-02 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
|
* gst/deinterlace2/tvtime/vfir.c: (deinterlace_line_c),
|
||||||
|
(deinterlace_line_mmx), (gst_deinterlace_method_vfir_class_init):
|
||||||
|
Implement the VFIR deinterlacing method as simple method.
|
||||||
|
|
||||||
2008-08-02 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
2008-08-02 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
* gst/deinterlace2/gstdeinterlace2.c:
|
* gst/deinterlace2/gstdeinterlace2.c:
|
||||||
|
|
|
@ -47,15 +47,9 @@
|
||||||
|
|
||||||
GType gst_deinterlace_method_vfir_get_type (void);
|
GType gst_deinterlace_method_vfir_get_type (void);
|
||||||
|
|
||||||
typedef GstDeinterlaceMethod GstDeinterlaceMethodVFIR;
|
typedef GstDeinterlaceSimpleMethod GstDeinterlaceMethodVFIR;
|
||||||
|
|
||||||
typedef struct
|
typedef GstDeinterlaceSimpleMethodClass GstDeinterlaceMethodVFIRClass;
|
||||||
{
|
|
||||||
GstDeinterlaceMethodClass parent_class;
|
|
||||||
void (*scanline) (uint8_t * dst, uint8_t * lum_m4,
|
|
||||||
uint8_t * lum_m3, uint8_t * lum_m2,
|
|
||||||
uint8_t * lum_m1, uint8_t * lum, int size);
|
|
||||||
} GstDeinterlaceMethodVFIRClass;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The MPEG2 spec uses a slightly harsher filter, they specify
|
* The MPEG2 spec uses a slightly harsher filter, they specify
|
||||||
|
@ -68,11 +62,16 @@ typedef struct
|
||||||
* C implementation.
|
* C implementation.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
deinterlace_line_c (uint8_t * dst, uint8_t * lum_m4,
|
deinterlace_line_c (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
|
||||||
uint8_t * lum_m3, uint8_t * lum_m2,
|
guint8 * dst, GstDeinterlaceScanlineData * scanlines, gint width)
|
||||||
uint8_t * lum_m1, uint8_t * lum, int size)
|
|
||||||
{
|
{
|
||||||
int sum;
|
gint sum;
|
||||||
|
guint8 *lum_m4 = scanlines->tt1;
|
||||||
|
guint8 *lum_m3 = scanlines->t0;
|
||||||
|
guint8 *lum_m2 = scanlines->m1;
|
||||||
|
guint8 *lum_m1 = scanlines->b0;
|
||||||
|
guint8 *lum = scanlines->bb1;
|
||||||
|
gint size = width * 2;
|
||||||
|
|
||||||
for (; size >= 0; size--) {
|
for (; size >= 0; size--) {
|
||||||
sum = -lum_m4[0];
|
sum = -lum_m4[0];
|
||||||
|
@ -93,11 +92,15 @@ deinterlace_line_c (uint8_t * dst, uint8_t * lum_m4,
|
||||||
#ifdef BUILD_X86_ASM
|
#ifdef BUILD_X86_ASM
|
||||||
#include "mmx.h"
|
#include "mmx.h"
|
||||||
static void
|
static void
|
||||||
deinterlace_line_mmx (uint8_t * dst, uint8_t * lum_m4,
|
deinterlace_line_mmx (GstDeinterlaceMethod * self, GstDeinterlace2 * parent,
|
||||||
uint8_t * lum_m3, uint8_t * lum_m2,
|
guint8 * dst, GstDeinterlaceScanlineData * scanlines, gint width)
|
||||||
uint8_t * lum_m1, uint8_t * lum, int size)
|
|
||||||
{
|
{
|
||||||
mmx_t rounder;
|
mmx_t rounder;
|
||||||
|
guint8 *lum_m4 = scanlines->tt1;
|
||||||
|
guint8 *lum_m3 = scanlines->t0;
|
||||||
|
guint8 *lum_m2 = scanlines->m1;
|
||||||
|
guint8 *lum_m1 = scanlines->b0;
|
||||||
|
guint8 *lum = scanlines->bb1;
|
||||||
|
|
||||||
rounder.uw[0] = 4;
|
rounder.uw[0] = 4;
|
||||||
rounder.uw[1] = 4;
|
rounder.uw[1] = 4;
|
||||||
|
@ -106,7 +109,7 @@ deinterlace_line_mmx (uint8_t * dst, uint8_t * lum_m4,
|
||||||
pxor_r2r (mm7, mm7);
|
pxor_r2r (mm7, mm7);
|
||||||
movq_m2r (rounder, mm6);
|
movq_m2r (rounder, mm6);
|
||||||
|
|
||||||
for (; size > 3; size -= 4) {
|
for (; width > 1; width -= 2) {
|
||||||
movd_m2r (*lum_m4, mm0);
|
movd_m2r (*lum_m4, mm0);
|
||||||
movd_m2r (*lum_m3, mm1);
|
movd_m2r (*lum_m3, mm1);
|
||||||
movd_m2r (*lum_m2, mm2);
|
movd_m2r (*lum_m2, mm2);
|
||||||
|
@ -137,94 +140,44 @@ deinterlace_line_mmx (uint8_t * dst, uint8_t * lum_m4,
|
||||||
emms ();
|
emms ();
|
||||||
|
|
||||||
/* Handle odd widths */
|
/* Handle odd widths */
|
||||||
if (size > 0)
|
if (width > 0) {
|
||||||
deinterlace_line_c (dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, size);
|
scanlines->tt1 = lum_m4;
|
||||||
|
scanlines->t0 = lum_m3;
|
||||||
|
scanlines->m1 = lum_m2;
|
||||||
|
scanlines->b0 = lum_m1;
|
||||||
|
scanlines->bb1 = lum;
|
||||||
|
|
||||||
|
deinterlace_line_c (self, parent, dst, scanlines, width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
|
||||||
deinterlace_frame_vfir (GstDeinterlaceMethod * d_method,
|
|
||||||
GstDeinterlace2 * object)
|
|
||||||
{
|
|
||||||
GstDeinterlaceMethodVFIRClass *klass =
|
|
||||||
GST_DEINTERLACE_METHOD_VFIR_GET_CLASS (d_method);
|
|
||||||
gint line = 0;
|
|
||||||
uint8_t *cur_field, *last_field;
|
|
||||||
uint8_t *t0, *b0, *tt1, *m1, *bb1, *out_data;
|
|
||||||
|
|
||||||
cur_field =
|
|
||||||
GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
|
|
||||||
last_field =
|
|
||||||
GST_BUFFER_DATA (object->field_history[object->history_count - 1].buf);
|
|
||||||
|
|
||||||
out_data = GST_BUFFER_DATA (object->out_buf);
|
|
||||||
|
|
||||||
if (object->field_history[object->history_count - 2].flags ==
|
|
||||||
PICTURE_INTERLACED_BOTTOM) {
|
|
||||||
memcpy (out_data, cur_field, object->line_length);
|
|
||||||
out_data += object->output_stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (out_data, cur_field, object->line_length);
|
|
||||||
out_data += object->output_stride;
|
|
||||||
line++;
|
|
||||||
|
|
||||||
for (; line < object->field_height; line++) {
|
|
||||||
t0 = cur_field;
|
|
||||||
b0 = cur_field + object->field_stride;
|
|
||||||
|
|
||||||
tt1 = last_field;
|
|
||||||
m1 = last_field + object->field_stride;
|
|
||||||
bb1 = last_field + (object->field_stride * 2);
|
|
||||||
|
|
||||||
/* set valid data for corner cases */
|
|
||||||
if (line == 1) {
|
|
||||||
tt1 = bb1;
|
|
||||||
} else if (line == object->field_height - 1) {
|
|
||||||
bb1 = tt1;
|
|
||||||
}
|
|
||||||
|
|
||||||
klass->scanline (out_data, tt1, t0, m1, b0, bb1, object->line_length);
|
|
||||||
out_data += object->output_stride;
|
|
||||||
cur_field += object->field_stride;
|
|
||||||
last_field += object->field_stride;
|
|
||||||
|
|
||||||
memcpy (out_data, cur_field, object->line_length);
|
|
||||||
out_data += object->output_stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (object->field_history[object->history_count - 2].flags ==
|
|
||||||
PICTURE_INTERLACED_TOP) {
|
|
||||||
/* double the last scanline of the top field */
|
|
||||||
memcpy (out_data, cur_field, object->line_length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstDeinterlaceMethodVFIR, gst_deinterlace_method_vfir,
|
G_DEFINE_TYPE (GstDeinterlaceMethodVFIR, gst_deinterlace_method_vfir,
|
||||||
GST_TYPE_DEINTERLACE_METHOD);
|
GST_TYPE_DEINTERLACE_SIMPLE_METHOD);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_deinterlace_method_vfir_class_init (GstDeinterlaceMethodVFIRClass * klass)
|
gst_deinterlace_method_vfir_class_init (GstDeinterlaceMethodVFIRClass * klass)
|
||||||
{
|
{
|
||||||
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
|
GstDeinterlaceMethodClass *dim_class = (GstDeinterlaceMethodClass *) klass;
|
||||||
|
GstDeinterlaceSimpleMethodClass *dism_class =
|
||||||
|
(GstDeinterlaceSimpleMethodClass *) klass;
|
||||||
#ifdef BUILD_X86_ASM
|
#ifdef BUILD_X86_ASM
|
||||||
guint cpu_flags = oil_cpu_get_flags ();
|
guint cpu_flags = oil_cpu_get_flags ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dim_class->fields_required = 2;
|
dim_class->fields_required = 2;
|
||||||
dim_class->deinterlace_frame = deinterlace_frame_vfir;
|
|
||||||
dim_class->name = "Blur Vertical";
|
dim_class->name = "Blur Vertical";
|
||||||
dim_class->nick = "vfir";
|
dim_class->nick = "vfir";
|
||||||
dim_class->latency = 0;
|
dim_class->latency = 0;
|
||||||
|
|
||||||
#ifdef BUILD_X86_ASM
|
#ifdef BUILD_X86_ASM
|
||||||
if (cpu_flags & OIL_IMPL_FLAG_MMX) {
|
if (cpu_flags & OIL_IMPL_FLAG_MMX) {
|
||||||
klass->scanline = deinterlace_line_mmx;
|
dism_class->interpolate_scanline = deinterlace_line_mmx;
|
||||||
} else {
|
} else {
|
||||||
klass->scanline = deinterlace_line_c;
|
dism_class->interpolate_scanline = deinterlace_line_c;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
klass->scanline = deinterlace_line_c;
|
dism_class->interpolate_scanline = deinterlace_line_c;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue