1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef MEDIA_FILTERS_VPX_VIDEO_DECODER_H_
6 #define MEDIA_FILTERS_VPX_VIDEO_DECODER_H_
8 #include "base/functional/callback.h"
9 #include "base/sequence_checker.h"
10 #include "media/base/supported_video_decoder_config.h"
11 #include "media/base/video_decoder.h"
12 #include "media/base/video_decoder_config.h"
13 #include "media/base/video_frame.h"
14 #include "media/base/video_frame_pool.h"
15 #include "media/filters/frame_buffer_pool.h"
16 #include "media/filters/offloading_video_decoder.h"
22 class FrameBufferPool;
24 // Libvpx video decoder wrapper.
25 // Note: VpxVideoDecoder accepts only YV12A VP8 content or VP9 content. This is
26 // done to avoid usurping FFmpeg for all VP8 decoding, because the FFmpeg VP8
27 // decoder is faster than the libvpx VP8 decoder.
28 // Alpha channel, if any, is sent in the DecoderBuffer's side_data() as a frame
29 // on its own of which the Y channel is taken [1].
30 // [1] http://wiki.webmproject.org/alpha-channel
31 class MEDIA_EXPORT VpxVideoDecoder : public OffloadableVideoDecoder {
33 static SupportedVideoDecoderConfigs SupportedConfigs();
35 explicit VpxVideoDecoder(OffloadState offload_state = OffloadState::kNormal);
37 VpxVideoDecoder(const VpxVideoDecoder&) = delete;
38 VpxVideoDecoder& operator=(const VpxVideoDecoder&) = delete;
40 ~VpxVideoDecoder() override;
42 // VideoDecoder implementation.
43 VideoDecoderType GetDecoderType() const override;
44 void Initialize(const VideoDecoderConfig& config,
46 CdmContext* cdm_context,
48 const OutputCB& output_cb,
49 const WaitingCB& waiting_cb) override;
50 void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) override;
51 void Reset(base::OnceClosure reset_cb) override;
53 // OffloadableVideoDecoder implementation.
54 void Detach() override;
56 void force_allocation_error_for_testing() {
57 memory_pool_->force_allocation_error_for_testing();
61 enum class DecoderState { kUninitialized, kNormal, kDecodeFinished, kError };
63 // Return values for decoding alpha plane.
64 enum AlphaDecodeStatus {
65 kAlphaPlaneProcessed, // Alpha plane (if found) was decoded successfully.
66 kNoAlphaPlaneData, // Alpha plane was found, but decoder did not return any
68 kAlphaPlaneError // Fatal error occured when trying to decode alpha plane.
71 // Handles (re-)initializing the decoder with a (new) config.
72 // Returns true when initialization was successful.
73 bool ConfigureDecoder(const VideoDecoderConfig& config);
77 // Try to decode |buffer| into |video_frame|. Return true if all decoding
78 // succeeded. Note that decoding can succeed and still |video_frame| be
79 // nullptr if there has been a partial decoding.
80 bool VpxDecode(const DecoderBuffer* buffer,
81 scoped_refptr<VideoFrame>* video_frame);
83 bool CopyVpxImageToVideoFrame(const struct vpx_image* vpx_image,
84 const struct vpx_image* vpx_image_alpha,
85 scoped_refptr<VideoFrame>* video_frame);
87 AlphaDecodeStatus DecodeAlphaPlane(const struct vpx_image* vpx_image,
88 const struct vpx_image** vpx_image_alpha,
89 const DecoderBuffer* buffer);
91 // Indicates if the decoder is being wrapped by OffloadVideoDecoder; controls
92 // whether callbacks are bound to the current loop on calls.
93 const bool bind_callbacks_;
95 SEQUENCE_CHECKER(sequence_checker_);
97 // |state_| must only be read and written to on |offload_task_runner_| if it
98 // is non-null and there are outstanding tasks on the offload thread.
99 DecoderState state_ = DecoderState::kUninitialized;
103 VideoDecoderConfig config_;
105 std::unique_ptr<vpx_codec_ctx> vpx_codec_;
106 std::unique_ptr<vpx_codec_ctx> vpx_codec_alpha_;
108 // |memory_pool_| is a single-threaded memory pool used for VP9 decoding
109 // with no alpha. |frame_pool_| is used for all other cases.
110 scoped_refptr<FrameBufferPool> memory_pool_;
111 VideoFramePool frame_pool_;
114 // Helper class for creating a VpxVideoDecoder which will offload > 720p VP9
115 // content from the media thread.
116 class OffloadingVpxVideoDecoder : public OffloadingVideoDecoder {
118 OffloadingVpxVideoDecoder()
119 : OffloadingVideoDecoder(
121 std::vector<VideoCodec>(1, VideoCodec::kVP9),
122 std::make_unique<VpxVideoDecoder>(
123 OffloadableVideoDecoder::OffloadState::kOffloaded)) {}
128 #endif // MEDIA_FILTERS_VPX_VIDEO_DECODER_H_