Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(568)

Side by Side Diff: chromecast/media/cma/ipc/media_message_fifo.h

Issue 2300993003: CmaRenderer is dead. Long live MojoRenderer. (Closed)
Patch Set: update OWNERS file Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CHROMECAST_MEDIA_CMA_IPC_MEDIA_MESSAGE_FIFO_H_
6 #define CHROMECAST_MEDIA_CMA_IPC_MEDIA_MESSAGE_FIFO_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <list>
12 #include <memory>
13
14 #include "base/atomicops.h"
15 #include "base/callback.h"
16 #include "base/logging.h"
17 #include "base/macros.h"
18 #include "base/memory/ref_counted.h"
19 #include "base/memory/weak_ptr.h"
20 #include "base/threading/thread_checker.h"
21
22 namespace chromecast {
23 namespace media {
24 class MediaMemoryChunk;
25 class MediaMessage;
26 class MediaMessageFlag;
27
28 // MediaMessageFifo is a lock free fifo implementation
29 // to pass audio/video data from one thread to another or from one process
30 // to another one (in that case using shared memory).
31 //
32 // Assuming the feeder and the consumer have a common block of shared memory
33 // (representing the serialized structure of the fifo),
34 // the feeder (which must be running on a single thread) instantiates its own
35 // instance of MediaMessageFifo, same applies to the consumer.
36 //
37 // Example: assuming the block of shared memory is given by |mem|, a typical
38 // feeder (using MediaMessageFifo instance fifo_feeder) will push messages
39 // in the following way:
40 // // Create a dummy message to calculate the size of the serialized message.
41 // std::unique_ptr<MediaMessage> dummy_msg(
42 // MediaMessage::CreateDummyMessage(msg_type));
43 // // ...
44 // // Write all the fields to the dummy message.
45 // // ...
46 //
47 // // Create the real message, once the size of the serialized message
48 // // is known.
49 // std::unique_ptr<MediaMessage> msg(
50 // MediaMessage::CreateMessage(
51 // msg_type,
52 // base::Bind(&MediaMessageFifo::ReserveMemory,
53 // base::Unretained(fifo_feeder.get())),
54 // dummy_msg->content_size()));
55 // if (!msg) {
56 // // Not enough space for the message:
57 // // retry later (e.g. when receiving a read activity event, meaning
58 // // some enough space might have been release).
59 // return;
60 // }
61 // // ...
62 // // Write all the fields to the real message
63 // // in exactly the same way it was done for the dummy message.
64 // // ...
65 // // Once message |msg| is going out of scope, then MediaMessageFifo
66 // // fifo_feeder is informed that the message is not needed anymore
67 // // (i.e. it was fully written), and fifo_feeder can then update
68 // // the external write pointer of the fifo so that the consumer
69 // // can start consuming this message.
70 //
71 // A typical consumer (using MediaMessageFifo instance fifo_consumer)
72 // will retrive messages in the following way:
73 // std::unique_ptr<MediaMessage> msg(fifo_consumer->Pop());
74 // if (!msg) {
75 // // The fifo is empty, i.e. no message left.
76 // // Try reading again later (e.g. after receiving a write activity event.
77 // return;
78 // }
79 // // Parse the message using Read functions of MediaMessage:
80 // // ...
81 // // Once the message is going out of scope, MediaMessageFifo will receive
82 // // a notification that the underlying memory can be released
83 // // (i.e. the external read pointer can be updated).
84 //
85 //
86 class MediaMessageFifo {
87 private:
88 struct Descriptor {
89 size_t size;
90 size_t rd_offset;
91 size_t wr_offset;
92
93 // Ensure the first item has the same alignment as an int64_t.
94 int64_t first_item;
95 };
96
97 public:
98 static const int kDescriptorSize = sizeof(Descriptor);
99
100 // Creates a media message fifo using |mem| as the underlying serialized
101 // structure.
102 // If |init| is true, the underlying fifo structure is initialized.
103 MediaMessageFifo(std::unique_ptr<MediaMemoryChunk> mem, bool init);
104 ~MediaMessageFifo();
105
106 // When the consumer and the feeder are living in two different processes,
107 // we might want to convey some messages between these two processes to notify
108 // about some fifo activity.
109 void ObserveReadActivity(const base::Closure& read_event_cb);
110 void ObserveWriteActivity(const base::Closure& write_event_cb);
111
112 // Reserves a writeable block of memory at the back of the fifo,
113 // corresponding to the serialized structure of the message.
114 // Returns NULL if the required size cannot be allocated.
115 std::unique_ptr<MediaMemoryChunk> ReserveMemory(size_t size);
116
117 // Pop a message from the queue.
118 // Returns a null pointer if there is no message left.
119 std::unique_ptr<MediaMessage> Pop();
120
121 // Flush the fifo.
122 void Flush();
123
124 private:
125 // Add some accessors to ensure security on the browser process side.
126 size_t current_rd_offset() const;
127 size_t current_wr_offset() const;
128 size_t internal_rd_offset() const {
129 DCHECK_LT(internal_rd_offset_, size_);
130 return internal_rd_offset_;
131 }
132 size_t internal_wr_offset() const {
133 DCHECK_LT(internal_wr_offset_, size_);
134 return internal_wr_offset_;
135 }
136
137 // Reserve a block of free memory without doing any check on the available
138 // space. Invoke this function only when all the checks have been done.
139 std::unique_ptr<MediaMemoryChunk> ReserveMemoryNoCheck(size_t size);
140
141 // Invoked each time there is a memory region in the free space of the fifo
142 // that has possibly been written.
143 void OnWrMemoryReleased();
144
145 // Invoked each time there is a memory region in the allocated space
146 // of the fifo that has possibly been released.
147 void OnRdMemoryReleased();
148
149 // Functions to modify the internal/external read/write pointers.
150 void CommitRead(size_t new_rd_offset);
151 void CommitWrite(size_t new_wr_offset);
152 void CommitInternalRead(size_t new_rd_offset);
153 void CommitInternalWrite(size_t new_wr_offset);
154
155 // An instance of MediaMessageFifo must be running on a single thread.
156 // If the fifo feeder and consumer are living on 2 different threads
157 // or 2 different processes, they must create their own instance
158 // of MediaMessageFifo using the same underlying block of (shared) memory
159 // in the constructor.
160 base::ThreadChecker thread_checker_;
161
162 // Callbacks invoked to notify either of some read or write activity on the
163 // fifo. This is especially useful when the feeder and consumer are living in
164 // two different processes.
165 base::Closure read_event_cb_;
166 base::Closure write_event_cb_;
167
168 // The serialized structure of the fifo.
169 std::unique_ptr<MediaMemoryChunk> mem_;
170
171 // The size in bytes of the fifo is cached locally for security purpose.
172 // (the renderer process cannot modify the size and make the browser process
173 // access out of range addresses).
174 size_t size_;
175
176 // TODO(damienv): This is a work-around since atomicops.h does not define
177 // an atomic size_t type.
178 #if SIZE_MAX == UINT32_MAX
179 typedef base::subtle::Atomic32 AtomicSize;
180 #elif SIZE_MAX == UINT64_MAX
181 typedef base::subtle::Atomic64 AtomicSize;
182 #else
183 #error "Unsupported size_t"
184 #endif
185 AtomicSize* rd_offset_;
186 AtomicSize* wr_offset_;
187
188 // Internal read offset: this is where data is actually read from.
189 // The external offset |rd_offset_| is only used to protect data from being
190 // overwritten by the feeder.
191 // At any time, the internal read pointer must be between the external read
192 // offset and the write offset (circular fifo definition of "between").
193 size_t internal_rd_offset_;
194 size_t internal_wr_offset_;
195
196 // Note: all the memory read/write are followed by a memory fence before
197 // updating the rd/wr pointer.
198 void* base_;
199
200 // Protects the messages that are either being read or written.
201 std::list<scoped_refptr<MediaMessageFlag> > rd_flags_;
202 std::list<scoped_refptr<MediaMessageFlag> > wr_flags_;
203
204 base::WeakPtr<MediaMessageFifo> weak_this_;
205 base::WeakPtrFactory<MediaMessageFifo> weak_factory_;
206
207 DISALLOW_COPY_AND_ASSIGN(MediaMessageFifo);
208 };
209
210 } // namespace media
211 } // namespace chromecast
212
213 #endif // CHROMECAST_MEDIA_CMA_IPC_MEDIA_MESSAGE_FIFO_H_
OLDNEW
« no previous file with comments | « chromecast/media/cma/ipc/media_message.cc ('k') | chromecast/media/cma/ipc/media_message_fifo.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698