MythTV  0.26-pre
filter_onefield.c
Go to the documentation of this file.
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 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends