Пример #1
0
int main()
{
  int cpuname_id;

  cpuname_id=cpu_detect();

  printf("%s\n", cpuname[cpuname_id]);
  return 0;
}
Пример #2
0
void setup_default_settings(void)
{
    // CPU status variable
    struct CPU_INFO cpu_info;
    const struct GameSettings default_settings = {
     0,                         // field_0
     4,                         // video_shadows
     3,                         // view_distance
     0,                         // video_rotate_mode
     1,                         // video_textures
     0,                         // video_cluedo_mode
     127,                       // sound_volume
     90,                        // redbook_volume
     1,                         // field_8
     0,                         // gamma_correction
     Lb_SCREEN_MODE_640_480,    // Default Screen mode 0x004 640X480
     {
          {KC_UP, KMod_NONE},       {KC_DOWN, KMod_NONE},
          {KC_LEFT, KMod_NONE},     {KC_RIGHT, KMod_NONE},
          {KC_LCONTROL, KMod_NONE}, {KC_LSHIFT, KMod_NONE},
          {KC_DELETE, KMod_NONE},   {KC_PGDOWN, KMod_NONE},
          {KC_HOME, KMod_NONE},     {KC_END, KMod_NONE},
          {KC_T, KMod_NONE},        {KC_L, KMod_NONE},
          {KC_L, KMod_SHIFT},       {KC_P, KMod_SHIFT},
          {KC_T, KMod_ALT},         {KC_T, KMod_SHIFT},
          {KC_H, KMod_NONE},        {KC_W, KMod_NONE},
          {KC_S, KMod_NONE},        {KC_T, KMod_CONTROL},
          {KC_G, KMod_NONE},        {KC_B, KMod_NONE},
          {KC_H, KMod_SHIFT},       {KC_G, KMod_SHIFT},
          {KC_B, KMod_SHIFT},       {KC_F, KMod_NONE},
          {KC_A, KMod_NONE},        {KC_LSHIFT, KMod_NONE},
          {KC_NUMPAD0, KMod_NONE},  {KC_BACK, KMod_NONE},
          {KC_P, KMod_NONE},        {KC_M, KMod_NONE},
     },                         // kbkeys
     1,                         // tooltips_on
     1,                         // first_person_move_invert
     6                          // first_person_move_sensitivity
    };
    LbMemoryCopy(&settings, &default_settings, sizeof(struct GameSettings));
    settings.video_scrnmode = get_next_vidmode_for_switching(Lb_SCREEN_MODE_INVALID);
    cpu_detect(&cpu_info);
    
    // Removing this because we suppose these requirements are always met, and only reserved 640*400
    // in default switch mode list. 
    // if ((cpu_get_family(&cpu_info) > CPUID_FAMILY_PENTIUM) && (is_feature_on(Ft_HiResVideo)))
    // {

    //     SYNCDBG(6,"Updating to hires video mode");
    //     settings.video_scrnmode = get_next_vidmode_for_switching(settings.video_scrnmode);
    // }
}
Пример #3
0
int32_t kernel_main(multiboot_t *mboot_ptr)
{
    textmode_init();

    printf("                   _____ _                 _       ____   _____ \n                  / ____(_)               | |     / __ \\ / ____|\n                 | (___  _ _ __ ___  _ __ | | ___| |  | | (___  \n                  \\___ \\| | '_ ` _ \\| '_ \\| |/ _ \\ |  | |\\___ \\ \n                  ____) | | | | | | | |_) | |  __/ |__| |____) |\n                 |_____/|_|_| |_| |_| .__/|_|\\___|\\____/|_____/ \n                                    | |                         \n                                    |_|                         \n");
    textmode_set_colors(COLOR_RED, COLOR_BLACK);
    textmode_move_cursor(19, 6);
    printf("Version %i.%i.%i", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD);
    textmode_move_cursor(19, 7);
    printf("Built %s", VERSION_DATE);
    textmode_set_colors(COLOR_GREEN, COLOR_BLACK);
    textmode_move_cursor(41, 6);
    printf("Written by Joe Biellik");
    textmode_set_colors(COLOR_LTGRAY, COLOR_BLACK);
    textmode_move_cursor(0, 9);

    fpu_init();
    gdt_init();
    idt_init();

    __asm __volatile__("sti"); // Start interrupts

    pit_init();
    serial_init();

    // Test serial
    int8_t buffer[50];
    sprintf(buffer, "SimpleOS %i.%i.%i (%s)\n", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_DATE);
    serial_write(SERIAL_PORT_A, buffer);

    // Test RTC
    datetime_t *dt = 0;
    rtc_get(dt);
    printf("Started at %02i-%02i-%02i %02i:%02i:%02i\n\n", dt->year, dt->month, dt->day, dt->hour, dt->min, dt->sec);

    // Test CPU
    cpu_detect();

    printf("\n");

    // Test PCI
    pci_scan();

    for (;;);

    return 0x12345678;
}
Пример #4
0
void map_init(void)
{
	static char *cpu[]={"808","80C8","NEC V","8018","8028"};
	static char *fpu[]={"87","287+"};
	cpu_detect();
	kputs("Processor: ");
	kputs(cpu[cpu_type]);
	if (cpu_type == 2)
		kputs(bus_width == 8 ? "20" : "30");
	else
		kputs(bus_width == 8 ? "8" : "6");
	if (cpu_type == 4)
		kputs("+");
	if (fpu_type) {
		kputs(" / 80");
		kputs(fpu[fpu_type]);
	}
	kputs("\n");
	/* Should we do bogomips 8) */
//	init_irq();
}
Пример #5
0
/* First C function to be called on Xen boot */
asmlinkage void __init xen_start_kernel(void)
{
	pgd_t *pgd;

	if (!xen_start_info)
		return;

	xen_domain_type = XEN_PV_DOMAIN;

	/* Install Xen paravirt ops */
	pv_info = xen_info;
	pv_init_ops = xen_init_ops;
	pv_time_ops = xen_time_ops;
	pv_cpu_ops = xen_cpu_ops;
	pv_apic_ops = xen_apic_ops;
	pv_mmu_ops = xen_mmu_ops;

#ifdef CONFIG_X86_64
	/*
	 * Setup percpu state.  We only need to do this for 64-bit
	 * because 32-bit already has %fs set properly.
	 */
	load_percpu_segment(0);
#endif

	xen_init_irq_ops();
	xen_init_cpuid_mask();

#ifdef CONFIG_X86_LOCAL_APIC
	/*
	 * set up the basic apic ops.
	 */
	set_xen_basic_apic_ops();
#endif

	xen_setup_features();

	if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
		pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
		pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
	}

	machine_ops = xen_machine_ops;

	/*
	 * The only reliable way to retain the initial address of the
	 * percpu gdt_page is to remember it here, so we can go and
	 * mark it RW later, when the initial percpu area is freed.
	 */
	xen_initial_gdt = &per_cpu(gdt_page, 0);

	xen_smp_init();

	/* Get mfn list */
	if (!xen_feature(XENFEAT_auto_translated_physmap))
		xen_build_dynamic_phys_to_machine();

	pgd = (pgd_t *)xen_start_info->pt_base;

	/* Prevent unwanted bits from being set in PTEs. */
	__supported_pte_mask &= ~_PAGE_GLOBAL;
	if (!xen_initial_domain())
		__supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);

#ifdef CONFIG_X86_64
	/* Work out if we support NX */
	check_efer();
#endif

	/* Don't do the full vcpu_info placement stuff until we have a
	   possible map and a non-dummy shared_info. */
	per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];

	local_irq_disable();
	early_boot_irqs_off();

	xen_raw_console_write("mapping kernel into physical memory\n");
	pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);

	init_mm.pgd = pgd;

	/* keep using Xen gdt for now; no urgent need to change it */

	pv_info.kernel_rpl = 1;
	if (xen_feature(XENFEAT_supervisor_mode_kernel))
		pv_info.kernel_rpl = 0;

	/* set the limit of our address space */
	xen_reserve_top();

#ifdef CONFIG_X86_32
	/* set up basic CPUID stuff */
	cpu_detect(&new_cpu_data);
	new_cpu_data.hard_math = 1;
	new_cpu_data.wp_works_ok = 1;
	new_cpu_data.x86_capability[0] = cpuid_edx(1);
#endif

	/* Poke various useful things into boot_params */
	boot_params.hdr.type_of_loader = (9 << 4) | 0;
	boot_params.hdr.ramdisk_image = xen_start_info->mod_start
		? __pa(xen_start_info->mod_start) : 0;
	boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
	boot_params.hdr.cmd_line_ptr = __pa(xen_start_info->cmd_line);

	if (!xen_initial_domain()) {
		add_preferred_console("xenboot", 0, NULL);
		add_preferred_console("tty", 0, NULL);
		add_preferred_console("hvc", 0, NULL);
	}

	xen_raw_console_write("about to get started...\n");

	/* Start the world */
#ifdef CONFIG_X86_32
	i386_start_kernel();
#else
	x86_64_start_reservations((char *)__pa_symbol(&boot_params));
