diff options
Diffstat (limited to 'components/include')
9 files changed, 133 insertions, 429 deletions
diff --git a/components/include/v4l2_codec2/components/V4L2ComponentStore.h b/components/include/v4l2_codec2/components/ComponentStore.h index bfec407..a759d4d 100644 --- a/components/include/v4l2_codec2/components/V4L2ComponentStore.h +++ b/components/include/v4l2_codec2/components/ComponentStore.h @@ -1,9 +1,9 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// Copyright 2023 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_COMPONENT_STORE_H -#define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_COMPONENT_STORE_H +#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_COMPONENT_STORE_MIXIN_H +#define ANDROID_V4L2_CODEC2_COMPONENTS_COMPONENT_STORE_MIXIN_H #include <map> #include <mutex> @@ -15,10 +15,15 @@ namespace android { -class V4L2ComponentStore : public C2ComponentStore { +enum class VideoCodec; + +class ComponentStore : public C2ComponentStore { public: - static std::shared_ptr<C2ComponentStore> Create(); - ~V4L2ComponentStore(); + using GetFactory = std::function<std::unique_ptr<C2ComponentFactory>( + const std::string& /* name */, std::shared_ptr<C2ReflectorHelper>)>; + class Builder; + + virtual ~ComponentStore(); // C2ComponentStore implementation. C2String getName() const override; @@ -41,10 +46,21 @@ public: std::vector<C2FieldSupportedValuesQuery>& fields) const override; private: - V4L2ComponentStore(); + struct Declaration { + VideoCodec codec; + C2Component::kind_t kind; + GetFactory factory; + }; + + ComponentStore(C2String storeName); + + ::C2ComponentFactory* getFactory(const C2String& name); - ::C2ComponentFactory* GetFactory(const C2String& name); - std::shared_ptr<const C2Component::Traits> GetTraits(const C2String& name); + std::shared_ptr<const C2Component::Traits> getTraits(const C2String& name); + + C2String mStoreName; + + std::map<std::string, Declaration> mDeclarations; std::shared_ptr<C2ReflectorHelper> mReflector; @@ -54,8 +70,25 @@ private: std::mutex mCachedTraitsLock; std::map<C2String, std::shared_ptr<const C2Component::Traits>> mCachedTraits GUARDED_BY(mCachedTraitsLock); + + friend class Builder; +}; + +class ComponentStore::Builder final { +public: + Builder(C2String storeName); + ~Builder() = default; + + Builder& decoder(std::string name, VideoCodec codec, GetFactory factory); + + Builder& encoder(std::string name, VideoCodec codec, GetFactory factory); + + std::shared_ptr<ComponentStore> build() &&; + +private: + std::unique_ptr<ComponentStore> mStore; }; } // namespace android -#endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_COMPONENT_STORE_H +#endif // ANDROID_V4L2_CODEC2_COMPONENTS_COMPONENT_STORE_MIXIN_H diff --git a/components/include/v4l2_codec2/components/V4L2DecodeComponent.h b/components/include/v4l2_codec2/components/DecodeComponent.h index 962f7d6..27905c7 100644 --- a/components/include/v4l2_codec2/components/V4L2DecodeComponent.h +++ b/components/include/v4l2_codec2/components/DecodeComponent.h @@ -1,9 +1,9 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// Copyright 2023 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODE_COMPONENT_H -#define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODE_COMPONENT_H +#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_DECODE_COMPONENT_H +#define ANDROID_V4L2_CODEC2_COMPONENTS_DECODE_COMPONENT_H #include <atomic> #include <memory> @@ -17,22 +17,17 @@ #include <base/synchronization/waitable_event.h> #include <base/threading/thread.h> -#include <v4l2_codec2/components/V4L2DecodeInterface.h> +#include <v4l2_codec2/components/DecodeInterface.h> #include <v4l2_codec2/components/VideoDecoder.h> #include <v4l2_codec2/components/VideoFramePool.h> namespace android { -class V4L2DecodeComponent : public C2Component, - public std::enable_shared_from_this<V4L2DecodeComponent> { +class DecodeComponent : public C2Component, public std::enable_shared_from_this<DecodeComponent> { public: - static std::shared_ptr<C2Component> create(const std::string& name, c2_node_id_t id, - const std::shared_ptr<C2ReflectorHelper>& helper, - C2ComponentFactory::ComponentDeleter deleter); - V4L2DecodeComponent(const std::string& name, c2_node_id_t id, - const std::shared_ptr<C2ReflectorHelper>& helper, - const std::shared_ptr<V4L2DecodeInterface>& intfImpl); - ~V4L2DecodeComponent() override; + DecodeComponent(uint32_t debugStreamId, const std::string& name, c2_node_id_t id, + const std::shared_ptr<DecodeInterface>& intfImpl); + virtual ~DecodeComponent() override; // Implementation of C2Component. c2_status_t start() override; @@ -48,7 +43,7 @@ public: c2_status_t drain_nb(drain_mode_t mode) override; std::shared_ptr<C2ComponentInterface> intf() override; -private: +protected: // The C2Component state machine. enum class ComponentState { STOPPED, @@ -59,7 +54,7 @@ private: static const char* ComponentStateToString(ComponentState state); // Handle C2Component's public methods on |mDecoderTaskRunner|. - void startTask(c2_status_t* status, ::base::WaitableEvent* done); + virtual void startTask(c2_status_t* status, ::base::WaitableEvent* done) = 0; void stopTask(); void releaseTask(); void queueTask(std::unique_ptr<C2Work> work); @@ -69,6 +64,11 @@ private: // Try to process pending works at |mPendingWorks|. Paused when |mIsDraining| is set. void pumpPendingWorks(); + + void processCSDWork(const int32_t bitstreamId, const C2Work* work); + void processWork(const int32_t bitstreamId, const C2Work* work); + void processWorkBuffer(const int32_t bitstreamId, const C2ConstLinearBlock& linearBlock); + // Get the buffer pool. std::unique_ptr<VideoFramePool> getVideoFramePool(const ui::Size& size, HalPixelFormat pixelFormat, @@ -92,10 +92,11 @@ private: // Report error when any error occurs. void reportError(c2_status_t error); - static std::atomic<int32_t> sConcurrentInstances; + // Identifier used for debugging purposes. + uint32_t mDebugStreamId; // The pointer of component interface implementation. - std::shared_ptr<V4L2DecodeInterface> mIntfImpl; + std::shared_ptr<DecodeInterface> mIntfImpl; // The pointer of component interface. const std::shared_ptr<C2ComponentInterface> mIntf; // The pointer of component listener. @@ -137,13 +138,13 @@ private: // The device task runner and its sequence checker. We should interact with // |mDevice| on this. - ::base::Thread mDecoderThread{"V4L2DecodeComponentDecoderThread"}; + ::base::Thread mDecoderThread{"DecodeComponentDecoderThread"}; scoped_refptr<::base::SequencedTaskRunner> mDecoderTaskRunner; - ::base::WeakPtrFactory<V4L2DecodeComponent> mWeakThisFactory{this}; - ::base::WeakPtr<V4L2DecodeComponent> mWeakThis; + ::base::WeakPtrFactory<DecodeComponent> mWeakThisFactory{this}; + ::base::WeakPtr<DecodeComponent> mWeakThis; }; } // namespace android -#endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODE_COMPONENT_H +#endif // ANDROID_V4L2_CODEC2_COMPONENTS_DECODE_COMPONENT_H diff --git a/components/include/v4l2_codec2/components/V4L2DecodeInterface.h b/components/include/v4l2_codec2/components/DecodeInterface.h index f2ab898..7e513c5 100644 --- a/components/include/v4l2_codec2/components/V4L2DecodeInterface.h +++ b/components/include/v4l2_codec2/components/DecodeInterface.h @@ -1,9 +1,9 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// Copyright 2023 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODE_INTERFACE_H -#define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODE_INTERFACE_H +#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_DECODE_INTERFACE_H +#define ANDROID_V4L2_CODEC2_COMPONENTS_DECODE_INTERFACE_H #include <memory> #include <string> @@ -12,16 +12,18 @@ #include <ui/Size.h> #include <util/C2InterfaceHelper.h> +#include <v4l2_codec2/common/Common.h> #include <v4l2_codec2/common/VideoTypes.h> namespace android { -class V4L2DecodeInterface : public C2InterfaceHelper { +class DecodeInterface : public C2InterfaceHelper { public: - V4L2DecodeInterface(const std::string& name, const std::shared_ptr<C2ReflectorHelper>& helper); - V4L2DecodeInterface(const V4L2DecodeInterface&) = delete; - V4L2DecodeInterface& operator=(const V4L2DecodeInterface&) = delete; - ~V4L2DecodeInterface() = default; + DecodeInterface(const std::string& name, const std::shared_ptr<C2ReflectorHelper>& helper, + const SupportedCapabilities& caps); + DecodeInterface(const DecodeInterface&) = delete; + DecodeInterface& operator=(const DecodeInterface&) = delete; + ~DecodeInterface() = default; // interfaces for the client component. c2_status_t status() const { return mInitStatus; } @@ -38,6 +40,7 @@ private: // Configurable parameter setters. static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input>& info); static C2R SizeSetter(bool mayBlock, C2P<C2StreamPictureSizeInfo::output>& videoSize); + static C2R InputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input>& inputSize); static C2R MaxInputBufferSizeCalculator(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input>& me, const C2P<C2StreamPictureSizeInfo::output>& size); @@ -66,6 +69,9 @@ private: // buffer can be released by the component; only used for H264 because H264 may reorder the // output frames. std::shared_ptr<C2PortDelayTuning::output> mOutputDelay; + // The number of extra frames processed at one time by the component. Allows more input + // buffers to be simultaneously enqueued. + std::shared_ptr<C2PipelineDelayTuning> mPipelineDelay; // The input codec profile and level. For now configuring this parameter is useless since // the component always uses fixed codec profile to initialize accelerator. It is only used // for the client to query supported profile and level values. @@ -100,4 +106,4 @@ private: } // namespace android -#endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODE_INTERFACE_H +#endif // ANDROID_V4L2_CODEC2_COMPONENTS_DECODE_INTERFACE_H diff --git a/components/include/v4l2_codec2/components/V4L2EncodeComponent.h b/components/include/v4l2_codec2/components/EncodeComponent.h index 0b150e4..81c8c6d 100644 --- a/components/include/v4l2_codec2/components/V4L2EncodeComponent.h +++ b/components/include/v4l2_codec2/components/EncodeComponent.h @@ -1,14 +1,15 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// Copyright 2023 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_ENCODE_COMPONENT_H -#define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_ENCODE_COMPONENT_H +#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_ENCODE_COMPONENT_H +#define ANDROID_V4L2_CODEC2_COMPONENTS_ENCODE_COMPONENT_H #include <atomic> #include <memory> #include <optional> #include <unordered_map> +#include <vector> #include <C2Component.h> #include <C2ComponentFactory.h> @@ -22,23 +23,24 @@ #include <base/synchronization/waitable_event.h> #include <base/threading/thread.h> #include <util/C2InterfaceHelper.h> +#include <v4l2_codec2/common/Common.h> +#include <v4l2_codec2/common/VideoPixelFormat.h> namespace android { struct BitstreamBuffer; class FormatConverter; class VideoEncoder; -class V4L2EncodeInterface; +class EncodeInterface; -class V4L2EncodeComponent : public C2Component, - public std::enable_shared_from_this<V4L2EncodeComponent> { -public: - // Create a new instance of the V4L2EncodeComponent. - static std::shared_ptr<C2Component> create(C2String name, c2_node_id_t id, - std::shared_ptr<C2ReflectorHelper> helper, - C2ComponentFactory::ComponentDeleter deleter); +std::optional<std::vector<VideoFramePlane>> getVideoFrameLayout(const C2ConstGraphicBlock& block, + VideoPixelFormat* format); + +std::optional<uint32_t> getVideoFrameStride(VideoPixelFormat format, ui::Size size); - virtual ~V4L2EncodeComponent() override; +class EncodeComponent : public C2Component, public std::enable_shared_from_this<EncodeComponent> { +public: + virtual ~EncodeComponent() override; // Implementation of the C2Component interface. c2_status_t start() override; @@ -54,7 +56,7 @@ public: c2_blocking_t mayBlock) override; std::shared_ptr<C2ComponentInterface> intf() override; -private: +protected: // Possible component states. enum class ComponentState { UNLOADED, // Initial state of component. @@ -63,11 +65,13 @@ private: ERROR, // An error occurred. }; - V4L2EncodeComponent(C2String name, c2_node_id_t id, - std::shared_ptr<V4L2EncodeInterface> interface); + EncodeComponent(C2String name, c2_node_id_t id, std::shared_ptr<EncodeInterface> interface); - V4L2EncodeComponent(const V4L2EncodeComponent&) = delete; - V4L2EncodeComponent& operator=(const V4L2EncodeComponent&) = delete; + EncodeComponent(const EncodeComponent&) = delete; + EncodeComponent& operator=(const EncodeComponent&) = delete; + + // Initialize the V4L2 device for encoding with the requested configuration. + virtual bool initializeEncoder() = 0; // Initialize the encoder on the encoder thread. void startTask(bool* success, ::base::WaitableEvent* done); @@ -87,8 +91,6 @@ private: // Set the component listener on the encoder thread. void setListenerTask(const std::shared_ptr<Listener>& listener, ::base::WaitableEvent* done); - // Initialize the V4L2 device for encoding with the requested configuration. - bool initializeEncoder(); // Update the |mBitrate| and |mFramerate| currently configured on the V4L2 device, to match the // values requested by the codec 2.0 framework. bool updateEncodingParameters(); @@ -132,14 +134,12 @@ private: // The underlying V4L2 encoder. std::unique_ptr<VideoEncoder> mEncoder; - // The number of concurrent encoder instances currently created. - static std::atomic<int32_t> sConcurrentInstances; // The component's registered name. const C2String mName; // The component's id, provided by the C2 framework upon initialization. const c2_node_id_t mId = 0; // The component's interface implementation. - const std::shared_ptr<V4L2EncodeInterface> mInterface; + const std::shared_ptr<EncodeInterface> mInterface; // Mutex used by the component to synchronize start/stop/reset/release calls, as the codec 2.0 // API can be accessed from any thread. @@ -153,6 +153,11 @@ private: // An input format convertor will be used if the device doesn't support the video's format. std::unique_ptr<FormatConverter> mInputFormatConverter; + // Pixel format of frames sent to V4L2 encoder, determined when the first input frame is queued. + VideoPixelFormat mInputPixelFormat = VideoPixelFormat::UNKNOWN; + // Layout of frames sent to V4L2 encoder, determined when the first input frame is queued. + std::vector<VideoFramePlane> mInputLayout; + // The bitrate currently configured on the v4l2 device. uint32_t mBitrate = 0; // The bitrate mode currently configured on the v4l2 device. @@ -175,15 +180,15 @@ private: std::atomic<ComponentState> mComponentState; // The encoder thread on which all interaction with the V4L2 device is performed. - ::base::Thread mEncoderThread{"V4L2EncodeComponentThread"}; + ::base::Thread mEncoderThread{"EncodeComponentThread"}; // The task runner on the encoder thread. scoped_refptr<::base::SequencedTaskRunner> mEncoderTaskRunner; // The WeakPtrFactory used to get weak pointers of this. - ::base::WeakPtr<V4L2EncodeComponent> mWeakThis; - ::base::WeakPtrFactory<V4L2EncodeComponent> mWeakThisFactory{this}; + ::base::WeakPtr<EncodeComponent> mWeakThis; + ::base::WeakPtrFactory<EncodeComponent> mWeakThisFactory{this}; }; } // namespace android -#endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_ENCODE_COMPONENT_H +#endif // ANDROID_V4L2_CODEC2_COMPONENTS_ENCODE_COMPONENT_H diff --git a/components/include/v4l2_codec2/components/V4L2EncodeInterface.h b/components/include/v4l2_codec2/components/EncodeInterface.h index fefebf0..e59f58c 100644 --- a/components/include/v4l2_codec2/components/V4L2EncodeInterface.h +++ b/components/include/v4l2_codec2/components/EncodeInterface.h @@ -1,9 +1,9 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. +// Copyright 2023 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_ENCODE_INTERFACE_H -#define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_ENCODE_INTERFACE_H +#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_ENCODE_INTERFACE_H +#define ANDROID_V4L2_CODEC2_COMPONENTS_ENCODE_INTERFACE_H #include <optional> #include <vector> @@ -14,6 +14,7 @@ #include <ui/Size.h> #include <util/C2InterfaceHelper.h> +#include <v4l2_codec2/common/Common.h> #include <v4l2_codec2/common/EncodeHelpers.h> namespace media { @@ -24,9 +25,10 @@ namespace android { // Codec 2.0 interface describing the V4L2EncodeComponent. This interface is used by the codec 2.0 // framework to query the component's capabilities and request configuration changes. -class V4L2EncodeInterface : public C2InterfaceHelper { +class EncodeInterface : public C2InterfaceHelper { public: - V4L2EncodeInterface(const C2String& name, std::shared_ptr<C2ReflectorHelper> helper); + EncodeInterface(const C2String& name, std::shared_ptr<C2ReflectorHelper> helper, + const SupportedCapabilities& caps); // Interfaces for the V4L2EncodeInterface // Note: these getters are not thread-safe. For dynamic parameters, component should use @@ -53,7 +55,7 @@ public: void setFramerate(uint32_t framerate) { mFrameRate->value = framerate; } protected: - void Initialize(const C2String& name); + void Initialize(const C2String& name, const SupportedCapabilities& caps); // Configurable parameter setters. static C2R H264ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::output>& info, @@ -70,6 +72,10 @@ protected: static C2R IntraRefreshPeriodSetter(bool mayBlock, C2P<C2StreamIntraRefreshTuning::output>& period); + // Recorded lowest configured level + // Is static for the need to use H264ProfileLevelSetter as a setter + static C2Config::level_t lowestConfigLevel; + // Constant parameters // The kind of the component; should be C2Component::KIND_ENCODER. @@ -121,4 +127,4 @@ protected: } // namespace android -#endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_ENCODE_INTERFACE_H +#endif // ANDROID_V4L2_CODEC2_COMPONENTS_ENCODE_INTERFACE_H diff --git a/components/include/v4l2_codec2/components/V4L2ComponentFactory.h b/components/include/v4l2_codec2/components/V4L2ComponentFactory.h deleted file mode 100644 index fc6abea..0000000 --- a/components/include/v4l2_codec2/components/V4L2ComponentFactory.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_COMPONENT_FACTORY_H -#define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_COMPONENT_FACTORY_H - -#include <memory> -#include <string> - -#include <C2ComponentFactory.h> -#include <util/C2InterfaceHelper.h> - -namespace android { - -class V4L2ComponentFactory : public C2ComponentFactory { -public: - static std::unique_ptr<V4L2ComponentFactory> create( - const std::string& componentName, std::shared_ptr<C2ReflectorHelper> reflector); - V4L2ComponentFactory(const std::string& componentName, bool isEncoder, - std::shared_ptr<C2ReflectorHelper> reflector); - ~V4L2ComponentFactory() override = default; - - // Implementation of C2ComponentFactory. - c2_status_t createComponent(c2_node_id_t id, std::shared_ptr<C2Component>* const component, - ComponentDeleter deleter) override; - c2_status_t createInterface(c2_node_id_t id, - std::shared_ptr<C2ComponentInterface>* const interface, - InterfaceDeleter deleter) override; - -private: - const std::string mComponentName; - const bool mIsEncoder; - std::shared_ptr<C2ReflectorHelper> mReflector; -}; - -} // namespace android - -#endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_COMPONENT_FACTORY_H diff --git a/components/include/v4l2_codec2/components/V4L2Decoder.h b/components/include/v4l2_codec2/components/V4L2Decoder.h deleted file mode 100644 index 2ecb3bd..0000000 --- a/components/include/v4l2_codec2/components/V4L2Decoder.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODER_H -#define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODER_H - -#include <stdint.h> - -#include <memory> -#include <optional> - -#include <base/callback.h> -#include <base/memory/weak_ptr.h> - -#include <ui/Rect.h> -#include <ui/Size.h> -#include <v4l2_codec2/common/V4L2Device.h> -#include <v4l2_codec2/common/VideoTypes.h> -#include <v4l2_codec2/components/VideoDecoder.h> -#include <v4l2_codec2/components/VideoFrame.h> -#include <v4l2_codec2/components/VideoFramePool.h> - -namespace android { - -class V4L2Decoder : public VideoDecoder { -public: - static std::unique_ptr<VideoDecoder> Create( - const VideoCodec& codec, const size_t inputBufferSize, const size_t minNumOutputBuffers, - GetPoolCB getPoolCB, OutputCB outputCb, ErrorCB errorCb, - scoped_refptr<::base::SequencedTaskRunner> taskRunner); - ~V4L2Decoder() override; - - void decode(std::unique_ptr<ConstBitstreamBuffer> buffer, DecodeCB decodeCb) override; - void drain(DecodeCB drainCb) override; - void flush() override; - -private: - enum class State { - Idle, // Not received any decode buffer after initialized, flushed, or drained. - Decoding, - Draining, - Error, - }; - static const char* StateToString(State state); - - struct DecodeRequest { - DecodeRequest(std::unique_ptr<ConstBitstreamBuffer> buffer, DecodeCB decodeCb) - : buffer(std::move(buffer)), decodeCb(std::move(decodeCb)) {} - DecodeRequest(DecodeRequest&&) = default; - ~DecodeRequest() = default; - - std::unique_ptr<ConstBitstreamBuffer> buffer; // nullptr means Drain - DecodeCB decodeCb; - }; - - V4L2Decoder(scoped_refptr<::base::SequencedTaskRunner> taskRunner); - bool start(const VideoCodec& codec, const size_t inputBufferSize, - const size_t minNumOutputBuffers, GetPoolCB getPoolCb, OutputCB outputCb, - ErrorCB errorCb); - bool setupInputFormat(const uint32_t inputPixelFormat, const size_t inputBufferSize); - void pumpDecodeRequest(); - - void serviceDeviceTask(bool event); - bool dequeueResolutionChangeEvent(); - bool changeResolution(); - bool setupOutputFormat(const ui::Size& size); - - void tryFetchVideoFrame(); - void onVideoFrameReady(std::optional<VideoFramePool::FrameWithBlockId> frameWithBlockId); - - std::optional<size_t> getNumOutputBuffers(); - std::optional<struct v4l2_format> getFormatInfo(); - Rect getVisibleRect(const ui::Size& codedSize); - bool sendV4L2DecoderCmd(bool start); - - void setState(State newState); - void onError(); - - std::unique_ptr<VideoFramePool> mVideoFramePool; - - scoped_refptr<V4L2Device> mDevice; - scoped_refptr<V4L2Queue> mInputQueue; - scoped_refptr<V4L2Queue> mOutputQueue; - - std::queue<DecodeRequest> mDecodeRequests; - std::map<int32_t, DecodeCB> mPendingDecodeCbs; - - size_t mMinNumOutputBuffers = 0; - GetPoolCB mGetPoolCb; - OutputCB mOutputCb; - DecodeCB mDrainCb; - ErrorCB mErrorCb; - - ui::Size mCodedSize; - Rect mVisibleRect; - - std::map<size_t, std::unique_ptr<VideoFrame>> mFrameAtDevice; - - // Block IDs can be arbitrarily large, but we only have a limited number of - // buffers. This maintains an association between a block ID and a specific - // V4L2 buffer index. - std::map<size_t, size_t> mBlockIdToV4L2Id; - - State mState = State::Idle; - - scoped_refptr<::base::SequencedTaskRunner> mTaskRunner; - - ::base::WeakPtr<V4L2Decoder> mWeakThis; - ::base::WeakPtrFactory<V4L2Decoder> mWeakThisFactory{this}; -}; - -} // namespace android - -#endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODER_H diff --git a/components/include/v4l2_codec2/components/V4L2Encoder.h b/components/include/v4l2_codec2/components/V4L2Encoder.h deleted file mode 100644 index d7b55c0..0000000 --- a/components/include/v4l2_codec2/components/V4L2Encoder.h +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_ENCODER_H -#define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_ENCODER_H - -#include <stdint.h> -#include <memory> -#include <optional> -#include <queue> -#include <vector> - -#include <base/memory/weak_ptr.h> -#include <base/sequenced_task_runner.h> -#include <ui/Size.h> - -#include <v4l2_codec2/common/Common.h> -#include <v4l2_codec2/components/VideoEncoder.h> - -namespace android { - -struct BitstreamBuffer; -struct VideoFramePlane; -class V4L2Device; -class V4L2Queue; - -class V4L2Encoder : public VideoEncoder { -public: - // Number of buffers on V4L2 device queues. - static constexpr size_t kInputBufferCount = 2; - static constexpr size_t kOutputBufferCount = 2; - - static std::unique_ptr<VideoEncoder> create( - C2Config::profile_t profile, std::optional<uint8_t> level, const ui::Size& visibleSize, - uint32_t stride, uint32_t keyFramePeriod, C2Config::bitrate_mode_t bitrateMode, - uint32_t bitrate, std::optional<uint32_t> peakBitrate, - FetchOutputBufferCB fetchOutputBufferCb, InputBufferDoneCB inputBufferDoneCb, - OutputBufferDoneCB outputBufferDoneCb, DrainDoneCB drainDoneCb, ErrorCB errorCb, - scoped_refptr<::base::SequencedTaskRunner> taskRunner); - ~V4L2Encoder() override; - - bool encode(std::unique_ptr<InputFrame> frame) override; - void drain() override; - void flush() override; - - bool setBitrate(uint32_t bitrate) override; - bool setPeakBitrate(uint32_t peakBitrate) override; - bool setFramerate(uint32_t framerate) override; - void requestKeyframe() override; - - VideoPixelFormat inputFormat() const override; - const ui::Size& visibleSize() const override { return mVisibleSize; } - const ui::Size& codedSize() const override { return mInputCodedSize; } - -private: - // Possible encoder states. - enum class State { - UNINITIALIZED, // Not initialized yet or initialization failed. - WAITING_FOR_INPUT_FRAME, // Waiting for frames to be queued. - WAITING_FOR_V4L2_BUFFER, // Waiting for V4L2 input queue buffers. - ENCODING, // Queuing input buffers. - DRAINING, // Draining encoder. - ERROR, // Encoder encountered an error. - }; - - // Contains a single encode request. - struct EncodeRequest { - EncodeRequest(std::unique_ptr<InputFrame> video_frame) - : video_frame(std::move(video_frame)) {} - ~EncodeRequest() = default; - EncodeRequest(EncodeRequest&&) = default; - EncodeRequest& operator=(EncodeRequest&&) = default; - - std::unique_ptr<InputFrame> video_frame; - bool end_of_stream = false; - }; - - V4L2Encoder(scoped_refptr<::base::SequencedTaskRunner> taskRunner, - FetchOutputBufferCB fetchOutputBufferCb, InputBufferDoneCB mInputBufferDoneCb, - OutputBufferDoneCB mOutputBufferDoneCb, DrainDoneCB drainDoneCb, ErrorCB errorCb); - - // Initialize the V4L2 encoder for specified parameters. - bool initialize(C2Config::profile_t outputProfile, std::optional<uint8_t> level, - const ui::Size& visibleSize, uint32_t stride, uint32_t keyFramePeriod, - C2Config::bitrate_mode_t bitrateMode, uint32_t bitrate, - std::optional<uint32_t> peakBitrate); - - // Handle the next encode request on the queue. - void handleEncodeRequest(); - // Handle a request to flush the encoder. - void handleFlushRequest(); - // Handle a request to drain the encoder. - void handleDrainRequest(); - // Called when draining the encoder has completed. - void onDrainDone(bool done); - - // Configure input format on the V4L2 device. - bool configureInputFormat(VideoPixelFormat inputFormat, uint32_t stride); - // Configure output format on the V4L2 device. - bool configureOutputFormat(C2Config::profile_t outputProfile); - // Configure required and optional controls on the V4L2 device. - bool configureDevice(C2Config::profile_t outputProfile, - std::optional<const uint8_t> outputH264Level); - // Configure required and optional H.264 controls on the V4L2 device. - bool configureH264(C2Config::profile_t outputProfile, - std::optional<const uint8_t> outputH264Level); - // Configure the specified bitrate mode on the V4L2 device. - bool configureBitrateMode(C2Config::bitrate_mode_t bitrateMode); - - // Attempt to start the V4L2 device poller. - bool startDevicePoll(); - // Attempt to stop the V4L2 device poller. - bool stopDevicePoll(); - // Called by the V4L2 device poller whenever an error occurred. - void onPollError(); - // Service I/O on the V4L2 device, called by the V4L2 device poller. - void serviceDeviceTask(bool event); - - // Enqueue an input buffer to be encoded on the device input queue. Returns whether the - // operation was successful. - bool enqueueInputBuffer(std::unique_ptr<InputFrame> frame); - // Enqueue an output buffer to store the encoded bitstream on the device output queue. Returns - // whether the operation was successful. - bool enqueueOutputBuffer(); - // Dequeue an input buffer the V4L2 device has finished encoding on the device input queue. - // Returns whether a buffer could be dequeued. - bool dequeueInputBuffer(); - // Dequeue an output buffer containing the encoded bitstream from the device output queue. - // Returns whether the operation was successful. - bool dequeueOutputBuffer(); - - // Create input buffers on the V4L2 device input queue. - bool createInputBuffers(); - // Create output buffers on the V4L2 device output queue. - bool createOutputBuffers(); - // Destroy the input buffers on the V4L2 device input queue. - void destroyInputBuffers(); - // Destroy the output buffers on the V4L2 device output queue. - void destroyOutputBuffers(); - - // Notify the client an error occurred and switch to the error state. - void onError(); - - // Change the state of the encoder. - void setState(State state); - // Get the specified encoder |state| as string. - static const char* stateToString(State state); - - // The list of currently queued encode requests. - std::queue<EncodeRequest> mEncodeRequests; - - // The video stream's visible size. - ui::Size mVisibleSize; - // The video stream's coded size. - ui::Size mInputCodedSize; - // The input layout configured on the V4L2 device. - std::optional<VideoFrameLayout> mInputLayout; - // Required output buffer byte size. - uint32_t mOutputBufferSize = 0; - - // How often we want to request the V4L2 device to create a key frame. - uint32_t mKeyFramePeriod = 0; - // Key frame counter, a key frame will be requested each time it reaches zero. - uint32_t mKeyFrameCounter = 0; - - // Whether we need to manually cache and prepend SPS and PPS to IDR frames. - bool mInjectParamsBeforeIDR = false; - // The latest cached SPS and PPS (without H.264 start code). - std::vector<uint8_t> mCachedSPS; - std::vector<uint8_t> mCachedPPS; - - // The V4L2 device and associated queues used to interact with the device. - scoped_refptr<V4L2Device> mDevice; - scoped_refptr<V4L2Queue> mInputQueue; - scoped_refptr<V4L2Queue> mOutputQueue; - - // List of frames associated with each buffer in the V4L2 device input queue. - std::vector<std::unique_ptr<InputFrame>> mInputBuffers; - // List of bitstream buffers associated with each buffer in the V4L2 device output queue. - std::vector<std::unique_ptr<BitstreamBuffer>> mOutputBuffers; - - // Callbacks to be triggered on various events. - FetchOutputBufferCB mFetchOutputBufferCb; - InputBufferDoneCB mInputBufferDoneCb; - OutputBufferDoneCB mOutputBufferDoneCb; - DrainDoneCB mDrainDoneCb; - ErrorCB mErrorCb; - - // The current state of the encoder. - State mState = State::UNINITIALIZED; - - scoped_refptr<::base::SequencedTaskRunner> mTaskRunner; - - ::base::WeakPtr<V4L2Encoder> mWeakThis; - ::base::WeakPtrFactory<V4L2Encoder> mWeakThisFactory{this}; -}; - -} // namespace android - -#endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_ENCODER_H diff --git a/components/include/v4l2_codec2/components/VideoEncoder.h b/components/include/v4l2_codec2/components/VideoEncoder.h index 7e5a3c2..eeb63c2 100644 --- a/components/include/v4l2_codec2/components/VideoEncoder.h +++ b/components/include/v4l2_codec2/components/VideoEncoder.h @@ -22,13 +22,21 @@ struct BitstreamBuffer; class VideoEncoder { public: + // Number of buffers on component delays. + static constexpr size_t kInputBufferCount = 2; + static constexpr size_t kOutputBufferCount = 2; + static constexpr VideoPixelFormat kInputPixelFormat = VideoPixelFormat::NV12; + + // The peak bitrate in function of the target bitrate, used when the bitrate mode is VBR. + static constexpr uint32_t kPeakBitrateMultiplier = 2u; + // The InputFrame class can be used to store raw video frames. // Note: The InputFrame does not take ownership of the data. The file descriptor is not // duplicated and the caller is responsible for keeping the data alive until the buffer // is returned by an InputBufferDoneCB() call. class InputFrame { public: - InputFrame(std::vector<int>&& fds, std::vector<VideoFramePlane>&& planes, + InputFrame(std::vector<int>&& fds, const std::vector<VideoFramePlane>& planes, VideoPixelFormat pixelFormat, uint64_t index, int64_t timestamp); ~InputFrame() = default; |