读书笔记 (2016.01)

幽灵舰队
很有趣的一本科幻小说,某些设定让人印象深刻:
* 社会的结构:殖民地的年轻人开拓疆土,不用服兵役;防卫军从老人中挑选,克隆DNA,传输意识,加上脑伴,简直是又一个攻壳机动队。
* 特种部队士兵的起名方式:从科学家和哲学家的名字里随机挑选,像极了docker里随机给container起名的方式,很有趣。而主角的姓氏狄拉克,也是我最喜欢的物理学家之一,呵呵。        幽灵舰队-美-约翰·斯卡尔齐

艾伦·图灵传——如谜的解谜者
作为搞IT的,祖师爷的传记当然想看一下。不过只看了一部分,并没有看完,因为内容确实太杂了。等有空的时候可以再继续。话说kindle上打开书本,就直接跳到没看完前的那一页,太方便了,十分适合看一半先不看的情况。。。
艾伦·图灵传——如谜的解谜者

时间简史
第一次看时间简史,大约是在高二的时候。记得那时要参加物理竞赛,学校组织俺们到南师大去上课,我舅舅家离那儿不远(进香河),所以我没有住校,而是骑个自行车往来于南师大。当时的“先锋书店”还在广州路上,我天天路过,进过一次之后,不出意外的迷上了这家书店——我在先锋书店的沙发上一坐就是一下午,在这书店里看完了《时间简史》,然后买了本《挪威的森林》。现在想来,真是文艺。。。
第二遍看《时间简史》,内容已然不新鲜,但是还是觉得讲得非常清楚。在科普这方面,霍金费曼都是顶级的。
时间简史

物理学的困惑
又一本没看完的书,为什么?这本书更多的感觉是吐槽,而不是科普。虽然它讲得也很清楚,很“正确”,但是作者夹带的私货太明显了,从一开始就知道你想表达什么,所以就别绕那么大弯了嘛。
当然,也许是因为我先看过了B·格林的几本书,所以对他的对头的书不太感冒吧。
不过,我也绝对不相信弦论就是这个世界的真理,真理到底是什么,这辈子也没机会知道吧。。。
物理学的困惑-L·斯莫林

三体
这是大概是第4次看《三体》了。
第一次是《科幻世界》的连载;
第二次是《三体》刚出版的时候,那会儿还写了篇博客推荐呢:推荐《三体》(没有剧透,放心)
第三次是《三体III 死神永生》出版前后,连着把1,2,3一起看完。
这次是因为amazon出了三体的kindle版合辑,虽然有实体书了,但还是想买个电子版,方便若干年之后再看一遍。不过既然买了,那就再看一遍,也已经隔了好几年了。
顺便推荐一下《三体X 观想之宙》,作为经过大刘认可的同人,写得也是相当好看的,虽然它更像是网络小说(其实它就是网络小说。。。),但不得不说它的想像以及行文,看得是蛮爽的。
三体全集-刘慈欣

怀孕这件大事儿》《怀孕这件大事儿之产后恢复大作战
这两本其实算不上书,只是几篇短文的合集。不过得说杜小溪写得确实不错,很多道理我们也懂,不过你这么总结一下,也方便我们跟老人沟通。总之,科学怀孕,科学“做月子”,我们也只能尽量和老人们沟通了。
怀孕这件大事儿 怀孕这件大事儿之产后恢复大作战

西尔斯怀孕百科》《怀孕圣经
老婆怀孕,生娃。整个过程中我们也把这两本书基本上翻了一遍。
现在女儿出生了,我的感觉是,这两本书只要看一本就够了。而且,最紧张的是前几个月,到后期只要按时去医院产检,一般都不太担心了。
不过还是要感谢一下这些书以及一些朋友的建议,老婆整个孕期都没出什么毛病,糖耐一次就过了,也没有高血压等等孕期的病;当然,最感谢的是老婆大人,这一切都是你控制得好啦!
西尔斯怀孕百科 怀孕圣经(第4版)

Share

Welcom, my baby girl

2015年12月24日早上,我的女儿出生了!
感觉一切发生得还是太快,于是赶紧记录一下这几天的生活…

之前老婆的孕期检查发现胎盘前置,只能剖,按计划,12月21日住进了国妇婴,待产。
医生一 开始准备23号剖,晓敏略施小计,把日期改成了24号。

