2010年1月31日 星期日

linux uart driver 8250.c

uart启动流程,及8250.c分析 收藏
参考:http://linux.chinaunix.net/bbs/viewthread.php?tid=1025844

一.串口初始化流程
在init/main.c start_kernel()-->setup_arch()-->arch_mem_init()-->plat_mem_setup()-->clx_serial_setup()

二.函数分析
函数一:
void __init clx_serial_setup(void)
{
struct uart_port s;
int line = 0;

memset(&s, 0, sizeof(s));

REG8(UART0_FCR) |= UARTFCR_UUE; //设置UFCR.UME=1,使能UART0
REG8(UART1_FCR) |= UARTFCR_UUE; //设置UFCR.UME=1,使能UART1

s.type = PORT_16550A; // 16550A工业标准
s.iotype = UPIO_MEM; // I/o类型是mem
s.regshift = 2; // uart_port.regshift=2
s.fifosize = 1; // uart_port.fifosize=1,传输fifo=1

s.uartclk= clx_clocks.uartclk; // UART时钟
s.flags = STD_COM_FLAGS; //STD_COM_FLAGS=ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,意思是启动时自动配置端口,并且在自动配置期间跳过UART检测

#if !defined(CONFIG_CLX_UART0_REMR)
s.line = line; // line=0,uart0号串口
s.irq = IRQ_UART0; // uart0的irq中断号
s.membase = (unsigned char __iomem *)UART0_BASE; //uart0 的基地址
if (early_serial_setup(&s) != 0) //调用early_serial_setup完成串口0设置,具体看后面函数二
printk(KERN_ERR "Serial ttyS0 setup failed!\n");
line++;
#endif

#if !defined(CONFIG_CLX_UART1_REMR)
s.line = line; // line=1,uart1号串口
s.irq = IRQ_UART1; // uart1的irq中断号
s.membase = (unsigned char __iomem *)UART1_BASE; //uart1 的基地址
if (early_serial_setup(&s) != 0) //调用early_serial_setup完成串口1设置
printk(KERN_ERR "Serial ttyS1 setup failed!\n");
#endif
}

函数二:
int __init early_serial_setup(struct uart_port *port) 路径drivers/serial/8250.c
{
if (port->line >= ARRAY_SIZE(serial8250_ports))
return -ENODEV; //如果对应的串口号没在数组列表中,则表示没有该设备,返回ENODEV

serial8250_isa_init_ports(); //该函数的作用是完成对应端口的初始化工作,具体分析看后面函数三
serial8250_ports[port->line].port = *port; //也就是serial8250_port[端口号]=传递过来参数的指针
serial8250_ports[port->line].port.ops = &serial8250_pops; //对应端口的操作
return 0;
}

函数三:
static void __init serial8250_isa_init_ports(void)
{
struct uart_8250_port *up;
static int first = 1;
int i;

if (!first)
return;
first = 0;
//初始化nr_uarts个串口 结构体的port.line,time定时器
for (i = 0; i < nr_uarts; i++) { //这里nr_uarts 是配置的4个
struct uart_8250_port *up = &serial8250_ports[i];

up->port.line = i;
spin_lock_init(&up->port.lock);

init_timer(&up->timer);
up->timer.function = serial8250_timeout;

/*
* ALPHA_KLUDGE_MCR needs to be killed.
*/
up->mcr_mask = ~ALPHA_KLUDGE_MCR; // 用户位mask
up->mcr_force = ALPHA_KLUDGE_MCR; // forced位mask

up->port.ops = &serial8250_pops; //port.ops设置
}
//port端口的初始化,在后面这些值会被覆盖,serial8250_ports[port->line].port= *port;
for (i = 0, up = serial8250_ports;
i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
i++, up++) {
up->port.iobase = old_serial_port[i].port;
up->port.irq = irq_canonicalize(old_serial_port[i].irq);
up->port.uartclk = old_serial_port[i].baud_base * 16;
up->port.flags = old_serial_port[i].flags;
up->port.hub6 = old_serial_port[i].hub6;
up->port.membase = old_serial_port[i].iomem_base;
up->port.iotype = old_serial_port[i].io_type;
up->port.regshift = old_serial_port[i].iomem_reg_shift;
if (share_irqs)
up->port.flags |= UPF_SHARE_IRQ;
}
}

三.8250.c uart驱动分析

1.初始化分析
static int __init serial8250_init(void)
{
int ret, i;

if (nr_uarts > UART_NR)
nr_uarts = UART_NR;

//输出有几个串口,默认值是32,是否采用共享中断;这里串口有4个,没有使用串口中断
printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
"%d ports, IRQ sharing %sabled\n", nr_uarts,
share_irqs ? "en" : "dis");

for (i = 0; i < NR_IRQS; i++)
spin_lock_init(&irq_lists[i].lock); //加锁

ret = uart_register_driver(&serial8250_reg); //注册uart串口驱动
if (ret)
goto out;

//创建一个platform_device结构:serial8250_isa_devs
serial8250_isa_devs = platform_device_alloc("serial8250",
PLAT8250_DEV_LEGACY);

if (!serial8250_isa_devs) {
ret = -ENOMEM;
goto unreg_uart_drv;
}
//将该结构serial8250_isa_devs注册到总线上
ret = platform_device_add(serial8250_isa_devs);
if (ret)
goto put_dev;
//添加端口,具体分析见后面函数一
serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);


//platform driver驱动注册
ret = platform_driver_register(&serial8250_isa_driver); //serial8250_isa_driver该结构体详见后面结构体一
if (ret == 0)
goto out;

platform_device_del(serial8250_isa_devs);
put_dev:
platform_device_put(serial8250_isa_devs);
unreg_uart_drv:
uart_unregister_driver(&serial8250_reg);
out:
return ret;
}


函数一:


static void __init
serial8250_register_ports(struct uart_driver *drv, struct device *dev) //两个参数,第一个表示被注册的uart_driver结构体,第二个参数device
{
int i;

serial8250_isa_init_ports(); //该函数二中函数函数三也分析

//添加nr_uarts=4个端口
for (i = 0; i < nr_uarts; i++) {

//serial8250_ports[i]对应的值在前面二中函数二early_serial_setup() ,以被赋了相应值
struct uart_8250_port *up = &serial8250_ports[i];

up->port.dev = dev;
uart_add_one_port(drv, &up->port); //添加端口函数
}
}

结构体一:
static struct platform_driver serial8250_isa_driver = {
.probe = serial8250_probe, //详见后面函数二分析
.remove = __devexit_p(serial8250_remove),
.suspend = serial8250_suspend,
.resume = serial8250_resume,
.driver = {
.name = "serial8250",
.owner = THIS_MODULE,
},
};
经过前面有关platform的分析我们知道.这个platform的name为” serial8250”.刚好跟前面注册的platform_device相匹配.会调用platform_driver-> probe.

函数二:
static int __devinit serial8250_probe(struct platform_device *dev)
{
struct plat_serial8250_port *p = dev->dev.platform_data;
struct uart_port port;
int ret, i;

memset(&port, 0, sizeof(struct uart_port));

for (i = 0; p && p->flags != 0; p++, i++) {
port.iobase = p->iobase;
port.membase = p->membase;
port.irq = p->irq;
port.uartclk = p->uartclk;
port.regshift = p->regshift;
port.iotype = p->iotype;
port.flags = p->flags;
port.mapbase = p->mapbase;
port.hub6 = p->hub6;
port.dev = &dev->dev;
if (share_irqs)
port.flags |= UPF_SHARE_IRQ;
ret = serial8250_register_port(&port);
if (ret < 0) {
dev_err(&dev->dev, "unable to register port at index %d "
"(IO%lx MEM%lx IRQ%d): %d\n", i,
p->iobase, p->mapbase, p->irq, ret);
}
}
return 0;
}
从上述代码可以看出.会将dev->dev.platform_data所代表的port添加到uart_driver中.这个dev->dev.platform_data究竟代表什么.我们在看到的时候再来研究它.
后面的解释是这样的 经过这个 config_port过程后,我们发现,并没有对serial8250_isa_devs->dev-> platform_data赋值,也就是说platform_driver->probe函数并无实质性的处理.在第一次for循环的时,就会因条件不符而退出.

2.现在,我们把精力集中到uart_port的操作上.

函数一:
serial8250_register_ports()-->uart_add_one_port()-->uart_configure_port()-->port->ops->config_port()-->serial8250_config_port()

static void serial8250_config_port(struct uart_port *port, int flags)
{
//参数一:对应的端口信息,
参数二:flags=UART_CONFIG_TYPE

struct uart_8250_port *up = (struct uart_8250_port *)port;
int probeflags = PROBE_ANY;
int ret;

/*
* Find the region that we can probe for. This in turn
* tells us whether we can probe for the type of port.
*/
ret = serial8250_request_std_resource(up);
if (ret < 0)
return;

ret = serial8250_request_rsa_resource(up);
if (ret < 0)
probeflags &= ~PROBE_RSA;

if (flags & UART_CONFIG_TYPE)
autoconfig(up, probeflags); //这个函数会调用
if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
autoconfig_irq(up);

if (up->port.type != PORT_RSA && probeflags & PROBE_RSA)
serial8250_release_rsa_resource(up);
if (up->port.type == PORT_UNKNOWN)
serial8250_release_std_resource(up);
}
serial8250_request_std_resource 和serial8250_request_rsa_resource都是分配操作的端口.
自己阅读这两个函数代表.会发现在serial8250_request_rsa_resource()中是会返回失败的.
另外,在uart_add_one_port()在进行端口匹配时,会先置flags为UART_CONFIG_TYPE.
这样,在本次操作中, if (flags & UART_CONFIG_TYPE)是会满足的.相应的就会进入autoconfig().

