1 // Copyright 2022 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_MOJO_SERVICES_STABLE_VIDEO_DECODER_SERVICE_H_
6 #define MEDIA_MOJO_SERVICES_STABLE_VIDEO_DECODER_SERVICE_H_
8 #include "base/memory/raw_ptr.h"
9 #include "base/sequence_checker.h"
10 #include "base/thread_annotations.h"
11 #include "base/unguessable_token.h"
12 #include "build/chromeos_buildflags.h"
13 #include "media/mojo/mojom/media_log.mojom.h"
14 #include "media/mojo/mojom/stable/stable_video_decoder.mojom.h"
15 #include "media/mojo/mojom/video_decoder.mojom.h"
16 #include "media/mojo/services/media_mojo_export.h"
17 #include "media/mojo/services/mojo_cdm_service_context.h"
18 #include "mojo/public/cpp/bindings/associated_receiver.h"
19 #include "mojo/public/cpp/bindings/associated_remote.h"
20 #include "mojo/public/cpp/bindings/receiver.h"
21 #include "mojo/public/cpp/bindings/remote.h"
23 #if BUILDFLAG(IS_CHROMEOS_ASH)
24 #include "chromeos/components/cdm_factory_daemon/remote_cdm_context.h"
25 #endif // BUILDFLAG(IS_CHROMEOS_ASH)
29 // A StableVideoDecoderService serves as an adapter between the
30 // stable::mojom::StableVideoDecoder interface and the mojom::VideoDecoder
31 // interface. This allows us to provide hardware video decoding capabilities to
32 // clients that may be using a different version of the
33 // stable::mojom::StableVideoDecoder interface, e.g., LaCrOS. A
34 // StableVideoDecoderService is intended to live in a video decoder process.
35 // This process can host multiple StableVideoDecoderServices, but the assumption
36 // is that they don't distrust each other. For example, they should all be
37 // serving the same renderer process.
39 // TODO(b/195769334): a StableVideoDecoderService should probably be responsible
40 // for checking incoming data to address issues that may arise due to the stable
41 // nature of the stable::mojom::StableVideoDecoder interface. For example,
42 // suppose the StableVideoDecoderService implements an older version of the
43 // interface relative to the one used by the client. If the client Initialize()s
44 // the StableVideoDecoderService with a VideoCodecProfile that's unsupported by
45 // the older version of the interface, the StableVideoDecoderService should
46 // reject that initialization. Conversely, the client of the
47 // StableVideoDecoderService should also check incoming data due to similar
49 class MEDIA_MOJO_EXPORT StableVideoDecoderService
50 : public stable::mojom::StableVideoDecoder,
51 public stable::mojom::VideoFrameHandleReleaser,
52 public mojom::VideoDecoderClient,
53 public mojom::MediaLog {
55 StableVideoDecoderService(
56 mojo::PendingRemote<stable::mojom::StableVideoDecoderTracker>
58 std::unique_ptr<mojom::VideoDecoder> dst_video_decoder,
59 MojoCdmServiceContext* cdm_service_context);
60 StableVideoDecoderService(const StableVideoDecoderService&) = delete;
61 StableVideoDecoderService& operator=(const StableVideoDecoderService&) =
63 ~StableVideoDecoderService() override;
65 // stable::mojom::StableVideoDecoder implementation.
66 void GetSupportedConfigs(GetSupportedConfigsCallback callback) final;
68 mojo::PendingAssociatedRemote<stable::mojom::VideoDecoderClient>
69 stable_video_decoder_client_remote,
70 mojo::PendingRemote<stable::mojom::MediaLog> stable_media_log_remote,
71 mojo::PendingReceiver<stable::mojom::VideoFrameHandleReleaser>
72 stable_video_frame_handle_releaser_receiver,
73 mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe,
74 const gfx::ColorSpace& target_color_space) final;
76 const VideoDecoderConfig& config,
78 mojo::PendingRemote<stable::mojom::StableCdmContext> cdm_context,
79 InitializeCallback callback) final;
80 void Decode(const scoped_refptr<DecoderBuffer>& buffer,
81 DecodeCallback callback) final;
82 void Reset(ResetCallback callback) final;
84 // mojom::stable::VideoFrameHandleReleaser implementation.
85 void ReleaseVideoFrame(const base::UnguessableToken& release_token) final;
87 // mojom::VideoDecoderClient implementation.
88 void OnVideoFrameDecoded(
89 const scoped_refptr<VideoFrame>& frame,
90 bool can_read_without_stalling,
91 const absl::optional<base::UnguessableToken>& release_token) final;
92 void OnWaiting(WaitingReason reason) final;
93 void RequestOverlayInfo(bool restart_for_transitions) final;
95 // mojom::MediaLog implementation.
96 void AddLogRecord(const MediaLogRecord& event) final;
99 void OnInitializeDone(InitializeCallback init_cb,
100 bool needs_transcryption,
101 const DecoderStatus& status,
102 bool needs_bitstream_conversion,
103 int32_t max_decode_requests,
104 VideoDecoderType decoder_type);
106 mojo::Remote<stable::mojom::StableVideoDecoderTracker> tracker_remote_
107 GUARDED_BY_CONTEXT(sequence_checker_);
109 // Incoming calls from the |dst_video_decoder_| to
110 // |video_decoder_client_receiver_| are forwarded to
111 // |stable_video_decoder_client_remote_|.
112 mojo::AssociatedReceiver<mojom::VideoDecoderClient>
113 video_decoder_client_receiver_ GUARDED_BY_CONTEXT(sequence_checker_);
114 mojo::AssociatedRemote<stable::mojom::VideoDecoderClient>
115 stable_video_decoder_client_remote_ GUARDED_BY_CONTEXT(sequence_checker_);
117 // Incoming calls from the |dst_video_decoder_| to |media_log_receiver_| are
118 // forwarded to |stable_media_log_remote_|.
119 mojo::Receiver<mojom::MediaLog> media_log_receiver_
120 GUARDED_BY_CONTEXT(sequence_checker_);
121 mojo::Remote<stable::mojom::MediaLog> stable_media_log_remote_
122 GUARDED_BY_CONTEXT(sequence_checker_);
124 // Incoming requests from the client to
125 // |stable_video_frame_handle_releaser_receiver_| are forwarded to
126 // |video_frame_handle_releaser_remote_|.
127 mojo::Receiver<stable::mojom::VideoFrameHandleReleaser>
128 stable_video_frame_handle_releaser_receiver_
129 GUARDED_BY_CONTEXT(sequence_checker_);
130 mojo::Remote<mojom::VideoFrameHandleReleaser>
131 video_frame_handle_releaser_remote_ GUARDED_BY_CONTEXT(sequence_checker_);
133 // The incoming stable::mojom::StableVideoDecoder requests are forwarded to
134 // |dst_video_decoder_receiver_| through |dst_video_decoder_remote_|.
136 // Note: the implementation behind |dst_video_decoder_receiver_| (i.e.,
137 // |dst_video_decoder_|) lives in-process. The reason we don't just make calls
138 // directly to that implementation is that when we call Construct(), we need
139 // to pass a mojo::PendingAssociatedRemote which needs to be sent over an
140 // existing pipe before using it to make calls.
141 std::unique_ptr<mojom::VideoDecoder> dst_video_decoder_
142 GUARDED_BY_CONTEXT(sequence_checker_);
143 mojo::Receiver<mojom::VideoDecoder> dst_video_decoder_receiver_
144 GUARDED_BY_CONTEXT(sequence_checker_);
145 mojo::Remote<mojom::VideoDecoder> dst_video_decoder_remote_
146 GUARDED_BY_CONTEXT(sequence_checker_);
148 #if BUILDFLAG(IS_CHROMEOS_ASH)
149 // Used for registering the |remote_cdm_context_| so that it can be resolved
150 // from the |cdm_id_| later.
151 const raw_ptr<MojoCdmServiceContext> cdm_service_context_
152 GUARDED_BY_CONTEXT(sequence_checker_);
153 scoped_refptr<chromeos::RemoteCdmContext> remote_cdm_context_
154 GUARDED_BY_CONTEXT(sequence_checker_);
155 #endif // BUILDFLAG(IS_CHROMEOS_ASH)
157 absl::optional<base::UnguessableToken> cdm_id_
158 GUARDED_BY_CONTEXT(sequence_checker_);
160 SEQUENCE_CHECKER(sequence_checker_);
165 #endif // MEDIA_MOJO_SERVICES_STABLE_VIDEO_DECODER_SERVICE_H_