#endif
}
Пример #6
0
/* First C function to be called on Xen boot */
asmlinkage void __init xen_start_kernel(void)
{
	pgd_t *pgd;

	if (!xen_start_info)
		return;

	xen_domain_type = XEN_PV_DOMAIN;

	/* Install Xen paravirt ops */
	pv_info = xen_info;
	pv_init_ops = xen_init_ops;
	pv_time_ops = xen_time_ops;
	pv_cpu_ops = xen_cpu_ops;
	pv_apic_ops = xen_apic_ops;

	x86_init.resources.memory_setup = xen_memory_setup;
	x86_init.oem.arch_setup = xen_arch_setup;
	x86_init.oem.banner = xen_banner;

	x86_init.timers.timer_init = xen_time_init;
	x86_init.timers.setup_percpu_clockev = x86_init_noop;
	x86_cpuinit.setup_percpu_clockev = x86_init_noop;

	x86_platform.calibrate_tsc = xen_tsc_khz;
	x86_platform.get_wallclock = xen_get_wallclock;
	x86_platform.set_wallclock = xen_set_wallclock;

	/*
	 * Set up some pagetable state before starting to set any ptes.
	 */

	xen_init_mmu_ops();

	/* Prevent unwanted bits from being set in PTEs. */
	__supported_pte_mask &= ~_PAGE_GLOBAL;
	if (!xen_initial_domain())
		__supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);

	__supported_pte_mask |= _PAGE_IOMAP;

	/*
	 * Prevent page tables from being allocated in highmem, even
	 * if CONFIG_HIGHPTE is enabled.
	 */
	__userpte_alloc_gfp &= ~__GFP_HIGHMEM;

#ifdef CONFIG_X86_64
	/* Work out if we support NX */
	check_efer();
#endif

	xen_setup_features();

	/* Get mfn list */
	if (!xen_feature(XENFEAT_auto_translated_physmap))
		xen_build_dynamic_phys_to_machine();

	/*
	 * Set up kernel GDT and segment registers, mainly so that
	 * -fstack-protector code can be executed.
	 */
	xen_setup_stackprotector();

	xen_init_irq_ops();
	xen_init_cpuid_mask();

#ifdef CONFIG_X86_LOCAL_APIC
	/*
	 * set up the basic apic ops.
	 */
	set_xen_basic_apic_ops();
#endif

	if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
		pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
		pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
	}

	machine_ops = xen_machine_ops;

	/*
	 * The only reliable way to retain the initial address of the
	 * percpu gdt_page is to remember it here, so we can go and
	 * mark it RW later, when the initial percpu area is freed.
	 */
	xen_initial_gdt = &per_cpu(gdt_page, 0);

	xen_smp_init();

	pgd = (pgd_t *)xen_start_info->pt_base;

	/* Don't do the full vcpu_info placement stuff until we have a
	   possible map and a non-dummy shared_info. */
	per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];

	local_irq_disable();
	early_boot_irqs_off();

	xen_raw_console_write("mapping kernel into physical memory\n");
	pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);

	init_mm.pgd = pgd;

	/* keep using Xen gdt for now; no urgent need to change it */

	pv_info.kernel_rpl = 1;
	if (xen_feature(XENFEAT_supervisor_mode_kernel))
		pv_info.kernel_rpl = 0;

	/* set the limit of our address space */
	xen_reserve_top();

#ifdef CONFIG_X86_32
	/* set up basic CPUID stuff */
	cpu_detect(&new_cpu_data);
	new_cpu_data.hard_math = 1;
	new_cpu_data.wp_works_ok = 1;
	new_cpu_data.x86_capability[0] = cpuid_edx(1);
#endif

	/* Poke various useful things into boot_params */
	boot_params.hdr.type_of_loader = (9 << 4) | 0;
	boot_params.hdr.ramdisk_image = xen_start_info->mod_start
		? __pa(xen_start_info->mod_start) : 0;
	boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
	boot_params.hdr.cmd_line_ptr = __pa(xen_start_info->cmd_line);

	if (!xen_initial_domain()) {
		add_preferred_console("xenboot", 0, NULL);
		add_preferred_console("tty", 0, NULL);
		add_preferred_console("hvc", 0, NULL);
	}

	xen_raw_console_write("about to get started...\n");

	xen_setup_runstate_info(0);

	/* Start the world */
#ifdef CONFIG_X86_32
	i386_start_kernel();
#else
	x86_64_start_reservations((char *)__pa_symbol(&boot_params));
#endif
}
Пример #7
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		main
 * @BRIEF		main entry point
 * @RETURNS		0 on success
 *			OMAPCONF_ERR_CPU
 *			OMAPCONF_ERR_ARG
 *			OMAPCONF_ERR_REG_ACCESS
 * @param[in, out]	argc: shell input argument number
 * @param[in, out]	argv: shell input argument(s)
 * @DESCRIPTION		main entry point
 *//*------------------------------------------------------------------------ */