24号一大早,护士过来做好了术前准备,然后说,等着吧,也许上午,也许要等到下午手术;医生查完房,也是说,等着吧,手术时间不定。
结果8点半刚过,手术室的车子就来接晓敏,要准备剖了,我们还没做好心理准备呐!推走前赶紧给晓敏拍张照留作纪念。
进产房喽

然后就是在手术室外面等了。。。
一开始,我一直在等着“叫号”,让家属签关于麻醉的协议——
9点15分,叫到我们的床位了,我以为刚开始手术要去签字,结果,一个小生命就在我眼前,然后医生啪啪啪地讲了一通,我有点懵。。。
然后我意识到:
  女儿出生了;
  晓敏还在手术中,之后要去ICU观察;
  因为妈妈要进ICU,女儿只能进新生儿科;
什么?!ICU?!我老婆千万不要有事!!
再按铃找了护士帮忙问清楚了情况:宝宝没事,但是必须在新生儿科由医院照顾;晓敏因为胎盘粘连有点出血,已经缝合好了,人没事,在ICU观察24小时。
好吧,只能等待了——只是,平安夜,想到晓敏一个人待在ICU,小女儿一个人待在新生儿科,都好可怜,好想她们。。。

不过还好,第二天,圣诞节,早上晓敏就从ICU出来了,回到了普通病房;到了中午,女儿也从新生儿科接回来,在妈妈身边了;到了下午,晓敏已经有奶了,也已经通气,能下床如厕了;女儿能吃能拉,很健康~ 开心!

到了28号,晓敏就出院了,回到了温暖而熟悉的家里。
床上,在阳光的依偎下,怀抱着小依依,感觉很幸福。
大小手

真心感谢国妇婴的医生和护士们,你们太厉害了!

最后——
你好,小依辰,欢迎来到这个世界~

附:致国妇婴产科(8楼)的感谢信

Share

Handle Discontinuity and PAT/PMT change in Android Multicast Playback

In previous post it briefly introduces how to implement multicast playback in Android.
In real world, multicast may get discontinuities or PAT/PMT changes, which will cause the playback intermittent or failure if it’s not correctly handled.

In this post, it will introduces how to handle discontinuity and PAT/PMT changes.

Background

In NuPlayer::Decoder::fetchInputData(), it handles three types of DISCONTINUITY:

  • DISCONTINUITY_TIME
  • DISCONTINUITY_AUDIO_FORMAT
  • DISCONTINUITY_VIDEO_FORMAT

Originally, they are used to handle adaptive cases in HLS, e.g. switch from low-resolution stream to high-resolution stream. They’re perfect for multicast stream’s discontinuity and PAT/PMT change as well.

Handle Discontinuity

In ATSParser::Stream::parse(), it already checks the ContinuityCounter in TS streams. We can just queue a time discontinuity unit, then NuPlayer::Decoder will handle the case, reset the playback and re-sync A/V.

if (mExpectedContinuityCounter >= 0
    && (unsigned)mExpectedContinuityCounter != continuity_counter) {
  ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID);
  ...
  signalDiscontinuity(DISCONTINUITY_TIME, NULL);
  ...
}

In ATSParser::Program::convertPTSToTimestamp(), there is a special flag for calculating time stamp from PTS.

if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {
  if (!mFirstPTSValid) {
    mFirstPTSValid = true;
    mFirstPTS = PTS;
    PTS = 0;
  } else if (PTS < mFirstPTS) {
    PTS = 0;
  } else {
    PTS -= mFirstPTS;
  }
}
...

If TS_TIMESTAMPS_ARE_ABSOLUTE is not set, it uses the first valid PTS as the base time stamp, and assumes the PTS is increasing all the time. This is not the case for multicast live streaming. So we need to set this flag to let it calculate time stamp by absolute value of PTS.

  // In MulticastSession::onConnect()
  mTSParser = new ATSParser(ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE);

With the changes, multicast discontinuity is correctly handled and it works fine when multicast stream is looped.

Handle PAT/PMT change

