00001
00002
00003
00004
00005
00006 #include <stdlib.h>
00007 #include <stdio.h>
00008
00009 #ifdef HAVE_STDINT_H
00010 #include <stdint.h>
00011 #endif
00012
00013 #include <string.h>
00014 #include <math.h>
00015
00016 #include "filter.h"
00017 #include "frame.h"
00018
00019 #include "config.h"
00020 #include "dsputil.h"
00021
00022 #include "color.h"
00023
00024 #if defined (ARCH_X86)
00025
00026 #include "greedyhmacros.h"
00027
00028 #define MAXCOMB_DEFAULT 5
00029 #define MOTIONTHRESHOLD_DEFAULT 25
00030 #define MOTIONSENSE_DEFAULT 30
00031
00032 static unsigned int GreedyMaxComb = MAXCOMB_DEFAULT;
00033 static unsigned int GreedyMotionThreshold = MOTIONTHRESHOLD_DEFAULT;
00034 static unsigned int GreedyMotionSense = MOTIONSENSE_DEFAULT;
00035
00036 #define IS_MMX
00037 #define SSE_TYPE MMXT
00038 #define FUNCT_NAME greedyh_filter_mmx
00039 #include "greedyh.asm"
00040 #undef SSE_TYPE
00041 #undef IS_MMX
00042 #undef FUNCT_NAME
00043
00044 #define IS_SSE
00045 #define SSE_TYPE SSE
00046 #define FUNCT_NAME greedyh_filter_sse
00047 #include "greedyh.asm"
00048 #undef SSE_TYPE
00049 #undef IS_SSE
00050 #undef FUNCT_NAME
00051
00052 #define IS_3DNOW
00053 #define FUNCT_NAME greedyh_filter_3dnow
00054 #define SSE_TYPE 3DNOW
00055 #include "greedyh.asm"
00056 #undef SSE_TYPE
00057 #undef IS_3DNOW
00058 #undef FUNCT_NAME
00059
00060
00061 #endif
00062
00063
00064
00065 #ifdef MMX
00066 #include "i386/mmx.h"
00067
00068 static const mmx_t mm_cpool[] =
00069 {
00070 { 0x0000000000000000LL },
00071 };
00072
00073 #else
00074 #define mmx_t int
00075 #endif
00076
00077 typedef struct ThisFilter
00078 {
00079 VideoFilter vf;
00080
00081 long long frames_nr[2];
00082 int8_t got_frames[2];
00083 unsigned char* frames[2];
00084 unsigned char* deint_frame;
00085 long long last_framenr;
00086
00087 int width;
00088 int height;
00089
00090 int mm_flags;
00091 TF_STRUCT;
00092 } ThisFilter;
00093
00094 static void AllocFilter(ThisFilter* filter, int width, int height)
00095 {
00096 if ((width != filter->width) || height != filter->height)
00097 {
00098 printf("greedyhdeint: size changed from %d x %d -> %d x %d\n", filter->width, filter->height, width, height);
00099 if (filter->frames[0])
00100 {
00101 free(filter->frames[0]);
00102 free(filter->frames[1]);
00103 free(filter->deint_frame);
00104 }
00105 filter->frames[0] = malloc(width * height * 2);
00106 filter->frames[1] = malloc(width * height * 2);
00107 memset(filter->frames[0], 0, width * height * 2);
00108 memset(filter->frames[1], 0, width * height * 2);
00109 filter->deint_frame = malloc(width * height * 2);
00110 filter->width = width;
00111 filter->height = height;
00112 memset(filter->got_frames, 0, sizeof(filter->got_frames));
00113 memset(filter->frames_nr, 0, sizeof(filter->frames_nr));
00114 }
00115 }
00116
00117
00118 #include <sys/time.h>
00119 #include <time.h>
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 static int GreedyHDeint (VideoFilter * f, VideoFrame * frame)
00158 {
00159 ThisFilter *filter = (ThisFilter *) f;
00160 TF_VARS;
00161
00162 int last_frame = 0;
00163 int cur_frame = 0;
00164 int second_field = 0;
00165 int bottom_field = 0;
00166
00167 AllocFilter((ThisFilter*)f, frame->width, frame->height);
00168
00169 if (filter->last_framenr != frame->frameNumber)
00170 {
00171
00172 cur_frame = (filter->last_framenr + 1) & 1;
00173 last_frame = (filter->last_framenr) & 1;
00174
00175 if (filter->last_framenr != (frame->frameNumber - 1))
00176 {
00177 cur_frame = frame->frameNumber & 1;
00178 last_frame = cur_frame;
00179 }
00180 second_field = 0;
00181 bottom_field = frame->top_field_first? 0 : 1;
00182 }
00183 else
00184 {
00185
00186 cur_frame = (filter->last_framenr) & 1;
00187 last_frame = (filter->last_framenr + 1) & 1;
00188 second_field = 1;
00189 bottom_field = frame->top_field_first? 1 : 0;
00190 }
00191 filter->got_frames[cur_frame] = 1;
00192 filter->frames_nr[cur_frame] = frame->frameNumber;
00193
00194 #if 0
00195 struct timeval l_stTV;
00196 char l_achBuf[256];
00197 char lbuf[13];
00198 gettimeofday(&l_stTV, NULL);
00199 strftime(&l_achBuf[0], 255, "%Y-%m-%d %H:%M:%S", localtime(&l_stTV.tv_sec));
00200 snprintf(lbuf, 13, ".%ld", l_stTV.tv_usec);
00201 strcat(l_achBuf, lbuf);
00202
00203 printf("GreedyHDeint call: %s\n", l_achBuf);
00204 #endif
00205
00206 switch(frame->codec)
00207 {
00208 case FMT_YV12:
00209
00210
00211
00212
00213 if (second_field == 0)
00214 {
00215 yv12_to_yuy2(
00216 frame->buf + frame->offsets[0], frame->pitches[0],
00217 frame->buf + frame->offsets[1], frame->pitches[1],
00218 frame->buf + frame->offsets[2], frame->pitches[2],
00219 filter->frames[cur_frame], 2 * frame->width,
00220 frame->width, frame->height,
00221 1 - frame->interlaced_frame);
00222 }
00223 break;
00224 default:
00225 fprintf(stderr, "Unsupported pixel format.\n");
00226 return 0;
00227 }
00228
00229 if (!filter->got_frames[last_frame])
00230 last_frame = cur_frame;
00231
00232 #ifdef MMX
00233
00234 if (filter->mm_flags & MM_SSE)
00235 {
00236 greedyh_filter_sse(
00237 filter->deint_frame, 2 * frame->width,
00238 filter->frames[cur_frame], filter->frames[last_frame],
00239 bottom_field, second_field, frame->width, frame->height);
00240 }
00241 else if (filter->mm_flags & MM_3DNOW)
00242 {
00243 greedyh_filter_3dnow(
00244 filter->deint_frame, 2 * frame->width,
00245 filter->frames[cur_frame], filter->frames[last_frame],
00246 bottom_field, second_field, frame->width, frame->height);
00247 }
00248 else if (filter->mm_flags & MM_MMX)
00249 {
00250 greedyh_filter_mmx(
00251 filter->deint_frame, 2 * frame->width,
00252 filter->frames[cur_frame], filter->frames[last_frame],
00253 bottom_field, second_field, frame->width, frame->height);
00254 }
00255 else
00256 #endif
00257 {
00258
00259 }
00260
00261 #if 0
00262 apply_chroma_filter(filter->deint_frame, frame->width * 2,
00263 frame->width, frame->height );
00264 #endif
00265
00266
00267 yuy2_to_yv12(
00268 filter->deint_frame, 2 * frame->width,
00269 frame->buf + frame->offsets[0], frame->pitches[0],
00270 frame->buf + frame->offsets[1], frame->pitches[1],
00271 frame->buf + frame->offsets[2], frame->pitches[2],
00272 frame->width, frame->height);
00273
00274 filter->last_framenr = frame->frameNumber;
00275
00276 return 0;
00277 }
00278
00279
00280 void CleanupGreedyHDeintFilter (VideoFilter * filter)
00281 {
00282 ThisFilter* f = (ThisFilter*)filter;
00283 free(f->deint_frame);
00284 free(f->frames[0]);
00285 free(f->frames[1]);
00286 }
00287
00288 VideoFilter* GreedyHDeintFilter (VideoFrameType inpixfmt, VideoFrameType outpixfmt,
00289 int *width, int *height, char *options)
00290 {
00291 ThisFilter *filter;
00292 (void) height;
00293 (void) options;
00294
00295 filter = (ThisFilter *) malloc (sizeof(ThisFilter));
00296 if (filter == NULL)
00297 {
00298 fprintf (stderr, "GreedyHDeint: failed to allocate memory for filter.\n");
00299 return NULL;
00300 }
00301
00302 filter->width = 0;
00303 filter->height = 0;
00304 memset(filter->frames, 0, sizeof(filter->frames));
00305 filter->deint_frame = 0;
00306
00307 AllocFilter(filter, *width, *height);
00308
00309 init_yuv_conversion();
00310 #ifdef MMX
00311 filter->mm_flags = mm_support();
00312 TF_INIT(filter);
00313 #else
00314 filter->mm_flags = 0;
00315 #endif
00316
00317 filter->vf.filter = &GreedyHDeint;
00318 filter->vf.cleanup = &CleanupGreedyHDeintFilter;
00319 return (VideoFilter *) filter;
00320 }
00321
00322
00323 static FmtConv FmtList[] =
00324 {
00325 { FMT_YV12, FMT_YV12 } ,
00326 FMT_NULL
00327 };
00328
00329 FilterInfo filter_table[] =
00330 {
00331 {
00332 symbol: "GreedyHDeintFilter",
00333 name: "greedyhdeint",
00334 descript: "combines data from several fields to deinterlace with less motion blur",
00335 formats: FmtList,
00336 libname: NULL
00337 },
00338 {
00339 symbol: "GreedyHDeintFilter",
00340 name: "greedyhdoubleprocessdeint",
00341 descript: "combines data from several fields to deinterlace with less motion blur",
00342 formats: FmtList,
00343 libname: NULL
00344 },FILT_NULL
00345 };
00346
00347