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
media / mojo / common / mojo_decoder_buffer_converter.h [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_MOJO_COMMON_MOJO_DECODER_BUFFER_CONVERTER_H_
#define MEDIA_MOJO_COMMON_MOJO_DECODER_BUFFER_CONVERTER_H_
#include <memory>
#include "base/containers/circular_deque.h"
#include "base/memory/scoped_refptr.h"
#include "media/base/demuxer_stream.h"
#include "media/mojo/mojom/media_types.mojom.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/simple_watcher.h"
namespace media {
class DecoderBuffer;
// Creates mojo::DataPipe and sets `producer_handle` and `consumer_handle`.
// Returns true on success. Otherwise returns false and reset the handles.
bool CreateDataPipe(uint32_t capacity,
mojo::ScopedDataPipeProducerHandle* producer_handle,
mojo::ScopedDataPipeConsumerHandle* consumer_handle);
// Returns the default capacity to be used with MojoDecoderBufferReader and
// MojoDecoderBufferWriter for |type|.
uint32_t GetDefaultDecoderBufferConverterCapacity(DemuxerStream::Type type);
// Combines mojom::DecoderBuffers with data read from a DataPipe to produce
// media::DecoderBuffers (counterpart of MojoDecoderBufferWriter).
class MojoDecoderBufferReader {
public:
using ReadCB = base::OnceCallback<void(scoped_refptr<DecoderBuffer>)>;
// Creates a MojoDecoderBufferReader of |capacity| bytes and set the
// |producer_handle|.
static std::unique_ptr<MojoDecoderBufferReader> Create(
uint32_t capacity,
mojo::ScopedDataPipeProducerHandle* producer_handle);
// Hold the consumer handle to read DecoderBuffer data.
explicit MojoDecoderBufferReader(
mojo::ScopedDataPipeConsumerHandle consumer_handle);
MojoDecoderBufferReader(const MojoDecoderBufferReader&) = delete;
MojoDecoderBufferReader& operator=(const MojoDecoderBufferReader&) = delete;
~MojoDecoderBufferReader();
// Enqueues conversion of and reading data for a mojom::DecoderBuffer. Once
// the data has been read, |read_cb| will be called with the converted
// media::DecoderBuffer.
//
// |read_cb| will be called in the same order as ReadDecoderBuffer(). This
// order must match the order that the data was written into the DataPipe!
// Callbacks may run on the original stack, on a Mojo stack, or on a future
// ReadDecoderBuffer() stack.
//
// If reading fails (for example, if the DataPipe is closed), |read_cb| will
// be called with nullptr.
void ReadDecoderBuffer(mojom::DecoderBufferPtr buffer, ReadCB read_cb);
// Reads all pending data from the pipe and fire all pending ReadCBs, after
// which fire the |flush_cb|. No further ReadDecoderBuffer() or Flush() calls
// should be made before |flush_cb| is fired.
// Note that |flush_cb| may be called on the same call stack as this Flush()
// call if there are no pending reads.
void Flush(base::OnceClosure flush_cb);
// Whether there's any pending reads in |this|.
bool HasPendingReads() const;
private:
void CancelReadCB(ReadCB read_cb);
void CancelAllPendingReadCBs();
void CompleteCurrentRead();
void ScheduleNextRead();
void OnPipeReadable(MojoResult result, const mojo::HandleSignalsState& state);
void ProcessPendingReads();
void OnPipeError(MojoResult result);
// Read side of the DataPipe for receiving DecoderBuffer data.
mojo::ScopedDataPipeConsumerHandle consumer_handle_;
// Provides notification about |consumer_handle_| readiness.
mojo::SimpleWatcher pipe_watcher_;
bool armed_;
// Buffers waiting to be read in sequence.
base::circular_deque<scoped_refptr<DecoderBuffer>> pending_buffers_;
// Callbacks for pending buffers.
base::circular_deque<ReadCB> pending_read_cbs_;
// Callback for Flush().
base::OnceClosure flush_cb_;
// Number of bytes already read into the current buffer.
size_t bytes_read_;
};
// Converts media::DecoderBuffers to mojom::DecoderBuffers, writing the data
// part to a DataPipe (counterpart of MojoDecoderBufferReader).
//
// If necessary, writes to the DataPipe will be chunked to fit.
// MojoDecoderBufferWriter maintains an internal queue of buffers to enable
// this asynchronous process.
//
// On DataPipe closure, future calls to WriteDecoderBuffer() will return
// nullptr. There is no mechanism to determine which past writes were
// successful prior to the closure.
class MojoDecoderBufferWriter {
public:
// Creates a MojoDecoderBufferWriter of |capacity| bytes and set the
// |consumer_handle|.
static std::unique_ptr<MojoDecoderBufferWriter> Create(
uint32_t capacity,
mojo::ScopedDataPipeConsumerHandle* consumer_handle);
// Hold the producer handle to write DecoderBuffer data.
explicit MojoDecoderBufferWriter(
mojo::ScopedDataPipeProducerHandle producer_handle);
MojoDecoderBufferWriter(const MojoDecoderBufferWriter&) = delete;
MojoDecoderBufferWriter& operator=(const MojoDecoderBufferWriter&) = delete;
~MojoDecoderBufferWriter();
// Converts a media::DecoderBuffer to a mojom::DecoderBuffer and enqueues the
// data to be written to the DataPipe.
//
// Returns nullptr if the DataPipe is already closed.
mojom::DecoderBufferPtr WriteDecoderBuffer(
scoped_refptr<DecoderBuffer> media_buffer);
private:
void ScheduleNextWrite();
void OnPipeWritable(MojoResult result, const mojo::HandleSignalsState& state);
void ProcessPendingWrites();
void OnPipeError(MojoResult result);
// Write side of the DataPipe for sending DecoderBuffer data.
mojo::ScopedDataPipeProducerHandle producer_handle_;
// Provides notifications about |producer_handle_| readiness.
mojo::SimpleWatcher pipe_watcher_;
bool armed_;
// Buffers waiting to be written in sequence.
base::circular_deque<scoped_refptr<DecoderBuffer>> pending_buffers_;
// Number of bytes already written from the current buffer.
size_t bytes_written_;
};
} // namespace media
#endif // MEDIA_MOJO_COMMON_MOJO_DECODER_BUFFER_CONVERTER_H_