summaryrefslogtreecommitdiff
path: root/chromium/media/mojo/services/mojo_video_decoder_service.h
blob: 45a1a5723ab9047bd97f4e6a081838b75c6cc02d (plain)
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
// Copyright 2016 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_MOJO_SERVICES_MOJO_VIDEO_DECODER_SERVICE_H_
#define MEDIA_MOJO_SERVICES_MOJO_VIDEO_DECODER_SERVICE_H_

#include <map>
#include <memory>

#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/unguessable_token.h"
#include "media/base/cdm_context.h"
#include "media/base/decode_status.h"
#include "media/base/overlay_info.h"
#include "media/base/video_decoder.h"
#include "media/mojo/mojom/video_decoder.mojom.h"
#include "media/mojo/services/media_mojo_export.h"
#include "media/mojo/services/mojo_media_client.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace media {

class DecoderBuffer;
class MojoCdmServiceContext;
class MojoDecoderBufferReader;
class MojoMediaClient;
class MojoMediaLog;
class VideoFrame;

// Implementation of a mojom::VideoDecoder which runs in the GPU process,
// and wraps a media::VideoDecoder.
class MEDIA_MOJO_EXPORT MojoVideoDecoderService final
    : public mojom::VideoDecoder {
 public:
  explicit MojoVideoDecoderService(
      MojoMediaClient* mojo_media_client,
      MojoCdmServiceContext* mojo_cdm_service_context);
  ~MojoVideoDecoderService() final;

  // mojom::VideoDecoder implementation
  void GetSupportedConfigs(GetSupportedConfigsCallback callback) final;
  void Construct(
      mojo::PendingAssociatedRemote<mojom::VideoDecoderClient> client,
      mojo::PendingAssociatedRemote<mojom::MediaLog> media_log,
      mojo::PendingReceiver<mojom::VideoFrameHandleReleaser>
          video_frame_handle_receiver,
      mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe,
      mojom::CommandBufferIdPtr command_buffer_id,
      const gfx::ColorSpace& target_color_space) final;
  void Initialize(const VideoDecoderConfig& config,
                  bool low_delay,
                  const absl::optional<base::UnguessableToken>& cdm_id,
                  InitializeCallback callback) final;
  void Decode(mojom::DecoderBufferPtr buffer, DecodeCallback callback) final;
  void Reset(ResetCallback callback) final;
  void OnOverlayInfoChanged(const OverlayInfo& overlay_info) final;

 private:
  // Helper methods so that we can bind them with a weak pointer to avoid
  // running mojom::VideoDecoder callbacks after connection error happens and
  // |this| is deleted. It's not safe to run the callbacks after a connection
  // error.
  void OnDecoderInitialized(Status status);
  void OnReaderRead(DecodeCallback callback,
                    std::unique_ptr<ScopedDecodeTrace> trace_event,
                    scoped_refptr<DecoderBuffer> buffer);
  void OnDecoderDecoded(DecodeCallback callback,
                        std::unique_ptr<ScopedDecodeTrace> trace_event,
                        media::Status status);

  // Called by |mojo_decoder_buffer_reader_| when reset is finished.
  void OnReaderFlushed();

  void OnDecoderReset();
  void OnDecoderOutput(scoped_refptr<VideoFrame> frame);

  void OnDecoderWaiting(WaitingReason reason);

  void OnDecoderRequestedOverlayInfo(
      bool restart_for_transitions,
      ProvideOverlayInfoCB provide_overlay_info_cb);

  // Whether this instance is active (Decode() was called at least once).
  bool is_active_instance_ = false;

  // Codec information stored via crash key.
  std::string codec_string_;

  // Decoder factory.
  MojoMediaClient* mojo_media_client_;

  // A helper object required to get the CDM from a CDM ID.
  MojoCdmServiceContext* const mojo_cdm_service_context_ = nullptr;

  // Channel for sending async messages to the client.
  mojo::AssociatedRemote<mojom::VideoDecoderClient> client_;

  // Proxy object for providing media log services.
  std::unique_ptr<MojoMediaLog> media_log_;

  // Holds VideoFrame references on behalf of the client, until the client
  // releases them or is disconnected.
  mojo::SelfOwnedReceiverRef<mojom::VideoFrameHandleReleaser>
      video_frame_handle_releaser_;

  // Helper for reading DecoderBuffer data from the DataPipe.
  std::unique_ptr<MojoDecoderBufferReader> mojo_decoder_buffer_reader_;

  // The CDM ID and the corresponding CdmContextRef, which must be held to keep
  // the CdmContext alive for the lifetime of the |decoder_|.
  absl::optional<base::UnguessableToken> cdm_id_;
  std::unique_ptr<CdmContextRef> cdm_context_ref_;

  std::unique_ptr<media::VideoDecoder> decoder_;

  InitializeCallback init_cb_;
  ResetCallback reset_cb_;

  ProvideOverlayInfoCB provide_overlay_info_cb_;

  base::WeakPtr<MojoVideoDecoderService> weak_this_;
  base::WeakPtrFactory<MojoVideoDecoderService> weak_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(MojoVideoDecoderService);
};

}  // namespace media

#endif  // MEDIA_MOJO_SERVICES_MOJO_VIDEO_DECODER_SERVICE_H_