1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
// 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_
|