在autoconfig中又会调用autoconfig_16550a(up);

其他的可以不去管。
经过这个 config_port过程后,我们发现,并没有对serial8250_isa_devs->dev-> platform_data赋值,也就是说platform_driver->probe函数并无实质性的处理.在第一次for循环的时,就会因条件不符而退出.

3.startup 分析
在前面分析uart驱动架构的时候,曾说过,在open的时候,会调用port->startup().在本次分析的驱动中,对应接口为serial8250_startup().
分段分析如下:
static int serial8250_startup(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
unsigned long flags;
unsigned char lsr, iir;
int retval;

//从结构体uart_config中取得相应的配置
up->capabilities = uart_config[up->port.type].flags;
up->mcr = 0;

if (up->port.type == PORT_16C950) { //这里我们没有调用
……………………
}

#ifdef CONFIG_SERIAL_8250_RSA
/*
* If this is an RSA port, see if we can kick it up to the
* higher speed clock.
enable_rsa(up);
#endif

/*
* Clear the FIFO buffers and disable them.
* (they will be reenabled in set_termios())
*/
//清楚FIFO buffers并 disable 他们,但会在以后set_termios()函数中,重新使能他们
serial8250_clear_fifos(up);

/*
* Clear the interrupt registers.
*/
复位LSR,RX,IIR,MSR寄存器
(void) serial_inp(up, UART_LSR);
(void) serial_inp(up, UART_RX);
(void) serial_inp(up, UART_IIR);
(void) serial_inp(up, UART_MSR);

/*
* At this point, there's no way the LSR could still be 0xff;
* if it is, then bail out, because there's likely no UART
* here.
*/
//若LSR寄存器中的值为0xFF.异常
if (!(up->port.flags & UPF_BUGGY_UART) &&
(serial_inp(up, UART_LSR) == 0xff)) {
printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
return -ENODEV;
}
/*
* For a XR16C850, we need to set the trigger levels
*/
//16850系列芯片的处理,忽略
if (up->port.type == PORT_16850) {
………………………………………………
}

if (is_real_interrupt(up->port.irq)) {
/*
* Test for UARTs that do not reassert THRE when the
* transmitter is idle and the interrupt has already
* been cleared. Real 16550s should always reassert
* this interrupt whenever the transmitter is idle and
* the interrupt is enabled. Delays are necessary to
* allow register changes to become visible.
*/
spin_lock_irqsave(&up->port.lock, flags);

wait_for_xmitr(up, UART_LSR_THRE);
serial_out_sync(up, UART_IER, UART_IER_THRI);
udelay(1); /* allow THRE to set */
serial_in(up, UART_IIR);
serial_out(up, UART_IER, 0);
serial_out_sync(up, UART_IER, UART_IER_THRI);
udelay(1); /* allow a working UART time to re-assert THRE */
iir = serial_in(up, UART_IIR);
serial_out(up, UART_IER, 0);

spin_unlock_irqrestore(&up->port.lock, flags);

/*
* If the interrupt is not reasserted, setup a timer to
* kick the UART on a regular basis.
*/
if (iir & UART_IIR_NO_INT) {
pr_debug("ttyS%d - using backup timer\n", port->line);
up->timer.function = serial8250_backup_timeout;
up->timer.data = (unsigned long)up;
mod_timer(&up->timer, jiffies +
poll_timeout(up->port.timeout) + HZ/5);
}
}
如果中断号有效,还要进一步判断这个中断号是否有效.具体操作为,先等待8250发送寄存器空.然后允许发送中断空的中断.然后判断IIR寄存器是否收到中断.如果有没有收到中断,则说明这根中断线无效.只能采用轮询的方式.关于轮询方式,我们在之后再以独立章节的形式给出分析
/*
* If the "interrupt" for this port doesn't correspond with any
* hardware interrupt, we use a timer-based system. The original
* driver used to do this with IRQ0.
*/
if (!is_real_interrupt(up->port.irq)) {
up->timer.data = (unsigned long)up;
mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
} else {
retval = serial_link_irq_chain(up);
if (retval)
return retval;
}
如果没有设置中断号,则采用轮询方式;如果中断后有效.流程转入serial_link_irq_chain().在这个里面.会注册中断处理函数
/*
* Now, initialize the UART
*/
serial_outp(up, UART_LCR, UART_LCR_WLEN8); //ULCR.WLS=11,即选择8位

spin_lock_irqsave(&up->port.lock, flags);
if (up->port.flags & UPF_FOURPORT) {
if (!is_real_interrupt(up->port.irq))
up->port.mctrl |= TIOCM_OUT1;
} else
/*
* Most PC uarts need OUT2 raised to enable interrupts.
*/
if (is_real_interrupt(up->port.irq))
up->port.mctrl |= TIOCM_OUT2;

serial8250_set_mctrl(&up->port, up->port.mctrl);

/*
* Do a quick test to see if we receive an
* interrupt when we enable the TX irq.
*/
serial_outp(up, UART_IER, UART_IER_THRI);
lsr = serial_in(up, UART_LSR);
iir = serial_in(up, UART_IIR);
serial_outp(up, UART_IER, 0);

if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
if (!(up->bugs & UART_BUG_TXEN)) {
up->bugs |= UART_BUG_TXEN;
pr_debug("ttyS%d - enabling bad tx status workarounds\n",
port->line);
}
} else {
up->bugs &= ~UART_BUG_TXEN;
}

spin_unlock_irqrestore(&up->port.lock, flags);

/*
* Finally, enable interrupts. Note: Modem status interrupts
* are set via set_termios(), which will be occurring imminently
* anyway, so we don't enable them here.
*/
up->ier = UART_IER_RLSI | UART_IER_RDI;
serial_outp(up, UART_IER, up->ier);

if (up->port.flags & UPF_FOURPORT) {
unsigned int icp;
/*
* Enable interrupts on the AST Fourport board
*/
icp = (up->port.iobase & 0xfe0) | 0x01f;
outb_p(0x80, icp);
(void) inb_p(icp);
}

/*
* And clear the interrupt registers again for luck.
*/
(void) serial_inp(up, UART_LSR);
(void) serial_inp(up, UART_RX);
(void) serial_inp(up, UART_IIR);
(void) serial_inp(up, UART_MSR);

return 0;
}


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yinkaizhong/archive/2008/12/20/3564401.aspx

Video Streaming with the Android Phone

Video Streaming with the Android Phone
This page describes how to stream video to the Google Developer Phone. This topic is a very interesting, but also quite complex one, and it took me a while to figure all variables out in a proper way.

If you follow this walkthrough you should be able to install a video streaming server, adapt any of your video content and stream the result to your Android Phone. It also contains encoding settings that you might find useful to encode your videos to watch them (locally)on the G-Phone.
Hope this is useful to someone out there.

Table of Contents
1. Video Streaming with the Google Phone
1. Setting up a Streaming Media Server
1. Installing Perl
2. Installing Darwin Streaming Server
1. Installation on Windows
2. Installation on Ubuntu Linux
3. Administrator Console
1. Starting
2. Stopping
4. Administering Darwin Streaming Server
5. Media Repository
6. Firewalls and Darwin Streaming Server
2. Creating Streaming Media for the Google Developer Phone
1. Encoding a Movie
1. Getting the Right Dimensions
2. Hinting the Result
3. Deploying the Media
4. Testing the Streaming
Video Streaming with the Google Phone
Android comes with the ability to play back video and audio that is stored locally on the device. More important though, Android is also able to receive streaming media such as video and audio with its Media Player API. In this tutorial we show what you need to
• set up a streaming media server
• create streaming media compatible with the Google Phone's available codecs
• Receive the streaming media on the phone
Setting up a Streaming Media Server
There are a variety of Streaming Media Servers out there, but the one that we think is the easiest to use is Apple's Darwin Streaming Server (DSS). Darwin Streaming Server is Open Source and its commercial brother is Apple's Quicktime Streaming Server (QSS). Darwin can be downloaded from here: http://dss.macosforge.org/. You can click on the previous releases link (http://dss.macosforge.org/post/previous-releases/) if you want to get a binary version and not go to the hassle of building Darwin Yourself. In this Tutorial we used DSS v5.5.
Installing Perl
Once you downloaded Darwin you need to install it on your machine. This requires that you have Perl installed. A working version of Perl (for Windows) can be found on the Strawberry Perl site: http://strawberryperl.com/. Download the Strawberry Perl and install it. Once you have it installed, open a command line and type the following command:
> perl -MCPAN -e shell

The CPAN shell opens and there you type:
CPAN> install Win32::Process

