| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef MEDIA_GPU_V4L2_V4L2_DECODE_SURFACE_H_ |
| #define MEDIA_GPU_V4L2_V4L2_DECODE_SURFACE_H_ |
| |
| #include <vector> |
| |
| #include "base/functional/callback.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/sequence_checker.h" |
| #include "media/base/video_color_space.h" |
| #include "media/gpu/v4l2/v4l2_device.h" |
| #include "ui/gfx/geometry/rect.h" |
| |
| struct v4l2_ext_controls; |
| struct v4l2_buffer; |
| |
| namespace media { |
| |
| // A V4L2-specific decode surface generated by V4L2DecodeSurfaceHandler. |
| // It is used to store common picture metadata (e.g. visible_rect) and |
| // platform-specific metadata (e.g. {input,output}_record). All the methods |
| // should be called on the same sequence. |
| class V4L2DecodeSurface : public base::RefCounted<V4L2DecodeSurface> { |
| public: |
| REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE(); |
| |
| // V4L2DecodeSurfaceHandler maintains a list of InputRecords, which records |
| // the status and metadata of input buffers. |
| // |input_buffer| and |output_buffer| are the buffers to be used as input and |
| // output in this transaction. |
| // |frame| is optional, and allows the caller to keep a reference to a |
| // VideoFrame for as long as this decode surface exists. |
| // |secure_handle| is a reference to the secure input memory when doing |
| // secure decoding on ARM, zero otherwise. |
| V4L2DecodeSurface(V4L2WritableBufferRef input_buffer, |
| V4L2WritableBufferRef output_buffer, |
| scoped_refptr<FrameResource> frame, |
| uint64_t secure_handle); |
| |
| V4L2DecodeSurface(const V4L2DecodeSurface&) = delete; |
| V4L2DecodeSurface& operator=(const V4L2DecodeSurface&) = delete; |
| |
| // Mark the surface as decoded. This will also release all surfaces used for |
| // reference, as they are not needed anymore and execute the done callback, |
| // if not null. |
| void SetDecoded(); |
| void SetVisibleRect(const gfx::Rect& visible_rect); |
| void SetColorSpace(const VideoColorSpace& color_space); |
| // Take references to each reference surface and keep them until the |
| // target surface is decoded. |
| void SetReferenceSurfaces( |
| std::vector<scoped_refptr<V4L2DecodeSurface>> ref_surfaces); |
| // Set the callback that will be called when the surface is released. This |
| // method must be called one time at most. |
| void SetReleaseCallback(base::OnceClosure release_cb); |
| |
| // Update the passed v4l2_ext_controls structure to add the request |
| // information. |
| virtual void PrepareSetCtrls(struct v4l2_ext_controls* ctrls) const = 0; |
| // Return the ID to use in order to reference this frame. |
| virtual uint64_t GetReferenceID() const = 0; |
| // Set controls, queue buffers and submit the request corresponding to this |
| // surface. |
| virtual bool Submit() = 0; |
| |
| bool decoded() const { return decoded_; } |
| V4L2WritableBufferRef& input_buffer() { |
| return input_buffer_; |
| } |
| int output_record() const { return output_record_; } |
| V4L2WritableBufferRef& output_buffer() { |
| return output_buffer_; |
| } |
| scoped_refptr<FrameResource> frame() const { return frame_; } |
| gfx::Rect visible_rect() const { return visible_rect_; } |
| const VideoColorSpace& color_space() const { return color_space_; } |
| uint64_t secure_handle() const { return secure_handle_; } |
| |
| std::string ToString() const; |
| |
| protected: |
| friend class base::RefCounted<V4L2DecodeSurface>; |
| virtual ~V4L2DecodeSurface(); |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| private: |
| V4L2WritableBufferRef input_buffer_; |
| V4L2WritableBufferRef output_buffer_; |
| scoped_refptr<FrameResource> frame_; |
| |
| // The index of the corresponding output record. |
| const int output_record_; |
| // The visible size of the buffer. |
| gfx::Rect visible_rect_; |
| // The color space of the buffer. |
| VideoColorSpace color_space_; |
| |
| // Indicate whether the surface is decoded or not. |
| bool decoded_; |
| // Callback function which is called when the instance is destroyed. |
| base::OnceClosure release_cb_; |
| |
| // The decoded surfaces of the reference frames, which is kept until the |
| // surface has been decoded. |
| std::vector<scoped_refptr<V4L2DecodeSurface>> reference_surfaces_; |
| |
| // Secure handle that identifies the buffer w/ the decrypted contents in the |
| // secure world. Used to resolve to the corresponding FD that references the |
| // secure world memory (V4L2 will resolve that fd back to this same value). |
| uint64_t secure_handle_ = 0; |
| }; |
| |
| // An implementation of V4L2DecodeSurface that uses requests to associate |
| // controls/buffers to frames |
| class V4L2RequestDecodeSurface : public V4L2DecodeSurface { |
| public: |
| V4L2RequestDecodeSurface(V4L2WritableBufferRef input_buffer, |
| V4L2WritableBufferRef output_buffer, |
| scoped_refptr<FrameResource> frame, |
| uint64_t secure_handle, |
| V4L2RequestRef request_ref) |
| : V4L2DecodeSurface(std::move(input_buffer), |
| std::move(output_buffer), |
| std::move(frame), |
| secure_handle), |
| request_ref_(std::move(request_ref)) {} |
| |
| V4L2RequestDecodeSurface(const V4L2RequestDecodeSurface&) = delete; |
| V4L2RequestDecodeSurface& operator=(const V4L2RequestDecodeSurface&) = delete; |
| |
| void PrepareSetCtrls(struct v4l2_ext_controls* ctrls) const override; |
| uint64_t GetReferenceID() const override; |
| bool Submit() override; |
| |
| private: |
| ~V4L2RequestDecodeSurface() override = default; |
| |
| // Request reference used for the surface. |
| V4L2RequestRef request_ref_; |
| }; |
| |
| } // namespace media |
| |
| #endif // MEDIA_GPU_V4L2_V4L2_DECODE_SURFACE_H_ |