In ATSParser implementation, it just parses PAT/PMT and store the program table and the A/V streams. If PAT/PMT is changed, it just update the program table and streams, and requires the “user” of ATSParser to handle the change, which is quite complicated.
In the other hand, when PAT/PMT is changed in multicast, we know the stream is changed and thus can just throw away the previous program table. So why not delete the previous ATSParser and create a new one to handle the new stream? It makes things much easier.
The changes:

  • ATSParser
    1. Add an observer that should receive the event of PAT/PMT change
    2. Save PAT/PMT crc32 and detect the change; If it’s changed, call onPatPmtChange() and notify the observer
  • MulticastSession
    1. Receive parser’s event and call onPatPmtChanged() for PAT/PMT changed event
    2. Reset ATSParser by delete and create new one
    3. Queue FORMAT change DISCONTINUITY for both audio and video
    4. In dequeueAccessUnit(), check the discontinuity queue and return DISCONTINUITY for audio/video stream.

With the changes, ATSParser is reset when PAT/PMT changes, as if it plays a new stream, which is exactly the expected behavior.

Share

Multicast playback in Android

This article is to briefly introduce how to add multicast playback support in Android platform based on AOSP 5.0.0_r2 tag.

Background

  • NuPlayer is the default media player in Android L. It’s part of libmediaplayerservice located in frameworks/av/media/libmediaplayerservice
  • libstagefright is a library used by NuPlayer to provide a lot of media related functions, e.g. media download, parse and extract. Located in frameworks/av/media/libstagefright
  • chromium_org is a library used by Browser to provide all webview related functions. <video> tag in Webview also uses this library to render its content. Located in external/chromium_org
  • Gallery2 is a default system app that handles media playback intents. Located in packages/apps/Gallery

The above components will be changed to add multicast support.

Implementations

Precondition

Multicast as a kernel option, shall be enabled in kernel build.
Note: this option is enabled by default on Nexus Tablets, but disabled on Nexus Phones.
So you probably need to compile your custom kernel if you plan to test multicast on your phone.

  CONFIG_IP_MULTICAST=y
NuPlayer
  • MediaPlayerFactory::IFactory::scoreFactory() checks the URI scheme to decide which player shall be used to play a certain media.
    In NuPlayerFactory::scoreFactory(), multicast’s score shall be added to be chosen for playing multicast stream.
    if (!strncasecmp("http://", url, 7)
        || !strncasecmp("https://", url, 8)
        || !strncasecmp("file://", url, 7)) {
      … // return kOurScore
    }
    if (!strncasecmp("rtsp://", url, 7)) {
      return kOurScore;
    }
    if (!strncasecmp("udp://", url, 6)
        || !strncasecmp("igmp://", url, 7)) {
      return kOurScore;
    }
  • NuPlayer checks the URI scheme and creates different DataSource to receive media data. MulticastSource is added to handle multicast stream.
    In NuPlayer::setDataSourceAsync(), multicast shall be supported as below
	if (IsHTTPLiveURL(url)) {
	  … // new HTTPLiveSource
	} else if (!strncasecmp(url, "rtsp://", 7)) {
	  … // new RTSPSource
	}
	…
	else if (!strncasecmp(url, "udp://", 6)
	         || !strncasecmp("igmp://", url, 7)) {
	  source = new MulticastSource(notify, httpService, url, headers);
	}
	else {
	  … // Generic source
	}
  • MulticastSource inherits NuPlayer::Source and provide related functions. Basically it just handles events and pass all functions to MulticastSession, which is implemented in libstagefright.
libstagefright
  • Multicast socket related code shall be implemented to provide the socket interface.
  • MulticastSession uses the socket to receive media data, uses existing ATSParser to parse the TS stream, and extract so-called accessUnit to feed the decoder. It could be put at frameworks/av/media/libstagefright/multicast
    This class handles the main part of multicast playback.
  • MulticastDataSource is created by DataSource and used by MediaExtractor to extract the meta data of the media, e.g. whether it has video or audio, what the video resolution is, etc.
    This class is used in <video> tag playback, that webview will retrieve the media element’s metadata.
    Note: DataSource expects the media as static content, so it uses readAt(offset) to read the data from the source. But multicast is a stream, so MulticastDataSource shall be implemented carefully to provide the correct data with offset to DataSource.
  • DataSource shall be updated to create MulticastDataSource for multicast scheme.
	if (!strncasecmp("file://", uri, 7)) {
	  … // new FileSource
	} else if (!strncasecmp("http://", uri, 7)
	           || !strncasecmp("https://", uri, 8)
	           || isWidevine) {
	  … // new Http or Cache source
	} else if (!strncasecmp("data:", uri, 5)) {
	  … // new DataURISource
	} else if (!strncasecmp("igmp://", uri, 7)
	           || !strncasecmp("udp://", uri, 6)) {
	  source = new MulticastDataSource(uri);
	} else {
	  … // new FileSource
	}
