Just another Adobe Blogs site

Archive for September, 2006

As we draw closer to an anticipated beta release of the Flash Player, we thought people might be interested in knowing what libraries their host systems will be expected to provide for the Player. We have boiled it down to this list:

libdl.so.2

libpthread.so.0

libX11.so.6

libXext.so.6

libXt.so.6

libfreetype.so.6

libfontconfig.so.1

libgtk-x11-2.0.so.0

libgobject-2.0.so.0

libglib-2.0.so.0

libm.so.6

libc.so.6

If the library loader cannot find any of the above libraries then the plugin will refuse to load and the user will continue to see the dreaded green puzzle piece in place of a bouncing animation.

There are 2 more optional libraries: libasound.so (for ALSA audio I/O) and libssl.so (for certain SSL connections). If either library is not present, its representative features will be disabled.

To clarify:

Question: What if I do not have ALSA — the standard Linux audio API — on my system?

What could possibly be so difficult about porting the Flash Player to Linux?

I’m glad you asked.

The executive summary of what follows would probably be: ensuring that a single plugin binary functions on the widest diversity of Linux/x86 distributions within reason. Read on for the details.

First, we take the existing Flash Player 7 Linux code along with the current revision of the main Player codebase, modify the Linux-specific stuff as needed, and get the plugin to compile in the first place. Then we upgrade the Linux-specific parts to take advantage of all the latest v8 and v9 features. Which APIs to use? That has already been covered in copious detail throughout previous posts.

While we have the plugin limping along on our development machines, there comes a point where we need to hand off builds to our QA team for testing. This is when we notice that the plugin works great on our dev boxes, but hardly or not at all on any other distributions. Generally, the problem is libraries, libraries, libraries. For example, the player dynamically opens libasound.so to dig out the ALSA audio functions. I recently learned that the ‘libasound.so’ symlink is only available on systems with the right devel packages installed. The proper file to open is ‘libasound.so.2′. Hopefully. Repeat for the rest of the dynamic library loads.

Things get more painful when the plugin refuses to load. The first line of debugging is the ‘ldd’ utility to see if the plugin is finding all of the libraries it wants on its new host system. A major problem has been that the plugin wants to find libstdc++.so.6. Certain older Linux systems that we are trying to support only have libstdc++.so.5. This is not something we can plausibly dynamically load at runtime as in the case of libasound.so.2. This is why I wanted to know how to statically link libstdc++.so.6 with the main binary– larger distro range.

Many thanks to participants on the Automake mailing list as well as my contacts at Red Hat, we actually figured out how to do this (it has to do with the way to toolchain is built vs. specific project built options).

Next problem: The plugin does not load on stock Fedora Core 5 or 6 systems. All the libraries are present and resolving this time. So what’s going on? These systems come “hardened” from the start and they don’t like binaries that contain something called text relocations (“textrels”). These textrels are caused by 2 things in this case:

statically linking libstdc++.so.6

manual assembly language optimizations

For number 1, we embarked on a new adventure to build a super-special custom toolchain that builds libstdc++.so.6 just right so that it can be static linked with the plugin without those nagging textrels. The ASM optimization bits are giving us some problems but Tinic thinks he has a way to make those functions play ball in order to create a fast binary. So now the plugin works on hardened Linux or SELinux or whatever the right buzzword is; it works with a Linux distro that uses the security feature of randomizing a program’s base address.

The word came down last week that I was to prepare a demo for yesterday’s Flashforward keynote. They gave me an IBM ThinkPad laptop and told me to install Linux and the current Flash Player onto the machine. I had a better brainstorm– something I keep hearing about called a live CD. So I set out to make my own custom live CD that was already equipped with Flash Player 9. The final CD was able to boot on both an IBM ThinkPad and an Intel-based MacBook and was a much better answer to the question, “What if we need to run the demo on a different machine instead?”

It took me a little while to customize the live CD. Previously, my only encounter with live CDs had only been a “Remastering Knoppix” session at a Linux user group. I couldn’t find good instructions for doing the same when I needed, particularly on a different type of system (Gentoo in my case). As a public service, I thought I would post the hackish instructions that I pieced together from various sources which led me to create the perfect live CD for this demo. The basic idea is to:

unpack the ISO-9660 filesystem

unpack the root squash filesystem

modify the root squash filesystem

re-pack the root squash filesystem

re-pack ISO-9660 filesystem

So it’s not unlike peeling an onion, deep frying it, and putting it back together– not a perfect or elegant process but the end result is much tastier! These are the technical steps:

the stock live CD comes with Windows installers for various free software packages like Firefox and Thunderbird; if you don’t need these on your live CD, you can save over 30 MB by deleting the programs/ directory

Did you get to attend the Flashforward conference in Austin, Texas, USA? If you did, you got to see the first public demonstration of Flash Player 9 running on Linux. Check this entry in the Flashforward blog for a photo (albeit backwards) depicting Adobe Flash Player 9 running in Firefox on a laptop running Ubuntu. The demo site shown is the designed-for-Flash-8 Nike Air site.

Update:Mike Downey came through with some slightly higher quality photos of the presentation, including this one:

On this and other forums, many participants put forth a plethora of possible solutions. Thing is, a lot of these solutions solve problems that we don’t have. I present herewith some of the problems that are quite solved already.

Rasterization: This refers to painting all of the graphical objects onto a video frame to prepare it for presentation. The core Flash engine takes care of this. It has performed this duty faithfully since Flash 1, a.k.a. FutureSplash. No need to delegate this task to an external library.

Audio/Video Synchronization: This is also something that the core Flash Player worries about, believe it or not. The notorious A/V sync problems with Player 7 on Linux were not a result of some fundamental inability of the Player to maintain sync.

Audio Output: Perhaps I tend towards oversimplification, but audio output is a matter of building an array of PCM samples and shoving them out to a kernel-abstracted DAC device. In Linux, the official way to do that is with ALSA.

Audio Mixing: Similar to rasterization, the Flash core has been mixing its own sounds for years. No need to sub-contract that to a third party library or “framework” that may or may not perform the task as precisely intended.

There are still plenty of fascinating problems involved in making the official Flash Player run well on Linux (Tinic writes of one we just discovered). The problems listed above are not among them.

Here is a curious problem: static linking standard C++ libraries into an executable binary. It is something that I have figured out how to do with a manually constructed link command. But I would really like to know if it’s possible to ask an autotools-based build environment to do the same thing. This is an interesting circumstance since a Linux developer does not usually need to be bothered with such matters; the build tools (autotools, in this case) just make the right build decisions depending on the host system. The build process for many software packages causes the software to ‘nest’ into the host system. Flash Player is different and I have a need to force this particular build decision.

Is there a setting in autoconf/automake and friends to ask the toolset to static link libstdc++? My searches on this matter have been fruitless, though some have alleged that there are projects out there that need to do this. Alternatively, I might be willing to evaluate other build systems (I often hear that SCons and CMake are leading contenders in this field) if they can fulfill this requirement, in addition to some other requirements (all quite reasonable):

automatically keep track of dependencies

manage multiple build targets

create multiple build configurations in separate directories, working from the same source tree

PS: To re-iterate a running theme on this blog, Adobe is not open sourcing the Player at this time. So please do not propose that as a possible solution to this quandary.