00001
00002
00003
00004 #include <stdlib.h>
00005 #include <stdio.h>
00006
00007 #ifdef HAVE_STDINT_H
00008 #include <stdint.h>
00009 #endif
00010
00011 #include <string.h>
00012
00013 #include "filter.h"
00014 #include "frame.h"
00015
00016 typedef struct OFFilter
00017 {
00018 int (*filter)(VideoFilter *, VideoFrame *);
00019 void (*cleanup)(VideoFilter *);
00020
00021 void *handle;
00022 VideoFrameType inpixfmt;
00023 VideoFrameType outpixfmt;
00024 char *opts;
00025 FilterInfo *info;
00026
00027
00028 int bottom;
00029 } OFFilter;
00030
00031 int oneFieldFilter(VideoFilter *f, VideoFrame *frame)
00032 {
00033 OFFilter *filter = (OFFilter *)(f);
00034 int height = frame->height;
00035 int bottom = filter->bottom;
00036 int stride = frame->pitches[0];
00037 int ymax = height - 2;
00038 int y;
00039 unsigned char *yoff = frame->buf + frame->offsets[0];
00040 unsigned char *uoff = frame->buf + frame->offsets[1];
00041 unsigned char *voff = frame->buf + frame->offsets[2];
00042
00043 for (y = 0; y < ymax; y += 2)
00044 {
00045 unsigned char *src = (bottom ? &(yoff[(y+1)*stride]) : &(yoff[y*stride]));
00046 unsigned char *dst = (bottom ? &(yoff[y*stride]) : &(yoff[(y+1)*stride]));
00047 memcpy(dst, src, stride);
00048 }
00049
00050 stride = frame->pitches[1];
00051 ymax = height / 2 - 2;
00052
00053 for (y = 0; y < ymax; y += 2)
00054 {
00055 unsigned char *src = (bottom ? &(uoff[(y+1)*stride]) : &(uoff[y*stride]));
00056 unsigned char *dst = (bottom ? &(uoff[y*stride]) : &(uoff[(y+1)*stride]));
00057 memcpy(dst, src, stride);
00058 src = (bottom ? &(voff[(y+1)*stride]) : &(voff[y*stride]));
00059 dst = (bottom ? &(voff[y*stride]) : &(voff[(y+1)*stride]));
00060 memcpy(dst, src, stride);
00061 }
00062
00063 return 0;
00064 }
00065
00066 VideoFilter *new_filter(VideoFrameType inpixfmt, VideoFrameType outpixfmt,
00067 int *width, int *height, char *options)
00068 {
00069 OFFilter *filter;
00070 (void)width;
00071 (void)height;
00072
00073 if (inpixfmt != FMT_YV12 || outpixfmt != FMT_YV12)
00074 return NULL;
00075
00076 filter = malloc(sizeof(OFFilter));
00077
00078 if (filter == NULL)
00079 {
00080 fprintf(stderr,"Couldn't allocate memory for filter\n");
00081 return NULL;
00082 }
00083
00084 filter->filter = &oneFieldFilter;
00085 filter->bottom = 0;
00086 if (options != NULL && strstr(options, "bottom") != NULL)
00087 filter->bottom = 1;
00088
00089 filter->cleanup = NULL;
00090 return (VideoFilter *)filter;
00091 }
00092
00093 static FmtConv FmtList[] =
00094 {
00095 { FMT_YV12, FMT_YV12 },
00096 FMT_NULL
00097 };
00098
00099 FilterInfo filter_table[] =
00100 {
00101 {
00102 symbol: "new_filter",
00103 name: "onefield",
00104 descript: "one-field-only deinterlace filter; parameter \"bottom\" for bottom field, otherwise top",
00105 formats: FmtList,
00106 libname: NULL,
00107 },
00108 FILT_NULL
00109 };