This will make Perl go to the Perl package network (the CPAN to be precise) and download the Win32::Process package needed by Darwin. If the downloading has succeeded, you can go on to installing Darwin Streaming Server.
Installing Darwin Streaming Server
Installation on Windows
Unpack the downloaded Darwin to a local folder and execute install.bat. If you are running the install.bat under Windows Vista, make sure you run it in administrator mode. You can do that by right-clicking on the file and select Start as Administrator from the context menu or you can start a command line shell in admin mode by doing the following:
1. Press the Start button in your task bar
2. type 'cmd' in the search bar
3. press Shift+Ctrl+Enter
This will start the console in administrator mode. You can then browse to the folder containing install.bat and execute it from command line.
Installation on Ubuntu Linux
Installation on Ubuntu Linux is straight-forward. All you need to do is download the tar.gz file with the binaries (for this tutorial we used Darwin 5.5.5 with the binaries given here: http://dss.macosforge.org/downloads/DarwinStreamingSrvr5.5.5-Linux.tar.gz) to your Linux machine, unzip and untar it e.g. like this:
$> gunzip DarwinStreamingSrvr5.5.5-Linux.tar.gz
$> tar xf DarwinStreamingSrvr5.5.5-Linux.tar

The result is an untared folder, which contains several executable scripts, one of them being called Install. Before you can execute Install you need to modify the script a bit. Open the script (e.g. with vim) and search for the following part:
useradd -M qtss

Once you have found it, replace it by
useradd -m qtss

Note the lowercase -m option. Safe the file and then from the shell execute
$> ./Install

You might have to be root to be allowed to do that.
Administrator Console
If the installation of Darwin is successful, you will be prompted for entering a user name and a password. Those are used by the Administrator Console of Darwin and need to be remembered well.
Starting
The admin console is started right after installation, so if you close the installation window, it will be terminated. To start it again, open a command shell, browse to the installation folder of Darwin (on Windows this is C:\Program Files\Darwin Streaming Server) and type
C:\Program Files\Darwin Streaming Server> perl streamingadminserver.pl

This will start the admin console server and you can access it from your browser under http://localhost:1220.
Stopping
To stop the admin console simply terminate the Perl script. Note: Terminating the admin server console does not terminate the streaming server. Darwin is installed as a Windows service and as such can only be stopped via the Windows Services view (right-click on My Computer-->Manage-->Services and Applications-->Services).
Administering Darwin Streaming Server
Via the admin console server you can administer Darwin. The first time you will access the console, you will be asked to enter an MP3 administrator's password. You will be asked for that password whenever you want to upload a new MP3 to Darwin, so remember it well. The admin console is pretty self-explanatory, so take a look around and see what you can do.
Media Repository
Whatever media you want to stream with Darwin has to be placed inside the Movies folder of your Darwin installation. On Windows, that is C:\Program Files\Darwin Streaming Server\Movies. See the description on Media Creation below, to see what pre-requisites your media has to fulfil.
Firewalls and Darwin Streaming Server
Darwin is an RTSP server and by default uses the regular RTSP port 554 for RTSP both over TCP and UDP. That port may be blocked by the firewall you installed Darwin on. To make sure the ports are open, you need to open those ports in your firewall. If you don't know how to do it, ask your friendly administrator.

Important: If you fail to have the proper ports open, you will not receive any streaming on the phone.

Note: In the admin console server, you can choose to enable streaming over port 80, which means that RTSP requests will be tunnelled through port 80 which is usually open in firewalls. For RTSP requests from the phone / external client to your Darwin Streaming Server machine, this means that you have to use an RTSP URL including the port to use, e.g. rtsp://yourserver:80/moviename.mp4.
Creating Streaming Media for the Google Developer Phone
Creating streaming media depends on two things:
1. the streaming server you are using
2. the capabilities of the client, i.e. the phone
In our case, we have decided for the Darwin Streaming Server as streaming server solution and the Android Dev Phone 1 as the client.

Both the capabilities of the server and the phone are important as they decide which media formats will work and which wont.

Darwin Streaming Server supports a variety of containers, among them .3gp, .mp4 and .mov. It is more or less agnostic to the codecs used to encode the media but needs to be hinted how to stream a media file. The Dev Phone on the other hand has specifications that indicate which container types and codecs are supported for which media. A list of specifications can be found here http://developer.android.com/guide/appendix/media-formats.html.
Essentially this page explains that Android currently supports the following Video Formats:


Codec
Encoder
Decoder
Container Format




H.263
yes
yes
3GPP (.3gp) and MPEG-4 (.mp4)




H.264 AVC
no
yes
3GPP (.3gp) and MPEG-4 (.mp4)




MPEG-4 SP
no
yes
3GPP (.3gp)





This limits our choice of codecs to H.263, H.264 and MPEG-4 Simple Profile. However, even if you know this it is difficult enough to create properly encoded videos that also show up in a suitable quality on the phone. In the next section we will give an overview of settings and tools that can be used to create suitable media.
Encoding a Movie
To make a movie suitable for playback and / or streaming on the phone, we need to encode it with the right codecs, and place the encoded movie into the right container format.
A tool that is invaluable for that task is SUPER which you can download from here: http://erightsoft.podzone.net/GetFile.php?SUPERsetup.exe

Once installed, the tool lets you add Media files to a list of files to encode and then specify the encoding settings for the resulting media file. To add a media file for encoding, right-click in the lower part of the SUPER window and select Add Multimedia File(s).
Browse to a folder with the movie you want to stream to the phone and select it. Now it is time to tune the settings to get the properly encoded result. A very good list of settings can be found here: http://androidcommunity.com/forums/vbglossar.php?do=showentry&catid=2&id=28

I copied the contents here, just in case the link will disappear one day:

Codecs:

MP4 H.264 AAC LC


Video:

480:270 3:2 23.976 480kbps (yes, you set the video to 480x270)


Audio:

44100 2 96kbps Default


Options:

Hi Quality:OFF Top Quality:OFF


Pad:

Top:24 Bottom:26 Left:0 Right:0


Crop:

Top:0 Bottom:0 Left:Calc Right:Calc


While everything else stays the same from movie to movie, the Calc options above need to be calculated depending on the resolution of the video source.
I'll quickly give the calculation and then give an example.

The calculation is ( Width - ( Height * 16 / 9 ) ) / 2. Width and Height are of the source video and the result would be what you would select for the left and right crop. Here's a couple examples from DVD rips: * 886x480 source video: ( 886 - ( 480 * 16 / 9 ) ) / 2 = 16 (set the left and right crop to 16) * 1128x480 source video: ( 1128 - ( 480 * 16 / 9 ) ) / 2 = 137 (set the left crop to 136 and the right crop to 138) * 852x480 source video: ( 852 - ( 480 * 16 / 9 ) ) / 2 = -0.7 (this movie is already 16x9 so you can turn Crop OFF).
After you have made the settings, click the Encode (Active Files) button. This will create a video output encoded with the settings you specified. You can verify the quality, with VLC player for example.

Important Note: The settings above may be too much for streaming to the phone. It could be noticed that there is considerable packet loss on the device, probably due to buffer overflows on the device's video player. The settings above are better for local playback on the phone. For streaming use the following settings for a movie in 16:9 format:

Codecs:

MP4 H.264 AAC LC




Video:

256:144 3:2 23.976 480kbps




Audio:

44100 2 96kbps Default




Options:

Hi Quality:OFF Top Quality:OFF




Pad:

Top:12 Bottom:14 Left:0 Right:0




Crop:

off



As you can see the video size has been reduced to roughly half the size of the settings above. This reduces the bandwidth considerably. If you still experience packet loss you can further reduce the width and height. But pay attention since the dimensions (at least the width) have to be a multiple of 16, i.e. width modulo 16 must yield 0. Otherwise Super will fail to encode. This is not a bug, but a constraint of the codec / container format.
Getting the Right Dimensions
When you change the size of the video, the following things need to be considered:
1. display size of the phone
2. aspect ratio of the original video
3. aspect ratio of the phone's display
4. encoder constraints
The Android phone's display size is 480x320 which yields an aspect ratio of 3:2(= 480:320). So 3:2 is the aspect ratio we want the encoded video to be at finally (like this the phone's player does not have to do expensive rescaling).

Let's now assume we have a video of size 1024x576 which has an aspect ratio of 16:9 (= 1024:576). To get that movie on a 3:2 screen, we can either stretch / shrink it - adding unwanted distortion to the movie - or add padding to the movie. Let's further assume we want to end up with a movie that has a width of 256. For it to still be in 16:9, we need to set the height to 144, which is 256 / 16 * 9.

We will then end up with a movie of size 256x144. The problem is, that this is 16:9 and we want 3:2 so that the player on the phone does not have to do rescaling. If our movie width is 256 and the movie were in 3:2, then the height of the movie would have to be 170 (= 256 / 3 * 2).

However, it is only 144 since we don't want to distort the movie. So the solution is to pad the remaining height with black pixels (the black stripes you know from TV) so that we reach the 3:2 height. Thus we need to pad 26 (= 170 - 144) pixels, and we do that by padding 12 on the top and 14 on the bottom (12 + 14 = 26). The 2 pixel difference is not visible.

