diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-06-25 07:42:13 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-06-25 07:42:13 +0000 |
commit | e30976ae7591dc6c02ca5715d9fccae688e7ad58 (patch) | |
tree | 397f41c8eb26b7ac27207cb06802b6602585e2cf | |
parent | 6be37d15ba4ff763d14515bf2b06448c3dc186a6 (diff) | |
parent | 8ceb3cc8d22071ea416a8fd0d3a954fd73efa189 (diff) | |
download | v4l2_codec2-e30976ae7591dc6c02ca5715d9fccae688e7ad58.tar.gz |
release-request-7bfcab52-d1c0-4256-9d6b-5b5092bc78ca-for-git_oc-mr1-release-4133428 snap-temp-L95800000077479875
Change-Id: I1eeb9b071f99cdde67581175e97d9fe39c4f6bf6
-rw-r--r-- | vda/Android.mk | 2 | ||||
-rw-r--r-- | vda/bitstream_buffer.cc | 27 | ||||
-rw-r--r-- | vda/bitstream_buffer.h | 76 | ||||
-rw-r--r-- | vda/picture.cc | 36 | ||||
-rw-r--r-- | vda/picture.h | 80 | ||||
-rw-r--r-- | vda/rect.h | 90 | ||||
-rw-r--r-- | vda/video_decode_accelerator.cc | 66 | ||||
-rw-r--r-- | vda/video_decode_accelerator.h | 307 |
8 files changed, 684 insertions, 0 deletions
diff --git a/vda/Android.mk b/vda/Android.mk index 4f3f649..fcb4082 100644 --- a/vda/Android.mk +++ b/vda/Android.mk @@ -5,10 +5,12 @@ LOCAL_CPP_EXTENSION:= .cc LOCAL_SRC_FILES:= \ bit_reader.cc \ bit_reader_core.cc \ + bitstream_buffer.cc \ h264_bit_reader.cc \ h264_decoder.cc \ h264_dpb.cc \ h264_parser.cc \ + picture.cc \ ranges.cc \ v4l2_device.cc \ video_codecs.cc \ diff --git a/vda/bitstream_buffer.cc b/vda/bitstream_buffer.cc new file mode 100644 index 0000000..4f71755 --- /dev/null +++ b/vda/bitstream_buffer.cc @@ -0,0 +1,27 @@ +// Copyright 2015 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. + +#include "bitstream_buffer.h" + +namespace media { + +BitstreamBuffer::BitstreamBuffer() + : BitstreamBuffer(-1, base::SharedMemoryHandle(), 0) {} + +BitstreamBuffer::BitstreamBuffer(int32_t id, + base::SharedMemoryHandle handle, + size_t size, + off_t offset, + base::TimeDelta presentation_timestamp) + : id_(id), + handle_(handle), + size_(size), + offset_(offset), + presentation_timestamp_(presentation_timestamp) {} + +BitstreamBuffer::BitstreamBuffer(const BitstreamBuffer& other) = default; + +BitstreamBuffer::~BitstreamBuffer() {} + +} // namespace media diff --git a/vda/bitstream_buffer.h b/vda/bitstream_buffer.h new file mode 100644 index 0000000..88555a28 --- /dev/null +++ b/vda/bitstream_buffer.h @@ -0,0 +1,76 @@ +// Copyright (c) 2011 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 MEDIA_BASE_BITSTREAM_BUFFER_H_ +#define MEDIA_BASE_BITSTREAM_BUFFER_H_ + +#include <stddef.h> +#include <stdint.h> + +#include "base/macros.h" +#include "base/memory/shared_memory.h" +#include "base/time/time.h" + +namespace media { + +// Indicates an invalid or missing timestamp. +constexpr base::TimeDelta kNoTimestamp = + base::TimeDelta::FromMicroseconds(std::numeric_limits<int64_t>::min()); + +// Class for passing bitstream buffers around. Does not take ownership of the +// data. This is the media-namespace equivalent of PP_VideoBitstreamBuffer_Dev. +class BitstreamBuffer { + public: + BitstreamBuffer(); + + // Constructs a new BitstreamBuffer. The content of the bitstream is located + // at |offset| bytes away from the start of the shared memory and the payload + // is |size| bytes. When not provided, the default value for |offset| is 0. + // |presentation_timestamp| is when the decoded frame should be displayed. + // When not provided, |presentation_timestamp| will be + // |media::kNoTimestamp|. + BitstreamBuffer(int32_t id, + base::SharedMemoryHandle handle, + size_t size, + off_t offset = 0, + base::TimeDelta presentation_timestamp = kNoTimestamp); + + BitstreamBuffer(const BitstreamBuffer& other); + + ~BitstreamBuffer(); + + int32_t id() const { return id_; } + base::SharedMemoryHandle handle() const { return handle_; } + + // The number of bytes of the actual bitstream data. It is the size of the + // content instead of the whole shared memory. + size_t size() const { return size_; } + + // The offset to the start of actual bitstream data in the shared memory. + off_t offset() const { return offset_; } + + // The timestamp is only valid if it's not equal to |media::kNoTimestamp|. + base::TimeDelta presentation_timestamp() const { + return presentation_timestamp_; + } + + void set_handle(const base::SharedMemoryHandle& handle) { handle_ = handle; } + + private: + int32_t id_; + base::SharedMemoryHandle handle_; + size_t size_; + off_t offset_; + + // This is only set when necessary. For example, AndroidVideoDecodeAccelerator + // needs the timestamp because the underlying decoder may require it to + // determine the output order. + base::TimeDelta presentation_timestamp_; + + // Allow compiler-generated copy & assign constructors. +}; + +} // namespace media + +#endif // MEDIA_BASE_BITSTREAM_BUFFER_H_ diff --git a/vda/picture.cc b/vda/picture.cc new file mode 100644 index 0000000..a086725 --- /dev/null +++ b/vda/picture.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2011 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. + +#include "picture.h" + +namespace media { + +PictureBuffer::PictureBuffer(int32_t id, const Size& size) + : id_(id), size_(size) {} + +PictureBuffer::PictureBuffer(int32_t id, + const Size& size, + VideoPixelFormat pixel_format) + : id_(id), + size_(size), + pixel_format_(pixel_format) {} + +PictureBuffer::PictureBuffer(const PictureBuffer& other) = default; + +PictureBuffer::~PictureBuffer() {} + +Picture::Picture(int32_t picture_buffer_id, + int32_t bitstream_buffer_id, + const Rect& visible_rect, + bool allow_overlay) + : picture_buffer_id_(picture_buffer_id), + bitstream_buffer_id_(bitstream_buffer_id), + visible_rect_(visible_rect), + allow_overlay_(allow_overlay) {} + +Picture::Picture(const Picture& other) = default; + +Picture::~Picture() = default; + +} // namespace media diff --git a/vda/picture.h b/vda/picture.h new file mode 100644 index 0000000..3dbf0e9 --- /dev/null +++ b/vda/picture.h @@ -0,0 +1,80 @@ +// Copyright (c) 2011 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 PICTURE_H_ +#define PICTURE_H_ + +#include <stdint.h> + +#include <vector> + +#include "rect.h" +#include "size.h" +#include "video_pixel_format.h" + +namespace media { + +// A picture buffer that has size and pixel format information. +class PictureBuffer { + public: + PictureBuffer(int32_t id, const Size& size); + PictureBuffer(int32_t id, + const Size& size, + VideoPixelFormat pixel_format); + PictureBuffer(const PictureBuffer& other); + ~PictureBuffer(); + + // Returns the client-specified id of the buffer. + int32_t id() const { return id_; } + + // Returns the size of the buffer. + Size size() const { return size_; } + + void set_size(const Size& size) { size_ = size; } + + VideoPixelFormat pixel_format() const { return pixel_format_; } + + private: + int32_t id_; + Size size_; + VideoPixelFormat pixel_format_ = PIXEL_FORMAT_UNKNOWN; +}; + +// A decoded picture frame. +class Picture { + public: + Picture(int32_t picture_buffer_id, + int32_t bitstream_buffer_id, + const Rect& visible_rect, + bool allow_overlay); + Picture(const Picture&); + ~Picture(); + + // Returns the id of the picture buffer where this picture is contained. + int32_t picture_buffer_id() const { return picture_buffer_id_; } + + // Returns the id of the bitstream buffer from which this frame was decoded. + int32_t bitstream_buffer_id() const { return bitstream_buffer_id_; } + + void set_bitstream_buffer_id(int32_t bitstream_buffer_id) { + bitstream_buffer_id_ = bitstream_buffer_id; + } + + // Returns the visible rectangle of the picture. Its size may be smaller + // than the size of the PictureBuffer, as it is the only visible part of the + // Picture contained in the PictureBuffer. + Rect visible_rect() const { return visible_rect_; } + + bool allow_overlay() const { return allow_overlay_; } + + private: + int32_t picture_buffer_id_; + int32_t bitstream_buffer_id_; + Rect visible_rect_; + bool allow_overlay_; +}; + +} // namespace media + +#endif // PICTURE_H_ diff --git a/vda/rect.h b/vda/rect.h new file mode 100644 index 0000000..d9640b2 --- /dev/null +++ b/vda/rect.h @@ -0,0 +1,90 @@ +// Copyright 2017 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. + +// Defines a simple integer rectangle class. The containment semantics +// are array-like; that is, the coordinate (x, y) is considered to be +// contained by the rectangle, but the coordinate (x + width, y) is not. +// The class will happily let you create malformed rectangles (that is, +// rectangles with negative width and/or height), but there will be assertions +// in the operations (such as Contains()) to complain in this case. + +#ifndef RECT_H_ +#define RECT_H_ + +#include <string> + +#include "base/strings/stringprintf.h" +#include "size.h" + +namespace media { + +// Helper struct for rect to replace gfx::Rect usage from original code. +// Only partial functions of gfx::Rect is implemented here. +class Rect { + public: + Rect() : x_(0), y_(0), size_(0, 0) {} + Rect(int width, int height) : x_(0), y_(0), size_(width, height) {} + Rect(int x, int y, int width, int height) + : x_(x), y_(y), size_(width, height) {} + explicit Rect(const Size& size) : x_(0), y_(0), size_(size) {} + + int x() const { return x_; } + void set_x(int x) { x_ = x; } + + int y() const { return y_; } + void set_y(int y) { y_ = y; } + + int width() const { return size_.width(); } + void set_width(int width) { size_.set_width(width); } + + int height() const { return size_.height(); } + void set_height(int height) { size_.set_height(height); } + + const Size& size() const { return size_; } + void set_size(const Size& size) { + set_width(size.width()); + set_height(size.height()); + } + + constexpr int right() const { return x() + width(); } + constexpr int bottom() const { return y() + height(); } + + void SetRect(int x, int y, int width, int height) { + set_x(x); + set_y(y); + set_width(width); + set_height(height); + } + + // Returns true if the area of the rectangle is zero. + bool IsEmpty() const { return size_.IsEmpty(); } + + // Returns true if this rectangle contains the specified rectangle. + bool Contains(const Rect& rect) const { + return (rect.x() >= x() && rect.right() <= right() && rect.y() >= y() && + rect.bottom() <= bottom()); + } + + std::string ToString() const { + return base::StringPrintf("(%d,%d) %s", + x_, y_, size().ToString().c_str()); + } + + private: + int x_; + int y_; + Size size_; +}; + +inline bool operator==(const Rect& lhs, const Rect& rhs) { + return lhs.x() == rhs.x() && lhs.y() == rhs.y() && lhs.size() == rhs.size(); +} + +inline bool operator!=(const Rect& lhs, const Rect& rhs) { + return !(lhs == rhs); +} + +} // namespace media + +#endif // RECT_H_ diff --git a/vda/video_decode_accelerator.cc b/vda/video_decode_accelerator.cc index 4948bf8..49afd44 100644 --- a/vda/video_decode_accelerator.cc +++ b/vda/video_decode_accelerator.cc @@ -2,13 +2,79 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/logging.h" + #include "video_decode_accelerator.h" namespace media { +VideoDecodeAccelerator::Config::Config() = default; +VideoDecodeAccelerator::Config::Config(const Config& config) = default; + +VideoDecodeAccelerator::Config::Config(VideoCodecProfile video_codec_profile) + : profile(video_codec_profile) {} + +VideoDecodeAccelerator::Config::~Config() = default; + +std::string VideoDecodeAccelerator::Config::AsHumanReadableString() const { + std::ostringstream s; + s << "profile: " << GetProfileName(profile); + return s.str(); +} + +void VideoDecodeAccelerator::Client::NotifyInitializationComplete( + bool success) { + NOTREACHED() << "By default deferred initialization is not supported."; +} + +VideoDecodeAccelerator::~VideoDecodeAccelerator() {} + +bool VideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( + const base::WeakPtr<Client>& decode_client, + const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { + // Implementations in the process that VDA runs in must override this. + LOG(FATAL) << "This may only be called in the same process as VDA impl."; + return false; +} + +void VideoDecodeAccelerator::ImportBufferForPicture( + int32_t picture_buffer_id, + const std::vector<base::FileDescriptor>& dmabuf_fds) { + NOTREACHED() << "Buffer import not supported."; +} + VideoDecodeAccelerator::SupportedProfile::SupportedProfile() : profile(VIDEO_CODEC_PROFILE_UNKNOWN), encrypted_only(false) {} VideoDecodeAccelerator::SupportedProfile::~SupportedProfile() {} +VideoDecodeAccelerator::Capabilities::Capabilities() : flags(NO_FLAGS) {} + +VideoDecodeAccelerator::Capabilities::Capabilities(const Capabilities& other) = + default; + +VideoDecodeAccelerator::Capabilities::~Capabilities() {} + +std::string VideoDecodeAccelerator::Capabilities::AsHumanReadableString() + const { + std::ostringstream s; + s << "["; + for (const SupportedProfile& sp : supported_profiles) { + s << " " << GetProfileName(sp.profile) << ": " << sp.min_resolution.width() + << "x" << sp.min_resolution.height() << "->" << sp.max_resolution.width() + << "x" << sp.max_resolution.height(); + } + s << "]"; + return s.str(); +} + } // namespace media + +namespace std { + +void default_delete<media::VideoDecodeAccelerator>::operator()( + media::VideoDecodeAccelerator* vda) const { + vda->Destroy(); +} + +} // namespace std diff --git a/vda/video_decode_accelerator.h b/vda/video_decode_accelerator.h index d293e15..8343abe 100644 --- a/vda/video_decode_accelerator.h +++ b/vda/video_decode_accelerator.h @@ -7,8 +7,19 @@ #include <vector> +#include "base/file_descriptor_posix.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" + +#include "bitstream_buffer.h" +#include "picture.h" #include "size.h" #include "video_codecs.h" +#include "video_pixel_format.h" + +namespace base { +class SingleThreadTaskRunner; +} namespace media { @@ -28,8 +39,304 @@ class VideoDecodeAccelerator { bool encrypted_only; }; using SupportedProfiles = std::vector<SupportedProfile>; + + struct Capabilities { + Capabilities(); + Capabilities(const Capabilities& other); + ~Capabilities(); + + std::string AsHumanReadableString() const; + + // Flags that can be associated with a VDA. + enum Flags { + NO_FLAGS = 0, + + // Normally, the VDA is required to be able to provide all PictureBuffers + // to the client via PictureReady(), even if the client does not return + // any of them via ReusePictureBuffer(). The client is only required to + // return PictureBuffers when it holds all of them, if it wants to get + // more decoded output. See VideoDecoder::CanReadWithoutStalling for + // more context. + // If this flag is set, then the VDA does not make this guarantee. The + // client must return PictureBuffers to be sure that new frames will be + // provided via PictureReady. + NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE = 1 << 0, + + // Whether the VDA supports being configured with an output surface for + // it to render frames to. For example, SurfaceViews on Android. + SUPPORTS_EXTERNAL_OUTPUT_SURFACE = 1 << 1, + + // If set, the VDA will use deferred initialization if the config + // indicates that the client supports it as well. Refer to + // NotifyInitializationComplete for more details. + SUPPORTS_DEFERRED_INITIALIZATION = 1 << 2, + + // If set, video frames will have COPY_REQUIRED flag which will cause + // an extra texture copy during composition. + REQUIRES_TEXTURE_COPY = 1 << 3, + + // Whether the VDA supports encrypted streams or not. + SUPPORTS_ENCRYPTED_STREAMS = 1 << 4, + + // If set the decoder does not require a restart in order to switch to + // using an external output surface. + SUPPORTS_SET_EXTERNAL_OUTPUT_SURFACE = 1 << 5, + }; + + SupportedProfiles supported_profiles; + uint32_t flags; + }; + + // Enumeration of potential errors generated by the API. + // Note: Keep these in sync with PP_VideoDecodeError_Dev. Also do not + // rearrange, reuse or remove values as they are used for gathering UMA + // statistics. + enum Error { + // An operation was attempted during an incompatible decoder state. + ILLEGAL_STATE = 1, + // Invalid argument was passed to an API method. + INVALID_ARGUMENT, + // Encoded input is unreadable. + UNREADABLE_INPUT, + // A failure occurred at the browser layer or one of its dependencies. + // Examples of such failures include GPU hardware failures, GPU driver + // failures, GPU library failures, browser programming errors, and so on. + PLATFORM_FAILURE, + // Largest used enum. This should be adjusted when new errors are added. + ERROR_MAX = PLATFORM_FAILURE, + }; + + // Config structure contains parameters required for the VDA initialization. + struct Config { + // Specifies the allocation and handling mode for output PictureBuffers. + // When set to ALLOCATE, the VDA is expected to allocate backing memory + // for PictureBuffers at the time of AssignPictureBuffers() call. + // When set to IMPORT, the VDA will not allocate, but after receiving + // AssignPictureBuffers() call, it will expect a call to + // ImportBufferForPicture() for each PictureBuffer before use. + enum class OutputMode { + ALLOCATE, + IMPORT, + }; + + Config(); + Config(const Config& config); + + explicit Config(VideoCodecProfile profile); + + ~Config(); + + std::string AsHumanReadableString() const; + + // The video codec and profile. + VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; + + // Whether the client supports deferred initialization. + bool is_deferred_initialization_allowed = false; + + // Coded size of the video frame hint, subject to change. + Size initial_expected_coded_size = Size(320, 240); + + OutputMode output_mode = OutputMode::ALLOCATE; + + // The list of picture buffer formats that the client knows how to use. An + // empty list means any format is supported. + std::vector<VideoPixelFormat> supported_output_formats; + + // The H264 SPS and PPS configuration data. Not all clients populate these + // fields, so they should be parsed from the bitstream instead, if required. + // Each SPS and PPS is prefixed with the Annex B framing bytes: 0, 0, 0, 1. + std::vector<uint8_t> sps; + std::vector<uint8_t> pps; + }; + + // Interface for collaborating with picture interface to provide memory for + // output picture and blitting them. These callbacks will not be made unless + // Initialize() has returned successfully. + // This interface is extended by the various layers that relay messages back + // to the plugin, through the PPP_VideoDecoder_Dev interface the plugin + // implements. + class Client { + public: + // Notify the client that deferred initialization has completed successfully + // or not. This is required if and only if deferred initialization is + // supported by the VDA (see Capabilities), and it is supported by the + // client (see Config::is_deferred_initialization_allowed), and the initial + // call to VDA::Initialize returns true. + // The default implementation is a NOTREACHED, since deferred initialization + // is not supported by default. + virtual void NotifyInitializationComplete(bool success); + + // Callback to tell client how many and what size of buffers to provide. + // Note that the actual count provided through AssignPictureBuffers() can be + // larger than the value requested. + // |format| indicates what format the decoded frames will be produced in + // by the VDA, or PIXEL_FORMAT_UNKNOWN if the underlying platform handles + // this transparently. + virtual void ProvidePictureBuffers(uint32_t requested_num_of_buffers, + VideoPixelFormat format, + const Size& dimensions) = 0; + + // Callback to dismiss picture buffer that was assigned earlier. + virtual void DismissPictureBuffer(int32_t picture_buffer_id) = 0; + + // Callback to deliver decoded pictures ready to be displayed. + virtual void PictureReady(const Picture& picture) = 0; + + // Callback to notify that decoded has decoded the end of the current + // bitstream buffer. + virtual void NotifyEndOfBitstreamBuffer(int32_t bitstream_buffer_id) = 0; + + // Flush completion callback. + virtual void NotifyFlushDone() = 0; + + // Reset completion callback. + virtual void NotifyResetDone() = 0; + + // Callback to notify about decoding errors. Note that errors in + // Initialize() will not be reported here, but will instead be indicated by + // a false return value there. + virtual void NotifyError(Error error) = 0; + + protected: + virtual ~Client() {} + }; + + // Video decoder functions. + + // Initializes the video decoder with specific configuration. Called once per + // decoder construction. This call is synchronous and returns true iff + // initialization is successful, unless deferred initialization is used. + // + // By default, deferred initialization is not used. However, if Config:: + // is_deferred_initialization_allowed is set by the client, and if + // Capabilities::Flags::SUPPORTS_DEFERRED_INITIALIZATION is set by the VDA, + // and if VDA::Initialize returns true, then the client can expect a call to + // NotifyInitializationComplete with the actual success / failure of + // initialization. Note that a return value of false from VDA::Initialize + // indicates that initialization definitely failed, and no callback is needed. + // + // For encrypted video, only deferred initialization is supported and |config| + // must contain a valid |cdm_id|. + // + // Parameters: + // |config| contains the initialization parameters. + // |client| is the client of this video decoder. Does not take ownership of + // |client| which must be valid until Destroy() is called. + virtual bool Initialize(const Config& config, Client* client) = 0; + + // Decodes given bitstream buffer that contains at most one frame. Once + // decoder is done with processing |bitstream_buffer| it will call + // NotifyEndOfBitstreamBuffer() with the bitstream buffer id. + // Parameters: + // |bitstream_buffer| is the input bitstream that is sent for decoding. + virtual void Decode(const BitstreamBuffer& bitstream_buffer) = 0; + + // Assigns a set of texture-backed picture buffers to the video decoder. + // + // Ownership of each picture buffer remains with the client, but the client + // is not allowed to deallocate the buffer before the DismissPictureBuffer + // callback has been initiated for a given buffer. + // + // Parameters: + // |buffers| contains the allocated picture buffers for the output. Note + // that the count of buffers may be larger than the count requested through + // the call to Client::ProvidePictureBuffers(). + virtual void AssignPictureBuffers( + const std::vector<PictureBuffer>& buffers) = 0; + + // Imports |dmabuf_fds| as backing memory for picture buffer + // associated with |picture_buffer_id|. This can only be be used if the VDA + // has been Initialize()d with config.output_mode = IMPORT, and should be + // preceded by a call to AssignPictureBuffers() to set up the number of + // PictureBuffers and their details. + // After this call, the VDA becomes the owner of those file descriptors, + // and is responsible for closing it after use, also on import failure. + virtual void ImportBufferForPicture( + int32_t picture_buffer_id, + const std::vector<base::FileDescriptor>& dmabuf_fds); + + // Sends picture buffers to be reused by the decoder. This needs to be called + // for each buffer that has been processed so that decoder may know onto which + // picture buffers it can write the output to. + // + // Parameters: + // |picture_buffer_id| id of the picture buffer that is to be reused. + virtual void ReusePictureBuffer(int32_t picture_buffer_id) = 0; + + // Flushes the decoder: all pending inputs will be decoded and pictures handed + // back to the client, followed by NotifyFlushDone() being called on the + // client. Can be used to implement "end of stream" notification. + virtual void Flush() = 0; + + // Resets the decoder: all pending inputs are dropped immediately and the + // decoder returned to a state ready for further Decode()s, followed by + // NotifyResetDone() being called on the client. Can be used to implement + // "seek". After Flush is called, it is OK to call Reset before receiving + // NotifyFlushDone() and VDA should cancel the flush. Note NotifyFlushDone() + // may be on the way to the client. If client gets NotifyFlushDone(), it + // should be before NotifyResetDone(). + virtual void Reset() = 0; + + // Destroys the decoder: all pending inputs are dropped immediately and the + // component is freed. This call may asynchornously free system resources, + // but its client-visible effects are synchronous. After this method returns + // no more callbacks will be made on the client. Deletes |this| + // unconditionally, so make sure to drop all pointers to it! + virtual void Destroy() = 0; + + // TO BE CALLED IN THE SAME PROCESS AS THE VDA IMPLEMENTATION ONLY. + // + // A decode "task" is a sequence that includes a Decode() call from Client, + // as well as corresponding callbacks to return the input BitstreamBuffer + // after use, and the resulting output Picture(s). + // + // If the Client can support running these three calls on a separate thread, + // it may call this method to try to set up the VDA implementation to do so. + // If the VDA can support this as well, return true, otherwise return false. + // If true is returned, the client may submit each Decode() call (but no other + // calls) on |decode_task_runner|, and should then expect that + // NotifyEndOfBitstreamBuffer() and PictureReady() callbacks may come on + // |decode_task_runner| as well, called on |decode_client|, instead of client + // provided to Initialize(). + // + // This method may be called at any time. + // + // NOTE 1: some callbacks may still have to come on the main thread and the + // Client should handle both callbacks coming on main and |decode_task_runner| + // thread. + // + // NOTE 2: VDA implementations of Decode() must return as soon as possible and + // never block, as |decode_task_runner| may be a latency critical thread + // (such as the GPU IO thread). + // + // One application of this is offloading the GPU Child thread. In general, + // calls to VDA in GPU process have to be done on the GPU Child thread, as + // they may require GL context to be current. However, some VDAs may be able + // to run decode operations without GL context, which helps reduce latency and + // offloads the GPU Child thread. + virtual bool TryToSetupDecodeOnSeparateThread( + const base::WeakPtr<Client>& decode_client, + const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner); + + protected: + // Do not delete directly; use Destroy() or own it with a scoped_ptr, which + // will Destroy() it properly by default. + virtual ~VideoDecodeAccelerator(); }; } // namespace media +namespace std { + +// Specialize std::default_delete so that +// std::unique_ptr<VideoDecodeAccelerator> uses "Destroy()" instead of trying to +// use the destructor. +template <> +struct default_delete<media::VideoDecodeAccelerator> { + void operator()(media::VideoDecodeAccelerator* vda) const; +}; + +} // namespace std + #endif // VIDEO_DECODE_ACCELERATOR_H_ |