Files
cup_edit/ios/include/filament/Stream.h
2022-07-10 17:49:56 +10:00

216 lines
8.2 KiB
C++

/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_STREAM_H
#define TNT_FILAMENT_STREAM_H
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/PixelBufferDescriptor.h>
#include <backend/CallbackHandler.h>
#include <utils/compiler.h>
namespace filament {
class FStream;
class Engine;
/**
* Stream is used to attach a video stream to a Filament `Texture`.
*
* Note that the `Stream` class is fairly Android centric. It supports two different
* configurations:
*
* - ACQUIRED.....connects to an Android AHardwareBuffer
* - NATIVE.......connects to an Android SurfaceTexture
*
* Before explaining these different configurations, let's review the high-level structure of an AR
* or video application that uses Filament:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* while (true) {
*
* // Misc application work occurs here, such as:
* // - Writing the image data for a video frame into a Stream
* // - Moving the Filament Camera
*
* if (renderer->beginFrame(swapChain)) {
* renderer->render(view);
* renderer->endFrame();
* }
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Let's say that the video image data at the time of a particular invocation of `beginFrame`
* becomes visible to users at time A. The 3D scene state (including the camera) at the time of
* that same invocation becomes apparent to users at time B.
*
* - If time A matches time B, we say that the stream is \em{synchronized}.
* - Filament invokes low-level graphics commands on the \em{driver thread}.
* - The thread that calls `beginFrame` is called the \em{main thread}.
*
* For ACQUIRED streams, there is no need to perform the copy because Filament explictly acquires
* the stream, then releases it later via a callback function. This configuration is especially
* useful when the Vulkan backend is enabled.
*
* For NATIVE streams, Filament does not make any synchronization guarantee. However they are simple
* to use and do not incur a copy. These are often appropriate in video applications.
*
* Please see `sample-stream-test` and `sample-hello-camera` for usage examples.
*
* @see backend::StreamType
* @see Texture#setExternalStream
* @see Engine#destroyStream
*/
class UTILS_PUBLIC Stream : public FilamentAPI {
struct BuilderDetails;
public:
using Callback = backend::StreamCallback;
using StreamType = backend::StreamType;
/**
* Constructs a Stream object instance.
*
* By default, Stream objects are ACQUIRED and must have external images pushed to them via
* <pre>Stream::setAcquiredImage</pre>.
*
* To create a NATIVE stream, call one of the <pre>stream</pre> methods
* on the builder.
*/
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder const& rhs) noexcept;
Builder& operator=(Builder&& rhs) noexcept;
/**
* Creates a NATIVE stream. Native streams can sample data directly from an
* opaque platform object such as a SurfaceTexture on Android.
*
* @param stream An opaque native stream handle. e.g.: on Android this is an
* `android/graphics/SurfaceTexture` JNI jobject. The wrap mode must
* be CLAMP_TO_EDGE.
*
* @return This Builder, for chaining calls.
*/
Builder& stream(void* stream) noexcept;
/**
*
* @param width initial width of the incoming stream. Whether this value is used is
* stream dependent. On Android, it must be set when using
* Builder::stream(long externalTextureId).
*
* @return This Builder, for chaining calls.
*/
Builder& width(uint32_t width) noexcept;
/**
*
* @param height initial height of the incoming stream. Whether this value is used is
* stream dependent. On Android, it must be set when using
* Builder::stream(long externalTextureId).
*
* @return This Builder, for chaining calls.
*/
Builder& height(uint32_t height) noexcept;
/**
* Creates the Stream object and returns a pointer to it.
*
* @param engine Reference to the filament::Engine to associate this Stream with.
*
* @return pointer to the newly created object, or nullptr if the stream couldn't be created.
*/
Stream* build(Engine& engine);
private:
friend class FStream;
};
/**
* Indicates whether this stream is a NATIVE stream or ACQUIRED stream.
*/
StreamType getStreamType() const noexcept;
/**
* Updates an ACQUIRED stream with an image that is guaranteed to be used in the next frame.
*
* This method tells Filament to immediately "acquire" the image and trigger a callback
* when it is done with it. This should be called by the user outside of beginFrame / endFrame,
* and should be called only once per frame. If the user pushes images to the same stream
* multiple times in a single frame, only the final image is honored, but all callbacks are
* invoked.
*
* This method should be called on the same thread that calls Renderer::beginFrame, which is
* also where the callback is invoked. This method can only be used for streams that were
* constructed without calling the `stream` method on the builder.
*
* @see Stream for more information about NATIVE and ACQUIRED configurations.
*
* @param image Pointer to AHardwareBuffer, casted to void* since this is a public header.
* @param callback This is triggered by Filament when it wishes to release the image.
* It callback tales two arguments: the AHardwareBuffer and the userdata.
* @param userdata Optional closure data. Filament will pass this into the callback when it
* releases the image.
*/
void setAcquiredImage(void* image, Callback callback, void* userdata) noexcept;
/**
* @see setAcquiredImage(void*, Callback, void*)
*
* @param image Pointer to AHardwareBuffer, casted to void* since this is a public header.
* @param handler Handler to dispatch the AcquiredImage or nullptr for the default handler.
* @param callback This is triggered by Filament when it wishes to release the image.
* It callback tales two arguments: the AHardwareBuffer and the userdata.
* @param userdata Optional closure data. Filament will pass this into the callback when it
* releases the image.
*/
void setAcquiredImage(void* image, backend::CallbackHandler* handler, Callback callback, void* userdata) noexcept;
/**
* Updates the size of the incoming stream. Whether this value is used is
* stream dependent. On Android, it must be set when using
* Builder::stream(long externalTextureId).
*
* @param width new width of the incoming stream
* @param height new height of the incoming stream
*/
void setDimensions(uint32_t width, uint32_t height) noexcept;
/**
* Returns the presentation time of the currently displayed frame in nanosecond.
*
* This value can change at any time.
*
* @return timestamp in nanosecond.
*/
int64_t getTimestamp() const noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_STREAM_H