Saturday, February 28, 2009

2. Draw a red block in c++


#define LOG_NDEBUG 0
#define LOG_TAG "NativeUITest"
#include <utils/Log.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>

#include <utils/IPCThreadState.h>
#include <utils/ProcessState.h>
#include <ui/SurfaceComposerClient.h>
#include <ui/Surface.h>
#include <ui/ISurfaceComposer.h>
#include "SkCanvas.h"
#include "SkDevice.h"

using namespace android;

static inline SkBitmap::Config convertPixelFormat(PixelFormat format)
{
/* note: if PIXEL_FORMAT_XRGB_8888 means that all alpha bytes are 0xFF,
then we can map to SkBitmap::kARGB_8888_Config, and optionally call
bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
*/
switch (format) {
case PIXEL_FORMAT_RGBA_8888: return SkBitmap::kARGB_8888_Config;
case PIXEL_FORMAT_RGBA_4444: return SkBitmap::kARGB_4444_Config;
case PIXEL_FORMAT_RGB_565: return SkBitmap::kRGB_565_Config;
case PIXEL_FORMAT_A_8: return SkBitmap::kA8_Config;
default: return SkBitmap::kNo_Config;
}
}

int main(int argc, char** argv)
{
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool();
int pid = getpid();
int nState = 0;
sp<SurfaceComposerClient> client = new SurfaceComposerClient;
sp<Surface> surface(client->createSurface(pid, 0, 176, 144, PIXEL_FORMAT_OPAQUE, ISurfaceComposer::eFXSurfaceNormal));

//set surface layer to INT_MAX
client->openTransaction();
//nState = surface->setSize(176, 144);
nState = surface->setPosition(100, 200);
nState = surface->setLayer(INT_MAX);
nState = surface->show();
client->closeTransaction();

//Start painting...
client->openTransaction();
Rect rect(0,0,176,144);
Region dirtyRegion(rect);
Surface::SurfaceInfo info;
status_t err = surface->lock(&info, &dirtyRegion);
if(err < 0)
{
client->closeTransaction();
IPCThreadState::self()->stopProcess();
return -1;
}
SkCanvas myCanvas;
SkCanvas* canvas = &myCanvas;
SkBitmap bitmap;
bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, info.bpr);
bitmap.setPixels(info.bits);
canvas->setBitmapDevice(bitmap);
canvas->clipRegion(dirtyRegion.toSkRegion());
int saveCount = canvas->save();
//paint hole
//canvas->drawColor(0, SkPorterDuff::kClear_Mode);
//paint a red block
canvas->drawARGB(255, 255, 0, 0);
canvas->restoreToCount(saveCount);
canvas->setBitmapDevice(SkBitmap());
nState = surface->unlockAndPost();
LOGI("surface->unlockAndPost, %d", nState);
client->closeTransaction();

sleep(10);
IPCThreadState::self()->stopProcess();
LOGI("quiting...");
return 0;
}

Thursday, February 26, 2009

Add syntax highlighter in Blogger

After adding syntax highlighter in my blog template, my previous blog looks much better now:)

Actually it's quite easy, just add following code snippet in the head section of blog template, right after <head> tag; then put <pre name='code' class='c++'>...</pre>around the code when you write blogs, everything will be ok:


<link href='http://syntaxhighlighter.googlecode.com/svn/trunk/Styles/SyntaxHighlighter.css' rel='stylesheet' type='text/css'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shCore.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushJava.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCpp.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushJScript.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushXml.js'/>
<script language='javascript'>
window.onload = function () {
dp.SyntaxHighlighter.ClipboardSwf = 'http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/clipboard.swf';
dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');
}
</script>
<style type='text/css'>
.console {
background-color: black;
color: #ffffff;
font-family: courier;
}
</style>

Note:
1) I directly link to the js scripts in google code here, you can upload them to your web spaces and replace them;
2) Other languages' syntax support is also available from there;
3) Replace < > with &lt; and &gt; when you composite the blog.

Reference:
[1] SyntaxHighlighter Usage
[2] Blogger + SyntaxHighlighter

Tuesday, February 24, 2009

1. Native console app for video playback in Android

I spent some time for writing a native C++  app to test video in console, actually it seems to be much easier than I thought:) Below is the code snippet:

PS. I thought I should paint a hole above video surface as SurfaceView does, but it appears not necessary.


int main(int argc, char** argv)
{
LOGI("entering main...");
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool();
MediaPlayer mediaplayer;
if(argc > 1)
{
LOGI("set datasource: %s", argv[1]);
mediaplayer.setDataSource(argv[1]);
}
else
{
LOGI("set datasource: /data/test.mp4");
mediaplayer.setDataSource("/data/test.mp4");
}

LOGI("create SurfaceComposerClient");
int pid = getpid();
int nState = 0;
sp<SurfaceComposerClient> videoClient = new SurfaceComposerClient;

LOGI("create video surface");
sp<surface> videoSurface(videoClient->createSurface(pid, 0, 176, 144, PIXEL_FORMAT_OPAQUE, ISurfaceComposer::eFXSurfaceNormal|ISurfaceComposer::ePushBuffers));
videoClient->openTransaction();
//nState = videoSurface->setSize(176, 144);
//LOGI("videosurface->setSize, %d", nState);
//nState = videoSurface->setPosition(0, 0);
//LOGI("videosurface->setPosition, %d", nState);

//set toppest z-order
nState = videoSurface->setLayer(INT_MAX);
LOGI("videosurface->setLayer, %d", nState);
nState = videoSurface->show();
LOGI("videosurface->show, %d", nState);
videoClient->closeTransaction();

LOGI("set video surface to player");
mediaplayer.setVideoSurface(videoSurface);

status_t retCode = mediaplayer.prepare();
if(retCode < 0)
{
LOGE("prepare failed: %d\n", retCode);
IPCThreadState::self()->stopProcess();
return -1;
};

mediaplayer.start();
for(int i=0; i < 10; i++)
{
sleep(1);
LOGI("playing, i=%d\n", i);
}
mediaplayer.reset();
LOGI("quiting...");

//close binder fd, still need waiting for all binder threads exit?
IPCThreadState::self()->stopProcess();
return 0;
}

Android

It has been nearly 4 months since my employer changed its strategy to Android platform. As I am getting familiar with the new platform, I will record related tips I've learned in the blog:) And i hope it can also be helpful for others when its content gets richer...