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

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: fix issues discovered with initial preflight 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
« no previous file with comments | « services/media/audio/audio_pipe.h ('k') | services/media/audio/audio_server_app.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(
17 MediaPacketStatePtr state,
18 AudioServerImpl* server,
19 std::vector<Region>&& regions, // NOLINT(build/c++11)
20 int64_t start_pts,
21 int64_t end_pts)
22 : state_(std::move(state)),
23 server_(server),
24 regions_(std::move(regions)),
25 start_pts_(start_pts),
26 end_pts_(end_pts) {
27 DCHECK(state_);
28 DCHECK(server_);
29 }
30
31 AudioPipe::AudioPacketRef::~AudioPacketRef() {
32 DCHECK(server_);
33 server_->SchedulePacketCleanup(std::move(state_));
34 }
35
36 AudioPipe::AudioPipe(AudioTrackImpl* owner,
37 AudioServerImpl* server)
38 : owner_(owner),
39 server_(server) {
40 DCHECK(owner_);
41 DCHECK(server_);
42 }
43
44 AudioPipe::~AudioPipe() {}
45
46 void AudioPipe::OnPacketReceived(MediaPacketStatePtr state) {
47 const MediaPacketPtr& packet = state->GetPacket();
48 DCHECK(packet);
49 DCHECK(packet->payload);
50 DCHECK(owner_);
51
52 // Start by making sure that we are regions we are receiving are made from an
53 // integral number of audio frames. Count the total number of frames in the
54 // process.
55 //
56 // TODO(johngro): Someday, automatically enforce this using
57 // alignment/allocation restrictions at the MediaPipe level of things.
58 uint32_t frame_count = 0;
59 uint32_t frame_size = owner_->BytesPerFrame();
60 const MediaPacketRegionPtr* region = &packet->payload;
61 size_t ndx = 0;
62 std::vector<AudioPacketRef::Region> regions;
63
64 regions.reserve(packet->extra_payload.size() + 1);
65
66 DCHECK(frame_size);
67 while (true) {
68 if ((frame_size > 1) && ((*region)->length % frame_size)) {
69 state->SetResult(MediaResult::INVALID_ARGUMENT);
70 return;
71 }
72
73 frame_count += ((*region)->length / frame_size);
74 if (frame_count > (std::numeric_limits<uint32_t>::max() >>
75 AudioTrackImpl::PTS_FRACTIONAL_BITS)) {
76 state->SetResult(MediaResult::INVALID_ARGUMENT);
77 return;
78 }
79
80 regions.emplace_back(
81 static_cast<const uint8_t*>(buffer()) + (*region)->offset,
82 frame_count << AudioTrackImpl::PTS_FRACTIONAL_BITS);
83
84 if (ndx >= packet->extra_payload.size()) {
85 break;
86 }
87
88 region = &(packet->extra_payload[ndx]);
89 ndx++;
90 }
91
92 // Figure out the starting PTS.
93 int64_t start_pts;
94 if (packet->pts != MediaPacket::kNoTimestamp) {
95 // The user provided an explicit PTS for this audio. Transform it into
96 // units of fractional frames.
97 LinearTransform tmp(0, owner_->FractionalFrameToMediaTimeRatio(), 0);
98 if (!tmp.DoForwardTransform(packet->pts, &start_pts)) {
99 state->SetResult(MediaResult::INTERNAL_ERROR);
100 return;
101 }
102 } else {
103 // No PTS was provided. Use the end time of the last audio packet, if
104 // known. Otherwise, just assume a media time of 0.
105 start_pts = next_pts_known_ ? next_pts_ : 0;
106 }
107
108 // The end pts is the value we will use for the next packet's start PTS, if
109 // the user does not provide an explicit PTS.
110 int64_t pts_delta = (static_cast<int64_t>(frame_count)
111 << AudioTrackImpl::PTS_FRACTIONAL_BITS);
112 next_pts_ = start_pts + pts_delta;
113 next_pts_known_ = true;
114
115 owner_->OnPacketReceived(AudioPacketRefPtr(
116 new AudioPacketRef(std::move(state),
117 server_,
118 std::move(regions),
119 start_pts,
120 next_pts_)));
121 }
122
123 void AudioPipe::OnFlushRequested(const FlushCallback& cbk) {
124 DCHECK(owner_);
125 owner_->OnFlushRequested(cbk);
126 next_pts_known_ = false;
127 }
128
129 } // namespace audio
130 } // namespace media
131 } // namespace mojo
OLDNEW
« no previous file with comments | « services/media/audio/audio_pipe.h ('k') | services/media/audio/audio_server_app.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698