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

content / renderer / pepper / video_decoder_shim.h [blame]

// 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 CONTENT_RENDERER_PEPPER_VIDEO_DECODER_SHIM_H_
#define CONTENT_RENDERER_PEPPER_VIDEO_DECODER_SHIM_H_

#include <stdint.h>

#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "base/containers/queue.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "media/base/video_decoder_config.h"
#include "media/renderers/paint_canvas_video_renderer.h"
#include "media/video/video_decode_accelerator.h"
#include "ppapi/c/pp_codecs.h"
#include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"

namespace content {

class PepperVideoDecoderHost;

// This class is a shim to wrap a media::VideoDecoder so that it can be used
// by PepperVideoDecoderHost. This class should be constructed, used, and
// destructed on the main (render) thread.
class VideoDecoderShim {
 public:
  static std::unique_ptr<VideoDecoderShim> Create(PepperVideoDecoderHost* host,
                                                  uint32_t texture_pool_size,
                                                  bool use_hw_decoder);

  VideoDecoderShim(const VideoDecoderShim&) = delete;
  VideoDecoderShim& operator=(const VideoDecoderShim&) = delete;

  ~VideoDecoderShim();

  bool Initialize(media::VideoCodecProfile profile);
  void Decode(media::BitstreamBuffer bitstream_buffer);
  void ReuseSharedImage(const gpu::Mailbox& mailbox, gfx::Size size);
  void Flush();
  void Reset();
  void Destroy();

  const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider()
      const {
    return shared_main_thread_context_provider_;
  }

 private:
  enum State {
    UNINITIALIZED,
    DECODING,
    FLUSHING,
    RESETTING,
  };

  struct PendingDecode;
  struct PendingFrame;
  class DecoderImpl;

  VideoDecoderShim(PepperVideoDecoderHost* host,
                   uint32_t texture_pool_size,
                   bool use_hw_decoder,
                   scoped_refptr<viz::ContextProviderCommandBuffer>
                       shared_main_thread_context_provider);

  void OnInitializeFailed();
  void OnDecodeComplete(int32_t result, std::optional<uint32_t> decode_id);
  void OnOutputComplete(std::unique_ptr<PendingFrame> frame);
  void SendSharedImages();
  void OnResetComplete();
  void NotifyCompletedDecodes();
  // Call this whenever we change GL state that the plugin relies on, such as
  // creating picture textures.
  void FlushCommandBuffer();

  std::unique_ptr<DecoderImpl> decoder_impl_;
  State state_;

  raw_ptr<PepperVideoDecoderHost> host_;
  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
  scoped_refptr<viz::ContextProviderCommandBuffer>
      shared_main_thread_context_provider_;

  // The current decoded frame size.
  gfx::Size texture_size_;

  std::vector<gpu::Mailbox> available_shared_images_;

  // Queue of completed decode ids, for notifying the host.
  using CompletedDecodeQueue = base::queue<uint32_t>;
  CompletedDecodeQueue completed_decodes_;

  // Queue of decoded frames that await rgb->yuv conversion.
  using PendingFrameQueue = base::queue<std::unique_ptr<PendingFrame>>;
  PendingFrameQueue pending_frames_;

  // The optimal number of textures to allocate for decoder_impl_.
  uint32_t texture_pool_size_;

  uint32_t num_pending_decodes_;

  const bool use_hw_decoder_;

  std::unique_ptr<media::PaintCanvasVideoRenderer> video_renderer_;

  base::WeakPtrFactory<VideoDecoderShim> weak_ptr_factory_{this};
};

}  // namespace content

#endif  // CONTENT_RENDERER_PEPPER_VIDEO_DECODER_SHIM_H_