|
MythTV
0.26-pre
|
00001 // selects one field only from interlaced video (defaulting to top) 00002 // based on linearblend 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 /* functions and variables below here considered "private" */ 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 };
1.7.6.1