After encoding, we end up with a movie that is actually 3:2 with size 256x170 but "contains" the downsized original in 16:9 format. If you understood that you can reproduce it with any size and aspect ratio you like.

Note: keep in mind the restrictions of the codec. Width % 16 must be 0.
Hinting the Result
After having created the properly encoded video file, we are only one step away from streaming it to the phone. In order to be able to do so, Darwin Streaming Server needs to get hints how to stream media it is not able to decode.

As mentioned above, Darwin is agnostic to the codec used by the file that is streamed which makes it easier to support new codec types as they are being created. In order to stream the encoded media properly, however, Darwin needs to process hints which are a separate track inside the media file's container. Without those hints, Darwin will not be able to stream your media - whether properly encoded or not.

To create a hinted media file, you need a program called MP4Box, which you can download binary versions of from here:

http://www.tkn.tu-berlin.de/research/evalvid/

Windows: http://www.tkn.tu-berlin.de/research/evalvid/EvalVid/mp4box-w32.zip
Linux: http://www.tkn.tu-berlin.de/research/evalvid/EvalVid/mp4box-lin.tar.bz2
Mac: http://www.tkn.tu-berlin.de/research/evalvid/EvalVid/mp4box-mac.tar.bz2

Once downloaded you can add it to your system's PATH or simply put it into the same folder as the media file you want to add hints to. To hint the movie we have created in the encoding step, open a command line shell, browse to the folder containing the encoded video and the MP4Box executable then run
mp4box -hint .mp4

When the program terminates successfully, our encoded media file is hinted and ready for deployment to Darwin.
Deploying the Media
To make our video available for streaming, all we need to do is copy the file to Darwin's Movies folder, under Windows this is C:\Program Files\Darwin Streaming Server\Movies.
Testing the Streaming
To test if streaming of your new file is working, you can use VLC player. Start VLC player and select File-->Open Network Stream. In the dialog enter RTSP as the protocol and the url rtsp://localhost/.mp4 and press OK.
The video should start playing back.

Important: Depending on the Version of VLC you either have to type the full RTSP URL or only the URL omitting the protocol prefix, i.e. localhost/movie.mp4 instead of rtsp://localhost/movie.mp4.

If testing with VLC worked fine, you should be able to access the video from the Media Player on the Android Phone as well. The easiest way to do that is to create a Web page with a link to the RTSP URL of the movie you are streaming, i.e. somehting like this:

rtsp://yourserver/yourmediafile.mp4

You can then access this page from your Android Phone’s browser and click on the link. This will start the internal Android Media Player and playback the video.

Of course, you can also create your own Media Player as shown in the Android Sample Applications or download one from the Android Market.

Happy streaming…

2010年1月30日 星期六

2010年1月29日 星期五

wifi phy layer

RFID

RFID totourial

http://www.idautomation.com/rfid_faq.html

2010年1月28日 星期四

The script of Desperate Housewives

The script of Desperate Housewives
Season 1 第一季
第一集:(下半集)

CUT TO: [INT. VAN DE KAMP HOUSE - DINING ROOM -- DINNER --- NIGHT]
(The VAN DE KAMP family is seated, eating silently.)
DANIELLE: Why can't we ever have normal soup?
BREE: Danielle, there is nothing abnormal about basil puree.
DANIELLE: Just once, can we have a soup that people have heard of? Like, french onion or navy bean.
BREE: First of all, your father can't eat onions, he's deadly allergic. (REX glances at BREE sullenly.) And I won't even dignify your navy bean suggestion. So. How's the osso bucco?
ANDREW: It's OK. (BREE stares at him.)
BREE: It's OK? Andrew, I spent 3 hours cooking this meal. How do you think it makes me feel when you say it's OK, in that sullen tone?
ANDREW: Who asked you to spend 3 hours on dinner? (REX stops chewing, looks at ANDREW. DANIELLE looks at BREE.)
BREE: Excuse me?
ANDREW: (REX looks back at his plate) Tim Harper's mom gets home from work, pops open a can of pork and beans, and boom, they're eating, everyone's happy.
BREE: You'd rather I serve pork and beans?
DANIELLE: Apologize now, I am begging.
ANDREW: I'm just saying, do you always have to serve cuisine? Can't we ever just have food?
BREE: Are you doing drugs?
ANDREW: What!?
BREE: (angry) Change in behaviour is one of the warning signs, and you have been as fresh as paint for the last 6 months. (looks down) That certainly would explain why you're always locked in the bathroom.
DANIELLE: (grinning) Trust me, that is not what he is doing.
ANDREW: (to DANIELLE) (sot to) Shut up. (REX looks embarrassed. BREE glances at REX, then back at ANDREW incredulously) Mom, I'm not the one with the problem here, alright? You're the one always acting like she's running for mayor of Stepford.
BREE: (looks at REX) Rex. Seeing as you're the head of this household, I would really appreciate you saying something.
REX: (beat) Pass the salt?
(DANIELLE passes the salt to REX. ANDREW, DANIELLE and REX continue their meal as BREE looks at REX, stunned.)

本段词汇与句法:
(1) basil puree 用basil做的蔬菜泥。Basil是西式菜谱里面常用到的一种香叶,也即是大统华里面卖的九层塔。
(2) navy bean 菜豆
(3) sullenly 面色愠怒地,不高兴地
(4) And I won’t even dignify your navy bean suggestion. 大意是:我不觉得你说得菜豆能做出精致的菜。 Dignify 是显得高贵的意思。
(5) osso bucco 意大利经典菜式,中文一般称做:米兰炖牛膝。这道菜最重要的部分,是炖牛膝完成后在菜上门撒的香料,该香料被称为 Gremolata, 是由大蒜,意大利香菜和柠檬皮制成, 看这道菜是否正宗,就看该香料是否做得好。由此可见,Bree还真是孜孜不倦追求高雅精致的菜式。
(6) incredulously 不相信地


