TV – 新的战场

Android 电视的发展非常出乎意料。生产内置 Android 系统电视机的厂商之多,价格下降速度之快,远胜 Android 在手机平台上的发展速度。如果从2007年 iPhone 发布算起,智能手机平台的竞争用了差不多4年才形成了一个明朗的局势, Android 只用了2年时间就在智能电视机领域的一家独大,这得要归功于2个方面:

1. 开源的 Android 。

制作 Android 的电机方案,虽然还是有一些硬件配适、UI调整和服务整合的工作,但这个平台无需准入审核,且整个操作系统的源码都公开了,这对于方案厂商实在是太方便了,负担也小很多,即使几个人的团队也能做。相对于前两年的 Linux 智能方案,这个平台更成熟,第三方应用等资源也更丰富。

2. 成熟的 ARM 方案:这是另一个出乎意料的地方,MIPS 在机顶盒领域有传统优势,2010年时就看到有 MIPS 芯片的 Android 电视机方案了,没成想去年到今年大量铺货的这些居然全是使用 ARM 处理器的。不过,仔细想想,经过这几年智能手机的飞速升级换代,基于 ARM 的成熟方案实在是太多太好找了,芯片供应商也多,价钱还便宜,Android 系统对 ARM 的支持也远较 MIPS 稳定(我们曾经将 RockPlayer 移植到 MIPS 上,但同一份代码,在两家厂商提供的工程样本上,一个会有指令错误,另一个跑得好好的,着实令人无语)。再看现在这些 Android 智能电视机,其实电视 和 Android 基本上是独立的,可以粗略的等同于,就是在电视机的基础上,另加了一块 ARM 板子跑 Android,这就更方便那些做惯 Android 手机硬件方案和ROM的人家转过来了。

同样瞄向电视机市场的 Google TV 问世也有一段时间了,却反应平淡。想想也是,这类盒子描向的是看似巨大的存量电视机市场,实则这类市场的其实极难激活,现有的电视内容已经很好的满足了这部分用户的需求。要想让这些用户有动力装个盒子,得要有不可替代的内容做为驱动,比如当初频道扩增器就卖得很火,又如广电用户如果不接受数字化改造就会陷入没节目看的悲惨境地。不幸的是,近几年的电视机,都可以轻松接个PC,而自带bt客户端、集成互联网视频资源的所谓高清播放机也已经极其便宜了,何况还有XBOX这类的娱乐主机也想分一杯羹。类似 Google TV 这种盒子,也没法接入传统的广播电视网,只是带来了互联网资源而已,着实看不出优势何在。所以想要在这存量市场里掘金,小打小闹或可,想要做成一个大产业则难,或许等到互联网内容已经能够取代传统广播式的频道内容,或者市场上已经没有非智能电视机,靠着用户习惯反向推动,这道路又何其漫长也。

对于 Android 智能电视机在 2013 年新出货量中的占比有种种预测,从 15% ~ 50% 不等,不过走向 Android 平台的趋势已经势不可挡。有心的平台层面令出机杼的,或许可以考虑一下定制 webOS ,同样是开源系统,毕竟做 Android ROM 或软硬件整体方案已经没有什么门槛可言,熟知 webOS 的人家倒还没多少;而智能电视机没有电池负累,家庭带宽也比手机强,更有利于云服务的推广,而 webOS 可以较好的利用 HTML5 开发者社区,也不用重头建设应用资源,还是有很大潜力的。

平台方面能玩的花样较少,但是电视机的操作体验、业务模式方面整个才起步,比之当年 AppStore 刚开张略强一点也有限。虽然大量的手机应用,稍改改就能放上去用,除去一些小工具,大部分都需要重新适应操作方式和用户心理。当用户坐在沙发上或躺在床上时,心态远比坐在PC前或操作手持设备时放松、休闲,现有的大部分应用还在照搬PC或手机平板的经验,这其中机会大把。另外,电视机是家庭共用的设备,针对家庭为单位的应用和服务,目前基本没有。

QNX’s problem 1: Mix C and C++ code.

It looks like some standard C header files like math.h in QNX toolchain contains C++ elements around by #ifdef __cplusplus preprocessor directives. That will bring some troubles when you need to mix C and C++ in one project.

Let’s see an example. Assume we have a C header file c.h and a C source file c.c, like below

c.h

#ifndef __C_H__
#define __C_H__
#include <stdint.h>
#include <math.h>
struct struct_c {
 int32_t dummy_field;
};
int func_c(struct struct_c * c);
#endif // __C_H__

c.c

#include <stdio.h>
extern "C" {
 #include "c.h"
}
int main()
{
 struct struct_c c;
 c.dummy_field = 1;
return printf("func_c() = %d\n", func_c(&c));
}

Compile them into a shared library libccc.so:

mbp17:qnx_header_test lee$ /Applications/bbndk/host_10_0_9_52/darwin/x86/usr/bin/ntoarmv7-gcc -c c.c
mbp17:qnx_header_test lee$ /Applications/bbndk/host_10_0_9_52/darwin/x86/usr/bin/ntoarmv7-gcc -shared c.o -o libccc.so
mbp17:qnx_header_test lee$ ls -l libccc.so
-rwxr-xr-x 1 lee staff 4725 11 1 11:36 libccc.so

That’s OK.

Now we have another C++ file named cc.cpp

#include <stdio.h>
extern "C" {
 #include "c.h"
}
int main()
{
 struct struct_c c;
 c.dummy_field = 1;
return printf("func_c() = %d\n", func_c(&c));
}

It is very simple. Let’s try to compile it. We got tons of errors! Some listed as below:

mbp17:qnx_header_test lee$ /Applications/bbndk/host_10_0_9_52/darwin/x86/usr/bin/ntoarmv7-g++ -c cc.cpp 2>&1 | more
In file included from /Applications/bbndk/target_10_0_9_386/qnx6//usr/include/math.h:4:0,
 from c.h:5,
 from cc.cpp:4:
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:116:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:150:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:157:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:163:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:200:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:207:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:212:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:218:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:224:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:229:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:234:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:239:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:245:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:251:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:256:1: error: template specialization with C linkage
I

Check error messages. Obviously math.h includes xtgmath.h internally. In latter some C++ template definitions are there around #ifdef __cplusplus directives. But in compiler’s view, though we wrapped #include “c.h” with extern “C” – it is necessary for linking, __cplusplus is still defined for C++ program. So, templates were incorrectly included into a pure C linkage enviroment.