[x264-devel] Re: [Patch] x264 on ppc without altivec

Alexis Ballier aballier at gentoo.org
Mon Mar 5 18:29:42 CET 2007


>
> Weeh! I think I know what the problem is!
>
> common/cpu.c
> 134 elif defined( SYS_LINUX )
> 135 uint32_t x264_cpu_detect( void )
> 136 {
> 137     /* FIXME (Linux PPC) */
> 138     return X264_CPU_ALTIVEC;
> 139 }
> 140 #endif


That's what I meant with the "nice fixme" in my first mail :)

> Please try attached patch, and tell me if it fixes the problem.
> If it doesn't, please send a complete GDB backtrace so that I can
> identify where exactly does it choke.

That's the libmpeg2 method I was refering to, but let's try it again to
have a (meaningful?) gdb output (but I dont think that'll help much) :


[Thread debugging using libthread_db enabled]
[New Thread 805449536 (LWP 3738)]

Program received signal SIGILL, Illegal instruction.
[Switching to Thread 805449536 (LWP 3738)]
0x10022888 in x264_cpu_detect () at common/cpu.c:160
160                     asm volatile ("mtspr 256, %0\n\t"
(gdb) bt full
#0  0x10022888 in x264_cpu_detect () at common/cpu.c:160
No locals.
#1  0x100064c4 in x264_param_default (param=0x7fc61ef8) at common/common.c:46
No locals.
#2  0x10001f2c in main (argc=4, argv=0xfddf520) at x264.c:107
        param = {cpu = 0, i_threads = 0, b_deterministic = 0, i_width =
0, i_height = 0, i_csp = 0, i_level_idc = 0, i_frame_total = 0, vui =
{i_sar_height = 0, i_sar_width = 0, i_overscan = 0, i_vidformat = 0,
b_fullrange = 0, i_colorprim = 0, i_transfer = 0, i_colmatrix = 0,
i_chroma_loc = 0}, i_fps_num = 0, i_fps_den = 0, i_frame_reference = 0,
i_keyint_max = 0, i_keyint_min = 0, i_scenecut_threshold = 0,
b_pre_scenecut = 0, i_bframe = 0, b_bframe_adaptive = 0, i_bframe_bias
= 0, b_bframe_pyramid = 0, b_deblocking_filter = 0,
i_deblocking_filter_alphac0 = 0, i_deblocking_filter_beta = 0, b_cabac
= 0, i_cabac_init_idc = 0, b_interlaced = 0, i_cqm_preset = 0,
psz_cqm_file = 0x0, cqm_4iy = '\0' <repeats 15 times>, cqm_4ic = '\0'
<repeats 15 times>, cqm_4py = '\0' <repeats 15 times>, cqm_4pc = '\0'
<repeats 15 times>, cqm_8iy = '\0' <repeats 63 times>, cqm_8py = '\0'
<repeats 63 times>, pf_log = 0, p_log_private = 0x0, i_log_level = 0,
b_visualize = 0, analyse = { intra = 0, inter = 0, b_transform_8x8 = 0,
b_weighted_bipred = 0, i_direct_mv_pred = 0, i_direct_8x8_inference =
0, i_chroma_qp_offset = 0, i_me_method = 0, i_me_range = 0, i_mv_range
= 0, i_mv_range_thread = 0, i_subpel_refine = 0, b_bidir_me = 0,
b_chroma_me = 0, b_bframe_rdo = 0, b_mixed_references = 0, i_trellis =
0, b_fast_pskip = 0, b_dct_decimate = 0, i_noise_reduction = 0,
i_luma_deadzone = {0, 0}, b_psnr = 0, b_ssim = 0}, rc = {i_rc_method =
0, i_qp_constant = 0, i_qp_min = 0, i_qp_max = 0, i_qp_step = 0,
i_bitrate = 0, f_rf_constant = 0, f_rate_tolerance = 0,
i_vbv_max_bitrate = 0, i_vbv_buffer_size = 0, f_vbv_buffer_init = 0,
f_ip_factor = 0, f_pb_factor = 0, b_stat_write = 0, psz_stat_out = 0x0,
b_stat_read = 0, psz_stat_in = 0x0, psz_rc_eq = 0x0, f_qcompress = 0,
f_qblur = 0, f_complexity_blur = 0, zones = 0x0, i_zones = 0, psz_zones
= 0x0}, b_aud = 0, b_repeat_headers = 0, i_sps_id = 0} opt =
{b_progress = 805326432, i_seek = 0, hin = 0x0, hout = 0x0, qpfile =
0x0} ret = <value optimized out>
(gdb)


of course common/cpu.c:160 is the asm code.


let's try something else :


$cat toto.c
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>

static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjump = 0;

static void sigill_handler (int sig)
{
    if (!canjump) {
        signal (sig, SIG_DFL);
        raise (sig);
    }

    canjump = 0;
    siglongjmp (jmpbuf, 1);
}


int x264_cpu_detect( void )
{
        signal (SIGILL, sigill_handler);
        if (sigsetjmp (jmpbuf, 1)) {
                signal (SIGILL, SIG_DFL);
        } else {
                canjump = 1;

                asm volatile ("mtspr 256, %0\n\t"
                                "vand %%v0, %%v0, %%v0"
                                :
                                : "r" (-1));

                signal (SIGILL, SIG_DFL);
                return 1;
        }
        return 0;
}



int main(){

        printf("%i\n", x264_cpu_detect());

        return 0;
}



$ gcc toto.c
$ ./a.out
0
$


so basically the code is not wrong.


and now with that patch :

$ svn diff
Index: common/cpu.c
===================================================================
--- common/cpu.c        (revision 628)
+++ common/cpu.c        (working copy)
@@ -32,6 +32,11 @@
 #include <sys/types.h>
 #include <sys/sysctl.h>
 #endif
+#ifdef SYS_LINUX
+#include <signal.h>
+#include <setjmp.h>
+#include <stdio.h>
+#endif

 #include <string.h>

@@ -111,7 +116,21 @@
 }

 #elif defined( ARCH_PPC )
+static sigjmp_buf jmpbuf;
+static volatile sig_atomic_t canjump = 0;

+static void sigill_handler (int sig)
+{
+    if (!canjump) {
+       printf(" sigill_handler in if(!canjump)\n");
+        signal (sig, SIG_DFL);
+        raise (sig);
+    }
+    printf(" sigill_handler after if(!canjump)\n");
+    canjump = 0;
+    siglongjmp (jmpbuf, 1);
+}
+
 #ifdef SYS_MACOSX
 #include <sys/sysctl.h>
 uint32_t x264_cpu_detect( void )
@@ -134,8 +153,25 @@
 #elif defined( SYS_LINUX )
 uint32_t x264_cpu_detect( void )
 {
-    /* FIXME (Linux PPC) */
-    return X264_CPU_ALTIVEC;
+       signal (SIGILL, sigill_handler);
+       if (sigsetjmp (jmpbuf, 1)) {
+               printf("x264_cpu_detect in if (sigsetjmp (jmpbuf, 1))
\n");
+               signal (SIGILL, SIG_DFL);
+       } else {
+               printf("x264_cpu_detect in else\n");
+               canjump = 1;
+
+               asm volatile ("mtspr 256, %0\n\t"
+                               "vand %%v0, %%v0, %%v0"
+                               :
+                               : "r" (-1));
+
+               signal (SIGILL, SIG_DFL);
+               printf("x264_cpu_detect found altivec\n");
+               return X264_CPU_ALTIVEC;
+       }
+       printf("x264_cpu_detect altivec not found\n");
+       return 0;
 }
 #endif

I get :

$./x264 -o ../toto.264 ../example.y4m
x264_cpu_detect in else
 sigill_handler after if(!canjump)
x264_cpu_detect in if (sigsetjmp (jmpbuf, 1))
x264_cpu_detect altivec not found
yuv4mpeg: 384x288 at 25/1fps, 0:0
x264 [info]: using cpu capabilities
Illegal instruction



So, to me, that means that the signal is caught by the thread, but
also sent to the whole process which dies.
I dont know if there is a way to play nicely with threads and signals
and found it simpler to disable altivec at compile time, thus the patch
I proposed.


Regards,

Alexis.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://mailman.videolan.org/pipermail/x264-devel/attachments/20070305/eb57a54d/attachment.pgp 


More information about the x264-devel mailing list