diff --git a/evs/1.0/default/EvsCamera.cpp b/evs/1.0/default/EvsCamera.cpp
index 6715a2e..c62f7b6 100644
--- a/evs/1.0/default/EvsCamera.cpp
+++ b/evs/1.0/default/EvsCamera.cpp
@@ -33,18 +33,22 @@
 const char EvsCamera::kCameraName_Backup[]    = "backup";
 const char EvsCamera::kCameraName_RightTurn[] = "Right Turn";
 
+// Arbitrary limit on number of graphics buffers allowed to be allocated
+// Safeguards against unreasonable resource consumption and provides a testable limit
+const unsigned MAX_BUFFERS_IN_FLIGHT = 100;
+
 
 // TODO(b/31632518):  Need to get notification when our client dies so we can close the camera.
-// As it stands, if the client dies suddently, the buffer may be stranded.
-// As possible work around would be to give the client a HIDL object to exclusively hold
-// and use it's destructor to perform some work in the server side.
+// As it stands, if the client dies suddenly, the buffer may be stranded.
 
-EvsCamera::EvsCamera(const char *id) {
+EvsCamera::EvsCamera(const char *id) :
+    mFramesAllowed(0),
+    mFramesInUse(0),
+    mStreamState(STOPPED) {
+
     ALOGD("EvsCamera instantiated");
 
     mDescription.cameraId = id;
-    mFrameBusy = false;
-    mStreamState = STOPPED;
 
     // Set up dummy data for testing
     if (mDescription.cameraId == kCameraName_Backup) {
@@ -52,16 +56,23 @@
         mDescription.vendorFlags            = 0xFFFFFFFF;   // Arbitrary value
         mDescription.defaultHorResolution   = 320;          // 1/2 NTSC/VGA
         mDescription.defaultVerResolution   = 240;          // 1/2 NTSC/VGA
-    }
-    else if (mDescription.cameraId == kCameraName_RightTurn) {
+    } else if (mDescription.cameraId == kCameraName_RightTurn) {
         // Nothing but the name and the usage hint
         mDescription.hints                  = static_cast<uint32_t>(UsageHint::USAGE_HINT_RIGHT_TURN);
-    }
-    else {
+    } else {
         // Leave empty for a minimalist camera description without even a hint
     }
+
+
+    // Set our buffer properties
+    mWidth  = (mDescription.defaultHorResolution) ? mDescription.defaultHorResolution : 640;
+    mHeight = (mDescription.defaultVerResolution) ? mDescription.defaultVerResolution : 480;
+
+    mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+    mUsage  = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE;
 }
 
+
 EvsCamera::~EvsCamera() {
     ALOGD("EvsCamera being destroyed");
     std::lock_guard<std::mutex> lock(mAccessLock);
@@ -70,11 +81,14 @@
     // (It really should be already)
     stopVideoStream();
 
-    // Drop the graphics buffer we've been using
-    if (mBuffer) {
-        // Drop the graphics buffer we've been using
-        GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
-        alloc.free(mBuffer);
+    // Drop all the graphics buffers we've been using
+    GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
+    for (auto&& rec : mBuffers) {
+        if (rec.inUse) {
+            ALOGE("Error - releasing buffer despite remote ownership");
+        }
+        alloc.free(rec.handle);
+        rec.handle = nullptr;
     }
 
     ALOGD("EvsCamera destroyed");
@@ -95,113 +109,109 @@
     ALOGD("setMaxFramesInFlight");
     std::lock_guard<std::mutex> lock(mAccessLock);
 
-    // TODO:  Update our stored value
-
-    // TODO:  Adjust our buffer count right now if we can.  Otherwise, it'll adjust in doneWithFrame
-
-    // For now we support only one!
-    if (bufferCount != 1) {
-        return EvsResult::BUFFER_NOT_AVAILABLE;
+    // We cannot function without at least one video buffer to send data
+    if (bufferCount < 1) {
+        ALOGE("Ignoring setMaxFramesInFlight with less than one buffer requested");
+        return EvsResult::INVALID_ARG;
     }
 
-    return EvsResult::OK;
+    // Update our internal state
+    if (setAvailableFrames_Locked(bufferCount)) {
+        return EvsResult::OK;
+    } else {
+        return EvsResult::BUFFER_NOT_AVAILABLE;
+    }
 }
 
+
 Return<EvsResult> EvsCamera::startVideoStream(const ::android::sp<IEvsCameraStream>& stream)  {
     ALOGD("startVideoStream");
     std::lock_guard<std::mutex> lock(mAccessLock);
 
-    // We only support a single stream at a time
     if (mStreamState != STOPPED) {
         ALOGE("ignoring startVideoStream call when a stream is already running.");
         return EvsResult::STREAM_ALREADY_RUNNING;
     }
 
+    // If the client never indicated otherwise, configure ourselves for a single streaming buffer
+    if (mFramesAllowed < 1) {
+        if (!setAvailableFrames_Locked(1)) {
+            ALOGE("Failed to start stream because we couldn't get a graphics buffer");
+            return EvsResult::BUFFER_NOT_AVAILABLE;
+        }
+    }
+
     // Record the user's callback for use when we have a frame ready
     mStream = stream;
 
-    // Allocate a graphics buffer into which we'll put our test images
-    if (!mBuffer) {
-        mWidth  = (mDescription.defaultHorResolution) ? mDescription.defaultHorResolution : 640;
-        mHeight = (mDescription.defaultVerResolution) ? mDescription.defaultVerResolution : 480;
-        // TODO:  What about stride?  Assume no padding for now...
-        mStride = 4* mWidth;    // Special cased to assume 4 byte pixels with no padding for now
-
-        ALOGD("Allocating buffer for camera frame");
-        GraphicBufferAllocator &alloc(GraphicBufferAllocator::get());
-        status_t result = alloc.allocate(mWidth, mHeight,
-                                         HAL_PIXEL_FORMAT_RGBA_8888, 1, GRALLOC_USAGE_HW_TEXTURE,
-                                         &mBuffer, &mStride, 0, "EvsCamera");
-        if (result != NO_ERROR) {
-            ALOGE("Error %d allocating %d x %d graphics buffer", result, mWidth, mHeight);
-            return EvsResult::BUFFER_NOT_AVAILABLE;
-        }
-        if (!mBuffer) {
-            ALOGE("We didn't get a buffer handle back from the allocator");
-            return EvsResult::BUFFER_NOT_AVAILABLE;
-        }
-    }
-
     // Start the frame generation thread
     mStreamState = RUNNING;
-    mCaptureThread = std::thread([this](){GenerateFrames();});
+    mCaptureThread = std::thread([this](){ generateFrames(); });
 
     return EvsResult::OK;
 }
 
-Return<EvsResult> EvsCamera::doneWithFrame(uint32_t /* frameId */, const hidl_handle& bufferHandle)  {
+
+Return<void> EvsCamera::doneWithFrame(const BufferDesc& buffer)  {
     ALOGD("doneWithFrame");
-    std::lock_guard<std::mutex> lock(mAccessLock);
-
-    if (!bufferHandle)
-    {
-        ALOGE("ignoring doneWithFrame called with invalid handle");
-        return EvsResult::INVALID_ARG;
-    }
-
-    // TODO:  Track which frames we've delivered and validate this is one of them
-
-    // Mark the frame buffer as available for a new frame
-    mFrameBusy = false;
-
-    // TODO:  If we currently have too many buffers, drop this one
-
-    return EvsResult::OK;
-}
-
-Return<void> EvsCamera::stopVideoStream()  {
-    ALOGD("stopVideoStream");
-
-    bool waitForJoin = false;
-    // Lock scope
-    {
+    {  // lock context
         std::lock_guard <std::mutex> lock(mAccessLock);
 
-        if (mStreamState == RUNNING) {
-            // Tell the GenerateFrames loop we want it to stop
-            mStreamState = STOPPING;
+        if (buffer.memHandle == nullptr) {
+            ALOGE("ignoring doneWithFrame called with null handle");
+        } else if (buffer.bufferId >= mBuffers.size()) {
+            ALOGE("ignoring doneWithFrame called with invalid bufferId %d (max is %lu)",
+                  buffer.bufferId, mBuffers.size()-1);
+        } else if (!mBuffers[buffer.bufferId].inUse) {
+            ALOGE("ignoring doneWithFrame called on frame %d which is already free",
+                  buffer.bufferId);
+        } else {
+            // Mark the frame as available
+            mBuffers[buffer.bufferId].inUse = false;
+            mFramesInUse--;
 
-            // Note that we asked the thread to stop and should wait for it do so
-            waitForJoin = true;
-        }
-    }
-
-    if (waitForJoin) {
-        // Block outside the mutex until the "stop" flag has been acknowledged
-        // NOTE:  We won't send any more frames, but the client might still get one already in flight
-        ALOGD("Waiting for stream thread to end...");
-        mCaptureThread.join();
-
-        // Lock scope
-        {
-            std::lock_guard <std::mutex> lock(mAccessLock);
-            mStreamState = STOPPED;
+            // If this frame's index is high in the array, try to move it down
+            // to improve locality after mFramesAllowed has been reduced.
+            if (buffer.bufferId >= mFramesAllowed) {
+                // Find an empty slot lower in the array (which should always exist in this case)
+                for (auto&& rec : mBuffers) {
+                    if (rec.handle == nullptr) {
+                        rec.handle = mBuffers[buffer.bufferId].handle;
+                        mBuffers[buffer.bufferId].handle = nullptr;
+                        break;
+                    }
+                }
+            }
         }
     }
 
     return Void();
 }
 
+
+Return<void> EvsCamera::stopVideoStream()  {
+    ALOGD("stopVideoStream");
+    std::unique_lock <std::mutex> lock(mAccessLock);
+
+    if (mStreamState == RUNNING) {
+        // Tell the GenerateFrames loop we want it to stop
+        mStreamState = STOPPING;
+
+        // Block outside the mutex until the "stop" flag has been acknowledged
+        // We won't send any more frames, but the client might still get some already in flight
+        ALOGD("Waiting for stream thread to end...");
+        lock.unlock();
+        mCaptureThread.join();
+        lock.lock();
+
+        mStreamState = STOPPED;
+        ALOGD("Stream marked STOPPED.");
+    }
+
+    return Void();
+}
+
+
 Return<int32_t> EvsCamera::getExtendedInfo(uint32_t opaqueIdentifier)  {
     ALOGD("getExtendedInfo");
     std::lock_guard<std::mutex> lock(mAccessLock);
@@ -215,6 +225,7 @@
     return 0;
 }
 
+
 Return<EvsResult> EvsCamera::setExtendedInfo(uint32_t /*opaqueIdentifier*/, int32_t /*opaqueValue*/)  {
     ALOGD("setExtendedInfo");
     std::lock_guard<std::mutex> lock(mAccessLock);
@@ -224,10 +235,124 @@
 }
 
 
-void EvsCamera::GenerateFrames() {
-    ALOGD("Frame generate loop started");
+bool EvsCamera::setAvailableFrames_Locked(unsigned bufferCount) {
+    if (bufferCount < 1) {
+        ALOGE("Ignoring request to set buffer count to zero");
+        return false;
+    }
+    if (bufferCount > MAX_BUFFERS_IN_FLIGHT) {
+        ALOGE("Rejecting buffer request in excess of internal limit");
+        return false;
+    }
 
-    uint32_t frameNumber;
+    // Is an increase required?
+    if (mFramesAllowed < bufferCount) {
+        // An increase is required
+        unsigned needed = bufferCount - mFramesAllowed;
+        ALOGI("Allocating %d buffers for camera frames", needed);
+
+        unsigned added = increaseAvailableFrames_Locked(needed);
+        if (added != needed) {
+            // If we didn't add all the frames we needed, then roll back to the previous state
+            ALOGE("Rolling back to previous frame queue size");
+            decreaseAvailableFrames_Locked(added);
+            return false;
+        }
+    } else if (mFramesAllowed > bufferCount) {
+        // A decrease is required
+        unsigned framesToRelease = mFramesAllowed - bufferCount;
+        ALOGI("Returning %d camera frame buffers", framesToRelease);
+
+        unsigned released = decreaseAvailableFrames_Locked(framesToRelease);
+        if (released != framesToRelease) {
+            // This shouldn't happen with a properly behaving client because the client
+            // should only make this call after returning sufficient outstanding buffers
+            // to allow a clean resize.
+            ALOGE("Buffer queue shrink failed -- too many buffers currently in use?");
+        }
+    }
+
+    return true;
+}
+
+
+unsigned EvsCamera::increaseAvailableFrames_Locked(unsigned numToAdd) {
+    // Acquire the graphics buffer allocator
+    GraphicBufferAllocator &alloc(GraphicBufferAllocator::get());
+
+    unsigned added = 0;
+
+    while (added < numToAdd) {
+        buffer_handle_t memHandle = nullptr;
+        status_t result = alloc.allocate(mWidth, mHeight,
+                                         mFormat, 1,
+                                         mUsage,
+                                         &memHandle, &mStride, 0, "EvsCamera");
+        if (result != NO_ERROR) {
+            ALOGE("Error %d allocating %d x %d graphics buffer", result, mWidth, mHeight);
+            break;
+        }
+        if (!memHandle) {
+            ALOGE("We didn't get a buffer handle back from the allocator");
+            break;
+        }
+
+        // Find a place to store the new buffer
+        bool stored = false;
+        for (auto&& rec : mBuffers) {
+            if (rec.handle == nullptr) {
+                // Use this existing entry
+                rec.handle = memHandle;
+                rec.inUse = false;
+                stored = true;
+                break;
+            }
+        }
+        if (!stored) {
+            // Add a BufferRecord wrapping this handle to our set of available buffers
+            mBuffers.emplace_back(memHandle);
+        }
+
+        mFramesAllowed++;
+        added++;
+    }
+
+    return added;
+}
+
+
+unsigned EvsCamera::decreaseAvailableFrames_Locked(unsigned numToRemove) {
+    // Acquire the graphics buffer allocator
+    GraphicBufferAllocator &alloc(GraphicBufferAllocator::get());
+
+    unsigned removed = 0;
+
+    for (auto&& rec : mBuffers) {
+        // Is this record not in use, but holding a buffer that we can free?
+        if ((rec.inUse == false) && (rec.handle != nullptr)) {
+            // Release buffer and update the record so we can recognize it as "empty"
+            alloc.free(rec.handle);
+            rec.handle = nullptr;
+
+            mFramesAllowed--;
+            removed++;
+
+            if (removed == numToRemove) {
+                break;
+            }
+        }
+    }
+
+    return removed;
+}
+
+
+// This is the asynchronous frame generation thread that runs in parallel with the
+// main serving thread.  There is one for each active camera instance.
+void EvsCamera::generateFrames() {
+    ALOGD("Frame generation loop started");
+
+    unsigned idx;
 
     while (true) {
         bool timeForFrame = false;
@@ -235,57 +360,69 @@
         {
             std::lock_guard<std::mutex> lock(mAccessLock);
 
-            // Tick the frame counter -- rollover is tolerated
-            frameNumber = mFrameId++;
-
             if (mStreamState != RUNNING) {
                 // Break out of our main thread loop
                 break;
             }
 
-            if (mFrameBusy) {
+            // Are we allowed to issue another buffer?
+            if (mFramesInUse >= mFramesAllowed) {
                 // Can't do anything right now -- skip this frame
-                ALOGW("Skipped a frame because client hasn't returned a buffer\n");
-            }
-            else {
-                // We're going to make the frame busy
-                mFrameBusy = true;
-                timeForFrame = true;
+                ALOGW("Skipped a frame because too many are in flight\n");
+            } else {
+                // Identify an available buffer to fill
+                for (idx = 0; idx < mBuffers.size(); idx++) {
+                    if (!mBuffers[idx].inUse) {
+                        if (mBuffers[idx].handle != nullptr) {
+                            // Found an available record, so stop looking
+                            break;
+                        }
+                    }
+                }
+                if (idx >= mBuffers.size()) {
+                    // This shouldn't happen since we already checked mFramesInUse vs mFramesAllowed
+                    ALOGE("Failed to find an available buffer slot\n");
+                } else {
+                    // We're going to make the frame busy
+                    mBuffers[idx].inUse = true;
+                    mFramesInUse++;
+                    timeForFrame = true;
+                }
             }
         }
 
         if (timeForFrame) {
-            // Lock our output buffer for writing
-            uint32_t *pixels = nullptr;
-            GraphicBufferMapper &mapper = GraphicBufferMapper::get();
-            mapper.lock(mBuffer,
-                        GRALLOC_USAGE_SW_WRITE_OFTEN,
-                        android::Rect(mWidth, mHeight),
-                        (void **) &pixels);
+            // Assemble the buffer description we'll transmit below
+            BufferDesc buff = {};
+            buff.width      = mWidth;
+            buff.height     = mHeight;
+            buff.stride     = mStride;
+            buff.format     = mFormat;
+            buff.usage      = mUsage;
+            buff.bufferId   = idx;
+            buff.memHandle  = mBuffers[idx].handle;
 
-            // If we failed to lock the pixel buffer, we're about to crash, but log it first
-            if (!pixels) {
-                ALOGE("Camera failed to gain access to image buffer for writing");
+            // Write test data into the image buffer
+            fillTestFrame(buff);
+
+            // Issue the (asynchronous) callback to the client -- can't be holding the lock
+            auto result = mStream->deliverFrame(buff);
+            if (result.isOk()) {
+                ALOGD("Delivered %p as id %d", buff.memHandle.getNativeHandle(), buff.bufferId);
+            } else {
+                // This can happen if the client dies and is likely unrecoverable.
+                // To avoid consuming resources generating failing calls, we stop sending
+                // frames.  Note, however, that the stream remains in the "STREAMING" state
+                // until cleaned up on the main thread.
+                ALOGE("Frame delivery call failed in the transport layer.");
+
+                // Since we didn't actually deliver it, mark the frame as available
+                std::lock_guard<std::mutex> lock(mAccessLock);
+                mBuffers[idx].inUse = false;
+                mFramesInUse--;
+
+                break;
             }
-
-            // Fill in the test pixels
-            for (unsigned row = 0; row < mHeight; row++) {
-                for (unsigned col = 0; col < mWidth; col++) {
-                    // Index into the row to set the pixel at this column
-                    // (We're making vertical gradient in the green channel, and
-                    // horitzontal gradient in the blue channel)
-                    pixels[col] = 0xFF0000FF | ((row & 0xFF) << 16) | ((col & 0xFF) << 8);
-                }
-                // Point to the next row
-                pixels = pixels + (mStride / sizeof(*pixels));
-            }
-
-            // Release our output buffer
-            mapper.unlock(mBuffer);
-
-            // Issue the (asynchronous) callback to the client
-            mStream->deliverFrame(frameNumber, mBuffer);
-            ALOGD("Delivered %p as frame %d", mBuffer, frameNumber);
         }
 
         // We arbitrarily choose to generate frames at 10 fps (1/10 * uSecPerSec)
@@ -293,11 +430,58 @@
     }
 
     // If we've been asked to stop, send one last NULL frame to signal the actual end of stream
-    mStream->deliverFrame(frameNumber, nullptr);
+    BufferDesc nullBuff = {};
+    auto result = mStream->deliverFrame(nullBuff);
+    if (!result.isOk()) {
+        ALOGE("Error delivering end of stream marker");
+    }
 
     return;
 }
 
+
+void EvsCamera::fillTestFrame(BufferDesc buff) {
+    // Lock our output buffer for writing
+    uint32_t *pixels = nullptr;
+    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+    mapper.lock(buff.memHandle,
+                GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_NEVER,
+                android::Rect(buff.width, buff.height),
+                (void **) &pixels);
+
+    // If we failed to lock the pixel buffer, we're about to crash, but log it first
+    if (!pixels) {
+        ALOGE("Camera failed to gain access to image buffer for writing");
+    }
+
+    // Fill in the test pixels
+    for (unsigned row = 0; row < buff.height; row++) {
+        for (unsigned col = 0; col < buff.width; col++) {
+            // Index into the row to check the pixel at this column.
+            // We expect 0xFF in the LSB channel, a vertical gradient in the
+            // second channel, a horitzontal gradient in the third channel, and
+            // 0xFF in the MSB.
+            // The exception is the very first 32 bits which is used for the
+            // time varying frame signature to avoid getting fooled by a static image.
+            uint32_t expectedPixel = 0xFF0000FF           | // MSB and LSB
+                                     ((row & 0xFF) <<  8) | // vertical gradient
+                                     ((col & 0xFF) << 16);  // horizontal gradient
+            if ((row | col) == 0) {
+                static uint32_t sFrameTicker = 0;
+                expectedPixel = (sFrameTicker) & 0xFF;
+                sFrameTicker++;
+            }
+            pixels[col] = expectedPixel;
+        }
+        // Point to the next row
+        pixels = pixels + (buff.stride / sizeof(*pixels));
+    }
+
+    // Release our output buffer
+    mapper.unlock(buff.memHandle);
+}
+
+
 } // namespace implementation
 } // namespace V1_0
 } // namespace evs