CUT TO: [INT. SUPERMARKET --- DAY]
NARRATOR: Three days after my funeral, Lynette replaced her grief with a much more useful emotion - indignation.
(A frazzled LYNETTE is at the crowded supermarket with her children. The baby is sitting in the cart, as, unseen by LYNETTE, the twins sneak off, pushing the other cart into another aisle as LYNETTE talks on the phone.)
LYNETTE: (on the phone) Tom, this is my 5th message and you still haven't called me back. Well, you must be having a lot of fun on your business trip. I can only imagine. Well, guess what, the kids and I wanna have some fun too, so unless you call me back by noon, we are getting on a plane and joining you.
PRESTON: Mom!
LYNETTE: (glances at PRESTON) Not now, honey, Mommy's threatening Daddy.
PRESTON: Mom!
LYNETTE: (turns around as she throws a bottle in the cart.) No, I am not... (She trails off, noticing the twins are gone) Where're your brothers?
(Cut to:PARKER pushing PORTER on the shopping cart in another aisle, putting random items from the shelf in the cart.)
PORTER: Noodles, my favourite!
(Cut to:LYNETTE, followed by PRESTON, pushes the cart out of the aisle, looking around, trying to find the twins. A SHOPPER looks up to see LYNETTE coming towards her.)
SHOPPER: Lynette Scavo?
LYNETTE: (sot to) Crap. (looks up, smiling widely) Natalie Klein, I don't believe it!
SHOPPER: Lynette! How long has it been?
LYNETTE:Years! Uh, how are you, how's the firm?
SHOPPER: Good, everyone misses you.
LYNETTE: Yeah.
SHOPPER: We all say, if you hadn't quit, you'd be running the place by now.
LYNETTE: Yeah, well. (smiles, looking down)
SHOPPER: So?how's domestic life? Don't you just love being a mom?
NARRATOR: And there it was - the question that Lynette always dreaded.
LYNETTE: (hesitant) Well, to be honest...
NARRATOR: To those who asked it, only one answer was acceptable. So, Lynette responded as she always did - she lied.
LYNETTE: It's the best job I've ever had. (smiling widely)
(Pan to:A cart comes out of an aisle behind LYNETTE and bumps into an elderly lady, who gasps and falls over. A man hurries to help her up. Sounds of glass breaking are heard as the twins are loudly fascinated by the commotion they're caused. LYNETTE closes her eyes, sighing.)

本段词汇与句法:
(1) frazzled 穿得破破烂烂的
(2) sneak off 偷偷跑开
(3) trail off 说话声音越来越弱
(4) dread 害怕,恐惧
(5) commotion 骚动 暴乱


CUT TO: [INT. SOLIS HOUSE - BEDROOM --- DAY (LATER)]
(A schoolbus is seen through the open balcony door, driving along the road. GABRIELLE laughs softly offscreen. The camera pans back as we see GABRIELLE and JOHN naked in bed, covered with sheets. She leans across his body and lights up a cigarette.
JOHN: You know what I don't get?
GABRIELLE: What?
JOHN: Why you married Mr. Solis.
(GABRIELLE raises her eyebrows, blows out a mouthful of smoke and leans on JOHN, stroking his chest.)
GABRIELLE: Well, he promised to give me everything I've ever wanted.
JOHN: Well, did he?
GABRIELLE: Yes.
JOHN: Then... why aren't you happy? (GABRIELLE takes a drag of her cigarette)
GABRIELLE: Turns out I wanted all the wrong things.
JOHN: So. Do you love him?
GABRIELLE: I do. (sighs)
JOHN: Well, then, why are we here? Why are we doing this?
GABRIELLE: Because I don't wanna wake up some morning with a sudden urge to blow my brains out. (kisses JOHN, then takes another drag of her cigarette)
JOHN: Hey, can I have a drag?
GABRIELLE: Absolutely not. You are much too young to smoke. (kisses JOHN again)
CUT TO: [INT. MEYER HOUSE - KITCHEN --- NIGHT]
(SUSAN is fixing her hair in the mirror, nervous. JULIE is sitting at the kitchen table, doing a school project of making a model of the Trojan Horse out of popsicle sticks.)
SUSAN: (exhales loudly) How would you feel about me using your child support payments for plastic surgery?
JULIE: Stop being so nervous, you're just asking him out to dinner. It's no big deal.
SUSAN: You're right. (stalling) So, is that your project for school? You know in 5th grade I made the white house out of sugar cubes.
JULIE: Stop stalling and go. Before Mike figures out he can do better.
SUSAN: (gapes at JULIE) Tell me again why I fought for custody of you?
JULIE: You were using me to hurt Dad.
SUSAN: Oh, that're right.
(SUSAN kisses JULIE's hair, then opens the kitchen back door to walk outside.)
SUSAN: Oh god.
(JULIE smiles, looking back down at her project)

本段的词汇与句法:
(1) You know what I don't get? 你知道我什么事情不明白吗?
(2) Urge 冲动
(3) Popsicle 冰棒
(4) Gape 张嘴


(Cut to:EXT. MIKE- PORCH - NIGHT SUSAN walks up the steps and rings MIKE's doorbell. He opens the front door.)
SUSAN: (smiles) Hi.
MIKE: Hey, Susan.
SUSAN: Are you busy?
MIKE: No, not at all, what's up?
SUSAN: Well, I., I just was wondering, if, um, if there was any chance that, um, you would uh... (nervous laughter) I just... wanted to ask if...
(EDIE appears at the door beside MIKE, holding a bottle of beer.)
SUSAN: (sees EDIE, surprised) Edie. What are you...?
EDIE: I was making ambrosia, and I made too much so I thought I'd bring some over to Mike. What's going on?
MIKE: Uh, Susan was just about to ask me something.
SUSAN: Uh... (beat) I have a clog.
MIKE: Excuse me?
SUSAN: And you're a plumber. Right?
MIKE: Yeah.
SUSAN: The clog's in the pipe.
MIKE: Yeah, that's usually where they are.
SUSAN: (laughs) Well, I've got one.
MIKE: Well, let me get my tools.
SUSAN: Now? You wanna come over now? (uh oh.) Y-you have company.
EDIE: I don't mind. (smiles innocently at SUSAN)
MIKE: Just give me 2 minutes. I'll be right over.
(EDIE smirks at SUSAN, then shuts the door. SUSAN lets out a small yelp as she rushes down the porch steps.)
(Cut to: INT. SUSAN- HOUSE - KITCHEN --- NIGHT SUSAN and JULIE are at the sink, frantically trying to stuff handfuls of hair down the sink.)
SUSAN: That's it, just stuff the hair down.
JULIE: I stuffed it; it's not enough to clog it.
SUSAN: Here, here, look. Put in this peanut butter. And this cooking oil. (grabs a jar of olives from the counter) And these olives!
JULIE: Mom, Mom I'm telling you it's not working.
(The doorbell rings. MIKE is seen through the window outside the kitchen back door. He looks in the window, smiling at SUSAN.)

SUSAN: Uh, oh god. That's him. How am I gonna stuff up the sink... (trails off as she and JULIE turn to notice JULIE's miniature Trojan horse sitting on the kitchen table.)
(Cut to:INT. SUSAN- HOUSE - KITCHEN --- NIGHT (LATER))
(MIKE is lying on the ground, looking up at the pipes in the kitchen sink. SUSAN is leaning against the kitchen counter as he works.)
MIKE: Well. (takes a bunch of popsicle sticks out of a section of the pipes as he looks up at SUSAN, who tucks some hair behind her ear.) Here's your problem. Looks like somebody stuffed a bunch of popsicle sticks down there.
(JULIE creeps down the stairs to peer out at them.)
SUSAN: I've told Julie a million times not to play in the kitchen. (laughs) Kids, y' know?
(MIKE laughs understandingly as SUSAN looks up, smiling. JULIE catches SUSAN's eye and glares at her. SUSAN gestures apologetically at JULIE.)

本段词汇与句法:
(1) ambrosia 词典上的意思是:美味的食物,神的食物。(对于ambrosia, 我的认识仅限于IGA里面的称作ambrosia的沙拉,全用水果做成,还加了大量的whipped cream, 很美味,就是太rich了)
(2) smirk 假笑,带有坏意的笑
(3) let out 放出 离开
(4) miniature = small


CUT TO: [EXT. SADDLE RANCH CHOP HOUSE --- DUSK]
(Fade to: Interior of the restaurant, where the VAN DE KAMP family are sitting in a booth as a SERVER has just finished taking their orders.)
SERVER:Alright, I'll go put in your order. I'll be right back with your drinks and your plates for the salad bar. (walks away)
REX: Thank you.
BREE: Andrew, Danielle, napkins? (smiles at them)
ANDREW: They have video games. Can we go play until our food gets here?
BREE: Andrew. This is family time. I think we should all...
REX: (interrupts BREE) Go ahead and play. (DANIELLE and ANDREW look at REX, surprised, as they get up and leave.)
BREE: I know that you think I'm angry about coming here, but I'm not. I mean, the kids wanted a change of pace, something fun. I get it. (smiles at REX) Probably will want something healthier tomorrow night though, I'm thinking about chicken?
REX: (interrupts BREE) I want a divorce. (BREE looks at him, stunned) I just can't live in this... this detergent commercial anymore.
(The SERVER stops beside their table.)
SERVER:The salad bar's right over there, help yourself.
REX: Thank you.(watches as the SERVER walks away)
BREE: Um. Think I'll go get your salad for you.
(BREE takes his plate and walks to the salad bar. MRS. HUBER sees her and gets up, following BREE to the salad bar. BREE puts some lettuce leaves on the plate as MRS. HUBER comes up to her.)
MRS. HUBER:Bree Van De Kamp!
BREE: (looks up, startled) Oh, hello Mrs. Huber. (distractedly putting some onions onto REX's salad.)
MRS. HUBER:Oh we didn't get a chance to talk at Mary Alice's wake. How are you doing?
(BREE is lost for words, unable to answer as she looks back at REX sitting in their booth, avoiding her eyes.)
NARRATOR: Bree longed to share the truth about her husband's painful betrayal, but sadly for Bree, admitting defeat was not an option.
BREE: (smiles at MRS. HUBER) Great. Everything is just great. (puts some dressing on the salad)
(Cut to:BREE slides back into their booth, where REX is sitting.)
BREE: Okay, well, I got you the honey mustard dressing; the ranch looked just a little bit suspect. (starts cutting the bread as REX sighs, starting on his salad)
REX: (chews the salad as he watches BREE) Are we gonna talk about what I just said?
BREE: If you think I'm gonna discuss the dissolution of my marriage in a place where the restrooms are labelled "chicks" and "dudes (looks up at REX), you're out of your mind.
REX: (starts to choke, wheezing. He gestures at his salad) What's in this?
BREE: What do you mean what's in this? It's salad.
REX: With?(coughing and wheezing) with onions?
BREE: What?
REX: (fighting for breath) You put onions in my salad!!
(REX slides out of the booth, collapsing on the floor as he pulls the tablecloth, and everything on it, along with him on the ground. BREE stands up, stunned as she watches him collapsed on the floor.)
BREE: (gasps) No, I didn't! (realizing) Oh wait?

本段词汇与句法:
(1) I know that you think I'm angry about coming here… 这简直是鸡同鸭讲,Bree太过于把自己装饰为优雅练达的丽人形象,以至于忽略了家庭成员的感受,这也是他们家庭矛盾的根源。
(2) this detergent commercial anymore…. Rex 这里把他妻子比喻为电视中卖清洁剂的广告模特,意指Bree平时虽然勤做家务又很能干,但是家庭成员间缺乏温馨感。


CUT TO: [INT. YOUNG HOUSE - ZACH'S ROOM --- NIGHT]
(A sound of a pick awakens ZACH, who slides out of bed, puts on his glasses and looks out the window.)
NARRATOR: The sound that awakened my son was something he'd heard only once before, many years ago, when he was quite young.
(ZACH walks along the garden path, towards the sound. He comes to the pool, where PAUL has drained the water, and is digging the rocks and dirt on the bottom with a pick.)
NARRATOR: But he recognized it instantly.
(PAUL looks up at ZACH, who watches him, breathing hard. PAUL returns to his task, using the pick to loosen the concrete at the bottom of the pool systematically, lit by only a small light propped up next to him. ZACH just stands at the side of the pool, watching, as we hear the sounds of PAUL grunting as he hacks at the concrete.)
NARRATOR: It was the sound of family secret.
CUT TO: [EXT. WISTERIA LANE --- MORNING]
(Cut to:INT. SCAVO HOUSE - LIVING ROOM/KITCHEN --- MORNING
LYNETTE is feeding the baby, trying to coax him to eat puréed peaches.)
NARRATOR: Seven days after my funeral, life on Wisteria Lane finally returned to normal. Which, for some of my friends, was unfortunate.
(The baby flicks a spoonful of peaches onto LYNETTE's face and shirt. The baby gurgles with laughter. She puts her head in her hands as PARKER appears at the open doorway.)
PARKER:Mommy, Mommy!
LYNETTE: (sotto) Now what.

PARKER:Daddy's home! (LYNETTE turns to look at the doorway, surprised.)
(TOM appears at the door, holding a luggage bag, PORTER and PRESTON in his arms, PARKER hanging onto his trouser leg.)
TOM: (laughing) Come on! Is everybody home?
LYNETTE: Hey, yeah! (smiling and laughing, she gets up and picks up the baby. She is surprised, happy to see him.)
SCAVO kids: Yeah, yeah!
TOM: Hey!
LYNETTE: I wasn't expecting you for a week!
TOM: (puts PORTER and PRESTON on the floor as he pats the baby on the head. LYNETTE wipes some of the peach off her face.) I have to go back to Frisco in the morning. When I got your call, you sounded a little frazzled. (kisses LYNETTE)
LYNETTE: Yeah! It's been a little rough!
TOM: Hmm, yeah, peaches.
PARKER:Daddy, Daddy, did you buy us any presents?
TOM: Oh god, presents. Oh, wait a minute, lemme see. (takes a rugby ball out of his bag) Ooooh.
SCAVO kids: Yaaaaayyy! (LYNETTE smiles)
TOM: But I'm not gonna give it to you, unless you promise me that you're gonna go outside right now and practice throwing for 20 minutes, okay? You promise?
SCAVO kids: Yeah, yeah, yeah!! (all run outside)
TOM: Get out! Who's open! Go left! (throws the ball out the open doorway)
SCAVO kids: Yeah yeah yeah!
TOM: Deeper, deeper, touchdown! (throws his arms up in the air)
(Cut to:TOM and LYNETTE, bursting through the doorway to their bedroom, kissing and giggling)
LYNETTE: Oh my god, oh my, oh!
(They collapse on the bed, TOM on top of LYNETTE.)
LYNETTE: Ooh, you gotta be kidding! I'm exhausted! I look terrible, I'm covered in peaches!
TOM: Sorry baby, I gotta have you.
LYNETTE: (rubs her forehead with her hand) Well, is it ok if I just lie here?
TOM: Absolutely. (kisses her)
LYNETTE: (giggles) I love you.
TOM: I love you more. (LYNETTE giggles as they kiss)
LYNETTE: Oh wait, I gotta tell you, I was having trouble with swelling, so the doctor took me off the pill, so you're just gonna have to put on a condom.
TOM: Condom?
LYNETTE: Yeah.
TOM: What's the big deal? Let's risk it.
LYNETTE: (incredulous) Let's risk it?
TOM: Yeah.
LYNETTE: Ooh! (hits him on the face)
(TOM collapses on the bed, groaning, holding his face. LYNETTE hits him with a stuffed toy.)

本段词汇与句法:
(1) spoonful 一匙 同样的,mouthful 一口东西
(2) frazzled 这里的意思是,声音疲惫的
(3) But I'm not gonna give it to you….. I am goona do something 及其常用说法, 等于 I am going to do something


CUT TO: [INT. HOSPITAL - REX'S ROOM --- DAY]
(REX is lying in the hospital bed, watching BREE, who sits a chair next to the bed, avoiding his eyes.)
REX: I can't believe you tried to kill me.
BREE: Yes, well, I feel badly about that. I told you, Mrs. Huber came over and I got distracted. It was a mistake.
REX: Since when do you make mistakes?
BREE: (laughing) What's that supposed to mean?
REX: It means I'm sick of you being so damn perfect all the time. I-I-I'm sick of the bizarre way your hair doesn't move. I'm sick of you making the bed in the morning before I've even used the bathroom. (BREE looks incredulously at REX) You're, you're this plastic suburban housewife with her pearls and her spatula, who says things like We owe the Hendersons a dinner? (BREE looks down in at her lap, upset) Where's the woman I fell in love with? Who, who used to burn the toast, drink milk out of the carton, and laugh? I need her. Not this cold perfect thing you've become.
BREE: (composes herself. She gets up and takes a vase off the table) These need water.
(BREE walks into the bathroom, putting the vase in the sink and filling it with water. She looks at herself in the mirror, and starts to cry, putting her hand over her mouth.)
NARRATOR: BREE sobbed quietly in the bathroom for 5 minutes. But her husband never knew. Because when Bree finally emerged, she was perfect.
(BREE walks out of the bathroom holding the vase, smiling serenely.)

本段词汇与句法:
(1) What's that supposed to mean? 那是什么意思?
(2) Bizarre 怪异的,奇怪的
(3) Spatula 炒菜铲


CUT TO:[EXT. SOLIS HOUSE - YARD --- NIGHT]
(CARLOS kneels on the sidewalk, putting his face close to the grass. GABRIELLE comes out of the front door, all dressed up in an elegant dress, hair curled on her head. She shuts the door and comes down the steps.)
GABRIELLE: I found my earrings, we can go now.
CARLOS: Was John here today?
(GABRIELLE stops short.)
GABRIELLE: Well, yeah.
CARLOS: The lawn hasn't been mowed. I've had it; we're getting a real gardener.
GABRIELLE: Why??
CARLOS: Are you deaf? I just said, he's not doing his job.
GABRIELLE: It's dark, you just can't see that the lawn has been mowed.
CARLOS: It hasn't been. Feel this grass.
GABRIELLE: I'm not feeling the grass! Let's just get going, come on! We're late! (walks off towards the car as CARLOS looks closely at the grass.)
(Cut to:EXT. OUTDOOR PARTY VENUE --- NIGHT)
(CARLOS walks with GABRIELLE on his arm. The party is filled with elegantly dressed people.)
CARLOS: (throws his car keys at the valet) Take care of it.
VALET: Yes, sir.
CARLOS: There's Tanaka. Time for me to go into my dance.
GABRIELLE: (smiles) Good luck, sweetheart. (kisses CARLOS on the cheek.)
(CARLOS smiles at GABRIELLE and walks away towards TANAKA. GABRIELLE looks around, and stops a WAITER passing by.)
GABRIELLE: Oh, excuse me.
WAITER: Ma'am?
GABRIELLE: You see that man who just walked away? Can you make sure he has a drink in his hand all. night long. (tucks a folded banknote in his pocket.)
Waiter: (smiles) Yes, ma'am.
(GABRIELLE looks around, and hurries off.)
(Cut to:INT. GABRIELLE'S CAR --- NIGHT (LATER)
GABRIELLE is driving the car. We see that she's driving back to Wisteria Lane. She parks the car in her driveway, hurries into the open garage door, reappearing pushing the lawn mower. She pushes the machine onto the grass and begins to mow the lawn, tottering along in her high heels and party dress.)
(Cut to:EXT. OUTDOOR PARTY VENUE --- NIGHT (STILL LATER)
GABRIELLE hurries back to the party. She sees CARLOS with TANAKA, a drink on his hand, who hasn't even noticed that she'd left. She sighs with relief, running her hand along her hair. GABRIELLE picks a piece of grass from her hair, throwing it over her shoulder hastily.
(Cut to:EXT. SOLIS HOUSE --- DAY (THE NEXT MORNING)
CARLOS comes out of the front door and walks down the walkway. He stops and crouches down to run his hand along the mowed grass. Looking puzzled, CARLOS straightens up and continues walking to the car mollified. We pan up to see GABRIELLE watching from the upstairs balcony, sighing with relief as she's successfully covered her affair.)

本段词汇与句法:
(1) I’ve had it. 我受够了。
(2) Valet 仆从
(3) Totter 蹒跚 摇晃
(4) Hastily 慌张地
(5) Mollified 得到安慰的,


CUT TO:[INT. SUPERMARKET --- DAY]
(SUSAN pushes her cart along the aisle. Spotting MRS. HUBER, she tries to sneak past, with no luck. MRS. HUBER notices her.)
MRS. HUBER:Susan? Susan!
SUSAN: (smiles) Oh. Mrs. Huber, how you doing?
MRS. HUBER:Not too well, I'm afraid. I'm trying to find something to soothe my stomach.
SUSAN: It's upset?
MRS. HUBER:Yeah, I had the worst macaroni and cheese at the wake, it's been running through my system ever since.
SUSAN: (sympathetic smile) Oh.
MRS. HUBER:And I need to be at my best tonight. Edie Britt's son is spending the night tonight.
SUSAN: (raises her eyebrows) He's spending the night?
MRS. HUBER:Apparently, Edie is having a gentleman friend over on dinner, and I think she plans on entertaining into the wee hours, if you know what I mean.

(SUSAN is stunned. She immediately hurries out, leaving her cart in the middle of the aisle while MRS. HUBER is busy browsing.)
MRS. HUBER:Oh, here's some antacid. Have you ever tried this? (looks up, notices SUSAN is gone)
(Cut to:INT. SUSAN's HOUSE - KITCHEN ---- NIGHT SUSAN is pacing the floor as JULIE watches her, curled up on the couch.)
SUSAN: I can't believe it. This can't be happening. Mike can't like Edie better than me, he just can't!
JULIE: I don't know what's going on. Maybe they're just... having dinner.
(SUSAN gives her a look.)
JULIE: You're right. They're doing it.

本段词汇与句法:
(1) ever since 从那时起
(2) wee hours 凌晨


(Cut to:EXT. WISTERIA LANE --- NIGHT)
(SUSAN holds a measuring cup and walks up to EDIE's front porch. She rings the doorbell.)
SUSAN: Edie?
(SUSAN walks along the side of EDIE's house, peering in the back door.)
SUSAN: Edie? Hello..?
(SUSAN tries the back door and finds it open. Hearing music, she walks in.)
SUSAN: Anybody home? I need to borrow sugar?
(SUSAN walks along the corridor, where she picks up a piece of EDIE's discarded clothing. She goes into the living room, where she sees lots of candles lit, glasses of wine and chocolate on the coffee table. The measuring drop drops out of her hand and onto the floor. She picks up EDIE's pink, flowered bra, looking at it as she hears a noise.)
EDIE: [OS] Oh! Oh my god!
(SUSAN realizes what EDIE is doing upstairs. Upset, she drops down onto the couch)
NARRATOR: And just like that, the possibility that Susan had clung onto, the maybe of Mike Delfino was gone forever. And despite the precariousness of the situation, Susan took a moment to mourn her loss.
(SUSAN throws EDIE's bra behind her, where it catches the flame of the candles. It starts to burn, and lights up the curtain as well. SUSAN picks up a piece of chocolate and eats it. Smelling smoke, she turns around and discovers the curtain is on fire.)
SUSAN: Oh... Oh! Oh!
(SUSAN tries to put out the fire with no avail. She throws the leftover wine from the glasses onto the fire, which makes it worse.)
NARRATOR: It didn't take long for Susan to realize, this was just not her night.
(SUSAN abandons the scene, and runs out, cutting through the back garden. Meanwhile, EDIE's living room goes up in flames.)
EDIE: (OS) Is somebody out there? Oh my god, there's smoke!
CUT TO: [EXT. EDIE'S HOUSE ---- NIGHT (LATER)]
(The house is a burning inferno. The neighbourhood has turned out to watch as fire-fighters try and save the blazing house. EDIE, wrapped in a blanket and followed by a fireman, rushes out from behind a fire truck and sees the burning house.)
EDIE: (teary) Oh my god. Oh... (leans against the fire truck)

本段词汇与句法:
(1) clung (cling的过去式,等于stick的意思)
(2) SUSAN tries to put out the fire with no avail. No avail 是徒劳,不起作用的意思,一般也用法是: of no avail
(3) Inferno 火海
(4) Buming house 火焰到处窜起的房子


(We follow SUSAN, as she walks by MRS. HUBER.)
MRS. HUBER: (in a lowered voice, to neighbour) ...candles unattended in the den. Paramedics say she was lucky, she could've been killed!
(SUSAN walks up to where LYNETTE, BREE and GABRIELLE are standing together behind the tape, facing the burning house.)
LYNETTE: (to GABRIELLE and BREE) She was having sex with some guy when the fire started.
GABRIELLE: What happened to him?
LYNETTE: He got smoke inhalation, he's at the hospital.
SUSAN: Oh..
BREE: Susan, are you alright? You look awful.
SUSAN: I'm fine. I'm fine. I just feel really bad for Edie.
GABRIELLE: Oh, don't worry about Edie. She's a strong lady.
LYNETTE: Absolutely. She'll get through this. She'll find a way to survive.
BREE: We all do.
GABRIELLE: Come on.
(They all turn around and walk away. BREE, GABRIELLE and LYNETTE go to their respective spouses. SUSAN goes to lean against a car hood, watching the burning house, arms folded. Suddenly, MIKE walks up behind her.)
MIKE: Wow, what happened?
SUSAN: (surprised) Mike!
NARRATOR: And suddenly, there he was, like a phoenix rising from the ashes.
SUSAN: I, I thought you were... um. Where were you?
MIKE: I just got back from the movies. Edie had a fire, huh?
SUSAN: Yeah. Yeah, but she's fine now. Everything's fine now.
NARRATOR: And just like that, Susan was happy. Life was suddenly full of possibilities.
(SUSAN smiles, looking back at the burning house. MIKE looks at her, smiling, as he too turns his head to the house. The camera pans out, showing them standing together from behind, both watching the burning house side by side.)
(Cut to:INT. MIKE'S HOUSE - ENTRANCE ---- NIGHT)
NARRATOR: Not to mention a few unexpected surprises.
(MIKE picks up the phone and dials.)
MAN: Hello?
MIKE: Hey, it's me.
MAN: Do you have anything yet.
MIKE: No, not yet, but don't worry. I'm definitely getting closer.
(MIKE pulls a gun out of his pocket, putting it down next to the phone.)

本段词汇与句法:
(1) she could've been killed! 她很可能会被烧死。类似的用法还有,I should’ve told her that the store was already closed.
(2) He got smoke inhalation 他吸了太多烟


CUT TO: [EXT. MARY ALICE'S HOUSE - FRONT YARD --- DAY]
(SUSAN, BREE, LYNETTE and GABRIELLE walk down the pathway to the gate, where a car with the trunk open is parked at the kerb.)
SUSAN: I brought some champagne. I thought we should all have a toast.
NARRATOR: The next day, my friends came together to pack away my clothes, my personal belongings, and what was left of my life.
SUSAN: Alright ladies, lift 'em up. To Mary Alice, good friend and neighbour. Wherever you are, we hope you've found peace.
LYNETTE: To Mary Alice.
GABRIELLE: To Mary Alice.
(They clink their glasses together, and drink their champagne. They lower their glasses, and look at each other, remembering. LYNETTE runs her hand across SUSAN's cheek affectionately, then goes to the car trunk as they all break up.)
LYNETTE: Let's get this show on the road.
(GABRIELLE holds up a pair of pants from a box on the sidewalk. A piece of paper falls onto the ground.)
GABRIELLE: You guys check out Mary Alice's clothes? Size 8, hah! She always told me she was a size 6. Guess we found the skeleton in her closet.
NARRATOR: Not quite, Gabrielle, not quite.
(BREE picks up the piece of paper.)
GABRIELLE: What's that?
BREE: It's a letter, addressed to Mary Alice.
NARRATOR: How ironic, to have something I tried so desperately to keep secret, treated so casually.
(GABRIELLE opens up the piece of paper.)
LYNETTE: What're you doing? That's private.
GABRIELLE: It's open, what's the big deal?
(GABRIELLE and LYNETTE read the piece of paper. They pass it to SUSAN, who reads the note with BREE looking over her shoulder:
I KNOW WHAT YOU DID
IT MAKES ME SICK
I'M GOING TO TELL
They look up in shock and amazement.)
SUSAN: What does this mean?
LYNETTE: I don't know, but check out the postmark.
BREE: Oh my god, she got it the day she died.
GABRIELLE: (takes the envelope, looking at it) Do you think this is why she...?
NARRATOR: I'm so sorry, girls. I never wanted you to be burdened with this.
SUSAN: Oh Mary Alice, what did you do?
(The camera pans out on BREE, GABRIELLE, LYNETTE and SUSAN, looking at each other in amazement.)

本段词汇与句法:
(1) affectionately 热情地, 体贴地
(2) skeleton 骨骼
(3) what's the big deal? 有什么大不了的?
(4) Burden with 背上包袱 使负担

(下集)

device creation process

2010年1月27日 星期三

Android init 启动过程分析

分析android的启动过程,从内核之上,我们首先应该从文件系统的init开始,因为 init 是内核进入文件系统后第一个运行的程序,通常我们可以在linux的命令行中指定内核第一个调用谁,如果没指定那么内核将会到/sbin/, /bin/ 等目录下查找默认的init,如果没有找到那么就报告出错。
下面是曾经用过的几种开发板的命令行参数:
S3C2410 启动参数:
noinitrd root=/dev/nfs nfsroot=192.168.2.56:/nfsroot/rootfs ip=192.168.2.188:192.168.2.56:192.168.2.56:255.255.255.0::eth0:on console=ttySAC0
S3C2440 启动参数:
setenv bootargs console=ttySAC0 root=/dev/nfs nfsroot=192.168.2.56:/nfsroot/rootfs ip=192.168.2.175:192.168.2.56:192.168.2.201:255.255.255.0::eth0:on mem=64M init=/init
marvell 310 启动参数:
boot root=/dev/nfs nfsroot=192.168.2.56:/nfsroot/rootfs,rsize=1024,wsize=1024 ip=192.168.2.176:192.168.2.201:192.168.2.201:255.255.255.0::eth0:-On console=ttyS2,115200 mem=64M init=/init

init的源代码在文件:./system/core/init/init.c 中,init会一步步完成下面的任务:
1.初始化log系统

2.解析/init.rc和/init.%hardware%.rc文件

3. 执行 early-init action in the two files parsed in step 2.

4. 设备初始化,例如:在 /dev 下面创建所有设备节点,下载 firmwares.

5. 初始化属性服务器,Actually the property system is working as a share memory. Logically it looks like a registry under Windows system.

6. 执行 init action in the two files parsed in step 2.

7. 开启 属性服务。

8. 执行 early-boot and boot actions in the two files parsed in step 2.

9. 执行 Execute property action in the two files parsed in step 2.

10. 进入一个无限循环 to wait for device/property set/child process exit events.例如, 如果SD卡被插入,init会收到一个设备插入事件,它会为这个设备创建节点。系统中比较重要的进程都是由init来fork的,所以如果他们他谁崩溃了,那么init 将会收到一个 SIGCHLD 信号,把这个信号转化为子进程退出事件, 所以在loop中,init 会操作进程退出事件并且执行 *.rc 文件中定义的命令。
例如,在init.rc中,因为有:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
所以,如果zygote因为启动某些服务导致异常退出后,init将会重新去启动它。

int main(int argc, char **argv)
{
...
//需要在后面的程序中看打印信息的话,需要屏蔽open_devnull_stdio()函数
open_devnull_stdio();
...
//初始化log系统
log_init();
//解析/init.rc和/init.%hardware%.rc文件
parse_config_file("/init.rc");
...
snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
parse_config_file(tmp);
...
//执行 early-init action in the two files parsed in step 2.
action_for_each_trigger("early-init", action_add_queue_tail);
drain_action_queue();
...
/* execute all the boot actions to get us started */
/* 执行 init action in the two files parsed in step 2 */
action_for_each_trigger("init", action_add_queue_tail);
drain_action_queue();
...
/* 执行 early-boot and boot actions in the two files parsed in step 2 */
action_for_each_trigger("early-boot", action_add_queue_tail);
action_for_each_trigger("boot", action_add_queue_tail);
drain_action_queue();

/* run all property triggers based on current state of the properties */
queue_all_property_triggers();
drain_action_queue();

/* enable property triggers */
property_triggers_enabled = 1;
...
for(;;) {
int nr, timeout = -1;
...
drain_action_queue();
restart_processes();

if (process_needs_restart) {
timeout = (process_needs_restart - gettime()) * 1000;
if (timeout < 0)
timeout = 0;
}
...
nr = poll(ufds, 3, timeout);
if (nr <= 0)
continue;

if (ufds[2].revents == POLLIN) {
/* we got a SIGCHLD - reap and restart as needed */
read(signal_recv_fd, tmp, sizeof(tmp));
while (!wait_for_one_process(0))
;
continue;
}

if (ufds[0].revents == POLLIN)
handle_device_fd(device_fd);

if (ufds[1].revents == POLLIN)
{
handle_property_set_fd(property_set_fd);
}
}

return 0;
}


2.解析init.rc脚本
init.rc 脚本的具体语法可以参考下面文档
http://www.kandroid.org/android_pdk/bring_up.html
名词解释:
Android初始化語言由四大类声明组成:行为类(Actions),命令类(Commands),服务类(Services),选项类(Options).
初始化语言以行为单位,由以空格间隔的语言符号組成。C风格的反斜杠转义符可以用来插入空白到语言符号。双引号也可以用来防止文本被空格分成多个语言符号。当反斜杠在行末时,作为换行符。
* 以#开始(前面允许空格)的行为注释。
* Actions和Services隐含声明一个新的段落。所有该段落下Commands或Options的声明属于该段落。第一段落前的Commands或Options被忽略。
* Actions和Services拥有唯一的命名。在他们之后声明相同命名的类将被当作错误并忽略。
Actions是一系列命令的命名。Actions拥有一个触发器(trigger)用来決定action何時执行。当一个action在符合触发条件被执行时,如果它还没被加入到待执行队列中的话,則加入到队列最后。
队列中的action依次执行,action中的命令也依次执行。Init在执行命令的中间处理其他活动(设备创建/销毁,property 设置,进程重启)。

Actions的表现形式:
on



重要的数据结构
两个列表,一个队列。
static list_declare(service_list);
static list_declare(action_list);
static list_declare(action_queue);
*.rc 脚本中所有 service关键字定义的服务将会添加到 service_list 列表中。
*.rc 脚本中所有 on 关键开头的项将会被会添加到 action_list 列表中。
每个action列表项都有一个列表,此列表用来保存该段落下的 Commands

脚本解析过程:
parse_config_file("/init.rc")
int parse_config_file(const char *fn)
{
char *data;
data = read_file(fn, 0);
if (!data) return -1;

parse_config(fn, data);
DUMP();
return 0;
}
static void parse_config(const char *fn, char *s)

...
case T_NEWLINE:
if (nargs) {
int kw = lookup_keyword(args[0]);
if (kw_is(kw, SECTION)) {
state.parse_line(&state, 0, 0);
parse_new_section(&state, kw, nargs, args);
} else {
state.parse_line(&state, nargs, args);
}
nargs = 0;
}
...


parse_config会逐行对脚本进行解析,如果关键字类型为 SECTION ,那么将会执行 parse_new_section()
类型为 SECTION 的关键字有: on 和 sevice
关键字类型定义在 Parser.c (system\core\init) 文件中
Parser.c (system\core\init)
#define SECTION 0x01
#define COMMAND 0x02
#define OPTION 0x04
关键字 属性
capability, OPTION, 0, 0)
class, OPTION, 0, 0)
class_start, COMMAND, 1, do_class_start)
class_stop, COMMAND, 1, do_class_stop)
console, OPTION, 0, 0)
critical, OPTION, 0, 0)
disabled, OPTION, 0, 0)
domainname, COMMAND, 1, do_domainname)
exec, COMMAND, 1, do_exec)
export, COMMAND, 2, do_export)
group, OPTION, 0, 0)
hostname, COMMAND, 1, do_hostname)
ifup, COMMAND, 1, do_ifup)
insmod, COMMAND, 1, do_insmod)
import, COMMAND, 1, do_import)
keycodes, OPTION, 0, 0)
mkdir, COMMAND, 1, do_mkdir)
mount, COMMAND, 3, do_mount)
on, SECTION, 0, 0)
oneshot, OPTION, 0, 0)
onrestart, OPTION, 0, 0)
restart, COMMAND, 1, do_restart)
service, SECTION, 0, 0)
setenv, OPTION, 2, 0)
setkey, COMMAND, 0, do_setkey)
setprop, COMMAND, 2, do_setprop)
setrlimit, COMMAND, 3, do_setrlimit)
socket, OPTION, 0, 0)
start, COMMAND, 1, do_start)
stop, COMMAND, 1, do_stop)
trigger, COMMAND, 1, do_trigger)
symlink, COMMAND, 1, do_symlink)
sysclktz, COMMAND, 1, do_sysclktz)
user, OPTION, 0, 0)
write, COMMAND, 2, do_write)
chown, COMMAND, 2, do_chown)
chmod, COMMAND, 2, do_chmod)
loglevel, COMMAND, 1, do_loglevel)
device, COMMAND, 4, do_device)

