| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_CHROMEOS_CAMERA_MJPEG_DECODE_ACCELERATOR_H_ |
| #define COMPONENTS_CHROMEOS_CAMERA_MJPEG_DECODE_ACCELERATOR_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| #include <sys/types.h> |
| |
| #include "base/files/scoped_file.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "media/base/bitstream_buffer.h" |
| |
| namespace media { |
| class VideoFrame; |
| } |
| |
| namespace chromeos_camera { |
| |
| // MJPEG decoder interface. |
| // The input are JPEG images including headers (Huffman tables may be omitted). |
| // The decoder will convert to the output color format if the input color format |
| // or subsampling does not match that and if it is capable of doing so. The |
| // client is responsible for allocating buffers and keeps the ownership of them. |
| // The intended use case of this interface is decoding MJPEG images coming |
| // from camera capture. It can also be used for normal still JPEG image |
| // decoding, but normal JPEG images may use more JPEG features that may not be |
| // supported by a particular accelerator implementation and/or platform. |
| class MjpegDecodeAccelerator { |
| public: |
| // Callback for JPEG decoder initialization. |
| typedef base::OnceCallback<void(bool success)> InitCB; |
| |
| static const int32_t kInvalidTaskId = -1; |
| |
| // Enumeration of decode errors generated by NotifyError callback. These |
| // values are persisted to logs. Entries should not be renumbered and numeric |
| // values should never be reused. |
| enum Error { |
| // No error. Decode succeeded. |
| NO_ERRORS = 0, |
| // Invalid argument was passed to an API method, e.g. the output buffer is |
| // too small, JPEG width/height are too big for JDA. |
| INVALID_ARGUMENT = 1, |
| // Encoded input is unreadable, e.g. failed to map on another process. |
| UNREADABLE_INPUT = 2, |
| // Failed to parse compressed JPEG picture. |
| PARSE_JPEG_FAILED = 3, |
| // Failed to decode JPEG due to unsupported JPEG features, such as profiles, |
| // coding mode, or color formats. |
| UNSUPPORTED_JPEG = 4, |
| // A fatal failure occurred in the GPU process layer or one of its |
| // dependencies. Examples of such failures include hardware failures, |
| // driver failures, library failures, browser programming errors, and so |
| // on. Client is responsible for destroying JDA after receiving this. |
| PLATFORM_FAILURE = 5, |
| // Largest used enum. This should be adjusted when new errors are added. |
| MJDA_ERROR_CODE_MAX = PLATFORM_FAILURE, |
| }; |
| |
| class Client { |
| public: |
| // Callback called after each successful Decode(). |
| // Parameters: |
| // |task_id| is the id passed to Decode() call. |
| virtual void VideoFrameReady(int32_t task_id) = 0; |
| |
| // Callback to notify errors. Client is responsible for destroying JDA when |
| // receiving a fatal error, i.e. PLATFORM_FAILURE. For other errors, client |
| // is informed about the buffer that failed to decode and may continue |
| // using the same instance of JDA. |
| // Parameters: |
| // |error| is the error code. |
| // |task_id| is the id passed to Decode() call that resulted in the |
| // recoverable error. For PLATFORM_FAILURE, |task_id| may be |
| // |kInvalidTaskId| if the error was not related to any particular buffer |
| // being processed. |
| virtual void NotifyError(int32_t task_id, Error error) = 0; |
| |
| protected: |
| virtual ~Client() = default; |
| }; |
| |
| // Destroys the decoder: all pending inputs are dropped immediately. This |
| // call may asynchronously free system resources, but its client-visible |
| // effects are synchronous. After destructor returns, no more callbacks |
| // will be made on the client. |
| virtual ~MjpegDecodeAccelerator() = 0; |
| |
| // Initializes the MJPEG decoder. Should be called once per decoder |
| // construction. This call is asynchronous and executes |init_cb| upon |
| // completion. Parameters: |
| // |client| is the Client interface for decode callback. The provided |
| // pointer must be valid until destructor is called. |
| // |init_cb| is the MJPEG decoder initialization status report callback. |
| // |
| // |init_cb| is called on the same thread as InitializeAsync() and can |
| // potentially be called even after the MjpegDecodeAccelerator destructor. |
| virtual void InitializeAsync(Client* client, InitCB init_cb) {} |
| |
| // Decodes the given bitstream buffer that contains one JPEG frame. It |
| // supports at least baseline encoding defined in JPEG ISO/IEC 10918-1. The |
| // decoder will convert the output to |video_frame->format()| or return |
| // PLATFORM_FAILURE if it cannot convert. |
| // Parameters: |
| // |bitstream_buffer| contains encoded JPEG frame. |
| // |video_frame| contains an allocated video frame for the output, backed |
| // with an UnsafeSharedMemoryRegion or DMA buffer. |
| // |
| // Client is responsible for filling the |video_frame->coded_size()|, |
| // |video_frame->visible_rect()|, and allocating its backing buffer. For |
| // unsafe shared memory backed VideoFrames, I420 and NV12 formats are |
| // supported. For DMA-buf backed VideoFrames, the supported formats depend on |
| // the underlying hardware implementation. After decode completes, the |
| // decoded JPEG frame will be filled into the |video_frame|. Ownership of the |
| // |bitstream_buffer| and |video_frame| remains with the client. The client |
| // is not allowed to deallocate them before VideoFrameReady or NotifyError() |
| // is invoked for given id of |bitstream_buffer|, or destructor returns. |
| virtual void Decode(media::BitstreamBuffer bitstream_buffer, |
| scoped_refptr<media::VideoFrame> video_frame) = 0; |
| |
| // The same as above but the JPEG image is stored in a DMA buffer. |
| // Parameters: |
| // |src_dmabuf_fd| contains encoded JPEG frame. |
| // |src_size| is the size of the JPEG frame. |
| // |src_offset| is the offset at which the JPEG data starts. |
| // |dst_frame| contains an allocated video frame for the output, backed with |
| // an UnsafeSharedMemoryRegion or DMA buffer. |
| virtual void Decode(int32_t task_id, |
| base::ScopedFD src_dmabuf_fd, |
| size_t src_size, |
| off_t src_offset, |
| scoped_refptr<media::VideoFrame> dst_frame) = 0; |
| |
| // Returns true when the JPEG decoder is supported. This can be called before |
| // Initialize(). |
| virtual bool IsSupported() = 0; |
| }; |
| |
| } // namespace chromeos_camera |
| |
| #endif // COMPONENTS_CHROMEOS_CAMERA_MJPEG_DECODE_ACCELERATOR_H_ |