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

Side by Side Diff: services/media/audio/audio_pipe.cc

Issue 1424933002: Add an initial revision of an audio server. (Closed) Base URL: https://github.com/domokit/mojo.git@change4
Patch Set: refactor MixerKernel into a class to prepare for the addition of a linear interpolation sampler Created 5 years, 1 month 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 2015 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 #include <limits>
6 #include <vector>
7
8 #include "services/media/audio/audio_pipe.h"
9 #include "services/media/audio/audio_server_impl.h"
10 #include "services/media/audio/audio_track_impl.h"
11
12 namespace mojo {
13 namespace media {
14 namespace audio {
15
16 AudioPipe::AudioPacketRef::AudioPacketRef(MediaPacketStatePtr state,
17 AudioServerImpl* server,
18 std::vector<Region>&& regions,
19 int64_t start_pts,
20 int64_t end_pts)
21 : state_(std::move(state)),
22 server_(server),
23 regions_(regions),
24 start_pts_(start_pts),
25 end_pts_(end_pts) {
26 DCHECK(state_);
27 DCHECK(server_);
28 }
29
30 AudioPipe::AudioPacketRef::~AudioPacketRef() {
31 DCHECK(server_);
32 server_->SchedulePacketCleanup(std::move(state_));
jeffbrown 2015/11/04 23:43:33 Destructor side-effects like these make be a littl
johngro 2015/11/06 02:20:25 yeah, I am not thrilled with this either. It is a
33 }
34
35 AudioPipe::AudioPipe(AudioTrackImpl* owner,
36 AudioServerImpl* server)
37 : owner_(owner),
38 server_(server) {
39 DCHECK(owner_);
40 DCHECK(server_);
41 }
42
43 AudioPipe::~AudioPipe() {}
44
45 void AudioPipe::OnPacketReceived(MediaPacketStatePtr state) {
46 const MediaPacketPtr& packet = state->GetPacket();
47 DCHECK(packet);
48 DCHECK(packet->payload);
49 DCHECK(owner_);
50
51 // Start by making sure that we are regions we are receiving are made from an
52 // integral number of audio frames. Count the total number of frames in the
53 // process.
54 //
55 // TODO(johngro): Someday, automatically enforce this using
56 // alignment/allocation restrictions at the MediaPipe level of things.
57 uint32_t frame_count = 0;
58 uint32_t frame_size = owner_->BytesPerFrame();
59 const MediaPacketRegionPtr* region = &packet->payload;
60 size_t ndx = 0;
61 std::vector<AudioPacketRef::Region> regions;
jeffbrown 2015/11/04 23:43:33 I was slightly surprised to see you allocating on
johngro 2015/11/06 02:20:25 I was made slightly ill by my actions in doing so.
62
63 regions.reserve(packet->extra_payload.size() + 1);
64
65 DCHECK(frame_size);
66 while (true) {
67 if ((frame_size > 1) && ((*region)->length % frame_size)) {
68 state->SetResult(MediaResult::INVALID_ARGUMENT);
jeffbrown 2015/11/04 23:43:33 can we just close the pipe?
johngro 2015/11/06 02:20:25 Acknowledged. Placing the general close-the-pipe-a
69 return;
70 }
71
72 frame_count += ((*region)->length / frame_size);
73 if (frame_count > (std::numeric_limits<uint32_t>::max() >>
74 AudioTrackImpl::PTS_FRACTIONAL_BITS)) {
75 state->SetResult(MediaResult::INVALID_ARGUMENT);
76 return;
77 }
78
79 regions.emplace_back(
80 static_cast<const uint8_t*>(buffer()) + (*region)->offset,
jeffbrown 2015/11/04 23:43:33 Make sure to check that the offset is within the b
johngro 2015/11/06 02:20:25 Offset and length containment has already been han
81 frame_count << AudioTrackImpl::PTS_FRACTIONAL_BITS);
82
83 if (ndx >= packet->extra_payload.size()) {
84 break;
85 }
86
87 region = &(packet->extra_payload[ndx]);
88 ndx++;
89 }
90
91 // Figure out the starting PTS.
92 int64_t start_pts;
93 if (packet->pts != MediaPacket::kNoTimestamp) {
94 // The user provided an explicit PTS for this audio. Transform it into
95 // units of fractional frames.
96 LinearTransform tmp(0, owner_->FractionalFrameToMediaTimeRatio(), 0);
97 if (!tmp.DoForwardTransform(packet->pts, &start_pts)) {
98 state->SetResult(MediaResult::INTERNAL_ERROR);
99 return;
100 }
101 } else {
102 // No PTS was provided. Use the end time of the last audio packet, if
103 // known. Otherwise, just assume a media time of 0.
104 start_pts = next_pts_known_ ? next_pts_ : 0;
105 }
106
107 // The end pts is the value we will use for the next packet's start PTS, if
108 // the user does not provide an explicit PTS.
109 int64_t pts_delta = (static_cast<int64_t>(frame_count)
110 << AudioTrackImpl::PTS_FRACTIONAL_BITS);
111 next_pts_ = start_pts + pts_delta;
112 next_pts_known_ = true;
113
114 owner_->OnPacketReceived(AudioPacketRefPtr(
115 new AudioPacketRef(std::move(state),
116 server_,
117 std::move(regions),
jeffbrown 2015/11/04 23:43:33 So this object contains a pointer to an mmap'd reg
johngro 2015/11/06 02:20:25 FWIW - enforcement like this belong at the MediaPi
118 start_pts,
119 next_pts_)));
120 }
121
122 void AudioPipe::OnFlushRequested(const FlushCallback& cbk) {
123 DCHECK(owner_);
124 owner_->OnFlushRequested(cbk);
125 next_pts_known_ = false;
126 }
127
128 } // namespace audio
129 } // namespace media
130 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698