00001
00002
00003
00004
00005 #include <stdlib.h>
00006 #include <stdio.h>
00007
00008 #ifdef 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 BDFilter
00018 {
00019 int (*filter)(VideoFilter *, VideoFrame *);
00020 void (*cleanup)(VideoFilter *);
00021
00022 void *handle;
00023 VideoFrameType inpixfmt;
00024 VideoFrameType outpixfmt;
00025 char *opts;
00026 FilterInfo *info;
00027
00028
00029 unsigned char *tmp_ptr;
00030 int tmp_size;
00031 unsigned char *line_state;
00032 int state_size;
00033 } BDFilter;
00034
00035 #define ODD(_n) (((_n)%2)==1)
00036
00037 static void doSplit(BDFilter *filter, unsigned char *buf, int lines, int width)
00038 {
00039
00040 int i, j, k_start, modv;
00041 unsigned char *line_state = filter->line_state;
00042 unsigned char *tmp = filter->tmp_ptr;
00043
00044 modv = lines - 1;
00045 if (ODD(lines))
00046 modv = lines;
00047 memset(line_state, 0, modv);
00048 k_start = 1;
00049 line_state[0] = 1;
00050 while (k_start < modv)
00051 {
00052 i = j = k_start;
00053 memcpy(tmp, &(buf[i*width]), width);
00054 while (!line_state[j])
00055 {
00056 line_state[j] = 1;
00057 i = j;
00058 j = j * 2 % modv;
00059 memcpy(&(buf[i*width]), &(buf[j*width]), width);
00060 }
00061 memcpy(&(buf[i*width]), tmp, width);
00062 while (k_start < modv && line_state[k_start])
00063 k_start++;
00064 }
00065 }
00066
00067 int bobDeintFilter(VideoFilter *f, VideoFrame *frame)
00068 {
00069 BDFilter *filter = (BDFilter *)(f);
00070 int width = frame->width;
00071 int height = frame->height;
00072 int ymax = height;
00073 int stride = frame->pitches[0];
00074
00075 unsigned char *yoff = frame->buf + frame->offsets[0];
00076 unsigned char *uoff = frame->buf + frame->offsets[1];
00077 unsigned char *voff = frame->buf + frame->offsets[2];
00078
00079 if (filter->tmp_size < width)
00080 {
00081 filter->tmp_ptr = (unsigned char *)realloc(
00082 filter->tmp_ptr, width * sizeof(char));
00083 filter->tmp_size = width;
00084 }
00085 if (filter->state_size < height)
00086 {
00087 filter->line_state = (unsigned char *)realloc(
00088 filter->line_state, height * sizeof(char));
00089 filter->state_size = height;
00090 }
00091
00092 doSplit(filter, yoff, ymax, stride);
00093
00094 stride = frame->pitches[1];
00095 ymax = height >> 1;
00096 doSplit(filter, uoff, ymax, stride);
00097 doSplit(filter, voff, ymax, stride);
00098
00099 return 0;
00100 }
00101
00102 void bobDtor(VideoFilter *f)
00103 {
00104 BDFilter *filter = (BDFilter *)(f);
00105 if (filter->line_state)
00106 free(filter->line_state);
00107 if (filter->tmp_ptr)
00108 free(filter->tmp_ptr);
00109 }
00110
00111 VideoFilter *new_filter(VideoFrameType inpixfmt, VideoFrameType outpixfmt,
00112 int *width, int *height, char *options)
00113 {
00114 BDFilter *filter;
00115 (void)width;
00116 (void)height;
00117 (void)options;
00118
00119 if (inpixfmt != FMT_YV12 || outpixfmt != FMT_YV12)
00120 return NULL;
00121
00122 filter = malloc(sizeof(BDFilter));
00123
00124 if (filter == NULL)
00125 {
00126 fprintf(stderr,"Couldn't allocate memory for filter\n");
00127 return NULL;
00128 }
00129
00130 filter->filter = &bobDeintFilter;
00131 filter->tmp_size = 0;
00132 filter->tmp_ptr = NULL;
00133 filter->state_size = 0;
00134 filter->line_state = NULL;
00135 filter->cleanup = &bobDtor;
00136 return (VideoFilter *)filter;
00137 }
00138
00139 static FmtConv FmtList[] =
00140 {
00141 { FMT_YV12, FMT_YV12 },
00142 FMT_NULL
00143 };
00144
00145 FilterInfo filter_table[] =
00146 {
00147 {
00148 symbol: "new_filter",
00149 name: "bobdeint",
00150 descript: "bob deinterlace filter; splits fields to top and bottom of buffer",
00151 formats: FmtList,
00152 libname: NULL,
00153 },
00154 FILT_NULL
00155 };