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

Side by Side Diff: media/audio/android/audio_track_output_stream.cc

Issue 2466463005: Support (E)AC3 passthrough
Patch Set: Add unit tests Created 3 years, 6 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 2017 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 "media/audio/android/audio_track_output_stream.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/logging.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/time/default_tick_clock.h"
12 #include "jni/AudioTrackOutputStream_jni.h"
13 #include "media/audio/audio_manager_base.h"
14
15 using base::android::AttachCurrentThread;
16
17 namespace media {
18
19 // Android audio format. For more information, please see:
20 // https://developer.android.com/reference/android/media/AudioFormat.html
21 enum {
22 kEncodingPcmFloat = 4, // ENCODING_PCM_FLOAT
23 kEncodingAc3 = 5, // ENCODING_AC3
24 kEncodingEac3 = 6, // ENCODING_E_AC3
25 };
26
27 AudioTrackOutputStream::AudioTrackOutputStream(AudioManagerBase* manager,
28 const AudioParameters& params)
29 : params_(params),
30 audio_manager_(manager),
31 callback_(nullptr),
DaleCurtis 2017/06/15 21:46:31 Inline initialize these parameters in the header f
AndyWu 2017/08/02 01:43:38 Done.
32 audio_bus_(AudioBus::Create(params_)),
33 muted_(false),
34 volume_(1.0),
35 total_read_frames_(0),
36 tick_clock_(new base::DefaultTickClock()) {
DaleCurtis 2017/06/15 21:46:31 No need for this unless you're going to add a test
AndyWu 2017/08/02 01:43:38 Done.
37 audio_bus_->Zero();
38 }
39
40 AudioTrackOutputStream::~AudioTrackOutputStream() {
41 DCHECK(!callback_);
42 }
43
44 bool AudioTrackOutputStream::Open() {
45 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
46 JNIEnv* env = AttachCurrentThread();
47 j_audio_output_stream_.Reset(Java_AudioTrackOutputStream_create(env));
48
49 int format = kEncodingPcmFloat;
50 if (params_.IsBitstreamFormat()) {
51 if (params_.format() == AudioParameters::AUDIO_BITSTREAM_AC3) {
52 format = kEncodingAc3;
53 } else if (params_.format() == AudioParameters::AUDIO_BITSTREAM_EAC3) {
54 format = kEncodingEac3;
55 } else {
56 NOTREACHED();
57 }
58 }
59
60 return Java_AudioTrackOutputStream_open(env, j_audio_output_stream_.obj(),
61 params_.channels(),
62 params_.sample_rate(), format);
63 }
64
65 void AudioTrackOutputStream::Start(AudioSourceCallback* callback) {
66 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
67 callback_ = callback;
68 total_read_frames_ = 0;
69 Java_AudioTrackOutputStream_start(AttachCurrentThread(),
70 j_audio_output_stream_.obj(),
71 reinterpret_cast<intptr_t>(this));
72 }
73
74 void AudioTrackOutputStream::Stop() {
75 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
76 Java_AudioTrackOutputStream_stop(AttachCurrentThread(),
77 j_audio_output_stream_.obj());
78 callback_ = nullptr;
79 }
80
81 void AudioTrackOutputStream::Close() {
82 DCHECK(!callback_);
83 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
84
85 Java_AudioTrackOutputStream_close(AttachCurrentThread(),
86 j_audio_output_stream_.obj());
87 audio_manager_->ReleaseOutputStream(this);
88 }
89
90 void AudioTrackOutputStream::SetMute(bool muted) {
91 if (muted_ == muted)
92 return;
93
94 muted_ = muted;
95 Java_AudioTrackOutputStream_setVolume(AttachCurrentThread(),
96 j_audio_output_stream_.obj(),
97 muted_ ? 0.0 : volume_);
98 }
99
100 void AudioTrackOutputStream::SetVolume(double volume) {
101 // Track |volume_| since AudioTrack uses a scaled value.
102 volume_ = volume;
103 if (muted_)
104 return;
105
106 Java_AudioTrackOutputStream_setVolume(AttachCurrentThread(),
107 j_audio_output_stream_.obj(), volume);
108 };
109
110 void AudioTrackOutputStream::GetVolume(double* volume) {
111 *volume = volume_;
112 };
113
114 // AudioOutputStream::SourceCallback implementation methods called from Java.
115 int AudioTrackOutputStream::OnMoreData(JNIEnv* env,
116 jobject obj,
117 jobject audio_data,
118 int total_played_frames) {
DaleCurtis 2017/06/15 21:46:31 As Chris notes, this should be an int64_t.
AndyWu 2017/08/02 01:43:38 AudioTrack.getPlaybackHeadPosition()[1] returns a
DaleCurtis 2017/08/03 01:38:10 Overflow isn't defined for signed types, so if you
AndyWu 2017/08/03 17:11:17 Well, I consider 0x7FFFFFFF + 1 = 0x80000000 is ov
DaleCurtis 2017/08/03 17:22:55 Thanks for changing it. For future reference, what
AndyWu 2017/08/03 21:58:45 Thanks for the great information. :) It does make
119 if (!callback_)
120 return 0;
121
122 int delay_in_frame = total_read_frames_ - total_played_frames;
DaleCurtis 2017/06/15 21:46:31 Ditto; int64_t.
AndyWu 2017/08/02 01:43:38 Done.
123 if (delay_in_frame < 0)
DaleCurtis 2017/06/15 21:46:31 Should be impossible?, DCHECK instead?
AndyWu 2017/08/02 01:43:38 Normally, it should not happen. However, it could
124 delay_in_frame = 0;
125 base::TimeDelta delay = base::TimeDelta::FromSecondsD(
DaleCurtis 2017/06/15 21:46:31 Use AudioTimestampHelper::FramesToTime().
AndyWu 2017/08/02 01:43:38 Done.
126 static_cast<double>(delay_in_frame) / params_.sample_rate());
127
128 callback_->OnMoreData(delay, tick_clock_->NowTicks(), 0, audio_bus_.get());
129
130 if (audio_bus_->data_size() <= 0)
131 return 0;
132
133 total_read_frames_ += audio_bus_->frames();
134
135 void* native_bus = env->GetDirectBufferAddress(audio_data);
DaleCurtis 2017/06/15 21:46:31 Get this pointer ahead of time and use AudioBus::W
AndyWu 2017/08/02 01:43:38 TBD
136 memcpy(native_bus, audio_bus_->channel(0), audio_bus_->data_size());
137 return audio_bus_->data_size();
138 }
139
140 void AudioTrackOutputStream::OnError(JNIEnv* env, jobject obj) {
141 DCHECK(callback_);
142 callback_->OnError();
143 }
144
145 // static
146 bool AudioTrackOutputStream::RegisterAudioTrackOutputStream(JNIEnv* env) {
147 return RegisterNativesImpl(env);
148 }
149
150 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698