Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Dr.Dobb's journal.2006.03

.pdf
Скачиваний:
20
Добавлен:
23.08.2013
Размер:
928.95 Кб
Скачать

#382 MARCH 2006

Dr.DobbsSOFTWARE

TOOLS FOR THE

PROFESSIONAL

J O U R N A L PROGRAMMER

http://www.ddj.com

INTELLIGENT SYSTEMS

Resource-Aware Mobile Devices

Real-Time Stereoscopic Video Streaming

Getting Personal with Java’s PIM API

Keeping C/C++ Code Scalable

Michael Swaine

Debugging and

Steps Outside

The Box

Embedded Linux Runtime Environments

 

Ed Nisley on

More Summer of Code

 

 

 

 

Engineering &

 

 

 

 

Professionalism

 

 

 

 

 

Book Reviews

 

 

 

 

 

Perl,

Themes,

Performance,

Skins, &

PHP, & More

ASP.NET 2.0

C O N T E

F E A T U R E S

Resource-Aware Mobile Device Applications 10

by Hari Gopal

Smart-client applications need to be constantly aware of the changing status of the constrained devices resources.

Real-Time Stereoscopic Video Streaming 18

by Karen McMenemy & Stuart Ferguson

Our authors examine real-time virtual reality by showing you how to use DirectX and OpenGL to build a stereoscopic webcam.

Getting Personal with J2ME’s PIM API 23

by Tom Thompson

J2ME, the Java platform for portable devices, doesn’t allow access to a device’s address book. The JSR 75 Personal Information Management and JSR 75 FileConnection packages change all this.

Keeping C/C++ Code Scalable 28

by Kirk J. Krauss

Kirk presents techniques for identifying committed virtual address space in C/C++ programs.

Themes, Skins, and ASP.NET 2.0 36

by Vikram Srivatsa

In ASP.NET 2.0, a Theme is a way of defining the look-and-feel for server controls in web applications.

Debugging & Embedded Linux Runtime Environments 40

by Rajesh Mishra

Debugging in embedded Linux runtime environments requires an assortment of tools.

Google’s Summer of Code: Part IV 44

by DDJ Staff & Friends

Google’s Summer of Code resulted in thousands of lines of code. Here are more students who participated.

C O L U M N S

Programming Paradigms 46 by Michael Swaine

Embedded Space 49 by Ed Nisley

Programmer’s Bookshelf 53

Gregory V. Wilson

F O R U M

EDITORIAL 6

SWAINE’S FLAMES 56

by Jonathan Erickson

by Michael Swaine

OF INTEREST 55

NEXT MONTH: April is all about

by DDJ Staff

Algorithms — and we announce

PRAGMATIC EXCEPTIONS 50

this year’s recipient of the

Dr. Dobb’s Journal Excellence

by Benjamin Booth

in Programming Award.

N

T

S

MARCH 2006 VOLUME 31, ISSUE 3

 

 

 

O N L I N E E X C L U S I V E S

http://www.ddj.com/exclusives/

Beyond SOA Governance

Brent Carlson looks at why SOA governance has become a hot topic in industry discussions.

D O B B S C A S T A U D I O

http://www.ddj.com/podcast/

Visual Studio 2005: A Developer’s Perspective

Matthew Etter likes what he sees with VS 2005. Here’s why.

Assessing the VB6 Assessment Tool

Federico Zoufaly promotes automated migration to .NET instead of rewriting to retain significant investments in legacy apps.

D O T N E T J U N K I E S

http://www.dotnetjunkies.com/

Highlighting Multiple Search Keywords in ASP.NET

Here’s a technique for highlighting multiple key words no matter where they were in the text.

B Y T E . C O M

http://www.byte.com/

Dynamic Plug-In Linking, Loading, and Dispatching with Ada 2005

Statically typed, statically built, object-oriented languages such as Ada can make full use of the notion of dynamic plug-ins.

T H E N E W S S H O W

http://thenewsshow.tv/

2006 Priorities

Bob Evans looks at what IT priorities are for 2006.

U N I X R E V I E W . C O M

http://www.unixreview.com

Security: Forensic Tools in Court

Will open-source forensic tools be considered valid when you go to court?

RESOURCE CENTER As a service to our readers, source code, related files, and author guidelines are available at http://www.ddj.com/. Letters to the editor, article proposals and submissions, and inquiries should be sent to editors@ddj.com. For subscription questions, call 800-456-1215 (U.S. or Canada). For all other countries, call 902-563-4753 or fax 902-563-4807. E-mail subscription questions to ddj@neodata.com, or write to Dr. Dobb’s Journal, P.O. Box 56188, Boulder, CO 80322-6188. If you want to change the information you receive from CMP and others about products and services, go to http://www.cmp.com/feedback/permission.html or contact Customer Service at Dr. Dobb’s Journal, P.O. Box 56188, Boulder, CO 80322-6188.

