mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 19:21:06 +00:00
Added point sampling interpolation.
Original commit message from CVS: Added point sampling interpolation.
This commit is contained in:
parent
08b4e78a53
commit
82acefa7b0
2 changed files with 73 additions and 12 deletions
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include <gstvideoscale.h>
|
||||
#include <gst/meta/videoraw.h>
|
||||
#include <libs/colorspace/gstcolorspace.h>
|
||||
|
||||
static void gst_videoscale_scale_yuv(GstVideoScale *scale, unsigned char *src, unsigned char *dest);
|
||||
static void gst_videoscale_scale_rgb(GstVideoScale *scale, unsigned char *src, unsigned char *dest);
|
||||
|
@ -33,15 +32,16 @@ static void gst_videoscale_scale_rgb(GstVideoScale *scale, unsigned char *src, u
|
|||
static void generate_rowbytes(unsigned char *copy_row, int src_w, int dst_w, int bpp);
|
||||
static void gst_videoscale_scale_nearest(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh);
|
||||
static void gst_videoscale_scale_plane_slow(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh);
|
||||
static void gst_videoscale_scale_point_sample(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh);
|
||||
|
||||
/* filters */
|
||||
static unsigned char gst_videoscale_bilinear(unsigned char *src, double x, double y, int sw, int sh);
|
||||
static unsigned char gst_videoscale_bicubic(unsigned char *src, double x, double y, int sw, int sh);
|
||||
|
||||
GstVideoScale *gst_videoscale_new(int sw, int sh, int dw, int dh, int format, GstVideoScaleMethod method)
|
||||
GstVideoScale *gst_videoscale_new(gint sw, gint sh, gint dw, gint dh, GstColorSpaceType format, GstVideoScaleMethod method)
|
||||
{
|
||||
GstVideoScale *new = g_malloc(sizeof(GstVideoScale));
|
||||
int scale_bytes;
|
||||
gint scale_bytes;
|
||||
|
||||
new->source_width = sw;
|
||||
new->source_height = sh;
|
||||
|
@ -63,9 +63,17 @@ GstVideoScale *gst_videoscale_new(int sw, int sh, int dw, int dh, int format, Gs
|
|||
new->scale = gst_videoscale_scale_rgb;
|
||||
scale_bytes = 2;
|
||||
break;
|
||||
default:
|
||||
g_print("videoscale: unsupported video format %d\n", format);
|
||||
g_free(new);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (method) {
|
||||
case GST_VIDEOSCALE_POINT_SAMPLE:
|
||||
new->scaler = gst_videoscale_scale_point_sample;
|
||||
DEBUG("videoscale: scaling method POINT_SAMPLE\n");
|
||||
break;
|
||||
case GST_VIDEOSCALE_NEAREST:
|
||||
generate_rowbytes(new->copy_row, sw, dw, scale_bytes);
|
||||
new->scaler = gst_videoscale_scale_nearest;
|
||||
|
@ -83,7 +91,8 @@ GstVideoScale *gst_videoscale_new(int sw, int sh, int dw, int dh, int format, Gs
|
|||
break;
|
||||
default:
|
||||
g_print("videoscale: unsupported scaling method %d\n", method);
|
||||
break;
|
||||
g_free(new);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new;
|
||||
|
@ -115,7 +124,7 @@ static void gst_videoscale_scale_yuv(GstVideoScale *scale, unsigned char *src, u
|
|||
int dw = scale->dest_width;
|
||||
int dh = scale->dest_height;
|
||||
|
||||
DEBUG("videoscale: scaling YUV420 %dx%d to %dx%d\n", sw, sh, dw, dh);
|
||||
DEBUG("videoscale: scaling YUV420P %dx%d to %dx%d\n", sw, sh, dw, dh);
|
||||
|
||||
scale->scaler(scale, src, dest, sw, sh, dw, dh);
|
||||
|
||||
|
@ -145,7 +154,7 @@ static unsigned char gst_videoscale_bilinear(unsigned char *src, double x, doubl
|
|||
double dest;
|
||||
int color;
|
||||
|
||||
DEBUG("videoscale: scaling bilinear %dx%d\n", sw, sh);
|
||||
printf("videoscale: scaling bilinear %f %f %dx%d\n", x, y, sw, sh);
|
||||
|
||||
dest=(1-a)*(1-b)*RC(j,k)+
|
||||
a*(1-b)*RC(j+1,k);
|
||||
|
@ -172,6 +181,8 @@ static unsigned char gst_videoscale_bicubic(unsigned char *src, double x, double
|
|||
double t1, t2, t3, t4;
|
||||
double a1, a2, a3, a4;
|
||||
|
||||
DEBUG("videoscale: scaling bicubic %dx%d\n", sw, sh);
|
||||
|
||||
a1 = -a*(1-a)*(1-a);
|
||||
a2 = (1-2*a*a+a*a*a);
|
||||
a3 = a*(1+a-a*a);
|
||||
|
@ -274,6 +285,53 @@ static void generate_rowbytes(unsigned char *copy_row, int src_w, int dst_w, int
|
|||
}
|
||||
|
||||
|
||||
static void gst_videoscale_scale_point_sample(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh)
|
||||
{
|
||||
int ypos, yinc, y;
|
||||
int xpos, xinc, x;
|
||||
int sum, xcount, ycount, loop;
|
||||
unsigned char *srcp, *srcp2;
|
||||
|
||||
DEBUG("videoscale: scaling nearest %p %p %d\n", src, dest, dw);
|
||||
|
||||
|
||||
ypos = 0x10000;
|
||||
yinc = (sh<<16)/dh;
|
||||
xinc = (sw<<16)/dw;
|
||||
|
||||
for (y = dh; y; y--) {
|
||||
|
||||
ycount = 1;
|
||||
srcp = src;
|
||||
while (ypos >0x10000) {
|
||||
ycount++;
|
||||
ypos-=0x10000;
|
||||
src += sw;
|
||||
}
|
||||
|
||||
xpos = 0x10000;
|
||||
for ( x=dw; x; x-- ) {
|
||||
xcount = 0;
|
||||
sum=0;
|
||||
while ( xpos >= 0x10000L ) {
|
||||
loop = ycount;
|
||||
srcp2 = srcp;
|
||||
while (loop--) {
|
||||
sum += *srcp2;
|
||||
srcp2 += sw;
|
||||
}
|
||||
srcp++;
|
||||
xcount++;
|
||||
xpos -= 0x10000L;
|
||||
}
|
||||
*dest++ = sum/(xcount*ycount);
|
||||
xpos += xinc;
|
||||
}
|
||||
|
||||
ypos += yinc;
|
||||
}
|
||||
}
|
||||
|
||||
static void gst_videoscale_scale_nearest(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh)
|
||||
{
|
||||
int pos, inc, y;
|
||||
|
@ -303,7 +361,6 @@ static void gst_videoscale_scale_nearest(GstVideoScale *scale, unsigned char *sr
|
|||
: "memory" );
|
||||
|
||||
|
||||
//g_print("videoscale: scaling nearest %d\n", y);
|
||||
dest+= dw;
|
||||
|
||||
pos += inc;
|
||||
|
|
|
@ -22,31 +22,35 @@
|
|||
#define __GST_VIDEOSCALE_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <libs/colorspace/gstcolorspace.h>
|
||||
|
||||
typedef enum {
|
||||
GST_VIDEOSCALE_POINT_SAMPLE,
|
||||
GST_VIDEOSCALE_NEAREST,
|
||||
GST_VIDEOSCALE_BILINEAR,
|
||||
GST_VIDEOSCALE_BICUBIC
|
||||
} GstVideoScaleMethod;
|
||||
|
||||
typedef struct _GstVideoScale GstVideoScale;
|
||||
typedef void (*GstVideoScaleScaler) (GstVideoScale *scale, guchar *src, guchar *dest);
|
||||
|
||||
struct _GstVideoScale {
|
||||
guint source_width;
|
||||
guint source_height;
|
||||
guint dest_width;
|
||||
guint dest_height;
|
||||
guint format;
|
||||
GstColorSpaceType format;
|
||||
GstVideoScaleMethod method;
|
||||
/* private */
|
||||
guchar copy_row[8192];
|
||||
guchar *temp;
|
||||
void (*scale) (GstVideoScale *scale, unsigned char *src, unsigned char *dest);
|
||||
void (*scaler) (GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh);
|
||||
unsigned char (*filter) (unsigned char *src, double x, double y, int sw, int sh);
|
||||
GstVideoScaleScaler scale;
|
||||
void (*scaler) (GstVideoScale *scale, guchar *src, guchar *dest, gint sw, gint sh, gint dw, gint dh);
|
||||
guchar (*filter) (guchar *src, gdouble x, gdouble y, gint sw, gint sh);
|
||||
};
|
||||
|
||||
GstVideoScale *gst_videoscale_new(int sw, int sh, int dw, int dh, int format, GstVideoScaleMethod method);
|
||||
GstVideoScale *gst_videoscale_new(gint sw, gint sh, gint dw, gint dh, GstColorSpaceType format, GstVideoScaleMethod method);
|
||||
#define gst_videoscale_scale(scaler, src, dest) (scaler)->scale((scaler), (src), (dest))
|
||||
void gst_videoscale_destroy(GstVideoScale *scale);
|
||||
|
||||
#endif /* __GST_VIDEOSCALE_H__ */
|
||||
|
|
Loading…
Reference in a new issue