int main(int argc, char *argv[])
{
	int ret;
	struct sigaction act;
	unsigned int start, end, time, delay;
	double sampling_rate;
	char *prefix;
	char *cfgfile;
	int c;

	cpu_found = 0;
	ret = 0;

	/* Register signal handler in order to catch incorrect memory access. */
	act.sa_sigaction = &main_sigbus_handler;
	act.sa_flags = SA_SIGINFO;
	sigaction(SIGBUS, &act, NULL);

	/* Some of the omapconf functions do not support DEVICE OFF Mode,
	 * so by default acquire a wakelock if OS is Android.
	 */
	if (os_is_android())
		wakelock_acquire();

	/* To be case-insensitive, lowercase all arguments */
	main_arguments_lowercase(argc, argv);

	/* Scan user arguments for options */
	argc--;
	argv++;
	ret = main_options_scan(&argc, &argv);
	if (ret < 0)
		goto main_exit;

	if (!cpu_is_forced()) {
		/* Detect CPU if not user-enforced */
		ret = cpu_detect();
		switch (ret) {
		case 0:
			cpu_found = 1;
			break;

		case OMAPCONF_ERR_REG_ACCESS:
			omapconf_revision_show(stdout);
			printf("'/dev/mem' could not be opened.\n");
			printf(
				"Privileged access required to run omapconf.\n\n");
			ret = OMAPCONF_ERR_REG_ACCESS;
			goto main_exit;

		case OMAPCONF_ERR_CPU:
			printf(
				"Warning: chip not recognized, running in safe mode (only platform-generic functions allowed).\n\n");
			break;

		case OMAPCONF_ERR_UNEXPECTED:
		default:
			omapconf_revision_show(stdout);
			printf("Unexpected error, sorry ... (%d)\n\n", ret);
			ret = OMAPCONF_ERR_UNEXPECTED;
			goto main_exit;
		}

	}

	if (argc == 0) {
		help(HELP_USAGE);
		ret = OMAPCONF_ERR_ARG;
		goto main_exit;
	}

	/* Platform-generic functions, no need to detect cpu */
	if (strcmp(argv[0], "--help") == 0) {
		omapconf_revision_show(stdout);
		help(HELP_ALL);
		ret = 0;
		goto main_exit;
	} else if (strcmp(argv[0], "--version") == 0) {
		omapconf_revision_show(stdout);
		ret = 0;
		goto main_exit;
	} else if (strcmp(argv[0], "--cpuinfo") == 0) {
		omapconf_revision_show(stdout);
		chips_info_show(stdout, 1);
		ret = 0;
		goto main_exit;
	} else if (strcmp(argv[0], "--buildinfo") == 0) {
		omapconf_revision_show(stdout);
		release_info_show(stdout);
		ret = 0;
		goto main_exit;
	} else if (strcmp(argv[0], "read") == 0) {
		if ((argc >= 2) &&
			(strcmp(argv[1], "audioic") == 0)) {
			goto main_platform_specific;
		} else if ((argc >= 2) &&
			(strcmp(argv[1], "i2c") == 0)) {
			if (argc < 5) {
				ret = err_arg_missing_msg_show(HELP_I2C_RW);
				goto main_exit;
			} else if (argc == 5) {
				ret = main_i2c_read(argc, argv);
				goto main_exit;
			} else {
				ret = err_arg_too_many_msg_show(HELP_I2C_RW);
				goto main_exit;
			}
		}

		if (argc == 2) {
			ret = main_readreg(uppercase(argv[1]), "hex");
			goto main_exit;
		} else if (argc == 3) {
			ret = main_readreg(uppercase(argv[1]),
				lowercase(argv[2]));
			goto main_exit;
		} else {
			ret = err_arg_too_many_msg_show(HELP_RW);
			goto main_exit;
		}
	} else if (strcmp(argv[0], "write") == 0) {
		if ((argc >= 2) &&
			(strcmp(argv[1], "audioic") == 0)) {
			goto main_platform_specific;
		} else if ((argc >= 2) &&
			(strcmp(argv[1], "i2c") == 0)) {
			if (argc < 6) {
				ret = err_arg_missing_msg_show(HELP_I2C_RW);
				goto main_exit;
			} else if (argc == 6) {
				ret = main_i2c_write(argc, argv);
				goto main_exit;
			} else {
				ret = err_arg_too_many_msg_show(HELP_I2C_RW);
				goto main_exit;
			}
		}

		if (argc < 3) {
			ret = err_arg_missing_msg_show(HELP_RW);
			goto main_exit;
		} else if (argc == 3) {
			ret = main_writereg(uppercase(argv[1]),
				uppercase(argv[2]));
			goto main_exit;
		} else {
			ret = err_arg_too_many_msg_show(HELP_RW);
			goto main_exit;
		}
	} else if (strcmp(argv[0], "clear") == 0) {
		if ((argc >= 2) && (strcmp(argv[1], "bit") == 0)) {
			ret = main_clearbit(argc, argv);
			goto main_exit;
		}
	} else if (strcmp(argv[0], "set") == 0) {
		if ((argc >= 2) && (strcmp(argv[1], "bit") == 0)) {
			ret = main_setbit(argc, argv);
			goto main_exit;
		}
	} else if (strcmp(argv[0], "i2c") == 0) {
		if ((argc != 5) && (argc != 6)) {
			help(HELP_I2C_RW);
			ret = OMAPCONF_ERR_ARG;
			goto main_exit;
		}
		if (strcmp(argv[1], "read") == 0) {
			ret = main_i2c_read(argc, argv);
			goto main_exit;
		} else if (strcmp(argv[1], "write") == 0) {
			ret = main_i2c_write(argc, argv);
			goto main_exit;
		} else {
			ret = err_arg_msg_show(HELP_I2C_RW);
			goto main_exit;
		}
	} else if ((strcmp(argv[0], "dump") == 0)
		&& (argc == 3)
		&& (sscanf(argv[1], "0x%08x", &start) == 1)
		&& (sscanf(argv[2], "0x%08x", &end) == 1)) {
		ret = mem_address_range_dump(start, end);
		goto main_exit;
	} else if ((argc >= 3) &&
		(strcmp(argv[0], "trace") == 0) &&
		(strcmp(argv[1], "perf") == 0) &&
		(strcmp(argv[2], "setup") == 0)) {
		if (argc == 3)
			ret = trace_perf_setup(
				(char *) trace_perf_default_cfgfile);
		else
			ret = trace_perf_setup(argv[3]);
		goto main_exit;
	} else if ((argc >= 2) &&
		(strcmp(argv[0], "trace") == 0) &&
		(strcmp(argv[1], "perf") == 0)) {
		time = TRACE_PERF_DEFAULT_CAPTURE_TIME;
		delay = TRACE_PERF_DEFAULT_DELAY_TIME;
		sampling_rate = TRACE_PERF_DEFAULT_SAMPLING_RATE;
		prefix = NULL;
		cfgfile = (char *) trace_perf_default_cfgfile;

		omapconf_revision_show(stdout);
		chips_info_show(stdout, 0);
		release_info_show(stdout);

		if (argc == 2) {
			time = TRACE_PERF_DEFAULT_CAPTURE_TIME;
			delay = TRACE_PERF_DEFAULT_DELAY_TIME;
			sampling_rate = TRACE_PERF_DEFAULT_SAMPLING_RATE;
			prefix = NULL;
			cfgfile = (char *) trace_perf_default_cfgfile;
		} else if (argc == 3) {
			ret = sscanf(argv[2], "%u", &time);
			if (ret != 1) {
				help(HELP_TRACE);
				ret = OMAPCONF_ERR_ARG;
				goto main_exit;
			}
		} else {
			while ((c = getopt(argc, argv, "d:t:s:p:c:")) != -1) {
				switch (c) {
				case 'd': /* delay time */
					ret = sscanf(optarg, "%u", &delay);
					if (ret != 1) {
						ret = err_arg_msg_show(
							HELP_TRACE);
						goto main_exit;
					}
					break;
				case 't': /* capture time */
					ret = sscanf(optarg, "%u", &time);
					if (ret != 1) {
						ret = err_arg_msg_show(
							HELP_TRACE);
						goto main_exit;
					}
					break;
				case 's': /* sampling rate */
					ret = sscanf(optarg, "%lf",
						&sampling_rate);
					if (ret != 1) {
						ret = err_arg_msg_show(
							HELP_TRACE);
						goto main_exit;
					}
					break;
				case 'p': /* file prefix */
					prefix = optarg;
					break;
				case 'c': /* configuration file */
					cfgfile = optarg;
					break;
				default:
					ret = err_arg_msg_show(HELP_TRACE);
					goto main_exit;
				}
			}
		}
		if (cpu_is_omap44xx())
			main44xx_init();
		else if (cpu_is_omap54xx())
			dpll54xx_init();
		ret = trace_perf_capture(cfgfile, prefix,
				sampling_rate, time, delay);
		goto main_exit;
	}


	/* Platform-specific functions */
main_platform_specific:
	if (cpu_found) {
		omapconf_revision_show(stdout);
		chips_info_show(stdout, 0);
		release_info_show(stdout);
		if (cpu_is_omap44xx()) {
			ret = main44xx(argc, argv);
			goto main_exit;
		} else if (cpu_is_omap54xx()) {
			ret = main54xx(argc, argv);
			goto main_exit;
		} else if (cpu_is_dra7xx()) {
			ret = main_dra7xx(argc, argv);
			goto main_exit;
		} else {
			printf("Unsupported chip, sorry ...\n\n");
			ret = OMAPCONF_ERR_CPU;
			goto main_exit;
		}
	} else {
		printf("Function disabled in safe mode, sorry ...\n\n");
		ret = OMAPCONF_ERR_NOT_AVAILABLE;
		goto main_exit;
	}

main_exit:
	if (os_is_android())
		wakelock_release();

	/* Unmap last mapped memory page */
	mem_unmap();

	/* Deinitializations */
	if (cpu_get() != OMAP_MAX) {
		opp_deinit();
		voltdm_deinit();
		temp_sensor_deinit();
		module_deinit();
		powerdm_deinit();
		clockdm_deinit();
	}

	return ret;
}
Пример #8
0
MVRecalculate::MVRecalculate(PClip _super, PClip _vectors, int _thSAD, int _smooth, int _blksizex, int _blksizey,
                     int st, int stp, int lambda, bool chroma,
                     int _pnew, int _overlapx, int _overlapy,
					 const char* _outfilename, int _dctmode, int _divide,
					 int _sadx264, bool _isse, IScriptEnvironment* env) :
