// Copyright 2002 Ben Rudiak-Gould et al. // http://www.avisynth.org // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit // http://www.gnu.org/copyleft/gpl.html . // // Linking Avisynth statically or dynamically with other modules is making a // combined work based on Avisynth. Thus, the terms and conditions of the GNU // General Public License cover the whole combination. // // As a special exception, the copyright holders of Avisynth give you // permission to link Avisynth with independent modules that communicate with // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license // terms of these independent modules, and to copy and distribute the // resulting combined work under terms of your choice, provided that // every copy of the combined work is accompanied by a complete copy of // the source code of Avisynth (the version of Avisynth used to produce the // combined work), being distributed under the terms of the GNU General // Public License plus this exception. An independent module is a module // which is not derived from or based on Avisynth, such as 3rd-party filters, // import and export plugins, or graphical user interfaces. static int C_scenechange_16(const BYTE* c_plane, const BYTE* tplane, int height, int width, int c_pitch, int t_pitch) { unsigned int accum = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { accum += abs(tplane[x] - c_plane[x]); } c_plane += c_pitch; tplane += t_pitch; } return accum; } /********************* * YV12 Scenechange detection. * * (c) 2003, Klaus Post * * ISSE, MOD 16 version. * * Returns an int of the accumulated absolute difference * between two planes. * * The absolute difference between two planes are returned as an int. * This version is optimized for mod16 widths. Others widths are allowed, * but the remaining pixels are simply skipped. *********************/ static int isse_scenechange_16(const BYTE* c_plane, const BYTE* tplane, int height, int width, int c_pitch, int t_pitch) { int wp=width; int hp=height; int returnvalue=0xbadbad00; __asm { xor ebx,ebx // Height pxor mm5,mm5 // Maximum difference mov edx, c_pitch //copy pitch mov ecx, t_pitch //copy pitch pxor mm6,mm6 // We maintain two sums, for better pairablility pxor mm7,mm7 mov esi, c_plane mov edi, tplane jmp yloopover align 16 yloop: inc ebx add edi,ecx // add pitch to both planes add esi,edx yloopover: cmp ebx,[hp] jge endframe xor eax,eax // Width align 16 xloop: cmp eax,[wp] jge yloop movq mm0,[esi+eax] movq mm2,[esi+eax+8] movq mm1,[edi+eax] movq mm3,[edi+eax+8] psadbw mm0,mm1 // Sum of absolute difference psadbw mm2,mm3 paddd mm6,mm0 // Add... paddd mm7,mm2 add eax,16 jmp xloop endframe: paddd mm7,mm6 movd returnvalue,mm7 emms } return returnvalue; }