Menu
Amazon AppStream
Developer Guide

This documentation is for an older version of Amazon AppStream. For information about the latest version, see the Amazon AppStream 2.0 Developer Guide.

Creating Your Client

To create a client, your client must create an XStxClientLibraryHandle object. This is the top level object that you will use to interact with the libraries you will use to connect to sessions, render the audio and video, and send inputs to the application.

The following excerpt from the example client in the Amazon AppStream SDK illustrates this step. The excerpt is from the XStxModule::init() function of XStxModule.cpp.

Note

We strongly recommend using the provided source code and pre-compiled clients rather than creating your own implementation based on these excerpts.

Copy
XStxResult XStxModule::init() { XStxResult createResult = XSTX_RESULT_OK; if ((createResult = XStxClientLibraryCreate(XSTX_CLIENT_API_VERSION_MAJOR, XSTX_CLIENT_API_VERSION_MINOR, &mClientLibraryHandle)) != XSTX_RESULT_OK) { const char *name; const char *desc; XStxResultGetInfo(createResult, &name, &desc); LOGE("XStxClientLibraryCreate failed with: %s", name); return createResult; } mVideoRenderer = newVideoRenderer(); return XSTX_RESULT_OK; }

The function creates a client library handle (mclientLibraryHandle) that the client will use to create a client object. The example client creates the client object by instantiating an object from a user-defined class.

The following excerpt from the example client in the Amazon AppStream SDK illustrates this step. The excerpt is from the XStxModule::connect function of XStxModule.cpp.

Copy
if ((result = XStxClientCreate(mClientLibraryHandle, &mClientHandle)) != XSTX_RESULT_OK) { LOGE("Failed to create client."); const char *name; const char *desc; XStxResultGetInfo(result, &name, &desc); LOGE("XStxClientCreate failed with: %s", name); return result; }

The object needs a structure to respond to the callback functions from the application. The client creates and populates a XStxIClientListener structure to respond to the callback functions.

The following excerpt from the example client in the Amazon AppStream SDK illustrates this step. The excerpt is from the XStxModule::connect function of XStxModule.cpp.

Copy
... memset(&mStxListener, 0, sizeof(mStxListener)); ... mStxListener.mClientReadyFcn = &::clientReady; mStxListener.mClientReadyCtx = this; mStxListener.mClientStoppedFcn = &::clientStopped; mStxListener.mClientStoppedCtx = this; mStxListener.mMessageReceivedFcn = &::messageReceived; mStxListener.mMessageReceivedCtx = this; mStxListener.mStreamQualityMetricsReceivedFcn = &::clientQoS; mStxListener.mStreamQualityMetricsReceivedCtx = this; mStxListener.mSize = sizeof(mStxListener);

After populating the structure, call the XStxClientSetListener function to configure a listener that responds to the callback functions.

The following excerpt from the example client in the Amazon AppStream SDK illustrates this step. The excerpt is from the XStxModule::connect function of XStxModule.cpp.

Copy
if ((result = XStxClientSetListener(mClientHandle, &mStxListener)) != XSTX_RESULT_OK) { LOGE("Failed to set listener"); const char *name; const char *desc; XStxResultGetInfo(result, &name, &desc); LOGE("XStxClientSetListener failed with: %s", name); platformErrorMessage(true, desc); return result; }

The client uses structures to get, render, and decode video and audio frames. The next step is to create and populate these structures. The example client instantiates a class to create and populate the structures.

To handle a video frame, the client create and populate the following structures defined in VideoModule.h:

  • XStxIVideoDecoder. Used to get and decode a video frame.

  • XStxIVideoRenderer. Used to render a video frame.

  • XStxIRawVideoFrameAllocator. Used to get and recycle a video frame.

The following excerpt from the example client in the Amazon AppStream SDK illustrates populating the structures for video. The excerpt is from the XStxModule::connect function of XStxModule.cpp.

Copy
// initialize video module if (!mVideoModule.initialize(mClientHandle, *mVideoRenderer)) { LOGE("Failed to create video decoder/renderer"); return XSTX_RESULT_NOT_INITIALIZED_PROPERLY; }

To handle an audio frame, the client create and populate the following structures defined in AudioModule.h:

  • XStxIAudioDecoder. Used to get and decode an audio frame.

  • XStxIAudioRenderer. Used to render an audio frame.

  • XStxIRawAudioFrameAllocator. Used to get and recycle an audio frame.

The following excerpt from the example client in the Amazon AppStream SDK illustrates populating the structures for audio. The excerpt is from XStxModule::connect function of XStxModule.cpp.

Copy
// initialize audio module if (!mAudioModule.initialize(mClientHandle)) { LOGE("Failed to create audio decoder/renderer"); return XSTX_RESULT_NOT_INITIALIZED_PROPERLY; }

The client is now ready to configure and start a session with the application. The client configures a session by calling the XStxClientSetEntitlementUrl function with the endpoint of the entitlement service.

The following excerpt from the example client in the Amazon AppStream SDK illustrates this step. The excerpt is from the XStxModule::connect function of XStxModule.cpp.

Copy
if ((result = XStxClientSetEntitlementUrl(mClientHandle, address.c_str())) != XSTX_RESULT_OK) { const char *name; const char *desc; XStxResultGetInfo(result, &name, &desc); LOGE("XStxClientSetEntitlementUrl failed with: %s", name); return result; }

The client starts a session by calling a function.

The following excerpt from the example client in the Amazon AppStream SDK illustrates this step. The excerpt is from the XStxModule::connect function of XStxModule.cpp.

Copy
// non-blocking! if ((result = XStxClientStart(mClientHandle)) != XSTX_RESULT_OK) { LOGE("Failed to start client."); const char *name; const char *desc; XStxResultGetInfo(result, &name, &desc); LOGE("XStxClientStart failed with: %s", name); return result; }