summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h
blob: 4cc056b7be745a43081b779a4901bff3ecd41e6c (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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// 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.

#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIARECORDER_MEDIA_RECORDER_HANDLER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIARECORDER_MEDIA_RECORDER_HANDLER_H_

#include <memory>

#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_piece.h"
#include "base/threading/thread_checker.h"
#include "third_party/blink/public/web/modules/mediastream/encoded_video_frame.h"
#include "third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h"
#include "third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace media {
class AudioBus;
class AudioParameters;
class VideoFrame;
class WebmMuxer;
}  // namespace media

namespace blink {

class MediaRecorder;
class MediaStreamDescriptor;
struct WebMediaCapabilitiesInfo;
struct WebMediaConfiguration;

// MediaRecorderHandler orchestrates the creation, lifetime management and
// mapping between:
// - MediaStreamTrack(s) providing data,
// - {Audio,Video}TrackRecorders encoding that data,
// - a WebmMuxer class multiplexing encoded data into a WebM container, and
// - a single recorder client receiving this contained data.
// All methods are called on the same thread as construction and destruction,
// i.e. the Main Render thread. (Note that a BindToCurrentLoop is used to
// guarantee this, since VideoTrackRecorder sends back frames on IO thread.)
class MODULES_EXPORT MediaRecorderHandler final
    : public GarbageCollected<MediaRecorderHandler> {
 public:
  explicit MediaRecorderHandler(
      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
  ~MediaRecorderHandler();

  // MediaRecorder API isTypeSupported(), which boils down to
  // CanSupportMimeType() [1] "If true is returned from this method, it only
  // indicates that the MediaRecorder implementation is capable of recording
  // Blob objects for the specified MIME type. Recording may still fail if
  // sufficient resources are not available to support the concrete media
  // encoding."
  // [1] https://w3c.github.io/mediacapture-record/MediaRecorder.html#methods
  bool CanSupportMimeType(const String& type, const String& web_codecs);
  bool Initialize(MediaRecorder* client,
                  MediaStreamDescriptor* media_stream,
                  const String& type,
                  const String& codecs,
                  int32_t audio_bits_per_second,
                  int32_t video_bits_per_second);
  bool Start(int timeslice);
  void Stop();
  void Pause();
  void Resume();

  // Implements WICG Media Capabilities encodingInfo() call for local encoding.
  // https://wicg.github.io/media-capabilities/#media-capabilities-interface
  using OnMediaCapabilitiesEncodingInfoCallback =
      base::OnceCallback<void(std::unique_ptr<WebMediaCapabilitiesInfo>)>;
  void EncodingInfo(const WebMediaConfiguration& configuration,
                    OnMediaCapabilitiesEncodingInfoCallback cb);
  String ActualMimeType();

  void Trace(Visitor*) const;

 private:
  friend class MediaRecorderHandlerFixture;
  friend class MediaRecorderHandlerPassthroughTest;

  // Called to indicate there is encoded video data available. |encoded_alpha|
  // represents the encode output of alpha channel when available, can be
  // nullptr otherwise.
  void OnEncodedVideo(const media::WebmMuxer::VideoParameters& params,
                      std::string encoded_data,
                      std::string encoded_alpha,
                      base::TimeTicks timestamp,
                      bool is_key_frame);
  void OnPassthroughVideo(const media::WebmMuxer::VideoParameters& params,
                          std::string encoded_data,
                          std::string encoded_alpha,
                          base::TimeTicks timestamp,
                          bool is_key_frame);
  void HandleEncodedVideo(const media::WebmMuxer::VideoParameters& params,
                          std::string encoded_data,
                          std::string encoded_alpha,
                          base::TimeTicks timestamp,
                          bool is_key_frame);
  void OnEncodedAudio(const media::AudioParameters& params,
                      std::string encoded_data,
                      base::TimeTicks timestamp);
  void WriteData(base::StringPiece data);

  // Updates |video_tracks_|,|audio_tracks_| and returns true if any changed.
  bool UpdateTracksAndCheckIfChanged();

  // Stops recording if all sources are ended
  void OnSourceReadyStateChanged();

  void OnVideoFrameForTesting(scoped_refptr<media::VideoFrame> frame,
                              const base::TimeTicks& timestamp);
  void OnEncodedVideoFrameForTesting(scoped_refptr<EncodedVideoFrame> frame,
                                     const base::TimeTicks& timestamp);
  void OnAudioBusForTesting(const media::AudioBus& audio_bus,
                            const base::TimeTicks& timestamp);
  void SetAudioFormatForTesting(const media::AudioParameters& params);

  // Set to true if there is no MIME type configured upon Initialize()
  // and the video track's source supports encoded output, giving
  // this class the freedom to provide whatever it chooses to produce.
  bool passthrough_enabled_;

  // Sanitized video and audio bitrate settings passed on initialize().
  int32_t video_bits_per_second_;
  int32_t audio_bits_per_second_;

  // Video Codec and profile, VP8 is used by default.
  VideoTrackRecorder::CodecProfile video_codec_profile_;

  // Audio Codec, OPUS is used by default.
  AudioTrackRecorder::CodecId audio_codec_id_;

  // |recorder_| has no notion of time, thus may configure us via
  // start(timeslice) to notify it after a certain |timeslice_| has passed. We
  // use a moving |slice_origin_timestamp_| to track those time chunks.
  base::TimeDelta timeslice_;
  base::TimeTicks slice_origin_timestamp_;

  // The last seen video codec of the last received encoded video frame.
  base::Optional<media::VideoCodec> last_seen_codec_;

  bool invalidated_ = false;
  bool recording_;
  // The MediaStream being recorded.
  Member<MediaStreamDescriptor> media_stream_;
  HeapVector<Member<MediaStreamComponent>> video_tracks_;
  HeapVector<Member<MediaStreamComponent>> audio_tracks_;

  Member<MediaRecorder> recorder_;

  Vector<std::unique_ptr<VideoTrackRecorder>> video_recorders_;
  Vector<std::unique_ptr<AudioTrackRecorder>> audio_recorders_;

  // Worker class doing the actual Webm Muxing work.
  std::unique_ptr<media::WebmMuxer> webm_muxer_;

  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;

  DISALLOW_COPY_AND_ASSIGN(MediaRecorderHandler);
};

}  // namespace blink
#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIARECORDER_MEDIA_RECORDER_HANDLER_H_