GenericVideoFilter(_super),
mvClip(_vectors, 999999, 255, env)
{
    outfilename = _outfilename;
    smooth = _smooth;

   	// get parameters of super clip - v2.0
	SuperParams64Bits params;
    memcpy(&params, &child->GetVideoInfo().num_audio_samples, 8);
    int nHeight = params.nHeight;
    int nSuperHPad = params.nHPad;
    int nSuperVPad = params.nVPad;
    int nSuperPel = params.nPel;
    int nSuperModeYUV = params.nModeYUV;
    int nSuperLevels = params.nLevels;

    nModeYUV = chroma ? YUVPLANES : YPLANE;
    if ((nModeYUV & nSuperModeYUV) != nModeYUV)
			env->ThrowError("MRecalculate: super clip does not contain needed color data");

    MVAnalysisData *pAnalyseFilter = reinterpret_cast<MVAnalysisData *>(_vectors->GetVideoInfo().nchannels);

	analysisData.nWidth = pAnalyseFilter->GetWidth();
	analysisData.nHeight = pAnalyseFilter->GetHeight();
	analysisData.pixelType = pAnalyseFilter->GetPixelType();
	analysisData.yRatioUV = (vi.IsYV12()) ? 2 : 1;
	analysisData.xRatioUV = 2; // for YV12 and YUY2, really do not used and assumed to 2

    pSrcGOF = new MVGroupOfFrames(nSuperLevels, analysisData.nWidth, analysisData.nHeight, nSuperPel, nSuperHPad, nSuperVPad, nSuperModeYUV, _isse, analysisData.yRatioUV);
    pRefGOF = new MVGroupOfFrames(nSuperLevels, analysisData.nWidth, analysisData.nHeight, nSuperPel, nSuperHPad, nSuperVPad, nSuperModeYUV, _isse, analysisData.yRatioUV);
    int nSuperWidth = child->GetVideoInfo().width;
    int nSuperHeight = child->GetVideoInfo().height;

//	if (video->GetVideoInfo().width != analysisData.nWidth ||
//	    video->GetVideoInfo().height != analysisData.nHeight ||
//	    video->GetVideoInfo().pixel_type != analysisData.pixelType )
//	        env->ThrowError("MVRecalculate: video must have same properties !");

    if (nHeight != analysisData.nHeight || nSuperWidth - 2*nSuperHPad != analysisData.nWidth)
    		env->ThrowError("MRecalculate : wrong frame size");
	if (vi.pixel_type != analysisData.pixelType )
	        env->ThrowError("MRecalculate: wrong pixel type");

	analysisData.nBlkSizeX = _blksizex;
	analysisData.nBlkSizeY = _blksizey;
	if (( analysisData.nBlkSizeX != 4 || analysisData.nBlkSizeY != 4) &&
        ( analysisData.nBlkSizeX != 8 || analysisData.nBlkSizeY != 4) &&
        ( analysisData.nBlkSizeX != 8 || analysisData.nBlkSizeY != 8 ) &&
        ( analysisData.nBlkSizeX != 16 || analysisData.nBlkSizeY != 2 ) &&
        ( analysisData.nBlkSizeX != 16 || analysisData.nBlkSizeY != 8 ) &&
        ( analysisData.nBlkSizeX != 16 || analysisData.nBlkSizeY != 16 ) &&
        ( analysisData.nBlkSizeX != 32 || analysisData.nBlkSizeY != 16))
		env->ThrowError("MVRecalculate: Block's size must be 4x4, 8x4, 8x8, 16x2, 16x8, 16x16, 32x16");

//	if (!vi.IsYV12() && !vi.IsYUY2())
//		env->ThrowError("MVRecalculate: Clip must be YV12 or YUY2");

//   analysisData.nPel = pel;
//	if (( analysisData.nPel != 1 ) && ( analysisData.nPel != 2 ) && ( analysisData.nPel != 4 ))
//		env->ThrowError("MVRecalculate: pel has to be 1 or 2 or 4");
	analysisData.nPel =	pAnalyseFilter->GetPel();

//   analysisData.nDeltaFrame = df;
//   if ( analysisData.nDeltaFrame < 1 )
//      analysisData.nDeltaFrame = 1;
   analysisData.nDeltaFrame = pAnalyseFilter->GetDeltaFrame();

   if (_overlapx<0 || _overlapx >= _blksizex || _overlapy<0 || _overlapy >= _blksizey)
		env->ThrowError("MRecalculate: overlap must be less than block size");

//   if (_overlapx%2 || (_overlapy%2 >0 && vi.IsYV12()))
   if (_overlapx%2 || (_overlapy%2 >0 && vi.IsYV12()))
		env->ThrowError("MRecalculate: overlap must be more even");

	if (_divide != 0 && (_blksizex < 8 && _blksizey < 8) )
		env->ThrowError("MRecalculate: Block sizes must be 8 or more for divide mode");
   if (_divide != 0 && (_overlapx%4 || (_overlapy%4 >0 && vi.IsYV12() ) || (_overlapy%2 >0 && vi.IsYUY2() )  ))
		env->ThrowError("MRecalculate: overlap must be more even for divide mode");

    divideExtra = _divide;

    headerSize = max(4 + sizeof(analysisData), 256); // include itself, but usually equal to 256 :-)

	analysisData.nOverlapX = _overlapx;
	analysisData.nOverlapY = _overlapy;

	int nBlkX = (analysisData.nWidth - analysisData.nOverlapX) / (analysisData.nBlkSizeX - analysisData.nOverlapX);
//	if (analysisData.nWidth > (analysisData.nBlkSize - analysisData.nOverlap) * nBlkX )
//		nBlkX += 1;

	int nBlkY = (analysisData.nHeight - analysisData.nOverlapY) / (analysisData.nBlkSizeY - analysisData.nOverlapY);
//	if (analysisData.nHeight > (analysisData.nBlkSize - analysisData.nOverlap) * nBlkY )
//		nBlkY += 1;

	analysisData.nBlkX = nBlkX;
	analysisData.nBlkY = nBlkY;
//	int nWidth_B = nBlkX*(analysisData.nBlkSizeX - analysisData.nOverlapX) + analysisData.nOverlapX;
//	int nHeight_B = nBlkY*(analysisData.nBlkSizeY - analysisData.nOverlapY) + analysisData.nOverlapY;

//	analysisData.nLvCount = ilog2(	((nBlkX) > (nBlkY)) ? (nBlkY) : (nBlkX) ) - lv;
//	analysisData.nLvCount = ( analysisData.nLvCount < 1 ) ? 1 : analysisData.nLvCount;
	analysisData.nLvCount = 1;

//	analysisData.isBackward = isb;
	analysisData.isBackward = pAnalyseFilter->IsBackward();


   nLambda = lambda;
//   lsad = _lsad;
   pnew = _pnew;
//   plevel = _plevel;
//   global = _global;

   if (_dctmode == 0)
   {
		hinstFFTW3 = NULL;
		DCTc = 0;
   }
   else
   {
	   if (_isse && (_blksizex == 8) && _blksizey ==8 )
			DCTc = new DCTINT(_blksizex, _blksizey, _dctmode);
	   else
	   {
			hinstFFTW3 = LoadLibrary("fftw3.dll"); // delayed loading
			if (hinstFFTW3==NULL) env->ThrowError("MRecalculate: Can not load FFTW3.DLL !");
			DCTc = new DCTFFTW(_blksizex, _blksizey, hinstFFTW3, _dctmode); // check order x,y
	   }
	}

	switch ( st )
	{
	case 0 :
		searchType = ONETIME;
		nSearchParam = ( stp < 1 ) ? 1 : stp;
		break;
	case 1 :
		searchType = NSTEP;
		nSearchParam = ( stp < 0 ) ? 0 : stp;
		break;
	case 3 :
		searchType = EXHAUSTIVE;
		nSearchParam = ( stp < 1 ) ? 1 : stp;
		break;
	case 2 :
	default :
		searchType = LOGARITHMIC;
		nSearchParam = ( stp < 1 ) ? 1 : stp;
	}

//    nPelSearch = ( _pelSearch < analysisData.nPel) ? analysisData.nPel : _pelSearch; // not below value of pel at finest level

//	analysisData.pixelType = vi.pixel_type;

   analysisData.nFlags = 0;
   analysisData.nFlags |= _isse ? MOTION_USE_ISSE : 0;
   analysisData.nFlags |= analysisData.isBackward ? MOTION_IS_BACKWARD : 0;
   analysisData.nFlags |= chroma ? MOTION_USE_CHROMA_MOTION : 0;
/*
#define CPU_CACHELINE_32   0x00001000
#define CPU_CACHELINE_64   0x00002000
#define CPU_MMX            0x00004000
#define CPU_MMXEXT         0x00008000
#define CPU_SSE            0x00010000
#define CPU_SSE2           0x00020000
#define CPU_SSE2_IS_SLOW   0x00040000
#define CPU_SSE2_IS_FAST   0x00080000
#define CPU_SSE3           0x00100000
#define CPU_SSSE3          0x00200000
#define CPU_PHADD_IS_FAST  0x00400000
#define CPU_SSE4           0x00800000
//force MVRecalculate to use a different function for SAD / SADCHROMA (debug)
#define MOTION_USE_SSD     0x01000000
#define MOTION_USE_SATD    0x02000000
*/
	if (_sadx264 == 0)
	{
		analysisData.nFlags |= cpu_detect();
	}
	else
	{
		if ((_sadx264 > 0)&&(_sadx264 <= 12))
		{
			//force specific function
			analysisData.nFlags |= CPU_MMXEXT;
			analysisData.nFlags |= (_sadx264 == 2) ? CPU_CACHELINE_32 : 0;
			analysisData.nFlags |= ((_sadx264 == 3)||(_sadx264 == 5)||(_sadx264 == 7)) ? CPU_CACHELINE_64 : 0;
			analysisData.nFlags |= ((_sadx264 == 4)||(_sadx264 == 5)||(_sadx264 ==10)) ? CPU_SSE2_IS_FAST : 0;
			analysisData.nFlags |= (_sadx264 == 6) ? CPU_SSE3 : 0;
			analysisData.nFlags |= ((_sadx264 == 7)||(_sadx264 >=11)) ? CPU_SSSE3 : 0;
			//beta (debug)
			analysisData.nFlags |= (_sadx264 == 8) ? MOTION_USE_SSD : 0;
			analysisData.nFlags |= ((_sadx264 >= 9)&&(_sadx264 <= 12)) ? MOTION_USE_SATD : 0;
			analysisData.nFlags |= (_sadx264 ==12) ? CPU_PHADD_IS_FAST : 0;
		}
	}

//	analysisData.usePelClip = false;
//   if (pelclip && (analysisData.nPel >= 2))
//   {
//		if (pelclip->GetVideoInfo().width != video->GetVideoInfo().width*analysisData.nPel || pelclip->GetVideoInfo().height != video->GetVideoInfo().height*analysisData.nPel)
//			env->ThrowError("MVRecalculate: pelclip frame size must be Pel of source!");
//		else
//			analysisData.usePelClip = true;
//   }

	vectorFields = new GroupOfPlanes(analysisData.nWidth, analysisData.nHeight, analysisData.nBlkSizeX, analysisData.nBlkSizeY,
		analysisData.nLvCount, analysisData.nPel, analysisData.nFlags,
		analysisData.nOverlapX, analysisData.nOverlapY, analysisData.nBlkX, analysisData.nBlkY, analysisData.yRatioUV, divideExtra);

//   analysisData.nIdx = _idx;

   analysisData.nMagicKey = MOTION_MAGIC_KEY;

//   analysisData.pmvCore = &mvCore;
//   analysisData.pmvCore = pAnalyseFilter->GetMVCore();//&mvCore;
//   mvCore = analysisData.pmvCore;

   analysisData.nHPadding = nSuperHPad;
   analysisData.nVPadding = nSuperVPad;

//   mvCore->AddFrames(analysisData.nIdx, analysisData.nDeltaFrame*2+1, analysisData.nLvCount,
//	   analysisData.nWidth, analysisData.nHeight, analysisData.nPel, analysisData.nHPadding,
//	   analysisData.nVPadding, YUVPLANES, _isse, analysisData.yRatioUV);


	analysisData.nVersion = MVANALYSIS_DATA_VERSION; // MVAnalysisData and outfile format version: last update v1.8.1

	if (lstrlen(outfilename) > 0) {
		outfile = fopen(outfilename,"wb");
		if (outfile == NULL)
			env->ThrowError("MRecalculate: out file can not be created!");
		else
		{
			fwrite( &analysisData, sizeof(analysisData), 1, outfile );
			outfilebuf = new short[nBlkX*nBlkY*4]; // short vx, short vy, int SAD = 4 words = 8 bytes per block
		}
	 }
	 else {
		 outfile = NULL;
		 outfilebuf = NULL;
	 }

//	analysisData.sharp = _sharp; // pel2 interpolation type

    // vector steam packed in
	vi.height = 1;
	vi.width = headerSize/sizeof(int) + vectorFields->GetArraySize(); //v1.8.1
	vi.pixel_type = VideoInfo::CS_BGR32;
    vi.audio_samples_per_second = 0; //v1.8.1

	if (divideExtra) { //v1.8.1
        memcpy(&analysisDataDivided, &analysisData, sizeof(analysisData));
        analysisDataDivided.nBlkX = analysisData.nBlkX * 2;
        analysisDataDivided.nBlkY = analysisData.nBlkY * 2;
        analysisDataDivided.nBlkSizeX = analysisData.nBlkSizeX / 2;
        analysisDataDivided.nBlkSizeY = analysisData.nBlkSizeY / 2;
        analysisDataDivided.nOverlapX = analysisData.nOverlapX / 2;
        analysisDataDivided.nOverlapY = analysisData.nOverlapY / 2;
        analysisDataDivided.nLvCount = analysisData.nLvCount + 1;
        vi.nchannels = reinterpret_cast<int>(&analysisDataDivided);
//        analysisDataDivided.pmvCore = mvCore;
	}
	else
	{

   //  we'll transmit to the processing filters a handle
   // on the analyzing filter itself ( it's own pointer ), in order
   // to activate the right parameters.
        vi.nchannels = reinterpret_cast<int>(&analysisData);
	}

   if ( chroma ) // normalize threshold to block size
      thSAD = _thSAD * (analysisData.nBlkSizeX * analysisData.nBlkSizeY) / (8 * 8) * (1 + analysisData.yRatioUV) / analysisData.yRatioUV;
   else
      thSAD = _thSAD * (analysisData.nBlkSizeX * analysisData.nBlkSizeY) / (8 * 8);


}
static void VS_CC mvrecalculateCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) {
    MVRecalculateData d;
    MVRecalculateData *data;

    int err;

    d.thSAD = int64ToIntS(vsapi->propGetInt(in, "thsad", 0, &err));
    if (err)
        d.thSAD = 200;

    d.smooth = int64ToIntS(vsapi->propGetInt(in, "smooth", 0, &err));
    if (err)
        d.smooth = 1;

    d.blksize = int64ToIntS(vsapi->propGetInt(in, "blksize", 0, &err));
    if (err)
        d.blksize = 8;

    d.blksizev = int64ToIntS(vsapi->propGetInt(in, "blksizev", 0, &err));
    if (err)
        d.blksizev = d.blksize;

    d.search = int64ToIntS(vsapi->propGetInt(in, "search", 0, &err));
    if (err)
        d.search = 4;

    d.searchparam = int64ToIntS(vsapi->propGetInt(in, "searchparam", 0, &err));
    if (err)
        d.searchparam = 2;

    d.chroma = !!vsapi->propGetInt(in, "chroma", 0, &err);
    if (err)
        d.chroma = 1;

    d.truemotion = !!vsapi->propGetInt(in, "truemotion", 0, &err);
    if (err)
        d.truemotion = 1;

    d.nLambda = int64ToIntS(vsapi->propGetInt(in, "lambda", 0, &err));
    if (err)
        d.nLambda = d.truemotion ? (1000 * d.blksize * d.blksizev / 64) : 0;

    d.pnew = int64ToIntS(vsapi->propGetInt(in, "pnew", 0, &err));
    if (err)
        d.pnew = d.truemotion ? 50 : 0; // relative to 256

    d.overlap = int64ToIntS(vsapi->propGetInt(in, "overlap", 0, &err));

    d.overlapv = int64ToIntS(vsapi->propGetInt(in, "overlapv", 0, &err));
    if (err)
        d.overlapv = d.overlap;

    d.dctmode = int64ToIntS(vsapi->propGetInt(in, "dct", 0, &err));

    d.divideExtra = int64ToIntS(vsapi->propGetInt(in, "divide", 0, &err));

    d.isse = !!vsapi->propGetInt(in, "isse", 0, &err);
    if (err)
        d.isse = 1;

    d.meander = !!vsapi->propGetInt(in, "meander", 0, &err);
    if (err)
        d.meander = 1;

    d.fields = !!vsapi->propGetInt(in, "fields", 0, &err);

    d.tff = !!vsapi->propGetInt(in, "tff", 0, &err);
    d.tffexists = err;


    if (d.search < 0 || d.search > 7) {
        vsapi->setError(out, "Recalculate: search must be between 0 and 7 (inclusive).");
        return;
    }

    if (d.dctmode < 0 || d.dctmode > 10) {
        vsapi->setError(out, "Recalculate: dct must be between 0 and 10 (inclusive).");
        return;
    }

    if (d.dctmode >= 5 && !((d.blksize == 4 && d.blksizev == 4) ||
                (d.blksize == 8 && d.blksizev == 4) ||
                (d.blksize == 8 && d.blksizev == 8) ||
                (d.blksize == 16 && d.blksizev == 8) ||
                (d.blksize == 16 && d.blksizev == 16))) {
        vsapi->setError(out, "Recalculate: dct 5..10 can only work with 4x4, 8x4, 8x8, 16x8, and 16x16 blocks.");
        return;
    }

    if (d.divideExtra < 0 || d.divideExtra > 2) {
        vsapi->setError(out, "Recalculate: divide must be between 0 and 2 (inclusive).");
        return;
    }


    d.analysisData.nBlkSizeX = d.blksize;
    d.analysisData.nBlkSizeY = d.blksizev;
    if ((d.analysisData.nBlkSizeX != 4  || d.analysisData.nBlkSizeY != 4) &&
            (d.analysisData.nBlkSizeX != 8  || d.analysisData.nBlkSizeY != 4) &&
            (d.analysisData.nBlkSizeX != 8  || d.analysisData.nBlkSizeY != 8) &&
            (d.analysisData.nBlkSizeX != 16 || d.analysisData.nBlkSizeY != 2) &&
            (d.analysisData.nBlkSizeX != 16 || d.analysisData.nBlkSizeY != 8) &&
            (d.analysisData.nBlkSizeX != 16 || d.analysisData.nBlkSizeY != 16) &&
            (d.analysisData.nBlkSizeX != 32 || d.analysisData.nBlkSizeY != 32) &&
            (d.analysisData.nBlkSizeX != 32 || d.analysisData.nBlkSizeY != 16)) {

        vsapi->setError(out, "Recalculate: the block size must be 4x4, 8x4, 8x8, 16x2, 16x8, 16x16, 32x16, or 32x32.");
        return;
    }


    if (d.overlap < 0 || d.overlap > d.blksize / 2 ||
        d.overlapv < 0 || d.overlapv > d.blksizev / 2) {
        vsapi->setError(out, "Recalculate: overlap must be at most half of blksize, overlapv must be at most half of blksizev, and they both need to be at least 0.");
        return;
    }

    if (d.divideExtra && (d.blksize < 8 && d.blksizev < 8) ) {
        vsapi->setError(out, "Recalculate: blksize and blksizev must be at least 8 when divide=True.");
        return;
    }

    d.analysisData.nOverlapX = d.overlap;
    d.analysisData.nOverlapY = d.overlapv;

    SearchType searchTypes[] = { ONETIME, NSTEP, LOGARITHMIC, EXHAUSTIVE, HEX2SEARCH, UMHSEARCH, HSEARCH, VSEARCH };
    d.searchType = searchTypes[d.search];

    if (d.searchType == NSTEP)
        d.nSearchParam = ( d.searchparam < 0 ) ? 0 : d.searchparam;
    else
        d.nSearchParam = ( d.searchparam < 1 ) ? 1 : d.searchparam;


    // XXX maybe get rid of these two
    // Bleh, they're checked by client filters. Though it's kind of pointless.
    d.analysisData.nMagicKey = MOTION_MAGIC_KEY;
    d.analysisData.nVersion = MVANALYSIS_DATA_VERSION; // MVAnalysisData and outfile format version: last update v1.8.1


    d.headerSize = VSMAX(4 + sizeof(d.analysisData), 256); // include itself, but usually equal to 256 :-)


    d.node = vsapi->propGetNode(in, "super", 0, 0);
    d.supervi = vsapi->getVideoInfo(d.node);

    if (d.overlap % (1 << d.supervi->format->subSamplingW) ||
        d.overlapv % (1 << d.supervi->format->subSamplingH)) {
        vsapi->setError(out, "Recalculate: The requested overlap is incompatible with the super clip's subsampling.");
        vsapi->freeNode(d.node);
        return;
    }

    if (d.divideExtra && (d.overlap % (2 << d.supervi->format->subSamplingW) ||
                          d.overlapv % (2 << d.supervi->format->subSamplingH))) { // subsampling times 2
        vsapi->setError(out, "Recalculate: overlap and overlapv must be multiples of 2 or 4 when divide=True, depending on the super clip's subsampling.");
        vsapi->freeNode(d.node);
        return;
    }


    char errorMsg[1024];
    const VSFrameRef *evil = vsapi->getFrame(0, d.node, errorMsg, 1024);
    if (!evil) {
        vsapi->setError(out, std::string("Recalculate: failed to retrieve first frame from super clip. Error message: ").append(errorMsg).c_str());
        vsapi->freeNode(d.node);
        return;
    }
    const VSMap *props = vsapi->getFramePropsRO(evil);
    int evil_err[6];
    int nHeight = int64ToIntS(vsapi->propGetInt(props, "Super_height", 0, &evil_err[0]));
    d.nSuperHPad = int64ToIntS(vsapi->propGetInt(props, "Super_hpad", 0, &evil_err[1]));
    d.nSuperVPad = int64ToIntS(vsapi->propGetInt(props, "Super_vpad", 0, &evil_err[2]));
    d.nSuperPel = int64ToIntS(vsapi->propGetInt(props, "Super_pel", 0, &evil_err[3]));
    d.nSuperModeYUV = int64ToIntS(vsapi->propGetInt(props, "Super_modeyuv", 0, &evil_err[4]));
    d.nSuperLevels = int64ToIntS(vsapi->propGetInt(props, "Super_levels", 0, &evil_err[5]));
    vsapi->freeFrame(evil);

    for (int i = 0; i < 6; i++)
        if (evil_err[i]) {
            vsapi->setError(out, "Recalculate: required properties not found in first frame of super clip. Maybe clip didn't come from mv.Super? Was the first frame trimmed away?");
            vsapi->freeNode(d.node);
            return;
        }


    if (d.supervi->format->colorFamily == cmGray)
        d.chroma = 0;

    d.nModeYUV = d.chroma ? YUVPLANES : YPLANE;

    if ((d.nModeYUV & d.nSuperModeYUV) != d.nModeYUV) { //x
        vsapi->setError(out, "Recalculate: super clip does not contain needed colour data.");
        vsapi->freeNode(d.node);
        return;
    }

    d.vectors = vsapi->propGetNode(in, "vectors", 0, NULL);
    d.vi = vsapi->getVideoInfo(d.vectors);

    evil = vsapi->getFrame(0, d.vectors, errorMsg, 1024);
    if (!evil) {
        vsapi->setError(out, std::string("Recalculate: failed to retrieve first frame from vectors clip. Error message: ").append(errorMsg).c_str());
        vsapi->freeNode(d.node);
        vsapi->freeNode(d.vectors);
        return;
    }

    // XXX This really should be passed as a frame property.
    const MVAnalysisData *pAnalyseFilter = reinterpret_cast<const MVAnalysisData *>(vsapi->getReadPtr(evil, 0) + sizeof(int));

    d.analysisData.yRatioUV = pAnalyseFilter->GetYRatioUV();
    d.analysisData.xRatioUV = pAnalyseFilter->GetXRatioUV();

    d.analysisData.nWidth = pAnalyseFilter->GetWidth();
    d.analysisData.nHeight = pAnalyseFilter->GetHeight();

    d.analysisData.nDeltaFrame = pAnalyseFilter->GetDeltaFrame();
    d.analysisData.isBackward = pAnalyseFilter->IsBackward();
    vsapi->freeFrame(evil);


    d.analysisData.bitsPerSample = d.supervi->format->bitsPerSample;

    int pixelMax = (1 << d.supervi->format->bitsPerSample) - 1;
    d.thSAD = int((double)d.thSAD * pixelMax / 255.0 + 0.5);

    // normalize threshold to block size
    int referenceBlockSize = 8 * 8;
    d.thSAD = d.thSAD * (d.analysisData.nBlkSizeX * d.analysisData.nBlkSizeY) / referenceBlockSize;
    if (d.chroma)
        d.thSAD += d.thSAD / (d.analysisData.xRatioUV * d.analysisData.yRatioUV) * 2;


    d.analysisData.nMotionFlags = 0;
    d.analysisData.nMotionFlags |= d.isse ? MOTION_USE_ISSE : 0;
    d.analysisData.nMotionFlags |= d.analysisData.isBackward ? MOTION_IS_BACKWARD : 0;
    d.analysisData.nMotionFlags |= d.chroma ? MOTION_USE_CHROMA_MOTION : 0;


    if (d.isse)
    {
        d.analysisData.nCPUFlags = cpu_detect();
    }

    if (d.supervi->format->bitsPerSample > 8)
        d.isse = 0; // needed here because MVPlane can't have isse=1 with more than 8 bits

    d.analysisData.nPel = d.nSuperPel;//x

    int nSuperWidth = d.supervi->width;
    if (nHeight != d.analysisData.nHeight || nSuperWidth - 2 * d.nSuperHPad != d.analysisData.nWidth) {
        vsapi->setError(out, "Recalculate: wrong frame size.");
        vsapi->freeNode(d.node);
        vsapi->freeNode(d.vectors);
        return;
    }

    d.analysisData.nHPadding = d.nSuperHPad; //v2.0    //x
    d.analysisData.nVPadding = d.nSuperVPad;


    int nBlkX = (d.analysisData.nWidth - d.analysisData.nOverlapX) / (d.analysisData.nBlkSizeX - d.analysisData.nOverlapX);//x
    int nBlkY = (d.analysisData.nHeight - d.analysisData.nOverlapY) / (d.analysisData.nBlkSizeY - d.analysisData.nOverlapY);

    d.analysisData.nBlkX = nBlkX;
    d.analysisData.nBlkY = nBlkY;

    d.analysisData.nLvCount = 1;


    if (d.divideExtra) { //v1.8.1
        memcpy(&d.analysisDataDivided, &d.analysisData, sizeof(d.analysisData));
        d.analysisDataDivided.nBlkX = d.analysisData.nBlkX * 2;
        d.analysisDataDivided.nBlkY = d.analysisData.nBlkY * 2;
        d.analysisDataDivided.nBlkSizeX = d.analysisData.nBlkSizeX / 2;
        d.analysisDataDivided.nBlkSizeY = d.analysisData.nBlkSizeY / 2;
        d.analysisDataDivided.nOverlapX = d.analysisData.nOverlapX / 2;
        d.analysisDataDivided.nOverlapY = d.analysisData.nOverlapY / 2;
        d.analysisDataDivided.nLvCount = d.analysisData.nLvCount + 1;
    }

    try {
        d.mvClip = new MVClipDicks(d.vectors, 8 * 8 * 255, 255, vsapi);
    } catch (MVException &e) {
        vsapi->setError(out, std::string("Recalculate: ").append(e.what()).c_str());
        vsapi->freeNode(d.node);
        vsapi->freeNode(d.vectors);
        return;
    }


    data = (MVRecalculateData *)malloc(sizeof(d));
    *data = d;

    vsapi->createFilter(in, out, "Recalculate", mvrecalculateInit, mvrecalculateGetFrame, mvrecalculateFree, fmParallel, 0, data, core);
}
MVAnalyse::MVAnalyse(PClip _child, int _blksizex, int _blksizey, int lv, int st, int stp, int _pelSearch,
                     bool isb, int lambda, bool chroma, int df,
                     int _lsad, int _plevel, bool _global, int _pnew, int _pzero, int _pglobal, int _overlapx, int _overlapy,
					 const char* _outfilename, int _dctmode, int _divide,
					 int _sadx264, int _badSAD, int _badrange, bool _isse, bool _meander, bool _temporal, bool _tryMany, IScriptEnvironment* env) :
