显示标签为“原创文章”的博文。显示所有博文
显示标签为“原创文章”的博文。显示所有博文

2009-03-02

ffmpeg使用x264编码的配置 + ffmpeg与 x264编码器参数完整对照表

  使用ffmpeg进行.264编码的相关文章比较少,google了一下,特总结如下:

  • qscale的取值可以是0.01-255但实际使用超过50就很糟糕了
  • ffmpeg的cbr模式可以把码率控制的不错,但是vbr无法限制最高码率(虽然有max的设置,但是程序没有实现)
  • x264标准的封装是x264+aac in flv或者x264+aac in MP4

接下来说明下ffmpeg命令行的语法规则(本块内容来自2009-03-02官方文档):
语法规则结构:
ffmpeg [[infile options][`-i' infile]]... {[outfile options] outfile}...
一个最简单的命令形式:
ffmpeg -i input.avi -b 64k output.avi

这个命令把视频以64k的码率重编码。
显然,输入文件前面要加一个-i选项下面介绍一些有用的全局参数:
  • -formats 参数。会显示你机器当前支持的封装、编码、解码器的信息
  • -y参数,会指示ffmpeg覆盖输出文件
  • -t 指定视频流持续的时常,支持以秒为单位的数字或"时:分:秒[.毫秒]"
  • -fs 指定输出文件大小的限制
  • -ss 指定开始的时间,和-t的单位一样
  • -target 直接设定你想要转成的目标格式,所有的相关设置都会采用内设值,当然也你也可以加上自己要修改的参数。可用的选择有:
    "vcd", "svcd", "dvd", "dv", "dv50", "pal-vcd", "ntsc-svcd", ...
    这个例子把视频转换成vcd的格式
    ffmpeg -i myfile.avi -target vcd /tmp/vcd.mpg
接下来介绍视频选项:
  • -b 指定码率注意单位是bit/s,所以我们一般要加k,比如 -b 1000k 就是1000kb/s
  • -g 设置组的大小
  • -vframes 指定要编码的帧数,比如-vframes 1 就是编码1帧,截图的时候就这样写.
  • -r 指定帧率,默认是25
  • -s 指定图像分辨率,用wxh的格式,比如320x240
  • -aspect 指定宽高比 可以些16:9这种,也可以写小数比如1.3333
  • -croptop 指定顶部裁减多少像素,类似的还有-cropleft -cropright -cropbuttom
  • -bt 设置比特率容许的误差,默认4000k,在第一阶段时使用这个参数会告诉码率控制器能够偏移平均码率多远,这个选项和最大最小码率无关.设太小了不利于质量
  • -maxrate 和-minrate 指定允许的最大和最小码率,一般如果要用cbr模式编码的话会用这个:
    ffmpeg -i myfile.avi -b 4000k -minrate 4000k -maxrate 4000k -bufsize 1835k out.m2v
    否则用处不大
  • -vcodec 强制使用某种编码器
  • -sameq 使用和源文件相同的质量,这个选项是动态码率的
  • -pass 指定编码阶段,这个只有1和2,第一阶段的时候应该不处理音频,并且把输出导向空,比如:
    ffmpeg -i foo.mov -vcodec libxvid -pass 1 -an -f rawvideo -y NUL
    ffmpeg -i foo.mov -vcodec libxvid -pass 1 -an -f rawvideo -y /dev/null
  • -qscale 使用固定量化因子来量化视频这个是在vbr模式的,前面有提到,越小质量越好,不要超过50,相关的参数还有-qmin --qmax用来设定最大最小可使用的量化值
  • -qdiff 指定固定量化器因子允许的最大偏差
  • -qblur 指定量化器模糊系数,可用范围是0.0-1.0越大使得码率在时间上分配的越平均
  • -qcomp 指定视频量化器压缩系数,默认0.5
  • -me_method 指定运动估计方法(motion estimation method),可用的选择从垃圾到好排列如下:
    zero (0向量)
    phods
    log
    x1
    hex
    umh
    epzs (默认)
    full (完全搜索,很慢又好不到哪里去)
  • -mbd 设定宏模块决策,可用的值:
    0 使用mb_cmp,不知道是什么东西,所以这些参数我参考一下mencoder里面的
    1 选用需要比特最少的宏块模式
    2 选用码率失真最优的宏块模式
  • -4mv 使用宏块的4个运动向量,只支持mpeg4
  • -part 使用数据划分,只支持mpeg4
  • -ilme 强制允许交错的编码,只支持mpeg2和mpeg4,你可以选择用-deinterlace来去交错
音频部分:
  • -ar 设置采样频率,默认44100hz
  • -ab 设置比特率,默认64k
  • -an 禁用音频录制
  • -acodec 指定音频编码器


下面举几个x264编码的例子:
我使用mencoder调用x264编码一个psp用的视频:
x264+aac in mp4 for psp
mencoder -oac lavc -lavcopts acodec=libfaac:abitrate=94 -ovc x264 -x264encopts cabac=1:ref=3:deblock=1,-1,-1:analyse=0x1:0x111:me=umh:subme=9:psy_rd=0.9,0.0:mixed_ref=1:me_range=32:chroma_me=1:trellis=2:8x8dct=0:cmp=0:deadzone=21,11:chroma_qp_offset=-2:nr=0:decimate=0:mbaff=0:bframes=2:b_pyramid=0:b_adapt=1:b_bias=0:direct=3:wpredb=1:keyint=250:keyint_min=25:scenecut=40:rc=cqp:qp=18:ip_ratio=1.40:pb_ratio=1.30:aq=0 -lavdopts er=2 -pp 6 -of lavf -lavfopts format=psp -vf scale=480:-3
对应的ffmpeg编码参数是:
ffmpeg
ffmpeg -i inputfile.avi -f psp -acodec libfaac -ab 94k -vcodec libx264 -cqp 28 -coder 1 -refs 3 -deblockalpha 1 -deblockbeta -1 -me_method umh -subq 9 -me_range 32 -trellis 2 -chromaoffset -2 -nr 0 -bf 2 -b_strategy 1 -bframebias 0 -directpred 3 -g 250 -i_qfactor 1.3 -b_qfactor 1.4 -flags2 +bpyramid+wpred+mixed_refs+8x8dct -er 2 -s 480x320
需要注意的是,flags2里面那块,似乎要按照一定顺序才能正常工作,其他地方都差不多,详细情况可以从下面两篇文章得出:
第一篇是这个在网上被传了很多,但有些问题的对照表格,我修改了有问题的部分:
FFmpeg option x264 option
-g <frames> --keyint
-b <bits per second> --bitrate
-bufsize <bits> --vbv-bufsize
-maxrate <bits> --vbv-maxrate
-pass <1,2,3> --pass
-crf <float> --crf
-cqp <int> --qp
-bf <int> --bframes
-coder <0,1> --no-cabac
-bframebias <int> --b-bias
-keyint_min <int> --min-keyint
-sc_threshold <int> --scenecut
-deblockalpha <int>-deblockbeta <int> --deblock
-qmin <int> --qpmin
-qmax <int> --qpmax
-qdiff <int> --qpstep
-qcomp <float> --qcomp
-qblur <float> --qblur
-complexityblur <float> --cplxblur
-refs <int> --ref
-directpred <int> --direct
-me_method <epzs,hex,umh,full> --me
-me_range <int> --merange
-subq <int> --subme
-bidir_refine <0,1> --bime
-trellis <0,1,2> --trellis
-nr <int> --nr
-level <int> --level
-bt <bits> --ratetol = -bt / -b
-rc_init_occupancy <bits> --vbv-init = -rc_init_occupancy / -bufsize
-i_qfactor <float> --ipratio = 1 / -i_qfactor
-b_qfactor <float> --pbratio
-chromaoffset <int> --chroma-qp-offset
-rc_eq <string> --rc_eq
-threads <int> --threads
-cmp <-chroma/+chroma> --no-chroma-me
-partitions --partitions
+parti8×8 i8×8
+parti4×4 i4×4
+partp8×8 p8×8
+partp4×4 p4×4
+partb8×8 b8×8
-flags
-loop/+loop --no-deblock/–deblock
-psnr/+psnr --no-psnr/nothing
-flags2
+bpyramid --b-pyramid
+wpred --weightb
+brdo --b-rdo 我这里的ffmpeg已经不能用这个了
+mixed_refs --mixed-refs
+dct8×8 --8×8dct
-fastpskip/+fastpskip --no-fast-pskip
+aud --aud


下面是一篇关于这些参数详细解释的文章,转自:http://ffmpeg.x264.googlepages.com/mapping
一下是这篇文章在2008年11月19日更新的版本:

Frame-type options:

  • --keyint <integer> (x264)
    -g <integer>
    (FFmpeg)
    Keyframe interval, also known as GOP length. This determines the maximum distance between I-frames. Very high GOP lengths will result in slightly more efficient compression, but will make seeking in the video somewhat more difficult. Recommended default: 250

  • --min-keyint <integer> (x264)
    -keyint_min <integer> (FFmpeg)
    Minimum GOP length, the minimum distance between I-frames. Recommended default: 25

  • --scenecut <integer> (x264)
    -sc_threshold <integer> (FFmpeg)
    Adjusts the sensitivity of x264's scenecut detection. Rarely needs to be adjusted. Recommended default: 40

  • --pre-scenecut (x264)
    UNKNOWN (FFmpeg)
    Slightly faster (but less precise) scenecut detection. Normal scenecut detection decides whether a frame is a scenecut after the frame is encoded, and if so then re-encodes the frame as an I-frame. This is not compatible with threading, however, and so --pre-scenecut is automatically activated when multiple encoding threads are used.

  • --bframes <integer> (x264)
    -bf <integer> (FFmpeg)
    B-frames are a core element of H.264 and are more efficient in H.264 than any previous standard. Some specific targets, such as HD-DVD and Blu-Ray, have limitations on the number of consecutive B-frames. Most, however, do not; as a result, there is rarely any negative effect to setting this to the maximum (16) since x264 will, if B-adapt is used, automatically choose the best number of B-frames anyways. This parameter simply serves to limit the max number of B-frames. Note that Baseline Profile, such as that used by iPods, does not support B-frames. Recommended default: 16

  • --b-adapt <integer> (x264)
    -b_strategy <integer> (FFmpeg)
    x264, by default, adaptively decides through a low-resolution lookahead the best number of B-frames to use. It is possible to disable this adaptivity; this is not recommended. Recommended default: 1
  • 0: Very fast, but not recommended. Does not work with pre-scenecut (scenecut must be off to force off b-adapt).

    1: Fast, default mode in x264. A good balance between speed and quality.

    2: A much slower but more accurate B-frame decision mode that correctly detects fades and generally gives considerably better quality. Its speed gets considerably slower at high bframes values, so its recommended to keep bframes relatively low (perhaps around 3) when using this option. It also may slow down the first pass of x264 when in threaded mode.

  • --b-bias 0 (x264)
    -bframebias 0 (FFmpeg)
    Make x264 more likely to choose higher numbers of B-frames during the adaptive lookahead. Not generally recommended. Recommended default: 0

  • --b-pyramid (x264)
    -flags2 +bpyramid (FFmpeg)
    Allows B-frames to be kept as references. The name is technically misleading, as x264 does not actually use pyramid coding; it simply adds B-references to the normal reference list. B-references get a quantizer halfway between that of a B-frame and P-frame. This setting is generally beneficial, but it increases the DPB (decoding picture buffer) size required for playback, so when encoding for hardware, disabling it may help compatibility.

  • --no-cabac (x264)
    -coder 0,1 (FFmpeg)
    CABAC is the default entropy encoder used by x264. Though somewhat slower on both the decoding and encoding end, it offers 10-15% improved compression on live-action sources and considerably higher improvements on animated sources, especially at low bitrates. It is also required for the use of trellis quantization. Disabling CABAC may somewhat improve decoding performance, especially at high bitrates. CABAC is not allowed in Baseline Profile. Recommended default: -coder 1 (CABAC enabled)

  • --ref <integer> (x264)
    -refs <integer> (FFmpeg)
    One of H.264's most useful features is the abillity to reference frames other than the one immediately prior to the current frame. This parameter lets one specify how many references can be used, through a maximum of 16. Increasing the number of refs increases the DPB (Decoded Picture Buffer) requirement, which means hardware playback devices will often have strict limits to the number of refs they can handle. In live-action sources, more reference have limited use beyond 4-8, but in cartoon sources up to the maximum value of 16 is often useful. More reference frames require more processing power because every frame is searched by the motion search (except when an early skip decision is made). The slowdown is especially apparent with slower motion estimation methods. Recommended default: -refs 6

  • --no-deblock (x264)
    -flags -loop (FFmpeg)
    Disable loop filter. Recommended default: -flags +loop (Enabled)

  • --deblock (x264)
    -deblockalpha <integer>(FFmpeg)
    -deblockbeta <integer>(FFmpeg)
    One of H.264's main features is the in-loop deblocker, which avoids the problem of blocking artifacts disrupting motion estimation. This requires a small amount of decoding CPU, but considerably increases quality in nearly all cases. Its strength may be raised or lowered in order to avoid more artifacts or keep more detail, respectively. Deblock has two parameters: alpha (strength) and beta (threshold). Recommended defaults:-deblockalpha 0 -deblockbeta 0 (Must have '-flags +loop')

  • --interlaced (x264)
    UNKNOWN (FFmpeg)
    Enables interlaced encoding. x264's interlaced encoding is not as efficient as its progressive encoding; consider deinterlacing for maximum effectiveness.

Ratecontrol:

  • --qp <integer>(x264)
    -cqp <integer>(FFmpeg)
    Constant quantizer mode. Not exactly constant completely--B-frames and I-frames have different quantizers from P-frames. Generally should not be used, since CRF gives better quality at the same bitrate.

  • --bitrate <integer>(x264)
    -b <integer>(FFmpeg)
    Enables target bitrate mode. Attempts to reach a specific bitrate. Should be used in 2-pass mode whenever possible; 1-pass bitrate mode is generally the worst ratecontrol mode x264 has.

  • --crf <float>(x264)
    -crf <float>(FFmpeg)
    Constant quality mode (also known as constant ratefactor). Bitrate corresponds approximately to that of constant quantizer, but gives better quality overall at little speed cost. The best one-pass option in x264.

  • --vbv-maxrate <integer>(x264)
    -maxrate <integer>(FFmpeg)
    Specifies the maximum bitrate at any point in the video. Requires the VBV buffersize to be set. This option is generally used when encoding for a piece of hardware with bitrate limitations.

  • --vbv-bufsize <integer>(x264)
    -bufsize <integer> (FFmpeg)
    Depends on the profile level of the video being encoded. Set only if you're encoding for a hardware device.

  • --vbv-init <float>(x264)
    -rc_init_occupancy <float>(FFmpeg)
    Initial VBV buffer occupancy. Note: Don't mess with this.

  • --qpmin <integer> (x264)
    -qmin <integer> (FFmpeg)
    Minimum quantizer. Doesn't need to be changed. Recommended default: -qmin 10

  • --qpmax <integer> (x264)
    -qmax <integer> (FFmpeg)
    Maximum quantizer. Doesn't need to be changed. Recommended default: -qmax 51

  • --qpstep <integer> (x264)
    -qdiff <integer> (FFmpeg)
    Set max QP step. Recommended default: -qdiff 4

  • --ratetol <float>(x264)
    -bt <float>(FFmpeg)
    Allowed variance of average bitrate

  • --ipratio <float>(x264)
    -i_qfactor <float>(FFmpeg)
    Qscale difference between I-frames and P-frames.

  • --pbratio <float>(x264)
    -b_qfactor <float>(FFmpeg)
    Qscale difference between P-frames and B-frames.

  • --chroma-qp-offset <integer>(x264)
    -chromaoffset <integer>(FFmpeg)
    QP difference between chroma and luma.

  • --aq-strength <float> (x264)
    UNKNOWN (FFmpeg)
    Adjusts the strength of adaptive quantization. Higher values take more bits away from complex areas and edges and move them towards simpler, flatter areas to maintain fine detail. Default: 1.0

  • --pass <1,2,3> (x264)
    -pass <1,2,3>(FFmpeg)
    Used with --bitrate. Pass 1 writes the stats file, pass 2 reads it, and 3 both reads and writes it. If you want to use three pass, this means you will have to use --pass 1 for the first pass, --pass 3 for the second, and --pass 2 or 3 for the third.

  • --stats <string>(x264)
    UNKNOWN (FFmpeg)
    Allows setting a specific filename for the firstpass stats file.

  • --rceq <string>(x264)
    -rc_eq <string>(FFmpeg)
    Ratecontrol equation. Recommended default: -rc_eq 'blurCplx^(1-qComp)'

  • --qcomp <float>(x264)
    -qcomp <float> (FFmpeg)
    QP curve compression: 0.0 => CBR, 1.0 => CQP. Recommended default: -qcomp 0.60

  • --cplxblur <float>(x264)
    -complexityblur <float>(FFmpeg)
    Reduce fluctuations in QP (before curve compression) [20.0]

  • --qblur <float>(x264)
    -qblur <float>(FFmpeg)
    Reduce fluctuations in QP (after curve compression) [0.5]

  • --zones /(x264)
    UNKNOWN (FFmpeg)
    Allows setting a specific quantizer for a specific region of video.

  • --qpfile (x264)
    UNKNOWN (FFmpeg)
    Allows one to read in a set of frametypes and quantizers from a file. Useful for testing various encoding options while ensuring the exact same quantizer distribution.

Analysis:

  • --partitions <string> (x264)
    -partitions <string> (FFmpeg)

    p8x8 (x264) /+partp8x8 (FFmpeg)

    p4x4 (x264) /+partp4x4 (FFmpeg)

    b8x8 (x264) /+partb8x8 (FFmpeg)

    i8x8 (x264) /+parti8x8 (FFmpeg)

    i4x4 (x264) /+parti4x4 (FFmpeg)

    One of H.264's most useful features is the ability to choose among many combinations of inter and intra partitions. P-macroblocks can be subdivided into 16x8, 8x16, 8x8, 4x8, 8x4, and 4x4 partitions. B-macroblocks can be divided into 16x8, 8x16, and 8x8 partitions. I-macroblocks can be divided into 4x4 or 8x8 partitions. Analyzing more partition options improves quality at the cost of speed. The default is to analyze all partitions except p4x4 (p8x8, i8x8, i4x4, b8x8), since p4x4 is not particularly useful except at high bitrates and lower resolutions. Note that i8x8 requires 8x8dct, and is therefore a High Profile-only partition. p8x8 is the most costly, speed-wise, of the partitions, but also gives the most benefit. Generally, whenever possible, all partition types except p4x4 should be used.

  • --direct <integer>(x264)
    -directpred <integer>(FFmpeg)
    B-frames in H.264 can choose between spatial and temporal prediction mode. Auto allows x264 to pick the best of these; the heuristic used is whichever mode allows more skip macroblocks. Auto should generally be used.

  • --direct-8x8 (x264)
    UNKONWN (FFmpeg)
    This should be left at the default (-1).

  • --weightb (x264)
    -flags2 +wpred(FFmpeg)
    This allows B-frames to use weighted prediction options other than the default. There is no real speed cost for this, so it should always be enabled.

  • --me (x264)
    -me_method (FFmpeg)

    dia (x264) / epzs (FFmpeg) is the simplest search, consisting of starting at the best predictor, checking the motion vectors at one pixel upwards, left, down, and to the right, picking the best, and repeating the process until it no longer finds any better motion vector.

    hex (x264) / hex (FFmpeg) consists of a similar strategy, except it uses a range-2 search of 6 surrounding points, thus the name. It is considerably more efficient than DIA and hardly any slower, and therefore makes a good choice for general-use encoding.

    umh (x264) / umh (FFmpeg) is considerably slower than HEX, but searches a complex multi-hexagon pattern in order to avoid missing harder-to-find motion vectors. Unlike HEX and DIA, the merange parameter directly controls UMH's search radius, allowing one to increase or decrease the size of the wide search.

    esa (x264) / full (FFmpeg) is a highly optimized intelligent search of the entire motion search space within merange of the best predictor. It is mathematically equivalent to the bruteforce method of searching every single motion vector in that area, though faster. However, it is still considerably slower than UMH, with not too much benefit, so is not particularly useful for everyday encoding.

    One of the most important settings for x264, both speed and quality-wise.

  • --merange <integer>(x264)
    -me_range <integer>(FFmpeg)
    MErange controls the max range of the motion search. For HEX and DIA, this is clamped to between 4 and 16, with a default of 16. For UMH and ESA, it can be increased beyond the default 16 to allow for a wider-range motion search, which is useful on HD footage and for high-motion footage. Note that for UMH and ESA, increasing MErange will significantly slow down encoding.

  • --mvrange(x264)
    UNKNOWN (FFmpeg)
    Limits the maximum motion vector range. Since x264 by default limits this to 511.75 for standards compliance, this should not be changed.

  • --subme 6(x264)
    -subq 6(FFmpeg)

    1: Fastest, but extremely low quality. Should be avoided except on first pass encoding.

    2-5: Progressively better and slower, 5 serves as a good medium for higher speed encoding.

    6-7: 6 is the default. Activates rate-distortion optimization for partition decision. This can considerably improve efficiency, though it has a notable speed cost. 6 activates it in I/P frames, and subme7 activates it in B frames.

    8-9: Activates rate-distortion refinement, which uses RDO to refine both motion vectors and intra prediction modes. Slower than subme 6, but again, more efficient.

    An extremely important encoding parameter which determines what algorithms are used for both subpixel motion searching and partition decision.

  • --psy-rd <float>:<float> (x264)
    UNKNOWN (FFmpeg)
    First value represents the amount that x264 biases in favor of detail retention instead of max PSNR in mode decision. Requires subme >= 6. Second value is psy-trellis, an experimental algorithm that tries to improve sharpness and detail retention at the expense of more artifacting. Recommended starting values are 0.1-0.2. Requires trellis >= 1. Recommended default: 1.0:0.0

  • --mixed-refs(x264)
    -flags2 +mixed_refs(FFmpeg)
    H.264 allows p8x8 blocks to select different references for each p8x8 block. This option allows this analysis to be done, and boosts quality with little speed impact. It should generally be used, though it obviously has no effect with only one reference frame.

  • --no-chroma-me(x264)
    UNKNOWN (FFmpeg)
    Chroma is used in the last steps of the subpixel refinement by default. For a slight speed increase, this can be disabled (at the cost of quality).

  • --8x8dct (x264)
    -flags2 +dct8x8(FFmpeg)
    Gives a notable quality boost by allowing x264 to choose between 8x8 and 4x4 frequency transform size. Required for i8x8 partitions. Speed cost for this option is near-zero both for encoding and decoding; the only reason to disable it is when one needs support on a device not compatible with High Profile.

  • --trellis <0,1,2>(x264)
    -trellis <0,1,2>(FFmpeg)

    0: disabled

    1: enabled only on the final encode of a MB

    2: enabled on all mode decisions

    The main decision made in quantization is which coefficients to round up and which to round down. Trellis chooses the optimal rounding choices for the maximum rate-distortion score, to maximize PSNR relative to bitrate. This generally increases quality relative to bitrate by about 5% for a somewhat small speed cost. It should generally be enabled. Note that trellis requires CABAC.

  • --no-fast-pskip(x264)
    -flags2 -fastpskip(FFmpeg)
    By default, x264 will skip macroblocks in P-frames that don't appear to have changed enough between two frames to justify encoding the difference. This considerably speeds up encoding. However, for a slight quality boost, P-skip can be disabled. In this case, the full analysis will be done on all P-blocks, and the only skips in the output stream will be the blocks whose motion vectors happen to match that of the skip vector and motion vectors happen to match that of the skip vector and which have no residual. The speed cost of enabling no-fast-pskip is relatively high, especially with many reference frames. There is a similar B-skip internal to x264, which is why B-frames generally encode much faster than P-frames, but it cannot be disabled on the commandline.

  • --no-dct-decimate(x264)
    UNKNOWN (FFmpeg)
    By default, x264 will decimate (remove all coefficients from) P-blocks that are extremely close to empty of coefficents. This can improve overall efficiency with little visual cost, but may work against an attempt to retain grain or similar. DCT decimation should be left on unless there's a good reason to disable it.

  • --nr(x264)
    UNKNOWN (FFmpeg)
    a fast, built-in noise reduction routine. Not as effective as external filters such as hqdn3d, but faster. Since x264 already naturally reduces noise through its quantization process, this parameter is not usually necessary.

  • --deadzone-inter(264)
    --deadzone-intra (x264)
    UNKNOWN (FFmpeg)
    UNKNOWN (FFmpeg)
    When trellis isn't activated, deadzone parameters determine how many DCT coefficients are rounded up or down. Rounding up results in higher quality and more detail retention, but costs more bits--so rounding is a balance between quality and bit cost. Lowering these settings will result in more coefficients being rounded up, and raising the settings will result in more coefficients being rounded down. Recommended: keep them at the defaults.

  • --cqm (264)
    --cqpfile(x264)UNKNOWN (FFmpeg)
    UNKNOWN (FFmpeg)
    Allows the use of a custom quantization matrix to weight frequencies differently in the quantization process. The presets quant matrices are "jvt" and "flat". --cqpfile reads a custom quant matrices from a JM-compatible file. Recommended only if you know what you're doing.

2009-02-19

Linux下转换视频文件Mencoder篇。续

  之前那篇已经太长了,再修改数据丢失的风险太大,所以就新开了一帖。如果有需要可以先看下旧的那篇

关于h.264编码
  去年底我曾经详细的通过实际压缩出来的结果对比研究和几个星期的x264编码的效果。但是可惜的是当时忙于项目,没有记录,现在要用时发现信息已经丢掉甚多,实为可惜。所以先整理一小部分还找的到的资料。
  h.264编码几乎是现在的一种国际标准了,连那个啥dobe的flash 都能够直接解码了,就这一点就比Silverlight强了很多。
  首先看一下编码参数:
mencoder test.avi -o /dev/null -oac copy -ovc x264 -x264encopts pass=1:turbo:me_range=16:qp_max=51:brdo:ratetol=1.0:bitrate=1000:me=umh:partitions=p8x8,b8x8,i8x8,i4x4:qp_min=10:bframes=1:qp_step=4:direct_pred=auto && mencoder test.avi -o testssdfsd.avi -oac lavc -lavcopts acodec=ac3:abitrate=96 -ovc deadzone_inter=21:pass=2:me_range=16:qcomp=0.6:qp_max=51:brdo:chroma_me:vbv_init=0.9:ratetol=1.0:bitrate=1000:me=umh:partitions=p8x8,b8x8,i8x8,i4x4:chroma_qp_offset=0:subq=5:pb_factor=1.3:deblock=0,0:qp_min=10:ip_factor=1.4:cabac:bframes=1:frameref=5:qp_step=4:b_adapt:b_bias=0:trellis=1:direct_pred=auto:nr=0:deadzone_intra=11:keyint_min=25:keyint=250

  这个是我研究出来看起来效果相对不错的编码参数,但是未必是最好的。码率的指定我没有研究,这里指定1000是为了做基准对比。
注:以上编码参数有漏掉,待我找到原来的再补上,你可以先在ovc后面加 x264enc -x264encopts
  首先可以确定的一点是2 pass的编码效果肯定比1 pass能强上一点,主要原因是2 pass在第一轮的对视频文件的测试中能够使第二轮真正编码的时候更加充分的利用码率,就是把码率用在刀刃上。
  参数解释:第一阶段的编码,文档的解释是收集视频上的统计信息,并将这些信息写入一个文件中。 除了那些默认为打开的选项,你可能想关闭一些消耗CPU的选项。这里我使用turbo能够加快速度,本来turbo有两个值可以选的turbo=1或turbo=2,1对最终编码质量没有影响,二有一点小影响,1最大能把速度加快到2倍,2就能4倍了,由于turbo选项会减小subq、frameref的值,所以我们就没必要在第一阶段设置这两个值了。
  第二阶段的编码就可以把要的全开开了。这里不重复说明了,以前的帖子里有解释,看这个

  最后,补充一下关于需要使用flash播放264编码的相关知识,首先,官方推荐方案是h.264+aac,封装可以使用flv或mp4,但是如果你在写flex的时候两种格式似乎在加载代码上有不同,可以参考这个帖子,flv的格式标准可以从这里下载。未免那个连接挂了,这里引用一句里面最精华的内容:

在FLEX中一般都用videoDisPlayer这个控件播放视频文件,通过使用source属性设置进行播放flv文件,如:rtmp://123.32.4.22:1935/fms/aa.flv.
但如果播放MP4格式文件如是aa.mp4,还可以使用videoDisPlayer,但不同的地方在source赋值,应该这么写:rtmp://123.32.4.22:1935/fms/MP4:aa
-----------------------------------------
关于封装:
  mencoder本生支持的封装格式有限,不过通过使用libavformat获得了很多封装格式的支持。
你可以使用
mencoder -of help
这个命令获得你的mencoder支持的封装格式。显然,这里相当少:
Available output formats:
avi - Microsoft Audio/Video Interleaved
mpeg - MPEG-1/2 system stream format
lavf - FFmpeg libavformat muxers
rawvideo - (video only, one stream only) raw stream, no muxing
rawaudio - (audio only, one stream only) raw stream, no muxing

但是,命运是能够改变的。当你使用lavf的时候,程序会根据你的扩展名自动判别封装格式,最新的官方文档有详细的说明:
libavformat container nameDescription
mpgMPEG-1 and MPEG-2 PS
asfAdvanced Streaming Format
aviAudio-Video Interleaved
wavWaveform Audio
swfMacromedia Flash
flvMacromedia Flash video
rmRealMedia
auSUN AU
nutNUT open container (experimental and not yet spec-compliant)
movQuickTime
mp4MPEG-4 format
dvSony Digital Video container
mkvMatroska open audio/video container

  所以呢,结果就是,你可以任意使用这些封装格式,只需要-of lavf即可。
/*-----------------------------------------------------*/
*原创文章,转载请保留指向本文的连接
/*-----------------------------------------------------*/

2008-12-17

微软Imagine Cup 2009集训营一个下午的收获

  上周末微软中国开了个“Imagine Cup 2009“集训营,我们这些没在北京某处的同学们只有用live meeting 参加在线视频会议了。别说,上次参加全球的那个什么总结的视频会议都有很完美的效果,一时间让我认为现在视频会议的技术如此完美。没想到这次简直堪称垃圾。噪声不断也没有一个有效的控制手段,其中一位演讲的微软员工太欠缺这种视频演说的经验了可能,声音小的不到噪音的一半。我们再三提醒,再三由大变小。。。

  不过这次还是收获了不少东西。今天有空整理一下分享出来:
 
-----------------------------------------
IT解决方案:
  为我们介绍这个的是微软的一明叫做沈旭的技术经理,
  按照那位沈旭的说法,IT解决方案就是用多个产品构建一个架构性的解决问题的项目。

  做一个IT解决方案的需要:

  1. 相关的技术知识,MSF,MOF.(这两个是微软针对IT项目提供的参考方案)
  2. 前期:
    • 了解客户背景、客户需求
    • 解决方案设计,制定验收标准
    • 项目管理相关
      时间表、人员分工、风险评估、备选方案
  3. 中期
    • 部署、实施
    • 调优

  4. 后期
    • 测试:
      构建测试环境
      设计测试用例
    • 撰写项目报告

-----------------------------------------
  以上就是一个IT解决方案的整个业务流程。

接下来是软件开发项目的团队管理:
-----------------------------------------

  其实写软件容易管理一个软件团队高效的做好项目不是一件容易的事情。上图是那天ppt的截图。一个软件项目被分成上面这些成员来完成。之前我一直认为项目经理就是负责统筹整个项目并且参与项目构架的,结果这次才发现不是。
  架构师是从高层全局控制整个项目的,
  项目经理是负责平衡整个项目资源的分配,时间、成本控制,他应该独立于技术之外的。即使他是技术出身的。

  一般一个项目的流程是业务人员从客户那里获得客户需求,经过分析获得用例和非功能性需求之后交与项目经理,之后项目经理按照技术的角度来筛选可行性的功能,再交给开发团队。

  一般由于涉及具体的技术细节,开发人员一旦进入开发就很容易迷失到某一功能的完美当中去,这样就失去了对整体的把握。所以一般负责整体统筹的人就不应该作为Chief Developer。

  但是由于工作中,小团队常常不够人,这个时候就必须要有人兼任工作。
以下是演讲者根据他的经验给出的建议:
一般可以兼任的有:
PM + Architect
Architect + Chief Developer
Developer + Designer + Tester
但是:
PM + Chief Developer = FAIL!

------------------------------------------------------------------------------------

在会议的最后曾经参加过Imagine Cup的姚冬靖给我们介绍了一些他的经验,从声音和表现中可以了解到这位同学虽然现在在微软了,不过还是学姐级的人物哈。》》》好好学习中。。。。
------------------------------------------
组队的经验:
  • 统一的愿景
  • 多样化的成员
创新:
  • 头脑风暴->定案
  • 在已有的成果上
实现:
  胜者,先胜而后求其战
  • 先有保底方案,再逐步完善
  • 折衷,妥协
  提交项目时要考虑很多细节的问题,比如其他机器是不是能够很好的运行在你自己机器上编译好的东西啊。遇到这种冲突的时候如果实在无法解决的话就要想办法变通。。

最后,English Speech Capability
  • How to sell your solution
  • Business Sense
  • English

------------------------------------------


以上是那天记录的笔记,稍微重新整理了一下,但是未必能很完美的体现出那天的精髓所在,那天我们这些远程参加者在极度痛苦的噪音之下从2点拼到了快6点,总的来说这次微软中国的活动做的和微软美国直接开的视频会议还有一定差距。希望他们多多加油吧。。。
2009年5月还有第二轮集训,到时候有兴趣的读者可以参加。。。

如果希望观看录像的话可以到微软学生中心去下载。。。。

2008-12-02

Warning: Smarty error: unable to read resource: "index.htm" in .../smarty/libs/Smarty.class.php on line 1092 的解决方法

站点用到了smarty,迁移到其他服务器的时候结果不能使用提示类似于这样:

Warning: Smarty error: unable to read resource: "index.htm" in .../smarty/libs/Smarty.class.php on line 1092

这种情况就是无法读取到index.htm文件,所以只需要修改一下这个Smarty.class.php中的配置信息即可。

打开文件找到下面这些内容的位置:


    /**
* The name of the directory where templates are located.
*
* @var string
*/
var $template_dir = 'templates';

/**
* The directory where compiled templates are located.
*
* @var string
*/
var $compile_dir = 'templates_c';


只需要把这两个变量的值改成模板文件夹的相对路径即可。这里是相对于站点路径的相对路径,
我如说我的域名lab.xxx.xxx.xxx这个站点就是使用smarty的站点。现在我的模板文件的路径是
lab.xxx.xxx.xxx/smarty/templates,所以我要把上面两个设置成
smart/templates和smarty/templates_c

2008-11-15

Solaris10 05/08 在服务器上安装的管理 Part.2

  昨天手工之后没有检查,结果今天刚开始配置就遇到问题了,tar不支持gzip,没有make等等,原来安装的时候选了核心组件版本,结果现在很多包都要装过。

  还是老规矩直接上http://www.sunfreeware.com/去下载包,安装就直接用:

pkgadd -d filename

安装好。装好后记得要修改一下系统变量:

vi /etc/profile

添加下面蓝色的

#ident "@(#)profile 1.19 01/03/13 SMI" /* SVr4.0 1.3 */
# The profile that all logins get before using their own .profile.
trap "" 2 3

export LOGNAME PATH

PATH=/usr/local/bin:/usr/local/sbin: /usr/bin:/usr/sbin:/usr/ccs/bin;

expotr PATH


改完以后登录的用户的path都变成上面设置的了,不过如果你su到root的话。他的path却还是/usr/bin /usr/sbin,难度root账户的path设置无效了吗?不是,其实是这样:


如果以root用户身份登录或者用 su - 命令进行切换,则修改 home目录下.profile是管用的. 如果是简单的 用 su 进行切换, 则系统保留除 PATH之外的所有环境变量, PATH被设为 /etc/default/su 中的 SUPATH ,缺省时为/usr/sbin:/usr/bin
所以,如果要让PATH还是你设置的那个你就需要用su -命令来switch user。

此外,一个一定要注意的地方是,默认gun的那些包安装都会把执行文件装到/usr/local/bin下面,而sun自带的相同名称的软件都会放到/usr/bin下面,所以,要谨防因为调用错了程序而导致的奇怪问题。因为我一般都用gun版本的,所以只要保证path里面/usr/local/bin在后者之前即可。

之后编译安装mysql,这里,我遇到的问题是出现了libstdc++.so.6 找不到文件的错误,其实就是make的时候它搜寻的是/usr/lib/libstdc++.so.6但是在Solaris里面,这个文件在/usr/local/libstdc++.so.6,所以只需要做一个软连接就搞定了。

安装完之后,为了能够使用SMF来管理mysql的启动,需要做这些:
在/var/svc/manifest/network目录建立文件mysql.xml内容



<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">

<!-- MySQL Manifest - cuddletech, benr, August 28th, 2005 -->

<service_bundle type='manifest' name='cuddletech:mysql'>

<service
name='application/mysql'
type='service'
version='4'>

<create_default_instance enabled='false'/>

<single_instance/>

<dependency name='fs-local'
grouping='require_all'
restart_on='none'
type='service'>
<service_fmri value='svc:/system/filesystem/local'/>
</dependency>

<exec_method
type='method'
name='start'
exec='/etc/sfw/mysql/mysql.server start'
timeout_seconds='60' />

<exec_method
type='method'
name='stop'
exec='/usr/sfw/bin/mysqladmin shutdown'
timeout_seconds='60' />

<exec_method
type='method'
name='refresh'
exec='/usr/sfw/bin/mysqladmin refresh'
timeout_seconds='60' />

<stability value='Unstable' />

<template>
<common_name>
<loctext xml:lang='C'>MySQL Server</loctext>
</common_name>
<documentation>
<doc_link name='mysql.org'
uri='http://dev.mysql.com/doc/mysql/en/index.html' />
</documentation>
</template>
</service>

</service_bundle>


之后使用svccfg验证并导入配置文件
#svccfg validate /var/svc/manifest/network/mysql.xml
#svccfg import /var/svc/manifest/network/mysql.xml
这样就ok了。
基本的配置mysql:
获得配置文件:
cp /opt/mysql/share/mysql/my-large.cnf /etc/my.cnf
之后初始化数据库:
/opt/mysql/bin/mysql_install_db --user=mysql
之后启动数据库:
/opt/mysql/bin/mysqld_safe --user=mysql &
测试关闭数据库:
/usr/sfw/bin/mysqladm -u root shutdown
如果要使数据库的编码改为utf8
那么
vi /etc/my.cnf
在[client]后面添加一行
default-character-set=utf8
在[mysqld]之后添加同样的一行。
default-character-set=utf8
之后启动以后mysql -uroot
show variables like 'character%';
会显示如下结果
+--------------------------+----------------------------+
Variable_name Value
+--------------------------+----------------------------+
character_set_client utf8
character_set_connection utf8
character_set_database utf8
character_set_filesystem binary
character_set_results utf8
character_set_server utf8
character_set_system utf8
character_sets_dir /usr/share/mysql/charsets/
+--------------------------+----------------------------+
不过可惜的是,这样加使用mysqladmin就会提示
/usr/sfw/bin/mysqladmin: unknown variable 'default-character-set=utf8'
暂时没有去找新的方法。

接下来安装apache,参考之前的一篇文章。装好之后同样为了整合到SMF,这样做:

vi /var/svc/manifest/network/apache2.xml



<?xml version="1.0"?>

<!-- Copyright 2004 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. ident "@(#)http-apache.xml 1.2 04/11/11 SMI" -->

<service_bundle name="SUNWapchr:apache" type="manifest">

<service name="network/http" type="service" version="1">

<!-- Because we may have multiple instances of network/http provided by different implementations, we keep dependencies and methods within the instance. -->

<instance name="apache" enabled="false">
<dependency name="physical" type="service" restart_on="error" grouping="optional_all">
<service_fmri value="svc:/network/physical:default">
</dependency>

<exec_method name="start" type="method" timeout_seconds="60" exec="/etc/init.d/apache start">

<exec_method name="stop" type="method" timeout_seconds="60" exec="/etc/init.d/apache stop">

<exec_method name="refresh" type="method" timeout_seconds="60" exec="/etc/init.d/apache restart">

<property_group name="httpd" type="application">
<stability value="Evolving">
<propval name="ssl" type="boolean" value="false">
</property_group>

<property_group name="startd" type="framework">
<!-- sub-process core dumps shouldn't restart session -->
<propval name="ignore_error" type="astring" value="core,signal">
</property_group>

</instance>

<stability value="Evolving">

<template>
<common_name>
<loctext lang="C">
Apache HTTP server
</loctext>
</common_name>
<documentation>
<manpage title="apache" section="1M">
<doc_link name="apache.org" uri="http://httpd.apache.org">
</documentation>
</template>
</service>

</service_bundle>



之后导入svccfg:
# svccfg validate /var/svc/manifest/network/apache2.xml
# svccfg import /var/svc/manifest/network/apache2.xml

2008-11-14

Solaris10 05/08 在服务器上安装的管理 Part.1

  之前一直使用01/08版的,这次为了直接支持ZFS boot特地弄了个05/08版的,结果变化还真不少,而且能在核心机房的时间不多,所以还是需要一些配置的。
  安装过程之中设置好网络,装好后立马把SSH配置调整好,之后立马添加普通用户:
useradd -u 22222 -g adm -d /export/home/testuser -m -s /usr/bin/bash testuser
  这样一来就可以远程用SSH登录了,记得修改一下root账户的默认shell
vi /etc/passwd
  之后收起光盘走人了。。。。

DNS配置
  回到自己的机器上,SSH过去,好了,现在我们开始修改吧。首先,有时候你会发现,虽然在安装过程中指定了DNS服务器,但是在实际装好后DNS用的/etc/resolv.conf这个文件更本不存在。据说这是Solaris 2系列历史上遗留下来的毛病,即安装过程中你可以指定 DNS服务器 和 默认路由,但他不会自动保存。必须在安装完成系统之后手工建立和设定/etc/resolv.conf 和 /etc/defaultrouter 两个文件。不过我这里倒是有后者。
  要使DNS生效,还需要一番配置,首先是resolv.conf文件:
vi /etc/resolv.conf
--------------------------content to be added--------------------------------
; Sample resolv.conf file for the machine polaris
domain doc.com
; try local name server
nameserver 127.0.0.1
; if local name server down, try these servers
nameserver 123.45.6.1
nameserver 111.22.3.5
; sort the addresses returned by gethostbyname(3c)
sortlist
130.155.160.0/255.255.240.0
130.155.0.0
--------------------------------------------------------------------------

以上内容是从docs.sun.com转来的范例,注意domain后面的域名必须马上回车不允许任何空白字符出现。一般如果只需制定dns服务器的话只用nameserver。
编辑完后保存,下一步,编辑/etc/nsswitch.conf找到host这一行改成这样:
hosts: files dns
当然,根据使用的名字服务不同官方给出的配置是这样的:
-----------------------------------------------------------------------------
Specify DNS as a source of hosts information.
DNS can be the only source or an additional source for the hosts information. Locate the hosts line and use DNS in one of the ways shown below:
hosts: files dns
or
hosts: nisplus dns [NOTFOUND=return] files
or
hosts: dns nisplus [NOTFOUND=return] files
Do not use the above syntax for NIS clients, since they will be forced to search for unresolved names twice in DNS.
----------------------------------------------------------------------

最后启动服务:
svcadm enable network/dns/client
这样就可以使用DNS了。
Solaris解析域名的顺序是这样的:

  1. 查询/etc/nsswitch.conf以确定解析顺序,因为之前我们制定的是file dns ,所以先根据本地配置来查询,之后才是dns服务器,因此接下来
  2. 查询/etc/hosts如果没有再下来
  3. 从/etc/resolv.conf查询dns服务器和搜索顺序。之后提交请求。

接下来,由于我发现系统的时间不对。于是同步一下,有两种方法:
rdate time-a.nist.gov
ntpdate time-a.nist.gov


接下来处理一下服务,因为之前我害怕有软件包没有装好,之后还得回来装,所以就安装了entire版本的。现在需要去除一些服务。
online         10:33:13 svc:/application/graphical-login/cde-login:default
online 19:30:36 svc:/network/cde-spc:default
online 10:33:39 svc:/network/rpc/cde-ttdbserver:tcp
online 10:33:39 svc:/network/rpc/cde-calendar-manager:default
online 10:33:41 svc:/application/cde-printinfo:default

第一个cde-login是cde登录的服务,我们只用console,所以关了。
第二个的解释是:The CDE Subprocess Control Service is a network daemon that accepts requests from clients to execute commands and launch applications remotely.貌似它会打开6112端口,我试着关闭了,不影响ssh,所以也disable。
第三个是ToolTalk database server,tooltalk是xstart的一个组件,而这个server干下面这些活
  1. ToolTalk objects specs.
  2. ToolTalk session IDs of sessions with clients that have joined a file using the tt_file_join call.
  3. File-scoped messages that are queued because the message disposition is TT_QUEUED and a handler that can handle the message has not yet been started.

所以也禁用了。

第五个看了就知道没用。

第六个是CDE Print Viewer,The CDE Print Viewer program provides a graphical interface that displays the status of print queues and print jobs。所以也禁用了。

为什么要禁用这些?原因很简单,第一我不用gui 第二,你google一下就会发现这些服务都有漏洞报告,虽然比较早,但是也未必就被修复了。

要管理这些服务在Solaris里面非常方便,直接使用SMF管理。
inetadm :提供观察或配置由 inetd 控制的服务的功能
svcadm :提供执行常见服务管理任务(如启用、禁用或重新启动服务实例)的功能
svccfg :提供显示和处理服务配置系统信息库内容的功能
svcprop :从服务配置系统信息库中检索属性值,并采用适用于 shell 脚本的输出格式
svcs :提供服务配置系统信息库中所有服务实例的服务状态的详细视图

这样稍微处理了一下之后系统就干净了。可以开始接下来的工作了。

2008-10-03

Solaris环境下Tomcat的安装配置以及与Apache的整合

  在最开始,安装之前现了解一下背景知识是相当有用的。

  Tomcat 本身已经提供了 HTTP 服务,该服务默认的端口是 8080,装好 tomcat 后通过 8080 端口可以直接使用 Tomcat 所运行的应用程序,你也可以将该端口改为 80。

  但是鉴于以下原因,我们需要整合Apache和Tomcat:

  1. 提升对静态文件的处理性能
  2. 利用 Web 服务器来做负载均衡以及容错
  3. 无缝的升级应用程序

  由于Tomcat本身就是Apache软件基金会的一个项目,自然它肯定能够很好的和Apache结合。因此很多服务器都采用这种方式。

  一般来说,要进行这种集成,我们一般希望让静态的页面有apache处理,动态的jsp就由tomcat处理。


目前有三种方法可以将 apache 和 tomcat 整合在一起。

JK:

This is the top-level entry point of the documentation bundle for the Apache Tomcat Connectors

Select one of the links from the navigation menu (to the left) to drill down to the more detailed documentation that is available. Each available manual is described in more detail below.

  上面就是JK的官方介绍,它本来就是tomcat项目的一部分。

http_proxy :

  直接利用Apache自带的 mod_proxy 模块使用代理技术来连接 Tomcat。http_proxy 模式是基于 HTTP 协议的代理,因此它要求 Tomcat 必须提供 HTTP 服务,也就是说必须启用 Tomcat 的 HTTP Connector。

ajp_proxy:

ajp_proxy 连接方式其实跟 http_proxy 方式一样,都是由 mod_proxy 所提供的功能。配置也是一样,只需要把 http:// 换成 ajp:// ,同时连接的是 Tomcat 的 AJP Connector 所在的端口。
简单来说这三种方法就是:
 通过ajp13协议,apache将动态内容的请求转发给tomcat
 在apache进程中运行tomcat来处理动态内容  
 使用本地高速Unix domain socket,apache将动态内容的请求转发给tomcat


  实际上虽然后两者在性能上不会逊色多少,而且更简便灵活,但是在稳定性上恐怕还是JK更胜一筹,所以我还是使用JK来配置吧。


  找了很多资料,最终对我有帮助的就只有两个信息。一个是前面这个,另外一个就是这种连接的原理:假设apache使用端口是80,tomcat使用端口是8080。服务器ip是10.1.1.12这个时候,当我们通过http://10.1.1.12访问网站的时候内容是由apache处理的,当我们通过http://10.1.1.12:8080访问网站的时候,内容就是有tomcat处理的。但是,当整合成功以后,我们通过http://10.1.1.12访问网站中的jsp页面,比如http://10.1.1.12/test.jsp时,apache会把请求转给tomcat来处理。
  这个就是我们整合的终极目标了,也是通过这个来判断是否整合成功。而通过apache转给tomcat的请求在tomcat的status的jkstutus中能看到:

jk-8009

Max threads: 200 Current thread count: 4 Current thread busy: 3
Max processing time: 369 ms Processing time: 0.374 s Request count: 3 Error count: 1 Bytes received: 0.00 MB Bytes sent: 0.00 MB

StageTimeB SentB RecvClientVHostRequest
K44520 ms??10.1.1.111??
K2680 ms??10.1.1.111??

P: Parse and prepare request S: Service F: Finishing R: Ready K: Keepalive



那么,接下来我们开始动手。。。

我的apache已经装好了,那么先装好tomcat:

开始安装之前先添加JAVA_HOME路径到环境变量:
JAVA_HOME=/usr/java
CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
CATALINA_BASE=/usr/local/tomcat
CATALINA_HOME=/usr/local/tomcat
JRE_HOME=/usr/java/jre
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin:$CATALINA_HOME/bin:/usr/sfw/bin:/usr/ccs
export PATH JAVA_HOME CLASSPATH CATALINA_BASE CATALINA_HOME JRE_HOME


之后解压官方下载的包,然后拷贝到安装的目录下,执行
./bin/startup.sh
之后打开http://localhost:8080
出现成功信息就表示安装成功了。
安装JK:
  根据说明文件直接编译吧

配置:
  要配置好Apache和Tomcat的整合,必须要配置这三个文件:

httpd.conf
Apache 服务器的配置文件,用来加载 JK 模块以及指定 JK 配置文件信息

workers.properties
到 Tomcat 服务器的连接定义文件

uriworkermap.properties
URI 映射文件,用来指定哪些 URL 由 Tomcat 处理,你也可以直接在 httpd.conf 中配置这些 URI,但是独立这些配置的好处是 JK 模块会定期更新该文件的内容,使得我们修改配置的时候无需重新启动 Apache 服务器。



cp ./conf/workers.properties /usr/local/apache/conf/
cp ./conf/uriworkermap.properties /usr/local/apache/conf/
之后按照这个文件里面的提示修改文件吧。
然后编辑apache的httpd.conf,以下是官方文档里的内容
# Load mod_jk module
# Update this path to match your modules location
LoadModule jk_module modules/mod_jk.so
# 加载jkmodule的参数
# Where to find workers.properties
# Update this path to match your conf directory location (put workers.properties next to httpd.conf)
JkWorkersFile /etc/httpd/conf/workers.properties
# 指定workers.properties的所在路径
# Where to put jk shared memory
# Update this path to match your local state directory or logs directory
JkShmFile /var/log/httpd/mod_jk.shm
# Where to put jk logs
# Update this path to match your logs directory location (put mod_jk.log next to access_log)
JkLogFile /var/log/httpd/mod_jk.log
# Set the jk log level [debug/error/info]
JkLogLevel info
# Select the timestamp log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
# Send everything for context /examples to worker named worker1 (ajp13)
JkMount /examples/* worker1、
# 将/examples虚拟路径下的所有内容转有worker1处理,其实这个worker1就是jk的配置文件中配置用于连接apache和tomcat的东西。
除了这些外,我们应该自己添加的东西:
JkMount /*.do worker1
JkMount /*.jsp worker1
#类似上面,指定目录下所有扩展名为.do .jsp的文件由worker1来处理

之后修改/usr/local/apache/conf/worker.properties
基本上按照说明修改一些路径就可以了。上面在httpd.conf中指定的worker1应该出现在worker.list中,并且拥有worker.worker1.type=ajp13.
此外这个文件还可以用来配置负载均衡,不过我暂时不需要了。所以就没有配置了。而且默认的文档里其实已经有配置一个loadbalancer,如果需要我们只需要把worker.list后面的对象改成loadbalancer前面的worker1自然也改成这个就可以了。worker.list指定的对象是告诉jk哪些worker是可用的。


这样配置之后,基本就没有问题了。开启tomcat和apache看看。

最后记得在启动脚本里增加tomcat的自动启动。

参考文章:http://www.ibm.com/developerworks/cn/opensource/os-lo-apache-tomcat/index.html



---------------------------------------------------------------
此外,如果需要将tomcat的管理统一到Solaris的smf之中,可以这样做:

vi /var/svc/manifest/network/tomcat.xml
文件内容:

<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type='manifest' name='Tomcat'>
<service name='application/server/tomcat' type='service' version='1'>
<single_instance />
<dependency
name='filesystem'
grouping='require_all'
restart_on='none'
type='service'>
<service_fmri value='svc:/system/filesystem/local' />
</dependency>
<exec_method
type='method'
name='start'
exec='/opt/Webservices/tomcat/bin/startup.sh'
timeout_seconds='300' />
<exec_method
type='method'
name='stop'
exec='/opt/Webservices/tomcat/bin/shutdown.sh'
timeout_seconds='300' />
<instance name='default' enabled='true' />
<stability value='Unstable' />
<template>
<common_name>
<loctext xml:lang='C'>Tomcat6.018</loctext>
</common_name>
</template>
</service>
</service_bundle>

之后
svccfg validate 和 svccfg improt这个文件即可。

2008-09-29

Solaris console环境下构建Apache+MySQL+PHP 平台

  其实,Solaris Express Developer Edition的安装过程中只要选完全安装这些东西就会自动装好的,不过,我们总得学会自力更生吧,所以我在安装系统的过程中没有安装这些,而选择了自己手动安装。
  基本上呢,solaris需要的东西都能通过http://www.sunfreeware.com/这个地方下载到,因为没有GUI,所以我们要会用ftp命令,路径可以在网站里查到,我们用ftp程序直接下载动solaris系统吧。看下网站上的说明就明白了:

[179] steve> ftp ftp.sunfreeware.com
Connected to ftp.sunfreeware.com.
220 ftp.sunfreeware.com FTP server ready.
Name (ftp.sunfreeware.com:steve): anonymous
331 Guest login ok, send your complete e-mail address as password.
Password:
230-
230-==============================================
230-This is the ftp.sunfreeware.com ftp server
230-
230-If you have not already done so, make sure
230-you have read the Downloading/Installation,
230-FAQ, and Disclaimer links on
230-http://sunfreeware.com.
230-
230-This is a restricted access system. All
230-transfers are logged. If you disagree
230-with this practice, log off now.
230-
230-Questions go to Steve Christensen at
230-steve@smc.vnet.net.
230-==============================================
230-
230-
230 Guest login ok, access restrictions apply.
ftp> bin
200 Type set to I.
ftp> cd pub/freeware
250 CWD command successful.
ft>p

这里为了方便,我期望使用ssh远程登录到solaris服务器上,因此先安装。如果你之前装了就别再装了,用svcs查看一下有没有ssh服务在运行:
svcs | grep ssh
如果没有的话再安装,从这个网站下载的软件包只要gzip -d 一下之后用pkgadd -d 一下就安装完了。
接下来配置openssh:
配置文件是/etc/ssh/sshd_config
我要做的只有几个事:
改端口:把port右边的22改成需要的端口号。
允许root用户登录,虽然这不安全,但在我现在使用的时刻正好需要。
好了,ssh配置完以后就可以在图形界面下的机器用ssh远程登录到服务器了,而且可以直接使用sftp传送文件,这样就不要每个文件都去输入名字传输了。
接下来就准备安装Apache了,从那个网站的下载介绍里面能看到它的包依赖信息:
apache-2.2.9-sol10-x86-local.gz Apache 2 - the popular web server - installs in /usr/local/apache2. Dependencies: expat, libiconv, openldap, sasl, zlib, openssl-0.9.8h, and either the libgcc-3.4.6 or gcc-3.4.6. Documentation can be found in /usr/local/apache2/doc/apache2. The configuration files in /usr/local/apache2/conf must be edited to fit your site's needs, including ssl support.

本来可以直接使用这个网站提供的包来安装这三个软件的的,不过我希望试试自己编译,所以直接从官网下了unix版的源码来编译安装:

先是mysql:

 从官方下载的包安装:
  • 建立目录:
    mkdir /usr/local/apache
  • 建立mysql的用户组和用户
    groupadd -g 110 mysql
    useradd -u 10001 -g mysql -m -d /export/home/mysql -s /bin/bash mysql
    passwd mysql

  • 安装好软件包就可以了,注意,如果之后安装php的时候用的是32位的,就要装32位的mysql,否则无法编译php。装好后如果能够正常启动服务并用空密码登录root就成功了,不能的话看下面
  不知为什么我的机器就是装不好官方下的那个包,总是提示pid文件找不到什么的,无奈之下,采取另外一种方法:
rm -fr /opt/mysql/mysql/data/*
因为我用官方包安装所以安装的路径是这个。
之后
cd /opt/mysql/mysql
./scripts/mysql_install_db --user=mysql

这里如果成功的话再
./bin/safe_mysqld --user=mysql
应该就能启动服务了。
不过相当无奈的是这个情况下root用户一直被拒绝登录。只能用别的方法了:
先停止服务:
/etc/init.d/mysql stop
用这个类似于超级维护模式的方法开启服务:
./bin/safe_mysqld --user=mysql --skip-grant-tables --skip-networking &
好了,输入mysql总算是进入mysql monitor了。不过问题来了。
select * from mysql.users
结果是0条数据。。。汗死。。。
所以我就试试直接新建一个用户的方法了:
mysql> INSERT INTO mysql.user (Host,User,Password)VALUES('%','test',PASSWORD('tset'));
mysql> FLUSH PRIVILEGES


弄完之后
/etc/init.d/mysql restart
最后成功的用那个帐户登录了。。。。
最后在启动脚本里面增加文件让mysql开关机时自动开启关闭:
ln /opt/mysql/mysql/support-files/mysql.server /etc/rc3.d/S99mysql
ln
/opt/mysql/mysql/support-files/mysql.server /etc/rc0.d/K00mysql
ln
/opt/mysql/mysql/support-files/mysql.server /etc/rc1.d/K00mysql
ln
/opt/mysql/mysql/support-files/mysql.server /etc/rc2.d/K00mysql
ln
/opt/mysql/mysql/support-files/mysql.server /etc/rcS.d/K00mysql

mysql到此就装好了。
 从源代码安装:
  • 准备动作同上,之后解压源代码,执行:
    ./configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --disable-nls --prefix=/usr/local/mysql --with-mysqld-user=mysql --with-charset=gb2312 --with-extra-charsets=all
    with-as那一项是指定汇编编译器
  • 上一步执行成功之后就可以开始编译了,make的过程比较持久,我们好好等待吧。
  • 之后的步骤同上

 

接下来是Apache+php了:
  • 在编译之前必须安装一下软件包:
    SUNWarc
    SUNWbtool
    SUNWhea
    SUNWlibm
    SUNWsprot
    SUNWtoo

    这些包可以直接从光盘安装,方法:
    pkgadd -d /cdrom/sol_11_x86/Solaris_11/Product/ SUNWarc
    ...

  • 必须注意的一点是,Apache2.2以上的版本除了要安装编译环境之外还必须安装apr-1.2.2-sol10-x86-local.gz与aprutil-1.2.2-sol10-x86-local.gz这两个包,否则configure会出现configure failed for srclib/apr错误。目前从sunfreeware下的包还是不能编译apache,貌似是少了一个版本文件,所以我是从apr.apache.org那里下了新版自己编译的。
  • 编译apache:
    ./configure --prefix=/usr/local/apache -enable-so -enable-mods-shared=most
    这样就动态编译了apache了。编译完后安装,之后别动。
  • 编译php:
    ./configure --prefix=/usr/local/php --with-mysql=/usr/local/mysql --with-apxs2=/usr/local/apache/bin/apxs
    注意那个apxs2
  • cp /usr/local/apache/bin/apachectl /etc/init.d/httpd
    cp php.ini-dist /usr/local/apache/conf/php.ini
  • 修改配置文件:
    检查LoadModule 中是否有
    LoadModule 5_module modules/libphp5.so
    这一行,没有加上。
    ServerName这一行指定好自己的服务器的域名或ip。
    默认的DocumentRoot可以修改。
    加一行AddType application/x-httpd-php .php .phtml
  • 之后/etc/init.d/httpd start来开启apache,就可以在别的机器上测试一下apache成功与否了。
基本上写一个index.php页面,内容如下:
<html>
<body>
<title>Hello World</title>
<?php phpinfo(); ?>
</body>
</html>


如果成功的话,就会出现php的信息了。
最后增加启动脚本并且连接文件:
ln -s /etc/init.d/httpd /etc/rc3.d/S90http
ln -s /etc/init.d/httpd /etc/rc3.d/K90http
ln -s /usr/local/apache/bin/apachectl /usr/bin/apache
/*******************************************
*原创文章,转载请注明出处
*******************************************/

Solaris10 console下配置网络

主要有几个文件需要配置:

  1. /etc/hosts 主机名解析 就是host表
  2. /etc/hostname.interface interface是网卡名,用于分配主机名,直接在里面输入主机名就好了。
  3. /etc/netmasks 设置子网掩码格式类似于:
    10.1.1.0 255.255.255.0
  4. /etc/inetd.conf 参见下面这段话
    UNIX并不是让每种服务的守护进程都在自己的端口上等待请求,而是将代表各个服务守护进程等待请求的任务交给一个叫inetd的服务进程。这样就可以大 大减少对系统资源的占用。只有当超级服务进程发现一个服务请求时,它才调用该服务的守护进程。/etc/inetd.conf配置文件允许inetd在启 动时决定自己将代表哪些服务等待服务请求。如果一种服务的守护进程没有包含在inetd.conf文件中,那么当inetd接收到该服务的请求时,会把该 请求丢弃。
    文件的字段:
    service_name 这是文件/etc/services中列出的服务的标志符。
    socket_type 用来标志使用的数据传输服务的类型。
    proto 标识传输协议的名字。是UPD和TCP
    flags 可以被设为"等待"和"非等待"。如果被设为"等待" 状态,inetd在恢复监听端口上的其他请求时,必须等待服 务协议释放将其连接到网络的连接。"非等待"可以使 inetd立即监听其他的请求。大多数TCP协议的采用"非等 待"方式,而UDP采用"等待"方式。
    user 表示调用服务的用户名。
    server_pathname 表示inetd在响应相关服务请求时必须调用的 服务程序的完整路径名。
    Args 该域包括服务的程序所使用的命令行参数。即以程序名开 始,然后跟随用户设置的参数
  5. /etc/defaultrouter 设定默认路由 直接输入网关的ip地址一般就可以了。
  6. /etc/gateways 这个是路由表文件,设置比较麻烦
  7. /etc/nsswitch.files 设定名字搜索顺序 记得在hosts: files背后加个dns
  8. /etc/resolv.conf 配置dns服务器的地址和域名格式:
    domain abc.efg.com
    nameserver 10.3.3.33

其他命令:
ifconfig
nslookup
netstat等等

2008-09-22

ubuntu的小键盘问题

  基本上,这个问题相当奇怪,不知道什么时候,重启一下之后突然小键盘没办法输入数字了。。。反倒变成鼠标控制键了,而且numlock是启动的状态。。。
  结果呢,其实只要用shift+alt+numLock组合键一按就可以恢复了。其实在xwindow的常用快捷键里有介绍的:


1. Ctrl-Alt-“+” 或者 Ctrl-Alt-“-”- 改变屏幕分辨率(提高/降低)。前提是在X-Window server配置文件中写入了多种可用分辨率。
2. Ctrl-Alt-Backspace - 杀死X-server,返回登录界面。所有正在运行的应用程序将被终止。
3. Ctrl-Alt-Escape - xkill - 点击一个应用程序强制关闭。
4. Ctrl-Shift-Num Lock 把键盘上的小键盘(数字键盘)变成鼠标,启动后你可以用小键盘进行鼠标操作。数字键盘上的/和 * 分别代表鼠标左键和鼠标右键,数字键盘上的 5是双击。
5. Ctrl-Alt-Fn (F1, F2, F3,…) - 切换到第 n 个文本控制台。一般Alt+F7切换回X-window。
6. Alt-F2 - 开启一个运行命令的小窗口。如果输入的是可执行命令则直接运行;如果输入的是文件名系统将调用适当的应用程序打开它;输入网址将用默认的浏览器打开它。
基本上,这个也是一项功能吧。

2008-09-21

mkv视频的处理

  随着高清的普及,以mkv封装发布的视频越来越多。这种格式的视频需要处理的话直接用普通的傻瓜式程序是不可能的,而使用mencoder又会改变封装,这个过程会产生奇怪的问题。比如不同步,时间轴不准等等。这个时候就需要使用强大的MKVToolnix。
  官方对它的定义是:MKVToolnix -- Cross-platform tools for Matroska
  当然就是跨平台,又开源的东西了。我这次用的是linux平台来解说。也可自己参照官网的文档:http://www.bunkus.org/videotools/mkvtoolnix/source.html
  MKVToolnix包括mkvmerge mkvinfo mkvextract
  mkvmerge的gui版使用mmg命令启动。下面主要介绍一下我自己常用的功能:

切割mkv视频:
  mkvmerge在切割方面提供了三种方法,见split参数解释:
  

Splits the output file after a given size or a given time. Please note that tracks can only be split right before a key frame. Due to buffering mkvmerge will split right before the next key frame after the split point has been reached. Therefore the split point may be a bit off from what the user has specified.
At the moment mkvmerge supports three different modes.
1. Splitting by size.
The parameter d may end with k, m or g to indicate that the size is in KB, MB or GB respectively. Otherwise a size in Bytes is assumed. After the current output file has reached this size limit a new one will be started. The size: prefix may be omitted for compatibility reasons.
2. Splitting after a duration.
The paramter must have the form HH:MM:SS.nnnnnnnnn for specifying the duration in up to nano-second precision or a number n followed by the letter ’s’ for the duration in seconds. "HH" is the number of hours, "MM" the number of minutes, "SS" the number of seconds and "nnnnnnnnn" the number of nanoseconds. Both the number of hours and the number of nanoseconds can be omitted. There can be up to nine digits after the decimal point. After the duration of the contents in the current output has reached this limit a new output file will be started. The duration: prefix may be omitted for compatibility reasons.
3. Splitting after specific timecodes.
The parameters A, B etc must all have the same format as the ones used for the duration (see above). The list of timecodes is separated by commas. After the current file has reached the current split point’s timecode a new file is created. Then the next split point given in this list is used. The timecodes: prefix must not be omitted.
For this splitting mode the output filename is treated differently than for the normal operation. It may contain a printf like expression ’%d’ including an optional field width, e.g. ’%02d’. If it does then the current file number will be formatted appropriately and inserted at that point in the filename. If there is no such pattern then a pattern of ’-%03d’ is assumed right before the file’s extension: ’-o output.mkv’ would result in ’output-001.mkv’ and so on. If there’s no extension then ’-%03d’ will be appended to the name.  
  废话很长,其实就是三种,一个按大小分割,一个按每次分割出的文件有多长时间分割,还有一个按照时间点分割也就是从头开始,当时间到你填入的时间点时它会自动分割一个文件。
比如我填50s,160s那么视频会被分成三个片段,一个从头到50s第二个从50s到160s,第三个从160s到结束。


提取mkv视频中的流:
  直接用mkvextract命令就好了。

封装成mkv:
  同样使用mkvmerge就好了。

2008-09-17

从雷曼兄弟简史说去–

  昨天,Wall Street Journal又发布了一条死亡消息:

雷曼兄弟公司(1850年至2008年)从起家于亚拉巴马州到倒闭于华尔街的经营史:

  • 1850: 来自于德国巴伐利亚的移民亨利•雷曼、埃马努尔•雷曼和迈尔•雷曼三兄弟在亚拉巴马州的蒙哥马利创办了这家公司,从事大宗商品交易业务。
  • 1984: 雷曼兄弟公司的投资银行家和交易员之间的争斗导致该公司被出售给了Shearson公司。
  • 1990: Shearson Lehman Hutton重新启用了雷曼兄弟这一公司名称。
  • 1993: 美国运通公司(American Express) 将Shearson分拆出去,获得独立的雷曼公司再次以雷曼兄弟的名字著称于世。
  • 1994:该公司以雷曼兄弟控股公司(Lehman Brothers Holdings Inc.)的名称在纽约证交所上市。
  • 2003: 雷曼兄弟收购了资产管理公司Neuberger Berman。
  • 2008: 饱受按揭贷款市场问题打击的雷曼兄弟公司申请破产保护。

  3月16号,JP Morgan捡便宜赚到了Bear Stearns,没过半年Lehman Brothers也终于倒下了,
巴克莱花了20亿买下了Lehman的“好银行”部分,继Lehman之后,美国墙倒众人推式的好戏又在AIG上上演了,道指暴跌500点可见这个公司的影响有多么大了,那么,AIG是否会成为下一个下场的演员呢?虽然Fed在考虑出资拯救,但是结果会如何还是未必之数。所以,让我们拭目以待吧。
  金融界的动荡能够撼动巨头,轻易的让它们崩溃,终于能够理解为什么日本90年代能有那种悲惨的经济情况了。美国这个资本巨鳄的市场居然看起来这么的脆弱。着实让我等经济领域的初学者感到惊奇。
  话说回来,以平常的角度看,我们知道变革,剧烈的变革,但是,略微稳定的生活却在消弭这种感觉。仿佛,渐渐的我们不自觉的会感到,这个世界是稳定的,那种看上去庞大的东西是不会轻易毁灭的了,渐渐的丧失了洞察力。渐渐的在小小的平庸之中沉醉,直到有一天,变革的风暴席卷而来,将我等卷入其中,那个时候,我们这小小的生活被轻易的撕裂,才幡然醒悟,原来,变革是时刻在发生的。

2008-08-27

XML基础知识概要

  终于到传说中我因为在高中的时候没有学习而最后悔的XML了。本文假定读者熟悉HTML
  XML(eXtensible Mark-up Language),类似与HTML又不同,关键在于它可以自定义自己的标记符和属性,所以是extensible。
  与HTML不同的是,XML一般用于存储数据、处理数据和交换数据。

基本规则:
  XML采用层次数据结构规则。我们总能让XML文件与一个树型数据结构互相转换。
  与HTML类似,XML的标记也是成对出现的,嵌套时同样对称存在。标记也允许若干参数与属性。注释和HTML一样都是<!-- comments -->.

  在xml中所有的参数的值必须使用单引号或者双引号包围。

  只有严格符合XML标准的文档才是格式良好的xml文档。
  注意,XML大小写敏感。
  
文档类型定义DTD:
  为了对数据的合法性进行验证,XML文件一般会有一个文档类型定义(Document Type Definition),指定元素应该以怎样的规则保存。他定义了某个标志符是否存在,存在的顺序和嵌套法则。
  XML的一个重要的特征是名字空间,学过C++和Java都很清楚这个概念。XML支持名字空间,因而定义的标记符不会和其他人的类似名字的标记符冲突。要在DTD中定义名字空间只需要在元素的标记符中增加一个xmlns属性。

一个经典的DTD演示了XML的强大功能:

<!-- DTD for Shakespeare J. Bosak 1994.03.01, 1997.01.02 -->

<!-- Revised for case sensitivity 1997.09.10 -->

<!-- Revised for XML 1.0 conformity 1998.01.27 (thanks to Eve Maler) -->



<!ENTITY amp "&">

<!ELEMENT PLAY (TITLE, FM, PERSONAE, SCNDESCR, PLAYSUBT, INDUCT?,

PROLOGUE?, ACT+, EPILOGUE?)>

<!ELEMENT TITLE (#PCDATA)>

<!ELEMENT FM (P+)>

<!ELEMENT P (#PCDATA)>

<!ELEMENT PERSONAE (TITLE, (PERSONA | PGROUP)+)>

<!ELEMENT PGROUP (PERSONA+, GRPDESCR)>

<!ELEMENT PERSONA (#PCDATA)>

<!ELEMENT GRPDESCR (#PCDATA)>

<!ELEMENT SCNDESCR (#PCDATA)>

<!ELEMENT PLAYSUBT (#PCDATA)>

<!ELEMENT INDUCT (TITLE, SUBTITLE*, (SCENE+|(SPEECH|STAGEDIR|SUBHEAD)+))>

<!ELEMENT ACT (TITLE, SUBTITLE*, PROLOGUE?, SCENE+, EPILOGUE?)>

<!ELEMENT SCENE (TITLE, SUBTITLE*, (SPEECH | STAGEDIR | SUBHEAD)+)>

<!ELEMENT PROLOGUE (TITLE, SUBTITLE*, (STAGEDIR | SPEECH)+)>

<!ELEMENT EPILOGUE (TITLE, SUBTITLE*, (STAGEDIR | SPEECH)+)>

<!ELEMENT SPEECH (SPEAKER+, (LINE | STAGEDIR | SUBHEAD)+)>

<!ELEMENT SPEAKER (#PCDATA)>

<!ELEMENT LINE (#PCDATA | STAGEDIR)*>

<!ELEMENT STAGEDIR (#PCDATA)>

<!ELEMENT SUBTITLE (#PCDATA)>

<!ELEMENT SUBHEAD (#PCDATA)>

这份文档是XML的创始人Jon Bosak写的,你可以从http://saxon.sourceforge.net/saxon6.5.5/samples.html#shakespeare这里找到


XML文档:

  每个XML文档都有一个逻辑和物理结构。

  物理上,文档是由称为Entities的单元组成,实体都有内容,并且都是实体的名字标识的。尸体可以是各种可以存储的东西,文档开始于根或者文档实体。

  格式良好的XML文档在逻辑上有一个层次树结构,这个树的根节点就是文档实体,文档实体没有名字,只是用来表示根,XML的文档的根元素成为文档元素,它和外部出现的处理指令、注释等作为文档实体的子节点,根元素和它的内部子元素也是一颗树。

  简而言之,XML文档就是一种树型的逻辑结构。


  实体可以包含parsed 和unparsed数据,前者是由一些表示数据与标记的字符组成,parsed entity内容被称为它的替换文本,作为文档整体的一部分,在XML处理程序分析XML文档时,凡是出现引用parsed entity的地方都会被这个实体的内容替换。unparsed entity是一种资源,有一个相关联的用名字标识的notation。前者用实体引用的方法通过名字调用,后者通过entity属性中给出的名字来调用。

  逻辑上,一个XML由声明、元素、注释、字符引用和处理指令组成,所有这些东西都是通过标记来表明,XML标记包括开始标签,结束标签,空元素标签,实体引用,字符引用,注释,CDATA段定界符、文档类型声明,处理指令,XML声明,文本声明以及在文档实体顶层的空白和普通字符组成。


---------------------------------------------------------------------
---------------------------------------------------------------------

XML文档的解析

  通常程序获得xml文档都是通过xml解析器,其模型一般都是程序通过xml解析器提供的api来调用xml解析器。
  所有的解析器都对DOM(Document Object Model)和SAX(Simple API for XML)这两套api提供支持。
  在Java中,有一个叫做JAXP(Java API for XML Processing)的API它只是提供给java程序员一种标准化的形式的XML编程方式。开发者只需要使用JAXP编程,而无须关心底层的解析器。

  DOM的核心概念是节点,使用DOM分析XML文档,它会把XML文档映射成一个对象,这个对象叫做节点。在内存中,这些节点形成一颗文档树。通过操作这个树型对象来获取内容。

  SAX的处理机制有些不同,它是基于事件处理的API,它包括解析器和事件处理器,前者负责读取XML文档,并向事件处理器发送事件,后者负责对事件做出响应,进行处理,这一点我觉得和java的监听器的架构有点类似。

2008-08-24

JAVA绘图板中绘制图形的解决方法

  如果你和我一样是一个Java新手的话,如果你也正在编写一个能够绘制一些基本图形的绘图板程序的话。那么,你一定会面临的一个问题就是,包括鼠标的拖拽时的问题在内的图形绘制了。
  如果之使用默认的repaint等方法,一定会遇到的问题就是,即使你实现了鼠标拖拽的时候图形的动态绘制。但是无法解决之前绘制的图形的消失问题。
  原来画好一条直线,拖拽着画下一条的时候前面那条就会消失掉。当然,一种解决方法就是重载paintComponent方法。让每次repaint的时候都把列表中所有的图形全部重画。不过这不是一个好方法。因为在鼠标拖拽的时候。至少要重复10多次repaint的动作。如果原来的组建数量多了。那么计算量就是成几何级数上升的。所以我们不能采用这个方法。
  这个方法不通之后,我查阅了不少资料,看了几个程序。最后得到的思路就是。结合双缓冲。
  我重载了监听器的3个方法。分别是压下鼠标。拖拽鼠标(就是压下为松开并移动mouseDragged)。释放鼠标。
  压下鼠标时,向图形定义类的实例传送一个坐标值。拖拽鼠标时实时更新点坐标,但是不传递这个点坐标,而是利用它的值不断重绘图形。当放开鼠标时向图形定义类的实例传送第二个坐标。这里就是关键了。传递完坐标之后先保存这个实例,然后向前面建立的用于双缓冲的图形绘制所有已保存的实例。
  这里看似和普通过程没有区别,不过关键在那个双缓冲用的图形。在我重载的paintComponent方法中,我是先刷新一次整个页面。也就是清空了,之后绘制那个双缓冲的图形,最后绘制用户正在画的图形。
  这样一来,在拖拽过程中实际只绘制了两个对象,一个是双缓冲的图形,另外一个就是用户正在绘制的图形,而在鼠标松开的那个阶段我清空了双缓存的图形,完全重新绘制它。这样就保证了添加移动撤销等动作能够正常执行。

/*******************************************
*原创文章,转载请注明出处
*******************************************/

2008-08-23

学校的锐捷认证在Linux下可行性的进一步测试

  上次研究ubuntu 8.04 的64位下运行锐捷的方法就是为了在学校的宿舍实现linux下的锐捷认证。
  上次虽然完成了程序的运行,但是最终还是没有能够成功的认证,究其原因,因为我们学校的锐捷认证是通过绑定mac地址+dhcp实现的,而锐捷那个可悲的客户端dhcp分配本身就似乎有问题,去官方论坛问了好久也没人回帖。无奈之下又试了好几个网上能找到的开源版,不过最终都没用,最终,采取了强制的静态ip的方法。因为这种分配机制ip不是一直都是随机分配的,有一个租用期限,这个期限之内理论上强制用同一个ip是没问题的。根据网上搜集到的资料确实有人用这种方法成功通过认证。可惜的是用这种方法仍然无法认证。回复的错误信息是“不允许的客户端”。
  之后因为舍友奇怪的错误,我弄了个网上的锐捷客户端3.22-1113,居然也同样不能认证,提示的也是同一个错误"不允许的客户端",要知道我们学校使用的客户端版本号就是3.22-1113(当然程序显然是我们学校专用的),会出这种错,推测可能是学校专用版发送的数据包里有特别的识别信息。所以其他的客户端显然是不行用的。而我也很久没有抓过包了,各种知识也生疏了,要从这方面入手恐怕很困难,于是只能想想别的方法。

  不久,逆转的机会出现了。我在考虑一种假设:linux主机,通过kvm运行windows,在windows中认证,然后linux主机通过这台认证过了的windows虚拟机上网。
  基本原理虽然简单,但是其中可能遇到的问题相当的多,为此,我们需要做黑箱测试(因为我在计算机方面比较喜欢动手而不是纯粹逻辑思考)。为了便于调试,我选择先在windows环境下。


平台:
主机:windows xp sp2
虚拟化软件:VMware 6.5
客户机:windows server 2003 standard
锐捷认证成功后,我的客户机的网络设置是:ip:10.5.27.108 ,mask 255.255.254.0 Gateway:10.5.26.1,DNS:210.XX.XX.XX


  我们第一个要测试的项目是,在虚拟化的环境下是否能在虚拟机中进行锐捷认证。所以我选择了桥接网络模式,结果证实是可以的,我现在的这篇博文就是在虚拟机下远程登录我的另外一台机器写的。因此也证实连接是稳定可靠的。
  确认能够认证了以后,我就开始考虑它的网络模型了,因为我知道在存在多块网卡,或者开启代理服务器的情况下,锐捷认证是会code 4断开的。所以最理想的情况就是在这种桥接模式下。客户机开启路由服务,主机通过客户机连接。
  我查阅了很多资料。开启了windows 2003的路由与远程访问中的路由服务,也确实使用了lan路由功能,查阅了ip路由表,确认了设置是正常的。但是,无论如何,主机都无法连接至客户机之外的任何主机。甚至连真正的网关都ping不通。去年学的ccna的详细知识中关键的部分忘了不少。暂时是没办法搞定这种情况。于是只能先停手,等待下次ccna学好再风云再起。。。
  不过话说回来,这个时候我也在怀疑是否是虚拟机提供的虚拟网络模式不能允许这种连接方法。因此,为了证明虚拟机可以允许我的这种连接的想法,我打算采取不稳定,但是更加容易的一种方法。
  
  传统的虚拟机应用都是主机能够上网,为了让虚拟机上网一般VMware提供的两种方法。一个桥接,一个nat。但是这次因为我们的需求,所以要让它反过来。不过由于VMware设置nat的原理,我们不能用这个,但是,我们可以通过其他的方式实现。
  基本思路是虚拟机再增加一个虚拟网卡,这个网卡作为内部网络的网关。而虚拟机原来的网卡作为连接的真正网卡。
  首先,还是使用桥接。在客户机进行锐捷认证。之后使用Sygate office 4.5来配置代理服务器。不过果然麻烦的是一般的方法还是有问题,查阅了不少资料以后,终于成功了,我使用的方法如下:
  • 先建立一个网卡Microsoft Loopback Adapter,在添加硬件那里就可以添加了。
  • 之后为这个网卡配置一个ip,只需要配置ip地址和子网掩码。我这里的设置是192.168.0.11和255.255.255.0
  • 然后在sygate中配置,选择use Single NIC mode,Gateway IP for internal设置成前前面建立的虚拟网卡的ip地址。Local Area Network Connections 设置成客户机的网卡。
  • 主机的设置把主机的ip指定成和客户机中的虚拟网卡同一个网段,我的设置是192.168.0.111,子网掩码,255.255.255.0,网关和DNS都是那个虚拟网卡的地址也就是我这里的192.168.0.11.
  • 之后,只需要在虚拟机中开启sygate服务,等锐捷认证成功了以后,sygate中的状态显示已经上线了,确定客户机能够正常连接。这个时候主机终于成功的通过客户机连接到网络了。




注意图中的红圈,我这里只要dns能连通就可以上网了。最右边的红圈里面的东西消失是因为这个时候锐捷已经断线了。这也就是这种方法的大问题,锐捷会自动检测代理,这种情况下是会自动掉线的。所以虽然证明了结论但是还是没有可行性的。

好了,这次基本就这些,剩下的下次有机会再测试的时候有了新进展就会更新的。

/*******************************************
*原创文章,转载请注明出处
*******************************************/

2008-08-22

Java的一种图像处理及优化方法

  本来是在研究Graphics的图形处理的,不过找的的资料说的是图像的,但是我们还是可以从中找到方向:
  下面的代码是一个简单的小程序,基本就是两张图片,一大一小,用户可以在大图片上拖动小图片:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
/**
* A pin-the-tail-on-th-donkye demo
* @author ulysess
*/
public class pin extends java.applet.Applet{
  Image frontone,backone;
  int new_x=400;
  int new_y=646;

  public void init(){
    frontone = getImage(getDocumentBase(),"sets.png");
    backone = getImage(getDocumentBase(),"eva.jpg");

    addMouseMotionListener(new MouseMotionListener(){
      public void mouseDragged(MouseEvent e){
        System.out.println("drag");
        new_x=e.getX();
        new_y=e.getY();
        repaint();
      }

      public void mouseMoved(MouseEvent e){}
    } );
  }
  public void paint (Graphics g) {
    g.setColor(Color.black);
    g.drawImage(backone,5, 5, this);
    g.drawImage(frontone, new_x-25, new_y-25, this);
  }

}


  基本上,只需要这些就能够实现效果了,不过可悲的是,拖动图片的时候会闪烁的异常厉害。也就是没有实际使用意义。
  下面讨论下其中的过程:因为applet是一个重量级组件,所以当拖动鼠标时调用的repaint()会调用Component.update(Graphics g)这个方法。
它的实现如下:

public void update(Graphics g){
  g.setColor(getBackground());
  g.fillRect(0,0,width,height);
  g.setColor(getForeground());
  paint(g);
}

  这里可以看出,当使用reapint()时,update重绘整个面板,然后有再次调用了paint(),这样就造成了重复,我们可以重载update方法来消除这个重复,但是结果仍然不好。
  因此我们就需要使用双缓冲或称离屏处理(offscreen imaging)技术来优化显示效果。

双重缓冲:
  基本上,双缓冲就是让程序使用两个graphics对象,绘制时在内存中绘制其中一个作为缓冲用的对象,在绘制完成后再显示到屏幕上,这样能很快的更新图像,显然输出结果比在屏幕上计算结果快的多。而所需要做的只是简单的改动代码(蓝色部分):


import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
/**
* A pin-the-tail-on-th-donkye demo
* @author ulysess
*/
public class pin extends java.applet.Applet{
  Image frontone,backone;
  Image myOffScreenImage;
  Graphics myOffScreenGraphics;
  int new_x=400;
  int new_y=646;

  public void init(){
    frontone = getImage(getDocumentBase(),"sets.png");
    backone = getImage(getDocumentBase(),"eva.jpg");
    myOffScreenImage=createImage(getSize().width,getSize().height);
    myOffScreenGraphics = myOffScreenImage.getGraphics();
    addMouseMotionListener(new MouseMotionListener(){
      public void mouseDragged(MouseEvent e){
        System.out.println("drag");
        new_x=e.getX();
        new_y=e.getY();
        repaint();
      }

      public void mouseMoved(MouseEvent e){}
    } );
  }
  public void paint (Graphics g) {
    g.setColor(Color.black);
    g.drawImage(backone,5, 5, this);
    g.drawImage(frontone, new_x-25, new_y-25, this);
  }
  public void update(Graphics g)
  {
    paint(myOffScreenGraphics);
    g.drawImage(myOffScreenImage,0,0,this);
  }

}

  很显然,只增加了一个用于创建后台图信的image图像对象和一个后台Graphics图形对象,
关键的地方在最后重载的update方法,在repaint时,现绘制myOffScreenGraphics对象,之后再通过g.drawImage把这个对象对应的图像画到屏幕上。仅仅如此处理,结果就让人惊奇了,一点都不会闪烁了。

剪切矩形:
  还有一种方法称为剪切矩形法。主要的原理就是使用一个剪切矩形区域告诉程序,只有这个区域中的内容发生变化,只需要在这个矩形内绘图即可。其他地方不需要改变。
为了演示效果,我们把前面个的双缓冲给去掉。
  当使用setClip(int x,int y,int width,int height)设定了剪切矩形的时候,之后paint处理的范围也就仅仅在这个矩形之内,而不会去刷新矩形外的内容。即使paint的实现中有填充整个窗口的设定。
  下面来看看代码,蓝色部分为剪切矩形的实现,红色部分为处理的改进(全部都是相对于最初的代码的变化):

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
/**
* A pin-the-tail-on-th-donkye demo
* @author ulysess
*/
public class pin extends java.applet.Applet{
  Image frontone,backone;
  int new_x=300,old_x=0;
  int new_y=446,old_y=0;

  public void init(){
    frontone = getImage(getDocumentBase(),"sets.png");
    backone = getImage(getDocumentBase(),"eva.jpg");

    addMouseMotionListener(new MouseMotionListener(){
      public void mouseDragged(MouseEvent e){
        System.out.println("drag");
        new_x=e.getX();
        new_y=e.getY();
        repaint();
      }

      public void mouseMoved(MouseEvent e){}
    } );
  }
  public void paint (Graphics g) {
    g.setColor(Color.black);
    g.drawImage(backone,5, 5, this);
    g.drawImage(frontone, new_x-25, new_y-25, this);
  }
  
  public void update(Graphics g)
  {
    int cut=0;
    g.setClip(new_x-Math.abs(old_x-new_x), new_y-Math.abs(old_y-new_y) ,325+2*Math.abs(old_x-new_x) ,251+2*Math.abs(old_y-new_y));
    old_x=new_x;
    old_y=new_y;
    paint(g);
  }
}

  所以,实际上,要使用剪切矩形只需要重载update方法,在paint之前setClip为需要的矩形区域即可,当时,因为用户移动的速度不一致,所以如果你的矩形设置不好,会产生严重的图形碎块,这个时候怎么办呢?红色的部分就是优化的方法,增加了old_变量,保存上次的点值,根据点的变化来确定矩形的大小。325和251是我这里用的图片的长宽而已。经过这样设置以后,你就会看到实际只有拖动的部分在刷新,而其他部分是没有刷新的。不过拖动的部分还是闪烁的十分厉害,这样,结合前面的双重缓冲就可以让这个程序的效率比之前大大提升了。

  最后,在重载update之后,会发现第一次打开程序的时候,页面背景图是不会显示的,必须最小化再最大化,或者用其他窗口覆盖一下才会出现,这个问题很奇怪,我测试了也还是的不出结论,我们不可能在update里面加一个drawImage加载背景图。因为这样一旦有动作就要加载图片,浪费太多资源。经过最后的测试发现,可能是程序初始化的时候虽然我们没有任何动作,但是程序会自动repaint()两次,只要在这个过程中让update去drawImage背景图片就没有问题了。
  不过个人还是不大喜欢这样。希望以后能在其他教程上找到原因。

/*******************************************
*原创文章,转载请注明出处
*******************************************/

2008-08-21

闲扯云计算

  去年底开始,云计算这个词突然间就火爆起来了,也许和当年IBM的电子商务一样,对未来有巨大的影响吧。当然也可能只是历史的长河中一粒被冲上岸的小石子而已。
  基本上来说,凡是能够聚集到一定的规模就能获得规模效应所带来的最直接的好处——大幅降低成本,提高效率。举个例子,如果你买的多的话,液氮比牛奶便宜。正因如此,才有如此多的巨头争相推出所谓的云计算。先是Amazon,接着出现了DELL,Yahoo,Google等等等等。
  说实话虽然这个词很热门,但是到现在能说清楚它的前因后果,来龙去脉,有效用途,应用前景的人不多。无非就是下几个定义,或者说说它是网格的进化产物,它能提供强大的运算功能,而且好像还有提到Google APP和那个Yahoo BOSS的人。只是始终不见网上有人能把它说清楚的。当然以我目前的水平看,我也不会不自量力妄图去解释这种东西。
  基本上,从目前看起来最好的应用来说,云计算能为我们提供的最具可见性的功能就是把网络服务和硬件架构分离开,从此以后你就不再需要租借机房,买自己的服务器,浪费时间去维护,需要的只是交钱给云计算服务提供商和维护好自己的网络服务即可。这看起来的确相当美妙,只是,这种模式无法克服已有的地域型限制,很多时候用户不仅需要计算能力,还要足够强大的网络带宽与连接能力。而且,从企业级应用来说,多数情况下,他们需要的是一个内部网络的封闭式环境。一是高速,二是规避多数风险。而且。对于某些超牛逼的IT企业来说,也不可能淘汰他们已经花巨资建立的数据中心和机房。
  那么,云计算的定位为何呢?从目前的BOSS和Google APP来看,个人觉得,前者的技术门槛略高,后者只能替代一部分的企业应用。不过由此,我们也最终发现一点。不同于以往的高性能计算,云计算已经找到自己的方向,希望往实用化的商业应用方法发展,不久的将来,如果有一轮新的互联网浪潮的话,它最可能成为那些小小创业者的偏好。这样,从服务器业到整个互联网产业的格局都将产生变化吧。。。
  随性闲扯,未必正确,读者自辨。

2008-08-12

基本的UML类图读法

  虽然我不干软工,但是基本的UML图还是应该要能读懂的。这里推荐一个软件:dia。相当好用,不仅是uml图,各种流程图啦。网络的拓扑图啦都能轻松画出来。
  以下是基本的UML类图的规则。


  在UML类图中,每个类用一个矩形表示,其中由三部分组成:类名,属性和操作比如我这个

  这里可以看到相当多的箭头和两种类视图,由于这个UML图用于表示这几个主要的类之间的关系,所以除了包含main方法的类之外,其他所有类都省略了属性和方法。
  注意PaintBox类,你可以看到void在类名的背后,用一个冒号隔开了,这个就是UML图的规则。至于那个方法名前面的加号表示是public可见性的方法。减号当然也就是private属性的了。至于protect就是一个#号了。
  图中的由一个空心菱形加一条实线组成的有向线段表示的是有空心菱形的一端是个聚合类(就是一种has-a的关系,比如汽车是由很多其他部件聚合而成的,一个聚合对象就是将其他对象的引用作为自己的实例数据的对象),所以这里那个PaintFrame是 DrawPanel,ButtonBar,JMenuBar的聚合类。
  至于那个虚线箭头表示的是类关系,比如图中就显示了PaintBox类使用了PaintFrame类的类方法。
  空心三角形加直线表示继承关系,是从子类指向父类。
  继承关系可以出现多继承和兄弟类,不过由于Java不支持多继承,所以就不贴了。

所有Java GUI程序窗口空白?

你是否遇到这种情况呢?测试了半天程序检查了半天就是没有问题。但是也就是一个空白的窗口。
最后记起来原来连Netbeans也会出现这种问题。
实际上貌似这是在特定情况下导致所有的java的GUI程序都和我们的3d桌面特效程序起了冲突。关了3d桌面特效就正常了。。可是我在家里都没有这个问题。
果然只能归咎于垃圾显卡了。
万恶的垃圾精英主板。以后再也不买这个牌子了。。。

2008-07-20

从上榜CEO看IT业变化

  上个月,《巴伦周刊》公布了它的年度全球CEO30强榜。同时也附带了评选原因,简略的看一看这些去年在全球大放异彩的CEO们我们能够从中看到这些企业的动向。这种体验不同于读到企业最新投资最新产品这样的新闻从小处体验出来的变化,而是往往从战略层面看到他们的掌舵人眼中的方向。
  就IT类和周边行业来说。基本上在这些CEO接手了公司之后都对公司进行了重大的变革,使得公司变得更加灵活,更具创新能力。去年虽然是全球经济相当不好受的一年。但是就IT及周边行业来说,仍然是急速变革,且新产品层出不穷的一年。
  基本上,上榜的几家公司还是可以分成几个类别的:

硬件制造类:

苹果CEO史蒂夫•乔布斯(Steven Jobs)
惠普CEO马克·赫德(Mark Hurd)
思科CEO约翰·钱伯斯(John Chambers)
黑莓联席CEO吉姆·巴尔斯利(Jim Balsillie)和迈克·拉扎里迪斯(Mike Lazaridis)
任天堂CEO岩田聪(Satoru Iwata)
  《巴伦周刊》给出的他们的上榜理由分别是:
乔布斯:依然是天才人物,依然致力于开发绝对的超级产品。
赫德:以创新让技术巨头再创辉煌。
钱伯斯:深水静流
御手洗富士夫:让佳能找到了业务重心
岩田聪:他将视频游戏机推向千家万户。
  自从1997年重返APPLE之后乔布斯又再度发挥出他独特的创造力,大力改革APPLE,90年代末挽救苹果的iMac,本世纪初长盛不衰的摇钱树iPod,还有去年令业界为之震惊的iPhone,以及标示了APPLE野心的Apple TV,这些极致的设计,和让人们疯狂排队购买的产品,除了APPLE还有哪个公司能做得出来呢?
  狂妄与偏执确实是Jobs的特色,但是这也是硅谷成功者们之所以成功而必须的特质。Jobs现在不仅是APPLE的CEO,而且还是崇拜者眼中的神。
  自从1997年重返苹果以后,苹果市值增长了40倍,达到了1,130亿美元。这个有着天生的创新的基因的苹果凭借其天生的灵活性接下来也将越走越好
 
  而马克·赫德也从卡丽·费奥瑞娜(Carly Fiorina)手中接过了一个烂摊子,当时的惠普各项业绩严重衰退,在自己的市场内又受到日本公司的严重威胁。2005年赫德继任以来,他成功的在一年多的时间中让惠普再次坐上PC业务第一的宝座,他通过大刀阔斧的改革大幅度的削减成本,提升利润,并且大胆的进军打印业务,成功的拓展了业务范围。最终再次令惠普如日中天。
  不过,从原来的科技型企业转型成了现在的消费电子企业的惠普,是否能在这个高速竞争低利润的市场持续的增长呢?让我们拭目以待。

  思科的CEO钱伯斯是个具有宽广的胸怀和富有远见的人,在他的领导下,思科这家本来就是一个具有绝对优势的公司,在技术上永远保持这自身领域世界第一的位置。而且其利润率在硬件生产商中高居榜首。通过巧妙的对新技术公司的收购策略,思科必将在此领域作为一颗常青树。与钱伯斯本人不喜欢招摇的风格相比其强硬的手段果然不愧为静水深流这个上榜原因。

  黑莓的两位联席CEO创造了在西方广受欢迎的黑莓手机。彻底的改变了西方人的交流习惯。在这个手机将在一定程度上取代个人电脑在商务应用的时代。又怎么能不赚钱呢?

  这两年任天堂的Wii让任天堂赚的盆满钵满,凭借划时代的创意,以及新用户群体的开发,任天堂重振昔日雄风。

软件服务类:

IBMCEO帕尔米萨诺
阿里巴巴CEO马云
  他们的上榜理由:
帕尔米萨诺:让蓝色巨人闪耀光芒
马云:他挤走了eBay
  帕尔米萨诺在前任手中接下了IBM之后,同样也面临着20世纪IT产业的剧烈变革,IBM要何去何从?他重组IBM的业务,出售PC部门,大举收购,把IBM打造成不折不扣的软件服务业巨头。至今,IBM仍然保持着惊人的高速增长。
  阿里巴巴可以说是中国互联网产业最辉煌的果实,不仅在本土打败了ebay,而且凭借旗下的支付宝和淘宝成功的在中国的C2C市场占有了绝对份额的,它的IPO也是继Google之后最大的,凭借着马云独特的风格与宽广胸怀,阿里巴巴将是未来一段时间内中国互联网行业的指路之星。

  从这些CEO和他们的公司最近的发展不难看出,在这个IT业急速发展的时代。只有能够适应急剧变化的环境,保有自己强大的创新能力才能一直坐稳宝座。
  三点动向:
  • 个人用户的日常应用日趋移动化
  • 硬件制造商的方向必须配合这个趋势
  • 网络化进一步发展必然使得基础设施供应商和服务提供商的竞争日益激烈且日益缩小