1/* 2 * GStreamer 3 * Copyright (c) 2002 Tom Barry All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public 16 * License along with this library; if not, write to the 17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21/* 22 * Relicensed for GStreamer from GPL to LGPL with permit from Tom Barry. 23 * See: http://bugzilla.gnome.org/show_bug.cgi?id=163578 24 */ 25 26 27#ifndef TopFirst 28#define TopFirst IsOdd 29#endif 30 31#ifdef SEFUNC 32#undef SEFUNC 33#endif 34 35#if defined(IS_MMXEXT) 36#define SEFUNC(x) Search_Effort_MMXEXT_##x(int src_pitch, int dst_pitch, int rowsize, const unsigned char *pWeaveSrc, const unsigned char *pWeaveSrcP, unsigned char *pWeaveDest, int IsOdd, const unsigned char *pCopySrc, const unsigned char *pCopySrcP, int FldHeight) 37#elif defined(IS_3DNOW) 38#define SEFUNC(x) Search_Effort_3DNOW_##x(int src_pitch, int dst_pitch, int rowsize, const unsigned char *pWeaveSrc, const unsigned char *pWeaveSrcP, unsigned char *pWeaveDest, int IsOdd, const unsigned char *pCopySrc, const unsigned char *pCopySrcP, int FldHeight) 39#elif defined(IS_MMX) 40#define SEFUNC(x) Search_Effort_MMX_##x(int src_pitch, int dst_pitch, int rowsize, const unsigned char *pWeaveSrc, const unsigned char *pWeaveSrcP, unsigned char *pWeaveDest, int IsOdd, const unsigned char *pCopySrc, const unsigned char *pCopySrcP, int FldHeight) 41#else 42#define SEFUNC(x) Search_Effort_C_##x(int src_pitch, int dst_pitch, int rowsize, const unsigned char *pWeaveSrc, const unsigned char *pWeaveSrcP, unsigned char *pWeaveDest, int IsOdd, const unsigned char *pCopySrc, const unsigned char *pCopySrcP, int FldHeight) 43#endif 44 45#include "TomsMoCompAll2.inc" 46 47#define USE_STRANGE_BOB 48 49#include "TomsMoCompAll2.inc" 50 51#undef USE_STRANGE_BOB 52 53#undef SEFUNC 54#if defined(IS_MMXEXT) 55#define SEFUNC(x) Search_Effort_MMXEXT_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight) 56#elif defined(IS_3DNOW) 57#define SEFUNC(x) Search_Effort_3DNOW_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight) 58#elif defined(IS_MMX) 59#define SEFUNC(x) Search_Effort_MMX_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight) 60#else 61#define SEFUNC(x) Search_Effort_C_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight) 62#endif 63 64static void FUNCT_NAME(GstDeinterlaceMethod *d_method, 65 const GstDeinterlaceField* history, guint history_count, 66 GstVideoFrame *outframe, int cur_field_idx) 67{ 68 GstDeinterlaceMethodTomsMoComp *self = GST_DEINTERLACE_METHOD_TOMSMOCOMP (d_method); 69 glong SearchEffort = self->search_effort; 70 gint UseStrangeBob = self->strange_bob; 71 gint IsOdd; 72 const guint8 *pWeaveSrc; 73 const guint8 *pWeaveSrcP; 74 guint8 *pWeaveDest; 75 const guint8 *pCopySrc; 76 const guint8 *pCopySrcP; 77 guint8 *pCopyDest; 78 gint src_pitch; 79 gint dst_pitch; 80 gint rowsize; 81 gint FldHeight; 82 83 if (cur_field_idx + 2 > history_count || cur_field_idx < 1) { 84 GstDeinterlaceMethod *backup_method; 85 86 backup_method = g_object_new (gst_deinterlace_method_linear_get_type(), 87 NULL); 88 89 gst_deinterlace_method_setup (backup_method, d_method->vinfo); 90 gst_deinterlace_method_deinterlace_frame (backup_method, 91 history, history_count, outframe, cur_field_idx); 92 93 g_object_unref (backup_method); 94 return; 95 } 96 97 /* double stride do address just every odd/even scanline */ 98 src_pitch = GST_VIDEO_FRAME_PLANE_STRIDE (outframe, 0) * 2; 99 dst_pitch = GST_VIDEO_FRAME_PLANE_STRIDE (outframe, 0); 100 rowsize = GST_VIDEO_FRAME_PLANE_STRIDE (outframe, 0); 101 102 FldHeight = GST_VIDEO_INFO_HEIGHT (self->parent.vinfo) / 2; 103 104 pCopySrc = GST_VIDEO_FRAME_PLANE_DATA (history[history_count-1].frame, 0); 105 if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM) 106 pCopySrc += GST_VIDEO_FRAME_PLANE_STRIDE (history[history_count-1].frame, 0); 107 pCopySrcP = GST_VIDEO_FRAME_PLANE_DATA (history[history_count-3].frame, 0); 108 if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM) 109 pCopySrcP += GST_VIDEO_FRAME_PLANE_STRIDE (history[history_count-3].frame, 0); 110 pWeaveSrc = GST_VIDEO_FRAME_PLANE_DATA (history[history_count-2].frame, 0); 111 if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM) 112 pWeaveSrc += GST_VIDEO_FRAME_PLANE_STRIDE (history[history_count-2].frame, 0); 113 pWeaveSrcP = GST_VIDEO_FRAME_PLANE_DATA (history[history_count-4].frame, 0); 114 if (history[history_count - 4].flags & PICTURE_INTERLACED_BOTTOM) 115 pWeaveSrcP += GST_VIDEO_FRAME_PLANE_STRIDE (history[history_count-4].frame, 0); 116 117 /* use bottom field and interlace top field */ 118 if (history[history_count-2].flags == PICTURE_INTERLACED_BOTTOM) { 119 IsOdd = 1; 120 121 // if we have an odd field we copy an even field and weave an odd field 122 pCopyDest = GST_VIDEO_FRAME_PLANE_DATA (outframe, 0); 123 pWeaveDest = pCopyDest + dst_pitch; 124 } 125 /* do it vice verca */ 126 else { 127 128 IsOdd = 0; 129 // if we have an even field we copy an odd field and weave an even field 130 pCopyDest = (guint8 *) GST_VIDEO_FRAME_PLANE_DATA (outframe, 0) + dst_pitch; 131 pWeaveDest = GST_VIDEO_FRAME_PLANE_DATA (outframe, 0); 132 } 133 134 135 // copy 1st and last weave lines 136 Fieldcopy(pWeaveDest, pCopySrc, rowsize, 137 1, dst_pitch*2, src_pitch); 138 Fieldcopy(pWeaveDest+(FldHeight-1)*dst_pitch*2, 139 pCopySrc+(FldHeight-1)*src_pitch, rowsize, 140 1, dst_pitch*2, src_pitch); 141 142#ifdef USE_VERTICAL_FILTER 143 // Vertical Filter currently not implemented for DScaler !! 144 // copy 1st and last lines the copy field 145 Fieldcopy(pCopyDest, pCopySrc, rowsize, 146 1, dst_pitch*2, src_pitch); 147 Fieldcopy(pCopyDest+(FldHeight-1)*dst_pitch*2, 148 pCopySrc+(FldHeight-1)*src_pitch, rowsize, 149 1, dst_pitch*2, src_pitch); 150#else 151 152 // copy all of the copy field 153 Fieldcopy(pCopyDest, pCopySrc, rowsize, 154 FldHeight, dst_pitch*2, src_pitch); 155#endif 156 // then go fill in the hard part, being variously lazy depending upon 157 // SearchEffort 158 159 if(!UseStrangeBob) { 160 if (SearchEffort == 0) 161 { 162 SEFUNC(0); 163 } 164 else if (SearchEffort <= 1) 165 { 166 SEFUNC(1); 167 } 168 /* else if (SearchEffort <= 2) 169 { 170 SEFUNC(2); 171 } 172 */ 173 else if (SearchEffort <= 3) 174 { 175 SEFUNC(3); 176 } 177 else if (SearchEffort <= 5) 178 { 179 SEFUNC(5); 180 } 181 else if (SearchEffort <= 9) 182 { 183 SEFUNC(9); 184 } 185 else if (SearchEffort <= 11) 186 { 187 SEFUNC(11); 188 } 189 else if (SearchEffort <= 13) 190 { 191 SEFUNC(13); 192 } 193 else if (SearchEffort <= 15) 194 { 195 SEFUNC(15); 196 } 197 else if (SearchEffort <= 19) 198 { 199 SEFUNC(19); 200 } 201 else if (SearchEffort <= 21) 202 { 203 SEFUNC(21); 204 } 205 else 206 { 207 SEFUNC(Max); 208 } 209 } 210 else 211 { 212 if (SearchEffort == 0) 213 { 214 SEFUNC(0SB); 215 } 216 else if (SearchEffort <= 1) 217 { 218 SEFUNC(1SB); 219 } 220 /* else if (SearchEffort <= 2) 221 { 222 SEFUNC(2SB); 223 } 224 */ 225 else if (SearchEffort <= 3) 226 { 227 SEFUNC(3SB); 228 } 229 else if (SearchEffort <= 5) 230 { 231 SEFUNC(5SB); 232 } 233 else if (SearchEffort <= 9) 234 { 235 SEFUNC(9SB); 236 } 237 else if (SearchEffort <= 11) 238 { 239 SEFUNC(11SB); 240 } 241 else if (SearchEffort <= 13) 242 { 243 SEFUNC(13SB); 244 } 245 else if (SearchEffort <= 15) 246 { 247 SEFUNC(15SB); 248 } 249 else if (SearchEffort <= 19) 250 { 251 SEFUNC(19SB); 252 } 253 else if (SearchEffort <= 21) 254 { 255 SEFUNC(21SB); 256 } 257 else 258 { 259 SEFUNC(MaxSB); 260 } 261 } 262 263#if defined(BUILD_X86_ASM) && !defined(IS_C) 264 __asm__ __volatile__("emms"); 265#endif 266} 267