chromium_org

By default, WebMediaPlayerAndroid does not support multicast scheme, and thus it treats the URI as a file and fails to load the media. WebMediaPlayerAndroid::load() shall be updated to support multicast scheme.

  if (url_.scheme() == "udp" || url_.scheme() == "igmp") {
    DVLOG(1) << "Do not load multicast";
    UpdateReadyState(WebMediaPlayer::ReadyStateHaveNothing);
    DidLoadMediaInfo(MediaInfoLoader::kOk, GURL(url), GURL(""), false);
    return;
  }
Gallery2

By default, Gallery2 does not handle multicast, and thus if an application sends a VIEW intent with multicast scheme, no application handles the intent and exception throws. AndroidManifest.xml shall be updated to support multicast scheme, so that it handles such VIEW intent.

            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="udp" />
                <data android:scheme="igmp" />
                <data android:mimeType="video/*" />
                <data android:mimeType="audio/*" />
             </intent-filter>

Conclusion

The above is a simplified introduction of the changes needed to support multicast playback in AOSP.
Google will probably not officially add such support, but some fork may be interested in multicast. This could be a start of the work.

Share

读书笔记(2015.6)

继续记录一下前段时间读的书

  • QED:光和物质的奇妙理论
    后悔现在才看到的,费曼的超级牛B的书。
    光是波?不对。光是粒子?不完全是。波粒二象性?不重要——
    这本书的第一讲就“轻描淡写”地把光子这么一个神奇的东西的*性质*讲得清清楚楚,计算概率就行了。
    第二讲,顺便把直觉上光是直线传播这一宏观上似乎是对的概念,重新解释了一下——光可以沿任何路径传播。不信?看它如何描述光栅的,就信了。
    第三讲开始加入了电子,内力大增,理解起来有点难度了——但是如果只看结论,却是清晰无比,得到结论的“推理”(或者说计算)过程也是一目了然。
    最后一讲看完,真心觉得费曼太牛了,能把量子电动力学这么一个高深的学科,讲得如此清晰易懂。
    用他的话说,“一个笨人能理解的东西,其他人也能理解”,虽然,我们只是在数石子而已。
    QED
  • 神们自己
    阿西莫夫的科幻小说,创意十足,无论是平行世界,还是平行世界里的智慧生物,都有基本的物理理论来支撑,所以看上去完全不觉得是“幻想”,反而很真实,很过瘾。
    The_Gods_Themselves
  • 未来边缘
    大刘的短篇小说集之一,收录了《天使时代》《2018年4月1日》《微纪元》《赡养上帝》《命运》,以前都在《科幻世界》里看过了,不过亚马逊上特价的时候还是收了。多年之后重看高中、大学时期看过的科幻短篇,调剂一下也不错。
    未来边缘
  • Doom启世录
    抱歉这本下了盗版。。。因为没有中文版卖。。。
    之前是听鸟哥说起了这本书,找了个电子版看了。印象中小学的时候在486电脑上玩过doom(不确定了),对于这类美式的游戏也不太感冒,就这么瞎看看翻完了,没有太多感觉。也许只有真正的粉丝才能从这本书里看到那个时代的激情吧。
    当然,必须得说卡马克这样的人还是非常佩服的。
    Doom启世录
  • 一网打尽:贝佐斯与亚马逊时代
    也是亚马逊特价的时候买的。之前其实不太关心亚马逊是怎么一步步从卖书开始变成最大的网上零售商的,买这本书更多的是想看看亚马逊是怎么从卖东西的,变成云计算、云服务的提供商。可惜这本书里没有答案。
    不过倒是看到一家电商如何地压榨供应商,压榨员工,为客户提供更低的价格和更好的服务。这在以前简直是不可想像的。幸而亚马逊发展起来了,国内的亚马逊,京东们也在往这个方向走着。而淘宝走在了另外一条路上。。。
    The_Everything_Store
Share