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