GenericVideoFilter(_child)
{

	if (!vi.IsYV12() && !vi.IsYUY2())
		env->ThrowError("MAnalyse: Clip must be YV12 or YUY2");

	// get parameters of super clip - v2.0
	SuperParams64Bits params;
    memcpy(&params, &child->GetVideoInfo().num_audio_samples, 8);
    int nHeight = params.nHeight;
    int nSuperHPad = params.nHPad;
    int nSuperVPad = params.nVPad;
    int nSuperPel = params.nPel;
    int nSuperModeYUV = params.nModeYUV;
    int nSuperLevels = params.nLevels;

    if (nHeight <=0 || nSuperHPad<0 || nSuperHPad>=vi.width/2 || nSuperVPad<0
    || nSuperPel<1 || nSuperPel>4 || nSuperModeYUV< 0 || nSuperModeYUV>YUVPLANES || nSuperLevels<1)
		env->ThrowError("MAnalyse: wrong super clip (pseudoaudio) parameters");

	analysisData.nWidth = vi.width - nSuperHPad*2;

	analysisData.nHeight = nHeight;

	analysisData.pixelType = vi.pixel_type;
	analysisData.yRatioUV = (vi.IsYV12()) ? 2 : 1;
	analysisData.xRatioUV = 2; // for YV12 and YUY2, really do not used and assumed to 2

//		env->ThrowError("MVAnalyse: %d, %d, %d, %d, %d",nPrepHPad, nPrepVPad, nPrepPel, nPrepModeYUV, nPrepLevels );
    pSrcGOF = new MVGroupOfFrames(nSuperLevels, analysisData.nWidth, analysisData.nHeight, nSuperPel, nSuperHPad, nSuperVPad, nSuperModeYUV, _isse, analysisData.yRatioUV);
    pRefGOF = new MVGroupOfFrames(nSuperLevels, analysisData.nWidth, analysisData.nHeight, nSuperPel, nSuperHPad, nSuperVPad, nSuperModeYUV, _isse, analysisData.yRatioUV);
    nSuperWidth = child->GetVideoInfo().width;
    nSuperHeight = child->GetVideoInfo().height;


	analysisData.nBlkSizeX = _blksizex;
	analysisData.nBlkSizeY = _blksizey;
	if (( analysisData.nBlkSizeX != 4 || analysisData.nBlkSizeY != 4) &&
        ( analysisData.nBlkSizeX != 8 || analysisData.nBlkSizeY != 4) &&
        ( analysisData.nBlkSizeX != 8 || analysisData.nBlkSizeY != 8 ) &&
        ( analysisData.nBlkSizeX != 16 || analysisData.nBlkSizeY != 2 ) &&
        ( analysisData.nBlkSizeX != 16 || analysisData.nBlkSizeY != 8 ) &&
        ( analysisData.nBlkSizeX != 16 || analysisData.nBlkSizeY != 16 ) &&
        ( analysisData.nBlkSizeX != 32 || analysisData.nBlkSizeY != 32 ) &&
        ( analysisData.nBlkSizeX != 32 || analysisData.nBlkSizeY != 16))
		env->ThrowError("MAnalyse: Block's size must be 4x4, 8x4, 8x8, 16x2, 16x8, 16x16, 32x16, 32x32");


   analysisData.nPel = nSuperPel;
	if (( analysisData.nPel != 1 ) && ( analysisData.nPel != 2 ) && ( analysisData.nPel != 4 ))
		env->ThrowError("MAnalyse: pel has to be 1 or 2 or 4");

   analysisData.nDeltaFrame = df;
//   if ( analysisData.nDeltaFrame < 1 )
//      analysisData.nDeltaFrame = 1;

   if (_overlapx<0 || _overlapx >= _blksizex || _overlapy<0 || _overlapy >= _blksizey)
		env->ThrowError("MAnalyse: overlap must be less than block size");

   if (_overlapx%2 || (_overlapy%2 >0 && vi.IsYV12()))
		env->ThrowError("MAnalyse: overlap must be more even");

	if (_divide != 0 && (_blksizex < 8 && _blksizey < 8) )
		env->ThrowError("MAnalyse: Block sizes must be 8 or more for divide mode");
   if (_divide != 0 && (_overlapx%4 || (_overlapy%4 >0 && vi.IsYV12() ) || (_overlapy%2 >0 && vi.IsYUY2() )  ))
		env->ThrowError("MAnalyse: overlap must be more even for divide mode");

    divideExtra = _divide;

    headerSize = max(4 + sizeof(analysisData), 256); // include itself, but usually equal to 256 :-)

	analysisData.nOverlapX = _overlapx;
	analysisData.nOverlapY = _overlapy;

	int nBlkX = (analysisData.nWidth - analysisData.nOverlapX) / (analysisData.nBlkSizeX - analysisData.nOverlapX);

	int nBlkY = (analysisData.nHeight - analysisData.nOverlapY) / (analysisData.nBlkSizeY - analysisData.nOverlapY);

	analysisData.nBlkX = nBlkX;
	analysisData.nBlkY = nBlkY;

   int nWidth_B = (analysisData.nBlkSizeX - analysisData.nOverlapX)*nBlkX + analysisData.nOverlapX; // covered by blocks
   int nHeight_B = (analysisData.nBlkSizeY - analysisData.nOverlapY)*nBlkY + analysisData.nOverlapY;
    // calculate valid levels
    int nLevelsMax = 0;
	while (	((nWidth_B>>nLevelsMax) - analysisData.nOverlapX)/(analysisData.nBlkSizeX-analysisData.nOverlapX) > 0 &&
            ((nHeight_B>>nLevelsMax) -analysisData.nOverlapY)/(analysisData.nBlkSizeY-analysisData.nOverlapY) > 0) // at last one block
	{
		nLevelsMax++;
	}

	analysisData.nLvCount = lv > 0 ? lv :  nLevelsMax + lv;
	if (analysisData.nLvCount > nSuperLevels)
        env->ThrowError("MAnalyse: it is not enough levels  in super clip (%d), while MAnalyse asks %d", nSuperLevels, analysisData.nLvCount);
	if ( analysisData.nLvCount < 1 || analysisData.nLvCount > nLevelsMax)
        env->ThrowError("MAnalyse: non-valid number of levels (%d)", analysisData.nLvCount);

	analysisData.isBackward = isb;


   nLambda = lambda;
   lsad = _lsad*(_blksizex*_blksizey)/64;
   pnew = _pnew;
   plevel = _plevel;
   global = _global;
   pglobal = _pglobal;
   pzero = _pzero;
   badSAD = _badSAD*(_blksizex*_blksizey)/64;
   badrange = _badrange;
   meander = _meander;
   tryMany = _tryMany;

   if (_dctmode == 0)
   {
		hinstFFTW3 = NULL;
		DCTc = 0;
   }
   else
   {
	   if (_isse && (_blksizex == 8) && _blksizey ==8 )
			DCTc = new DCTINT(_blksizex, _blksizey, _dctmode);
	   else
	   {
			hinstFFTW3 = LoadLibrary("fftw3.dll"); // delayed loading
			if (hinstFFTW3==NULL) env->ThrowError("MAnalyse: Can not load FFTW3.DLL !");
			DCTc = new DCTFFTW(_blksizex, _blksizey, hinstFFTW3, _dctmode); // check order x,y
	   }
	}

	switch ( st )
	{
	case 0 :
		searchType = ONETIME;
		nSearchParam = ( stp < 1 ) ? 1 : stp;
		break;
	case 1 :
		searchType = NSTEP;
		nSearchParam = ( stp < 0 ) ? 0 : stp;
		break;
	case 3 :
		searchType = EXHAUSTIVE;
		nSearchParam = ( stp < 1 ) ? 1 : stp;
		break;
	case 4 :
		searchType = HEX2SEARCH;
		nSearchParam = ( stp < 1 ) ? 1 : stp;
		break;
	case 5 :
		searchType = UMHSEARCH;
		nSearchParam = ( stp < 1 ) ? 1 : stp; // really min is 4
		break;
	case 6 :
		searchType = HSEARCH;
		nSearchParam = ( stp < 1 ) ? 1 : stp;
		break;
	case 7 :
		searchType = VSEARCH;
		nSearchParam = ( stp < 1 ) ? 1 : stp;
		break;
	case 2 :
	default :
		searchType = LOGARITHMIC;
		nSearchParam = ( stp < 1 ) ? 1 : stp;
	}

    nPelSearch = ( _pelSearch <= 0) ?  analysisData.nPel : _pelSearch; // not below value of 0 at finest level


   analysisData.nFlags = 0;
   analysisData.nFlags |= _isse ? MOTION_USE_ISSE : 0;
   analysisData.nFlags |= analysisData.isBackward ? MOTION_IS_BACKWARD : 0;
   analysisData.nFlags |= chroma ? MOTION_USE_CHROMA_MOTION : 0;
/*
#define CPU_CACHELINE_32   0x00001000
#define CPU_CACHELINE_64   0x00002000
#define CPU_MMX            0x00004000
#define CPU_MMXEXT         0x00008000
#define CPU_SSE            0x00010000
#define CPU_SSE2           0x00020000
#define CPU_SSE2_IS_SLOW   0x00040000
#define CPU_SSE2_IS_FAST   0x00080000
#define CPU_SSE3           0x00100000
#define CPU_SSSE3          0x00200000
#define CPU_PHADD_IS_FAST  0x00400000
#define CPU_SSE4           0x00800000
//force MVAnalyse to use a different function for SAD / SADCHROMA (debug)
#define MOTION_USE_SSD     0x01000000
#define MOTION_USE_SATD    0x02000000
*/
	if (_sadx264 == 0)
	{
		analysisData.nFlags |= cpu_detect();
	}
	else
	{
		if ((_sadx264 > 0)&&(_sadx264 <= 12))
		{
			//force specific function
			analysisData.nFlags |= CPU_MMXEXT;
			analysisData.nFlags |= (_sadx264 == 2) ? CPU_CACHELINE_32 : 0;
			analysisData.nFlags |= ((_sadx264 == 3)||(_sadx264 == 5)||(_sadx264 == 7)) ? CPU_CACHELINE_64 : 0;
			analysisData.nFlags |= ((_sadx264 == 4)||(_sadx264 == 5)||(_sadx264 ==10)) ? CPU_SSE2_IS_FAST : 0;
			analysisData.nFlags |= (_sadx264 == 6) ? CPU_SSE3 : 0;
			analysisData.nFlags |= ((_sadx264 == 7)||(_sadx264 >=11)) ? CPU_SSSE3 : 0;
			//beta (debug)
			analysisData.nFlags |= (_sadx264 == 8) ? MOTION_USE_SSD : 0;
			analysisData.nFlags |= ((_sadx264 >= 9)&&(_sadx264 <= 12)) ? MOTION_USE_SATD : 0;
			analysisData.nFlags |= (_sadx264 ==12) ? CPU_PHADD_IS_FAST : 0;
		}
	}

    nModeYUV = chroma ? YUVPLANES : YPLANE;
    if ((nModeYUV & nSuperModeYUV) != nModeYUV)
			env->ThrowError("MAnalyse: super clip does not contain needed color data");

	vectorFields = new GroupOfPlanes(analysisData.nBlkSizeX, analysisData.nBlkSizeY,
		analysisData.nLvCount, analysisData.nPel, analysisData.nFlags,
		analysisData.nOverlapX, analysisData.nOverlapY, analysisData.nBlkX, analysisData.nBlkY, analysisData.yRatioUV, divideExtra);

   analysisData.nMagicKey = MOTION_MAGIC_KEY;

   analysisData.nHPadding = nSuperHPad; //v2.0
   analysisData.nVPadding = nSuperVPad;

	analysisData.nVersion = MVANALYSIS_DATA_VERSION; // MVAnalysisData and outfile format version: last update v1.8.1
	//DebugPrintf(" MVAnalyseData size= %d",sizeof(analysisData));

    outfilename = _outfilename;
	if (lstrlen(outfilename) > 0) {
		outfile = fopen(outfilename,"wb");
		if (outfile == NULL)
			env->ThrowError("MAnalyse: out file can not be created!");
		else
		{
			fwrite( &analysisData, sizeof(analysisData), 1, outfile );
			outfilebuf = new short[nBlkX*nBlkY*4]; // short vx, short vy, int SAD = 4 words = 8 bytes per block
		}
	 }
	 else {
		 outfile = NULL;
		 outfilebuf = NULL;
	 }

    // vector steam packed in
	vi.height = 1;
	vi.width = headerSize/sizeof(int) + vectorFields->GetArraySize(); //v1.8.1
	vi.pixel_type = VideoInfo::CS_BGR32;
    vi.audio_samples_per_second = 0; //v1.8.1

	if (divideExtra) { //v1.8.1
        memcpy(&analysisDataDivided, &analysisData, sizeof(analysisData));
        analysisDataDivided.nBlkX = analysisData.nBlkX * 2;
        analysisDataDivided.nBlkY = analysisData.nBlkY * 2;
        analysisDataDivided.nBlkSizeX = analysisData.nBlkSizeX / 2;
        analysisDataDivided.nBlkSizeY = analysisData.nBlkSizeY / 2;
        analysisDataDivided.nOverlapX = analysisData.nOverlapX / 2;
        analysisDataDivided.nOverlapY = analysisData.nOverlapY / 2;
        analysisDataDivided.nLvCount = analysisData.nLvCount + 1;
        vi.nchannels = reinterpret_cast<int>(&analysisDataDivided);
	}
	else
	{

   //  we'll transmit to the processing filters a handle
   // on the analyzing filter itself ( it's own pointer ), in order
   // to activate the right parameters.
        vi.nchannels = reinterpret_cast<int>(&analysisData);
	}

    pVecPrev = _temporal ? new int [vectorFields->GetArraySize()] : 0; // array for prev vectors
    nVecPrev = -2;

}
Пример #11
0
static int check_all_flags( void )
{
    int ret = 0;
    int cpu0 = 0, cpu1 = 0;
    uint32_t cpu_detect_rs = cpu_detect();
#if HAVE_MMX
    if( cpu_detect_rs & VSIMD_CPU_MMX2 )
    {
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_MMX | VSIMD_CPU_MMX2, "MMX" );
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_CACHELINE_64, "MMX Cache64" );
        cpu1 &= ~VSIMD_CPU_CACHELINE_64;