Back issues may be purchased prepaid for $9.00 per copy (which includes shipping and handling). For issue availability, send e-mail to orders@cmp.com, fax to 785-838-7566, or call 800-444-4881 (U.S. and Canada) or 785-838-7500 (all other countries). Please send payment to Dr. Dobb’s Journal, 4601 West 6th Street, Suite B, Lawrence, KS 66049-4189. Digital versions of back issues and individual articles can be purchased electronically at http://www.ddj.com/.

WEB SITE ACCOUNT ACTIVATION Dr. Dobb’s Journal subscriptions include full access to the CMP Developer Network web sites. To activate your account, register at http://www.ddj.com/registration/ using the web ALL ACCESS subscriber code located on your mailing label.

DR. DOBB’S JOURNAL (ISSN 1044-789X) is published monthly by CMP Media LLC., 600 Harrison Street, San Francisco, CA 94017; 415-947-6000. Periodicals Postage Paid at San Francisco and at additional mailing offices. SUBSCRIPTION: $34.95 for 1 year; $69.90 for 2 years. International orders must be prepaid. Payment may be made via Mastercard, Visa, or American Express; or via U.S. funds drawn on a U.S. bank. Canada and Mexico: $45.00 per year. All other foreign: $70.00 per year. U.K. subscribers contact Jill Sutcliffe at Parkway Gordon 01-49-1875-386. POSTMASTER: Send address changes to Dr. Dobb’s Journal, P.O. Box 56188, Boulder, CO 80328-6188. Registered for GST as CMP Media LLC, GST #13288078, Customer #2116057, Agreement #40011901. INTERNATIONAL NEWSSTAND DISTRIBUTOR: Source Interlink International, 27500 Riverview Center Blvd., Suite 400, Bonita Springs, FL 34134, 239-949-4450. Entire contents © 2006 CMP Media LLC.

Dr. Dobb’s Journal is a registered trademark of CMP Media LLC. All rights reserved.

http://www.ddj.com

Dr. Dobb’s Journal, March 2006

5

E D I T O R I A L

AI:

50 Years Young