parse_new_section()中再分别对 service 或者 on 关键字开头的内容进行解析。
...
case K_service:
state->context = parse_service(state, nargs, args);
if (state->context) {
state->parse_line = parse_line_service;
return;
}
break;
case K_on:
state->context = parse_action(state, nargs, args);
if (state->context) {
state->parse_line = parse_line_action;
return;
}
break;
}
...

对 on 关键字开头的内容进行解析
static void *parse_action(struct parse_state *state, int nargs, char **args)
{
...
act = calloc(1, sizeof(*act));
act->name = args[1];
list_init(&act->commands);
list_add_tail(&action_list, &act->alist);
...
}

对 service 关键字开头的内容进行解析
static void *parse_service(struct parse_state *state, int nargs, char **args)
{
struct service *svc;
if (nargs < 3) {
parse_error(state, "services must have a name and a program\n");
return 0;
}
if (!valid_name(args[1])) {
parse_error(state, "invalid service name '%s'\n", args[1]);
return 0;
}
//如果服务已经存在service_list列表中将会被忽略
svc = service_find_by_name(args[1]);
if (svc) {
parse_error(state, "ignored duplicate definition of service '%s'\n", args[1]);
return 0;
}

nargs -= 2;
svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs);
if (!svc) {
parse_error(state, "out of memory\n");
return 0;
}
svc->name = args[1];
svc->classname = "default";
memcpy(svc->args, args + 2, sizeof(char*) * nargs);
svc->args[nargs] = 0;
svc->nargs = nargs;
svc->onrestart.name = "onrestart";
list_init(&svc->onrestart.commands);
//添加该服务到 service_list 列表
list_add_tail(&service_list, &svc->slist);
return svc;
}
服务的表现形式:
service [ ]*