#if ARCH_X86
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_CACHELINE_32, "MMX Cache32" );
        cpu1 &= ~VSIMD_CPU_CACHELINE_32;
#endif
        if( cpu_detect_rs & VSIMD_CPU_LZCNT )
        {
            ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_LZCNT, "MMX LZCNT" );
            cpu1 &= ~VSIMD_CPU_LZCNT;
        }
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SLOW_CTZ, "MMX SlowCTZ" );
        cpu1 &= ~VSIMD_CPU_SLOW_CTZ;
    }
    if( cpu_detect_rs & VSIMD_CPU_SSE )
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SSE, "SSE" );
    if( cpu_detect_rs & VSIMD_CPU_SSE2 )
    {
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SSE2 | VSIMD_CPU_SSE2_IS_SLOW, "SSE2Slow" );
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SSE2_IS_FAST, "SSE2Fast" );
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_CACHELINE_64, "SSE2Fast Cache64" );
        cpu1 &= ~VSIMD_CPU_CACHELINE_64;
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SLOW_SHUFFLE, "SSE2 SlowShuffle" );
        cpu1 &= ~VSIMD_CPU_SLOW_SHUFFLE;
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SLOW_CTZ, "SSE2 SlowCTZ" );
        cpu1 &= ~VSIMD_CPU_SLOW_CTZ;
        if( cpu_detect_rs & VSIMD_CPU_LZCNT )
        {
            ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_LZCNT, "SSE2 LZCNT" );
            cpu1 &= ~VSIMD_CPU_LZCNT;
        }
    }
    if( cpu_detect_rs & VSIMD_CPU_SSE3 )
    {
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SSE3 | VSIMD_CPU_CACHELINE_64, "SSE3" );
        cpu1 &= ~VSIMD_CPU_CACHELINE_64;
    }
    if( cpu_detect_rs & VSIMD_CPU_SSSE3 )
    {
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SSSE3, "SSSE3" );
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_CACHELINE_64, "SSSE3 Cache64" );
        cpu1 &= ~VSIMD_CPU_CACHELINE_64;
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SLOW_SHUFFLE, "SSSE3 SlowShuffle" );
        cpu1 &= ~VSIMD_CPU_SLOW_SHUFFLE;
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SLOW_CTZ, "SSSE3 SlowCTZ" );
        cpu1 &= ~VSIMD_CPU_SLOW_CTZ;
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SLOW_ATOM, "SSSE3 SlowAtom" );
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_CACHELINE_64, "SSSE3 Cache64 SlowAtom" );
        cpu1 &= ~VSIMD_CPU_CACHELINE_64;
        cpu1 &= ~VSIMD_CPU_SLOW_ATOM;
        if( cpu_detect_rs & VSIMD_CPU_LZCNT )
        {
            ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_LZCNT, "SSSE3 LZCNT" );
            cpu1 &= ~VSIMD_CPU_LZCNT;
        }
    }
    if( cpu_detect_rs & VSIMD_CPU_SSE4 )
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SSE4, "SSE4" );
    if( cpu_detect_rs & VSIMD_CPU_SSE42 )
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_SSE42, "SSE4.2" );
    if( cpu_detect_rs & VSIMD_CPU_AVX )
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_AVX, "AVX" );
    if( cpu_detect_rs & VSIMD_CPU_XOP )
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_XOP, "XOP" );
    if( cpu_detect_rs & VSIMD_CPU_FMA4 )
    {
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_FMA4, "FMA4" );
        cpu1 &= ~VSIMD_CPU_FMA4;
    }
    if( cpu_detect_rs & VSIMD_CPU_FMA3 )
    {
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_FMA3, "FMA3" );
        cpu1 &= ~VSIMD_CPU_FMA3;
    }
    if( cpu_detect_rs & VSIMD_CPU_AVX2 )
    {
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_FMA3 | VSIMD_CPU_AVX2, "AVX2" );
        if( cpu_detect_rs & VSIMD_CPU_LZCNT )
        {
            ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_LZCNT, "AVX2 LZCNT" );
            cpu1 &= ~VSIMD_CPU_LZCNT;
        }
    }
    if( cpu_detect_rs & VSIMD_CPU_BMI1 )
    {
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_BMI1, "BMI1" );
        cpu1 &= ~VSIMD_CPU_BMI1;
    }
    if( cpu_detect_rs & VSIMD_CPU_BMI2 )
    {
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_BMI1|VSIMD_CPU_BMI2, "BMI2" );
        cpu1 &= ~(VSIMD_CPU_BMI1|VSIMD_CPU_BMI2);
    }