Anniversaries come and go, sometimes with fanfare, often times unnoticed. Take, for instance, “artificial intelligence.” It’s hard to believe, but this year marks the 50th anniversary of the term — and the discipline — of AI. It was in 1956 that John McCarthy, Marvin Minsky (who

along with McCarthy founded MIT’s AI lab), IBM’s Nathaniel Rochester, and Bell Lab’s C.E. Shannon presented “A Proposal for the Dartmouth Summer Research Project on Artificial Intelligence” at the Dartmouth Artificial Intelligence Conference (http://www-formal.stanford.edu/jmc/history/ dartmouth/dartmouth.html). The conference and the project, convened with the goal of creating truly intelligent machines, established AI as a unique field of study within computer science.

AI immediately leaped to the forefront in academic, research, and commercial communities. AIcentric programming languages sprang up, with more than 25 commercial implementations of Prolog and nearly 20 implementations of Lisp. Companies such as Texas Instruments, Intel, and Apple waded into the fray with hardware-based AI solutions. All in all, real progress was made in robotics, machine vision, mechanical manipulation, advanced automation, and computational geometry, at least according to Minsky and Seymour Papert in their “Progress Report on Artificial Intelligence” (http://web.media.mit.edu/~minsky/papers/PR1971.html). Yes indeed. AI’s future looked rosy— then it all seemed to fall apart.

For reasons ranging from unfulfilled promises to unreturned investments, AI became a four-letter word in the late 1980s. Overnight, it seemed, the sure way to kill a product or bankrupt a company was to tag them as “artificial intelligence,” and AI bashing became the sport du jour in the Wall Street Journal and Forbes. Even Minsky jumped on the AI-bashing bandwagon, bluntly stating in a 2003 Boston University speech that “AI has been brain-dead since the 1970s.” He went on to accuse researchers of throwing in the towel when it comes to building fully autonomous, intelligent machines. In particular, Minsky singled out the expert system community, which, he said, was reinventing the wheel every time a new problem was encountered. The problem, said Minsky, was that expert systems (and the experts behind them) were neglecting “common-sense reasoning,” in which computers can grasp the everyday assumptions that we take for granted.

Well, most researchers anyway. Minsky did point to one bright spot — Cycorp (https://www.cyc

.com/). The Cycorp Cyc Knowledge Server is a large, multicontextual knowledge base and inference engine with more than one million assertions (rules) in a common-sense knowledge base. Because it is based on common sense, Cyc knows that “trees are usually outdoors, that once people die they stop buying things, and that glasses of liquid should be carried right-side up.” Cyc can also handle natural-language queries so that users can ask for “photos of strong and daring men” and a photo of a man climbing a cliff pops up.

Today, Cycorp’s goal is to break the “software brittleness bottleneck” by building a foundation of basic common-sense knowledge in applications ranging from e-commerce and machine translation, to speech recognition and games. To enable this, Cycorp built a knowledge base, inference engine, the CycL programming language, natural-language-processing subsystem, the Cyc semantic integration bus, and various Cyc developer toolsets. Additionally, an open-source version of Cyc is freely available (http://sourceforge.net/projects/opencyc/).

Still, Cycorp isn’t the only intelligent systems game in town. Franz’s Allegro Common Lisp is now in Release 8, and is routinely used in video games, data mining, bioinformatics, modeling and simulation, and the like. Then there’s the neural-net application written by Oklahoma State University’s Ramesh Sharda, which predicts a movie’s success or failure in the marketplace based on rules weighing a movie’s cast, genre, competition, special effects, and the like. Other mission-critical applications include robotic jockeys competing in camel races across the Sahara (http://www

.uaeinteract.com/news/), the Intellibuddy chatbot (http://www.intellibuddy.com/), and Marion “Tank” LeFleur, the roboreceptionist with an attitude in the lobby at Carnegie Mellon University (http://roboceptionist.com/).

Kidding aside, the successful completion of Stanford University’s robotic vehicle “Stanley” (a 2004 Volkswagen Touareg) in DARPA’s Grand Challenge — a 128-mile race across the Mojave Desert — was a major step forward that involved significant progress across a wide range of AI technologies (http://devnet.developerpipeline.com/documents/s=9903/ddj051010pc/). Moreover, as David Israel, Program Director at SRI’s Artificial Intelligence Center (http://www.ai.sri.com/) points out, DARPA continues strong funding of AI-related efforts through its Information Processing Technologies Office, while in the private sector, companies such as Google, Microsoft, and Yahoo are deeply involved with serious AI research.

So from all appearances, AI— cognitive computing, machine learning, decision support or whatever name it goes by— is alive and kicking. From that perspective, AI sounds like it’s 50 years young, instead of 50 years old.

Jonathan Erickson editor-in-chief jerickson@ddj.com

6

Dr. Dobb’s Journal, March 2006

http://www.ddj.com

Dr.DobbsSOFTWARE

TOOLS FOR THE

PROFESSIONAL

J O U

R N A L

 

PROGRAMMER

 

 

 

 

 

 

P U B L I S H E R

E D I T O R - I N - C H I E F

Michael Goodman

 

Jonathan Erickson

E D I T O R I A L

MANAGING EDITOR

Deirdre Blake

SENIOR PRODUCTION EDITOR

Monica E. Berg

EXECUTIVE EDITOR

Kevin Carlson

MANAGING EDITOR, SPECIAL PROJECTS

Della Wyser

COPY EDITOR

Amy Stephens

ART DIRECTOR

Margaret A. Anderson

SENIOR CONTRIBUTING EDITOR

Al Stevens

CONTRIBUTING EDITORS

Bruce Schneier, Ray Duncan, Jack Woehr, Jon Bentley,

Tim Kientzle, Gregory V. Wilson, Mark Nelson, Ed Nisley,

Jerry Pournelle, Dennis E. Shasha

EDITOR-AT-LARGE

Michael Swaine

PRODUCTION MANAGER

Stephanie Fung

I N T E R N E T O P E R A T I O N S

DIRECTOR

Michael Calderon

SENIOR WEB DEVELOPER

Steve Goyette

WEBMASTERS

Sean Coady, Joe Lucca

A U D I E N C E D E V E L O P M E N T

AUDIENCE DEVELOPMENT DIRECTOR

Kevin Regan

AUDIENCE DEVELOPMENT MANAGER

Karina Medina

AUDIENCE DEVELOPMENT ASSISTANT MANAGER

Shomari Hines

AUDIENCE DEVELOPMENT ASSISTANT

Andrea Abidor

M A R K E T I N G / A D V E R T I S I N G

ASSOCIATE PUBLISHER

Will Wise

SENIOR MANAGERS, MEDIA PROGRAMS see page 54

Pauline Beall, Michael Beasley, Cassandra Clark, Ron Cordek, Mike Kelleher, Andrew Mintz

MARKETING DIRECTOR

Jessica Marty

SENIOR ART DIRECTOR OF MARKETING

Carey Perez

DR. DOBB’S JOURNAL

2800 Campus Drive, San Mateo, CA 94403

650-513-4300. http://www.ddj.com/

CMP MEDIA LLC

Steve Weitzner President and CEO

John Day Executive Vice President and CFO

Jeff Patterson Executive Vice President, Corporate Sales and Marketing

Bill Amstutz Senior Vice President, Audience Marketing and Development

Mike Azzara Senior Vice President, Internet Business Joseph Braue Senior Vice President, CMP Integrated Marketing Solutions

Sandra Grayson Senior Vice President and General Counsel

Anne Marie Miller Senior Vice President, Corporate Sales Marie Myers Senior Vice President, Manufacturing Alexandra Raine Senior Vice President, Communications Kate Spellman Senior Vice President, Corporate Marketing Michael Zane Vice President, Audience Development Robert Faletra President, Channel Group

Tony Keefe President, CMP Entertainment Media Vicki Masseria President, CMP Healthcare Media

Philip Chapnick Senior Vice President, Group Director, Applied Technologies Group

Paul Miller Senior Vice President, Group Director, Electronics and Software Groups

Fritz Nelson Senior Vice President, Group Director, Enterprise Group

Stephen Saunders Senior Vice President, Group Director, Communications Group

Printed in the USA

American Buisness Press

8

Dr. Dobb’s Journal, March 2006

http://www.ddj.com

Resource-Aware Mobile

Device Applications

Smart clients know their limitations

HARI GOPAL

Smart clients that work offline when in disconnected mode, but seamlessly synchronize with the enterprise back end when connected, are gaining in popularity. The challenges in making this possible, however, involve issues such as con-

strained memory, limited battery power, and intermittent network connectivity. Consequently, designing smart clients for mobile devices that can dynamically and intelligently adapt their behavior based on the changing status of the constrained resources is critical to success. For example, a well-designed smart client should sense the network connectivity status and adapt its behavior accordingly, either by connecting to a network resource or a local resource hosted on the device. Similarly, a smart client should monitor available memory on the device, initiate a synchronization session with a back-end data store, and free device memory under low-memory availability. Likewise, on sensing short battery life, smart clients should disable some of their power-draining features, such as network connectivity.

Displaying intelligence such as this requires that smart clients be aware of the changing context (status) of the device’s available resources. The direct way of embedding this intelligence into clients involves using underlying API calls, either constantly or periodically. However, a more elegant way involves notifying clients regularly about the dynamic resource context via asynchronous callback mechanisms. An asynchronous notification mechanism such as this helps you write code for listeners at a single place that handles the changing resource context, making the design more clean and maintainable.

In this article, I present ResourceMonitor, a resource status monitoring component for the .NET Compact Framework, and show how you can use it to develop resource-aware, smartclient applications for Pocket PC devices.

Component Requirements and Design

Windows CE provides unmanaged, low-level APIs to get the device memory, power, and network connectivity status. There is no direct managed .NET Compact Framework API available for this functionality, and you are required to use the limited P/Invoke capabilities of the .NET Compact Framework to call the underlying native APIs from managed code. In addition to presenting an asynchronous callback mechanism, ResourceMonitor provides a managed API to determine the status of device resources.

Hari is a technical architect for Infosys Technologies Limited. He can be contacted at harigopal_ponnapalli@infosys.com.

Windows CE supports several notifications for changing application resource status. To the best of my knowledge, however, the thresholds for deciding the changing status are predetermined by Windows CE, and you cannot define/control what is low battery or low memory for specific applications. ResourceMonitor is designed to give you this flexibility.

“Windows CE provides unmanaged, low-level APIs to get the device memory, power, and network connectivity status”

To make ResourceMonitor flexible, configurable, and powerful, I had several requirements:

ResourceMonitor should be developed as a managed .NET Compact Framework class library. Application developers using ResourceMonitor should be shielded from learning the nuances of calling native API features using P/Invoke.

ResourceMonitor should monitor and notify the status of network connectivity, battery power, and device memory.

ResourceMonitor should support an asynchronous callback mechanism that notifies the client of the changing status of the resources.

Application developers should be able to configure, both statically and dynamically, the resources to be monitored by ResourceMonitor. For example, in a specific case, you can choose to monitor only network connectivity initially, and later update ResourceMonitor dynamically to monitor memory and battery also.

Application developers should be able to configure the frequency of the notifications. However, the callback events will be raised only when there is a change in the resource status.

ResourceMonitor should provide the facility to dynamically start and stop the notifications.

In ResourceMonitor, the CMemoryInfo, CBatteryInfo, and CNetworkInfo types provide abstractions to Memory, Battery, and

10

Dr. Dobb’s Journal, March 2006

http://www.ddj.com

(continued from page 10)

Network resources, respectively, and can be used independently to determine the resource status. ICommonEvents is the interface that declares all callback events supported by ResourceMonitor. CResourceMonitor is the main class that initiates a background thread, which monitors the status of the configured resources at the configured frequency. Smart clients interested in receiving resource notifications must implement this interface and register that object with CResourceMonitor.

Monitoring Battery Power

For the most part, mobile devices are battery-powered devices with limited battery life. Typical battery life ranges from a few hours to a few days. Computationally intensive tasks such as network access, looping conditions, and the like, consume more power. Consequently, we design smart clients that adapt our behavior, based on device power status. Windows CE provides native API function calls to determine the device power status —GetSystemPowerStatusEx and GetSystemPowerStatusEx2. Each function fills a structure SYSTEM_POWER_STATUS_EX and SYSTEM_POWER_STATUS_EX2, respectively, supplied to them. ResourceMonitor uses SYSTEM_POWER_STATUS_EX2.

The CBatteryInfo class is a managed wrapper that internally uses P/Invoke to determine the power status, but exposes only important power characteristics as public methods. Some of this supported functionality includes determining battery status, battery life, AC power status, and the like. You can directly instantiate this class to determine the device power status. Listing One shows how you use CBatteryInfo directly (without callbacks) to determine the device power status in the .NET Compact Framework.

Monitoring Memory

Handheld devices come with limited memory that’s insufficient for storing enterprise application data. Thus, the traditional handheld applications are based on a thin-client paradigm, which assumes “always connectivity.” With advancements in mobile hardware technologies, however, today’s devices have more memory (32 to 64 MB of RAM), as well as facilities to add more memory if necessary (via Compact Flash). This advancement in memory capabilities of small devices lets enterprise mobile application architects design solutions that can host the required enterprise data on the device itself. This memory capability is the key enabler of smart-client applications because this means that the applications need not always be connected. In addition, it means that data created and hosted locally on devices can be synchronized with the enterprise back end when the network is available. In short, effective designs of smart-client applications dictates that applications be aware of available memory on the device.

Windows CE provides GlobalMemoryStatus, a native function to determine memory status, and the MEMORYSTATUS structure, which holds memory status characteristics. The CMemoryInfo class is a managed wrapper that internally uses P/Invoke to determine the memory status, but exposes only important memory characteristics as public methods. Some of the functionality includes determining total memory, available memory, and the like. You can directly instantiate this class to determine the device memory status. Listing Two shows using CMemoryInfo directly (without callbacks) to determine the device-memory status in the .NET Compact Framework.

Monitoring Network Availability Status

Wireless is the only possible communication mechanism for handhelds for remote connectivity from the field. But again, wireless connectivity in handhelds is intermittent because of network outage, low-battery power, and the like. Well-designed

mobile applications should adapt their behavior seamlessly and work smoothly, even when they are turned offline. Network status can be determined using either the native Windows CE API calls or the System.Net managed assembly. ResourceMonitor uses System.Net library calls of the .NET Compact Framework. One prominent technique to determine the network availability status is to determine the IP address of the host (device). For instance, if the IP address is 127.0.0.1 (localhost), the network is not available. Any address other than 127.0.0.1 can be treated as the condition where the network is available. The static

GetHostByName function of the System.Net.Dns class is used to determine the current IP address of the host. (See the .NET Compact Framework documentation for more information about the System.Net.Dns API.)

If the network available status is True (that is, the host is assigned an address other than 127.0.0.1), it doesn’t necessarily mean that the application will successfully make a network connection. Applications can still fail to make connections with network servers for any number of reasons. Consequently, applications must support error handling, depending on the underlying transport protocol.

The CNetworkInfo class provides methods to determine the network availability status and the host IP address. Listing Three uses CNetworkInfo directly (without callbacks) to determine the network connectivity status in the .NET Compact Framework.

Callback Mechanism

While the resource status can be determined directly by using the System.Net library, a more elegant, programmer-friendly, and reusable way of implementing this is through asynchronous notifications. This mechanism lets you write the logic related to handling the changing resource status at a single place in event handlers, which is invoked only when there is a change in the status of the resource being monitored.

One way of implementing this application-level event notification in .NET is via a callback mechanism. Another way is through the use of delegate functions as defined in the .NET Framework. ResourceMonitor uses the first approach and implements notifications through callbacks.

ICommonEvents, the interface that defines all ResourceMonitor events, contains declarations for all memory, power, and network status-related events. Typically, events are raised only when there is a change in resource status; for instance, power turning from high to low, network availability status changes, and so on. You must implement a class that provides an implementation of this interface, and register an instance of it with ResourceMonitor to receive notifications. This way, you have the flexibility to implement only those events in which the application is interested. You should provide a default null implementation for event methods that are not required. Events supported by this interface include battery events, memory events, and network events; see Table 1.

CResourceMonitor is the main class that provides the callback notification mechanism. This class starts a background thread that runs when the ResourceMonitor component instance is created. This thread polls the resource status at configured intervals and provides callback notifications to the application whenever there is a change in the resource status. It provides options to statically (at the time of instance creation) and dynamically change the background thread polling interval, resources to be monitored, and the like. This lets you tune the scheduling of background threads appropriately so as not to burden the processor. ResourceMonitor also lets applications monitor application-specific memory and battery values. For example, an application can specify that events be raised when the available memory crosses, say, 60 percent and battery memory left crosses 40 percent.

12

Dr. Dobb’s Journal, March 2006

http://www.ddj.com

Event

Description

(a)

 

BatteryTurnedCriticalEvent

Triggered when the percent of battery left on device

 

turns critical from low when not on AC power.

BatteryTurnedLowEvent

Triggered when the percent of battery left on device

 

turns low from high when device is not on AC power,

 

or changed to low from critical when device is charging.

BatteryTurnedHighEvent

Triggered when percent of battery left on device turns

 

high from low while charging, or from fully charged to

 

high when not on AC power.

BatteryTurnedBelowCfgEvent

Triggered when percent of battery left on device falls

 

below the application configured value.

BatteryTurnedAboveCfgEvent

Triggered when percent of battery left on device crosses

 

above the application configured value.

BatteryFullyChargedEvent

Triggered when the battery status changes to fully

 

charged while charging.

BatteryTurnedChargingEvent

Triggered immediately when the device is connected on

 

AC power for charging.

BatteryStatusUnknownEven

Triggered when the device battery status is not known.

(b)

 

MemoryTurnedAboveCfgEvent Triggered when the percent of available memory on

 

device crosses above the application configured value.

MemoryTurnedBelowCfgEvent Triggered when the percent of available memory on

(c)

device falls below the application configured value.

 

NetworkStatusChangedEvent

Triggered when network connectivity status changes

 

from available to unavailable and vice versa.

 

 

Table 1: (a) Battery events; (b) memory events; (c) network events.

(continued from page 12)

The CResourceMonitor class provides a public constructor that takes an application-specific implementation of ICommonEvents object, polling interval, and the resource-monitoring options. The SetPollingInterval method lets applications set the polling interval to seconds. This method can be used to dynamically change the polling interval. The SetMonitorOption method lets applications change the resources to be monitored. SetCfgBValue takes an integer parameter that sets the percent of remaining battery life to be monitored. Similarly, SetCfgMValue lets applications specify the percent of available memory to be monitored. The StopThread function stops the background thread and allows applications to choose not to receive further notifications. StartCallback starts the background thread and lets applications start receiving callback notifications.

I’ve included an application (available electronically; see “Resource Center,” page 5) that demonstrates how the different configuration options of ResourceMonitor can be adjusted. This test application lets users interact with the program, and change the resource-monitoring options, polling interval, and battery and memory percent values.

Conclusion

Well-behaving, smart-client applications require that the application be constantly aware of the changing status of the constrained devices resources. Currently, you have to use lowlevel APIs to determine the resource status. The .NET Compact Framework does not expose any managed API to extract these features, and mandates use of the P/Invoke (platform invoke) features of the .NET Compact Framework.

Acknowledgments

Thanks to Rama Krishna for providing implementation support for this component in the .NET Compact Framework; Puneet Gupta and Abdul Sakib Mondal of Infosys Technologies Limited for their feedback.

DDJ

(Listings begin on page 16.)

14

Dr. Dobb’s Journal, March 2006

http://www.ddj.com

Listing One

(a) Visual Basic

Imports Infosys.PervasiveIT.ResourceMonitor

...

Try

Dim objBattery As New CBatteryInfo Dim retVal As Integer

retVal = objBattery.acPwrStatus If (retVal = 1) Then

MessageBox.Show("Online", "AC Power Status") ElseIf (retVal = 0) Then

MessageBox.Show("Offline", "AC Power Status")

Else

MessageBox.Show("Unknown", "AC Power Status") End If

Catch ex As Exception

MessageBox.Show ("Exception caught ") End Try

...

(b) C#

using Infosys.PervasiveIT.ResourceMonitor;

...

try

{

CBatteryInfo objBattery = new CBatteryInfo(); int retVal = objBattery.acPwrStatus;

if (retVal == 1)

MessageBox.Show("Online", "AC Power Status"); else if(retVal == 0)

MessageBox.Show("Offline", "AC Power Status");

else

MessageBox.Show("Unknown", "AC Power Status"); }catch(System.Exception exception)

{

MessageBox.Show("Exception caught ");

}

..

Listing Two

(a) Visual Basic

Imports Infosys.PervasiveIT.ResourceMonitor

...

Try

Dim objMemory As New CMemoryInfo Dim retVal As Long

retVal = objMemory.MemoryUsed MessageBox.Show(retVal.ToString() + " Bytes", "Memory Used") Catch ex As Exception

MessageBox.Show("Exception caught ") End Try

..

(b) C#

using Infosys.PervasiveIT.ResourceMonitor;

...

try

{

CMemoryInfo objMemory = new CMemoryInfo(); long retVal = objMemory.MemoryUsed;

MessageBox.Show(retVal.ToString() + " Bytes", "Memory Used"); }catch(System.Exception exception)

{

MessageBox.Show("Exception caught ");

}

..

Listing Three

(a) Visual Basic

Imports Infosys.PervasiveIT.ResourceMonitor

...

Try

Dim objNetwork As New CNetworkInfo Dim retVal As String

retVal = objNetwork.IPAddress MessageBox.Show(retVal, "IP Address") Catch ex As Exception

MessageBox.Show("Exception caught ") End Try

..

(b) C#

using Infosys.PervasiveIT.ResourceMonitor;

...

try

{

CNetworkInfo objNetwork = new CNetworkInfo(); string retVal = objNetwork.IPAddress(); MessageBox.Show(retVal , "IP Address"); }catch(System.Exception exception)

{

MessageBox.Show("Exception caught ");

}

..

DDJ

16

Dr. Dobb’s Journal, March 2006

http://www.ddj.com

Real-Time Stereoscopic

Video Streaming

Using off-the-shelf hardware

KAREN MCMENEMY AND

STUART FERGUSON

As the bandwidth of Internet connections continues to increase, the idea of distributed virtual reality is itself becoming a reality. While we’re

already seeing it to some degree in multiplayer computer games, distributed virtual reality goes further, making it possible for participants to believe they are gathered together in the same place at the same time. But to really believe what your eyes and ears are telling you, you need to be able to touch things and get a sense of space and depth, something that can only come by seeing stereoscopically.

Until recently, stereoscopic display technology has been either extravagantly expensive or rather crude. There’s no longer any reason for this. The availability of inexpensive webcams that interface to standard PC equipment via USB means that purchasing two color video input devices costs less than $50. Likewise, the cost of stereoscopic display devices are also plummeting. Shutter-eye glasses such as those from eDimensional (http://www.edimensional

.com/), for instance, deliver the stereoscopic effect by doubling the frame rate and inserting special sync signals in the video raster that are not normally seen on screen. In this article, we examine realtime VR by showing you how to use DirectX and OpenGL in a commodity PC to build a stereoscopic webcam.

Karen is a lecturer in the Intelligent Systems and Control Group at Queen’s University, Belfast; and Stuart is with the School of Electronics, Electrical Engineering, and Computer Science. They can be contacted at k.mcmenemy@ee.qub.ac.uk and r.ferguson@ee.qub.ac.uk, respectively.

Concept and Hardware

Figures 1 and 2 present the block architecture of the client/server software that powers our stereo TV.

The server application uses the DirectShow API to acquire synchronous video frames from two image sources and write them into a RAM buffer as a single frame. It can optionally preview the stereoscopic images from the cameras and deliver the images from the buffer in response to requests from clients.

The client application uses TCP/IP to request a left/right (L/R) image pair from the server. It uses the same stereoscopic display capabilities of the 3D graphics OpenGL libraries as are used by the server in its preview function to display the output. To focus on the main code details, we’ve excluded all error-processing statements and most variable declaration constructs from Listings One through Eleven (available electronically; see “Resource Center,” page 5).

To test the programs, we used two USB 2.0 compatible webcams (Trust 360 Spacecam, http://www.trust.fr/products/product

.aspx?artnr=13959) that deliver output at a resolution of 640× 480 and at a rate of up to 30 frames per second (fps). Lower resolutions and frame rates are achieved when USB 1.0 cameras are used. The PC was standard —512-MB RAM and an Intel Pentium 4 3.2-GHz processor. Interestingly, the processor’s Hyper-Threading Technology had to be disabled because it interfered with the camera drivers when two cameras were connected. Stereoscopic display was delivered using a 100-Hz refresh rate CRT and lowcost infrared shutter-eye glasses system from eDimensional. The glasses were connected via the VESA Standard Stereo Device Connector to an nVidia Quadro 4 750XGL display adapter. The same stereo display system was used in the client computer that had an AMD Athlon 1.35-GHz processor.

Server Program Architecture

The server application program is a conventional Win32 project written in C++. The application is implemented using mul-

tiple threads and the overall design strategy and data flow is illustrated in Figure 1. There are four primary threads:

The main application.

A thread-handling data acquisition from the left video camera.

A thread-handling data acquisition from the right video camera.

A thread-handling TCP/IP request for video frames to be sent to client applications.

“Like the server, the client is a standard Win32 application”

The left/right video camera threads also handle the option of previewing the video in either one stereoscopic capable window or as individual windows for the left/right camera. The thread that deals with the TCP/IP communications via the Windows sockets interface spawns additional threads to handle client connections. The image data flows from the camera threads into two screen buffers (implemented as a single block of RAM). The images in these buffers are read by the display thread and the communications thread as necessary (Figure 1).

The WinMain application entry point sets up a standard Win32 API by registering necessary window classes, identifying a message-processing function to handle messages for the application’s main window followed by instancing a window of that class. It also initializes the COM object libraries and proceeds to spawn the three work threads: the sockets thread and two camera threads that acquire the left and right images. Once this is done, it goes into a Windows message loop until a

18

Dr. Dobb’s Journal, March 2006

http://www.ddj.com

(continued from page 18)

WM_QUIT is detected. Finally, the main process thread kills the child processes, cleans up any memory buffers, and exits.

All the working threads have read or write access (appropriately protected via critical sections in the code) to two global variables that define the horizontal and vertical resolutions of the video output from the cameras and a memory buffer that holds the video image frames. The video buffer stores 24-bit RGB pixels and at twice the camera resolution. The first half of the video buffer is used to store the pictures from the left camera and the second half is used to store the pictures from the right camera. The camera threads have write access to these buffers, the rendering and sockets thread have read-only access. Because the resolution of the camera won’t change during program execution, the resolution is only determined once at the start of the initialization of the first camera thread to run. It is assumed that the second camera is going to operate with the same dimensions. Listing One presents the most-significant global variables and the C++ class of the object responsible for controlling the video acquisition from the cameras. Listing Two is the most significant features of the WinMain function.

Each camera thread uses the same code (entry point, void GLWindowPr(void *arg), Listing Three). When the thread is spawned, the _beginthread(..) function is passed a pointer to a structure with a member variable to indicate whether this thread is to look for and use the left or right camera and to copy the image data from the video source into the corresponding frame buffer, left camera video data to left buffer, and so on. The threads act independently, but use the DirectShow synchronization mechanism to get as little delay as possible between the left and right video streams. (In practice, this works well with USB 2.0 cameras but less so with USB 1.0 cameras attached to slower host computers.)

To facilitate a preview of the acquired video, the camera threads create floating display windows. If the server’s display hardware is stereo enabled, only one of

Figure 1: The server program’s block structure.

these windows is made visible; otherwise, both are shown. The window message function initializes the OpenGL display system and configures it to draw into the rendering thread’s window. OpenGL uses left and right double buffers to support stereoscopic display. The message-handling functions use a timer to render at regular intervals. The OpenGL glDrawPixels(..) function fulfills the task of making visible the video data buffer. Listing Four has an outline of the code for the rendering and window message handling.

Before there is any video to render, however, the GLWindowPr(..) function must build and run a DirectShow filter graph to capture the video. The key steps are in Listing Five. You need an instance of a custom rendering filter for the graph, and this is created in the line:

pRenderer = new CRenderer(this, id, NULL, &hr);

Listing Six defines the class for this object and its member variables and methods.

Function CaptureVideo(..) (Listing Seven) uses a CaptureBuilder2 object to link up the filters in the graph. The video sources are enumerated and one is selected for the left or right source (depending on whether this is the first or second camera handler thread). Function FindCaptureDevice(..) (Listing Eight) shows how this is achieved using the DirectShow COM objects. Looking back at Listing Seven, the

CaptureBuilder2 method RenderStream( ) links the video source with our CRenderer filter. It is the job of our custom filter to copy the DirectShow media samples into the video buffer (Listing Nine). Once built, the filter graph is run via the DirectShow media control interface. The video acquisition threads wait in a message-processing loop until terminated by the application’s main thread.

The server application’s socket thread binds to a high TCP port and listens for a connection from a client. The socket thread is terminated by a signal from the main thread. When a client connects, a new handler thread is started to serve out the video frames. The client handler thread (Listing Ten) carries out a short handshaking protocol with the client to determine whether it wants: stereo images,

Figure 2: The client application’s block structure.

20

Dr. Dobb’s Journal, March 2006

http://www.ddj.com