#elif ARCH_PPC
    if( cpu_detect_rs & VSIMD_CPU_ALTIVEC )
    {
        fprintf( stderr, "x264: ALTIVEC against C\n" );
        ret = check_all_funcs( 0, VSIMD_CPU_ALTIVEC );
    }
#elif ARCH_ARM
    if( cpu_detect_rs & VSIMD_CPU_NEON )
        x264_checkasm_call = x264_checkasm_call_neon;
    if( cpu_detect_rs & VSIMD_CPU_ARMV6 )
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_ARMV6, "ARMv6" );
    if( cpu_detect_rs & VSIMD_CPU_NEON )
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_NEON, "NEON" );
    if( cpu_detect_rs & VSIMD_CPU_FAST_NEON_MRC )
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_FAST_NEON_MRC, "Fast NEON MRC" );
#elif ARCH_AARCH64
    if( cpu_detect_rs & VSIMD_CPU_ARMV8 )
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_ARMV8, "ARMv8" );
    if( cpu_detect_rs & VSIMD_CPU_NEON )
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_NEON, "NEON" );
#elif ARCH_MIPS
    if( cpu_detect_rs & VSIMD_CPU_MSA )
        ret |= add_flags( &cpu0, &cpu1, VSIMD_CPU_MSA, "MSA" );
#endif
    return ret;
}